diff --git a/2020/inputs/24.txt b/2020/inputs/24.txt new file mode 100644 index 0000000..4053c1e --- /dev/null +++ b/2020/inputs/24.txt @@ -0,0 +1,313 @@ +wseseseswsesesewnesesesesewneseseswnene +seswswsenenweseneesweenwswneswsenwsenw +nenwneneneeneneneneseeenene +swwenwseswseswwnweswswswnwwswesww +nwenenwnwwswnwsewneneswnwswnwwwwsenw +seswseseswsesweseswswswnw +seneesweneesweweeseeseeeenese +nwswnwenwnwnwnwseneswnenwneswswsenenwnenw +wsewwwwwwnenwwwwwneswww +wneneneneenenewneneenesenenenee +sesenweswswneswneswwswnwnwseswseswswnesw +eenwneswseswnwneseneneswwesenwswnwwnese +swnwwenenenwnwnwnwwswnwnwnwnwnwnwneswsw +neeeweswneesweeseeeenweswswwnenw +swswseswnwswseseseneneswsw +eeswnwwnwsenenesenwnwnenwenwnwnenwwnwsw +wseeseswsesewenwswswnweseseseseseswswne +newnewneneneeneswseeneeneeneneese +wenweeswseeeeweseeswneeenwene +swneneswswswnwseseseseswneswswsesesesese +weweewwswwwnw +esesesesewesesenweseseeneswswenesee +eswneswswnwswenewnenwneeeswneswnene +esenenesewseseseesewsesese +wswseneseseeewseswnwneeseneewenee +swseswseewswweeswnwewswenwnewsese +seswseseswwneswswswseswswnwswnwnewnene +sweeesenenenewnenenwneneeneeenewsw +wnwwwwseswnwwwswneswswesewswsenwsww +swswseswswnwneesewswseswneswswsw +seenwseswseesenwseeseseseseseseswswne +swswswnewswswswswswswswsenewwwnewse +swswsewneneswseswnewseswneswneseswsese +wwswnwewswsesenweneeeenwwneee +nwnenenwnwnenenenwnewnwnwnwswe +wwsenwsewwweewwswwswwwnenew +wnenwewnenenenweneenwnwswsw +weeewsweeeeneeeenwneneneneesw +sewnwnwwnwwnwwneweeswnwsenwswnw +swnenenenwswnweswnenenenewnenenene +nwswnwnwsenwesenwnwnwnenwsenenwnwnwwnwsew +nweeeenenenewsweeeneeeeesewese +neneneneneenenwneneeneewnesw +nenwnenwnwnwswnwnwnwnwnwnwnw +nenwswnwnwnwwswnwnwwwnwenwsenwneswnwne +wseneseseseesweseseeenenwenewsese +senwwsesenwenwenenwewseswnweswsese +eweseeseswenwseseeseesenwnwnenwee +wwnwnwwenwnesewwnwnwswwnweeswww +neeneeeneeenenenenwenese +nesenwnwneenwnenwwswnwseswswwwnwene +nesweeswwseswsesewnesewswnw +nwnwewnwnewswnwswwnww +enwnesenwsweseeeewneseeee +seneswwsesesenesesesesesesesenwsesesese +seweswsenesweswswnwswswswwswswswswsw +swswswswswwswneenwswswswswswsewswsene +nenwenewnwnwneneswneneneneneneswenenesene +esenwsesesesesesesesesese +nenwnenwnwnwnenenwnwnenweswnene +swwwwwnewnwnwseewnww +nesenenenenwnewnenwswnweneesenew +wwwwwwwwsewswwswwnw +sesweswswswenwnwswswswswwseswswnwswswswnw +sewnwswswewesee +swnwswswsewswswswneseswswswsw +seswenwnwseeswwnwneseesenweseseesenw +ewesenwseseseeseeseseswsewwwsesw +neeswnenwseenwnenenenwewwnenwnenwnw +eswweeeneneeswenwneenwsewseswse +wwswseseeeseewnwseesesesenwsenese +nwswnwnwenwweswseneswswneswsenenenw +nwwweswewswwnwswswswewwwnwwseee +seseeswsewnwnenweneneenwse +swswwwswsewnwswswww +nwseweseesewsesesewneseseswesese +wwwwnewwwwnwnenwwswwsw +nwenenwseneneswnesenenwnwsewnwswwnwswnwnw +wswneswswswenwseswnwswsesweswswwsesenwne +neesenwnenwseseesweswnwenwneeewe +wneswwwwswwwswweeswweswswwww +wnwewwwwwewwswwwwwwwew +seewwswwwswwneswswwneswnw +swnwswnwsesenwnweswswwseneeewswswsw +swenenwneswwnenweswswnenweeeeeseee +wnwnwneenwswswsenwseenwnwnenwwnwwnene +neneeneswnwneeseewneeweneneneenee +seesenwnwsenesesweseseseswseeneswnwwnw +nweeseseneeenewneeeeeswenwneee +swnenesenwswnenwnwewweswswnwwnenese +senwnewwsenwnwnwnenwnwnwnwnwneeesenwnw +swseenwswneseeseeseseseeewnesenee +sewwswwsenesewnenwewwneeswswee +swneneeeswneneeenenwnene +swwneswswwswseswswswsewwwwnww +nenwnenenenenenesenwsweneneswnenenwnenw +nweswneswseeeeeeswneeeeeneew +swneseneenweeeenwsweseenwsw +nwwswswwenweswwswswwswswswneewwsw +nesweeewsenewsenwnenenwneeneneenenene +swswwswnwwneeswweswswwswswesewwswe +seswseseseeenenweenewwsewseseesese +wswweswwseswwwnw +wsenwsesesenwnenenenwnwswwwnwnenwswwne +swswsweseswswswswswnwswsweswnwswneswswsw +wswwwnwwwwwe +seneseswseseeswnewswswsenwswsesesesese +neesenenesenwenweenwsewneew +wswwswswwswnwswwewswewwnwswesw +swsewsweseneseseneswnese +seseseneswesesesesesesese +newwnesesewnwnenewneneneneswneneswenese +eseswneeenewsenwnewee +nwswswswneswwsweswsw +nwwswwswswsewnwswweewwswswswwswnese +wnewseneeeesweseeewseseseseseneese +swenewnwnweeneneneneswnewsenwnwnenw +nweweeeeswneweseneneneeeswnene +eswneseeeesenweewseweseneesee +nwwswwneneenwsenenwnweneneneeneswe +eweswneneeeseeswenwsenenwnesesewenw +nwseneeswneesesenenwnwneneeswnenwnenwse +swswnwsweeswnesenwswswswswswswswsenwse +nenwnwenwnwswneswnwsenwnwnwenwnwswnwsesw +nwseneenwnwnenwwnwnenwsw +nwnesewswswswsweswwswneswnweswe +enwswwwnewnewwswwwwnwswwwseww +nenwnenenwwneweneseswenwnenwneeswswne +nenwnenwswwneneneneenwswnwneswneneneenesw +neseseneswnewnenesesenenwnwneswsenwnwnw +swenenenenenenesenewnene +nwnwnwnwnwnwnwnwnwenwnwnwswnw +neseneswwnwneswnwsewseseeswenwneswswsw +wwwwneenwnwseswenenwnenwwwnwsesw +wwnewswwwnewswwsewwww +sesesewswsweseswseswse +seswewneenwnenwnwnenwnwnwnwneneswswnwnenw +neeseenwseesweneseweeseeesenwsw +swneneneenewswneneewnenwnwwnwswswnesese +swnesenwnwnwnewnwnenenenwnenenw +wwwnewneeswsenwnwswwnwnwenwnwnewnw +eeeeeeneweeseeeeee +neweeswsenenwseeeeeneneneeneeneswnw +nwnwwenwnwseenwnwenwwnwswwnwswewne +wneenewenweenwseseseesesenewww +eewneeneneeneeenene +swswsenwweenwswswswswswswswsw +nwneneseeenwnwnwswnwwswnwse +swenwnwenwswwnwnwswneenwnwnwnenwnwnwse +wsewswwnenwneseswsenwsww +seeeenwseseneeeeseeeswesew +weenwnewnenwseenwnwnenwnenwnenwwne +sweeeswesenwwnwswwneswnwwewenenw +eeneeenwesewweeneeeswewee +sweseswseswneseseswswsewsesw +wneswseseseseswseseseswswwswsesee +swswswswswseswswwwseeseenewnewsw +eeswnwnwnesewswneseneswsesweewswsee +eseweeneseseseee +weswswnwswsesewswsewenwneneswswenwnw +seseenwseeswneswseenwseseewee +eeneneeswsweseswewwneenwe +neseewnwwesewnwwwswwsewnesenew +eneswnenwewneseneneenenweneneseene +sesenesesesesesenewswsesewseseseseseew +nenenwnenwneeneneneneenwwswneeswnwesw +wwewwsewewwsewwnwwwnwnewww +nweneewnwseneseseeeeswsenweeenew +nwnwwseswseeseseseneenwewswnwseswse +neewsweseeeweswnwsenenwnwwwne +senenwnewseseeswsweseseswswnwwseesesenw +neswswnwnenenwnwsewwnwneswswenwsewnwnenw +wwswwenwnewseneeswsewewnw +seswsewseseneseswneesesenwseseswsesesene +ewwsenenwwseswswsenwnewweenwwenww +nenweenwneenwseneneewwsweeesewe +wswnwwwewwwsewnwsewwsewnwnwse +nwnenwnwenwnwenwnwnesweneswnwnwnwnwswnenw +seeneswwesesesewswsenwwwneewnwne +swwnwswseeswwswswenwswsweswswswwwnw +seswnwewswseswwswwseenesw +eneneseneneneeeneswneneeewnweseswne +enwwneeneeeeesw +sesesenwsesenweesweseeseseneseseswe +nwnwnwnenwenenenenww +nwnwwnwswenwnwnwwnwnwnwwesewnwwnwsw +wwneesenwwsenweswwsewsewwnenww +swswseswswneneswswswswwsweseseswnwswse +wseenwwwwnwnwnenwnwwnwesewsenwnww +wseneseswswwwsewswswwnewsweneswswnww +nwsewnwwnenwnesewsewwnwwswnwnwswnw +senwenesenenenesweenewnewnenenenenw +swnwswweewnwwwnwswseswewewwsww +wsewswnewsenewsewwwswwwwwwnw +nwsenwnenenenenwnwnwnenwnw +nenenwnenwnwnwnwnwenwwnesenwswnene +nwwweewenweeswesw +wnwnwnwsenwswnenwweswwnwnenwwwnwww +seseneenwseneneswwneseneeeweneneenw +swswwswswwswswswswwwesww +nenesenewnwsenenenenwwnenwenenenenww +wnwneseswswswswswnenewswenwswwsesesw +wwwwnwseswwswwsww +nwseenenwswweeseseneseeesewswsesene +nenewsenewwneesweneesewwnwe +wwswwewwwwseswwwweswnweesw +nesweewswsweneeneneenwne +wseseswnwesenwnewseneswenwneswseesw +nwnwwswsenweeswswnwseswsweswse +nenwnwnwnwswneneenenwswswsenwnwnenwnwsenw +wswnewwnwswwwewnwnwsenwnw +nwswneneseeseneeswwne +nwseseswswneswnewsenwseneseswseeseswsenw +enwnwnwswnwnwseneswnwswneswenwwwnesee +wnwnwwswnwnwnenwwwnwnwnwnw +nenwewnesewwswwswneswwseewnwww +nwswsweewswsesesesweswnewnewneesesw +nenwsewwwswwwwswwseswww +nwnwseneneneneneswnwnwnwneswewneneewne +weswsweseseneswsenwsenwseneneesesenwsesw +nwnwswwnwnwnwwnwwnwenw +swnwnwnwenwnwneswnwenwsenwnwnwnwnwnenw +neswnenwneenwswnesenwneesweneswwnene +neeeneneeeeeeesewweeesw +eswneneneseswseswswsesenwnwseswseseswse +seeeeneseseseseswenwnweseesw +wewewnenwnwnesweenwnwwsewswnew +seseweseseseeseneesesewswenewse +wnesewswwswwswwwwneewwwwswsewnw +nwweseswnwwsweseseeneneseeesewsese +nwswneeseewseswneeswnwwwnw +seseswwneesenwneseseeenweseseseesesw +enwnenenenweneneneneneswswnenenesene +eneswseeneseweeeeneenweenwene +swwwwwwwwswnwe +nwsesesesesesewnewseeeswsesee +nwseeseeseseeswsenweneseesweee +nweswwneswnwwnwswweswnwnwnwnwnwnewe +neneswseswenenwnweseeswseseswwnwswswne +wnwnwwwwneswewnwwwseswnenwwww +wnwenwsewwwneseswnwesweeeewse +seeseswnweseseeswswwnwswnwnwwswsee +swswswewsewswseswnwnwwswswswswnewswse +eswseneswnwsweneenw +enwnwswnwwsewwenwnwnwsenwwnwnwnwnw +eeeenesewseeeeeeseweneswwee +eswsweeneneneeeneseneneneewswnwnwe +nwwseseswsenwnwenenewwneneneenewnwnw +nwnwnwnwnwnenwnwnwnwnwnwnwnesw +wneeneswewneneenesenwnwswne +nenweswneesweeeneee +neseneswneneneseenenewenenwneneenwse +swnwswsweneswswswwnwswswswsewseseswwnew +swenwwnesenweewww +swswwwwnwswwwnwnwwswwwseewswe +seswseseswsesesesesenwsese +nenwsewnesenwnenenwnenenesenenenewseswne +nenwnwnwswnenweneenwnenwneswswswnenwesw +wswseswewneseseesenenenwnewswseseswswsw +nesewseseseseseseeseseseseseswenwswnwse +senweswswswseswseswseweeswswwse +wwweesewnwnwswswswswswwwnenwwww +nwswseneenwswswwnwsweseswswswwswswsw +weswneneswneenenesenesewnenenwnenwsesw +neneenenenenenenenwswneneneneeswne +eeenwseseeeeeswseweeenwneeee +swswswswswswwsweswswnwswwenwswswsw +senwnwswswswswewnesenewwswnwwwswsw +nenenwneswnenwnwwnesenenewnenwnenwesese +wwsewnewswnweswsesenwnwnwnwsweswe +nwnenwnwsenwnwnwnwnwwnwseswwnwwnenwewnw +seswswnenweeswnwnwnwswswswneswse +nenesenweeseeneneswneenweweeswene +enesweneeneewneswwnenewneenwnw +swseseswsesenweswnwnwnesenw +nwsenwwnwnwneenwwwnwwwwwnww +seeseneswseswswswsesewswswseswsenewwse +swnenenenwewnenwsenwsenwnwnwnwnw +ewwwswnenwswnwwsenwewneenwwnwwse +swneenweeeneenweeeeeswnweeswnwse +sweeeeseenweeeeeenwwee +weswwwwwnesewwwswwswswwnw +swswswswswswnwswswswswswswswe +wnwnwnenwswnwsenwsenwwnwnwnwwnenwswe +swwwswwwnwnwnweswnwwwenwnwenewne +eenwesesewseenw +neeeseseeenwenwsweeseeeeewe +swnesenwnesenwnwnenwnenewswseenenenwnw +enwwneenwneswnwsenenwnwwnwnwnwnwnw +swswnwnweenwswwneneeswnwnwnewnwwswsene +neswwswsenenwwnwneesesenwnwswweswnee +seswsesesenewneswsese +seneswnenwswswnwneeneswnenwwnesenenww +sesesesesenewewseeseene +eseeewneeneeeeweeneswnweneneswe +neswswswswswseeswswnwwswsweswwsw +wnenwswsewenwnwswwnwenwswwnwnwee +seseneswsewswseseswnesesesesesenwswsese +enewswswnwsewnweswswneswwewwwneswse +seseseswnwnwnwnwnwnwnenwnenwnwnewwnwnwnw +neswnenwwneswswswew +seseenwneneneweseeenwnenewswwwneew +swswswneswswwnwswsweeswswseswseswnwseswne +nenenwwneswswenwnwnenenwnenewnesenenw +enwwneneeeneenenenewsesenewsenenenesw +swseseseseseseseseswnwsesese +swnwnwewsesewenesenwswew +eesenwnwenesweswweeswswsenwnwse +nwwneseseseneneswwswseswswsewswneswsenw +sweseswnwswnwswswswswswswsenwswswesweswsw +seneswneneenwnewnwwseswnewene +wnwnesewnenenwseswnwnenwneenenenenenee +seseeseneswswseseseeenwsenenwsesesee diff --git a/2020/samples/24.txt b/2020/samples/24.txt new file mode 100644 index 0000000..3dc2f67 --- /dev/null +++ b/2020/samples/24.txt @@ -0,0 +1,20 @@ +sesenwnenenewseeswwswswwnenewsewsw +neeenesenwnwwswnenewnwwsewnenwseswesw +seswneswswsenwwnwse +nwnwneseeswswnenewneswwnewseswneseene +swweswneswnenwsewnwneneseenw +eesenwseswswnenwswnwnwsewwnwsene +sewnenenenesenwsewnenwwwse +wenwwweseeeweswwwnwwe +wsweesenenewnwwnwsenewsenwwsesesenwne +neeswseenwwswnwswswnw +nenwswwsewswnenenewsenwsenwnesesenew +enewnwewneswsewnwswenweswnenwsenwsw +sweneswneswneneenwnewenewwneswswnese +swwesenesewenwneswnwwneseswwne +enesenwswwswneneswsenwnewswseenwsese +wnwnesenesenenwwnenwsewesewsesesew +nenewswnwewswnenesenwnesewesw +eneswnwswnwsenenwnwnwwseeswneewsenese +neswnwewnwnwseenwseesewsenwsweewe +wseweeenwnesenwwwswnew diff --git a/2020/src/day24.rs b/2020/src/day24.rs index 0c4b22d..0f84a5f 100644 --- a/2020/src/day24.rs +++ b/2020/src/day24.rs @@ -1,12 +1,139 @@ +use std::collections::HashMap; +use std::collections::HashSet; use std::io::Read; +use std::mem::swap; +use crate::common::Lines; use crate::Solution; +type Pos = (i32, i32); + +const DIRECTIONS: [Pos; 6] = [(-2, 0), (2, 0), (-1, -1), (-1, 1), (1, -1), (1, 1)]; + +fn convert_pos(s: &str) -> Pos { + let mut s = s.chars(); + + let mut x = 0; + let mut y = 0; + + while let Some(c) = s.next() { + match c { + 'e' => x += 2, + 'w' => x -= 2, + 'n' | 's' => { + if c == 'n' { + y += 1; + } else { + y -= 1; + } + + match s.next() { + Some('e') => x += 1, + Some('w') => x -= 1, + _ => panic!(), + } + } + _ => panic!(), + } + } + + (x, y) +} + +fn step(current: &HashSet, target: &mut HashSet) { + let mut black_count: HashMap = current.iter().map(|&pos| (pos, 0)).collect(); + + for &(x, y) in current { + for &(dx, dy) in &DIRECTIONS { + let pos = (x + dx, y + dy); + + *black_count.entry(pos).or_default() += 1; + } + } + + target.clear(); + + for (pos, neighbours) in black_count { + let is_black = current.contains(&pos); + + let going_black = match neighbours { + 1 | 2 if is_black => true, + 2 if !is_black => true, + _ => false, + }; + + if going_black { + target.insert(pos); + } + } +} + +fn get_black_tiles(input: &mut dyn Read) -> HashSet { + let mut black = HashSet::new(); + + for line in Lines::new(input) { + let pos = convert_pos(&line); + + if !black.insert(pos) { + black.remove(&pos); + } + } + + black +} + #[derive(Default)] pub struct Day24; impl Solution for Day24 { - fn part1(&mut self, _input: &mut dyn Read) -> String { - todo!() + fn part1(&mut self, input: &mut dyn Read) -> String { + get_black_tiles(input).len().to_string() + } + + fn part2(&mut self, input: &mut dyn Read) -> String { + let mut state = get_black_tiles(input); + let mut scratch_pad = state.clone(); + + for _ in 0..100 { + step(&state, &mut scratch_pad); + swap(&mut state, &mut scratch_pad); + } + + state.len().to_string() + } +} + +#[cfg(test)] +mod tests { + use crate::test_implementation; + + use super::*; + + const SAMPLE: &[u8] = include_bytes!("../samples/24.txt"); + + #[test] + fn test_convert_pos() { + assert_eq!((1, -1), convert_pos("esew")); + assert_eq!((0, 0), convert_pos("nwwswee")); + } + + #[test] + fn test_step() { + let state = get_black_tiles(&mut SAMPLE.clone()); + let mut target = state.clone(); + + step(&state, &mut target); + + assert_eq!(15, target.len()); + } + + #[test] + fn sample_part1() { + test_implementation!(Day24, 1, SAMPLE, 10); + } + + #[test] + fn sample_part2() { + test_implementation!(Day24, 2, SAMPLE, 2208); } }