diff --git a/input/year2016/day02.txt b/input/year2016/day02.txt new file mode 100644 index 0000000..870e70b --- /dev/null +++ b/input/year2016/day02.txt @@ -0,0 +1,5 @@ +RLRDDRLLDLRLUDDULLDRUUULDDLRLUDDDLDRRDUDDDLLURDDDLDDDRDURUDRDRRULUUDUDDRRRLRRRRRLRULRLLRULDRUUDRLRRURDDRLRULDLDULLLRULURRUULLRLLDDDDLLDURRUDLDLURDRDRDLUUUDDRDUUDDULLUURRDRLDDULURRRUDLLULULDLLURURUDRRRRUDRLRDLRRLDDRDDLULDLLLURURDUDRRRRUULURLRDULDRLUDRRUDDUULDURUDLDDURRRDLULLUUDRLLDUUDLDRUDDRLLLLLLDUDUDDLRDLRRDRUDDRRRLLRRDLLRLDDURUURRRDDLDUULLDLDLRURDLLLDDRUUDRUDDDDULRLLDUULRUULLLULURRRLLULDLDUDLDLURUDUDULLDLLUUDRRDRLUURURURURDLURUUDLDRLUDDUUDULDULULLLDLDDULLULLDULRRDRULLURRRULLDDDULULURLRDURLLURUDDULLRUDLRURURRDRDUULDRUUDURDURDDLRDUUULDUUDRDURURDRRRURLLDDLLLURURULULUDLRDLDRDRURLRLULRDLU +UDLDURRULDRDDLDUULUDLDUULUURDDRUDRURRRUDRURLLDDRURLDLRDUUURDLLULURDDUDDDRRRURLLDLDLULRDULRLULDLUUDLLRLDLRUUULDDUURDLDDRRDLURLDUDDRURDRRURDURRRLUULURDDLRDLDRRRLDUDRLRLLRLDDUULDURUUULLLRRRRRRRDRRRDRLUULDLDDLULDRDUDLLUDRRUDRUUDULRLUURDDDDRRUUDLURULLLURDULUURDRDDURULRUDRRDLRDUUUUUDDDRDRDDRUDRDDDRLRUUDRDRDDDLUDRDRLDRDDRULURDRLDRUDUDRUULRLLUDRDRLLLLDUDRRLLURDLLLDRRUDDUDRLRLDUDRLURRUUULURDDRUURRLDRLRRRUUDLULDDDRDLDUUURLLUULDDRRUDLDDRUDUDUURURDDRDULLLLLULRRRDLRRRDDDLURDDDDLUULLLRDDURRRRLURRLDDLRUULULRDRDDDDLDUUUUUUDRRULUUUDD +UURDRRUDLURRDDDLUDLRDURUDURDLLLLRDLRLRDDRDRDUUULRDLLDLULULRDUDDRRUUDURULDLUDLRDRUDLDDULLLDDRDLLDULLLURLLRDDLDRDULRRDDULRDURLLRUDRLRRLUDURLDRDLDLRLLLURLRRURDLDURDLUDULRDULLLDRDDRDLDRDULUULURDRRRLDRRUULULLDDRRLDLRUURLRUURLURRLLULUUULRLLDDUDDLRLDUURURUDLRDLURRLLURUDLDLLUDDUULUUUDDDURDLRRDDDLDRUDRLRURUUDULDDLUUDDULLDDRRDDRRRUDUDUDLDLURLDRDLLLLDURDURLRLLLUUDLRRRRUDUDDLDLRUURRLRRLUURRLUDUDRRRRRRRLDUDDRUDDLUDLRDDDRLDUULDRDRRDLDRURDLDRULRLRLUDRDLRRUURUUUUDLDUUULLLRRRRRDLRRURDDLLLLUULDLLRULLUDLLDLLUDLRLRRLRURDDRRL +URDRDLLRDDDLLLDDLURLRURUURRRLUURURDURRLLUDURRLRLDLUURDLULRRDRUDDLULDLDRLDLRLRRLLLDDDUDDDLRURURRLLDRRRURUDLRDDLLDULDDLDRLUUUDRRRULDUULRDDDLRRLLURDDURLULRDUDURRLLDLLRLDUDDRRDDLRLLLDUDRLUURRLLDULRLDLUUUUUDULUDLULUDDUURRURLDLDRRLDLRRUDUDRRDLDUDDLULLDLLRDRURDRDRRLDDDDRDDRLLDDDLLUDRURLURDRRRRRUDDDUDUDDRDUUDRRUDUDRLULDDURULUURUUUURDRULRLRULLDDRRRUULRRRRURUDLDLRDLLDRLURLRUULLURDUDULRRURLRLLRRLLLURULRRRLDDUULLUUULRRDRULUUUUDRDRRDLRURLRLLRLRRRDRDRLDLUURUURULLDLULRRLRRDRULRRLLLDDURULLDLDLDLUUURDLDLUUDULRLLUDDRRDLLDLDLDURLUURRDDRRURDRLUDRLUUUDLDULDLUDRLDUDDLLRUDULLLLLDRRLLUULLUUURRDDUURDLLRDDLRLLU +LDUDRRDLUUDDRLLUUULURLDUDLUDLRLDRURLULRLLDDLRRUUUDDDDRDULDDUUDLRUULDRULLRDRUDDURLDUUURRUDUDRDRDURRDLURRRDRLDLRRRLLLRLURUURRDLLRDLDDLLRDUDDRDUULRULRRURLUDDUDDDUULLUURDULDULLLLRUUUDDRRRLDDDLDLRRDRDRDLUULRLULDRULDLRDRRUDULUDLLUDUULRDLRRUUDDLLDUDDRULURRLULDLDRRULDDRUUDDLURDLRDRLULRRLURRULDUURDLUDLLDRLDULLULDLLRDRDLLLUDLRULLRLDRDDDLDDDLRULDLULLRUUURRLLDUURRLRLDUUULDUURDURRULULRUUURULLLRULLURDDLDRLLRDULLUDLDRRRLLLLDUULRRLDURDURDULULDUURLDUDRLRURRDLUUULURRUDRUUUDRUR \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index cf72e57..9fb52a6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,4 +6,5 @@ pub mod util { pub mod year2016 { pub mod day01; + pub mod day02; } diff --git a/src/main.rs b/src/main.rs index f549069..1ad167c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -65,5 +65,5 @@ fn solutions() -> impl Iterator { } fn year2016() -> Vec { - vec![solution!(year2016, day01)] + vec![solution!(year2016, day01), solution!(year2016, day02)] } diff --git a/src/util/index.rs b/src/util/index.rs index be4c3bb..736f18f 100644 --- a/src/util/index.rs +++ b/src/util/index.rs @@ -32,19 +32,56 @@ impl Ix2 { pub const LEFT: Ix2 = Dim([-1, 0]); pub const RIGHT: Ix2 = Dim([1, 0]); + #[inline] + pub fn x(&self) -> Ix { + self.0[0] + } + + #[inline] + pub fn y(&self) -> Ix { + self.0[1] + } + + pub fn within(&self, lower: impl Into, upper: impl Into) -> bool { + let lower = lower.into(); + let upper = upper.into(); + + self.x() >= lower.x() + && self.x() <= upper.x() + && self.y() >= lower.y() + && self.y() <= upper.y() + } + #[inline] pub fn clockwise(self) -> Self { - Dim([-self.0[1], self.0[0]]) + Dim([-self.y(), self.x()]) } #[inline] pub fn counter_clockwise(self) -> Self { - Dim([self.0[1], -self.0[0]]) + Dim([self.y(), -self.x()]) } pub fn manhatten(&self, other: Ix2) -> i64 { (self.0[0] - other.0[0]).abs() + (self.0[1] - other.0[1]).abs() } + + pub fn linearize(&self, width: usize, height: usize) -> usize { + self.y() as usize * height + (width - 1) + } +} + +impl From for Ix2 { + #[inline] + fn from(value: u8) -> Self { + match value { + b'U' | b'^' => Ix2::UP, + b'D' | b'v' => Ix2::DOWN, + b'L' | b'<' => Ix2::LEFT, + b'R' | b'>' => Ix2::RIGHT, + _ => panic!(""), + } + } } impl std::ops::Add for Ix2 { diff --git a/src/year2016/day02.rs b/src/year2016/day02.rs new file mode 100644 index 0000000..25739bd --- /dev/null +++ b/src/year2016/day02.rs @@ -0,0 +1,96 @@ +use crate::util::index::Ix2; + +fn solve( + input: &str, + mut start: Ix2, + within_fn: fn(&Ix2) -> bool, + lookup_fn: fn(&Ix2) -> char, +) -> String { + input + .lines() + .fold(Vec::new(), |mut acc, line| { + for dir in line.bytes() { + let newpos = start + dir.into(); + if (within_fn)(&newpos) { + start = newpos; + } + } + acc.push((lookup_fn)(&start).to_string()); + acc + }) + .join("") +} + +pub fn part1(input: &str) -> impl std::fmt::Display { + #[inline] + #[rustfmt::skip] + fn within(coord: &Ix2) -> bool { + [ + [0, 0], [1, 0], [2, 0], + [0, 1], [1, 1], [2, 1], + [0, 2], [1, 2], [2, 2] + ].contains(&coord.0) + } + + #[inline] + fn lookup(coord: &Ix2) -> char { + match coord.0 { + [0, 0] => '7', + [1, 0] => '8', + [2, 0] => '9', + [0, 1] => '4', + [1, 1] => '5', + [2, 1] => '6', + [0, 2] => '1', + [1, 2] => '2', + [2, 2] => '3', + _ => unreachable!(""), + } + } + solve(input, [0, 2].into(), within, lookup) +} + +pub fn part2(input: &str) -> impl std::fmt::Display { + #[inline] + #[rustfmt::skip] + fn within(coord: &Ix2) -> bool { + [ + [2, 0], + [1, 1], [2, 1], [3, 1], + [0, 2], [1, 2], [2, 2], [3, 2], [4, 2], + [1, 3], [2, 3], [3, 3], + [2, 4], + ].contains(&coord.0) + } + + #[inline] + fn lookup(coord: &Ix2) -> char { + match coord.0 { + [2, 0] => 'D', + [1, 1] => 'A', + [2, 1] => 'B', + [3, 1] => 'C', + [0, 2] => '5', + [1, 2] => '6', + [2, 2] => '7', + [3, 2] => '8', + [4, 2] => '9', + [1, 3] => '2', + [2, 3] => '3', + [3, 3] => '4', + [2, 4] => '1', + _ => unreachable!(""), + } + } + solve(input, [0, 2].into(), within, lookup) +} + +#[test] +fn test_part1() { + assert_eq!("1985", part1("ULL\nRRDDD\nLURDL\nUUUUD").to_string()) +} + +#[test] +fn test_part2() { + assert_eq!("5DB3", part2("ULL\nRRDDD\nLURDL\nUUUUD").to_string()) +}