diff --git a/Cargo.lock b/Cargo.lock index e8a0610..54239a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,4 +3,23 @@ [[package]] name = "adventofcode-2019" version = "0.1.0" +dependencies = [ + "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", +] +[[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)", +] + +[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 63d51fd..7ed23ab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ version = "0.1.0" authors = [] [dependencies] +itertools = "0.8" [[bin]] name = "day-01-part-1-evqna" @@ -69,6 +70,62 @@ path = "./day-07/part-1/atauveron.rs" name = "day-07-part-2-atauveron" path = "./day-07/part-2/atauveron.rs" +[[bin]] +name = "day-03-part-1-evqna" +path = "./day-03/part-1/evqna.rs" + +[[bin]] +name = "day-03-part-2-evqna" +path = "./day-03/part-2/evqna.rs" + +[[bin]] +name = "day-04-part-1-evqna" +path = "./day-04/part-1/evqna.rs" + +[[bin]] +name = "day-04-part-2-evqna" +path = "./day-04/part-2/evqna.rs" + +[[bin]] +name = "day-05-part-1-evqna" +path = "./day-05/part-1/evqna.rs" + +[[bin]] +name = "day-05-part-2-evqna" +path = "./day-05/part-2/evqna.rs" + +[[bin]] +name = "day-06-part-1-evqna" +path = "./day-06/part-1/evqna.rs" + +[[bin]] +name = "day-06-part-2-evqna" +path = "./day-06/part-2/evqna.rs" + +[[bin]] +name = "day-07-part-1-evqna" +path = "./day-07/part-1/evqna.rs" + +[[bin]] +name = "day-07-part-2-evqna" +path = "./day-07/part-2/evqna.rs" + +[[bin]] +name = "day-08-part-1-evqna" +path = "./day-08/part-1/evqna.rs" + +[[bin]] +name = "day-08-part-2-evqna" +path = "./day-08/part-2/evqna.rs" + +[[bin]] +name = "day-09-part-1-evqna" +path = "./day-09/part-1/evqna.rs" + +[[bin]] +name = "day-09-part-2-evqna" +path = "./day-09/part-2/evqna.rs" + [[bin]] name = "day-08-part-1-atauveron" path = "./day-08/part-1/atauveron.rs" diff --git a/day-01/part-1/evqna.rs b/day-01/part-1/evqna.rs index 2925719..2161dd4 100644 --- a/day-01/part-1/evqna.rs +++ b/day-01/part-1/evqna.rs @@ -2,19 +2,18 @@ use std::env::args; use std::time::Instant; fn main() { - let input = args().nth(1).expect("Please provide an input"); let now = Instant::now(); - let output = run(&input); + let output = run(&args().nth(1).expect("Please provide an input")); let elapsed = now.elapsed(); println!("_duration:{}", elapsed.as_secs_f64() * 1000.); println!("{}", output); } -fn run(input: &str) -> isize { +fn run(input: &str) -> usize { input .split_whitespace() .map(|w| { - let mass = w.parse().unwrap_or(0); + let mass: usize = w.parse().unwrap(); mass / 3 - 2 }) .sum() diff --git a/day-01/part-2/evqna.rs b/day-01/part-2/evqna.rs index 44e6e04..bf7dd11 100644 --- a/day-01/part-2/evqna.rs +++ b/day-01/part-2/evqna.rs @@ -2,15 +2,14 @@ use std::env::args; use std::time::Instant; fn main() { - let input = args().nth(1).expect("Please provide an input"); let now = Instant::now(); - let output = run(&input); + let output = run(&args().nth(1).expect("Please provide an input")); let elapsed = now.elapsed(); println!("_duration:{}", elapsed.as_secs_f64() * 1000.); println!("{}", output); } -fn fuel_requirement(mut mass: i32) -> i32 { +fn fuel_requirement(mut mass: isize) -> isize { let mut total_fuel = 0; loop { let extra_fuel = mass / 3 - 2; @@ -22,9 +21,14 @@ fn fuel_requirement(mut mass: i32) -> i32 { } } -fn run(input: &str) -> i32 { - let modules = input.split_whitespace().map(|l| l.parse().unwrap_or(0)); - modules.map(fuel_requirement).sum() +fn run(input: &str) -> isize { + input + .split_whitespace() + .map(|w| { + let mass: isize = w.parse().unwrap(); + fuel_requirement(mass) + }) + .sum() } #[cfg(test)] diff --git a/day-02/part-1/evqna.rs b/day-02/part-1/evqna.rs index 0b5f5e2..aa1ae69 100644 --- a/day-02/part-1/evqna.rs +++ b/day-02/part-1/evqna.rs @@ -9,7 +9,7 @@ fn main() { println!("{}", output); } -fn run_program(mem: &mut Vec) -> usize { +fn run_program(mem: &mut Vec) { let mut ip = 0; loop { let op = mem[ip]; @@ -24,29 +24,18 @@ fn run_program(mem: &mut Vec) -> usize { mem[c] = mem[a] * mem[b]; } ip += 4; - }; - - mem[0] + } } -fn run(input: &str) -> i32 { +fn run(input: &str) -> usize { let mut mem: Vec = input .split(',') - .map(|n| n.parse().unwrap_or(0)) + .map(|n| n.parse().unwrap()) .collect(); mem[1] = 12; mem[2] = 02; - run_program(&mut mem) as i32 + run_program(&mut mem); + mem[0] } - -// #[cfg(test)] -// mod tests { -// use super::*; - -// #[test] -// fn run_test() { -// assert_eq!(run("1,1,1,4,99,5,6,0,99"), 30) -// } -// } diff --git a/day-02/part-2/evqna.rs b/day-02/part-2/evqna.rs index b094b43..d6c17f6 100644 --- a/day-02/part-2/evqna.rs +++ b/day-02/part-2/evqna.rs @@ -9,8 +9,8 @@ fn main() { println!("{}", output); } -fn run_program(arr: &Vec, noun: usize, verb: usize) -> usize { - let mut mem = arr.clone(); +fn run_program(program: &Vec, noun: usize, verb: usize) -> usize { + let mut mem = program.clone(); mem[1] = noun; mem[2] = verb; @@ -33,29 +33,18 @@ fn run_program(arr: &Vec, noun: usize, verb: usize) -> usize { mem[0] } -fn run(input: &str) -> i32 { +fn run(input: &str) -> usize { let mem: Vec = input .split(',') - .map(|n| n.parse().unwrap_or(0)) + .map(|n| n.parse().unwrap()) .collect(); for noun in 0..100 { for verb in 0..100 { if run_program(&mem, noun, verb) == 19690720 { - return (100 * noun + verb) as i32 + return 100 * noun + verb } } } - - 0 + panic!("No match found"); } - -// #[cfg(test)] -// mod tests { -// use super::*; - -// #[test] -// fn run_test() { -// assert_eq!(run("1,1,1,4,99,5,6,0,99"), 30) -// } -// } diff --git a/day-03/input/evqna.txt b/day-03/input/evqna.txt new file mode 100644 index 0000000..b93d74d --- /dev/null +++ b/day-03/input/evqna.txt @@ -0,0 +1,2 @@ +R999,D666,L86,U464,R755,U652,R883,D287,L244,U308,L965,U629,R813,U985,R620,D153,L655,D110,R163,D81,L909,D108,L673,D165,L620,U901,R601,D561,L490,D21,R223,U478,R80,U379,R873,U61,L674,D732,R270,U297,L354,U264,L615,D2,R51,D582,R280,U173,R624,U644,R451,D97,R209,U245,R32,U185,R948,D947,R380,D945,L720,U305,R911,U614,L419,D751,L934,U371,R291,D166,L137,D958,R368,U441,R720,U822,R961,D32,R242,D972,L782,D166,L680,U111,R379,D155,R213,U573,R761,D543,R762,U953,R317,U841,L38,U900,R573,U766,R807,U950,R945,D705,R572,D994,L633,U33,L173,U482,R253,D835,R800,U201,L167,U97,R375,D813,L468,D924,L972,U570,R975,D898,L195,U757,L565,D378,R935,U4,L334,D707,R958,U742,R507,U892,R174,D565,L862,D311,L770,D619,L319,D698,L169,D652,L761,D644,R837,U43,L197,D11,L282,D345,L551,U460,R90,D388,R911,U602,L21,D275,L763,U880,R604,D838,R146,U993,L99,U99,R928,U54,L148,D863,R618,U449,R549,D659,R449,D435,L978,D612,L645,D691,R190,D434,L841,D364,L634,D590,R962,U15,R921,D442,L284,U874,R475,D556,L135,U376,L459,D673,L515,U438,L736,U266,L601,U351,R496,U891,L893,D597,L135,D966,R121,U763,R46,D110,R830,U644,L932,D122,L123,U145,R273,U690,L443,D372,R818,D259,L695,U69,R73,D718,R106,U929,L346,D291,L857,D341,R297,D823,R819,U496,L958,U394,R102,D763,L444,D835,L33,U45,R812,U845,R196,U458,R231,U637,R661,D983,L941,U975,L353,U609,L698,U152,R122,D882,R682,D926,R729,U429,R255,D227,R987,D547,L446,U217,R678,D464,R849,D472,L406,U940,L271,D779,R980,D751,L171,D420,L49,D271,R430,D530,R509,U479,R135,D770,R85,U815,R328,U234,R83 +L1008,D951,L618,U727,L638,D21,R804,D19,L246,U356,L51,U8,L627,U229,R719,D198,L342,U240,L738,D393,L529,D22,R648,D716,L485,U972,L580,U884,R612,D211,L695,U731,R883,U470,R732,U723,R545,D944,R18,U554,L874,D112,R782,D418,R638,D296,L123,U426,L479,U746,L209,D328,L121,D496,L172,D228,L703,D389,R919,U976,R364,D468,L234,U318,R912,U236,R148,U21,R26,D116,L269,D913,L949,D206,L348,U496,R208,U706,R450,U472,R637,U884,L8,U82,L77,D737,L677,D358,L351,U719,R154,U339,L506,U76,L952,D791,L64,U879,R332,D244,R638,D453,L107,D908,L58,D188,R440,D147,R913,U298,L681,D582,L943,U503,L6,U459,L289,D131,L739,D443,R333,D138,R553,D73,L475,U930,L332,U518,R614,D553,L515,U602,R342,U95,R131,D98,R351,U921,L141,U207,R199,U765,R55,U623,R768,D620,L722,U31,L891,D862,R85,U271,R590,D184,R960,U149,L985,U82,R591,D384,R942,D670,R584,D637,L548,U844,R353,U496,L504,U3,L830,U239,R246,U279,L146,U965,R784,U448,R60,D903,R490,D831,L537,U109,R271,U306,L342,D99,L234,D936,R621,U870,R56,D29,R366,D562,R276,D134,L289,D425,R597,D102,R276,D600,R1,U322,L526,D744,L259,D111,R994,D581,L973,D871,R173,D924,R294,U478,R384,D242,R606,U629,R472,D651,R526,U55,R885,U637,R186,U299,R812,D95,R390,D689,R514,U483,R471,D591,L610,D955,L599,D674,R766,U834,L417,U625,R903,U376,R991,U175,R477,U524,L453,D407,R72,D217,L968,D892,L806,D589,R603,U938,L942,D940,R578,U820,L888,U232,L740,D348,R445,U269,L170,U979,L159,U433,L31,D818,L914,U600,L33,U159,R974,D983,L922,U807,R682,U525,L234,U624,L973,U123,L875,D64,L579,U885,L911,D578,R17,D293,L211 \ No newline at end of file diff --git a/day-03/part-1/evqna.rs b/day-03/part-1/evqna.rs new file mode 100644 index 0000000..7909c8a --- /dev/null +++ b/day-03/part-1/evqna.rs @@ -0,0 +1,120 @@ +use std::env::args; +use std::time::Instant; + +extern crate itertools; +use itertools::Itertools; +use std::cmp; + +fn main() { + let now = Instant::now(); + let output = run(&args().nth(1).expect("Please provide an input")); + let elapsed = now.elapsed(); + println!("_duration:{}", elapsed.as_secs_f64() * 1000.); + println!("{}", output); +} + +type Coords = Vec<(isize, isize)>; + +fn manhattan_norm(x: (isize, isize)) -> isize { + x.0.abs() + x.1.abs() +} + +fn run(input: &str) -> isize { + let wires: Vec> = input + .split_whitespace() + .map(|w| w.split(',').collect()) + .collect(); + + let turns_A = build_turns(&wires[0]); + let turns_B = build_turns(&wires[1]); + let mut intersections = build_intersections(&turns_A, &turns_B); + intersections.sort_by_key(|x| manhattan_norm(*x)); + manhattan_norm(intersections[1]) // Skip the origin +} + +fn build_turns(wire: &Vec<&str>) -> Coords { + let mut pos = (0, 0); + let mut turn_coords = vec![pos]; + + for segment in wire { + let direction = segment.chars().next().unwrap(); + let length: isize = segment[1..].parse().unwrap(); + match direction { + 'L' => pos.0 -= length, + 'R' => pos.0 += length, + 'U' => pos.1 += length, + 'D' => pos.1 -= length, + _ => println!("Wrong direction"), + } + turn_coords.push(pos); + } + + turn_coords +} + +// Computes intersection [x, y] of segments [a, b] and [c, d] in 1D +// Input segments must be sorted (a <= b and c <= d) +// If intersection is empty result will have x > y +fn segment_overlap(a: isize, b:isize, c:isize, d:isize) -> (isize, isize) { + (cmp::max(a, c), cmp::min(b, d)) +} + +fn build_intersections(turns_A: &Coords, turns_B: &Coords) -> Coords { + let mut intersections: Coords = Vec::new(); + // Du sale + for (a, b) in turns_A.iter().tuple_windows() { + // Reorder segments for easier comparisons + let (a, b) = if a.0 <= b.0 && a.1 <= b.1 { (a,b) } else { (b,a) }; + for (c, d) in turns_B.iter().tuple_windows() { + if a.0 == b.0 { + let x_1 = a.0; + if c.1 == d.1 { + let y_2 = c.1; + let (c, d) = if c.0 <= d.0 { (c,d) } else { (d,c) }; + if (a.1 <= y_2 && y_2 <= b.1) && (c.0 <= x_1 && x_1 <= d.0) { + intersections.push((x_1, y_2)); + } + } + else if c.0 == x_1 { + let (c, d) = if c.1 <= d.1 { (c,d) } else { (d,c) }; + let (y_min, y_max) = segment_overlap(a.1, b.1, c.1, d.1); + for y in y_min..y_max+1 { + intersections.push((x_1, y)); + } + } + } + else if a.1 == b.1 { + let y_1 = a.1; + if c.0 == d.0 { + let x_2 = c.0; + let (c, d) = if c.1 <= d.1 { (c,d) } else { (d,c) }; + if (a.0 <= x_2 && x_2 <= b.0) && (c.1 <= y_1 && y_1 <= d.1) { + intersections.push((x_2, y_1)); + } + } + else if c.1 == y_1 { + let (c, d) = if c.0 <= d.0 { (c,d) } else { (d,c) }; + let (x_min, x_max) = segment_overlap(a.0, b.0, c.0, d.0); + for x in x_min..x_max+1 { + intersections.push((x, y_1)); + } + } + } + } + } + intersections +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn run_test() { + assert_eq!(run("R8,U5,L5,D3\nU7,R6,D4,L4\n"), 6); + assert_eq!(run("R75,D30,R83,U83,L12,D49,R71,U7,L72\n + U62,R66,U55,R34,D71,R55,D58,R83\n"), 159); + assert_eq!(run("R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51\n + U98,R91,D20,R16,D67,R40,U7,R15,U6,R7\n"), 135); + } +} diff --git a/day-03/part-2/evqna.rs b/day-03/part-2/evqna.rs new file mode 100644 index 0000000..a28c522 --- /dev/null +++ b/day-03/part-2/evqna.rs @@ -0,0 +1,147 @@ +use std::env::args; +use std::time::Instant; + +extern crate itertools; +use itertools::Itertools; +use std::cmp; + +fn main() { + let now = Instant::now(); + let output = run(&args().nth(1).expect("Please provide an input")); + let elapsed = now.elapsed(); + println!("_duration:{}", elapsed.as_secs_f64() * 1000.); + println!("{}", output); +} + +#[derive(Debug)] +struct WirePos { + wire_length: isize, + x: isize, y: isize, +} + +fn run(input: &str) -> isize { + let wires: Vec> = input + .split_whitespace() + .map(|w| w.split(',').collect()) + .collect(); + + let turns_A = build_turns(&wires[0]); + let turns_B = build_turns(&wires[1]); + let mut intersections = build_intersections(&turns_A, &turns_B); + intersections.sort_by_key(|x| x.wire_length); + + intersections[1].wire_length // Skip the origin +} + +fn build_turns(wire: &Vec<&str>) -> Vec { + let (mut x, mut y) = (0, 0); + let mut wire_length = 0; + + let mut positions = vec![WirePos { x, y, wire_length}]; + for segment in wire { + let direction = segment.chars().next().unwrap(); + let length: isize = segment[1..].parse().unwrap(); + match direction { + 'L' => x -= length, + 'R' => x += length, + 'U' => y += length, + 'D' => y -= length, + _ => println!("Wrong direction"), + } + wire_length += length; + positions.push(WirePos { x, y, wire_length}); + } + positions +} + +// Computes intersection [x, y] of segments [a, b] and [c, d] in 1D +// Input segments must be sorted (a <= b and c <= d) +// If intersection is empty result will have x > y +fn segment_overlap(a: isize, b:isize, c:isize, d:isize) -> (isize, isize) { + (cmp::max(a, c), cmp::min(b, d)) +} + +#[derive(Debug)] +enum Axis { + X, Y, +} + +fn length_to_intersection(origin: &WirePos, x: isize, y: isize, axis: &Axis) -> isize { + match axis { + Axis::Y => origin.wire_length + (x - origin.x).abs(), + Axis::X => origin.wire_length + (y - origin.y).abs(), + } +} + +fn build_intersections(turns_A: &Vec, turns_B: &Vec) -> Vec { + let mut intersections: Vec = Vec::new(); + // Du sale + for (a, b) in turns_A.iter().tuple_windows() { + let main_axis = if a.x == b.x { Axis::X } else { Axis::Y }; + // Reorder segments for easier comparisons + let orig_a = a; + let (a, b) = if a.x <= b.x && a.y <= b.y { (a,b) } else { (b,a) }; + for (c, d) in turns_B.iter().tuple_windows() { + let orig_c = c; + let axis_2 = if c.x == d.x { Axis::X } else { Axis::Y }; + + if a.x == b.x { + let x = a.x; + if c.y == d.y { + let y = c.y; + let (c, d) = if c.x <= d.x { (c,d) } else { (d,c) }; + if (a.y <= y && y <= b.y) && (c.x <= x && x <= d.x) { + let wire_length = length_to_intersection(orig_a, x, y, &main_axis) + + length_to_intersection(orig_c, x, y, &axis_2); + intersections.push(WirePos { x, y, wire_length }); + } + } + else if c.x == x { + let (c, d) = if c.y <= d.y { (c,d) } else { (d,c) }; + let (y_min, y_max) = segment_overlap(a.y, b.y, c.y, d.y); + for y in y_min..y_max+1 { + let wire_length = length_to_intersection(orig_a, x, y, &main_axis) + + length_to_intersection(orig_c, x, y, &axis_2); + intersections.push(WirePos { x, y, wire_length }); + } + } + } + else if a.y == b.y { + let y = a.y; + if c.x == d.x { + let x = c.x; + let (c, d) = if c.y <= d.y { (c,d) } else { (d,c) }; + if (a.x <= x && x <= b.x) && (c.y <= y && y <= d.y) { + let wire_length = length_to_intersection(orig_a, x, y, &main_axis) + + length_to_intersection(orig_c, x, y, &axis_2); + intersections.push(WirePos { x, y, wire_length }); + } + } + else if c.y == y { + let (c, d) = if c.x <= d.x { (c,d) } else { (d,c) }; + let (x_min, x_max) = segment_overlap(a.x, b.x, c.x, d.x); + for x in x_min..x_max+1 { + let wire_length = length_to_intersection(orig_a, x, y, &main_axis) + + length_to_intersection(orig_c, x, y, &axis_2); + intersections.push(WirePos { x, y, wire_length }); + } + } + } + } + } + intersections +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn run_test() { + assert_eq!(run("R8,U5,L5,D3\nU7,R6,D4,L4\n"), 30); + assert_eq!(run("R75,D30,R83,U83,L12,D49,R71,U7,L72\n + U62,R66,U55,R34,D71,R55,D58,R83\n"), 610); + assert_eq!(run("R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51\n + U98,R91,D20,R16,D67,R40,U7,R15,U6,R7\n"), 410); + } +} diff --git a/day-04/input/evqna.txt b/day-04/input/evqna.txt new file mode 100644 index 0000000..32fdd49 --- /dev/null +++ b/day-04/input/evqna.txt @@ -0,0 +1 @@ +347312-805915 diff --git a/day-04/part-1/evqna.rs b/day-04/part-1/evqna.rs new file mode 100644 index 0000000..dcdb0b6 --- /dev/null +++ b/day-04/part-1/evqna.rs @@ -0,0 +1,50 @@ +use std::env::args; +use std::time::Instant; + +fn main() { + let now = Instant::now(); + let output = run(&args().nth(1).expect("Please provide an input")); + let elapsed = now.elapsed(); + println!("_duration:{}", elapsed.as_secs_f64() * 1000.); + println!("{}", output); +} + +fn get_digits(mut n: usize) -> Vec { + let mut digits = Vec::new(); + while n > 0 { + digits.push(n % 10); + n /= 10; + } + digits.reverse(); + digits +} + +fn check_valid(pwd: usize) -> bool { + let digits = get_digits(pwd); + let mut increasing_digits = true; + let mut has_double = false; + let mut p = 0; + for d in digits { + if d < p { + increasing_digits = false; + } + if d == p { + has_double = true; + } + p = d; + } + increasing_digits && has_double +} + +fn run(input: &str) -> usize { + let nums: Vec = input + .split('-') + .map(|s| s.parse().unwrap()) + .collect(); + + let (min, max) = (nums[0], nums[1]); + let count = (min..max+1) + .filter(|&n| check_valid(n)) + .count(); + count +} diff --git a/day-04/part-2/evqna.rs b/day-04/part-2/evqna.rs new file mode 100644 index 0000000..05d36ec --- /dev/null +++ b/day-04/part-2/evqna.rs @@ -0,0 +1,70 @@ +use std::env::args; +use std::time::Instant; + +fn main() { + let now = Instant::now(); + let output = run(&args().nth(1).expect("Please provide an input")); + let elapsed = now.elapsed(); + println!("_duration:{}", elapsed.as_secs_f64() * 1000.); + println!("{}", output); +} + +fn get_digits(mut n: usize) -> Vec { + let mut digits = Vec::new(); + while n > 0 { + digits.push(n % 10); + n /= 10; + } + digits.reverse(); + digits +} + +fn check_valid(&pwd: &usize) -> bool { + let digits = get_digits(pwd); + let mut increasing_digits = true; + let mut has_double = false; + let mut p = 0; + let mut consecutive_equal = 1; + for d in digits { + if d == p { + consecutive_equal += 1; + } + else if consecutive_equal == 2 { + has_double = true; + consecutive_equal = 1; + } else { + consecutive_equal = 1; + } + + if d < p { + increasing_digits = false; + } + p = d; + } + if consecutive_equal == 2 { + has_double = true; + } + increasing_digits && has_double +} + +fn run(input: &str) -> usize { + let nums: Vec = input + .split('-') + .map(|s| s.parse().unwrap()) + .collect(); + + let (min, max) = (nums[0], nums[1]); + (min..max+1) + .filter(&check_valid) + .count() +} + + #[cfg(test)] + mod tests { + use super::*; + + #[test] + fn run_test() { + assert_eq!(check_valid(&777788), true); + } + } diff --git a/day-05/input/evqna.txt b/day-05/input/evqna.txt new file mode 100644 index 0000000..cc24dae --- /dev/null +++ b/day-05/input/evqna.txt @@ -0,0 +1 @@ +3,225,1,225,6,6,1100,1,238,225,104,0,101,14,135,224,101,-69,224,224,4,224,1002,223,8,223,101,3,224,224,1,224,223,223,102,90,169,224,1001,224,-4590,224,4,224,1002,223,8,223,1001,224,1,224,1,224,223,223,1102,90,45,224,1001,224,-4050,224,4,224,102,8,223,223,101,5,224,224,1,224,223,223,1001,144,32,224,101,-72,224,224,4,224,102,8,223,223,101,3,224,224,1,223,224,223,1102,36,93,225,1101,88,52,225,1002,102,38,224,101,-3534,224,224,4,224,102,8,223,223,101,4,224,224,1,223,224,223,1102,15,57,225,1102,55,49,225,1102,11,33,225,1101,56,40,225,1,131,105,224,101,-103,224,224,4,224,102,8,223,223,1001,224,2,224,1,224,223,223,1102,51,39,225,1101,45,90,225,2,173,139,224,101,-495,224,224,4,224,1002,223,8,223,1001,224,5,224,1,223,224,223,1101,68,86,224,1001,224,-154,224,4,224,102,8,223,223,1001,224,1,224,1,224,223,223,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,108,226,677,224,1002,223,2,223,1006,224,329,1001,223,1,223,1007,226,226,224,1002,223,2,223,1006,224,344,101,1,223,223,1008,226,226,224,102,2,223,223,1006,224,359,1001,223,1,223,107,226,677,224,1002,223,2,223,1005,224,374,101,1,223,223,1107,677,226,224,102,2,223,223,1006,224,389,101,1,223,223,108,677,677,224,102,2,223,223,1006,224,404,1001,223,1,223,1108,677,226,224,102,2,223,223,1005,224,419,101,1,223,223,1007,677,226,224,1002,223,2,223,1006,224,434,101,1,223,223,1107,226,226,224,1002,223,2,223,1006,224,449,101,1,223,223,8,677,226,224,102,2,223,223,1006,224,464,1001,223,1,223,1107,226,677,224,102,2,223,223,1005,224,479,1001,223,1,223,1007,677,677,224,102,2,223,223,1005,224,494,1001,223,1,223,1108,677,677,224,102,2,223,223,1006,224,509,101,1,223,223,1008,677,677,224,102,2,223,223,1005,224,524,1001,223,1,223,107,226,226,224,1002,223,2,223,1005,224,539,101,1,223,223,7,226,226,224,102,2,223,223,1005,224,554,101,1,223,223,1108,226,677,224,1002,223,2,223,1006,224,569,1001,223,1,223,107,677,677,224,102,2,223,223,1005,224,584,101,1,223,223,7,677,226,224,1002,223,2,223,1005,224,599,101,1,223,223,108,226,226,224,1002,223,2,223,1005,224,614,101,1,223,223,1008,677,226,224,1002,223,2,223,1005,224,629,1001,223,1,223,7,226,677,224,102,2,223,223,1005,224,644,101,1,223,223,8,677,677,224,102,2,223,223,1005,224,659,1001,223,1,223,8,226,677,224,102,2,223,223,1006,224,674,1001,223,1,223,4,223,99,226 \ No newline at end of file diff --git a/day-05/part-1/evqna.rs b/day-05/part-1/evqna.rs new file mode 100644 index 0000000..e08fe89 --- /dev/null +++ b/day-05/part-1/evqna.rs @@ -0,0 +1,138 @@ +use std::env::args; +use std::time::Instant; + +fn main() { + let now = Instant::now(); + let output = run(&args().nth(1).expect("Please provide an input")); + let elapsed = now.elapsed(); + println!("_duration:{}", elapsed.as_secs_f64() * 1000.); + println!("{}", output); +} + +fn run(input: &str) -> isize { + let mut mem: Vec = input + .split(',') + .map(|n| n.parse().unwrap()) + .collect(); + + run_program(&mut mem) +} + +#[derive(Debug)] +#[derive(PartialEq)] +enum Op { + Add, + Mul, + Input, + Output, + Exit, +} + +#[derive(Debug, Copy, Clone)] +#[derive(PartialEq)] +enum Mode { + Position, + Immediate, +} + +#[derive(Debug)] +struct Operation { opcode: Op, operands: Vec } + +#[derive(Debug)] +struct Operand { mode: Mode, operand: usize } + +fn run_program(mem: &mut [isize]) -> isize { + let mut ip = 0; + let mut last_output = 0; + loop { + let op = parse_op(&mem[ip..]); +// println!("{} {:?}", ip, op); + + if op.opcode == Op::Exit { + return last_output; + } + + last_output = run_op(&op, mem).unwrap_or(last_output); + ip += 1 + op.operands.len(); + } +} + +fn run_op(op: &Operation, mem: &mut [isize]) -> Option { + match op.opcode { + Op::Add => { + let a = get_read_operand_value(mem, &op.operands[0]); + let b = get_read_operand_value(mem, &op.operands[1]); + let c = get_write_operand_ref(mem, &op.operands[2]); + *c = a + b; + } + Op::Mul => { + let a = get_read_operand_value(mem, &op.operands[0]); + let b = get_read_operand_value(mem, &op.operands[1]); + let c = get_write_operand_ref(mem, &op.operands[2]); + *c = a * b; + } + Op::Input => { + let a = get_write_operand_ref(mem, &op.operands[0]); + *a = 1; + } + Op::Output => { + let a = get_read_operand_value(mem, &op.operands[0]); + return Option::from(a); + } + Op::Exit => {} + } + Option::None +} + +fn get_read_operand_value(mem: &[isize], operand: &Operand) -> isize { + match operand.mode { + Mode::Immediate => operand.operand as isize, + Mode::Position => mem[operand.operand], + } +} + +fn get_write_operand_ref<'a>(mem: &'a mut [isize], operand: &Operand) -> &'a mut isize { + assert_eq!(operand.mode, Mode::Position); + &mut mem[operand.operand] +} + +fn parse_op(mem_slice: &[isize]) -> Operation { + let instr = mem_slice[0] as usize; + let (opcode, nb_operands) = match instr % 100 { + 1 => (Op::Add, 3), + 2 => (Op::Mul, 3), + 3 => (Op::Input, 1), + 4 => (Op::Output, 1), + 99 => (Op::Exit, 0), + n => panic!("Invalid opcode {}", n), + }; + let modes = parse_modes(instr / 100, nb_operands); + let operands = (0..nb_operands) + .map(|i| Operand { operand: mem_slice[i + 1] as usize, mode: modes[i]}) + .collect(); + + Operation { opcode, operands } +} + +fn parse_modes(mut encoded_modes: usize, n: usize) -> Vec { + let mut modes = Vec::new(); + for _ in 0..n { + match encoded_modes % 10 { + 0 => modes.push(Mode::Position), + 1 => modes.push(Mode::Immediate), + n => panic!("Invalid operation mode {}", n), + } + encoded_modes /= 10; + } + modes +} + + #[cfg(test)] + mod tests { + use super::*; + + #[test] + fn run_test() { + assert_eq!(run("1002,4,3,4,33"), 0) + } + } diff --git a/day-05/part-2/evqna.rs b/day-05/part-2/evqna.rs new file mode 100644 index 0000000..9edf3ea --- /dev/null +++ b/day-05/part-2/evqna.rs @@ -0,0 +1,180 @@ +use std::env::args; +use std::time::Instant; + +fn main() { + let now = Instant::now(); + let output = run(&args().nth(1).expect("Please provide an input")); + let elapsed = now.elapsed(); + println!("_duration:{}", elapsed.as_secs_f64() * 1000.); + println!("{}", output); +} + +fn run(input: &str) -> isize { + let mut mem: Vec = input + .split(',') + .map(|n| n.parse().unwrap()) + .collect(); + + run_program(&mut mem) +} + +#[derive(Debug)] +#[derive(PartialEq)] +enum Op { + Add, + Mul, + Input, + Output, + JumpTrue, + JumpFalse, + Leq, + Eq, + Exit, +} + +#[derive(Debug, Copy, Clone)] +#[derive(PartialEq)] +enum Mode { + Position, + Immediate, +} + +#[derive(Debug)] +struct Operation { opcode: Op, operands: Vec } + +#[derive(Debug)] +struct Operand { mode: Mode, operand: usize } + +fn run_program(mem: &mut [isize]) -> isize { + let mut ip = 0; + let mut last_output = 0; + loop { + let op = parse_op(&mem[ip..]); +// println!("{} {:?}", ip, op); + + if op.opcode == Op::Exit { + return last_output; + } + + let prev_ip = ip; + last_output = run_op(&op, mem, &mut ip).unwrap_or(last_output); + if ip == prev_ip { + ip += 1 + op.operands.len(); + } + } +} + +const INPUT: isize = 5; + +fn run_op(op: &Operation, mem: &mut [isize], ip: &mut usize) -> Option { + match op.opcode { + Op::Add => { + let (a, b, c) = resolve_binary_operands(&op.operands, mem); + *c = a + b; + } + Op::Mul => { + let (a, b, c) = resolve_binary_operands(&op.operands, mem); + *c = a * b; + } + Op::Input => { + let a = get_write_operand_ref(mem, &op.operands[0]); + *a = INPUT; + } + Op::Output => { + let a = get_read_operand_value(mem, &op.operands[0]); + return Option::from(a); + } + Op::JumpTrue => { + let a = get_read_operand_value(mem, &op.operands[0]); + let b = get_read_operand_value(mem, &op.operands[1]); + if a != 0 { + *ip = b as usize; + } + } + Op::JumpFalse => { + let a = get_read_operand_value(mem, &op.operands[0]); + let b = get_read_operand_value(mem, &op.operands[1]); + if a == 0 { + *ip = b as usize; + } + } + Op::Leq => { + let (a, b, c) = resolve_binary_operands(&op.operands, mem); + *c = if a < b { 1 } else { 0 }; + } + Op::Eq => { + let (a, b, c) = resolve_binary_operands(&op.operands, mem); + *c = if a == b { 1 } else { 0 }; + } + Op::Exit => {} + } + Option::None +} + +fn resolve_binary_operands<'a>(operands: &[Operand], mem: &'a mut [isize]) + -> (isize, isize, &'a mut isize) { + let a = get_read_operand_value(mem, &operands[0]); + let b = get_read_operand_value(mem, &operands[1]); + let c = get_write_operand_ref(mem, &operands[2]); + (a, b, c) +} + +fn get_read_operand_value(mem: &[isize], operand: &Operand) -> isize { + match operand.mode { + Mode::Immediate => operand.operand as isize, + Mode::Position => mem[operand.operand], + } +} + +fn get_write_operand_ref<'a>(mem: &'a mut [isize], operand: &Operand) -> &'a mut isize { + assert_eq!(operand.mode, Mode::Position); + &mut mem[operand.operand] +} + +fn parse_op(mem_slice: &[isize]) -> Operation { + let instr = mem_slice[0] as usize; + let (opcode, nb_operands) = match instr % 100 { + 1 => (Op::Add, 3), + 2 => (Op::Mul, 3), + 3 => (Op::Input, 1), + 4 => (Op::Output, 1), + 5 => (Op::JumpTrue, 2), + 6 => (Op::JumpFalse, 2), + 7 => (Op::Leq, 3), + 8 => (Op::Eq, 3), + 99 => (Op::Exit, 0), + n => panic!("Invalid opcode {}", n), + }; + let modes = parse_modes(instr / 100, nb_operands); + let operands = (0..nb_operands) + .map(|i| Operand { operand: mem_slice[i + 1] as usize, mode: modes[i]}) + .collect(); + + Operation { opcode, operands } +} + +fn parse_modes(mut encoded_modes: usize, n: usize) -> Vec { + let mut modes = Vec::new(); + for _ in 0..n { + match encoded_modes % 10 { + 0 => modes.push(Mode::Position), + 1 => modes.push(Mode::Immediate), + n => panic!("Invalid operation mode {}", n), + } + encoded_modes /= 10; + } + modes +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn run_test() { + assert_eq!(run("1002,4,3,4,33"), 0); + assert_eq!(run("3,21,1008,21,8,20,1005,20,22,107,8,21,20,1006,20,31,\ +1106,0,36,98,0,0,1002,21,125,20,4,20,1105,1,46,104,\ +999,1105,1,46,1101,1000,1,20,4,20,1105,1,46,98,99"), 999); + } +} diff --git a/day-06/input/evqna.txt b/day-06/input/evqna.txt new file mode 100644 index 0000000..ce13a71 --- /dev/null +++ b/day-06/input/evqna.txt @@ -0,0 +1,1438 @@ +H1R)Z5F +R6L)JYJ +QVZ)B3R +ZD8)Y6T +FWC)F2N +3HH)HSX +2PQ)NXT +C7Q)7HM +6KQ)B1V +CVJ)SXY +ZZR)627 +HWF)5Q2 +7QR)BHQ +1FF)SBD +F9B)XXF +415)C8L +K38)LZ2 +Q3R)61L +Q8V)TDC +H5W)52V +PQY)BDX +C54)QSK +PHC)JPX +ZLS)CRN +PSR)T5C +FWK)Q48 +BNL)FWC +ZPV)CR3 +HM5)C5J +Y4F)X6L +FX1)1LX +D7W)P4X +5Y6)L55 +L2R)2WD +F26)TPF +YYH)F3Z +XQB)GPY +8W7)6PH +53X)K5N +MFG)KP7 +YTT)DJS +NDT)NN3 +S7X)8HH +5CR)BS6 +QH8)MKW +8FY)LG7 +SC1)CC6 +8DX)N55 +T71)M2G +SBD)T4B +9B1)K4M +KXB)YRK +H3S)DP9 +Y71)MW5 +43G)9NB +YFT)BFG +GSZ)H37 +QP8)VT7 +3CC)KJL +8VN)Y5S +CP6)GQB +BX3)DQ4 +P4X)XJT +ZMK)7WW +RVX)J55 +S9X)7MC +ZYY)T4P +X6L)126 +T1W)H6H +BS6)S7X +YNK)KKR +2BD)SM3 +PR8)MJ8 +L2H)2PQ +KM2)1WX +V8F)FX1 +92J)NWF +CF4)XMV +7G6)KXB +ZHP)K75 +9T5)Q7Y +X71)HV5 +KK5)1X2 +JCB)DWH +T8W)S9X +2S6)J6M +53K)H87 +F3J)JLL +5Y6)VY5 +CQD)2ZY +8W4)PX4 +4H2)KR4 +GWY)SNB +F8J)5T9 +S3G)54J +PQV)PKY +96C)L67 +CP6)R66 +H5P)6SZ +P9V)686 +CP8)S8Y +6CQ)QRM +PZK)DVV +DK5)QWQ +BPM)52D +V8R)YYS +CM7)2NF +H8P)F11 +TC5)KXG +7QK)6XG +D9F)NZ7 +1D5)86C +ZP5)C54 +C6T)Q7K +9KM)QPC +LBC)HFX +DK6)LZW +WXC)2FC +BX4)2XY +6H7)2HJ +DZ2)5RD +KYB)H6T +2QW)PVV +2MD)BNP +VMX)SLG +D6K)RXB +GHS)HGB +QCT)T29 +X1B)VT4 +BN9)M79 +SXK)CSF +SG7)YPY +ZPK)GHS +6X4)L59 +B89)LP3 +9TZ)HW9 +YPY)M5P +LS2)92L +Z2T)QQM +CK7)NKB +3PY)VS8 +2MQ)NT7 +C6Z)8F9 +NWF)35C +GYR)4NR +ZQG)W9H +7D1)V8R +Y2X)F26 +8X8)7KF +CN1)PZC +BPW)PBY +9WC)H8V +ZXH)GKH +CF4)N5L +C54)YJS +RY1)GZC +WMT)8CW +MZP)9SH +VZC)SKL +Y7T)C7V +SYG)R14 +ZLS)MLH +MZT)G1Z +NPR)VTV +LCQ)PZK +RNW)SXK +8CW)8YN +XXM)MFD +YL3)8WB +DTK)JFZ +TKC)J8R +MVL)TYJ +QR7)SKG +9GZ)BXM +M4Y)P9V +4XY)8QP +9XC)X52 +CVF)PTH +52S)D9L +TCP)SBL +SPG)KSV +MTN)GWY +VJL)N74 +4RT)LHJ +RG6)5X3 +Q7Z)CP8 +5X3)3PY +PVQ)TCF +JR1)7QK +DGV)YFL +BQ9)B2Q +W75)6KQ +13H)QYX +HQT)G2V +HDV)7RG +GV3)HFT +627)Q5F +YYS)RVQ +CQH)BPW +W3X)VXF +SZN)SLF +C7Q)8X8 +3SY)X64 +JG5)C6S +4C3)PSR +Q1W)RNW +T6J)NPL +T4L)D7L +L8P)27X +R66)TRQ +PKY)YCL +GQX)JVG +2NM)RWX +MP5)MR4 +5R2)GRN +JRM)M34 +THK)RPR +GKN)46X +1D1)8YS +XYN)6SV +SRV)GB3 +F9N)8FY +SLG)72G +J2Y)W6P +3RZ)K2W +W85)CY9 +MJ8)2FT +9B5)XW8 +PJD)6WB +DBX)V2T +M6X)VBM +XX2)BTC +1MN)XXM +DLD)3Q2 +4SH)BPL +T8Y)ZPV +3T9)HMW +C3Z)GDS +YJ4)L2Z +VJ7)Q7H +D72)K1T +5ZP)QP8 +XZD)894 +67Y)BKF +ZLD)YST +NQ1)F5H +2QB)M99 +WZ9)XC9 +COM)RR1 +F3J)G1X +SCR)L66 +46X)QT3 +4ZN)JDX +JYJ)2QB +XTB)349 +LM1)83X +29M)L2H +D5Y)VV1 +YTK)BKW +N72)GD4 +1PB)8ZM +V31)99V +RR1)68N +BM3)99C +XRT)VM9 +6FK)675 +5P9)CMQ +DSM)SJ5 +YST)KB5 +83N)6VW +ZCQ)5SM +V1Q)2S6 +LZR)QBL +H3G)9S1 +88G)YTK +NPL)ZHP +W44)NWY +5KZ)1MC +52V)9B5 +WL2)5P9 +JDX)V8F +R16)ZWZ +FVT)596 +8J4)FRL +2HC)986 +NFM)KWB +F2L)Y5X +VPS)43K +VX8)G8C +DMH)RCD +NCH)TPZ +9KG)MMP +RPR)CFW +JWY)SC1 +XTB)H3G +7FP)FMV +HGB)6JL +1P4)ZPK +WCF)11H +ZR1)Y75 +NP5)MNZ +GNT)8W7 +NGD)GNL +Q98)F6V +F32)7L4 +CFW)684 +T5C)QWC +VV6)SDZ +9QW)VKG +7WZ)R16 +LZ2)NYL +G2V)ZXH +VL4)9LX +9F5)CS5 +FYD)VX8 +R7C)2HC +LQS)54R +33W)F8J +N9C)ZGL +9ZB)5S8 +MLJ)8VY +LVY)T1W +1FC)JG5 +K75)LZR +LZ9)2XS +9P8)75M +LW6)TWM +K71)DGV +R2C)GKX +99C)ML2 +CM5)YKW +5YK)HM5 +9D9)G9V +2BT)74Z +TCP)NDT +L59)N3C +3FG)ZH5 +3S8)96C +JBB)9KG +QHN)CS4 +9TZ)PRZ +SM2)MHJ +Z5J)5QY +BNP)7HZ +HDY)LBC +QMV)7SK +GT4)SN7 +1MC)MZP +5C3)9WC +596)L1H +ZNZ)CM5 +PBN)KLS +2K7)BN9 +YJL)2VV +MJX)TDX +K2W)5ZP +1F9)6KC +BM8)D72 +79Q)ZTP +7RC)88G +7WW)JBB +43Z)7G1 +FKV)3W9 +T1W)911 +5RD)D7C +XBZ)NQ1 +C8L)F3M +M79)YFY +G2Q)LXS +F6V)T8Y +6XG)127 +CCV)2LJ +D9T)Q5L +ZTP)XL3 +LG7)X1Q +JHG)WBL +8F9)3DB +FNV)W7B +HS2)PR8 +6PL)WPM +HQH)9NT +WV2)3FL +1YM)Z51 +FCL)4KM +VBM)8DX +JXJ)MQD +H6C)K46 +72G)9XC +L66)Y2S +HMW)XPP +29T)LM1 +BPL)F3J +VTV)TX8 +9WW)L2R +Z51)GL2 +YD1)DZC +4TY)BPM +C84)GV3 +SFV)1ZV +XJT)17T +RK5)ZR8 +71K)DK5 +LTM)71K +QNL)XQB +WYV)N6B +JDX)5JC +6X9)CMF +TRQ)RMY +2S6)29M +4CJ)CTD +KG4)7BX +JLL)LCN +QYX)DMC +1P4)C6T +ZVW)RKM +XCQ)V31 +WM3)G6P +HFX)TD9 +7RC)Y4G +M5F)4WV +6GP)2K7 +PYL)5XS +88C)JMT +VB3)Q1D +RQS)JBS +SMJ)VSH +2WM)9RK +9SJ)1D5 +SP5)MLJ +9RK)2QW +1JZ)R6X +N4S)WGR +XWS)J1K +FGY)N79 +LM1)6DS +NVW)323 +LSM)46Z +97D)M6X +256)V8V +RCD)DHR +3B4)3RR +R49)8W6 +6BS)49C +C29)BM8 +NFG)9WW +9HC)F2L +DVV)N4S +CCP)R3W +DF9)ZN9 +W16)BDD +RND)CLC +CMF)HST +X1Q)C52 +MS4)5CY +BSM)W2H +971)482 +6JV)CBP +NB8)HG6 +LQM)ZMK +64H)DQJ +81H)2WM +P18)1QN +1Z3)RH9 +Q84)QH1 +SJ5)QBB +83X)W28 +XF3)D9T +L7W)BPN +PH6)81H +Q5F)4GJ +8DT)FKL +55R)F4L +R5T)5YJ +TDC)VHJ +WHB)FVT +TX8)7WX +RF8)35N +GD4)K2S +1ZV)2ST +T19)7FP +D6M)CYW +5XL)NK4 +5JC)JWY +G9X)CCV +Z1J)4C4 +PQZ)HD9 +VY5)6LJ +3HX)459 +H37)S1V +Z7P)G78 +YTV)YKQ +1QN)ZLD +BFD)THK +F52)FCQ +R44)XRT +YH7)YYH +DMC)R7Z +R5M)D12 +1MJ)XSC +85C)CVJ +7V2)K43 +M82)1H7 +8XZ)5PP +NJJ)Q17 +XS1)M82 +HJQ)P6K +MY4)NKS +L83)3NW +7HM)9G6 +3NP)S2N +175)927 +99V)ZJN +23H)PZW +1BK)R5M +QSK)XH1 +HPH)Z3Y +KVK)P5K +YKQ)WT5 +G6P)MFG +RYK)8JP +F2Q)BRM +GNT)XS1 +YHQ)8W4 +HTH)KQM +J72)JF2 +XXF)67Y +8VD)VFG +XL3)3HX +LL8)36C +FCK)KVN +X64)3NN +1HL)7Q3 +Y5X)1MF +T5K)YL3 +FSZ)QNL +P6K)DZN +B3P)KYB +1X2)ZNZ +TBN)V48 +BXM)1PB +8SD)GP8 +SLB)7BY +911)Q9X +DJ2)QN6 +3NR)YJL +8HB)SAN +L3L)52S +GZC)R1M +STY)H1C +H8G)GSK +DY6)L3L +C27)4SH +2MH)ZG7 +9SH)W8T +23L)C7Q +VK8)MGC +Y2C)9P8 +ZNR)DLW +RQS)G9X +PTH)NFM +XJ8)83C +WW5)2R2 +GMD)LVC +WBP)KSQ +XLH)Y71 +14T)9ZB +QQM)VZX +MJ8)H6Z +RMX)WBP +ZD1)3CB +BQZ)MY4 +TWK)53X +JK1)F7Q +7SK)85C +FS9)CTK +3Q2)9D7 +4KM)QMV +GK6)9FK +192)VRR +HJJ)YHQ +N5L)HS2 +GNL)LXK +KSV)DMH +9FK)YFT +K7B)KXZ +6DS)SRV +K5T)L1L +PH6)BVN +K43)9T5 +KWW)5FF +118)CN1 +2HJ)XJD +NYL)STY +MMP)9F5 +94C)W3X +CP9)NJZ +124)1MN +3DK)3RZ +1WX)4ZN +P7Q)F52 +8T5)2FV +CSF)4KZ +R14)R4C +KLS)F4H +G6Y)CLB +VHJ)ZCQ +CLB)MS4 +Y2Y)NCY +FCL)J9N +7L4)LTM +YMP)D5Y +K4M)5LW +C8B)3PF +2P5)VPS +1ZZ)GMD +T5G)H6R +HW9)S9J +VBX)FNN +894)3NR +JZJ)ZR1 +598)333 +P5K)8TP +LHM)B4Y +YV1)48F +QWC)NMQ +V8X)LH5 +53K)6FK +9T5)YTT +T46)PQZ +5RD)38X +Q1B)R2C +8LB)SYG +MCG)9CD +F9H)N6R +MCB)36H +R55)ZQG +KLL)NWG +N79)3NP +S65)D6K +L6R)2LX +NP2)XHX +MPZ)2HT +JFZ)C8X +HT7)9XL +KXZ)Q84 +6WB)WMM +N84)DTK +3FL)JHF +CY9)DSM +1QW)1YM +JLD)4CJ +6SZ)B6J +B2Q)F44 +D3M)HQH +FFP)PS9 +57T)1CV +BL7)7V2 +691)M7Z +CC6)7PS +JBS)HTH +LRC)3Z1 +7WX)1P4 +RH9)4JD +MJK)KZC +JJD)691 +XV1)8DG +G7S)X5S +7LW)6BS +KP7)D7W +BKV)6MQ +SBX)1JX +MR4)Z1M +L2Z)97T +8QP)NPR +C7V)9X7 +PWQ)TWK +MQD)WV2 +LCN)4QK +3KP)T46 +8J4)PYV +BPL)D8P +42C)V5D +83C)C2W +F4H)ZNR +BYW)MP5 +61L)CQH +RZB)T4S +FMV)2P5 +J6M)FYD +HTV)J3P +D3G)JLD +WGR)J1M +NXT)PV2 +TD9)3L1 +TYJ)8KG +BRN)RDX +LHJ)V8X +Q11)FGY +Y6T)F47 +L55)42C +94C)23L +R3P)DM5 +172)QFK +N3C)T5K +2VB)57T +T4S)PWQ +LZ4)JLG +TRQ)RL4 +J9N)SCR +T4P)LT4 +3NN)3X8 +FCQ)HCF +LR7)D6M +2R2)P7Q +9XL)69G +JVD)5XL +953)RZB +L9Z)YXK +HCF)YYB +L7P)X71 +L99)QM8 +9R3)VKY +NHP)ZD8 +S2N)DHN +66J)175 +9LX)K6N +V48)Z46 +6H7)WR6 +JCD)RG6 +8DG)7QR +D7L)HGP +JXJ)53P +YJS)F32 +F32)T4L +TCF)XF3 +73N)CXF +GKX)ZVW +VT1)75D +M7Z)BL7 +323)K7B +QVZ)D3G +Z4H)3CC +R5M)HY2 +PYY)WXC +6JW)PZR +2QL)WYV +4RX)XFS +7KF)3WD +1Z5)QHN +YH7)8F1 +6JL)N41 +132)V1Q +CMQ)118 +Q5J)JCD +WH9)PKS +7G1)LQM +XLV)HJJ +G8C)37T +JML)8LB +B3R)4RT +RNQ)FTV +XC5)SLB +MSJ)VW7 +HHB)QCT +46Z)PBN +H1C)VT1 +JNL)1ZZ +NN3)2PL +4QK)JZJ +8JP)QR7 +JB8)FFP +L99)J72 +7PS)G2Q +5T9)FTP +WPM)MZT +8RQ)G3H +65G)2H7 +NXB)9DR +K5T)F9N +FNN)YTM +G1K)XV1 +6MQ)5R2 +74Z)WCF +2VV)3H9 +649)Q8V +VZX)HT7 +11H)66J +KTF)H8G +KB5)FKV +G7G)MZZ +CTD)44K +3VR)C92 +G2V)7YL +VWK)172 +9S1)R49 +15X)24K +VJM)6TQ +1SP)XLH +GQH)1X3 +NJZ)PYY +YWG)BX3 +HQH)HJQ +VQS)3B4 +6CW)X3D +NT7)83N +1YQ)JM3 +2XY)HDY +TJV)92J +JPX)PJD +J1M)9K2 +C92)VS7 +ZWZ)NP5 +1JX)W5Q +NMS)FD9 +FVY)R5W +PS9)T8W +V2V)BSM +SD3)Y2C +68N)88C +RJR)VBX +M2G)LL8 +CRV)NCH +8LW)7MJ +675)2BD +9NT)BQ9 +2H7)T6J +CBP)KNW +ML2)Y94 +KQM)HPH +15K)N5F +CS4)N95 +G3H)S3G +WW2)34B +8PD)H6C +PZS)W99 +S9J)F2Q +LT4)R6L +PX4)Q7Z +5PP)9GZ +FXT)DTX +R5W)64H +HGP)BM3 +ZG2)FZH +MHV)W6G +YYB)4L5 +24K)WL2 +Y2L)TCP +FRL)C84 +RWX)ZJM +K87)LQS +PQY)5KZ +FKJ)STT +X7P)FQG +CM7)415 +HG6)9S8 +C2W)FS9 +G1X)J7B +WM6)RCB +PYV)LHM +QN6)14T +WT5)2MD +RL4)H3S +VTV)NB8 +8ZM)MD4 +XMY)NLX +CXF)NHC +8F1)G6Y +YFY)3DK +YJ4)LZ4 +9FK)CVH +FT7)9HC +ZH5)1JZ +3Z1)Q98 +GYG)971 +JLG)FQ9 +H6Z)8DT +J8R)NFG +N6R)HQX +FPT)97D +6MT)FSZ +NCY)LZ9 +W2R)CJ9 +LYK)PH6 +RCB)SM2 +SBL)C16 +X52)W44 +SDZ)2FG +H7Q)TBN +RV6)7TR +43K)GQX +2SM)4C9 +C6S)7G6 +NVF)9TZ +M34)CM7 +WS6)R2D +JHF)L83 +DZC)HTV +RCD)3PN +9NB)98D +G1X)699 +VLZ)2MH +MNZ)CCR +787)3K3 +JCB)1BK +6SV)D9F +DP9)L99 +R4C)9KM +T29)RYZ +R1M)PYL +T2B)RGB +NK4)J2Y +L1H)CRT +3PF)6CQ +Y5S)F9B +986)CP6 +C16)B5H +9GB)S65 +333)VV6 +P18)KVX +LXS)98L +S5C)4XY +PRZ)R44 +8W6)JR1 +B4Y)12G +349)Q77 +D9F)KM2 +T3C)QMD +N6B)9PQ +9G6)7XJ +D12)NVF +SN7)D82 +H8V)SSP +BPN)5YW +3CB)KFG +BTC)TVN +QT3)2KK +SXY)T19 +R2D)1JG +2VS)BN1 +R6X)JK1 +KFG)G5G +LZR)F9H +5QY)FWK +Y2S)WW5 +YJF)SF8 +94V)YMP +XGT)KVK +57S)S2G +4JD)CCP +118)G8D +TPF)FV1 +LTM)JNL +NVF)B89 +F44)94C +F4L)8HB +MS4)192 +NHC)RF8 +5YW)8LW +DNB)S5C +RTT)YQ4 +3RR)DF9 +GYG)8H4 +2DJ)PYS +XNG)1QJ +D7C)1YN +9CD)XBZ +86C)KF1 +RSF)NVW +4KZ)SFV +YTM)5SS +W3X)Y2Y +X52)FKJ +BR7)58V +JNQ)DB9 +R3P)13H +BDD)TC5 +Q83)LSM +FCK)7RC +1YN)19K +2KK)MCB +QBV)NMY +JF2)6VF +HQX)5Y6 +QWQ)MSJ +Z35)MHV +KF1)LR2 +3DB)LQ3 +127)X1B +LQM)DBX +ZG7)W85 +GVL)M4Y +482)MJK +YFL)RTT +Z46)MJD +L9L)1W9 +8GQ)D2G +44V)MTN +XH1)5C3 +F3M)QBV +F47)6P8 +YM7)6JV +2R5)W2R +N5F)5MM +4NR)C6Z +NKB)Y1C +KSQ)PY2 +QFK)JXJ +5S8)7D3 +C6T)FZB +LZW)VJ7 +XMV)KWW +VWK)CVF +ZCR)79Q +X3D)G1K +J1K)H7Q +K46)Y7T +H3G)53K +YCL)5Y3 +WHB)1YQ +BDX)GYG +MKW)RNQ +KJL)HDV +9SL)B3P +T46)RV6 +KXG)M24 +34B)Q1B +HJM)J8J +C8X)ZCR +PZR)65G +9YP)JML +3DK)GN9 +6PH)W75 +69G)4CS +Q48)HHB +1CV)XNV +D8P)JCB +NMP)LJZ +PZW)33W +6VD)SM1 +NZ7)HHQ +XW8)9SJ +CRT)MH9 +C8L)HQS +LQ3)H8P +9S8)ZZR +BFG)LYS +Q17)2R5 +WR6)5CR +49C)ZG2 +CRT)DK6 +5JC)QH8 +5YJ)2VB +5SS)GYR +1W9)L8P +35C)DJ2 +4CS)1HL +GG4)VWK +1MC)T5G +Z5F)5MJ +Y8P)XNG +Q98)Q83 +W99)VZC +DB9)RQS +L1L)F23 +8B4)LYK +YV1)YD1 +VW7)XZD +L28)6VD +PY6)XCQ +KVX)MCG +8VY)2SM +H6Y)X7P +Q7Y)LVY +M7Z)HWF +PP2)PY6 +CTK)CF4 +BVN)PZS +36P)6X9 +SSP)RY1 +GP8)YTV +3NW)8ZK +FWK)RKG +CCB)HZQ +MJX)WH9 +G92)JRM +7XJ)H1R +8H4)BLZ +2HT)7NY +TPZ)8SD +V2V)WHX +VSH)WM6 +LR2)649 +D9L)RVX +W2H)HJM +PV2)HFQ +43Z)GFF +1TD)FPT +NHL)SHF +8F9)8VD +GFF)1FF +Y1C)RMX +8KG)DY6 +6ZR)SD3 +LVC)NYT +HQS)X9N +Q1D)BYW +YD3)LW6 +R3W)H5P +FV1)XLV +LYW)VD4 +DZN)GV8 +1N3)C3Z +JCD)R5T +X9N)8VL +WV2)Q3R +17T)124 +8C2)VB3 +B1V)SZN +NMQ)GT4 +BRN)55R +X1B)9SN +5LW)Y2L +SRJ)RSF +CCV)PP2 +SJQ)LRC +RDX)XWS +QM8)8XZ +X3P)MN6 +GDS)V2M +X5S)4CZ +TDX)XGT +GV8)NJJ +BRM)1MJ +2ZY)L9L +W6P)BRN +QMD)FCK +W28)8DZ +HZ8)XYV +B5H)YOU +GL2)3HH +2WD)VL4 +NYT)6ZR +CSF)C8B +V7N)8VN +21R)N9C +XC9)94P +FD9)5BS +J3P)ZNH +HZ8)V2V +QYM)8PD +VT7)9GB +XHX)RM5 +YXK)43G +53P)G92 +HY2)953 +1N3)TKC +F2N)3S8 +FTP)2YT +VS8)RB5 +HD9)JR6 +XRX)VJM +MN9)LYW +M24)6JW +QD7)B5B +G6B)K38 +S2G)8RQ +BN1)29T +43G)6PL +4WV)H5W +RCB)CHQ +H6R)4TY +LP3)33B +CVH)C29 +C5J)YNK +3Q2)H65 +1QJ)KLL +VKG)L9Z +D2G)36P +HFT)NHP +VS7)Z2T +36C)X3P +4BM)1DG +GN9)ZMW +RGB)48B +K38)1N3 +YRB)T71 +4R7)BNL +Z63)4R7 +5Q2)4C1 +V4D)3VR +DTX)1F9 +R6C)3LL +2FC)H6Y +YYS)YJ4 +34B)XMY +7NY)KC7 +LYS)XTB +JR6)V4D +M5P)L28 +CR3)PHC +VFG)LCQ +Y3G)23H +G5G)FXT +2FV)NGD +BQ9)QD7 +5FF)N84 +RB5)YRB +QBL)YZ9 +7BY)K5T +NWY)D6H +YRK)MN9 +DM5)FT7 +1LX)QYP +KM8)3FG +92L)NMP +QCK)4RB +MLH)JJD +5CY)Z5J +V2T)D3M +4C4)SG7 +J7B)FFL +VKY)WS6 +VT4)JNQ +Y4G)YNQ +MBP)QCK +4C1)CRV +JBB)KTF +GMD)2MQ +NWY)1Z5 +BHQ)C27 +MZZ)R55 +9D7)74F +SKG)3T9 +1H7)DQY +F7Q)JVD +WPM)R6C +2QL)256 +BKF)7LW +3H9)15X +VXF)6X4 +PN3)3KP +DK5)VQS +V5D)ZD1 +4C3)1TD +CHQ)CCB +9HC)CQD +97T)WHB +953)1FC +3PN)GG4 +323)1SP +DF7)T3C +Z46)G7G +F5H)DNB +J2Y)XYN +G9V)FKK +HHQ)GSZ +Q9X)ZR9 +Q5L)PN3 +STT)BKV +7F9)CK7 +JML)7D1 +CQH)BQZ +H8P)HQT +RMY)WZ9 +C92)QKY +9DR)RND +QPC)K87 +74F)HZ8 +4RX)R8C +TWM)44V +6TQ)L6R +7MC)6YR +DMC)73N +ZR9)NHL +8YS)VMX +NZ7)KK5 +WMM)VLZ +SM1)YD3 +VV1)MQM +7BX)VK8 +1QW)SRJ +HWP)YM7 +48B)5NF +3PY)1Z3 +J55)9YP +PKS)LS2 +NP4)SP5 +NWF)V2W +DY7)DVK +FRC)KM8 +Q77)6H7 +7Q3)15K +KKR)NP2 +6KC)G7S +4RB)YR1 +KC7)Y4F +ZGL)FD4 +T4B)QD6 +Q83)BFD +5LW)C1T +G8D)SMJ +5Y3)Q1W +Q7K)4BM +SM3)LR7 +BX4)SKH +12G)SPG +DQ4)SJQ +216)1D1 +1MN)J24 +SF8)DZ2 +FQG)YWG +HST)R3P +F3Z)3SY +5BS)4H2 +QBB)Y2X +W8T)48T +M4P)6CW +JMT)6GP +KVN)5S4 +H65)8C2 +GVX)WMT +WVY)N72 +1DG)L7W +MGC)FRC +MFD)XJ8 +RKG)BX4 +NKS)4FP +QH1)2QL +7YF)PVQ +4C9)2VS +QKY)R7C +83C)KG4 +V4H)2DJ +GQB)DF7 +R7Z)GNT +KZC)JHG +5SM)W16 +2NF)6JN +SHK)94V +X2N)216 +RVQ)X2N +DJQ)NP4 +8VL)Z7P +KWB)8T5 +HJJ)MPZ +K2S)CP9 +NMQ)Z63 +7YL)21R +6LJ)8GQ +58V)VJL +3K3)PQV +V2M)Z4H +SLF)5H8 +S8Y)132 +PQZ)9QW +CLC)L7P +K6N)Q11 +HZQ)K71 +SKH)XX2 +HFQ)Q5J +2ST)WVY +D82)BR7 +CS5)DY7 +9K2)Z1J +J24)PQY +PVV)GVL +HV5)P18 +T4L)GKN +2FG)YJF +DHN)FCL +JM3)4RX +SNB)DJQ +C1T)QYM +5MM)M4P +N74)RJR +6P8)XRX +QYP)6MT +ZMW)7YF +8TP)GQH +XFS)9R3 +FQ9)9B1 +H87)Y8P +MH9)8B4 +4CZ)NXB +DHR)7F9 +GB3)T2B +8SD)1QL +44K)57S +2LJ)FVY +XYV)GK6 +3LL)TJV +5S4)9D9 +BKW)HWP +DJS)ZYY +8DZ)G6B +699)WW2 +XS1)WM3 +48T)YV1 +7RG)Z6B +FKL)9SL +J8J)598 +DQY)1QW +WR6)MJX +K5N)5BV +FZB)4C3 +PBY)ZP5 +D6H)Z35 +Z35)2NM +6JN)787 +38X)NMS +V1Q)5YK +W6G)XC5 +N5F)V4H +ZR8)M5F +L7W)DLD +DWH)7WZ +9QW)Y3G +QRM)MBP +TD9)QVZ +RTT)43Z +H6T)FNV +1X3)VHW +N41)SBX +MN6)MVL +XF3)RK5 +8WB)2S4 +V8V)2BT +T19)8J4 +F11)13C +2PL)GVX +GL2)JB8 +54J)ZLS +2XS)V7N +G1Z)SHK +GKH)RYK +YZ9)YH7 +7TR)VC9 +8HH)LFL \ No newline at end of file diff --git a/day-06/part-1/evqna.rs b/day-06/part-1/evqna.rs new file mode 100644 index 0000000..27c00da --- /dev/null +++ b/day-06/part-1/evqna.rs @@ -0,0 +1,45 @@ +use std::env::args; +use std::time::Instant; + +use std::collections::HashMap; + +fn main() { + let now = Instant::now(); + let output = run(&args().nth(1).expect("Please provide an input")); + let elapsed = now.elapsed(); + println!("_duration:{}", elapsed.as_secs_f64() * 1000.); + println!("{}", output); +} + +fn indirect_orbits(orbits: &HashMap<&str, Vec<&str>>, depth: usize, root: &str) -> usize { + if !orbits.contains_key(root) { + return 0; + } + + orbits[root].iter() + .fold(0, |acc, orbiter| acc + depth + indirect_orbits(&orbits, depth + 1, orbiter)) +} + +fn run(input: &str) -> usize { + let orbits = input + .split_whitespace() + .map(|line| line.split(')').collect::>()); + + let mut orbited_by: HashMap<&str, Vec<&str>> = HashMap::new(); + for objects in orbits { + let (center, orbiter) = (objects[0], objects[1]); + orbited_by.entry(center).or_default().push(orbiter); + } + + indirect_orbits(&orbited_by, 1, "COM") +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn run_test() { + assert_eq!(run("COM)B\nB)C\nC)D\nD)E\nE)F\nB)G\nG)H\nD)I\nE)J\nJ)K\nK)L"), 42) + } +} diff --git a/day-06/part-2/evqna.rs b/day-06/part-2/evqna.rs new file mode 100644 index 0000000..27c00da --- /dev/null +++ b/day-06/part-2/evqna.rs @@ -0,0 +1,45 @@ +use std::env::args; +use std::time::Instant; + +use std::collections::HashMap; + +fn main() { + let now = Instant::now(); + let output = run(&args().nth(1).expect("Please provide an input")); + let elapsed = now.elapsed(); + println!("_duration:{}", elapsed.as_secs_f64() * 1000.); + println!("{}", output); +} + +fn indirect_orbits(orbits: &HashMap<&str, Vec<&str>>, depth: usize, root: &str) -> usize { + if !orbits.contains_key(root) { + return 0; + } + + orbits[root].iter() + .fold(0, |acc, orbiter| acc + depth + indirect_orbits(&orbits, depth + 1, orbiter)) +} + +fn run(input: &str) -> usize { + let orbits = input + .split_whitespace() + .map(|line| line.split(')').collect::>()); + + let mut orbited_by: HashMap<&str, Vec<&str>> = HashMap::new(); + for objects in orbits { + let (center, orbiter) = (objects[0], objects[1]); + orbited_by.entry(center).or_default().push(orbiter); + } + + indirect_orbits(&orbited_by, 1, "COM") +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn run_test() { + assert_eq!(run("COM)B\nB)C\nC)D\nD)E\nE)F\nB)G\nG)H\nD)I\nE)J\nJ)K\nK)L"), 42) + } +} diff --git a/day-07/input/evqna.txt b/day-07/input/evqna.txt new file mode 100644 index 0000000..e69de29 diff --git a/day-07/part-1/evqna.rs b/day-07/part-1/evqna.rs new file mode 100644 index 0000000..71cf1f6 --- /dev/null +++ b/day-07/part-1/evqna.rs @@ -0,0 +1,25 @@ +use std::env::args; +use std::time::Instant; + +fn main() { + let now = Instant::now(); + let output = run(&args().nth(1).expect("Please provide an input")); + let elapsed = now.elapsed(); + println!("_duration:{}", elapsed.as_secs_f64() * 1000.); + println!("{}", output); +} + +fn run(input: &str) -> isize { + // Your code goes here + 0 +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn run_test() { + assert_eq!(run("Test example"), 0) + } +} diff --git a/day-07/part-2/evqna.rs b/day-07/part-2/evqna.rs new file mode 100644 index 0000000..71cf1f6 --- /dev/null +++ b/day-07/part-2/evqna.rs @@ -0,0 +1,25 @@ +use std::env::args; +use std::time::Instant; + +fn main() { + let now = Instant::now(); + let output = run(&args().nth(1).expect("Please provide an input")); + let elapsed = now.elapsed(); + println!("_duration:{}", elapsed.as_secs_f64() * 1000.); + println!("{}", output); +} + +fn run(input: &str) -> isize { + // Your code goes here + 0 +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn run_test() { + assert_eq!(run("Test example"), 0) + } +} diff --git a/day-08/input/evqna.txt b/day-08/input/evqna.txt new file mode 100644 index 0000000..cdb4497 --- /dev/null +++ b/day-08/input/evqna.txt @@ -0,0 +1 @@ +112222222222222212222122220212222222202222222222222122222222202100222222120222101222222122222222221222220102222222222020222222212221222222222222221222102222222222222212222222220222222222202222222222222122222222222100222222120222121222222122222222221222221002222222222222222222202221222222222222222222022222222222222212222222220222222222202222222222222222222222222201222222120222010222222022222222221222220012222222222021222222212222222222222222221222112222222222222222222022222212222222222222222222222022222222202000222222021222021222222222222222221222220202222222222222222222202221222222222222222222212222222222222202222222222222222222222222222222222222222222212021222222021222001222222222222222222222222122222222222222222222222221222222222222221222222222222222222202222122222222222222202222212222222122222202212110222222222222220222222022222222220222221012222222222020222222222221222222222222220222022222222222222202222222221222222222222222212222202122222202202012222222222222220222222122222222222222222122222222222220222222222222222222222212220222112222222222222222222122221212222222222222202222212222222222222111222222121222121222222122222222220222222100222222222221222222212221222222222222221222022222222222222212222022222212222222212222202222222222222212122011222222222222002222222122222222222222220012222222222021222222222220222222222222220222022222222222220212222022222202222222202222212222201122222202222212222222222222102222222222222222222222222212222222222222222222212220222222222202221222002222222222222222222022220212222222212222212222220122222212022201222222121222100222222122222222220222222122222222222122222222202222222222222212222222002222222222222222222122222212222222222222222222222222222222102110222222221222101222222222222222220222221212222222222021222222202222222222222222221222202220222222220212222222222222222222212222202222211022222202022221222222222222001222222122222222021222220012222222222122222222212221222222222222222222212222222222221202222022221222222222222222212222200222222212012101222222021222200222222022222222120222222210222222222021222222212222222222222222220222002222222222221212222222220212222222202222222222212222222222202202222222221222100222222022222222220222222000222222222121222222212220222222222212221222112220222222221222222222222222222222212222212222222122222212122212212222221222010222222022222222022222222002222222222120222222202222222222222202222222222222222222221222222022221222222222212222202222212122222222122201212222120222101222222222222222222222221212222222222120222222222220222222222202220222022221222222222212222122220222222222212222212222212022222202222012222222120222000222222222222222121222222221222022222220222222222222222222222202221222002221222222222222222122222212222222202222012222211222222212112111212222122222020222222022222222022222221011222122222220222222212221222220222211221222112222222222221222222122221222222222222222102222211222222212002101202222020222111222222222022222122222222022222222222122222222222222222220222220222222202222222222220222222122221212222222202222222222222022222222202200222221021222220222221222122222122222221011222022222222222222202220222220222201222222112222222222221202222122222222222222222222012222210122222212012000202222121222011222221022220222020222220002222122222222222222222220222222222202020222002220222222222222222122221022222222202222222222220122222212102201222221022222221222221022022222222222220100202222222220222222202220222221202201221222022221222222220222222022220002222222202222202222210222222202022101202222220222120222221220021222021222221000212122222220222222212222222220222211122222002222222222220202222222221212222222222222102222221222222212002001202222021222011222220021121222222222220201212122222021222222212220222222222221220220022220222222221212222122222222222222222222102222222022222202112000222021022222011222222121220222121222220101222022222122222222212221222222212212122222022220222222121222222222220202222222222222012222210222222212222120222220221222222222221121121222220222220022212222222222222222222220222220202220020222202221212222020222222222221022222222212222112222202022222212212021202222021222202222220122221222120222220020112122222022222222200222222222222210120222022222202222021212222022222002202222222222222222221122222202112201212221020222200220221020120222022222220012212022222120222222212222222222212211122222012222212222020222222122221002212222212222102222222222222210002010212221221222211222221220121222222222220211102122222022222222220221222221222220122221222221212222022202222122222122222222202222012222211022222202222110222121122222112221221222222222121222220202122022222022222222220220222222212200020221202220222222221202222222220202222222222222022222211122222222222120212022221222120222222221120222122222222100222022222021222222201222222220222220220222022222212222120211222122220222212222202222222222202222222212212221202221221222021221220021220222022222222002112122222021222222211220222221222200122222212021202222122200222122220022202222202222222222211222222200122122212122220222112221220122122222120222222222102022222122202222220221222221202202220222102222212222022200222112220222212222212222212222220022222212012020202121120222212221222020220222120222221101122222222022212222210220222221202211222220022021202222222220222120222222202222202222012222210222222210212021212021120222102220222222220222120222221000122122222220202222222020222222212222021222112022212222221202222021222102220222212222022222221022222222202102212021121222101222222120021222122222222212122122222021202222210022222222222212220222112021202222122201222101222212202222202222102222211022222210012010212120222222121221222121021222022222222002112022222222212202200222222222222210222220012121212222120202222012221102212222201222212222212122222220122101212221222222212222222020222222122222221122212022222121212222211221222222222220120222222220222222120221222200221112211222212222112222211122222220222010222121220222211220220120021222022222220021222222222020212212210221222221202222122222012220202222221211222212220202211222201222112222212122222202112222222121122222220222222120120222021222222001212122222021212212200121222221212200022222222020202222020222222100220112221222200222022222221222222200012010212221120222200222222220121222221222222211022222222222202222221122222221212210221220222120212222121200222100220202211222200222022122212122222222122100212121120122212221221021122222020222222102202222222022202222210121222220212200220222122221222222222200222110222012201222222222002022211122222211222001222021022122101220220221120222021222222200112122222020212212210020222220222212122221222220202222020212222010221122202222220222022222220022222221122221212120021122222221222220020222021222220010012222222022202212221121222220222201122220212221212222020211122202220112200222201222112022201222222202102022212021020122021222220222221222021222221000102022222120212222220021222221222222121220102022202222020202222000220002211222221222002022220022222201022112222122121222102220221120121222120222221201212122222222212202220022222222221200022222222222222222022212122211221112222222222222012022222222222220122120212122021022202220222220220222122222222210212122222122212222212021222200220201021222202120222222022221222212220222210222212222202122211222222212002001202022222022200220220222120222021222221222002122222122212222221221222221201211221221012220222221220200122212212102210222210222212122221122222212122101212122022022211221221122122222222222222200012102222020212212221221222202210211221221022021202220022220222101202222211222221222002122211222222202122100212221122022001220222122221222121222221020212002222122222212202222222201222210221220001221212221022221222201211222211222202222122222211222222222122202212121121122010220221222121222021222220201012212222220212212211220222211212202220222221022202222220220122101202022221222221222122222201022222200002202212220021222000222222021220222102222222202202102222120222212211222222201211210021222211120222221021221122120220222220222210222012222201022222221202121222020122122201220021120221222211222220122212122222220212222201221222210200211220222111020212221222211122000220002210222212222202002201222222201222202222222020222011221021120222222211222221120002222222022202222210222222201210201122220001222222221020202122020202022212222201202002012202222222200002101212122121222012220022022120222120222220110102002222122212202211022222220210200220221222121222222220212122020212112220222221212102102212022222210212221202122221022021220021021221222010222222011102222222221202212212020222222202201221221211222202221020201022120202102201222210212202222212122222201222011212121222122201222120220220222121222221210002112222220222202222022222211212221121222101121222222120200222202201012222222201212002012210222222221002111202021221122000222220020121222020222220122202022222020222212211121122211222222220222020220202221120221222111212022221222201212112122222022222221022100222122122122222222122022220222222222220002202212222222212202221222022210221222022220212121222222022222122201222122212222202202212202221122222211102112202222020022002222121221022022200220221020011202222121212212200121122200210202222222111220222220222200022112212002211222200222122202211022222212120211222221220022020220022221021222011222221120011002222021212212222222222210220221121221020222212221022220122000202102201222221212002122212122222001012121202122222022001222220022121022201222020200212112222020202222210021122212212210221222000221222221222202022122200222200222221222222212220222222200000012212120021122210222020120221222202221021000022102222220212112201122022222202201022222211222212222221222122221212112222222220212112212212022222112212011222122220122120222221220022022110221020111000112222120202222202021022221202200022220000220222220222221122122222002222222212212022112221122222201112210212220122222212222020222112222022221122122010222222120222012220121122211212200122220212222202220020202022210212022210222201222222122222022222011002011202120222122211221221222211102101221121202220102222122212212221222122210200202220221010122210220020201022020212122202222212202222212222222222001022201212022020222102220021122201221011221222212010002222220202002200021222201210221121220110221210221020211222012202102201222200212102212222122222212221001202021022122211222020122111221110220021212222012222221212212210020222212201200122221200222211222120212122122201222210222202222222002202222222222001222222121221022020222221022121021110220122211000122222121222011211022222221221111020222011120220220020221022020222212212222222212002212200022222221002221212220021022021222220022222000200222020100202002222200212002200220022220202201220222222021222220221210122101222102220222202212212102201122222002020012222022222202012221221222122121120221021112221212212001222000211220022222212002121220010121212220220201222020220012212222210222102022221022222221101021212021021122122222121222222101101222120110110112212010102111220222222202212011020222212222111222221210122020221212220222211202110022221222222102011120212120020102120221222222111121220222120011112002202010122212222220222201200112021200112121120220020201022110200002202222211222200022220122222200220111212021122012012221221222000211012221021201122212222022022012212022022200202012222212201022210221220211022102210112212222220222200012201222222011120101212022121022002220122121212122002221122101110202212110112012210122022201212210112212110121221222021212022200201102200222211202200022220222222000210201202020021010002222020021201101220220122201220202222102102021212120122211201001112212020122110221022220122122220012212222211202200212212022222022202222222121221202122221220222011000012222221212020212202222212202200221022201221111000200000220002220200210122221222012202222211212000202222222222021201101202122122020222220120221112200121210020210101122212201012021210221122200211102212200012020200220220222022111212202211222222222222212202122222111202022222222121021111220220120001220120222021211200002222000022000202221222210210220101220102021110220112200221122210212212222220222012112220122222112020110222220121121211202020022111000100211022112020212212121102022212222122202222220201212002022012222002202020010222212212202202202222212212022222010210101202122020002101222022122202022121222120220100102212120012020220020222201201000211211120120112222202212222021021112220202202202120022212022222021111220202222022222121201022120201010212211122121202002212121222222222022022202221021010201111201200220112201122220010222210222202222102012222222222112020002222020121220221221021221211212021202121021100022212020212210212122122201220120000211202201121222101222220202122002210222210202221222202222222221210001212022120221222211020022022001002220220222000012202021002020200222022210221011220200101202012220220202221201020122220222222202202112220222222102121221212122021100121210020122112201210220021120012002202101002002220220222212201022100221122220011210011222021020201022211222200212121112200022022002210100212222022122000200021120110212011200220001020202212022122122202220222211002022220200122020122200001212021200110202212222212212001212222022222000200101222010221210201211021022111100001221120221201212212222202211220121022221001121111221222212011200110202120121001202200212222202212202212122022100010012222211121110001202022222120022020221222002202002222011102212200220022210111202010210122212200211000102021001010202220222202202100222220122022100112200212211122012202011020220102021210202020221000222202020212201210022122202012211212211010011200211002020122110021022202202222222211112211222222000102010222222221112210211122122022112122222020001002212222101102221201021222210201010220221011022102202110221221022010222222222221212022102221222022120111002202210022121121100221121221000120212022212121112212220112010212222222211020222010202112201010212110001220102211222220222210202210112221122212201222200212112221120220212020221201100210210120111020112212100112201211020122222020211220200002101012201211122221022201012201202212222102112221022102021100112212201021102002011222120220200200202022110012122202000212202220221122211020011012210022000121200121200122202011212220212212212222222202022022000220022212102221100111101221120002111210000122201220212202100002202202022022201110201021222110120202222000012021211021122212221220202201022201122122001201022212210220121002000020121212020022021221222111012202210102211201121022210002120001220212020012210020222021120121222220221201222102002202222022000201001222122220222210010222022102200120202220002201102212001112012210200022220101122102202111121121210100220221020012212200210212202111212201022012201010020202201020202110002122220211200202212021001110022202001022022220201122212012010111210101002020222011112222111210122200220012220220002210222222001012120222112121012001112021121202212121112121012112112212210002010210222222202111200210211202121012002102000101211111010100120221012202200121110120121110120020121100021222100011001001200112000212100001000010102120220120002000122100001220102 \ No newline at end of file diff --git a/day-08/part-1/evqna.rs b/day-08/part-1/evqna.rs new file mode 100644 index 0000000..04bb74e --- /dev/null +++ b/day-08/part-1/evqna.rs @@ -0,0 +1,50 @@ +use std::env::args; +use std::time::Instant; + +fn main() { + let now = Instant::now(); + let output = run(&args().nth(1).expect("Please provide an input")); + let elapsed = now.elapsed(); + println!("_duration:{}", elapsed.as_secs_f64() * 1000.); + println!("{}", output); +} + +const WIDTH: usize = 25; +const HEIGHT: usize = 6; + +fn run(input: &str) -> usize { + let layers = input.as_bytes() + .chunks_exact(WIDTH * HEIGHT); + + let min_layer = layers + .min_by_key(|&layer| { + layer.iter().filter(|&&x| x == b'0').count() + }) + .unwrap(); + + layer_value(min_layer) +} + +fn layer_value(layer: &[u8]) -> usize { + // Filter + let ones = layer.iter().filter(|&&x| x == b'1').count(); + let twos = layer.iter().filter(|&&x| x == b'2').count(); + + // Fold +// let (ones, twos) = layer.iter().fold((0,0), |(ones, twos), &n| { +// if n == b'1' { (ones+1,twos) } else if n == b'2' { (ones,twos+1) } else { (ones,twos) } +// }); + + // Loop +// let (mut ones, mut twos) = (0, 0); +// for &n in layer { +// if n == b'1' { +// ones += 1; +// } +// else if n == b'2' { +// twos += 1; +// } +// } + + ones * twos +} diff --git a/day-08/part-2/evqna.rs b/day-08/part-2/evqna.rs new file mode 100644 index 0000000..cc2f615 --- /dev/null +++ b/day-08/part-2/evqna.rs @@ -0,0 +1,44 @@ +use std::env::args; +use std::time::Instant; + +use std::str; + +fn main() { + let now = Instant::now(); + let output = run(&args().nth(1).expect("Please provide an input")); + let elapsed = now.elapsed(); + println!("_duration:{}", elapsed.as_secs_f64() * 1000.); + println!("{}", output); +} + +const WIDTH: usize = 25; +const HEIGHT: usize = 6; + +fn run(input: &str) -> String { + let mut image = [0 as u8; WIDTH * HEIGHT]; + + input.as_bytes() + .chunks_exact(WIDTH * HEIGHT) + .for_each(|layer| { + for (p, b) in image.iter_mut().zip(layer) { + if *p == 0 && *b != b'2' { + *p = *b; + } + } + }); +// print_dbg(&image); + str::from_utf8(&image).unwrap().to_string() +} + +fn print_dbg(image: &[u8; WIDTH * HEIGHT]) { + for line in 0..HEIGHT { + for &n in &image[line*WIDTH..(line+1)*WIDTH] { + if n == b'1' { + print!("#"); + } else { + print!(" "); + } + } + print!("\n"); + } +} diff --git a/day-09/input/evqna.txt b/day-09/input/evqna.txt new file mode 100644 index 0000000..50089fa --- /dev/null +++ b/day-09/input/evqna.txt @@ -0,0 +1 @@ +1102,34463338,34463338,63,1007,63,34463338,63,1005,63,53,1102,3,1,1000,109,988,209,12,9,1000,209,6,209,3,203,0,1008,1000,1,63,1005,63,65,1008,1000,2,63,1005,63,904,1008,1000,0,63,1005,63,58,4,25,104,0,99,4,0,104,0,99,4,17,104,0,99,0,0,1101,0,31,1019,1101,25,0,1008,1102,35,1,1009,1102,422,1,1029,1102,1,21,1005,1102,1,734,1027,1102,29,1,1000,1101,32,0,1018,1102,28,1,1016,1101,0,38,1015,1101,0,378,1023,1101,30,0,1017,1102,1,381,1022,1101,0,37,1006,1102,1,1,1021,1101,0,24,1011,1102,1,23,1002,1101,0,0,1020,1101,0,20,1007,1101,427,0,1028,1101,26,0,1014,1101,27,0,1010,1101,0,39,1001,1101,34,0,1012,1102,1,36,1013,1101,0,33,1003,1101,804,0,1025,1101,737,0,1026,1102,1,809,1024,1102,1,22,1004,109,9,1201,-7,0,63,1008,63,20,63,1005,63,205,1001,64,1,64,1106,0,207,4,187,1002,64,2,64,109,2,21102,40,1,1,1008,1012,40,63,1005,63,233,4,213,1001,64,1,64,1106,0,233,1002,64,2,64,109,4,1208,-7,25,63,1005,63,255,4,239,1001,64,1,64,1106,0,255,1002,64,2,64,109,-24,1207,10,38,63,1005,63,271,1105,1,277,4,261,1001,64,1,64,1002,64,2,64,109,25,21107,41,40,-3,1005,1013,293,1105,1,299,4,283,1001,64,1,64,1002,64,2,64,109,5,1205,-1,311,1106,0,317,4,305,1001,64,1,64,1002,64,2,64,109,-23,1202,6,1,63,1008,63,22,63,1005,63,339,4,323,1105,1,343,1001,64,1,64,1002,64,2,64,109,1,2101,0,2,63,1008,63,37,63,1005,63,367,1001,64,1,64,1106,0,369,4,349,1002,64,2,64,109,29,2105,1,-5,1106,0,387,4,375,1001,64,1,64,1002,64,2,64,109,-26,2101,0,0,63,1008,63,23,63,1005,63,409,4,393,1106,0,413,1001,64,1,64,1002,64,2,64,109,26,2106,0,0,4,419,1106,0,431,1001,64,1,64,1002,64,2,64,109,-17,21108,42,42,6,1005,1017,453,4,437,1001,64,1,64,1106,0,453,1002,64,2,64,109,7,21101,43,0,-8,1008,1010,44,63,1005,63,477,1001,64,1,64,1105,1,479,4,459,1002,64,2,64,109,-7,1206,10,495,1001,64,1,64,1106,0,497,4,485,1002,64,2,64,109,-5,2108,36,0,63,1005,63,513,1106,0,519,4,503,1001,64,1,64,1002,64,2,64,109,3,2102,1,-5,63,1008,63,22,63,1005,63,541,4,525,1105,1,545,1001,64,1,64,1002,64,2,64,109,3,1207,-6,38,63,1005,63,567,4,551,1001,64,1,64,1105,1,567,1002,64,2,64,109,-15,2107,20,8,63,1005,63,585,4,573,1106,0,589,1001,64,1,64,1002,64,2,64,109,-1,1208,5,36,63,1005,63,609,1001,64,1,64,1106,0,611,4,595,1002,64,2,64,109,30,21101,44,0,-7,1008,1019,44,63,1005,63,633,4,617,1106,0,637,1001,64,1,64,1002,64,2,64,109,-25,1201,0,0,63,1008,63,39,63,1005,63,659,4,643,1105,1,663,1001,64,1,64,1002,64,2,64,109,27,1206,-8,677,4,669,1106,0,681,1001,64,1,64,1002,64,2,64,109,-28,2108,29,0,63,1005,63,703,4,687,1001,64,1,64,1106,0,703,1002,64,2,64,109,5,21107,45,46,7,1005,1012,725,4,709,1001,64,1,64,1106,0,725,1002,64,2,64,109,30,2106,0,-8,1105,1,743,4,731,1001,64,1,64,1002,64,2,64,109,-22,21102,46,1,4,1008,1017,44,63,1005,63,767,1001,64,1,64,1105,1,769,4,749,1002,64,2,64,109,-15,1202,10,1,63,1008,63,23,63,1005,63,793,1001,64,1,64,1106,0,795,4,775,1002,64,2,64,109,19,2105,1,7,4,801,1105,1,813,1001,64,1,64,1002,64,2,64,109,6,1205,-2,827,4,819,1106,0,831,1001,64,1,64,1002,64,2,64,109,-20,2107,22,2,63,1005,63,851,1001,64,1,64,1106,0,853,4,837,1002,64,2,64,109,20,21108,47,44,-8,1005,1015,869,1105,1,875,4,859,1001,64,1,64,1002,64,2,64,109,-22,2102,1,4,63,1008,63,23,63,1005,63,899,1001,64,1,64,1106,0,901,4,881,4,64,99,21101,0,27,1,21102,915,1,0,1106,0,922,21201,1,28703,1,204,1,99,109,3,1207,-2,3,63,1005,63,964,21201,-2,-1,1,21101,0,942,0,1106,0,922,22101,0,1,-1,21201,-2,-3,1,21101,957,0,0,1105,1,922,22201,1,-1,-2,1105,1,968,21201,-2,0,-2,109,-3,2105,1,0 \ No newline at end of file diff --git a/day-09/part-1/evqna.rs b/day-09/part-1/evqna.rs new file mode 100644 index 0000000..70f2db1 --- /dev/null +++ b/day-09/part-1/evqna.rs @@ -0,0 +1,210 @@ +use std::env::args; +use std::time::Instant; + +fn main() { + let now = Instant::now(); + let output = run(&args().nth(1).expect("Please provide an input")); + let elapsed = now.elapsed(); + println!("_duration:{}", elapsed.as_secs_f64() * 1000.); + println!("{}", output); +} + +fn run(input: &str) -> isize { + let mut mem: Vec = input + .split(',') + .map(|n| n.parse().unwrap()) + .collect(); + mem.resize(10_000, 0); + + let mut computer = Computer::new(&mut mem); + computer.run() +} + +#[derive(Debug)] +#[derive(PartialEq)] +enum Op { + Add, + Mul, + Input, + Output, + JumpTrue, + JumpFalse, + Leq, + Eq, + AdjustBase, + Exit, +} + +#[derive(Debug, Copy, Clone)] +#[derive(PartialEq)] +enum Mode { + Position, + Immediate, + Relative, +} + +#[derive(Debug)] +struct Operation { opcode: Op, operands: Vec } + +#[derive(Debug)] +struct Operand { mode: Mode, operand: isize } + +struct Computer<'a> { + ip: usize, + relative_base: isize, + mem: &'a mut [isize], + outputs: Vec, +} + +const INPUT: isize = 1; + +impl Computer<'_> { + fn new(mem: &mut [isize]) -> Computer { + Computer { + ip: 0, relative_base: 0, + mem, outputs: Vec::new(), + } + } + + fn run(&mut self) -> isize { + self.ip = 0; + loop { + let op = parse_op(&self.mem[self.ip..]); +// println!("{:?}", op); + if op.opcode == Op::Exit { + break; + } + + let last_ip = self.ip; + self.run_op(&op); + if self.ip == last_ip { + self.ip += op.operands.len() + 1; + } + } + *self.outputs.last().unwrap() + } + + fn run_op(&mut self, op: &Operation) { + match op.opcode { + Op::Add => { + let (a, b, c) = self.resolve_binary_operands(&op.operands); + *c = a + b; + } + Op::Mul => { + let (a, b, c) = self.resolve_binary_operands(&op.operands); + *c = a * b; + } + Op::Input => { + let a = self.get_write_operand_ref(&op.operands[0]); + *a = INPUT; + } + Op::Output => { + let a = self.get_read_operand_value(&op.operands[0]); +// println!("{}", a); + self.outputs.push(a); + } + Op::JumpTrue => { + let a = self.get_read_operand_value(&op.operands[0]); + let b = self.get_read_operand_value(&op.operands[1]); + if a != 0 { + self.ip = b as usize; + } + } + Op::JumpFalse => { + let a = self.get_read_operand_value(&op.operands[0]); + let b = self.get_read_operand_value(&op.operands[1]); + if a == 0 { + self.ip = b as usize; + } + } + Op::Leq => { + let (a, b, c) = self.resolve_binary_operands(&op.operands); + *c = if a < b { 1 } else { 0 }; + } + Op::Eq => { + let (a, b, c) = self.resolve_binary_operands(&op.operands); + *c = if a == b { 1 } else { 0 }; + } + Op::AdjustBase => { + let a = self.get_read_operand_value(&op.operands[0]); + self.relative_base += a; + } + Op::Exit => {} + } + } + + fn get_read_operand_value(&self, operand: &Operand) -> isize { + match operand.mode { + Mode::Immediate => operand.operand as isize, + Mode::Position => self.mem[operand.operand as usize], + Mode::Relative => self.mem[(operand.operand + self.relative_base) as usize], + } + } + + fn get_write_operand_ref(&mut self, operand: &Operand) -> &mut isize { + match operand.mode { + Mode::Position => &mut self.mem[operand.operand as usize], + Mode::Relative => &mut self.mem[(operand.operand + self.relative_base) as usize], + _ => panic!("Invalid operand write mode"), + } + } + + fn resolve_binary_operands(&mut self, operands: &[Operand]) -> (isize, isize, &mut isize) { + let a = self.get_read_operand_value(&operands[0]); + let b = self.get_read_operand_value(&operands[1]); + let c = self.get_write_operand_ref(&operands[2]); + (a, b, c) + } +} + +fn parse_op(mem_slice: &[isize]) -> Operation { + let instr = mem_slice[0] as usize; + let (opcode, nb_operands) = match instr % 100 { + 1 => (Op::Add, 3), + 2 => (Op::Mul, 3), + 3 => (Op::Input, 1), + 4 => (Op::Output, 1), + 5 => (Op::JumpTrue, 2), + 6 => (Op::JumpFalse, 2), + 7 => (Op::Leq, 3), + 8 => (Op::Eq, 3), + 9 => (Op::AdjustBase, 1), + 99 => (Op::Exit, 0), + n => panic!("Invalid opcode {}", n), + }; + let modes = parse_modes(instr / 100, nb_operands); + let operands = (0..nb_operands) + .map(|i| Operand { operand: mem_slice[i + 1], mode: modes[i]}) + .collect(); + + Operation { opcode, operands } +} + +fn parse_modes(mut encoded_modes: usize, n: usize) -> Vec { + let mut modes = Vec::new(); + for _ in 0..n { + match encoded_modes % 10 { + 0 => modes.push(Mode::Position), + 1 => modes.push(Mode::Immediate), + 2 => modes.push(Mode::Relative), + n => panic!("Invalid operation mode {}", n), + } + encoded_modes /= 10; + } + modes +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn run_test() { + assert_eq!(run("3,21,1008,21,8,20,1005,20,22,107,8,21,20,1006,20,31,\ +1106,0,36,98,0,0,1002,21,125,20,4,20,1105,1,46,104,\ +999,1105,1,46,1101,1000,1,20,4,20,1105,1,46,98,99"), 999); + assert_eq!(run("1102,34915192,34915192,7,4,7,99,0"), 1219070632396864); + assert_eq!(run("104,1125899906842624,99"), 1125899906842624); + assert_eq!(run("109,1,204,-1,1001,100,1,100,1008,100,16,101,1006,101,0,99"), 99); + } +} diff --git a/day-09/part-2/evqna.rs b/day-09/part-2/evqna.rs new file mode 100644 index 0000000..971781f --- /dev/null +++ b/day-09/part-2/evqna.rs @@ -0,0 +1,195 @@ +use std::env::args; +use std::time::Instant; + +fn main() { + let now = Instant::now(); + let output = run(&args().nth(1).expect("Please provide an input")); + let elapsed = now.elapsed(); + println!("_duration:{}", elapsed.as_secs_f64() * 1000.); + println!("{}", output); +} + +fn run(input: &str) -> isize { + let mut mem: Vec = input + .split(',') + .map(|n| n.parse().unwrap()) + .collect(); + mem.resize(10_000, 0); + + let mut computer = Computer::new(&mut mem); + computer.run() +} + +#[derive(Debug)] +#[derive(PartialEq)] +enum Op { + Add, + Mul, + Input, + Output, + JumpTrue, + JumpFalse, + Leq, + Eq, + AdjustBase, + Exit, +} + +#[derive(Debug, Copy, Clone)] +#[derive(PartialEq)] +enum Mode { + Position, + Immediate, + Relative, +} + +#[derive(Debug)] +struct Operation { opcode: Op, operands: Vec } + +#[derive(Debug)] +struct Operand { mode: Mode, operand: isize } + +struct Computer<'a> { + ip: usize, + relative_base: isize, + mem: &'a mut [isize], + outputs: Vec, +} + +const INPUT: isize = 2; + +impl Computer<'_> { + fn new(mem: &mut [isize]) -> Computer { + Computer { + ip: 0, relative_base: 0, + mem, outputs: Vec::new(), + } + } + + fn run(&mut self) -> isize { + self.ip = 0; + loop { + let op = parse_op(&self.mem[self.ip..]); +// println!("{:?}", op); + if op.opcode == Op::Exit { + break; + } + + let last_ip = self.ip; + self.run_op(&op); + if self.ip == last_ip { + self.ip += op.operands.len() + 1; + } + } + *self.outputs.last().unwrap() + } + + fn run_op(&mut self, op: &Operation) { + match op.opcode { + Op::Add => { + let (a, b, c) = self.resolve_binary_operands(&op.operands); + *c = a + b; + } + Op::Mul => { + let (a, b, c) = self.resolve_binary_operands(&op.operands); + *c = a * b; + } + Op::Input => { + let a = self.get_write_operand_ref(&op.operands[0]); + *a = INPUT; + } + Op::Output => { + let a = self.get_read_operand_value(&op.operands[0]); +// println!("{}", a); + self.outputs.push(a); + } + Op::JumpTrue => { + let a = self.get_read_operand_value(&op.operands[0]); + let b = self.get_read_operand_value(&op.operands[1]); + if a != 0 { + self.ip = b as usize; + } + } + Op::JumpFalse => { + let a = self.get_read_operand_value(&op.operands[0]); + let b = self.get_read_operand_value(&op.operands[1]); + if a == 0 { + self.ip = b as usize; + } + } + Op::Leq => { + let (a, b, c) = self.resolve_binary_operands(&op.operands); + *c = if a < b { 1 } else { 0 }; + } + Op::Eq => { + let (a, b, c) = self.resolve_binary_operands(&op.operands); + *c = if a == b { 1 } else { 0 }; + } + Op::AdjustBase => { + let a = self.get_read_operand_value(&op.operands[0]); + self.relative_base += a; + } + Op::Exit => {} + } + } + + fn get_read_operand_value(&self, operand: &Operand) -> isize { + match operand.mode { + Mode::Immediate => operand.operand as isize, + Mode::Position => self.mem[operand.operand as usize], + Mode::Relative => self.mem[(operand.operand + self.relative_base) as usize], + } + } + + fn get_write_operand_ref(&mut self, operand: &Operand) -> &mut isize { + match operand.mode { + Mode::Position => &mut self.mem[operand.operand as usize], + Mode::Relative => &mut self.mem[(operand.operand + self.relative_base) as usize], + _ => panic!("Invalid operand write mode"), + } + } + + fn resolve_binary_operands(&mut self, operands: &[Operand]) -> (isize, isize, &mut isize) { + let a = self.get_read_operand_value(&operands[0]); + let b = self.get_read_operand_value(&operands[1]); + let c = self.get_write_operand_ref(&operands[2]); + (a, b, c) + } +} + +fn parse_op(mem_slice: &[isize]) -> Operation { + let instr = mem_slice[0] as usize; + let (opcode, nb_operands) = match instr % 100 { + 1 => (Op::Add, 3), + 2 => (Op::Mul, 3), + 3 => (Op::Input, 1), + 4 => (Op::Output, 1), + 5 => (Op::JumpTrue, 2), + 6 => (Op::JumpFalse, 2), + 7 => (Op::Leq, 3), + 8 => (Op::Eq, 3), + 9 => (Op::AdjustBase, 1), + 99 => (Op::Exit, 0), + n => panic!("Invalid opcode {}", n), + }; + let modes = parse_modes(instr / 100, nb_operands); + let operands = (0..nb_operands) + .map(|i| Operand { operand: mem_slice[i + 1], mode: modes[i]}) + .collect(); + + Operation { opcode, operands } +} + +fn parse_modes(mut encoded_modes: usize, n: usize) -> Vec { + let mut modes = Vec::new(); + for _ in 0..n { + match encoded_modes % 10 { + 0 => modes.push(Mode::Position), + 1 => modes.push(Mode::Immediate), + 2 => modes.push(Mode::Relative), + n => panic!("Invalid operation mode {}", n), + } + encoded_modes /= 10; + } + modes +}