From 3b79d867c60baa29b590ee40d6f91f0b14f29578 Mon Sep 17 00:00:00 2001 From: Adam Wick Date: Thu, 24 Dec 2020 11:40:32 -0800 Subject: [PATCH] Day 24! --- inputs/day24.txt | 406 ++++++++++++++++++++++++++++++++++++++++ inputs/day24_test.txt | 20 ++ src/bin/lobby_layout.rs | 286 ++++++++++++++++++++++++++++ src/errors.rs | 14 ++ 4 files changed, 726 insertions(+) create mode 100644 inputs/day24.txt create mode 100644 inputs/day24_test.txt create mode 100644 src/bin/lobby_layout.rs diff --git a/inputs/day24.txt b/inputs/day24.txt new file mode 100644 index 0000000..f462ece --- /dev/null +++ b/inputs/day24.txt @@ -0,0 +1,406 @@ +neneeenenesweneswneesewenenwneew +eswswenweeseneseswwsenewsenw +seeweswwneswnwwwenwwwwwnenwwsesw +swsweseseseswswsenwswseswswsese +eseseseswsenweseseneseswnwneeewww +sweeeeeenweseenesweee +nwnwsewenwwnwnwsenwwnwseswnwnw +swswswwwswweswswswswswenenesesewwwe +swnwenenesenwsewswswseeeswnwwnewwsese +senwweewnwweswnenwwsw +ewneswswsweenwwnwsenwswnewsenwnwsw +nenenwwneenwnwnwwnesewsenenwnwnenwnw +nwnwwsenwwnwnwnwnwwnwnwewwnw +wnwnwnwnwseswwnwnwesewsenwnwnwnwnenew +seswewwneweswnwnwswwsw +neswesenenenewwswnenwnenenenwnenenenese +nwwswsenwnenwnesenwnwsenwnwnwwnwsenenwse +senwswwswwnweswswneswswwswnweswseswew +neeeeswnweswseeeeeneeeeenwwnene +nwnewnwnwnwswnewwsewnwwseenenwnww +eeseeeeeswneenwewee +neseseseeenwwseseeseneswnenwsewswse +wswswnwnwwswswneswwweeswswswwww +swnwnwneswswseswseswswswswswnwseswsesenesw +swneesenwnwnwwnwnwnenwnwnwnwnewnwsese +wswswswewnewnewsenewnwswseswswwse +swenwnwnwnenwnenwnwswnenenwswwnenwsenw +ewnenwnwweenwneesewnwwwwnwswse +eeewnweneneeesweesweeeneeee +nenwnwnwnwswwnwsewnwswswenwweswenw +senenenenenenwneneewnenenene +neneeneswnesewneneneeneneeenenenwe +nwswenwseswnwswenwnwnewnwneww +wnewwwweswwsww +seseswsewesesenesesewseewseseenenwe +neneseswnesenewwenenwneneneneneenew +swswswswwsweswseswsewwneswswswswneswswsw +sesenesesesenwsesesesenwsewnw +nenenenenenewnwswnwnenwsenesenwneswwne +swwnewweewwwwnwswnewwweswew +swnwwswesenewwwswwswwweseswswnesw +weeseseseneseseewwseseseseseseesese +nwenenenwwnenenenenwneneneseswnenwenesw +nwsewswswwswsweswnwwwnwswswsew +nwewnwwwewnwwnwnwwnwswwnwwsewnw +eesesesesesesewseseewneseesesesesenw +nwwenwweswnwswenwnw +sewseswswneneswnwenwneeswwnwwesenw +eseswwnwnwwenewneswnwsweenwseswne +wsewwswnwnwewnewswwwwswseswnew +eswnenwnwnenwswnenwnwnwnenwnwnwnenwsewne +neneewswnenenenenene +nwseeseseesesesesesesese +eenweneeeswswseeseeneesese +sewneeneneswseeewnwswsenewswenwwenw +nwwwweswnenwsenwwswnwwnwwwnwwnew +nwewwneswnwwwnwswswsesweswswwseww +neseswseweseeswsenwsesesesesw +nwswswseswswseeswswseswnewneseswswwsw +eweseeswseeeeseneenwenweeee +nesewwwwneeseweswwseneeseseswseswsw +nwswnwnewnewneeenwneeswwnwse +swwnwsesewneneeneenwseswseswnww +nwnwnwnwsenwnwnwnwnwnwnwnw +wwnewnwsesewwwwwwnwseewsenenew +swswswswenwswseswsweeswnwswswswswswswswnw +nwnwseeswnwnwswnenwwnwnewnwnwwnwnw +wnenenesesenwnwwnwsenenesewnewnenee +senwswnwnwwenenwnenwnenesewswenewnene +neseseeseneswswswswswwwswswnwswwsenesw +neswwsesenwnwnwneswseseseseswnesenwsese +eeweesenesweenweeneenwneeswse +wwnewswsenwnwsesenwswseneeswswseswnese +wnwsewnwnwnenwnwnwnwwnwnwwww +wwswswewwwwwwswwwwnewnwnenw +eeneseswswnewneneneenenenenenenenew +wswwnwswwswneneneswnwnwnwswseneneswsenene +nwswswewswsewswsewswsenweswswneswnwsw +wwwwesewnwnewwwnewwwwsese +nwnesenwnwnwnwswswnwwswwnwnwwwwneeenw +swseseswenwswswnwswwnenesenesesesesesese +nesewswswswsewswswnwswwswwswsw +wnwwwnwnwnwnwsewsenwsewwwwwww +wwwwwwwwswwswwwewwnw +swseseseseeswsesesenwseseswseswwsenwse +sweeeseeswnwenwneeenwneswenwneee +nwswseswswswswwsweswnesesweswswswseswse +nwnwenwnwnwnwnwswnwwnwnwwnenw +wseewnwnwnwenewnenenesenewnenwnenwne +nwsweswswswswswswswswsw +swswwswwswswswswnenewenwewweswnw +nwseeswnwnwseseseswneseswseseseenewsw +wseswseseesenweeeseeeewnwenene +newnenenwswnwnenenwneneseneneneenenesenw +wnwnwswseenwnwnwnwenwwwnwnenwnwswne +esesesesewneseswswsewswseswswneswsesesw +wsewwwnewswwnenenwnwwnwwnwnwwwsew +wsenwenwnwnwewwsesenwwwwnwnwnwnew +nwnwnenesenenenwnenewnenenwneneswswnene +eseneneewneneneeneeneneee +nenenenwnwseswswnwwnwnwwesenwsenewswne +neenwnwnenenwnwnwwnwnenwnwnwwnwswsenw +swwwswwswswwnwwwnenwseswswwseswsenw +nwsewneswnwesweeswnwwwnweswnwne +neswsewswseswseswswswneswseswneseseswsww +wsewwwnwnenwnwewwseenwwwwswnw +neseseswseswwswswswnenwsesewswswswswsw +swwsweswneseswswwswswswswweswwsw +nenwneneswneeneenene +eneweneseneeneeswswswenenesenenew +swseeseswswesenwsesenwswnwnwseeesenwswsw +nenenwnenwwwnenenweneneneseneswnenenene +neneenenwswswseswwwnweswnenesesewnewse +neneseneneseneenenenewswneeenenewnene +swsweesenesenenenwnwnwswsweneseenww +swnewwnwsewseswewsewsesenwneewnww +enenewnenenenwnenenenw +seseesesewwseseseseseswswseesesenese +eeenwneeeewneneeeeewswneneee +eswnwenweesenwseeswsweenwsenwnwesw +eesweeeneneeneeeeewnweeewe +seswswseseswswswsene +newswnewswwwneswwwse +neeswnenwewnwnesewsweneeswnwenesww +eswwwwwwswnesewwwnewwnwwww +ewsesenwseswsesenwsesesewesenwsenenese +nenwnewswneneneneeeneneseneneneenee +wwseseeeenwnwweseneewnweeeewsw +nwneswnwnwnwwwnwseenwnwnwenenwnw +swswswswswneswenwwweswswsw +swenwwwnwnewswnenwneswnwesweswwe +neswseenwseseeenwsesesew +seseeesesenwnwseeseseseswnesese +sweeeseseenwseeweesee +swneswsweswnewwswseswswsw +nwwwewsewwwwwwwwewswswnewsw +nenenewneswsenenenenesenenenenenenenwneenw +sewwwnesewswwnwwwwswewswwswew +swswseswnwnwswswswswswswnwseswenwseswswsw +nwnwnwnwnwnwnwnwnenwnwsenw +nenwwewnwwsewnewwnwsewwwewseswe +seseseswweewnwneneseseseesewsesesw +swswesenewswswswwewswsesweswsw +seseneneswwsewneeenwenenwseenwsee +nenwenwwneewnwneswnwnenwseswnwenwnwnw +sweswswswseswswswseseswseswwnesesesenw +nweeesweeeeneseeseeenwenwwe +sweewneneeeseeewswneeenwneenene +swsewseseenwsenesewseseseswswseswnese +wwwswseseswwnwwnwnenenwwswnwsenesene +seswswswseeseswseseseswnwsenwseswswsesene +nenwesenwswneneseeewsesesweeseeswse +nwseswswnwseeswnwswsenwnwnenwnenwnwnenwnw +neswnenwweesenwneswwneneswnwenenesw +nwneswnesesenwswenwsesewewsweewsw +neseeenenenewnenenweswew +eenweesweewneneseneeswee +weesenwsweenenenwswenenwneswenee +nwswswsweseswwsweswswswswnwswswswswsw +esweweseeeeseneeenweeeeee +swneswswswwswnenwewswenwswswwnew +eesweswnwseeeeeeeeneseeenwsee +senwwswnwnwnwnwnwnenwnwnwnwnwwnenenwnese +swwseeswswnwnenesewnenwsenweeeene +enenwnesenenenenwnenewneneneewswswwne +nwwneseseeseeseeseseeseseeseswnwsese +sewwswsewnwwswnwnwnewenweneswesw +eneeneeneeneewneeeeeeenwsesw +wwenwwnesenwnwnwwww +nwneneswnesenenenenwnwnenenenwnene +sweneseseswewnwswwneneneneseneesenwnw +nwewenwnwwwnwnenwsesenwnenesenwnwwwnw +nwenwnwswsenwnwnwnenwnwnwnwnwwesenenw +swswwnewweweswswnwswsenesewwwnww +nenewneswnenenweenenenwswsenene +swswswwswswswswswswswswswne +eeswswenwswneenwenweseenwnweeese +swnwnwnwwwsewnwnenwwwnww +wswwwenenwwwweswseswnwswweswsw +enewneneweseeswswenewnenwwnesene +swsenesweswswswswwswswswseseseswwsw +nwwseswnwsenwsenenwwnwnwneewwwwww +wwsesesenwnwnenesenwenenwswneneenesw +seseneweseeswseseneeseseesenwesese +nwnwwswwwweenwwnwwswsewwneww +eneneneeneswnenweneswenewneeseenenew +eseewneesenewesenwsewewwwsee +nwnwnwenenenwenwnwnwsenwnwnwswnewnenwne +neseeeesewneseseweeseseswseseesese +newwnwswwewneswseewsesweswneswwse +seseseseseeseenwseeenwsesesesese +eseswnesewseswswswsenwwswseswneswsee +eeseseseneeeeeseeeseeew +nwesweeneenwnwseneeeneeeneneneswse +swswswswseseswnwneswswseswsewse +senwnweswwnwwnwweseenwswsenwnwwse +wneneneenenesenewnwswswenwnene +eswseswneseseneseseeeeeewsenenwnew +sewseeeeenwseese +sesenwnwseseseswseseswswswseesenesesesenwse +nwwneewseswneeeneneneseenenwewneese +wwwswwnewwneswwwwwsewwwsw +seswwwwneswneswwneswswswswswseww +eewneenwsweseseweeeeneneneneesw +swswsewswswwswswnewwswsww +nwnwwswnenwwnwnenwswnwnwwsenwseeswwnw +swswsenwnewseeswseseneneswsewnwsesesenwsw +senwnwnwnwswneswnwenwnwwnesweswswnwnenw +neenenewswnwswnwsewwewswsenwnwwsw +senwnewnewnwwnwwnwseseswwnw +seeseseeneswneeswnenwwswswwswnwswwe +seswenweeneeneneneeneneneee +nwwnwwenwwwwwwwnw +swswswswwswwswwswsenenwsewnewneswswne +newswnwnwswnwenwwnenwnwnwwwwsewnwnw +eneewenweeeweeseenwseneeeswse +seseseswenwseseweseseenwnee +wnwwnenwswnwnwweeeswsw +senesesenwswseseseenwseswseswswseswsesw +seseseseseseseseseseseseenwsese +seenwnwnwswsewweeweseeneesewswene +wwwseswsesenwnwnenenwse +nwwewnwnwwneswnwwnwnwnwwnwewswne +neewneneseneneswnene +wswwswnwwwswwwewswswsww +wswwneswwswnwwnwnewseswsewswenwsw +ewnwwwwswwnwesweswswwsw +wswnwnwwnenwnewwsesewwseenewswenew +wswwnenwwswnenenwnenenenenweswseseswe +nesesenwswsweeswewwswneeneeeee +nwswwwnewwwwwwneewnwsewsewsew +nwwweswwswwwnwneswnwswenwnwneew +nwnwswnwswenenenwnwwnwnenwnenenweew +neswnwneseeneneenewswwnwnweseneene +nwswswwwwseeswnwswwsweswwnwseswww +neneseneswsesewenwseswneneswnenwwenew +neneneeneneneseneeneseneww +sweenenwenweeenesweeeenwesee +seseseseseseneesesesesesesesew +senesweewneeswenwseswseseeeesee +nesesenwwswnwnwwnewsenenwswnwnenwsee +neseewnwenenwwnewnenwnwsenwnwswswnwnw +eswnenenwswnewsweseswseewsesenwsee +enweeswenwewsweeeneenweeseesee +senwswswwswwswswwswswswswseswswswneswne +sweswwnwewseneeeenenewenweee +newnenwnwswwseseseesenwsese +enweeswseenwneeenenesweeneswenewsw +nwnwnwnwnwswenwnwnwnwnwnweswnwnwnwnwnw +nenenenweneswnesenwneswneneneneeneese +seseeenwswnweeeewswseeeswwnwsenw +esenwsewseseesewneseeseseseeeenese +seewnwsesesenwesesesesewneeeseee +eneseneewneneseweeneneeeneeee +nwwnwenwswsenwnwnwnwnwwnwswwnwnwnwnew +wnewwwwwwnwwwswnwww +wnwenwsenwswnwnwnwwnenwnwnw +eeneneswnwwneneswnwneeeneneneneewne +wsewnwwwwewwwwwwwsenwwnwwe +wwwseeseswsewsewewneswnwsewnenenw +seseneswsewneswswseswseswswswseneswsesesw +nwnwnwsenenweeneneeneswswneswneseeesw +eswseswwnwswseswswswswneenwswseswsese +eenewseneeeseneneeswwneeeenenee +nweeeeseeeseeseeswenwnenweswee +swswwneneneswenenwsenenenenenwnenwnwe +nwenwnwnwseswnwnwnwnwnwnwsenwnwnwnwnwnwnw +eswnwnweswsweseseswwswswnwseneswnenwswe +wnesewneswwneswwwwnwwwwsese +nwnenwnenenenenenenwneswnenwnenw +neswenenwswneneswnwee +wwnwwwwewwnwswnesewww +esenwnwswenenwnewswneswwenwswwnwswnww +swswwswnenwwswswnwseswswswwswswewsesw +nenwsenewnwswswneeswnwnenwnwnweenwnwne +neswwnwwwnwwwnenenwnwswwnwsenwnww +neneeneswenenenenenenee +swseweseneeeswwnenwswnwnwe +eewswweneweeneneeenenenenenenene +nwnwneneneneseneseswnenwnenwnwnenwnenene +enwnwenenwswswswnwsenwswswseswseenwe +eneneneneeeswneneenenenene +enwnenwwwsenwwwswneswnwwenwewww +neneneswnenewneneneeenwnenwnesewnene +seswsenwsesesenwewseswseseseseswsesenenwse +neneenewsesewneweeewseseenwneeene +nwwswwwsesenwwwsenewwnwnew +seseenesesesesesesesewesesee +nwwnwswswswseswwswseneswswswswswswswswe +wswwnwnwnwnwnwnwwnwnenwnwenwnwenwnw +seseswseneeswneswnewwswwwnwneesenene +nenwnwnwnenwnwnwnenwsenwnwnwnw +eswwwwwsewwnewswswwwswswneswww +esenwnwnweeewswneneswnwswnwswnenwnwnene +nenweseenwneenenwseeeneseene +newnwwsenwnwenwwwnwsewswnwnwenwww +newenenenenenenwenwswswswsene +nwsweswnwwnwewewwwenwwwwwnwwnw +sewnwsewwnwsenenwwww +swswnenwnwnewneswnewnweswsweswenwsenwse +wsweseeswnwseenewseneenee +eeeeeseeswnweeeenwseseewsese +sesesesenewsesesewesesesenwseseseene +sesewswseswsewseseseswweseeseseenese +esenwswwseseseseesesesenweseseseswe +nwnenenwnenwnwnenenesw +nwnenweneenwnenwnwnwswnenwneneswnenwnw +sewswswswswswnwswneeseswswswsw +swwswswswwwwneswneswwswswswnweswsw +neseswswesesewswwswswseswswnwseswnenese +nwswnwneewneweeseeseewewneneew +swseenenwwsenwnwnewneenwwewnwswe +swsweseswswswwwwswswswnewswsw +swnwwneneswswnwewwnwsenwenwnenwee +ewswseseneesewseneswsenwswseseswsese +eneeneeseswenwsewneeweenwnwese +swnwswswseswswswseseeswnwswswsweswnwsww +wwnwnwswnwsewwnwwnwwnwwnwsenwnee +eeseeeswneseneseeweneweseee +senesenwsesenwwsesesesesesesesesesesese +nwnewesewneswneeeeneeneeswnesenene +wesenwseswsweweenwnenwwnesese +nenwnwneeswneneeneneneswneneswneneenwnee +nwnwwsenwwnwnwwnwsenwnwenwnwnwwnwne +nwnwsenwnwsenwnwnwnenwnwwnesenwnwenwne +sewswweneesenenwneseswseswnweeeene +nwswnwnwnwnwwsenwnwwnwnwenwnwesenwnw +wwwwwwnenwwwwnesewwwse +swnenenenenenenwneneswnwneesenwnenewne +neneneswneneeneneneene +wswneseswswnewwnewswwwwwwwswsww +neeneseewnenwnwneseewneenenwwnenesww +enwseswseesesewnesweeeeneswsesenese +nwnwswnenenenwnwnwnenene +wswswswneswneswwswswsweseswswseswseswsw +sewseseesesweseneseseseseseswnwwsw +swseswswwnesenewnwwnweenweswwsenw +seseseswswseseseeseesesesesenwnwsesese +nenewnenwneswnwnese +seseneswseswswseseswswseswnwwswse +nwneeeeseseneseseeseeeeeeeeww +nwnwneenwswswnenwnenwnenwwneneenenwnwnw +nwnwenwnwnwsenwnwenwnwwnwnwnwswnwnwnw +wwnwwenesesewwwnewsesewnewwwe +wnwnwwwewnwseswwwwwnewnwswnwe +nwwwwswnesewwsewsenewnwnwsewnwnww +nweeeenwseeeseee +eneenewnwenewnwsesenewewswenenese +eswwsweswseswnwsenewnenwswseswwww +neswnesenenenwnenwenenwnwneneswneswnwne +enwseswnwnweesewnwseeseseeseseseseesw +wenwwwswnewswsesewwnwwnwnenewnw +nwwseseswswewwswwsewneswnenwnwesww +swnwnwnwswenenwnwnwnwsewenenenwnenesw +weneswwswswnwsweeesenenwsenwwwsw +eeseesenesesewnweseeenesweeeeew +eseweseseseesenwwsesenese +eneneneneneneneneeenenenenenwsw +esenwnweswenenwnwswnwwnewneenewnww +eeneneneeeeswneneenwsew +seweeseesenewswsenwewwneeeeee +newnwnwenwwnenesenewsenewswnweese +neswwwswswswneww +seswseswseneswseswswnewneswswswswsenenw +eneeneeeenwswneneeswnweenwseneswnene +neswseeswseseswswsewsese +wnewwswwneswswwenewswswwwswwnene +newswseswnwnwnwnenwnwnwnwnwnesenwne +neewswseswswnwswswseneswswswswswseswsesw +nwwneenwwwwsenwwseswenwnwswwnenw +wwwenwwnwnwwnwnwnwe +esesewsesesesesesenwsenwesenwswswswee +nwsesesenweseswseseseseswsesewseseenwse +newnwnwnenwswswwwnwwwnwwnwwnenwsw +swsewsenwseseseswwseseneesweswswsese +neeenweseeeeneswneeeeweee +nwenwnwnwnenwwnwnenenwnw +wwsewwenewwwwwwwsewwwnww +neneenesweneeneenwnenwneneseseeee +eswseneseseseeeeeeeseenwsewsese +nenenwswneeswnesenenewwnenenenwenwsese +nwwwwwewwswwswwnewwwwseeww +swswswswswswswseseswneeswswseneswwswwsww +nwneneswneeswenwseenweeneneewwwnee +swswswswneswwneseswwseswswswsw +swswseswneswwwswswwswsw +nwenweseesweeeeneeseeswseeesw +swswswsweswswnewwswwwswswwwnwswse +sewneseseswsesesesesewseseswnwseneswse +enenweeswsweswenwnwe +nenenwnwnenwnenwwnwswnwnenwsenenwne +neswseneswswnwwweneswnwseswswneewnese +nenweswsweeneeneswnweeneswneswee +wsenwseseseseeseseseseseseeseneswnese +swnenwwnwnwenwnwswnwnesenesesewnwnenenw +sweneeenenwenenenweeenenwsweeeswe +sewewnesesewnenwsesesesweseswswsesesw +neswswnenwneseseneneneneneneneswnenwnene +newnewweewwwnwseswwseswwewswww +senwseseseswswnesenweseswsewswsesesewsw +senenenenenenwnwnwsewnwnwenwnwnwwnene +nwnwenenwnwwneneswneneneneenwnwnwnese +seseseseseseswwneswseswesewswseswnwse +nenwnwnenwenenweswneneswweenwneneswnwnw +swnwseswewnewnesesesesesesesee +seswnenwwwewseneswswsenweneswnenenwe diff --git a/inputs/day24_test.txt b/inputs/day24_test.txt new file mode 100644 index 0000000..55460d5 --- /dev/null +++ b/inputs/day24_test.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 \ No newline at end of file diff --git a/src/bin/lobby_layout.rs b/src/bin/lobby_layout.rs new file mode 100644 index 0000000..11e367a --- /dev/null +++ b/src/bin/lobby_layout.rs @@ -0,0 +1,286 @@ +use advent2020::errors::{DirectionParseError, MapOperationError, TopLevelError}; +use std::env; +use std::fs; + +#[derive(Debug)] +enum Direction { + East, + SouthEast, + SouthWest, + West, + NorthWest, + NorthEast, +} + +impl Direction { + fn read>( + iter: &mut I, + ) -> Result, DirectionParseError> { + match iter.next() { + None => Ok(None), + Some('e') => Ok(Some(Direction::East)), + Some('w') => Ok(Some(Direction::West)), + Some('n') => match iter.next() { + None => Err(DirectionParseError::IncompleteNorthSouthDirection), + Some('e') => Ok(Some(Direction::NorthEast)), + Some('w') => Ok(Some(Direction::NorthWest)), + Some(c) => Err(DirectionParseError::InvalidNorthSouthSuffix(c)), + }, + Some('s') => match iter.next() { + None => Err(DirectionParseError::IncompleteNorthSouthDirection), + Some('e') => Ok(Some(Direction::SouthEast)), + Some('w') => Ok(Some(Direction::SouthWest)), + Some(c) => Err(DirectionParseError::InvalidNorthSouthSuffix(c)), + }, + Some(c) => Err(DirectionParseError::InvalidBaseDirection(c)), + } + } + + fn adjust_coord( + &self, + x: &mut usize, + y: &mut usize, + extent: usize, + ) -> Result<(), MapOperationError> { + let unshifted = (*y & 1) == 0; // whether this row has been "shifted left" + + match self { + Direction::East if *x + 1 == extent => return Err(MapOperationError::FellOffEdge), + Direction::East => *x += 1, + + Direction::West if *x == 0 => return Err(MapOperationError::FellOffEdge), + Direction::West => *x -= 1, + + Direction::NorthEast if unshifted && (*x + 1 == extent || *y == 0) => { + return Err(MapOperationError::FellOffEdge) + } + Direction::NorthEast if unshifted => { + *x += 1; + *y -= 1 + } + Direction::NorthWest if unshifted && *y == 0 => { + return Err(MapOperationError::FellOffEdge) + } + Direction::NorthWest if unshifted => *y -= 1, + + Direction::SouthEast if unshifted && (*x + 1 == extent || *y + 1 == extent) => { + return Err(MapOperationError::FellOffEdge) + } + Direction::SouthEast if unshifted => { + *x += 1; + *y += 1; + } + Direction::SouthWest if unshifted && *y + 1 == extent => { + return Err(MapOperationError::FellOffEdge) + } + Direction::SouthWest if unshifted => *y += 1, + + Direction::NorthEast if *y == 0 => return Err(MapOperationError::FellOffEdge), + Direction::NorthEast => *y -= 1, + Direction::NorthWest if *x == 0 || *y == 0 => { + return Err(MapOperationError::FellOffEdge) + } + Direction::NorthWest => { + *x -= 1; + *y -= 1; + } + + Direction::SouthEast if *y + 1 == extent => return Err(MapOperationError::FellOffEdge), + Direction::SouthEast => *y += 1, + Direction::SouthWest if *x == 0 || *y + 1 == extent => { + return Err(MapOperationError::FellOffEdge) + } + Direction::SouthWest => { + *x -= 1; + *y += 1 + } + } + Ok(()) + } +} + +fn read_directions>( + iter: &mut I, +) -> Result, DirectionParseError> { + let mut directions = Vec::new(); + + while let Some(x) = Direction::read(iter)? { + directions.push(x); + } + + Ok(directions) +} + +#[derive(Clone, Copy, Debug, PartialEq)] +enum Color { + White, + Black, +} + +impl Color { + fn flip(&mut self) { + match self { + Color::White => *self = Color::Black, + Color::Black => *self = Color::White, + } + } +} + +#[derive(Clone)] +struct Board { + edge_length: usize, + origin: (usize, usize), + raw_data: Vec, +} + +macro_rules! check_adjacent { + ($self: expr, $x: expr, $y: expr, $dir: expr, $val: ident) => { + let mut work_x = $x; + let mut work_y = $y; + + if $dir + .adjust_coord(&mut work_x, &mut work_y, $self.edge_length) + .is_ok() + && $self.get(work_x, work_y) == Color::Black + { + $val += 1; + } + }; +} + +impl Board { + fn new(edge_length: usize) -> Board { + let edge_length_squared = edge_length * edge_length; + let half_edge_length = edge_length / 2; + let origin = (half_edge_length, half_edge_length); + let raw_data = vec![Color::White; edge_length_squared]; + + Board { + edge_length, + origin, + raw_data, + } + } + + fn tile_counts(&self) -> (usize, usize) { + let mut black_count = 0; + let mut white_count = 0; + + for color in self.raw_data.iter() { + match color { + Color::White => white_count += 1, + Color::Black => black_count += 1, + } + } + + (black_count, white_count) + } + + fn flip(&mut self, directions: Vec) -> Result<(), TopLevelError> { + let (mut x, mut y) = self.origin; + + for direction in directions.iter() { + direction.adjust_coord(&mut x, &mut y, self.edge_length)?; + } + + self.raw_data[(y * self.edge_length) + x].flip(); + + Ok(()) + } + + fn get(&self, x: usize, y: usize) -> Color { + self.raw_data[(y * self.edge_length) + x] + } + + fn set(&mut self, x: usize, y: usize, v: Color) { + self.raw_data[(y * self.edge_length) + x] = v; + } + + fn adjacent_black_tiles(&self, x: usize, y: usize) -> usize { + let mut result = 0; + + check_adjacent!(self, x, y, Direction::East, result); + check_adjacent!(self, x, y, Direction::West, result); + check_adjacent!(self, x, y, Direction::NorthEast, result); + check_adjacent!(self, x, y, Direction::NorthWest, result); + check_adjacent!(self, x, y, Direction::SouthEast, result); + check_adjacent!(self, x, y, Direction::SouthWest, result); + + result + } + + fn next_day(self) -> Board { + let mut result = self.clone(); + + for x in 0..self.edge_length { + for y in 0..self.edge_length { + let black_count = self.adjacent_black_tiles(x, y); + + match self.get(x, y) { + Color::Black if black_count == 0 || black_count > 2 => { + result.set(x, y, Color::White) + } + Color::White if black_count == 2 => result.set(x, y, Color::Black), + _ => {} + } + } + } + + result + } +} + +#[test] +fn maneuvers_work() { + let mut board = Board::new(10); + + board.flip(vec![Direction::West]).unwrap(); + assert_eq!(1, board.tile_counts().0); + board.flip(vec![Direction::West]).unwrap(); + assert_eq!(0, board.tile_counts().0); + board + .flip(vec![Direction::West, Direction::West, Direction::East]) + .unwrap(); + assert_eq!(1, board.tile_counts().0); + board.flip(vec![Direction::West]).unwrap(); + assert_eq!(0, board.tile_counts().0); + board + .flip(read_directions(&mut "esew".chars()).unwrap()) + .unwrap(); + assert_eq!(1, board.tile_counts().0); + board.flip(vec![Direction::SouthEast]).unwrap(); + assert_eq!(0, board.tile_counts().0); + board + .flip(read_directions(&mut "nwwswee".chars()).unwrap()) + .unwrap(); + assert_eq!(1, board.tile_counts().0); + board.flip(vec![]).unwrap(); + assert_eq!(0, board.tile_counts().0); + board + .flip(read_directions(&mut "nwnwwswee".chars()).unwrap()) + .unwrap(); + assert_eq!(1, board.tile_counts().0); + board.flip(vec![Direction::NorthWest]).unwrap(); + assert_eq!(0, board.tile_counts().0); +} + +fn main() -> Result<(), TopLevelError> { + let filename = env::args().nth(1).expect("No file argument given."); + let contents = fs::read_to_string(filename)?; + let mut board = Board::new(250); + + for line in contents.lines() { + board.flip(read_directions(&mut line.chars())?)?; + } + + let (black_count, white_count) = board.tile_counts(); + println!("{} black tiles.", black_count); + println!("{} white tiles.", white_count); + + for i in 0..=100 { + println!("Day {}: {} black tiles", i, board.tile_counts().0); + board = board.next_day(); + } + + Ok(()) +} diff --git a/src/errors.rs b/src/errors.rs index 5b16ab7..fe4835b 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -58,6 +58,8 @@ pub enum TopLevelError { GrammarParseError(#[from] GrammarParseError), #[error("Bad tile parse: {0}")] TileParseError(#[from] TileParseError), + #[error("Error parsing directions: {0}")] + DirectionParseError(#[from] DirectionParseError), } #[derive(Error, Debug)] @@ -151,6 +153,8 @@ pub enum ExecutionError { pub enum MapOperationError { #[error("Out of bounds indexing map with ({0},{1})")] OutOfBounds(usize, usize), + #[error("Fell off the edge of the map")] + FellOffEdge, } #[derive(Error, Debug)] @@ -224,3 +228,13 @@ pub enum TileParseError { #[error("Weird start to tile: {0}")] BadTileStart(String), } + +#[derive(Error, Debug, PartialEq)] +pub enum DirectionParseError { + #[error("Invalid base for direction: {0}")] + InvalidBaseDirection(char), + #[error("Invalid suffix for north/south direction: {0}")] + InvalidNorthSouthSuffix(char), + #[error("Incomplete north/south direction")] + IncompleteNorthSouthDirection, +}