From f7d70ba76ec5f5e4ed5ace5bc5ccee56e698ac32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20B=C3=BChler?= Date: Sat, 7 Dec 2019 11:20:57 +0100 Subject: [PATCH] add day 2 to 7 --- Cargo.lock | 54 ++ Cargo.toml | 7 + day1/src/main.rs | 4 +- day2/Cargo.toml | 10 + day2/src/input.txt | 1 + day2/src/main.rs | 60 ++ day3/Cargo.toml | 9 + day3/src/input.txt | 2 + day3/src/main.rs | 191 +++++ day4/Cargo.toml | 9 + day4/src/main.rs | 80 ++ day5/Cargo.toml | 10 + day5/src/input.txt | 1 + day5/src/main.rs | 82 ++ day6/Cargo.toml | 9 + day6/src/input.txt | 1831 +++++++++++++++++++++++++++++++++++++++++ day6/src/main.rs | 87 ++ day7/Cargo.toml | 11 + day7/src/input.txt | 1 + day7/src/main.rs | 94 +++ shared/Cargo.toml | 9 + shared/src/intcode.rs | 148 ++++ shared/src/lib.rs | 1 + 23 files changed, 2709 insertions(+), 2 deletions(-) create mode 100644 day2/Cargo.toml create mode 100644 day2/src/input.txt create mode 100644 day2/src/main.rs create mode 100644 day3/Cargo.toml create mode 100644 day3/src/input.txt create mode 100644 day3/src/main.rs create mode 100644 day4/Cargo.toml create mode 100644 day4/src/main.rs create mode 100644 day5/Cargo.toml create mode 100644 day5/src/input.txt create mode 100644 day5/src/main.rs create mode 100644 day6/Cargo.toml create mode 100644 day6/src/input.txt create mode 100644 day6/src/main.rs create mode 100644 day7/Cargo.toml create mode 100644 day7/src/input.txt create mode 100644 day7/src/main.rs create mode 100644 shared/Cargo.toml create mode 100644 shared/src/intcode.rs create mode 100644 shared/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index da01ae3..d451514 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,3 +4,57 @@ name = "day1" version = "0.1.0" +[[package]] +name = "day2" +version = "0.1.0" +dependencies = [ + "shared 0.1.0", +] + +[[package]] +name = "day3" +version = "0.1.0" + +[[package]] +name = "day4" +version = "0.1.0" + +[[package]] +name = "day5" +version = "0.1.0" +dependencies = [ + "shared 0.1.0", +] + +[[package]] +name = "day6" +version = "0.1.0" + +[[package]] +name = "day7" +version = "0.1.0" +dependencies = [ + "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "shared 0.1.0", +] + +[[package]] +name = "either" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "itertools" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "shared" +version = "0.1.0" + +[metadata] +"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" +"checksum itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" diff --git a/Cargo.toml b/Cargo.toml index e8caeb5..4191b5b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,4 +1,11 @@ [workspace] members = [ "day1", + "day2", + "day3", + "day4", + "day5", + "day6", + "day7", + "shared", ] diff --git a/day1/src/main.rs b/day1/src/main.rs index b92229f..790e78f 100644 --- a/day1/src/main.rs +++ b/day1/src/main.rs @@ -31,7 +31,7 @@ fn main() { #[cfg(test)] mod day1test { #[test] - fn example1() { + fn examples1() { // Original descriptions: // > For a mass of 12, divide by 3 and round down to get 4, then subtract 2 to get 2. // > For a mass of 14, dividing by 3 and rounding down still yields 4, so the fuel required is also 2. @@ -44,7 +44,7 @@ mod day1test { } #[test] - fn example2() { + fn examples2() { // Original descriptions: // > A module of mass 14 requires 2 fuel. This fuel requires no further fuel (2 divided by 3 and rounded down is 0, which would call for a negative fuel), so the total fuel required is still just 2. // > At first, a module of mass 1969 requires 654 fuel. Then, this fuel requires 216 more fuel (654 / 3 - 2). 216 then requires 70 more fuel, which requires 21 fuel, which requires 5 fuel, which requires no further fuel. So, the total fuel required for a module of mass 1969 is 654 + 216 + 70 + 21 + 5 = 966. diff --git a/day2/Cargo.toml b/day2/Cargo.toml new file mode 100644 index 0000000..9e44882 --- /dev/null +++ b/day2/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "day2" +version = "0.1.0" +authors = ["Stefan Bühler "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +shared = { path = "../shared" } diff --git a/day2/src/input.txt b/day2/src/input.txt new file mode 100644 index 0000000..f9a20e9 --- /dev/null +++ b/day2/src/input.txt @@ -0,0 +1 @@ +1,0,0,3,1,1,2,3,1,3,4,3,1,5,0,3,2,9,1,19,1,19,5,23,1,9,23,27,2,27,6,31,1,5,31,35,2,9,35,39,2,6,39,43,2,43,13,47,2,13,47,51,1,10,51,55,1,9,55,59,1,6,59,63,2,63,9,67,1,67,6,71,1,71,13,75,1,6,75,79,1,9,79,83,2,9,83,87,1,87,6,91,1,91,13,95,2,6,95,99,1,10,99,103,2,103,9,107,1,6,107,111,1,10,111,115,2,6,115,119,1,5,119,123,1,123,13,127,1,127,5,131,1,6,131,135,2,135,13,139,1,139,2,143,1,143,10,0,99,2,0,14,0 \ No newline at end of file diff --git a/day2/src/main.rs b/day2/src/main.rs new file mode 100644 index 0000000..3d3ba01 --- /dev/null +++ b/day2/src/main.rs @@ -0,0 +1,60 @@ +use shared::intcode::{IntCode, CELL}; + +fn run(mut ic: IntCode, first: CELL, second: CELL) -> CELL { + ic.data[1] = first; + ic.data[2] = second; + ic.simulate(); + ic.data[0] +} + +fn main() { + let ic = include_str!("input.txt").parse::().unwrap(); + println!("Run 1: {}", run(ic.clone(), 12, 2)); + for limit in 0.. { + for fst in 0..limit { + let result = run(ic.clone(), fst, limit); + if result == 19690720 { + println!("Found parameters: {}", 100*fst + limit); + return; + } + } + if limit > 0 { + for snd in 0..limit-1 { + let result = run(ic.clone(), limit, snd); + if result == 19690720 { + println!("Found parameters: {}", 100*limit + snd); + return; + } + } + } + } +} + +#[cfg(test)] +mod day2test { + use super::*; + + fn parse(input: &str) -> IntCode { + input.parse().unwrap() + } + + fn run(input: &str) -> IntCode { + let mut ic = parse(input); + ic.simulate_step().expect_finished(); + ic + } + + #[test] + fn examples1() { + assert_eq!(run("1,9,10,3,2,3,11,0,99,30,40,50").data, parse("3500,9,10,70,2,3,11,0,99,30,40,50").data); + assert_eq!(run("1,0,0,0,99").data, parse("2,0,0,0,99").data); + assert_eq!(run("2,3,0,3,99").data, parse("2,3,0,6,99").data); + assert_eq!(run("2,4,4,5,99,0").data, parse("2,4,4,5,99,9801").data); + assert_eq!(run("1,1,1,4,99,5,6,0,99").data, parse("30,1,1,4,2,5,6,0,99").data); + } + + #[test] + fn examples2() { + // no examples present + } +} diff --git a/day3/Cargo.toml b/day3/Cargo.toml new file mode 100644 index 0000000..f1d1184 --- /dev/null +++ b/day3/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "day3" +version = "0.1.0" +authors = ["Stefan Bühler "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/day3/src/input.txt b/day3/src/input.txt new file mode 100644 index 0000000..9df377c --- /dev/null +++ b/day3/src/input.txt @@ -0,0 +1,2 @@ +R1005,U563,R417,U509,L237,U555,R397,U414,L490,U336,L697,D682,L180,U951,L189,D547,R697,U583,L172,D859,L370,D114,L519,U829,R389,U608,R66,D634,L320,D49,L931,U137,L349,D689,L351,D829,R819,D138,L118,D849,R230,U858,L509,D311,R815,U217,R359,U840,R77,U230,R361,U322,R300,D646,R348,U815,R793,D752,R967,U128,R948,D499,R359,U572,L566,U815,R630,D290,L829,D736,R358,U778,R891,U941,R544,U889,L920,U913,L447,D604,R538,U818,L215,D437,R447,U576,R452,D794,R864,U269,L325,D35,L268,D639,L101,U777,L776,U958,R105,U517,R667,D423,R603,U469,L125,D919,R879,U994,R665,D377,R456,D570,L685,U291,R261,U846,R840,U418,L974,D270,L312,D426,R621,D334,L855,D378,R694,U845,R481,U895,L362,D840,L712,U57,R276,D643,R566,U348,R361,D144,L287,D864,L556,U610,L927,U322,R271,D90,L741,U446,R181,D527,R56,U805,L907,D406,L286,U873,L79,D280,L153,D377,R253,D61,R475,D804,R788,U393,L660,U314,R489,D491,L234,D712,L253,U651,L777,D726,R146,U47,R630,U517,R226,U624,L834,D153,L513,U799,R287,D868,R982,U390,L296,D373,R9,U994,R105,D673,L657,D868,R738,D277,R374,U828,R860,U247,R484,U986,L723,D847,L578,U487,L51,D865,L328,D199,R812,D726,R355,D463,R761,U69,R508,D753,L81,D50,L345,D66,L764,D466,L975,U619,R59,D788,L737,D360,R14,D253,L512,D417,R828,D188,L394,U212,R658,U369,R920,U927,L339,U552,R856,D458,R407,U41,L930,D460,R809,U467,L410,D800,L135,D596,R678,D4,L771,D637,L876,U192,L406,D136,R666,U730,R711,D291,L586,U845,R606,U2,L228,D759,R244,U946,R948,U160,R397,U134,R188,U850,R623,D315,L219,D450,R489,U374,R299,D474,L767,D679,L160,D403,L708 +L1003,D878,R937,D979,R921,U572,R4,D959,L884,U394,R221,U206,R806,U912,R345,D290,R65,D996,L411,D157,R590,D557,L32,D360,L691,D861,L156,D603,R733,U444,L433,U144,L238,U213,R827,U949,R384,D409,L727,U923,L98,U781,L201,D200,R749,U288,L486,U158,L494,D522,R636,D330,L507,U691,R918,D706,R163,U609,R559,U674,R784,D87,R670,U401,L85,U981,R848,D579,L882,U777,R671,D385,R913,D899,R92,D780,L795,U821,R956,U446,L109,D955,L570,D874,R499,U845,R769,U88,L529,U657,R553,D357,L83,D324,L273,U689,L715,U933,R161,U561,L603,U349,L445,U781,R299,U26,L212,U429,R763,U116,R961,D258,L518,D668,L767,U587,L654,D24,R318,U35,L9,D199,L161,U419,R6,D707,R944,U499,R207,D349,L727,D637,R735,D137,R18,D214,L531,D327,L916,U440,R859,U483,R952,D631,L96,D320,L192,D985,R330,D196,L345,D575,L535,D868,R376,D126,R903,D619,L126,D624,L990,D67,L927,U685,L200,D759,L157,D816,L585,U910,R587,D598,L398,U706,R847,U682,L919,D291,L932,D54,L314,U430,L60,U206,L997,D487,L874,U957,L753,U999,R156,U102,L826,U923,L204,U293,L244,U787,L273,D687,R134,D167,L287,D459,R875,D32,R635,D400,L179,D19,L576,U60,L182,D409,R114,U329,R207,U525,L295,U305,L861,U280,R531,D49,L890,U521,L283,U37,R344,D867,L474,U893,R140,U289,L67,U490,R121,D34,L696,U902,R288,U249,R107,D750,R389,U125,L406,U950,R932,U795,R205,U583,L665,U214,R806,D409,R832,D39,R207,D977,L873,U645,L762,U847,L725,U397,R414,D558,L669,D736,R897,U464,R207,U359,R257,U304,L932,U240,L582,U409,L493,D481,R48,D537,R893,U48,R707,U630,L70,D289,L769,U98,L679,U504,L337,U117,L343,D574,R595,U168,R498 diff --git a/day3/src/main.rs b/day3/src/main.rs new file mode 100644 index 0000000..d8202a3 --- /dev/null +++ b/day3/src/main.rs @@ -0,0 +1,191 @@ +type Error = Box; + +#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug)] +pub enum Move { + Right(u32), + Left(u32), + Up(u32), + Down(u32), +} + +#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug)] +pub enum Segment { + Horizontal { + row: i32, + col_start: i32, + col_end: i32, + steps_start: i32, + steps_dir: i32, + }, + Vertical { + col: i32, + row_start: i32, + row_end: i32, + steps_start: i32, + steps_dir: i32, + }, +} + +impl Segment { + pub fn collision(&self, other: &Self) -> Option { + match (*self, *other) { + (Segment::Horizontal {..}, Segment::Horizontal {..}) => None, + (Segment::Vertical {..}, Segment::Vertical {..}) => None, + ( + Segment::Horizontal { row, col_start, col_end, steps_start: col_steps_start, steps_dir: col_steps_dir }, + Segment::Vertical { col, row_start, row_end, steps_start: row_steps_start, steps_dir: row_steps_dir }, + ) + |( + Segment::Vertical { col, row_start, row_end, steps_start: row_steps_start, steps_dir: row_steps_dir }, + Segment::Horizontal { row, col_start, col_end, steps_start: col_steps_start, steps_dir: col_steps_dir }, + ) + => { + if row_start <= row && row <= row_end && col_start <= col && col <= col_end { + let col_steps = col_steps_start + (col - col_start) * col_steps_dir; + let row_steps = row_steps_start + (row - row_start) * row_steps_dir; + Some(Position { row, col, steps: col_steps + row_steps }) + } else { + None + } + } + } + } +} + +#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)] +pub struct Position { + row: i32, + col: i32, + steps: i32, +} + +impl Position { + pub fn manhatten_distance(&self) -> u32 { + self.row.abs() as u32 + self.col.abs() as u32 + } + + pub fn trace(&mut self, mov: Move) -> Segment { + let start = *self; + match mov { + Move::Right(off) => { + self.col += off as i32; + self.steps += off as i32; + Segment::Horizontal { + row: start.row, + col_start: start.col, + col_end: self.col, + steps_start: start.steps, + steps_dir: 1, + } + }, + Move::Left(off) => { + self.col -= off as i32; + self.steps += off as i32; + Segment::Horizontal { + row: start.row, + col_start: self.col, + col_end: start.col, + steps_start: self.steps, + steps_dir: -1, + } + }, + Move::Up(off) => { + self.row -= off as i32; + self.steps += off as i32; + Segment::Vertical { + col: start.col, + row_start: self.row, + row_end: start.row, + steps_start: self.steps, + steps_dir: -1, + } + }, + Move::Down(off) => { + self.row += off as i32; + self.steps += off as i32; + Segment::Vertical { + col: start.col, + row_start: start.row, + row_end: self.row, + steps_start: start.steps, + steps_dir: 1, + } + }, + } + } +} + +impl std::str::FromStr for Move { + type Err = Error; + + fn from_str(s: &str) -> Result { + let e = move || Box::new(std::io::Error::new(std::io::ErrorKind::Other, "invalid move")); + let n = s[1..].parse::()?; + if s.is_empty() || !s.is_ascii() { + return Err(e()); + } + Ok(match s.as_bytes()[0] { + b'R' => Move::Right(n), + b'L' => Move::Left(n), + b'U' => Move::Up(n), + b'D' => Move::Down(n), + _ => return Err(e()), + }) + } +} + +fn parse_moves<'a>(input: &'a str) -> impl Iterator> + 'a { + input.split(',').map(str::parse) +} + +fn trace_moves<'a>(input: &'a str) -> impl Iterator> + 'a { + let mut pos = Position::default(); + parse_moves(input).map(move |m| m.map(|m| pos.trace(m))) +} + +fn closest_intersection(lines: &[Vec; 2]) -> u32 { + lines[0][1..].iter().map(|a| lines[1][1..].iter().filter_map(move |b| a.collision(b).map(|p| p.manhatten_distance()))).flatten().min().unwrap() +} + +fn shortest_delay(lines: &[Vec; 2]) -> i32 { + lines[0][1..].iter().map(|a| lines[1][1..].iter().filter_map(move |b| a.collision(b).map(|p| p.steps))).flatten().min().unwrap() +} + +fn parse(input: &str) -> [Vec; 2] { + let mut lines = input.split_whitespace().map(trace_moves).map(Iterator::collect::, _>>); + let result = [ + lines.next().expect("require two lines").unwrap(), + lines.next().expect("require two lines").unwrap(), + ]; + assert!(lines.next().is_none(), "require only two lines"); + result +} + +fn main() { + let input: &str = include_str!("input.txt"); + let lines = parse(input); + + println!("Distance 1: {}", closest_intersection(&lines)); + println!("Distance 2: {}", shortest_delay(&lines)); +} + +#[cfg(test)] +mod day3test { + use super::*; + + #[test] + fn examples1() { + assert_eq!(closest_intersection(&parse("R75,D30,R83,U83,L12,D49,R71,U7,L72 +U62,R66,U55,R34,D71,R55,D58,R83")), 159); + assert_eq!(closest_intersection(&parse("R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51 +U98,R91,D20,R16,D67,R40,U7,R15,U6,R7")), 135); + } + + #[test] + fn examples2() { + assert_eq!(shortest_delay(&parse("R75,D30,R83,U83,L12,D49,R71,U7,L72 +U62,R66,U55,R34,D71,R55,D58,R83")), 610); + assert_eq!(shortest_delay(&parse("R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51 +U98,R91,D20,R16,D67,R40,U7,R15,U6,R7")), 410); + } +} \ No newline at end of file diff --git a/day4/Cargo.toml b/day4/Cargo.toml new file mode 100644 index 0000000..2256260 --- /dev/null +++ b/day4/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "day4" +version = "0.1.0" +authors = ["Stefan Bühler "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/day4/src/main.rs b/day4/src/main.rs new file mode 100644 index 0000000..47f9428 --- /dev/null +++ b/day4/src/main.rs @@ -0,0 +1,80 @@ +/* +However, they do remember a few key facts about the password: + + It is a six-digit number. + The value is within the range given in your puzzle input. + Two adjacent digits are the same (like 22 in 122345). + Going from left to right, the digits never decrease; they only ever increase or stay the same (like 111123 or 135679). + +Other than the range rule, the following are true: + + 111111 meets these criteria (double 11, never decreases). + 223450 does not meet these criteria (decreasing pair of digits 50). + 123789 does not meet these criteria (no double). + +How many different passwords within the range given in your puzzle input meet these criteria? + +Your puzzle input is 206938-679128. + +*/ + +fn valid_password1(number: u32) -> bool { + use std::io::Write; + if number < 100_000 || number > 999_999 { return false; } + let mut digits = [0u8; 6]; + write!(&mut digits[..], "{}", number).unwrap(); + let mut have_double_digit = false; + for i in 0..5 { + if digits[i] > digits[i+1] { return false; } + if digits[i] == digits[i+1] { have_double_digit = true } + } + + have_double_digit +} + +fn valid_password2(number: u32) -> bool { + use std::io::Write; + if number < 100_000 || number > 999_999 { return false; } + let mut digits = [0u8; 6]; + write!(&mut digits[..], "{}", number).unwrap(); + let mut have_double_digit = false; + let mut current_run = 1; + for i in 0..5 { + if digits[i] > digits[i+1] { return false; } + if digits[i] == digits[i+1] { + current_run += 1; + } else { + if current_run == 2 { + have_double_digit = true; + } + current_run = 1; + } + } + if current_run == 2 { + have_double_digit = true; + } + + have_double_digit +} + +fn main() { + println!("Count 1: {}", (206938..=679128).filter(|n| valid_password1(*n)).count()); + println!("Count 2: {}", (206938..=679128).filter(|n| valid_password2(*n)).count()); +} + +#[cfg(test)] +mod day4test { + #[test] + fn examples1() { + assert!(super::valid_password1(111111)); + assert!(!super::valid_password1(223450)); + assert!(!super::valid_password1(123789)); + } + + #[test] + fn examples2() { + assert!(super::valid_password2(112233)); + assert!(!super::valid_password2(123444)); + assert!(super::valid_password2(111122)); + } +} diff --git a/day5/Cargo.toml b/day5/Cargo.toml new file mode 100644 index 0000000..3235101 --- /dev/null +++ b/day5/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "day5" +version = "0.1.0" +authors = ["Stefan Bühler "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +shared = { path = "../shared" } diff --git a/day5/src/input.txt b/day5/src/input.txt new file mode 100644 index 0000000..1fd7f0b --- /dev/null +++ b/day5/src/input.txt @@ -0,0 +1 @@ +3,225,1,225,6,6,1100,1,238,225,104,0,1101,9,90,224,1001,224,-99,224,4,224,102,8,223,223,1001,224,6,224,1,223,224,223,1102,26,62,225,1101,11,75,225,1101,90,43,225,2,70,35,224,101,-1716,224,224,4,224,1002,223,8,223,101,4,224,224,1,223,224,223,1101,94,66,225,1102,65,89,225,101,53,144,224,101,-134,224,224,4,224,1002,223,8,223,1001,224,5,224,1,224,223,223,1102,16,32,224,101,-512,224,224,4,224,102,8,223,223,101,5,224,224,1,224,223,223,1001,43,57,224,101,-147,224,224,4,224,102,8,223,223,101,4,224,224,1,223,224,223,1101,36,81,225,1002,39,9,224,1001,224,-99,224,4,224,1002,223,8,223,101,2,224,224,1,223,224,223,1,213,218,224,1001,224,-98,224,4,224,102,8,223,223,101,2,224,224,1,224,223,223,102,21,74,224,101,-1869,224,224,4,224,102,8,223,223,1001,224,7,224,1,224,223,223,1101,25,15,225,1101,64,73,225,4,223,99,0,0,0,677,0,0,0,0,0,0,0,0,0,0,0,1105,0,99999,1105,227,247,1105,1,99999,1005,227,99999,1005,0,256,1105,1,99999,1106,227,99999,1106,0,265,1105,1,99999,1006,0,99999,1006,227,274,1105,1,99999,1105,1,280,1105,1,99999,1,225,225,225,1101,294,0,0,105,1,0,1105,1,99999,1106,0,300,1105,1,99999,1,225,225,225,1101,314,0,0,106,0,0,1105,1,99999,1008,226,677,224,1002,223,2,223,1005,224,329,1001,223,1,223,1007,677,677,224,102,2,223,223,1005,224,344,101,1,223,223,108,226,677,224,102,2,223,223,1006,224,359,101,1,223,223,108,226,226,224,1002,223,2,223,1005,224,374,1001,223,1,223,7,226,226,224,1002,223,2,223,1006,224,389,1001,223,1,223,8,226,677,224,1002,223,2,223,1006,224,404,1001,223,1,223,107,677,677,224,1002,223,2,223,1006,224,419,101,1,223,223,1008,677,677,224,102,2,223,223,1006,224,434,101,1,223,223,1107,226,677,224,102,2,223,223,1005,224,449,1001,223,1,223,107,226,226,224,102,2,223,223,1006,224,464,101,1,223,223,107,226,677,224,102,2,223,223,1005,224,479,1001,223,1,223,8,677,226,224,102,2,223,223,1005,224,494,1001,223,1,223,1108,226,677,224,102,2,223,223,1006,224,509,101,1,223,223,1107,677,226,224,1002,223,2,223,1005,224,524,101,1,223,223,1008,226,226,224,1002,223,2,223,1005,224,539,101,1,223,223,7,226,677,224,1002,223,2,223,1005,224,554,101,1,223,223,1107,677,677,224,1002,223,2,223,1006,224,569,1001,223,1,223,8,226,226,224,1002,223,2,223,1006,224,584,101,1,223,223,1108,677,677,224,102,2,223,223,1005,224,599,101,1,223,223,108,677,677,224,1002,223,2,223,1006,224,614,101,1,223,223,1007,226,226,224,102,2,223,223,1005,224,629,1001,223,1,223,7,677,226,224,1002,223,2,223,1005,224,644,101,1,223,223,1007,226,677,224,102,2,223,223,1005,224,659,1001,223,1,223,1108,677,226,224,102,2,223,223,1006,224,674,101,1,223,223,4,223,99,226 \ No newline at end of file diff --git a/day5/src/main.rs b/day5/src/main.rs new file mode 100644 index 0000000..0383843 --- /dev/null +++ b/day5/src/main.rs @@ -0,0 +1,82 @@ +use shared::intcode::{IntCode, SimulateStep, CELL}; + +fn run_air_conditioner(mut ic: IntCode) -> (Vec, CELL) { + let mut test_results = Vec::new(); + ic.next_input = Some(1); // air conditioner unit ID + loop { + match ic.simulate_step() { + SimulateStep::Finished => { + let diagnostic = test_results.pop().expect("missing diagnostic code"); + return (test_results, diagnostic); + }, + SimulateStep::Output(v) => test_results.push(v), + SimulateStep::WaitForInput => panic!("AirConditioner already initialized, no further input"), + } + } +} + +fn run_thermal_radiator_controller(mut ic: IntCode) -> CELL { + ic.next_input = Some(5); // thermal radiator controller ID + let diagnostic = ic.simulate_step().expect_output(); + ic.simulate_step().expect_finished(); + diagnostic +} + +fn main() { + let ic = include_str!("input.txt").parse::().unwrap(); + + println!("AirConditioner: {:?}", run_air_conditioner(ic.clone())); + println!("ThermalRadiatorController: {:?}", run_thermal_radiator_controller(ic)); +} + +#[cfg(test)] +mod day5test { + use super::*; + + fn parse(input: &str) -> IntCode { + input.parse().unwrap() + } + + fn run_single_io(code: &str, input: CELL) -> CELL { + let mut ic = parse(code); + ic.next_input = Some(input); + let result = ic.simulate_step().expect_output(); + ic.simulate_step().expect_finished(); + result + } + + #[test] + fn examples1() { + // no runnable examples + } + + #[test] + fn examples2() { + // position mode: input is 8? + assert_eq!(run_single_io("3,9,8,9,10,9,4,9,99,-1,8", 8), 1); + assert_eq!(run_single_io("3,9,8,9,10,9,4,9,99,-1,8", 7), 0); + assert_eq!(run_single_io("3,9,8,9,10,9,4,9,99,-1,8", 9), 0); + // position mode: input less than 8? + assert_eq!(run_single_io("3,9,7,9,10,9,4,9,99,-1,8", 8), 0); + assert_eq!(run_single_io("3,9,7,9,10,9,4,9,99,-1,8", 7), 1); + assert_eq!(run_single_io("3,9,7,9,10,9,4,9,99,-1,8", 9), 0); + // immediate mode: input is 8? + assert_eq!(run_single_io("3,3,1108,-1,8,3,4,3,99", 8), 1); + assert_eq!(run_single_io("3,3,1108,-1,8,3,4,3,99", 7), 0); + assert_eq!(run_single_io("3,3,1108,-1,8,3,4,3,99", 9), 0); + // immediate mode: input less than 8? + assert_eq!(run_single_io("3,3,1107,-1,8,3,4,3,99", 8), 0); + assert_eq!(run_single_io("3,3,1107,-1,8,3,4,3,99", 7), 1); + assert_eq!(run_single_io("3,3,1107,-1,8,3,4,3,99", 9), 0); + // position mode: (bool) input + assert_eq!(run_single_io("3,12,6,12,15,1,13,14,13,4,13,99,-1,0,1,9", 0), 0); + assert_eq!(run_single_io("3,12,6,12,15,1,13,14,13,4,13,99,-1,0,1,9", 1), 1); + assert_eq!(run_single_io("3,12,6,12,15,1,13,14,13,4,13,99,-1,0,1,9", 999), 1); + assert_eq!(run_single_io("3,12,6,12,15,1,13,14,13,4,13,99,-1,0,1,9", -1), 1); + // immediate mode: (bool) input + assert_eq!(run_single_io("3,3,1105,-1,9,1101,0,0,12,4,12,99,1", 0), 0); + assert_eq!(run_single_io("3,3,1105,-1,9,1101,0,0,12,4,12,99,1", 1), 1); + assert_eq!(run_single_io("3,3,1105,-1,9,1101,0,0,12,4,12,99,1", 999), 1); + assert_eq!(run_single_io("3,3,1105,-1,9,1101,0,0,12,4,12,99,1", -1), 1); + } +} diff --git a/day6/Cargo.toml b/day6/Cargo.toml new file mode 100644 index 0000000..a518b57 --- /dev/null +++ b/day6/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "day6" +version = "0.1.0" +authors = ["Stefan Bühler "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/day6/src/input.txt b/day6/src/input.txt new file mode 100644 index 0000000..7d6db8d --- /dev/null +++ b/day6/src/input.txt @@ -0,0 +1,1831 @@ +BYZ)LMV +2CT)GV2 +6RK)HK7 +RJJ)MVV +YFQ)4LC +Q58)D46 +D4T)3X8 +9GF)P89 +TFP)9VJ +5J9)YYK +WKB)6B4 +PM4)3G9 +NRG)QDB +Y2X)464 +T1S)MJ1 +RQ8)PD6 +XP7)3F2 +Y4Q)65H +KBG)ZMM +PCT)H5K +YPG)NZ6 +1KP)RFT +3Y7)ZN5 +BYH)RWH +1BQ)X8J +1VJ)MWT +GHH)7NX +CWZ)WC1 +5YB)3F5 +YZG)NQJ +18F)VZV +Z6Z)ZX9 +PT3)KWY +QR2)5QK +HQL)6LJ +JMG)S4N +4RL)PWG +G1H)J8W +WCX)RB3 +CR4)GX5 +4YN)BDT +ZQY)C8H +JRF)Y62 +GPY)4RN +6TF)R8Y +JWD)L9L +QQ5)ZMX +YY5)JFY +F15)JCJ +J71)ZT8 +9KF)JR8 +82X)449 +544)WKB +QRN)MKW +Y57)1KV +2C2)6C7 +QNQ)MKH +X1H)XK6 +QBH)GKH +FMY)9P9 +7DZ)Q9L +8HP)F3V +XR9)4XS +9CP)25Q +4PC)92N +87B)C3N +FFW)1CY +DFH)3VC +4RS)PM4 +LQF)J6P +ZXM)1K7 +WYZ)C22 +K1Y)YMZ +KXV)P93 +K4G)MYZ +RWM)VC1 +T8S)93S +21J)MHY +MF7)N4L +255)BDL +1MG)M4B +KJL)K7J +MLX)ZR7 +COM)WWS +WPN)LRP +DQ6)9XW +DMF)RJ3 +JNL)QMM +68T)QLS +NQ1)RP3 +18C)7DC +KRH)2RT +KGT)DPL +99Q)SWR +KRP)DCW +Y3P)PCT +PZJ)2RN +FTY)R6J +7W2)T32 +6ZZ)VZ3 +DPL)7KV +VX2)NH8 +2QF)GS5 +Q8S)SZ4 +VP4)8B8 +S6X)BYZ +RKK)QQ5 +LYN)S7C +ZZD)ZTP +59C)25M +3SD)KPS +GPY)5LY +B6Q)9M6 +SDL)SGT +VY6)J47 +KY6)WMB +M3Z)CWZ +287)6FY +JR8)5LP +DXG)8GP +5GV)Q15 +WQ3)65V +MHY)ZTD +2KN)1LQ +FPF)7W2 +NPB)6NL +T32)9TC +JTZ)YHM +VNT)QWK +GNZ)VBD +JCW)JRR +N2B)TVX +VF2)P38 +V5Z)3W5 +SST)9LZ +TRC)PYG +9VJ)SSX +8BD)TXH +WVM)XRV +Z5B)T93 +Z5L)T7K +H1V)YOU +NKX)54Z +4XS)DZK +D3V)S4K +Q62)FWW +SWD)DJT +2MJ)MXT +98J)17N +GDZ)YN6 +DRP)4PC +4L3)VNG +R7G)7M9 +WX5)MFM +2S9)BK5 +N9H)FDR +22T)Y3Y +L65)XLK +3DJ)S18 +S18)WHR +S1Q)GYH +BF9)99R +CDW)MB6 +FF7)44W +5X7)XSL +QG3)WC8 +6Q4)83D +LP6)NTH +V84)X6W +SGR)FFW +CVX)54C +6KD)RML +KZV)JRY +KY5)W9D +L4N)38R +GVD)KXQ +RCK)XNX +XRV)TKH +5JZ)G19 +Q5V)7VD +FYK)2MQ +VKV)8ZL +YQM)6XF +DKB)SND +HMZ)689 +W2S)2YB +SWR)ZZD +MGQ)TW3 +3Y5)HHP +DJT)H7L +VNV)HMZ +C11)PWB +M3Z)SZ2 +DHF)QG3 +J9D)LQF +3LC)5YB +XQQ)DRY +HWQ)27J +4W8)FMF +TN1)VXT +3GJ)FFB +LRP)NPB +LR2)5ZR +ZLJ)5V4 +KXN)5QM +TXH)T4W +VNX)9ZB +J47)FPC +D9Y)9M7 +MKB)5VF +RMC)VQ3 +SVL)Z1C +RGC)S44 +8G4)MZ8 +6XK)3HJ +R3V)FLX +M6N)Y81 +RP3)YVK +C3B)PFW +4LK)GR1 +1QQ)6CC +76J)1KP +DYY)QYR +PBQ)7X8 +VZV)F15 +9F2)ZJN +VBD)6B2 +6X5)WXY +23D)SP2 +TQ1)TFW +WM1)G1Q +5V4)9NS +2WJ)QQF +ZV7)PYK +MP4)5DD +YC6)KW8 +SQ9)XZX +X5Q)6NH +54D)2LN +9NS)X5J +7T8)SRT +V45)7TG +CL7)QDF +XV4)9GF +ZYQ)H8P +5GM)M5Z +QYG)XLH +QLS)29F +TTB)J6F +LGZ)9L7 +HTD)C3B +7VD)3Y7 +FLQ)GWK +SY9)PN1 +BHB)MLX +3X4)G43 +CV3)DHF +7DM)HFB +YM9)8W7 +3D9)CMT +SKV)64Z +DTY)GGD +HLV)71T +Z6Y)N6H +JB2)73Y +MVG)LGZ +VYV)463 +JCS)24L +MCX)5TY +RWQ)9BS +HVV)H4L +CN8)8FJ +YS5)NY2 +7CX)67Y +5JY)LFV +3GQ)2K4 +433)KY5 +FLQ)MQ7 +3FR)CSB +TW8)V5Y +TY9)5CG +PWZ)86Z +XTT)3GJ +TM5)X18 +NNT)KZV +RX9)DJY +RQS)TN1 +S11)TJ4 +FTV)KBG +9YC)VCG +B8W)H29 +5ZH)2V1 +MFH)3MG +92Q)M6C +XSY)QT2 +347)614 +DLP)BF9 +B1L)KRP +NKF)88J +DDN)P4C +2RG)JKJ +5GZ)Q8S +WJK)GTB +RQC)21J +J56)3GZ +25M)SGR +P29)M1W +3FZ)PXR +LLQ)RRJ +NLD)PW6 +9R7)Y4X +JCC)6ZZ +96D)1MF +TZV)JJ7 +2RN)Q48 +Z7G)GD9 +85F)JWD +PFW)L9K +6TF)S7G +DV4)9R7 +Z9X)R9X +DXD)M6N +KWS)DPK +1R6)Q58 +1B2)4LT +D9M)L4Z +JKJ)K4V +P36)V7J +GTZ)W24 +GX5)MZ4 +H73)QMT +VNG)4SZ +9TV)BD2 +CG6)SNS +WD1)HTT +9R3)4L3 +7KV)96D +8HW)QHV +85K)HML +B77)BFL +RMB)3WP +MVC)B84 +6LJ)N3J +VPH)4NG +14Q)23D +PCB)H1K +RRJ)9KY +W24)VHN +RDN)S54 +7ZS)C28 +FWZ)FRW +7JQ)NNY +492)CG6 +NWC)ZZW +JF2)YY5 +6B4)5KN +LZY)JTZ +P3V)4D7 +NVT)1MG +SGT)P2M +2NX)WJJ +K6L)64P +KXL)X7Z +R2D)NPQ +33H)P62 +7SL)HF4 +FYF)GKD +NT5)XN9 +6TL)BVZ +5YK)K4B +XDG)347 +B2P)8BF +B5Y)8NZ +DDC)TW6 +GY6)XYL +T7D)D1Q +MXJ)6D6 +6NG)P3P +XSQ)D4T +HY9)RMB +K6L)ND1 +RHL)MKB +KRH)QB7 +SMS)BBM +DCW)GG2 +SMZ)1SY +ZVP)C53 +CJJ)ZRB +3VC)RFC +F3V)713 +9KM)83Z +18C)22W +7R9)RCX +QMT)Q1R +1VW)J8N +VSD)FWZ +W61)RMC +NQ4)Z61 +LTN)KVP +YYK)V5S +1GP)7W6 +BJW)RQJ +FRW)5JZ +1JF)KTT +ND1)N6L +69L)R48 +TW6)NZC +6VG)RCM +FQR)5Z9 +JTD)G9N +SDY)5T3 +S33)925 +1SY)9SY +QF6)964 +2ZH)BTK +1GC)22S +DJT)FCD +SKD)K79 +VG1)QRQ +S7S)346 +8GP)YZG +25R)1QQ +G4G)RWM +BHW)4JF +DHG)S1S +NJP)L5Z +ZTP)V5B +2K4)8HK +RPQ)KRH +VXT)8TN +BVZ)P3T +HQ8)5GM +C22)PMP +2B2)RH7 +PWG)QWH +B45)VP4 +RSR)WLL +2RT)1D2 +V5Y)ZGH +N3W)ZR9 +N46)MD5 +CMT)D19 +YNF)7CZ +294)ZV9 +K4B)NPK +5LP)CXN +BY9)6DF +NZ6)2QM +LRJ)Q25 +9ZL)G5B +9VF)GLK +VH8)KJL +PWM)W5W +Z61)3SD +FWZ)1VX +YMZ)4V7 +LP7)WZF +3TC)BBV +6QK)58C +W6T)ZCM +LMV)3SG +RXW)X9C +FB3)QXV +SFF)54D +9V5)VDX +ZCX)HR1 +J6F)9CT +S7C)FSD +565)YTK +GW5)WSN +JMG)VKV +83Z)MLH +FH1)HJ3 +Y3Y)CDW +WJ8)Y4Q +54C)GYZ +46L)4F9 +M9B)H6Y +C97)86G +T7D)BHW +SFQ)H2J +Y3W)M44 +G1Q)MXZ +M6C)WWR +J76)4JB +H2D)85F +PT6)9VF +KK9)6K7 +FM1)QVX +QX7)7X1 +X5D)1J2 +YXG)VMD +VHP)FTY +P62)X6M +XBT)V45 +2PP)GHP +BD2)8BD +HCS)59C +38R)VF7 +7NX)SQJ +9YX)1GX +W92)PDC +3TH)WFL +2P8)W6T +H85)693 +9NL)CJY +P2M)TRF +35P)8VZ +R2G)2XZ +DRG)LGS +XBC)7JQ +LH1)QNQ +ZR7)ZXG +B5H)S1Q +YG1)LTN +LLY)74V +4RN)Z6Y +P9R)17B +TFW)N4Y +HLS)JZL +XC8)R7L +Z4Q)B5H +6NL)V63 +Y5S)T9X +F72)JHN +PDC)DD5 +XF4)RXW +QDF)2B2 +45M)4J1 +WXY)YL8 +17N)DRL +L9K)TDM +5NN)84K +J6P)SG1 +3L2)366 +RVX)WD1 +RML)TNL +WJC)7D7 +3Y5)DLP +2XZ)9R3 +YL8)H3V +WW7)NT5 +WP9)9MZ +5GQ)G1H +BR6)ZG6 +F48)QF8 +J8H)L57 +3HJ)6KD +S4M)J9H +P3T)DR2 +5BP)DYM +SHH)JTD +TKT)BJJ +9KW)LRC +SGT)Y8D +ZXG)9CP +BSF)LD6 +86G)ZD4 +NMS)H71 +WFH)SP5 +5LY)3BB +XJT)51Q +P6P)SMS +WMB)L23 +1GX)C34 +2MQ)4R5 +T66)FPF +ZZ8)6T8 +Z88)PBQ +2MS)X1H +MYZ)98J +Q48)JD3 +CSN)8J5 +XVZ)M6S +FHF)HTN +HCZ)D3V +9JZ)SDL +38P)HQL +9J9)CJK +MPM)M92 +N1X)B6Q +ZN5)JW8 +JG6)3RK +R2G)TJ3 +SKD)HLT +W8R)GBT +58C)RGC +ZCM)26D +MKM)5BP +71T)M1Z +C2M)KNC +SZ2)2YX +XJX)4B3 +2BK)76J +XQ6)FZV +VNK)4RS +7MQ)RMS +FCD)34C +TF3)L4F +23D)XJ2 +W87)62T +25M)QNS +DDS)VG1 +F17)SH4 +LL6)5T2 +JYP)DFH +5NN)V2X +4R5)Q5V +Q25)Z8H +K6Q)BDR +R2K)PZJ +FP7)2S1 +KMN)3VW +ZT8)H9X +W33)43Y +758)R7G +8QB)6LC +6LC)MHQ +88J)GLF +H1K)N12 +BTK)DMF +ZG6)TFR +ZPZ)8TT +DJY)LSZ +S1Q)FY1 +74K)MVC +B34)9BH +5BP)W1Z +N3W)TLS +1J2)43R +9PG)HLS +Q74)8M5 +2GH)6VG +Z5B)B45 +L5Z)433 +JFC)ZKY +VC1)HT7 +229)GW5 +QF8)FTC +YB8)THG +55B)27V +DF4)J9R +R7J)2FL +N15)H5C +RZN)5N3 +B8C)WBW +7M9)VN2 +8T1)7DM +VN9)5KR +FYJ)SKV +MVG)1VL +GRG)ZK2 +7HH)3S1 +Q85)9PG +BGZ)MK7 +H39)P3V +6CF)FLQ +PK6)VYV +9MN)6NP +FY4)PQJ +CR4)LH1 +7RL)RSR +JRY)1W6 +6RV)R11 +MTV)VSD +N26)LWB +C4F)3X4 +9BK)LK2 +PB3)WQB +JKJ)NWL +BDL)KBT +K35)9F2 +WXN)1RD +FK9)XBT +FZT)34D +5SL)B34 +6XK)CDV +7XH)7PC +YHM)6VR +7DC)X5D +FL1)3GQ +7FM)67R +6VG)XQQ +W1Z)2JK +Y1V)GZS +R5J)6JY +4YL)ZW2 +H2F)7CX +VXQ)HYQ +65V)3CP +KTT)WW7 +6V7)T8S +LFR)LP7 +5CG)GFB +VCG)LCY +KWY)C48 +2YX)JG8 +73Y)6F1 +QJT)DGK +VJB)Z7G +8NZ)CDB +GXW)18C +WVM)JSX +XLK)9KF +JTD)PT6 +8G3)TJ9 +67R)YZH +J7G)5VG +4JB)5GK +R6P)7HH +X7Z)N8X +LDL)294 +H2J)T11 +DZK)XTT +8VZ)HWQ +DZ2)GKV +NTX)FP7 +2JK)TTB +FS9)22T +X6D)DC3 +LK2)CS3 +ZNQ)RPM +TW3)BK4 +MLH)NWC +2WN)RVX +M16)BJW +FDR)K6L +7T8)ZWX +RPM)4LK +3F5)BZT +TKK)KJ8 +6CR)C5V +XHY)X9T +ZG9)VFJ +D5Z)S82 +HJ3)1GP +JD3)BB2 +ZKY)6RK +9M6)175 +XM7)KSZ +ZZN)R2F +5T2)VY6 +1NY)878 +GS5)B61 +MNS)N6Z +MVF)P74 +LR9)PXG +572)229 +9GD)HSL +S4N)XBC +283)TRC +SC1)ZCX +HLT)MSD +9M6)SFQ +SJD)RBR +7F7)RPQ +PYG)BPR +X6M)RSH +35P)VSJ +CXN)4QX +GWG)KZQ +SWL)DKK +QHV)1B2 +BSC)H2D +1K8)B3G +Z78)LPF +K5Z)7DZ +BXR)HBQ +T8T)LNW +Y2V)3Q9 +BPR)HCS +TDM)DHS +MKH)1NJ +T3N)VF2 +GNH)BKP +MQ7)74K +4NL)YB8 +449)LV3 +NXG)WD4 +TXX)3L2 +PMM)TD9 +PYK)1NY +9MZ)CHL +K79)RL1 +F3V)XHY +MXM)FYF +V2X)SZR +ZZN)XBJ +2P5)XH9 +XYL)4XL +P61)MMF +NWL)P9R +2DQ)1VJ +2G6)2MS +B45)GRG +BB2)JC9 +H3J)LLQ +TD9)NJP +PQJ)MT7 +5R9)2BM +RFD)WB8 +8SP)WGJ +SDC)RY4 +ZTJ)PT3 +4PQ)VNX +5ZH)BFW +27J)Q62 +SG1)XQ6 +CHT)6NG +WYV)7FM +TF9)ZP4 +K8C)L4N +86G)VQD +GBG)FFH +5N3)TF3 +5KR)WQQ +ZLY)KB8 +CR2)TCV +ZWX)KMN +DL8)MGQ +PCL)L6H +B1Q)T2G +VNY)WTY +NGL)JBQ +HTN)YML +F8S)L4V +MWR)Z9H +ZGH)7ZS +RJG)QMB +35R)CR2 +9PD)P6P +9BH)J56 +K9G)P41 +K7F)WMP +SYM)K26 +XF3)BQF +RY4)N75 +XRQ)3NN +X8J)5SL +W6V)ZHV +Y3P)M14 +CS3)JRF +LQJ)LYN +V5Y)BRW +8J5)GHH +HFB)JF2 +V63)3YQ +GPX)572 +6GD)7F7 +8HK)B8W +68Y)QGR +ZK2)VL1 +QMM)J7G +198)38P +WTY)8RC +WFL)QV2 +K6B)TXX +3F2)QF6 +QDF)TQL +22T)3KS +8BH)2P8 +7WP)VV3 +3TH)HM1 +CDB)F8C +SMZ)M5J +MWJ)4FL +X4J)8SP +H71)WZC +356)1HX +Y9Z)RLR +M1Z)SDC +L9L)RDN +9PD)GNB +DGK)9TV +DD5)Q5F +XR5)6TF +6NH)SF8 +8ZL)SQ9 +FFH)K5L +6D6)36R +N7P)5Z3 +CDV)BPY +FKR)DTY +J8W)1S2 +F7M)HLV +17B)XVZ +9CT)XHF +XL4)GNZ +XZX)M16 +1GB)MVG +C92)K5N +Q2W)VLT +54N)S7S +GWK)T1D +6VB)3V6 +24L)BMT +VN2)N2G +9RX)SDY +7ZC)4RL +LN5)PK7 +BB9)TB5 +W4Y)NC8 +3SG)PKC +SNS)Q9N +JK3)FB3 +HK7)QWB +MJ4)TQ4 +GWP)RQT +T4W)9RX +TD9)9ZL +XF3)FYT +4LC)KLH +X6W)69V +WJJ)T52 +QB7)G8R +1W6)WQM +QW7)FMY +6GR)1QM +ZMM)9GD +ZV9)9YX +1NJ)HTK +XN9)P1R +G8R)D12 +FPC)XSY +6DF)WPZ +87M)ZG9 +QV2)DKB +H5C)GDZ +BDR)W2S +C53)3D9 +L4F)VB5 +V5B)3MR +PZJ)T99 +FFB)LRJ +9HZ)G1Z +BBV)2GH +65H)Y9Z +X4J)CHT +3X8)FLB +3F3)T7D +W7Q)9M1 +ZT4)FPP +Q5F)QYG +FTV)86Q +JQ5)L95 +53H)RH9 +PN1)94Z +MT7)3NM +DKD)YRQ +DR5)CVK +LXT)T3N +1D2)RQC +1BK)G87 +G95)JK3 +P3P)4FP +8DH)TKT +F2K)L1Z +KNC)N1P +PW6)RX9 +4SZ)GF8 +YVK)2BK +WHR)6RV +8PS)DZ2 +KB8)Z3Y +4FP)XP7 +Z5Q)46L +6C7)544 +VJ6)SK8 +VL5)L65 +8BF)VZX +S4K)QW4 +M4B)G3W +X33)VVD +WSN)GBG +SP5)YXQ +4XL)84M +W5W)Y1Q +S82)68S +HNN)GPY +6LD)X5Q +FPF)JVL +1CY)3Y5 +D3F)S6X +WJ8)2WN +26B)YL7 +4NF)NDC +Q15)PSF +52T)FM1 +VHN)9V5 +MSD)TWC +7D7)KYK +175)J71 +L4Z)HY9 +4HR)BSF +ZMY)TJC +RCM)QRN +HBQ)XJT +64P)ZXS +QDJ)6GD +J71)NSN +3WP)3TH +NPK)Y6M +6XF)4ZL +QT2)MWR +N75)WYV +GFB)S29 +62Z)9NL +DXS)GWP +71H)2CT +JWD)FWM +MK3)GVD +9M1)442 +SRT)D8M +BRW)P4H +M4H)9BV +ZVD)5GZ +WXP)X33 +LPS)Y3P +R9D)RVH +NL6)Y1V +N53)WQ3 +SK8)FS9 +DY8)52Y +D75)CWF +Q9L)VJH +H4R)KXN +4NG)P29 +74G)Z67 +GX5)NVT +DHS)ZLY +LM3)ZYQ +9P9)255 +KBT)JCS +CVK)Z9X +TCW)F8N +HJY)LC8 +KW8)K17 +F82)WYZ +D3P)ZVP +SJX)NGL +74V)R2K +LWB)R9D +14J)71N +9BS)43Z +8GP)3F3 +QMB)RDW +DR1)RWQ +GY7)BXR +255)RHC +XLJ)3R3 +P9C)NMS +KB8)5S5 +KLZ)RMG +1WZ)XLJ +W1Z)284 +XJ2)DL1 +N58)XDG +HYD)B5Y +NDC)RKK +4FL)XSQ +CDL)Q85 +C62)WF5 +94C)DVP +84T)2YY +ZTD)PJP +S82)DKD +6VR)CBC +M6S)W33 +949)MFH +4R5)SWP +J98)XZ7 +F8C)JCW +BHX)18F +WC1)KGT +9XW)Z2L +TCW)84X +ZCV)5T7 +K6Q)3NT +Q9N)FSS +8TN)VKD +XF4)G56 +J5C)LDL +D46)CGG +TJ3)96V +T5H)D8Y +YMN)QJT +1QM)F2K +RWH)KXL +T52)79Y +FSD)KXV +XNX)6CR +713)3TC +NLF)4LR +KY5)H4R +CWF)2CD +X9C)2S9 +ZX9)ZQY +JFY)K7H +5HT)Z1L +9TV)HYD +8RC)C77 +8MJ)3XG +5L7)7RL +VB4)DV3 +3Y3)7WP +HHP)5GQ +XH9)2PP +VF7)GWG +BPY)7ZC +LHY)YNF +PPS)WVK +ZHV)JQF +TKH)B2P +QRN)3FZ +8B8)S7K +T7K)SJD +S7K)YGQ +J8N)R7J +4FL)7XD +648)71B +G56)MPM +P38)68T +5H7)5B9 +TWC)PB3 +XRV)FK9 +WWR)KK9 +XK6)F2Q +FYT)7T8 +N85)54N +8DZ)45M +G2F)92Q +LCY)ZZ8 +PLD)LM3 +RQJ)4WJ +J6L)315 +Y6M)KY6 +C53)3DB +MWT)Y8S +Q62)H2F +6T8)B1J +43Z)5P4 +1HX)M8B +TVX)84T +2YB)Q68 +36R)V6Q +T9X)YG1 +2YY)NQ1 +5YP)GFM +QM9)J8H +JG8)16C +5VG)N9H +M16)JST +RJ3)HR2 +29J)N6Y +44W)VJ6 +9M7)F96 +Z67)3RW +WLL)NTX +CSB)4CL +CWP)GGC +84K)W7Q +QNQ)N25 +NWR)CSN +J9H)PG5 +DFW)K4G +FTC)68Y +VF7)4W8 +VXT)2NX +G5B)FH1 +DKK)DRG +C77)DJ1 +VZ3)XD3 +JVC)NRG +FLB)SHH +71T)MP4 +9NL)VNV +RDQ)RJJ +GVN)ZT4 +84T)MF7 +ZP4)4YN +WT2)3LC +4D7)4NF +5S5)9J9 +MB6)N9N +MN3)B99 +BFL)4XV +BN3)688 +5NJ)DPN +XK6)C92 +D8M)KWS +RPV)W5S +GX8)FTH +VCT)6Q4 +FWM)RDQ +86Z)1M5 +46L)JNL +BX1)1R6 +DV3)DXQ +JJ7)XFL +K5L)7MQ +X9J)SJX +NNY)MN3 +RH9)3DJ +GG2)C2M +JR8)KLZ +8M5)2SN +H9X)BYH +R48)ZZ2 +YGQ)55P +BZT)MXJ +N2G)VQJ +VQD)NWR +714)565 +Q6W)27Y +3NW)NL6 +H6H)F5C +4JF)YM9 +D3L)T6S +5QJ)QDJ +QYR)74G +HTT)VB4 +9L7)G2F +VVY)BR6 +G43)BSC +M8R)S3F +QF6)DCN +2C2)38G +BK4)VL5 +6K7)6H7 +5TY)96L +JF2)R2G +FLX)7R9 +FFX)2MJ +M14)C97 +34C)Q6W +HF4)W8T +K7J)TF9 +464)4NX +MKW)6VB +1S2)YPG +JK3)1JF +6ZW)WJ8 +38G)XNL +7F7)WXP +JST)2ZH +LNM)N26 +925)GC9 +H29)LHG +5B9)K1Y +ZD4)RH3 +NY2)M1R +HF4)2G6 +4L6)FKR +H2D)2KN +48L)7SQ +S1T)4YL +DJ1)XL4 +B84)1RM +92N)SY9 +7X1)MJ3 +X32)WVM +TJC)Q1T +YTK)MWQ +WB8)ZV7 +H5K)6LD +B66)1BQ +4LB)D3F +Z3Y)SQB +5Z3)2P5 +X6L)BNH +7DR)TQ1 +SDC)JY4 +RPC)SST +DXQ)WCX +WH3)YC6 +JTZ)DYY +9TL)QW7 +LRP)758 +TLS)Y2V +K5N)D75 +MWQ)BX1 +TRF)VLZ +DYM)PCL +JQF)9T7 +D12)JG6 +3DB)NQ4 +VKD)8BH +7XD)WM1 +T99)RKQ +4LJ)RHL +P4C)K66 +TWX)4TX +SY9)VJB +L6H)MVF +LV3)1FB +71N)2PL +VFJ)F82 +116)95T +VSJ)LR2 +6CC)W8R +R84)HNK +4TX)YWC +HTK)82X +P6P)B1G +Z4L)X9J +WVK)HNN +BQF)X6L +734)6V7 +LY2)HVV +Y8D)S1T +1SN)4LJ +3KS)6BX +797)GY6 +HR2)P6J +NQJ)C4F +3NT)3FR +2PP)Z5Q +F8N)8TY +3GZ)4LB +BJJ)33H +LFV)QL2 +TJ8)P9C +QWH)JQ5 +KJ8)4KV +C7W)S33 +Y4X)FTV +Z2L)JFC +B77)5QJ +N8X)CDL +RQT)HYC +71B)D9M +2LN)LGF +YKR)3MX +H6Y)116 +X5J)LBS +2BY)385 +N6Z)C98 +5GN)9KW +9TC)RQ8 +LPS)RBD +T32)YMN +W3J)Z6Z +7CZ)NRV +MGQ)DXS +HQK)2DV +HNW)8ZC +D3L)SYM +H3V)F84 +VL1)BY9 +LK9)HTD +VHQ)WX5 +DR2)W6V +3MX)2BY +2PL)5GV +V5S)R5J +JLB)FL1 +TQL)YQM +SWP)2DQ +29F)8DH +W7W)H39 +WGJ)5NJ +FQR)P36 +PG5)DY8 +WZC)F2V +ZJN)Y2X +P6J)N46 +RSH)5X7 +7K2)PC9 +1WY)LDR +3X8)H3J +R7T)LLY +Q1T)QRM +9M7)K8C +R2P)V43 +NRV)GKT +SQB)198 +2DK)Y5S +JVL)9BY +WPZ)LR9 +ZXS)2VP +GY6)JJ6 +XD3)3NW +XNL)4N5 +86Q)YKR +2FL)1K8 +F2D)PSP +16C)LY2 +TCV)TCW +JSX)71H +S29)W7W +96L)VX2 +YWC)C62 +68S)99Q +MZ4)2MX +WCX)9TL +D19)C11 +9SY)NNT +K26)RQS +YML)SMZ +K58)6X5 +W1B)M4H +3XG)J2R +PMP)V84 +Q25)CN8 +QWB)K58 +284)9BK +RCX)2C2 +1SQ)N3D +RFD)TWX +5F6)VN9 +22W)WXN +QNS)JBB +GKT)TKK +1WZ)DXG +QZL)VVY +9BK)5YP +1VX)X32 +KZQ)5JY +DCN)F8X +Y6M)N58 +ZP4)JLB +N9Q)8QB +VL1)QBH +LYN)8M7 +V6Q)RZN +2FL)DF4 +F48)TNH +MXZ)GXW +M92)YLD +MSD)CWP +F9P)FQR +W8T)R7T +RDW)TY9 +HNK)SVL +T3R)JWR +XLH)MBV +KLH)V5Z +WF5)Y3R +GR1)8RT +132)DR1 +HTT)4HR +27V)8HW +FSH)WT2 +X9J)5YK +1RM)PTQ +DVP)F72 +5Z3)BB9 +VQ3)WFH +QDB)X3S +F1C)S4M +MK7)PWZ +YL7)Y6R +961)WQ4 +GZS)1GC +ZRB)CR4 +62T)BGL +4KV)XRQ +GNB)62Z +F9P)TJ8 +T93)8DZ +94G)5GN +ND1)NKX +3NM)K6B +QRQ)MK3 +GTB)DXD +2CD)XC8 +X6M)J9D +CBC)5MV +JCJ)VNT +XBC)RFD +GFM)HNW +DGK)8B5 +346)7XH +GF8)GD5 +X53)85K +GD5)PMM +83Y)JB2 +5Z9)ZXW +BJJ)H85 +XR5)KGW +Z9H)YFQ +F58)HPW +9M1)RCK +VV3)3YX +36M)W61 +KDR)1SQ +3G9)D3P +CGG)FHB +PKC)3Y8 +JJ6)VPH +FSS)ZCV +Z2L)3P9 +XLJ)R3V +P93)KQQ +K17)JCC +7DM)TZV +N12)XMC +V7J)MJ4 +64F)83Y +S7G)98Y +84M)LSD +KWN)QR2 +3W5)F7M +ZW2)QPD +XFL)9MN +MW6)LK9 +PMP)XF3 +X9T)N9Q +CSN)14Q +3Y8)GY7 +DRP)GPJ +LGS)XM7 +RBF)QZL +VLZ)Z88 +95T)P61 +N6H)FHF +WMP)DFW +N6Y)87B +27Y)F8S +QD6)WJC +WD4)J5C +PD6)WGH +4LT)RJG +LPF)BHX +JBQ)D3G +THG)CVX +QWK)G1G +WWS)5HT +D3G)PCB +RMS)FSH +689)69Y +LSZ)F1C +315)FY4 +HYC)N7P +G19)MW6 +6F1)QX7 +6JY)DHG +FWW)F9P +F2Q)7D5 +83X)LL6 +NH8)WT9 +XTG)WP9 +4B3)MKM +WQB)TW8 +169)R84 +4CL)M8R +ZRB)N2B +LD6)Y57 +L57)B1Q +8RT)LN5 +MJ3)9DW +5MV)55B +3Q9)VHQ +R8Y)F2H +614)734 +22S)FF7 +W5S)4L6 +JHN)6ZW +LDJ)VH8 +T11)GVN +2VP)FZT +6H7)2QF +SDL)VCT +94Z)5J9 +TDH)FYJ +R6J)F2D +KPS)T8T +L6H)HQK +5ZR)14J +HML)648 +M1W)Q2W +MVV)169 +QPD)CV3 +QVX)LHY +WC8)RLH +51Q)8T2 +8GF)J76 +W92)PPS +96V)R6P +ZZ2)WPN +442)92Y +2S1)K35 +TB5)7TM +43Y)949 +F2H)JMG +K4V)DQ6 +JY4)R3X +GD5)7KF +MZ8)DRP +BK5)KDR +CJK)HQ8 +Y88)WJK +GLF)H73 +PSF)94C +Y79)17K +LNW)LDJ +TNH)N15 +MBV)K9G +VB5)SAN +6X7)RPV +54Z)SFF +3P9)R2P +YLD)961 +GPJ)PK6 +M5J)BNZ +N3J)8CH +YXQ)PWM +TNL)KL2 +JWR)D5Z +Z8B)N53 +QRM)WH3 +N1P)36M +714)64F +92Q)W49 +GGD)8HP +PK7)FLN +K7H)CKT +9V5)DDS +Y8S)R2D +F8X)N3W +S1S)DR5 +99R)4NL +R3X)5ZH +79Y)8V7 +V43)1B9 +2S1)H6H +8TT)9PD +PXG)7SL +9DW)DGZ +7X1)F1F +3V6)YXG +QKF)HJY +2DK)2FC +SQJ)DDC +4LR)S38 +MJ1)KTK +J9R)F48 +Q1R)F58 +FTY)QKF +P1R)1WZ +34D)XTG +QY8)LXT +MT7)Z4Q +SXQ)Q74 +8B5)BN3 +HVV)XF4 +TJ9)W1B +64Z)NXG +BFW)9KM +2QM)35H +NPQ)X53 +NGL)VNY +F7M)J6L +M8B)W87 +3CP)LPS +4QX)1RL +BKP)D9Y +8W7)FYK +Y62)3Y3 +Q68)6X7 +CJY)35R +8V7)ZPZ +L4V)B2T +FLN)1VW +S38)83X +RH7)9JZ +TQ4)6B3 +P89)MCX +SP2)RBF +ZMX)DL8 +BMT)6LB +PXR)1GB +8ZC)B8C +3BB)MXM +43R)W92 +Z8H)8GF +LSD)1KD +GD9)VHP +GHP)356 +KZY)Y3W +GC9)JYP +FZV)5L7 +1RL)2DK +35H)XJX +5GM)C7W +5DD)ZTJ +6LB)SC1 +693)T3R +FY1)4PQ +QL2)TMP +DGZ)ZXM +1B9)T96 +43Z)492 +C98)Z5B +L95)K6Q +3MG)YS5 +366)ZJJ +B6P)XV4 +J6D)TM5 +6NP)Z8B +4XV)53H +4B3)SWL +1VL)CJJ +F2V)5NN +XBJ)DDN +B3G)W3J +7TG)KZY +4V7)VNK +W9D)9YC +4J1)VZ6 +M5Z)94G +Y1Q)DV4 +KZY)ZLJ +7KF)TSB +GKH)JVC +FLB)1SN +DRY)8PS +WT9)T5H +69Y)8G3 +7G4)S11 +QQF)QM9 +8FJ)1BK +HSL)TFP +LHG)LZY +VJB)2WJ +XSL)GX8 +P74)XR9 +2V1)52T +WGH)69L +L1Z)J98 +VNV)HCZ +NG6)NLF +RBR)X4J +X18)35P +LBS)HK3 +7TM)NG6 +1RD)25R +6BX)29J +BNH)VF1 +QXV)797 +M1R)X6D +3R3)6CF +7D5)1WY +MHQ)B6P +MW3)XZK +G3W)LP6 +16C)NLD +9ZB)SXQ +2MX)K5Z +3Z2)7K2 +JLP)CL7 +17K)VXQ +FFB)G91 +RFC)48L +TMP)9HZ +T6S)Y79 +DVP)283 +CHL)QD6 +ZJJ)LFR +R2F)N85 +HT7)KWN +3YX)W4Y +BGL)K74 +5T3)287 +Z1L)ZNQ +C28)MW3 +385)MNS +GGC)6FJ +YRQ)8T1 +5F6)Z4L +8TY)5R9 +LC8)132 +688)BHB +55P)TDH +K74)GTZ +VZX)714 +N1X)2RG +MMF)26B +DV4)G4G +R9X)Z78 +RVH)B66 +LSZ)XR5 +TC1)6XK +98Y)LQJ +83D)BWG +NC8)D3L +BDT)6GR +SH4)SKD +7SQ)T1S +NKF)87M +5KN)FFX +DFH)TC1 +8T2)F17 +D8Y)5H7 +C34)H1V +HM1)ZZN +N25)T66 +3VW)GNH +RL1)N1X +YN6)5F6 +GKD)1JZ +18F)JLP +PQJ)6TL +Z78)MTV +BBM)ZMY +B1G)Y88 +JC9)NKF +QNS)7DR +463)8MJ +3MR)GPX +ZXW)PLD +BF9)7G4 +ZKY)Z5L +QGR)MWJ +NSN)SWD +C5V)3Z2 +VDX)M3Z +ZR9)K7F +2BM)RPC +GYH)QY8 +JBB)6QK +G9N)B77 +RPC)M9B +F84)B1L +1JZ)G95 +SND)8G4 +D1Q)J6D +N9N)LNM +YZH)V8R +TJ4)ZVD +2V1)BGZ diff --git a/day6/src/main.rs b/day6/src/main.rs new file mode 100644 index 0000000..774fe0d --- /dev/null +++ b/day6/src/main.rs @@ -0,0 +1,87 @@ +use std::cell::Cell; +use std::collections::{HashMap, HashSet}; + +fn parse(s: &str) -> impl Iterator { + s.split_ascii_whitespace().map(|l| { + let mut x = l.splitn(2, ')'); + let a = x.next().unwrap(); + let b = x.next().unwrap(); + (a, b) + }) +} + +fn count_orbits_get(orbit_relations: &HashMap<&str, (&str, Cell>)>, object: &str) -> u32 { + if object == "COM" { return 0; } + let around = &orbit_relations[object]; + if let Some(n) = around.1.get() { return n; } + let n = count_orbits_get(orbit_relations, around.0) + 1; + around.1.set(Some(n)); + n +} + +fn count_orbits(input: &str) -> u32 { + let orbit_relations: HashMap<&str, (&str, Cell>)> = parse(input).map(|(a, b)| (b, (a, Cell::new(None)))).collect(); + let mut sum = 0; + for (_object, around) in &orbit_relations { + if let Some(n) = around.1.get() { + sum += n; + } else { + let n = count_orbits_get(&orbit_relations, around.0) + 1; + around.1.set(Some(n)); + sum += n; + } + } + // println!("Map: {:?}", orbit_relations); + sum +} + +fn count_orbit_transfers(input: &str) -> u32 { + let orbit_relations: HashMap<&str, (&str, Cell>)> = parse(input).map(|(a, b)| (b, (a, Cell::new(None)))).collect(); + for (_object, around) in &orbit_relations { + if around.1.get().is_none() { + let n = count_orbits_get(&orbit_relations, around.0) + 1; + around.1.set(Some(n)); + } + } + // println!("Map: {:?}", orbit_relations); + let mut you = HashSet::new(); + let mut object = "YOU"; + loop { + if "COM" == object { break; } + object = orbit_relations[object].0; + // println!("YOU orbit (...) {}", object); + you.insert(object); + } + object = "SAN"; + loop { + if you.contains(&object) { + let you = orbit_relations["YOU"].1.get().unwrap(); + let san = orbit_relations["SAN"].1.get().unwrap(); + let bottom = orbit_relations[object].1.get().unwrap(); + return (you - bottom - 1) + (san - bottom - 1); + } + object = orbit_relations[object].0; + // println!("SAN orbit (...) {}", object); + } +} + +fn main() { + let input = include_str!("input.txt"); + println!("Orbit sum: {}", count_orbits(input)); + println!("Orbit transfers: {}", count_orbit_transfers(input)); +} + +#[cfg(test)] +mod day6test { + use super::*; + + #[test] + fn examples1() { + assert_eq!(count_orbits("COM)B B)C C)D D)E E)F B)G G)H D)I E)J J)K K)L"), 42); + } + + #[test] + fn examples2() { + assert_eq!(count_orbit_transfers("COM)B B)C C)D D)E E)F B)G G)H D)I E)J J)K K)L K)YOU I)SAN"), 4); + } +} \ No newline at end of file diff --git a/day7/Cargo.toml b/day7/Cargo.toml new file mode 100644 index 0000000..6d42b8d --- /dev/null +++ b/day7/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "day7" +version = "0.1.0" +authors = ["Stefan Bühler "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +itertools = "0.8.2" +shared = { path = "../shared" } diff --git a/day7/src/input.txt b/day7/src/input.txt new file mode 100644 index 0000000..beb7fed --- /dev/null +++ b/day7/src/input.txt @@ -0,0 +1 @@ +3,8,1001,8,10,8,105,1,0,0,21,34,51,64,73,98,179,260,341,422,99999,3,9,102,4,9,9,1001,9,4,9,4,9,99,3,9,1001,9,4,9,1002,9,3,9,1001,9,5,9,4,9,99,3,9,101,5,9,9,102,5,9,9,4,9,99,3,9,101,5,9,9,4,9,99,3,9,1002,9,5,9,1001,9,3,9,102,2,9,9,101,5,9,9,1002,9,2,9,4,9,99,3,9,1001,9,1,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,99,3,9,101,1,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,99,3,9,101,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,2,9,4,9,99,3,9,1001,9,1,9,4,9,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,99 diff --git a/day7/src/main.rs b/day7/src/main.rs new file mode 100644 index 0000000..969ef6c --- /dev/null +++ b/day7/src/main.rs @@ -0,0 +1,94 @@ +use shared::intcode::{IntCode, SimulateStep, CELL}; + +pub fn run_stages(ic: &IntCode, phases: &[CELL]) -> CELL { + let mut value = 0; + for ndx in 0..5 { + let mut stage = ic.clone(); + stage.next_input = Some(phases[ndx]); + stage.simulate_step().expect_wait_for_input(); + stage.next_input = Some(value); + value = stage.simulate_step().expect_output(); + stage.simulate_step().expect_finished(); + } + value +} + +pub fn run_feedback_stages(ic: &IntCode, phases: &[CELL]) -> CELL { + let mut stages = [ ic.clone(), ic.clone(), ic.clone(), ic.clone(), ic.clone() ]; + // init all with phase + for ndx in 0..5 { + stages[ndx].next_input = Some(phases[ndx]); + stages[ndx].simulate_step().expect_wait_for_input(); + } + + let mut output = 0; + stages[0].next_input = Some(output); + let mut current_ndx = 0; + loop { + match stages[current_ndx].simulate_step() { + SimulateStep::Output(v) => { + current_ndx = (current_ndx + 1) % 5; + stages[current_ndx].next_input = Some(v); + if current_ndx == 0 { + // remember last final output + output = v; + } + }, + SimulateStep::WaitForInput => { + panic!("Can't wait for new input before generating one"); + }, + SimulateStep::Finished => break, + } + } + + assert_eq!(current_ndx, 0, "first amplifiert should be first to stop"); + for ndx in current_ndx+1..5 { + stages[ndx].simulate_step().expect_finished(); + } + + output +} + +pub fn best_amplifier(ic: &IntCode) -> (Vec, CELL) { + use itertools::Itertools; + (0..5).permutations(5).map(|phases| { + let value = run_stages(ic, &phases); + (phases, value) + }).max_by_key(|(_, value)| *value).unwrap() +} + +pub fn best_feedback_amplifier(ic: &IntCode) -> (Vec, CELL) { + use itertools::Itertools; + (5..10).permutations(5).map(|phases| { + let value = run_feedback_stages(ic, &phases); + (phases, value) + }).max_by_key(|(_, value)| *value).unwrap() +} + +fn main() { + let ic = include_str!("input.txt").parse::().unwrap(); + + let (phases, max_value) = best_amplifier(&ic); + println!("Max Value: {} (from phases: {:?}", max_value, phases); + + let (phases, max_value) = best_feedback_amplifier(&ic); + println!("Max Feedback Value: {} (from phases: {:?}", max_value, phases); +} + +#[cfg(test)] +mod day7test { + use super::*; + + #[test] + fn examples1() { + assert_eq!(best_amplifier(&"3,15,3,16,1002,16,10,16,1,16,15,15,4,15,99,0,0".parse::().unwrap()), (vec![4,3,2,1,0], 43210)); + assert_eq!(best_amplifier(&"3,23,3,24,1002,24,10,24,1002,23,-1,23,101,5,23,23,1,24,23,23,4,23,99,0,0".parse::().unwrap()), (vec![0,1,2,3,4], 54321)); + assert_eq!(best_amplifier(&"3,31,3,32,1002,32,10,32,1001,31,-2,31,1007,31,0,33,1002,33,7,33,1,33,31,31,1,32,31,31,4,31,99,0,0,0".parse::().unwrap()), (vec![1,0,4,3,2], 65210)); + } + + #[test] + fn examples2() { + assert_eq!(best_feedback_amplifier(&"3,26,1001,26,-4,26,3,27,1002,27,2,27,1,27,26,27,4,27,1001,28,-1,28,1005,28,6,99,0,0,5".parse::().unwrap()), (vec![9,8,7,6,5], 139629729)); + assert_eq!(best_feedback_amplifier(&"3,52,1001,52,-5,52,3,53,1,52,56,54,1007,54,5,55,1005,55,26,1001,54,-5,54,1105,1,12,1,53,54,53,1008,54,0,55,1001,55,1,55,2,53,55,53,4,53,1001,56,-1,56,1005,56,6,99,0,0,0,0,10".parse::().unwrap()), (vec![9,7,8,5,6], 18216)); + } +} diff --git a/shared/Cargo.toml b/shared/Cargo.toml new file mode 100644 index 0000000..288c30c --- /dev/null +++ b/shared/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "shared" +version = "0.1.0" +authors = ["Stefan Bühler "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/shared/src/intcode.rs b/shared/src/intcode.rs new file mode 100644 index 0000000..6420045 --- /dev/null +++ b/shared/src/intcode.rs @@ -0,0 +1,148 @@ +const OP_ADD: CELL = 1; +const OP_MUL: CELL = 2; +const OP_INPUT: CELL = 3; +const OP_OUTPUT: CELL = 4; +const OP_JUMP_IF_TRUE: CELL = 5; +const OP_JUMP_IF_FALSE: CELL = 6; +const OP_LESS_THAN: CELL = 7; +const OP_EQUAL: CELL = 8; +const OP_HALT: CELL = 99; + +pub type CELL = i64; +type Mode = u8; + +#[derive(PartialEq, Eq, Clone, Debug)] +pub enum SimulateStep { + Finished, + WaitForInput, + Output(CELL), +} + +impl SimulateStep { + pub fn expect_output(self) -> CELL { + if let Self::Output(v) = self { + return v; + } + panic!("Expected Output, got {:?}", self); + } + + pub fn expect_finished(self) { + if let Self::Finished = self { return; } + panic!("Expected Finished, got {:?}", self); + } + + pub fn expect_wait_for_input(self) { + if let Self::WaitForInput = self { return; } + panic!("Expected WaitForInput, got {:?}", self); + } +} + +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct IntCode { + pub ip: usize, + pub next_input: Option, + pub data: Vec, +} + +impl IntCode { + #[inline(always)] + fn fetch(&mut self, mode: Mode) -> CELL { + let imm = self.data[self.ip]; + self.ip += 1; + match mode { + 1 => imm, + _ => self.data[imm as usize], + } + } + #[inline(always)] + fn store(&mut self, mode: Mode, value: CELL) { + let addr = self.ip; + self.ip += 1; + match mode { + 1 => self.data[addr] = value, + _ => { + let addr = self.data[addr] as usize; + self.data[addr] = value; + }, + } + } + + fn binop(&mut self, op: F, modes: [Mode; 3]) + where + F: FnOnce(CELL, CELL) -> CELL, + { + let src1 = self.fetch(modes[0]); + let src2 = self.fetch(modes[1]); + self.store(modes[2], op(src1, src2)); + } + + pub fn simulate(&mut self) { + assert_eq!(self.ip, 0); + assert!(self.next_input.is_none()); + self.simulate_step().expect_finished(); + } + + pub fn simulate_step(&mut self) -> SimulateStep { + loop { + let modes = self.data[self.ip]; + self.ip += 1; + let op = modes % 100; + let modes = modes / 100; + let mode1 = (modes % 10) as Mode; + let modes = modes / 10; + let mode2 = (modes % 10) as Mode; + let modes = modes / 10; + let mode3 = (modes % 10) as Mode; + let modes = [mode1, mode2, mode3]; + + match op { + OP_ADD => self.binop(|a, b| a + b, modes), + OP_MUL => self.binop(|a, b| a * b, modes), + OP_LESS_THAN => self.binop(|a, b| if a < b { 1 } else { 0 }, modes), + OP_EQUAL => self.binop(|a, b| if a == b { 1 } else { 0 }, modes), + OP_INPUT => { + if let Some(v) = self.next_input.take() { + self.store(mode1, v); + } else { + self.ip -= 1; // go back to opcode + return SimulateStep::WaitForInput; + } + }, + OP_OUTPUT => { + return SimulateStep::Output(self.fetch(mode1)); + }, + OP_HALT => { + self.ip -= 1; // make re-running this step end up here again + return SimulateStep::Finished; + }, + OP_JUMP_IF_TRUE => { + if self.fetch(mode1) != 0 { + self.ip = self.fetch(mode2) as usize; + } else { + self.ip += 1; // skip target + } + }, + OP_JUMP_IF_FALSE => { + if self.fetch(mode1) == 0 { + self.ip = self.fetch(mode2) as usize; + } else { + self.ip += 1; // skip target + } + }, + _ => panic!("invalid opcode: {}", op), + } + } + } +} + +impl std::str::FromStr for IntCode { + type Err = ::Err; + + fn from_str(s: &str) -> Result { + Ok(IntCode { + ip: 0, + next_input: None, + data: s.split(',').map(|s| s.trim().parse::()).collect::>()?, + }) + } +} diff --git a/shared/src/lib.rs b/shared/src/lib.rs new file mode 100644 index 0000000..e29d47d --- /dev/null +++ b/shared/src/lib.rs @@ -0,0 +1 @@ +pub mod intcode; \ No newline at end of file