summary refs log tree commit diff homepage
diff options
context:
space:
mode:
authorJune McEnroe <programble@gmail.com>2016-12-04 14:17:42 -0500
committerJune McEnroe <programble@gmail.com>2016-12-04 14:17:42 -0500
commit7455de504f913a0443f048fb602f4e36ecd46cc0 (patch)
tree64149ad8a282a31d73230dd5529b498af79fff0c
parentDay 4 (diff)
downloadaoc-7455de504f913a0443f048fb602f4e36ecd46cc0.tar.gz
aoc-7455de504f913a0443f048fb602f4e36ecd46cc0.zip
Day 4 part 2
-rw-r--r--src/bin/day04.rs64
1 files changed, 56 insertions, 8 deletions
diff --git a/src/bin/day04.rs b/src/bin/day04.rs
index 9f7d0ab..c6a9709 100644
--- a/src/bin/day04.rs
+++ b/src/bin/day04.rs
@@ -26,7 +26,7 @@ impl FromStr for Room {
 }
 
 impl Room {
-    fn real(&self) -> bool {
+    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'),
@@ -41,29 +41,71 @@ impl Room {
 
         letters.sort();
 
-        let expected: String = letters.into_iter()
+        letters.into_iter()
             .map(|l| l.1)
             .take(5)
-            .collect();
+            .collect()
+    }
+
+    fn verify_checksum(&self) -> bool {
+        self.checksum == self.checksum()
+    }
 
-        expected == self.checksum
+    fn decrypt_name(&self) -> String {
+        self.name.chars()
+            .map(|c| {
+                match c {
+                    '-' => ' ',
+                    _ => rotate(c, self.sector_id),
+                }
+            })
+            .collect()
     }
 }
 
-fn solve(input: &str) -> u32 {
+fn rotate(c: char, n: u32) -> char {
+    let mut c = c;
+    for _ in 0..n {
+        c = match c {
+            'a' ... 'y' => (c as u8 + 1) as char,
+            'z' => 'a',
+            _ => panic!("cannot rotate {}", c),
+        }
+    }
+    c
+}
+
+fn solve1(input: &str) -> u32 {
     input.lines()
         .map(str::parse)
         .map(Result::unwrap)
-        .filter(Room::real)
+        .filter(Room::verify_checksum)
         .map(|room| room.sector_id)
         .sum()
 }
 
+fn solve2(input: &str) -> Option<u32> {
+    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: {}", solve(&input));
+    println!("Part 1: {}", solve1(&input));
+    if let Some(sector_id) = solve2(&input) {
+        println!("Part 2: {}", sector_id);
+    }
 }
 
 #[test]
@@ -74,5 +116,11 @@ a-b-c-d-e-f-g-h-987[abcde]
 not-a-real-room-404[oarel]
 totally-real-room-200[decoy]
 ";
-    assert_eq!(1514, solve(&input[1..]));
+    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());
 }
2021-09-23Add quickJune McEnroe 2021-09-23Add The HobbitJune McEnroe Surprisingly good for something written by a man like a hundred years ago! 2021-09-22Remove PSF fontsJune McEnroe They were fun to make but I never actually used them. 2021-09-22Remove Linux-specific utilitiesJune McEnroe I haven't used these in ages. 2021-09-22Call sandbox in CGI modeJune McEnroe Otherwise upload won't actually work. 2021-09-22Support HTTP PUT in upJune McEnroe For use by Palaver[1]. Unfortunately, at least in the current App Store version of Palaver, this doesn't work correctly with basic auth. [1]: https://palaverapp.com/guides/commands/set.html#ui-image_service 2021-09-22Remove default faviconJune McEnroe I hate these things and also this one sucks. 2021-09-21Use Z_FILTERED strategyJune McEnroe 2021-09-21Recalculate various lengths only as neededJune McEnroe This actually speeds things up quite a bit, saving roughly a second on a big PNG screenshot. Almost all the remaining time is spent in deflate. 2021-09-21Rewrite pngo, add explicit optionsJune McEnroe Interesting to see how my code habits have changed. 2021-09-16Fix /* **/ comment matchingJune McEnroe 2021-09-15Remove typer, add downgrade to READMEJune McEnroe 2021-09-15Set bot mode on downgradeJune McEnroe 2021-09-15Enter capsicum in downgradeJune McEnroe 2021-09-15Factor out common parts of downgrade messagesJune McEnroe Also bump the message cap to 1024 because that is ostensibly useful for replying to older messages. 2021-09-14Add downgrade IRC botJune McEnroe 2021-09-14Sort by title if authors matchJune McEnroe There are probably better things to sort by but title definitely always exists. 2021-09-13Swap-remove tags as they're foundJune McEnroe This makes it even faster. From ~1s on a sqlite3.c amalgamation to ~0.85s. 2021-09-12Replace htagml regex with strncmpJune McEnroe Since ctags only ever produces regular expressions of the form /^re$/ or /^re/ with no other special characters, instead unescape the pattern and simply use strncmp. Running on a sqlite3.c amalgamation, the regex version takes ~37s while the strncmp version takes ~1s, producing identical output. Big win! 2021-09-11Also defer printing comment for lone close-parensJune McEnroe 2021-09-10Publish "git-comment"June McEnroe 2021-09-10Add git comment --pretty optionJune McEnroe 2021-09-08Defer printing comment if line is blank or closing braceJune McEnroe This fixes badly indented comments. 2021-09-08Up default min-repeat to 30 linesJune McEnroe 2021-09-08Handle dirty lines in git-commentJune McEnroe 2021-09-08Document and install git-commentJune McEnroe 2021-09-08Add repeat and all options to git-commentJune McEnroe 2021-09-08Add group threshold to git-commentJune McEnroe