Solved day 10

This commit is contained in:
2024-12-12 00:26:30 +01:00
parent e5f44470d6
commit f15cf3bc20
4 changed files with 171 additions and 1 deletions

52
input/day10.txt Normal file
View File

@@ -0,0 +1,52 @@
5678543238765121087216787432128921016563210454323433
4169654119654037892107894549017430457654782369412812
3018767001843246543210787678186543368945691078908903
2189678914980158934345698187098901275632100165001894
3434589125678767891016521096167872984789321874112765
7823678034569876780123434545252766543215476903233456
6910167012423495679654321032341057630306985012945101
5401986543410584508765678211352348921437894123876298
4323877892543673210104569300235496530890123434565387
3210967871652598789213075410145687432765210123432456
0101454960701659654322186703456710101854321076501201
1012343459898741023763099812769823478923212987655652
4323012321101232212854210129876012569012503234234743
5011001410765540101940110238787112876503414105109892
6722340543894691001233221045698108976434565696589321
9821059652023782317874536789587012885325676787678780
9778968701110678498965945893496543494018989801210690
8769878889231589567767893672109824323561234892309541
1454399998342490430850104589678012012370348763458032
0141287107654321521943213212565503123987659654567123
1230236256565410101237870101419654598543210508948910
2340145348978321253210965432308765687696501417654323
3986501567899010344789876323219454766787432321078890
5677432450987432455670189410012349845696501434569701
0548901321976501964563208231987210036723109621435652
1239678100823457877854010145676210129814918730898543
4310369234710165756905423210122305610905825623567678
3423456765600874543814554761201456723876734514410569
2102109894321984562323669854398556894985232305320438
3076521003965433871234778034567647895894101476761023
4585412312870122930129872129867634456783230585872310
5694303456781211123123401256798521065656187694965432
6783201019892100054076540346543438980521090123456501
0340112387653456963981639457832523671439876101219602
1258903490144327870190128768901214512112725614308712
2569876589231016983278787434980108903003014525456893
1876767676546781074349896523076587654394523496327854
0945778789035690165234765014123496543487621087018969
1239869876124789234105676543287017012567634589829678
9018756765453210785411085010196528921298565676543549
8723605034301305696532398923483437430143476589762138
7634514125212154387783437654589016521052187679854023
6501323896521093210598568943078723632367098512763210
7432454787436789765677678732189654045458963403892001
8901343474345658894389589823476902102167872354301123
7623676543216743001210438214567813458054961065689054
5012389012109812123309321301054324569123452876548765
4589438729001901014578010102344567078212556989231076
3676567438782342145665430230133898167901665476102989
2109652145699654398765421321212101237810174345603478
1078743034328765219876323478903894376521089298714565
2167634145410898701101210569816765489432100107623434

8
input/day10_example.txt Normal file
View File

@@ -0,0 +1,8 @@
89010123
78121874
87430965
96549874
45678903
32019012
01329801
10456732

108
src/day10.rs Normal file
View File

