diff --git a/src/day10/example.txt b/src/day10/example.txt new file mode 100644 index 0000000..cada9b3 --- /dev/null +++ b/src/day10/example.txt @@ -0,0 +1,8 @@ +89010123 +78121874 +87430965 +96549874 +45678903 +32019012 +01329801 +10456732 diff --git a/src/day10/input.txt b/src/day10/input.txt new file mode 100644 index 0000000..ff85d75 --- /dev/null +++ b/src/day10/input.txt @@ -0,0 +1,52 @@ +0145677654325490845691012345621876560340100123012398 +1238988998216781932782121234010983401259230034563387 +4323589867205432801543210945125672378768341459654456 +1014678454102301765456901876034561769897652368776301 +6765521543201512350307872962120120850785677879789210 +0896430439810487461217965871298438941454980968654321 +1765012126723596543478014560167569032363211457256762 +2872121035434654302569123441455678121071102340145895 +3961230345985783211098710332334599432980098743232434 +4550145456676890100167000146721087641001217650141325 +9649056765489910651254121035890014550732309654210016 +8738769894676328762343236124301123669845498763227807 +7129787923565439651456347833210008778996787120156998 +1013496014567010340987656944782119211087898031343210 +1012345002198321232876501855693024302332196541034101 +1234567123023450901965432761054435678445087670123256 +0144898454910767845670301622169546589556764581214347 +4343732367867893034981243213678696765698873294309838 +1234351078754702121893214504589787894780987101456789 +0943765469843213210721303698921009683211074560167678 +7856874348765434785630410787652118701202983076298987 +6765989219210125698540521236543025654343892189347567 +5667867804321087582101638347432134509856782345456498 +1054876965691296443492789858901213212790101276012387 +2123965476780125356783498767654300103685230983401456 +3278954587821034219870567658967876234576541092560845 +2567543296930761006721498743478965987655612451076921 +1056230145945852345012345412661234554567803367987830 +2340167034876945123211296401780109693069954298756101 +7887658123985231034500787345691218782178769110343232 +6992349032100112985011216217885011071078978021232349 +5801239844301101676720105606976522362567987876541458 +4321023765432432369838234745983439453454376965430167 +3087610321396565458949549836112378321043105302301298 +2198565410187076327658678921001065439652234211017657 +3233478903216189014547664567632104508701230322928943 +4542369894103273223014523498549812012349821498834012 +7651423765764784132123210210038763676256734567765423 +8960314349845695041012396342121054985109875498656701 +4871005256736786780169487653434873014018766787567892 +5654196149821677893278565694565963223321051096450943 +6743287032120563034567684787696954101438142345321056 +7899180129061432125675893256787845698589233239885469 +3458098938778743210986710143876034787670132178596378 +2167347845609654331235430782932128236101056017687267 +6056256741012103220543521691047659145692347012570167 +7890165432343210110652434598798578036785498743456898 +6784567876758701328701223123623457629876901234347107 +5413218965869232499899810034510256510267892301298256 +4303409954978149581234745218760105100126765410789340 +3212567823019058670365634309451234981237898323870121 +4321016012108767621256565678321015676546767654965432 diff --git a/src/day10/mod.rs b/src/day10/mod.rs new file mode 100644 index 0000000..e6180c5 --- /dev/null +++ b/src/day10/mod.rs @@ -0,0 +1,118 @@ +use std::vec; + +struct Grid<'a> { + string: &'a str, + width: usize, +} + +impl<'a> Grid<'a> { + fn new(string: &'a str) -> Self { + let width = string.find('\n').unwrap(); + Self { string, width } + } + + fn width(&self) -> usize { + self.width + } + + fn height(&self) -> usize { + self.string.len() / (self.width() + 1) + } + + fn table(&self, fill: T) -> Table { + Table::new(self.width(), self.height(), fill) + } + + fn index(&self, i: usize) -> (isize, isize) { + let x = (i % (self.width() + 1)) as isize; + let y = (i / (self.width() + 1)) as isize; + (x, y) + } + + fn get(&self, x: isize, y: isize) -> Option<&str> { + let i: usize = y.try_into().ok()?; + let j: usize = x.try_into().ok()?; + if j >= self.width() { + return None; + } + let k = i * (self.width() + 1) + j; + self.string.get(k..k + 1) + } +} + +struct Table { + width: usize, + elems: Vec, +} + +impl Table { + fn new(width: usize, height: usize, fill: T) -> Self { + let elems = vec![fill; width * height]; + Self { width, elems } + } +} + +impl Table { + fn get_mut(&mut self, x: isize, y: isize) -> Option<&mut T> { + let i: usize = y.try_into().ok()?; + let j: usize = x.try_into().ok()?; + if j >= self.width { + return None; + } + self.elems.get_mut(i * self.width + j) + } +} + +pub fn puzzle1(input: &str) -> usize { + let grid = Grid::new(input); + input + .chars() + .enumerate() + .filter(|&(_, c)| c == '0') + .map(|(i, _)| { + let mut visited = grid.table(false); + let mut stack = vec![(0, grid.index(i))]; + while let Some((n, (x, y))) = stack.pop() { + if grid.get(x, y).and_then(|s| s.parse().ok()) != Some(n) { + continue; + } + let here = visited.get_mut(x, y).unwrap(); + if *here { + continue; + } + *here = true; + stack.push((n + 1, (x + 1, y))); + stack.push((n + 1, (x, y - 1))); + stack.push((n + 1, (x - 1, y))); + stack.push((n + 1, (x, y + 1))); + } + let mut score = 0; + for y in 0..(grid.height() as isize) { + for x in 0..(grid.width() as isize) { + if grid.get(x, y) == Some("9") && *visited.get_mut(x, y).unwrap() { + score += 1; + } + } + } + score + }) + .sum() +} + +#[cfg(test)] +mod tests { + use super::*; + + const EXAMPLE: &str = include_str!("example.txt"); + const INPUT: &str = include_str!("input.txt"); + + #[test] + fn test_puzzle1_example() { + assert_eq!(puzzle1(EXAMPLE), 36); + } + + #[test] + fn test_puzzle1_input() { + assert_eq!(puzzle1(INPUT), 667); + } +} diff --git a/src/main.rs b/src/main.rs index 7cc69e9..c635358 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,6 +9,7 @@ mod day06; mod day07; mod day08; mod day09; +mod day10; use std::{env, fs}; @@ -45,6 +46,8 @@ fn main() { (9, 1) => day09::puzzle1(&input).to_string(), (9, 2) => day09::puzzle2(&input).to_string(), + (10, 1) => day10::puzzle1(&input).to_string(), + _ => panic!("no puzzle {} for day {}", puzzle, day), }; println!("{}", answer.trim_end());