From 93fe95beba8a6db97fc66ff0f8af266964941eb0 Mon Sep 17 00:00:00 2001 From: Wesley Moore Date: Tue, 12 Dec 2017 21:34:42 +1100 Subject: [PATCH] Add day 9 part 2 solution --- 2017/day/9/problem.txt | 16 ++++++ 2017/day/9/src/main.rs | 109 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 112 insertions(+), 13 deletions(-) diff --git a/2017/day/9/problem.txt b/2017/day/9/problem.txt index be8f22e..713630b 100644 --- a/2017/day/9/problem.txt +++ b/2017/day/9/problem.txt @@ -44,3 +44,19 @@ Your goal is to find the total score for all groups in your input. Each group is What is the total score for all groups in your input? +--- Part Two --- + +Now, you're ready to remove the garbage. + +To prove you've removed it, you need to count all of the characters within the garbage. The leading and trailing < and > don't count, nor do any canceled characters or the ! doing the canceling. + + <>, 0 characters. + , 17 characters. + <<<<>, 3 characters. + <{!>}>, 2 characters. + , 0 characters. + >, 0 characters. + <{o"i!a,<{i, 10 characters. + +How many non-canceled characters are within the garbage in your puzzle input? + diff --git a/2017/day/9/src/main.rs b/2017/day/9/src/main.rs index cc9da92..75318bf 100644 --- a/2017/day/9/src/main.rs +++ b/2017/day/9/src/main.rs @@ -20,12 +20,15 @@ fn main() { let file = File::open("input").expect("unable to open input file"); let reader = BufReader::new(file); - println!("{}", stream(reader)); + let (score, garbage_count) = stream(reader); + println!("{}", score); + println!("{}", garbage_count); } -fn stream(reader: R) -> usize where R: Read { +fn stream(reader: R) -> (usize, usize) where R: Read { let mut state = State { group_depth: 0, flags: Flags::Normal }; let mut score = 0; + let mut garbage_count = 0; for byte in reader.bytes() { state = match (state.flags, byte.ok().and_then(|b| char::from_u32(b as u32))) { @@ -39,15 +42,17 @@ fn stream(reader: R) -> usize where R: Read { (Flags::Normal, Some('<')) => State { group_depth: state.group_depth, flags: Flags::InGarbage }, (Flags::InGarbage, Some('>')) => State { group_depth: state.group_depth, flags: Flags::Normal }, (Flags::InGarbage, Some('!')) => State { group_depth: state.group_depth, flags: Flags::CancelNextInGarbage }, + (Flags::InGarbage, Some(_)) => { + garbage_count += 1; + State { group_depth: state.group_depth, flags: Flags::InGarbage } + }, (Flags::Normal, Some('!')) => State { group_depth: state.group_depth, flags: Flags::CancelNext }, (_, Some(_)) => state, (_, None) => panic!("error reading/converting byte") }; - - // println!("{:?}", state); } - score + (score, garbage_count) } // {}, score of 1. @@ -56,7 +61,8 @@ fn test_empty() { use std::io::Cursor; let cursor = Cursor::new(b"{}"); - assert_eq!(stream(cursor), 1); + let (score, _) = stream(cursor); + assert_eq!(score, 1); } // {{{}}}, score of 1 + 2 + 3 = 6. @@ -65,7 +71,8 @@ fn test_empty_nested() { use std::io::Cursor; let cursor = Cursor::new(b"{{{}}}"); - assert_eq!(stream(cursor), 6); + let (score, _) = stream(cursor); + assert_eq!(score, 6); } // {{},{}}, score of 1 + 2 + 2 = 5. @@ -74,7 +81,8 @@ fn test_empty_empty() { use std::io::Cursor; let cursor = Cursor::new(b"{{},{}}"); - assert_eq!(stream(cursor), 5); + let (score, _) = stream(cursor); + assert_eq!(score, 5); } // {{{},{},{{}}}}, score of 1 + 2 + 3 + 3 + 3 + 4 = 16. @@ -83,7 +91,8 @@ fn test_empty_empty_nested_empty() { use std::io::Cursor; let cursor = Cursor::new(b"{{{},{},{{}}}}"); - assert_eq!(stream(cursor), 16); + let (score, _) = stream(cursor); + assert_eq!(score, 16); } // {,,,}, score of 1. @@ -92,7 +101,8 @@ fn test_four_garbage() { use std::io::Cursor; let cursor = Cursor::new(b"{,,,}"); - assert_eq!(stream(cursor), 1); + let (score, _) = stream(cursor); + assert_eq!(score, 1); } // {{},{},{},{}}, score of 1 + 2 + 2 + 2 + 2 = 9. @@ -101,7 +111,8 @@ fn test_groups_with_garbage() { use std::io::Cursor; let cursor = Cursor::new(b"{{},{},{},{}}"); - assert_eq!(stream(cursor), 9); + let (score, _) = stream(cursor); + assert_eq!(score, 9); } // {{},{},{},{}}, score of 1 + 2 + 2 + 2 + 2 = 9. @@ -110,7 +121,8 @@ fn test_groups_with_cancellations() { use std::io::Cursor; let cursor = Cursor::new(b"{{},{},{},{}}"); - assert_eq!(stream(cursor), 9); + let (score, _) = stream(cursor); + assert_eq!(score, 9); } // {{},{},{},{}}, score of 1 + 2 = 3. @@ -119,7 +131,78 @@ fn test_groups_with_garbage_exclamation() { use std::io::Cursor; let cursor = Cursor::new(b"{{},{},{},{}}"); - assert_eq!(stream(cursor), 3); + let (score, _) = stream(cursor); + assert_eq!(score, 3); } +// Part Two +// <>, 0 characters. +#[test] +fn test_garbage_empty() { + use std::io::Cursor; + + let cursor = Cursor::new(b"{<>}"); + let (_, garbage_count) = stream(cursor); + assert_eq!(garbage_count, 0); +} + +// , 17 characters. +#[test] +fn test_garbage_count_random_characters() { + use std::io::Cursor; + + let cursor = Cursor::new(b"{}"); + let (_, garbage_count) = stream(cursor); + assert_eq!(garbage_count, 17); +} + +// <<<<>, 3 characters. +#[test] +fn test_garbage_repeated_start() { + use std::io::Cursor; + + let cursor = Cursor::new(b"{<<<<>}"); + let (_, garbage_count) = stream(cursor); + assert_eq!(garbage_count, 3); +} + +// <{!>}>, 2 characters. +#[test] +fn test_garbage_cancel_one() { + use std::io::Cursor; + + let cursor = Cursor::new(b"{<{!>}>}"); + let (_, garbage_count) = stream(cursor); + assert_eq!(garbage_count, 2); +} + +// , 0 characters. +#[test] +fn test_garbage_cancel_cancel() { + use std::io::Cursor; + + let cursor = Cursor::new(b"{}"); + let (_, garbage_count) = stream(cursor); + assert_eq!(garbage_count, 0); +} + +// >, 0 characters. +#[test] +fn test_garbage_cancel_cancel_end() { + use std::io::Cursor; + + let cursor = Cursor::new(b"{>}"); + let (_, garbage_count) = stream(cursor); + assert_eq!(garbage_count, 0); +} + +// <{o"i!a,<{i, 10 characters. +#[test] +fn test_garbage_gibberish() { + use std::io::Cursor; + + let cursor = Cursor::new(b"{<{o\"i!a,<{i}"); + let (_, garbage_count) = stream(cursor); + assert_eq!(garbage_count, 10); +}