summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--input/day_03.txt140
-rw-r--r--src/day_03.rs172
-rw-r--r--src/lib.rs1
-rw-r--r--src/main.rs3
4 files changed, 315 insertions, 1 deletions
diff --git a/input/day_03.txt b/input/day_03.txt
new file mode 100644
index 0000000..4eccb80
--- /dev/null
+++ b/input/day_03.txt
@@ -0,0 +1,140 @@
+...733.......289..262.....520..................161.462..........450.........................183.............................................
+....*....................*.............707.352....*............/.....................801...@...............333..196........484.635......287.
+....42.........131....913..............*......&..........634..................440..&...............83.....@...........404$..=....*..423.*...
+618.......272....*.........&......547.344...............#............689.589.*....150......382=................................168......433.
+..........=...............253.102*.........#......78.......804..........*........................858.........................-..............
+...69.......*37...510.797...........596.946........#..................................602.175...............203..100..........681.......546.
+...*.....110.....*......*..........*..........396......858=.......381....................*.......246*637..........=..391+...................
+...973........274..551.............576.21@.......$..................*.......................................176............181.883......*...
+.......223............+............................649.701.936...17..482..........80...........210.......+...=.........563.......*...222....
+.373..*..................532....707.......956....@..+.....*......*...........+927.*......698......+....763.........275*.....27..498.........
+....*......................+......*.........*..719....540.........24...=...........39...*...................514.........126..#..............
+.....974.......952*308..@..........965....450............*4.343......772../..............437............=....*............./.....309........
+............58..........840.....34................877........$............189..................*186......657.670................&.......854.
+....22.406..*......883............*......880...........939...................................58.....387..................*..................
+......*....587.........564/......599.......*...........*......................831.891/...552..........$.534+.....%802.975.960.346*..........
+.792+..............828................-807.6...........326....324...722...334..*...........*................................................
+.....................*.......................895..764*.........=...*........*..611..........79.......461@..546*940...818.346..........247...
+....%....473......................288.......*....................932.....590...........918......791..................................*......
+.....621...*........................*....129....425.10.....*.....................419....*.........*...166......#11...................831....
+119........302.832.............159.506................*.229.....493....39...............587....523.......*..........610...805.559...........
+......971.......*..........229*..........961........139..................+....411..................554....26.90.....$........*....-.........
+...........463.615...................315....#...................................-...422.......109.-............*247................231.56...
+..279*159.*...........126...569...............906..20..........990..........27.........%.......*.............................960-......./...
+...........364....812*.......*..$.........812*....*.....369....&......176......................15.346#...#.....908...828..........-650......
+.842*771....................189..9...............42...............897*...............479.................99.....+.......*...................
+................842*356.849...............336.......201................412......./...@...........205....................956....*319.383*....
+...438....&................*......../.......*.../...*....&.......62...*........348..............*....................54.....302.........298.
+......$..318................264.....28...259..824..306...249.......&.392...444............889#..418....945...496..../.......................
+................610.160......................................................%.699...987......................*.............................
+..........@125.....*..............292..#....514..........................165....*...*....&.....*672.....551.194.426......53...500.599...278.
+.275.192.........................*....854..#..............190............$.....40..662.706..774.........$................../..*......*......
+....*.........*840....*638.....82...................520...*................................................../.190...719.......34....620....
+...........532.....521................................*...423..75..........+....-........#...29.......258.605.....*..-......................
+...........................37........../354.%453.....248.........*...561.481....727....437........969...*......243..........................
+..................................183.........................+..250...+...................312.....=....150............@...229..............
+...624...454*710..../..........=..*......../........%30....308..............................*................+...381..941........461.341....
+......=............19.........297.......213..........................%............*522......442............962...-............92..-.....*...
+.................................................324.663............775...290=.301...............=...15........=....780..................562
+747........................438...35...806*.......*......................................%396..508......*700...16..-..$..230....443..617.....
+.......$.........447......*...............336..424.........618........-..276......260............................452......#......*...*......
+....824..@916....%...488..145....%.....55..........821.....#.....620.773....*116..*.......384............156.972................974..872....
+...................=...........494.....*......609................*...............768..195..*......108/..........*......440..................
+...187...........135.=.....44.........860..........$.......+..923...........966..........#..136.................423.......#....185..........
+.....*....298........761.........................217....157..................*.....................292....268........#........./............
+..789........../.375.........919.......425.........................542.....691..69..........184......*.......*.....578............531.......
+.......740..619..*..............=........%....788.....+..324..........*..........*......531..*..=82....962.409.690..........981.............
+......*...........652..+.........................*....32.#...........53...........761...*...353.....43*.......................*....6....611.
+....589......../........190.362@....961...........917......*...........................165...............&..718...............633...*.......
+.............781...565...............*................&..324...............................339..........964..+..........%..........427..312.
+.........927.......*........#260......919.......828..469........585..........803............/...&.......................365.................
+....406..........190........................308.*.................*.............*2.803&.........417....=............................955..126
+.....#...61.75.......149....293.768....678#......675............449.....@...............%...............347......301.....-.490.....*........
+............*........*.........*.............751........................888..&..348..49.747.........................*.318..#....888.........
+..........160......335.................455....*.......761...................564..*............*926...654...../....907................857....
+.....446.....................@....915.....&....639...=...........285..............567......862................731..............9........*...
+..........513.............694..........$...............233..721.&................................806.....101.........729.......@.........292
+...........*.....565..................329................*..*........137......$849...=773...........=...*.............*..+..........32......
+...359.277..849.....*399..................274....535....348.950.....*...............................................553..607......../.......
+.....%.*.................*...146.564.818....*.....*................438..............343..945......85............162.........................
+...#...67.374..*593.....740......*......*..553...795..664...$................493#....*............-...............*...971...................
+...510.....+........843.......791..277.................*....958....................489..#.................*657.213.....*...610.....193......
+........*......#....#.................#.......$..&12....531......167......659*...........521...157*....896...........503......+.......*241..
+257..171.245....959........................109................+...............454..................239...../................................
+...*...............................................#..........203...%...&..............359.330.846........751...382.985&.........646$..#....
+..624........453..................870......890#...662.............371..311...739..........*.......*.............*............=.........817..
+..................................*....................250.....54............*......../..........182...........237.....261@.250.............
+................743.......946.....943.....414#...80....@.........*..751............159..448..............91.............................&529
+683....@....370..............*........569..........$........131...........@34..........*....736.........*...434*929.........127.............
+...*.110.....*....48..........644....*....467.................*...............92.....673.......*718.....697.............979.&...............
+.745.......503.......288..827.....911.......+.......79..290.191..........$....*....................................230..........517.........
+.........%.....551..=.....#...........192.....917..&............597...479.....316.743...%.........#................*........122..*..........
+....529.461.../..............793.........*633..*.................%..................=.604.........320.......393..599.........*....717.......
+768...*...............=567.....-.144..............545................6....591..............216*.......73..*....*........215+.842............
+.....783....855............196......*.........909..*......537.......*......=....435............874.../...902.657........................@449
+.............*........%510........28..........*...605.....@.......468............#.....630........................418@..............701.....
+......397.....748........../...+........487..521......934...................&992.....-.....160.......477.....-.......................*......
+.916.................476.651..462..........%...........*...464......................425....*...........*..531...735....=..878.....853.......
+....*...............*.............*..................965...*.........754..3..657.......................92..........@..838...................
+.....116.....469...498........537..666....622&............237.......*..........*....204...........242.........&...............599=..........
+..............-................../.............283=...........283#.919.........638.*.........452.....*794......204.326...................168
+...........................541........................544.............../183........67..903+........................*....75.512..605........
+860..............*.........*.............455....730....*......................143................@....-.....=...366.......@......*...+59....
+...*..............447....916.....127........+.....*.....60................./....*...............572.658...891...+...300.....674.733.........
+.768................................*.-..........522.28.......870.....-....89./......764*...........................*........%..............
+............606....*...................798..............298...*......342......430........668.........485.270.265/..893..............=....524
+......#.880*.......88..907.........239..........509....=......406.+..........................264........*................829........991.%...
+....850.................%.....&913....*...........*...............302..&228.......%601....63*......414....*156.............&...310..........
+.............@....184.......=.......260..........748........................149................................895.....697.......*.66.......
+..........483.......*....500..970.......88..941...........25.....623...436...*.....................278..........=......*......522..*........
+................................*.........*.-.......885....*.......#....$..848........260.........-.....579.........950...........948.......
+...........270..........+....$..736.....245.........*....936.512........................*...@..........*.....$.&.........790................
+.....................634...764....................488.........#......454...............46.995........344...59..135..........#.@851...@949...
+808.......214.............................................610...................................185*........................................
+...........*.............+...........812........606..........*.................383..................218...355/................804.@687......
+.....751.476......145.....991.314.........................123.....917......434....*.634..&....@.................805....15......*............
+......#......25......*884......*..@......526*.................*20....*....*.....328.$....672.245....*392.423$...-.....*......83....484.581..
+..............................440.759............124*397...779.......752.303.....................764.................376.806......*....*....
+.401..976...75....765.......................%.......................................430...................................*......796....82..
+........*...&......*......474...2.-351....287.....=........@.......%....%....*731......$.......=....976.........960#.381..192...............
+........808........959.......#.....................322......243...534.134.828............*....95.........241...........*.......388...567....
+....$.........511......435.........825..................................................742...............&........%....888...#.............
+....53...........-....................$.......-...........................191.....933........454...................649..........=...........
+.....................993..430*....624........817.102.......660...............*.../.....157/...*...............................845...........
+.....&.....466..692.....*....../.....*.................987.........381....746..................744...........722.........340................
+..526.........*...*......74..810....257.........-....../............*...........941..898..................../......769...=...480..$...@.....
+........658...338.107..+.................563..550........388*....542.............+....&........112......572........&........*....553...588..
+631........#..........641..759......880.@....................740........247....................*...........*............$....310............
+..........................@.........*.............888....&........-.....*....3....154....790..24..847/......767......933..............#.....
+.....790...684....669............626....324....@.......862......77..+....627..*......*....*.....................809*.............922..913...
+......*.............*.....*243..................372..........+.......878.......155.36...656....%..........917.............#.....*...........
+....935....184/....888.357.....917..797....293...............427............................665..766.........*.........986.......671........
+................................*..................................93.247................$..........*641....598..........................459
+........................922*295..664....&..........188%.481..............*.............35.............................806.......107*32..*...
+..........261.$113.....................456...................916..480....942.848.....................781*3.146..168....*......=..........222
+137.......*.................243..............783*......940......*....*........*......155......*25...........*...$...902........217..........
+.../....460.....140..170.........................283..*......647...501...-.359...365.......491.........869..103.............................
+...............*......$.........941..................75................282....../...............786*.....*......741.686......24.............
+527........................*109.*...522..................*79.....#575...............................810...373..*......*..444*...............
+...*..&37...............331.................714*..............................62$...43..%.......................983.446.............79......
+886.............................................40.................506.421..............726............171...............676*964.....*......
+................651#...301..500..497.......601*......%...263*675......*.......136*56..................*.............836...............264...
+........229....................#...&...156.....495..769......................................597.......355.............#..365...379.........
+....539.......%...933...................*..138..................402...730.......................*718.......12................$.*............
+....*........63...*....................368.....691....................*..............................#...../.....772............116.........
+....501............777.......673..728......613.&...467....688.../..526...387...726.......@568.260..456..............*.......64..............
+403...........................*.....................*.....*...311.......&.....*....387.........*.......437..$901...744.929..................
+...*.......................825.........&...........867.........................994...@........346.......................*.............285...
+....260........892*.................294..................................#............................................172.....730...........
+........743........610.........954......44@.46....606$..................718......963.970.........863.....772..............*......*..........
+284.......*............950.....*..............@..................=.............*......%.............*425.../..=625.....479.305.331...-......
+...*...139................*...976........32........-.............655..........233.373.....870..431..................................17......
+399...........820........844.........%....../744.353.&...................370........*......*...........@...135..700............*............
+....*364.#....../....266...........295................486..........932..........98.311....319..........599....*.&.......98.#....202.........
+.........768.........*.........982...........................413....*....185.....+................637.......48...........*.132..............
+.....................239........*.....................551.......*38.111....*.@.....778...856*25........605...../....355.........230.........
+...105..........*.............879........264....177.....*.783............839.682......*..............*.....-....756....*...415.*.....589-...
+.............438....................428....*.........465.....*194....................803....100...955.238..836.........767.%...555..........
+.....86....&........702........./..*.......363.........................=630.737#............%...........................................259.
+......*....256.......*.......+..57..806.......................591*............................*348....829...................+460............
+.....................244....6.....................................789......................687..............................................
diff --git a/src/day_03.rs b/src/day_03.rs
new file mode 100644
index 0000000..5901038
--- /dev/null
+++ b/src/day_03.rs
@@ -0,0 +1,172 @@
+use std::collections::{HashMap, HashSet};
+
+use crate::{Problem, Solution};
+
+pub struct Day03;
+
+impl Problem for Day03 {
+ const DAY: u8 = 3;
+
+ const INPUT: &'static str = include_str!("../input/day_03.txt");
+}
+
+impl Solution for Day03 {
+ type Answer1 = usize;
+
+ type Answer2 = usize;
+
+ fn part_1(input: &str) -> anyhow::Result<Self::Answer1> {
+ let grid = input
+ .trim()
+ .split('\n')
+ .map(|l| l.trim().chars().collect::<Vec<_>>())
+ .collect::<Vec<_>>();
+
+ Ok(grid.iter().enumerate().fold(0, |mut acc, (row, line)| {
+ let line_iter = &mut line.iter().enumerate().peekable();
+ while line_iter.peek().is_some() {
+ let (part, is_part) = line_iter
+ .skip_while(|(_, n)| !n.is_ascii_digit())
+ .map_while(|(i, n)| n.to_digit(10).map(|u| (i, u)))
+ .fold((0, false), |(part, is_part), (col, n)| {
+ let is_part = is_part
+ || [row.saturating_sub(1), row, row + 1]
+ .into_iter()
+ .flat_map(|r| [col.saturating_sub(1), col, col + 1].map(|c| (r, c)))
+ .filter(|(r, c)| *r < grid.len() && *c < line.len())
+ .filter(|(r, c)| *r != row || *c != col)
+ .flat_map(|(r, c)| grid.get(r).and_then(|line| line.get(c)))
+ .any(|n| *n != '.' && !n.is_ascii_digit());
+
+ (part * 10 + n as usize, is_part)
+ });
+
+ if is_part {
+ acc += part;
+ }
+ }
+ acc
+ }))
+ }
+
+ fn part_2(input: &str) -> anyhow::Result<Self::Answer2> {
+ let grid = input
+ .trim()
+ .split('\n')
+ .map(|l| l.trim().chars().collect::<Vec<_>>())
+ .collect::<Vec<_>>();
+
+ Ok(grid
+ .iter()
+ .enumerate()
+ .fold(
+ &mut HashMap::<Symbol, HashSet<Part>>::new(),
+ |acc, (row, line)| {
+ let line_iter = &mut line.iter().enumerate().peekable();
+ while line_iter.peek().is_some() {
+ let (part, symbols) = line_iter
+ .skip_while(|(_, n)| !n.is_ascii_digit())
+ .map_while(|(i, n)| n.to_digit(10).map(|u| (i, u)))
+ .fold(
+ (Part::default(), HashSet::<Symbol>::new()),
+ |(mut part, mut neighbors), (col, n)| {
+ let new_neighbors = [row.saturating_sub(1), row, row + 1]
+ .into_iter()
+ .flat_map(|r| {
+ [col.saturating_sub(1), col, col + 1].map(|c| (r, c))
+ })
+ .filter(|(r, c)| *r < grid.len() && *c < line.len())
+ .filter(|(r, c)| *r != row || *c != col)
+ .flat_map(|(r, c)| {
+ grid.get(r)
+ .and_then(|line| line.get(c))
+ .map(|n| ((r, c), *n))
+ })
+ .filter(|(_, n)| *n != '.' && !n.is_ascii_digit())
+ .map(Symbol::from);
+
+ neighbors.extend(new_neighbors);
+ part.push_value(n as usize);
+ (part, neighbors)
+ },
+ );
+
+ symbols
+ .into_iter()
+ .filter(|s| s.value == '*')
+ .for_each(|s| {
+ acc.entry(s)
+ .and_modify(|h| {
+ h.insert(part);
+ })
+ .or_insert(HashSet::from([part]));
+ });
+ }
+ acc
+ },
+ )
+ .values_mut()
+ .filter(|h| h.len() == 2)
+ .fold(0, |acc, h| {
+ acc + h
+ .iter()
+ .copied()
+ .map(|p| p.value)
+ .reduce(|acc, v| acc * v)
+ .unwrap()
+ }))
+ }
+}
+
+#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
+struct Symbol {
+ value: char,
+ pos: (usize, usize),
+}
+
+impl From<((usize, usize), char)> for Symbol {
+ fn from((pos, value): ((usize, usize), char)) -> Self {
+ Symbol { value, pos }
+ }
+}
+
+#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
+struct Part {
+ value: usize,
+ start: (usize, usize),
+ end: (usize, usize),
+}
+
+impl Part {
+ fn push_value(&mut self, n: usize) {
+ self.value = self.value * 10 + n
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ const INPUT: &str = indoc::indoc! {"
+ 467..114..
+ ...*......
+ ..35..633.
+ ......#...
+ 617*......
+ .....+.58.
+ ..592.....
+ ......755.
+ ...$.*....
+ .664.598..
+ "};
+
+ #[test]
+ fn test_part_1() -> anyhow::Result<()> {
+ Ok(assert_eq!(4361, Day03::part_1(INPUT)?))
+ }
+
+ #[test]
+ fn test_part_2() -> anyhow::Result<()> {
+ Ok(assert_eq!(467835, Day03::part_2(INPUT)?))
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index f077524..42df819 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -2,6 +2,7 @@
pub mod day_01;
pub mod day_02;
+pub mod day_03;
pub trait Problem {
const DAY: u8;
diff --git a/src/main.rs b/src/main.rs
index 4242965..7ac9cfa 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,8 +1,9 @@
-use aoc_2023::{day_01::Day01, day_02::Day02, Solution};
+use aoc_2023::{day_01::Day01, day_02::Day02, day_03::Day03, Solution};
fn main() -> anyhow::Result<()> {
Day01::solve()?;
Day02::solve()?;
+ Day03::solve()?;
Ok(())
}