@@ -0,0 +1,108 @@
use crate::day_solver::DaySolver;
#[cfg(test)]
use crate::util::read_file;
use crate::util::{Coord, Grid};
use itertools::Itertools;
use std::collections::HashSet;
pub struct Day10 {
map: Grid<u8>
}
impl Day10 {
pub fn create(input: String) -> Self {
Day10 {
map: Grid {
data: input.lines().join("").chars().map(|c| (c as u8) - b'0').collect(),
width: input.lines().next().unwrap().len(),
default: Some(255)
}
}
}
fn calculate_score(&self, trailhead: Coord<usize>) -> usize {
// Since paths have an even, gradual, uphill slope, we can just go up in height and see what we can reach
let mut last_layer: HashSet<Coord<usize>> = HashSet::new();
last_layer.insert(trailhead);
for h in 1..10 {
let mut cur_layer = HashSet::new();
for pos in last_layer.clone() {
// Check which neighbors are height h
if self.map.get(pos.x + 1, pos.y) == &h { cur_layer.insert(Coord::new(pos.x + 1, pos.y)); };
if pos.x > 0 && self.map.get(pos.x - 1, pos.y) == &h { cur_layer.insert(Coord::new(pos.x - 1, pos.y)); };
if self.map.get(pos.x, pos.y + 1) == &h { cur_layer.insert(Coord::new(pos.x, pos.y + 1)); };
if pos.y > 0 && self.map.get(pos.x, pos.y - 1) == &h { cur_layer.insert(Coord::new(pos.x, pos.y - 1)); };
}
last_layer = cur_layer;
}
last_layer.len()
}
fn update_pos(&self, new_x: usize, new_y: usize, target_height: &u8, cur_paths_to_pos: usize, cur_layer: &mut HashSet<Coord<usize>>, paths_to_pos: &mut Grid<usize>) {
if self.map.get(new_x, new_y) == target_height {
cur_layer.insert(Coord::new(new_x, new_y));
paths_to_pos.set(new_x, new_y, paths_to_pos.get(new_x, new_y) + cur_paths_to_pos);
}
}
fn calculate_score_pt2(&self, trailhead: Coord<usize>) -> usize {
let mut last_layer: HashSet<Coord<usize>> = HashSet::new();
last_layer.insert(trailhead);
let mut paths_to_pos: Grid<usize> = Grid {
data: vec![0; self.map.data.len()],
width: self.map.width,
default: Some(0),
};
paths_to_pos.set(trailhead.x, trailhead.y, 1);
for h in 1..10 {
let mut cur_layer = HashSet::new();
for pos in last_layer.clone() {
let cur_paths_to_pos = paths_to_pos.get(pos.x, pos.y).to_owned();
self.update_pos(pos.x + 1, pos.y, &h, cur_paths_to_pos, &mut cur_layer, &mut paths_to_pos);
if pos.x > 0 { self.update_pos(pos.x - 1, pos.y, &h, cur_paths_to_pos, &mut cur_layer, &mut paths_to_pos); };
self.update_pos(pos.x, pos.y + 1, &h, cur_paths_to_pos, &mut cur_layer, &mut paths_to_pos);
if pos.y > 0 { self.update_pos(pos.x, pos.y - 1, &h, cur_paths_to_pos, &mut cur_layer, &mut paths_to_pos); };
}
last_layer = cur_layer;
}
last_layer.iter().map(|l| paths_to_pos.get(l.x, l.y)).sum()
}
}
impl DaySolver for Day10 {
fn solve_part1(&mut self) -> String {
self.map.find_positions(&|d| d == &0)
.map(|c| self.calculate_score(c))
.sum::<usize>().to_string()
}
fn solve_part2(&mut self) -> String {
self.map.find_positions(&|d| d == &0)
.map(|c| self.calculate_score_pt2(c))
.sum::<usize>().to_string()
}
}
#[test]
fn test_part1() {
let mut day = Day10::create(read_file("input/day10_example.txt"));
assert_eq!("36", day.solve_part1());
}
#[test]
fn test_part2() {
let mut day = Day10::create(read_file("input/day10_example.txt"));
assert_eq!("81", day.solve_part2());
}

View File

@@ -1,6 +1,7 @@
extern crate core; extern crate core;
use std::time::Instant; use std::time::Instant;
use crate::day10::Day10;
use crate::day1::Day1; use crate::day1::Day1;
use crate::day2::Day2; use crate::day2::Day2;
use crate::day3::Day3; use crate::day3::Day3;
@@ -24,6 +25,7 @@ mod day6;
mod day7; mod day7;
mod day8; mod day8;
mod day9; mod day9;
mod day10;
const DEFAULT_BENCHMARK_AMOUNT: u32 = 100; const DEFAULT_BENCHMARK_AMOUNT: u32 = 100;
@@ -104,7 +106,7 @@ fn build_day_solver(day: u8, input: String) -> Option<Box<dyn DaySolver>> {
7 => Some(Box::new(Day7::create(input))), 7 => Some(Box::new(Day7::create(input))),
8 => Some(Box::new(Day8::create(input))), 8 => Some(Box::new(Day8::create(input))),
9 => Some(Box::new(Day9::create(input))), 9 => Some(Box::new(Day9::create(input))),
// 10 => Some(Box::new(Day10::create(input))), 10 => Some(Box::new(Day10::create(input))),
// 11 => Some(Box::new(Day11::create(input))), // 11 => Some(Box::new(Day11::create(input))),
// 12 => Some(Box::new(Day12::create(input))), // 12 => Some(Box::new(Day12::create(input))),
_ => None _ => None