From 051be932a389b8bc3ea5d4626575454844639066 Mon Sep 17 00:00:00 2001 From: June McEnroe Date: Mon, 27 Nov 2017 17:11:18 -0500 Subject: Move to 2016 directory --- 2016/src/bin/day04.rs | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 2016/src/bin/day04.rs (limited to '2016/src/bin/day04.rs') diff --git a/2016/src/bin/day04.rs b/2016/src/bin/day04.rs new file mode 100644 index 0000000..8e724c2 --- /dev/null +++ b/2016/src/bin/day04.rs @@ -0,0 +1,123 @@ +use std::io::{self, Read}; +use std::str::FromStr; + +struct Room { + name: String, + sector_id: u32, + checksum: String, +} + +impl FromStr for Room { + type Err = (); + fn from_str(s: &str) -> Result { + let mut iter = s.trim_right_matches(']') + .rsplitn(3, |c| c == '-' || c == '['); + + let checksum = iter.next().ok_or(())?; + let sector_id = iter.next().ok_or(())?; + let name = iter.next().ok_or(())?; + + Ok(Room { + name: name.into(), + sector_id: sector_id.parse().map_err(|_| ())?, + checksum: checksum.into(), + }) + } +} + +impl Room { + fn checksum(&self) -> String { + let mut letters = [ + (0, 'a'), (0, 'b'), (0, 'c'), (0, 'd'), (0, 'e'), (0, 'f'), (0, 'g'), (0, 'h'), + (0, 'i'), (0, 'j'), (0, 'k'), (0, 'l'), (0, 'm'), (0, 'n'), (0, 'o'), (0, 'p'), + (0, 'q'), (0, 'r'), (0, 's'), (0, 't'), (0, 'u'), (0, 'v'), (0, 'w'), (0, 'x'), + (0, 'y'), (0, 'z'), + ]; + + for letter in self.name.chars().filter(|c| c.is_alphabetic()) { + let index = letter as u8 - b'a'; + letters[index as usize].0 -= 1; + } + + letters.sort(); + + letters.into_iter() + .map(|l| l.1) + .take(5) + .collect() + } + + fn verify_checksum(&self) -> bool { + self.checksum == self.checksum() + } + + fn decrypt_name(&self) -> String { + self.name.chars() + .map(|c| { + match c { + '-' => ' ', + _ => rotate(c, self.sector_id), + } + }) + .collect() + } +} + +fn rotate(c: char, n: u32) -> char { + let c = c as u8 + (n % 26) as u8; + if c > b'z' { + (c - 26) as char + } else { + c as char + } +} + +fn solve1(input: &str) -> u32 { + input.lines() + .map(str::parse) + .map(Result::unwrap) + .filter(Room::verify_checksum) + .map(|room| room.sector_id) + .sum() +} + +fn solve2(input: &str) -> Option { + input.lines() + .map(str::parse) + .map(Result::unwrap) + .filter(Room::verify_checksum) + .filter_map(|r| { + match r.decrypt_name().as_str() { + "northpole object storage" => Some(r.sector_id), + _ => None, + } + }) + .next() +} + +fn main() { + let mut input = String::new(); + io::stdin().read_to_string(&mut input).unwrap(); + + println!("Part 1: {}", solve1(&input)); + if let Some(sector_id) = solve2(&input) { + println!("Part 2: {}", sector_id); + } +} + +#[test] +fn part1() { + let input = " +aaaaa-bbb-z-y-x-123[abxyz] +a-b-c-d-e-f-g-h-987[abcde] +not-a-real-room-404[oarel] +totally-real-room-200[decoy] +"; + assert_eq!(1514, solve1(&input[1..])); +} + +#[test] +fn part2() { + let room: Room = "qzmt-zixmtkozy-ivhz-343[zimth]".parse().unwrap(); + assert_eq!("very encrypted name", room.decrypt_name()); +} -- cgit 1.4.1 /palaver/notify.c?h=2.5&id=457e4661d8c96d14382aebf6943294b5c1a83ffd&follow=1'>contrib/palaver: Use open_memstream instead of fmemopenJune McEnroe 2020-10-11Handle signals before the main loopJune McEnroe 2020-09-09Fix possibliy uninitialized error 2.0June McEnroe 2020-08-31Refactor reserialization and client self-producingJune McEnroe 2020-08-30Add chmod+chown to certbot exampleJune McEnroe 2020-08-30Rearrange bounce.c, move non-main mains below mainJune McEnroe 2020-08-30Sandbox pounce with unveil(2)June McEnroe 2020-08-28Refactor certificate loading and load all certs from config pathsJune McEnroe 2020-08-27Sandbox pounce with pledge(2)June McEnroe 2020-08-27Sandbox calico with pledge(2) and unveil(2)June McEnroe 2020-08-27Add support for OpenBSDJune McEnroe 2020-08-27Remove rc scriptsJune McEnroe 2020-08-27contrib/palaver: Fix documented database pathJune McEnroe 2020-08-27contrib/palaver: Remove rc scriptJune McEnroe 2020-08-27contrib/palaver: Fix database search and creationJune McEnroe 2020-08-27contrib/palaver: Use pounce's XDG directoryJune McEnroe 2020-08-27contrib/palaver: Only allow HTTPSJune McEnroe 2020-08-25Support the pounce_env rc variableJune McEnroe 2020-08-25Remove deprecated option namesJune McEnroe 2020-08-25Document configuration and data file searchJune McEnroe 2020-08-24Use dataOpen for save fileJune McEnroe 2020-08-24Use configOpen to load localCAJune McEnroe 2020-08-24Use configPath to load client cert/privJune McEnroe 2020-08-24Use configOpen in getopt_configJune McEnroe 2020-08-24Import xdg.c from catgirlJune McEnroe 2020-08-23Replace “RAND_bytes” by “getentropy”Issam E. Maghni 2020-08-16contrib/palaver: Add no message preview flagsJune McEnroe 2020-08-13contrib/palaver: Don't set channel for PMsJune McEnroe 2020-08-13Fix unintended interception of NICK after registrationJune McEnroe 2020-08-12Add Additional Components section to READMEJune McEnroe 2020-08-12Document -L / palaver optionJune McEnroe 2020-08-11contrib/palaver: Document service configurationJune McEnroe 2020-08-11contrib/palaver: Add install target and rc scriptJune McEnroe 2020-08-11contrib/palaver: Implement command and notificationsJune McEnroe