mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-25 21:00:31 +01:00
Implement day 20.
This commit is contained in:
@@ -71,8 +71,9 @@ day_bench!(day16, 16);
|
||||
day_bench!(day17, 17);
|
||||
day_bench!(day18, 18);
|
||||
day_bench!(day19, 19);
|
||||
day_bench!(day20, 20);
|
||||
|
||||
benchmark_main!(day01, day02, day03, day04, day05,
|
||||
day06, day07, day08, day09, day10,
|
||||
day11, day12, day13, day14, day15,
|
||||
day16, day17, day18, day19);
|
||||
day16, day17, day18, day19, day20);
|
||||
|
||||
1
2018/inputs/20.txt
Normal file
1
2018/inputs/20.txt
Normal file
File diff suppressed because one or more lines are too long
40
2018/loc.svg
40
2018/loc.svg
@@ -32,10 +32,10 @@ z
|
||||
<defs>
|
||||
<path d="M 0 0
|
||||
L 0 3.5
|
||||
" id="m949f39278e" style="stroke:#000000;stroke-width:0.8;"/>
|
||||
" id="me1cf09a1d9" style="stroke:#000000;stroke-width:0.8;"/>
|
||||
</defs>
|
||||
<g>
|
||||
<use style="stroke:#000000;stroke-width:0.8;" x="60.305455" xlink:href="#m949f39278e" y="307.584"/>
|
||||
<use style="stroke:#000000;stroke-width:0.8;" x="60.305455" xlink:href="#me1cf09a1d9" y="307.584"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_1">
|
||||
@@ -71,7 +71,7 @@ z
|
||||
<g id="xtick_2">
|
||||
<g id="line2d_2">
|
||||
<g>
|
||||
<use style="stroke:#000000;stroke-width:0.8;" x="127.941818" xlink:href="#m949f39278e" y="307.584"/>
|
||||
<use style="stroke:#000000;stroke-width:0.8;" x="127.941818" xlink:href="#me1cf09a1d9" y="307.584"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_2">
|
||||
@@ -110,7 +110,7 @@ z
|
||||
<g id="xtick_3">
|
||||
<g id="line2d_3">
|
||||
<g>
|
||||
<use style="stroke:#000000;stroke-width:0.8;" x="195.578182" xlink:href="#m949f39278e" y="307.584"/>
|
||||
<use style="stroke:#000000;stroke-width:0.8;" x="195.578182" xlink:href="#me1cf09a1d9" y="307.584"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_3">
|
||||
@@ -139,7 +139,7 @@ z
|
||||
<g id="xtick_4">
|
||||
<g id="line2d_4">
|
||||
<g>
|
||||
<use style="stroke:#000000;stroke-width:0.8;" x="263.214545" xlink:href="#m949f39278e" y="307.584"/>
|
||||
<use style="stroke:#000000;stroke-width:0.8;" x="263.214545" xlink:href="#me1cf09a1d9" y="307.584"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_4">
|
||||
@@ -153,7 +153,7 @@ z
|
||||
<g id="xtick_5">
|
||||
<g id="line2d_5">
|
||||
<g>
|
||||
<use style="stroke:#000000;stroke-width:0.8;" x="330.850909" xlink:href="#m949f39278e" y="307.584"/>
|
||||
<use style="stroke:#000000;stroke-width:0.8;" x="330.850909" xlink:href="#me1cf09a1d9" y="307.584"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_5">
|
||||
@@ -193,7 +193,7 @@ z
|
||||
<g id="xtick_6">
|
||||
<g id="line2d_6">
|
||||
<g>
|
||||
<use style="stroke:#000000;stroke-width:0.8;" x="398.487273" xlink:href="#m949f39278e" y="307.584"/>
|
||||
<use style="stroke:#000000;stroke-width:0.8;" x="398.487273" xlink:href="#me1cf09a1d9" y="307.584"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_6">
|
||||
@@ -286,10 +286,10 @@ z
|
||||
<defs>
|
||||
<path d="M 0 0
|
||||
L -3.5 0
|
||||
" id="med6d0249be" style="stroke:#000000;stroke-width:0.8;"/>
|
||||
" id="m480ecff4e3" style="stroke:#000000;stroke-width:0.8;"/>
|
||||
</defs>
|
||||
<g>
|
||||
<use style="stroke:#000000;stroke-width:0.8;" x="57.6" xlink:href="#med6d0249be" y="295.488"/>
|
||||
<use style="stroke:#000000;stroke-width:0.8;" x="57.6" xlink:href="#m480ecff4e3" y="295.488"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_8">
|
||||
@@ -302,7 +302,7 @@ L -3.5 0
|
||||
<g id="ytick_2">
|
||||
<g id="line2d_8">
|
||||
<g>
|
||||
<use style="stroke:#000000;stroke-width:0.8;" x="57.6" xlink:href="#med6d0249be" y="247.488"/>
|
||||
<use style="stroke:#000000;stroke-width:0.8;" x="57.6" xlink:href="#m480ecff4e3" y="247.488"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_9">
|
||||
@@ -316,7 +316,7 @@ L -3.5 0
|
||||
<g id="ytick_3">
|
||||
<g id="line2d_9">
|
||||
<g>
|
||||
<use style="stroke:#000000;stroke-width:0.8;" x="57.6" xlink:href="#med6d0249be" y="199.488"/>
|
||||
<use style="stroke:#000000;stroke-width:0.8;" x="57.6" xlink:href="#m480ecff4e3" y="199.488"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_10">
|
||||
@@ -331,7 +331,7 @@ L -3.5 0
|
||||
<g id="ytick_4">
|
||||
<g id="line2d_10">
|
||||
<g>
|
||||
<use style="stroke:#000000;stroke-width:0.8;" x="57.6" xlink:href="#med6d0249be" y="151.488"/>
|
||||
<use style="stroke:#000000;stroke-width:0.8;" x="57.6" xlink:href="#m480ecff4e3" y="151.488"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_11">
|
||||
@@ -346,7 +346,7 @@ L -3.5 0
|
||||
<g id="ytick_5">
|
||||
<g id="line2d_11">
|
||||
<g>
|
||||
<use style="stroke:#000000;stroke-width:0.8;" x="57.6" xlink:href="#med6d0249be" y="103.488"/>
|
||||
<use style="stroke:#000000;stroke-width:0.8;" x="57.6" xlink:href="#m480ecff4e3" y="103.488"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_12">
|
||||
@@ -361,7 +361,7 @@ L -3.5 0
|
||||
<g id="ytick_6">
|
||||
<g id="line2d_12">
|
||||
<g>
|
||||
<use style="stroke:#000000;stroke-width:0.8;" x="57.6" xlink:href="#med6d0249be" y="55.488"/>
|
||||
<use style="stroke:#000000;stroke-width:0.8;" x="57.6" xlink:href="#m480ecff4e3" y="55.488"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_13">
|
||||
@@ -577,7 +577,7 @@ z
|
||||
</g>
|
||||
</g>
|
||||
<g id="line2d_13">
|
||||
<path clip-path="url(#p419d591334)" d="M 73.832727 282.048
|
||||
<path clip-path="url(#p431c152dea)" d="M 73.832727 282.048
|
||||
L 87.36 277.248
|
||||
L 100.887273 270.528
|
||||
L 114.414545 269.568
|
||||
@@ -596,7 +596,7 @@ L 276.741818 266.688
|
||||
L 290.269091 266.688
|
||||
L 303.796364 263.808
|
||||
L 317.323636 278.208
|
||||
L 330.850909 289.728
|
||||
L 330.850909 270.528
|
||||
L 344.378182 289.728
|
||||
L 357.905455 289.728
|
||||
L 371.432727 289.728
|
||||
@@ -605,7 +605,7 @@ L 398.487273 289.728
|
||||
" style="fill:none;stroke:#1f77b4;stroke-linecap:square;stroke-width:1.5;"/>
|
||||
</g>
|
||||
<g id="line2d_14">
|
||||
<path clip-path="url(#p419d591334)" d="M 73.832727 295.488
|
||||
<path clip-path="url(#p431c152dea)" d="M 73.832727 295.488
|
||||
L 87.36 293.568
|
||||
L 100.887273 295.488
|
||||
L 114.414545 295.488
|
||||
@@ -633,7 +633,7 @@ L 398.487273 295.488
|
||||
" style="fill:none;stroke:#ff7f0e;stroke-linecap:square;stroke-width:1.5;"/>
|
||||
</g>
|
||||
<g id="line2d_15">
|
||||
<path clip-path="url(#p419d591334)" d="M 73.832727 232.128
|
||||
<path clip-path="url(#p431c152dea)" d="M 73.832727 232.128
|
||||
L 87.36 218.688
|
||||
L 100.887273 208.128
|
||||
L 114.414545 191.808
|
||||
@@ -652,7 +652,7 @@ L 276.741818 167.808
|
||||
L 290.269091 176.448
|
||||
L 303.796364 143.808
|
||||
L 317.323636 225.408
|
||||
L 330.850909 277.248
|
||||
L 330.850909 140.928
|
||||
L 344.378182 277.248
|
||||
L 357.905455 277.248
|
||||
L 371.432727 277.248
|
||||
@@ -870,7 +870,7 @@ L 348.72625 83.926688
|
||||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="p419d591334">
|
||||
<clipPath id="p431c152dea">
|
||||
<rect height="266.112" width="357.12" x="57.6" y="41.472"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
|
||||
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
@@ -1,25 +1,187 @@
|
||||
use std::collections::HashMap;
|
||||
use std::collections::VecDeque;
|
||||
use std::io::Read;
|
||||
|
||||
use common::Solution;
|
||||
|
||||
type Coordinate = (i32, i32);
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
enum Direction {
|
||||
North,
|
||||
South,
|
||||
West,
|
||||
East,
|
||||
}
|
||||
|
||||
impl Direction {
|
||||
pub fn walk(self, (x, y): Coordinate) -> Coordinate {
|
||||
use self::Direction::*;
|
||||
match self {
|
||||
North => (x, y - 1),
|
||||
West => (x - 1, y),
|
||||
South => (x, y + 1),
|
||||
East => (x + 1, y),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<usize> for Direction {
|
||||
fn from(idx: usize) -> Self {
|
||||
use self::Direction::*;
|
||||
match idx {
|
||||
0 => North,
|
||||
1 => South,
|
||||
2 => West,
|
||||
3 => East,
|
||||
val => panic!("Invalid direction: {}", val),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u8> for Direction {
|
||||
fn from(b: u8) -> Self {
|
||||
use self::Direction::*;
|
||||
match b {
|
||||
b'N' => North,
|
||||
b'S' => South,
|
||||
b'W' => West,
|
||||
b'E' => East,
|
||||
val => panic!("Invalid direction: {}", val),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Day20 {}
|
||||
pub struct Day20 {
|
||||
paths: HashMap<Coordinate, [bool; 4]>,
|
||||
}
|
||||
|
||||
impl Day20 {
|
||||
pub fn new() -> Self {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn follow_directions(&mut self, initial: &[Coordinate], data: &[u8]) -> (Vec<Coordinate>, usize) {
|
||||
let mut pos = Vec::from(initial);
|
||||
let mut positions = Vec::new();
|
||||
|
||||
let mut index = 0;
|
||||
|
||||
while index < data.len() {
|
||||
let b = data[index];
|
||||
match b {
|
||||
b'|' => {
|
||||
positions.extend_from_slice(&pos);
|
||||
pos = Vec::from(initial);
|
||||
}
|
||||
b'$' | b')' => {
|
||||
positions.extend_from_slice(&pos);
|
||||
positions.sort_unstable();
|
||||
positions.dedup();
|
||||
return (positions, index);
|
||||
}
|
||||
|
||||
b'(' => {
|
||||
let (new_pos, read) = self.follow_directions(&pos, &data[index + 1..]);
|
||||
pos = new_pos;
|
||||
index += read + 1;
|
||||
}
|
||||
|
||||
b'N' | b'S' | b'W' | b'E' => {
|
||||
let dir = Direction::from(b);
|
||||
for p in pos.iter_mut() {
|
||||
let entry = self.paths.entry(*p).or_insert([false; 4]);
|
||||
entry[dir as usize] = true;
|
||||
*p = dir.walk(*p);
|
||||
}
|
||||
}
|
||||
val => panic!("Invalid input character: {}", val)
|
||||
}
|
||||
index += 1;
|
||||
}
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
fn distances(&self) -> HashMap<Coordinate, usize> {
|
||||
let mut todo = VecDeque::new();
|
||||
let mut visited = HashMap::new();
|
||||
todo.push_back((0, (0, 0)));
|
||||
visited.insert((0, 0), 0);
|
||||
|
||||
while let Some((dist, pos)) = todo.pop_front() {
|
||||
if let Some(dirs) = self.paths.get(&pos) {
|
||||
let dirs = dirs.iter().enumerate()
|
||||
.filter_map(|(idx, state)| if *state {
|
||||
Some(Direction::from(idx))
|
||||
} else {
|
||||
None
|
||||
});
|
||||
for dir in dirs {
|
||||
let new_pos = dir.walk(pos);
|
||||
if !visited.contains_key(&new_pos) {
|
||||
visited.insert(new_pos, dist + 1);
|
||||
todo.push_back((dist + 1, new_pos));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
visited
|
||||
}
|
||||
}
|
||||
|
||||
impl Solution for Day20 {
|
||||
fn part1(&mut self, _input: &mut Read) -> String {
|
||||
unimplemented!()
|
||||
fn part1(&mut self, input: &mut Read) -> String {
|
||||
let mut data = Vec::new();
|
||||
input.read_to_end(&mut data).unwrap();
|
||||
let pos = (0, 0);
|
||||
|
||||
self.follow_directions(&[pos], &data[1..]);
|
||||
format!("{}", self.distances().values().max().unwrap())
|
||||
}
|
||||
|
||||
fn part2(&mut self, _input: &mut Read) -> String {
|
||||
unimplemented!()
|
||||
fn part2(&mut self, input: &mut Read) -> String {
|
||||
let mut data = Vec::new();
|
||||
input.read_to_end(&mut data).unwrap();
|
||||
let pos = (0, 0);
|
||||
|
||||
self.follow_directions(&[pos], &data[1..]);
|
||||
format!("{}", self.distances().values().filter(|&&x| x >= 1000).count())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {}
|
||||
mod tests {
|
||||
use common::Solution;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn sane_enums() {
|
||||
for idx in 0..4 {
|
||||
let direction = Direction::from(idx);
|
||||
let back = direction as usize;
|
||||
assert_eq!(idx, back);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sample_part1() {
|
||||
let samples: [&[u8]; 5] = [
|
||||
b"^WNE$",
|
||||
b"^ENWWW(NEEE|SSE(EE|N))$",
|
||||
b"^ENNWSWW(NEWS|)SSSEEN(WNSE|)EE(SWEN|)NNN$",
|
||||
b"^ESSWWN(E|NNENN(EESS(WNSE|)SSS|WWWSSSSE(SW|NNNE)))$",
|
||||
b"^WSSEESWWWNW(S|NENNEEEENN(ESSSSW(NWSW|SSEN)|WSWWN(E|WWS(E|SS))))$",
|
||||
];
|
||||
|
||||
let outputs = ["3", "10", "18", "23", "31"];
|
||||
|
||||
for (input, output) in samples.iter().zip(outputs.iter()) {
|
||||
println!("{}", String::from_utf8_lossy(input));
|
||||
let mut instance = Day20::new();
|
||||
assert_eq!(*output, instance.part1(&mut input.as_ref()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user