From 22f51dc3ab3b89b18db588f5908d53a6dc289c6c Mon Sep 17 00:00:00 2001 From: Vladan Popovic Date: Sun, 15 Dec 2019 22:12:21 +0100 Subject: [PATCH 01/12] Implement with Coordinates struct --- src/day_three.rs | 125 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 102 insertions(+), 23 deletions(-) diff --git a/src/day_three.rs b/src/day_three.rs index 5b13a59..45a6f4e 100644 --- a/src/day_three.rs +++ b/src/day_three.rs @@ -1,14 +1,66 @@ +use std::cmp::Ordering; use std::collections::BTreeSet; use std::io; use std::iter::{repeat, successors}; -fn next(c: (i32, i32), direction: &str) -> (i32, i32) { - match direction { - "R" => (c.0 + 1, c.1), - "L" => (c.0 - 1, c.1), - "U" => (c.0, c.1 + 1), - "D" => (c.0, c.1 - 1), - _ => panic!("Wrong direction format!"), +#[derive(Clone, Copy, Debug, Eq)] +struct Coordinate { + step: usize, + x: i32, + y: i32, +} + +impl PartialEq for Coordinate { + fn eq(&self, other: &Self) -> bool { + self.x == other.x && self.y == other.y + } +} + +impl Ord for Coordinate { + fn cmp(&self, other: &Self) -> Ordering { + self.x.cmp(&other.x) + } +} + +impl PartialOrd for Coordinate { + fn partial_cmp(&self, other: &Self) -> Option { + self.y.partial_cmp(&other.y) + } +} + +impl Coordinate { + fn new() -> Self { + Self { + step: 0, + x: 0, + y: 0, + } + } + + fn next(self: &Self, direction: &str) -> Coordinate { + match direction { + "R" => Coordinate { + step: self.step + 1, + x: self.x + 1, + y: self.y, + }, + "L" => Coordinate { + step: self.step + 1, + x: self.x - 1, + y: self.y, + }, + "U" => Coordinate { + step: self.step + 1, + x: self.x, + y: self.y + 1, + }, + "D" => Coordinate { + step: self.step + 1, + x: self.x, + y: self.y - 1, + }, + _ => panic!("Wrong direction format!"), + } } } @@ -19,7 +71,7 @@ fn direction_length(entry: String) -> (String, usize) { ) } -fn to_coordinates(entries: Vec) -> BTreeSet<(i32, i32)> { +fn to_coordinates(entries: Vec) -> BTreeSet { let mut wire = BTreeSet::new(); let mut it = entries @@ -29,8 +81,8 @@ fn to_coordinates(entries: Vec) -> BTreeSet<(i32, i32)> { successors( it.next() - .map(|direction| (next((0, 0), direction.as_ref()))), - |c| it.next().map(|direction| (next(*c, direction.as_ref()))), + .map(|direction| (Coordinate::next(&Coordinate::new(), direction.as_ref()))), + |c| it.next().map(|direction| (c.next(direction.as_ref()))), ) .for_each(|c| { wire.insert(c); @@ -39,26 +91,33 @@ fn to_coordinates(entries: Vec) -> BTreeSet<(i32, i32)> { wire } -fn distance(position: (i32, i32)) -> i32 { - position.0.abs() + position.1.abs() -} - fn closest(input: String) -> Option { - let entries: Vec> = input + let entries: Vec> = input .trim() .split("\n") .map(|line| line.split(",").map(String::from).collect()) .map(to_coordinates) .collect(); + println!( + "{:?}", + entries[0] + .intersection(&entries[1]) + .cloned() + .map(|c| c.x.abs() + c.y.abs()) + .collect::>() + ); + entries[0] .intersection(&entries[1]) .cloned() - .map(distance) + .map(|c| c.x.abs() + c.y.abs()) .min() } -fn first(input: String) -> Option {} +fn best(input: String) -> Option { + None +} pub fn main() -> io::Result<()> { let closest = closest(std::include_str!("../day3-input.txt").to_owned()); @@ -69,17 +128,37 @@ pub fn main() -> io::Result<()> { #[test] fn test_coordinates_for_entry() { - let mut expected: BTreeSet<(i32, i32)> = BTreeSet::new(); + let mut expected: BTreeSet = BTreeSet::new(); for i in 1..11 { - expected.insert((i, 0)); + expected.insert(Coordinate { + step: i, + x: i as i32, + y: 0, + }); } assert_eq!(to_coordinates(vec!["R10".to_owned()]), expected); expected = BTreeSet::new(); - expected.insert((1, 0)); - expected.insert((2, 0)); - expected.insert((2, 1)); - expected.insert((2, 2)); + expected.insert(Coordinate { + step: 1, + x: 1, + y: 0, + }); + expected.insert(Coordinate { + step: 2, + x: 2, + y: 0, + }); + expected.insert(Coordinate { + step: 3, + x: 1, + y: 1, + }); + expected.insert(Coordinate { + step: 4, + x: 2, + y: 2, + }); let input = "R2,U2".to_owned().split(",").map(String::from).collect(); assert_eq!(to_coordinates(input), expected); } From 7e4a7641ff7885a80df46076a7bec3307aef3af8 Mon Sep 17 00:00:00 2001 From: Vladan Popovic Date: Sun, 15 Dec 2019 23:18:00 +0100 Subject: [PATCH 02/12] Refactor to struct and enumerate steps --- src/day_three.rs | 115 ++++++++++++++++++++++++++++++----------------- 1 file changed, 75 insertions(+), 40 deletions(-) diff --git a/src/day_three.rs b/src/day_three.rs index 5b13a59..25e7544 100644 --- a/src/day_three.rs +++ b/src/day_three.rs @@ -1,50 +1,60 @@ +use std::cmp::Ordering; use std::collections::BTreeSet; use std::io; use std::iter::{repeat, successors}; -fn next(c: (i32, i32), direction: &str) -> (i32, i32) { +#[derive(Copy, Clone, Eq, Debug)] +struct Coord(usize, (i32, i32)); + +impl PartialEq for Coord { + fn eq(&self, other: &Self) -> bool { + self.1 == other.1 + } +} + +impl Ord for Coord { + fn cmp(&self, other: &Self) -> Ordering { + (self.1).cmp(&(other.1)) + } +} + +impl PartialOrd for Coord { + fn partial_cmp(&self, other: &Self) -> Option { + self.1.partial_cmp(&other.1) + } +} + +fn next(c: (i32, i32), direction: char) -> (i32, i32) { match direction { - "R" => (c.0 + 1, c.1), - "L" => (c.0 - 1, c.1), - "U" => (c.0, c.1 + 1), - "D" => (c.0, c.1 - 1), + 'R' => (c.0 + 1, c.1), + 'L' => (c.0 - 1, c.1), + 'U' => (c.0, c.1 + 1), + 'D' => (c.0, c.1 - 1), _ => panic!("Wrong direction format!"), } } -fn direction_length(entry: String) -> (String, usize) { - ( - entry.chars().nth(0).unwrap().to_string(), - entry[1..].parse().unwrap(), - ) -} - -fn to_coordinates(entries: Vec) -> BTreeSet<(i32, i32)> { +fn to_coordinates(entries: Vec) -> BTreeSet { let mut wire = BTreeSet::new(); let mut it = entries .into_iter() - .map(direction_length) + .map(|entry| (entry.chars().nth(0).unwrap(), entry[1..].parse().unwrap())) .flat_map(|(direction, length)| repeat(direction).take(length)); - successors( - it.next() - .map(|direction| (next((0, 0), direction.as_ref()))), - |c| it.next().map(|direction| (next(*c, direction.as_ref()))), - ) + successors(it.next().map(|direction| (next((0, 0), direction))), |c| { + it.next().map(|direction| (next(*c, direction))) + }) + .enumerate() .for_each(|c| { - wire.insert(c); + wire.insert(Coord(c.0 + 1, c.1)); }); wire } -fn distance(position: (i32, i32)) -> i32 { - position.0.abs() + position.1.abs() -} - -fn closest(input: String) -> Option { - let entries: Vec> = input +fn closest(input: &str) -> Option { + let entries: Vec> = input .trim() .split("\n") .map(|line| line.split(",").map(String::from).collect()) @@ -54,32 +64,49 @@ fn closest(input: String) -> Option { entries[0] .intersection(&entries[1]) .cloned() - .map(distance) + .map(|c| (c.1).0.abs() + (c.1).1.abs()) .min() } -fn first(input: String) -> Option {} +fn first(input: &str) -> Option { + let entries: Vec> = input + .trim() + .split("\n") + .map(|line| line.split(",").map(String::from).collect()) + .map(to_coordinates) + .collect(); + + entries[0] + .intersection(&entries[1]) + .cloned() + .map(|c| { + let other = entries[1].get(&c); + (c.0 + other.unwrap().0) as i32 + }) + .min() +} pub fn main() -> io::Result<()> { - let closest = closest(std::include_str!("../day3-input.txt").to_owned()); - println!("{:?}", closest); + let input = std::include_str!("../day3-input.txt"); + println!("{:?}", closest(input)); + println!("{:?}", first(input)); Ok(()) } #[test] fn test_coordinates_for_entry() { - let mut expected: BTreeSet<(i32, i32)> = BTreeSet::new(); + let mut expected: BTreeSet = BTreeSet::new(); for i in 1..11 { - expected.insert((i, 0)); + expected.insert(Coord(i - 1, (i as i32, 0))); } assert_eq!(to_coordinates(vec!["R10".to_owned()]), expected); expected = BTreeSet::new(); - expected.insert((1, 0)); - expected.insert((2, 0)); - expected.insert((2, 1)); - expected.insert((2, 2)); + expected.insert(Coord(0, (1, 0))); + expected.insert(Coord(1, (2, 0))); + expected.insert(Coord(2, (2, 1))); + expected.insert(Coord(3, (2, 2))); let input = "R2,U2".to_owned().split(",").map(String::from).collect(); assert_eq!(to_coordinates(input), expected); } @@ -87,11 +114,19 @@ fn test_coordinates_for_entry() { #[test] fn test_part_one() { let input = "R75,D30,R83,U83,L12,D49,R71,U7,L72\n\ - U62,R66,U55,R34,D71,R55,D58,R83" - .to_owned(); + U62,R66,U55,R34,D71,R55,D58,R83"; assert_eq!(closest(input), Some(159)); let input = "R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51\n\ - U98,R91,D20,R16,D67,R40,U7,R15,U6,R7" - .to_owned(); + U98,R91,D20,R16,D67,R40,U7,R15,U6,R7"; assert_eq!(closest(input), Some(135)); } + +#[test] +fn test_part_two() { + let input = "R75,D30,R83,U83,L12,D49,R71,U7,L72\n\ + U62,R66,U55,R34,D71,R55,D58,R83"; + assert_eq!(first(input), Some(610)); + let input = "R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51\n\ + U98,R91,D20,R16,D67,R40,U7,R15,U6,R7"; + assert_eq!(first(input), Some(464)); +} From 89f79dab93a48c2588ac262903c7faceb37c5cb1 Mon Sep 17 00:00:00 2001 From: Vladan Popovic Date: Sun, 15 Dec 2019 23:29:27 +0100 Subject: [PATCH 03/12] Use numbers in module names for better sorting --- src/{day_one.rs => day1.rs} | 0 src/{day_two.rs => day2.rs} | 0 src/{day_three.rs => day3.rs} | 0 src/main.rs | 14 +++++++------- 4 files changed, 7 insertions(+), 7 deletions(-) rename src/{day_one.rs => day1.rs} (100%) rename src/{day_two.rs => day2.rs} (100%) rename src/{day_three.rs => day3.rs} (100%) diff --git a/src/day_one.rs b/src/day1.rs similarity index 100% rename from src/day_one.rs rename to src/day1.rs diff --git a/src/day_two.rs b/src/day2.rs similarity index 100% rename from src/day_two.rs rename to src/day2.rs diff --git a/src/day_three.rs b/src/day3.rs similarity index 100% rename from src/day_three.rs rename to src/day3.rs diff --git a/src/main.rs b/src/main.rs index 68bcf50..535adac 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ -mod day_one; -mod day_three; -mod day_two; +mod day1; +mod day2; +mod day3; use std::fs::File; use std::io::{self, BufRead, BufReader}; @@ -11,12 +11,12 @@ fn main() -> io::Result<()> { .lines() .map(|line| line.unwrap().parse().unwrap()) .collect(); - day_one::main(masses); + day1::main(masses); - day_two::part_one(); - day_two::part_two(); + day2::part_one(); + day2::part_two(); - day_three::main()?; + day3::main()?; Ok(()) } From d2198c80469ed6734995f22e5e6f2068aab22377 Mon Sep 17 00:00:00 2001 From: Vladan Popovic Date: Mon, 16 Dec 2019 01:50:28 +0100 Subject: [PATCH 04/12] Day 4 complete part 1 and 2 --- src/day4.rs | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 3 +++ 2 files changed, 67 insertions(+) create mode 100644 src/day4.rs diff --git a/src/day4.rs b/src/day4.rs new file mode 100644 index 0000000..cbac3e0 --- /dev/null +++ b/src/day4.rs @@ -0,0 +1,64 @@ +use std::io; + +fn part1(x: &u32) -> bool { + let matching = x + .to_string() + .chars() + .map(|c| c.to_digit(10).unwrap()) + .fold((true, false, 0), |acc, next| { + (acc.0 && next >= acc.2, acc.1 || next == acc.2, next) + }); + + matching.0 && matching.1 +} + +fn part2(x: &u32) -> bool { + let matching = x.to_string().chars().map(|c| c.to_digit(10).unwrap()).fold( + (true, false, 0, 0), + |acc, next| { + if next == acc.3 && acc.2 >= 2 { + (acc.0 && next >= acc.3, acc.1, acc.2 + 1, next) + } else if next != acc.3 && acc.2 == 2 { + (acc.0 && next >= acc.3, true, 1, next) + } else if next == acc.3 && acc.2 < 2 { + (acc.0 && next >= acc.3, acc.1, acc.2 + 1, next) + } else { + (acc.0 && next >= acc.3, acc.1, 1, next) + } + }, + ); + matching.0 && (matching.1 || matching.2 == 2) +} + +pub fn main() -> io::Result<()> { + let input = "123257-647015"; + + let range: Vec = input + .split("-") + .map(|x| x.parse::().unwrap()) + .take(2) + .collect(); + + println!("part1 = {}", (range[0]..range[1]).filter(part1).count()); + println!("part2 = {}", (range[0]..range[1]).filter(part2).count()); + + Ok(()) +} + +#[test] +fn test_part1() { + assert!(part1(&111111)); + assert!(!part1(&223450)); + assert!(!part1(&123789)); +} + +#[test] +fn test_part2() { + assert!(!part2(&111111)); + assert!(!part2(&223450)); + assert!(!part2(&123789)); + assert!(part2(&112233)); + assert!(part2(&223334)); + assert!(!part2(&123444)); + assert!(part2(&111122)); +} diff --git a/src/main.rs b/src/main.rs index 535adac..45262c8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ mod day1; mod day2; mod day3; +mod day4; use std::fs::File; use std::io::{self, BufRead, BufReader}; @@ -18,5 +19,7 @@ fn main() -> io::Result<()> { day3::main()?; + day4::main()?; + Ok(()) } From d144372ea4340f9b8c0c8ab7a2f1ddaaecd19b3f Mon Sep 17 00:00:00 2001 From: Vladan Popovic Date: Tue, 24 Dec 2019 21:26:34 +0100 Subject: [PATCH 05/12] Day 5 part 1 and 2 --- src/day5.rs | 243 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100644 src/day5.rs diff --git a/src/day5.rs b/src/day5.rs new file mode 100644 index 0000000..aafbb03 --- /dev/null +++ b/src/day5.rs @@ -0,0 +1,243 @@ +use std; +use std::convert::TryInto; + +fn get_modes(x: i32) -> (i32, i32, i32, i32) { + ( + x as i32 % 100, + (x as i32 / 100) % 10, + (x as i32 / 1000) % 10, + x as i32 / 10000, + ) +} + +fn get_param(input: Vec, mode: i32, idx: usize) -> i32 { + match mode { + 0 => { + let new_idx: usize = input[idx as usize].try_into().unwrap(); + input[new_idx] + } + 1 => input[idx], + _ => panic!("invalid input"), + } +} + +fn set_param(input: &mut Vec, mode: i32, idx: i32, value: i32) -> () { + match mode { + 0 => { + let new_idx: usize = input[idx as usize].try_into().unwrap(); + input[new_idx] = value; + } + _ => { + panic!("invalid mode for output"); + } + } +} + +fn compute_intcode_extended(p: &mut Vec, input: i32) -> (Vec, Vec) { + let mut idx = 0; + let mut output: Vec = Vec::new(); + + while idx < p.len() - 1 { + let (opcode, m1, m2, m3) = get_modes(p[idx]); + match opcode { + 1 => { + let left = get_param(p.to_vec(), m1, idx + 1); + let right = get_param(p.to_vec(), m2, idx + 2); + let res = left + right; + set_param(p, m3, idx as i32 + 3, res); + idx += 4; + } + 2 => { + let left = get_param(p.to_vec(), m1, idx + 1); + let right = get_param(p.to_vec(), m2, idx + 2); + let res = left * right; + set_param(p, m3, idx as i32 + 3, res); + idx += 4; + } + 3 => { + let new_idx: usize = p[idx as usize + 1].try_into().unwrap(); + p[new_idx] = input; + idx += 2; + } + 4 => { + let value = get_param(p.to_vec(), m1, idx + 1); + output.push(value); + idx += 2; + } + 5 => { + let left = get_param(p.to_vec(), m1, idx + 1); + let right = get_param(p.to_vec(), m2, idx + 2); + if left != 0 { + idx = right as usize; + } else { + idx += 3; + } + } + 6 => { + let left = get_param(p.to_vec(), m1, idx + 1); + let right = get_param(p.to_vec(), m2, idx + 2); + if left == 0 { + idx = right as usize; + } else { + idx += 3; + } + } + 7 => { + let left = get_param(p.to_vec(), m1, idx + 1); + let right = get_param(p.to_vec(), m2, idx + 2); + set_param(p, m3, idx as i32 + 3, (left < right) as i32); + idx += 4; + } + 8 => { + let left = get_param(p.to_vec(), m1, idx + 1); + let right = get_param(p.to_vec(), m2, idx + 2); + set_param(p, m3, idx as i32 + 3, (left == right) as i32); + idx += 4; + } + 99 => { + break; + } + _ => panic!("invalid opcode: {}", opcode), + } + } + (p.to_vec(), output.to_vec()) +} + +pub fn main() -> std::io::Result<()> { + let input: Vec = std::include_str!("../day5-input.txt") + .trim() + .split(",") + .map(|x| x.parse().ok().expect(&format!("{} not a number", x))) + .collect(); + + let (_, output) = compute_intcode_extended(&mut input.clone(), 1); + println!("part 1 = {}", output.last().unwrap()); + + let (_, output) = compute_intcode_extended(&mut input.clone(), 5); + println!("part 2 = {}", output[0]); + Ok(()) +} + +#[test] +fn test_halt() { + let (result, _) = compute_intcode_extended(&mut vec![99], 1); + assert_eq!(result, vec![99]); +} + +#[test] +fn test_write_to_memory() { + let (result, _) = compute_intcode_extended(&mut vec![3, 3, 99, 0], 20); + assert_eq!(20, result[3]); +} + +#[test] +fn test_write_to_output() { + let (_, output) = compute_intcode_extended(&mut vec![4, 2, 99], 1); + assert_eq!(99, output[0]); +} + +#[test] +fn test_add() { + let (result, _) = compute_intcode_extended(&mut vec![1, 2, 2, 0, 99], 1); + assert_eq!(4, result[0]); +} + +#[test] +fn test_mul() { + let (result, _) = compute_intcode_extended(&mut vec![2, 2, 4, 0, 99], 1); + assert_eq!(396, result[0]); +} + +#[test] +fn test_immediate_mode() { + let (result, output) = compute_intcode_extended(&mut vec![1102, 2, 4, 0, 99], 1); + assert_eq!(8, result[0]); +} + +#[test] +fn test_position_mode_equal() { + let (result, output) = + compute_intcode_extended(&mut vec![3, 9, 8, 9, 10, 9, 4, 9, 99, -1, 8], 8); + assert_eq!(1, output[0]); +} + +#[test] +fn test_position_mode_not_equal() { + let (result, output) = + compute_intcode_extended(&mut vec![3, 9, 8, 9, 10, 9, 4, 9, 99, -1, 8], 10); + assert_eq!(0, output[0]); +} + +#[test] +fn test_position_mode_less_than() { + let (result, output) = + compute_intcode_extended(&mut vec![3, 9, 7, 9, 10, 9, 4, 9, 99, -1, 8], 3); + assert_eq!(1, output[0]); +} + +#[test] +fn test_position_mode_greater_than() { + let (result, output) = + compute_intcode_extended(&mut vec![3, 9, 7, 9, 10, 9, 4, 9, 99, -1, 8], 10); + assert_eq!(0, output[0]); +} + +#[test] +fn test_immediate_mode_equal() { + let (result, output) = compute_intcode_extended(&mut vec![3, 3, 1108, -1, 8, 3, 4, 3, 99], 8); + assert_eq!(1, output[0]); +} + +#[test] +fn test_immediate_mode_not_equal() { + let (result, output) = compute_intcode_extended(&mut vec![3, 3, 1108, -1, 8, 3, 4, 3, 99], 10); + assert_eq!(0, output[0]); +} + +#[test] +fn test_immediate_mode_less_than() { + let (result, output) = compute_intcode_extended(&mut vec![3, 3, 1107, -1, 8, 3, 4, 3, 99], 3); + assert_eq!(1, output[0]); +} + +#[test] +fn test_immediate_mode_greater_than() { + let (result, output) = compute_intcode_extended(&mut vec![3, 3, 1107, -1, 8, 3, 4, 3, 99], 10); + assert_eq!(0, output[0]); +} + +#[test] +fn test_position_jump_zero() { + let (result, output) = compute_intcode_extended( + &mut vec![3, 12, 6, 12, 15, 1, 13, 14, 13, 4, 13, 99, -1, 0, 1, 9], + 0, + ); + assert_eq!(0, output[0]); +} + +#[test] +fn test_position_jump_one() { + let (result, output) = compute_intcode_extended( + &mut vec![3, 12, 6, 12, 15, 1, 13, 14, 13, 4, 13, 99, -1, 0, 1, 9], + 100, + ); + assert_eq!(1, output[0]); +} + +#[test] +fn test_immediate_jump_zero() { + let (result, output) = compute_intcode_extended( + &mut vec![3, 3, 1105, -1, 9, 1101, 0, 0, 12, 4, 12, 99, 1], + 0, + ); + assert_eq!(0, output[0]); +} + +#[test] +fn test_immediate_jump_one() { + let (result, output) = compute_intcode_extended( + &mut vec![3, 3, 1105, -1, 9, 1101, 0, 0, 12, 4, 12, 99, 1], + 100, + ); + assert_eq!(1, output[0]); +} From 25f30c89fb0f34219e3ce0f5d724b6e74e22dabb Mon Sep 17 00:00:00 2001 From: Vladan Popovic Date: Tue, 24 Dec 2019 21:27:26 +0100 Subject: [PATCH 06/12] Hide dead code warnings (emacs env) --- .dir-locals.el | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .dir-locals.el diff --git a/.dir-locals.el b/.dir-locals.el new file mode 100644 index 0000000..f899e66 --- /dev/null +++ b/.dir-locals.el @@ -0,0 +1,3 @@ +(setenv "RUSTFLAGS" + (concat (getenv "RUSTFLAGS") + "-A dead_code")) From e067720cc8068a230a9484add8c88aadb9380ec9 Mon Sep 17 00:00:00 2001 From: Vladan Popovic Date: Tue, 24 Dec 2019 21:27:45 +0100 Subject: [PATCH 07/12] Move day1 specific code to module, hide all outputs --- src/day1.rs | 12 +++++++++++- src/main.rs | 31 ++++++++++++++++++------------- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/day1.rs b/src/day1.rs index bc1b05e..6204a5b 100644 --- a/src/day1.rs +++ b/src/day1.rs @@ -1,3 +1,6 @@ +use std::fs::File; +use std::io::{self, BufRead, BufReader}; + fn fuel_for(mass: u64) -> u64 { (mass / 3).saturating_sub(2) } @@ -8,9 +11,16 @@ fn total_fuel(mass: u64) -> u64 { .sum() } -pub fn main(masses: Vec) { +pub fn main() -> io::Result<()> { + let f = BufReader::new(File::open("day1-input.txt")?); + let masses: Vec = f + .lines() + .map(|line| line.unwrap().parse().unwrap()) + .collect(); let total: u64 = masses.into_iter().map(total_fuel).sum(); println!("Fuel needed for bringing Santa home is: {}", total); + + Ok(()) } #[test] diff --git a/src/main.rs b/src/main.rs index 45262c8..b6f489a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,25 +1,30 @@ +#[allow(dead_code)] mod day1; mod day2; mod day3; mod day4; +mod day5; +mod day6; -use std::fs::File; -use std::io::{self, BufRead, BufReader}; +fn main() -> std::io::Result<()> { + println!("========================= DAY 6"); + day6::main()?; -fn main() -> io::Result<()> { - let f = BufReader::new(File::open("day1-input.txt")?); - let masses: Vec = f - .lines() - .map(|line| line.unwrap().parse().unwrap()) - .collect(); - day1::main(masses); + //println!("========================= DAY 5"); + //day5::main()?; - day2::part_one(); - day2::part_two(); + //println!("========================= DAY 4"); + //day4::main()?; - day3::main()?; + //println!("========================= DAY 3"); + //day3::main()?; - day4::main()?; + //println!("========================= DAY 2"); + //day2::part_one(); + //day2::part_two(); + + //println!("========================= DAY 1"); + //day1::main()?; Ok(()) } From 933ff006d7f883881ad1dcfd5d3c07ac3eb144be Mon Sep 17 00:00:00 2001 From: Vladan Popovic Date: Wed, 25 Dec 2019 04:13:20 +0100 Subject: [PATCH 08/12] Day 6 part 1 and 2, very rudimentary --- src/day6.rs | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 src/day6.rs diff --git a/src/day6.rs b/src/day6.rs new file mode 100644 index 0000000..7f68117 --- /dev/null +++ b/src/day6.rs @@ -0,0 +1,160 @@ +use std::collections::BTreeSet; +use std::collections::HashMap; + +#[derive(Debug)] +struct OrbitMap { + ids: Vec, +} + +impl OrbitMap { + fn new(n: usize) -> Self { + Self { + ids: (0..n).collect::>(), + } + } + + fn orbit_around(&mut self, base: usize, orbiter: usize) { + self.ids[orbiter] = base; + //println!("{:?}", self.ids); + } + + fn range(&self, idx: usize) -> usize { + let mut i = idx; + let mut cnt = 0; + while i != self.ids[i] { + cnt += 1; + i = self.ids[i]; + } + cnt + } + + fn range_to(&self, idx: usize, limit: usize) -> usize { + let mut i = idx; + let mut cnt = 0; + while i != limit { + i = self.ids[i]; + cnt += 1; + } + cnt - 1 + } + + fn path(&self, idx: usize) -> BTreeSet { + let mut i = idx; + let mut res = BTreeSet::new(); + while i != self.ids[i] { + res.insert(i); + i = self.ids[i]; + } + res + } + + fn distance(&self, p: usize, q: usize) -> usize { + let ppath = self.path(p); + let qpath = self.path(q); + let common_roots = ppath.intersection(&qpath); + + common_roots + .map(|cr| self.range_to(p, *cr) + self.range_to(q, *cr)) + .min() + .unwrap() + } +} + +fn get_pairs(input: &str) -> Vec> { + input + .lines() + .map(|line| line.split(")").map(String::from).collect::>()) + .collect() +} + +fn get_space_objects(input: &str) -> HashMap { + let items = input + .lines() + .map(|line| line.split(")").map(String::from).collect::>()) + .flatten(); + + let mut space_objects: HashMap = HashMap::new(); + let mut n = 0; + items.for_each(|x| { + if !space_objects.contains_key(&x) { + space_objects.insert(x, n); + n += 1; + } + }); + //println!("{:?}", space_objects); + + space_objects +} + +fn calculate_map(input: &str) -> usize { + let space_objects = get_space_objects(input); + let pairs = get_pairs(input); + let mut orbit_map = OrbitMap::new(space_objects.len()); + + for pair in pairs { + //println!("{:?}", pair); + let base = space_objects.get(&pair[0]).unwrap(); + let orbiter = space_objects.get(&pair[1]).unwrap(); + orbit_map.orbit_around(*base, *orbiter); + } + //println!("{:?}", orbit_map.ids); + (0..orbit_map.ids.len()).map(|i| orbit_map.range(i)).sum() +} + +fn calculate_distance(input: &str) -> usize { + let space_objects = get_space_objects(input); + let pairs = get_pairs(input); + let mut orbit_map = OrbitMap::new(space_objects.len()); + + for pair in pairs { + //println!("{:?}", pair); + let base = space_objects.get(&pair[0]).unwrap(); + let orbiter = space_objects.get(&pair[1]).unwrap(); + orbit_map.orbit_around(*base, *orbiter); + } + //println!("{:?}", orbit_map.ids); + let me = *space_objects.get("YOU").unwrap(); + let santa = *space_objects.get("SAN").unwrap(); + orbit_map.distance(me, santa) +} + +pub fn main() -> std::io::Result<()> { + let input = std::include_str!("../day6-input.txt").trim(); + println!("part1 = {:?}", calculate_map(input)); + println!("part2 = {:?}", calculate_distance(input)); + Ok(()) +} + +#[test] +fn test_day6_part1() { + let input = "COM)B\n\ + B)C\n\ + C)D\n\ + D)E\n\ + E)F\n\ + B)G\n\ + G)H\n\ + D)I\n\ + E)J\n\ + J)K\n\ + K)L"; + assert_eq!(calculate_map(input), 42); +} + +#[test] +fn test_day6_part2() { + let input = "COM)B\n\ + B)C\n\ + C)D\n\ + D)E\n\ + E)F\n\ + B)G\n\ + G)H\n\ + D)I\n\ + E)J\n\ + J)K\n\ + K)L\n\ + K)YOU\n\ + I)SAN"; + assert_eq!(calculate_distance(input), 4); +} From 74cd67ddfc0a6a3f3d17f7b67367efcae2826ba0 Mon Sep 17 00:00:00 2001 From: Vladan Popovic Date: Sat, 28 Dec 2019 03:32:52 +0100 Subject: [PATCH 09/12] Simplified day6 :) --- src/day6.rs | 176 +++++++++++++--------------------------------------- 1 file changed, 42 insertions(+), 134 deletions(-) diff --git a/src/day6.rs b/src/day6.rs index 7f68117..30aec43 100644 --- a/src/day6.rs +++ b/src/day6.rs @@ -1,160 +1,68 @@ -use std::collections::BTreeSet; use std::collections::HashMap; +use std::iter::FromIterator; -#[derive(Debug)] -struct OrbitMap { - ids: Vec, -} - -impl OrbitMap { - fn new(n: usize) -> Self { - Self { - ids: (0..n).collect::>(), - } - } - - fn orbit_around(&mut self, base: usize, orbiter: usize) { - self.ids[orbiter] = base; - //println!("{:?}", self.ids); - } - - fn range(&self, idx: usize) -> usize { - let mut i = idx; - let mut cnt = 0; - while i != self.ids[i] { - cnt += 1; - i = self.ids[i]; - } - cnt - } - - fn range_to(&self, idx: usize, limit: usize) -> usize { - let mut i = idx; - let mut cnt = 0; - while i != limit { - i = self.ids[i]; - cnt += 1; - } - cnt - 1 - } - - fn path(&self, idx: usize) -> BTreeSet { - let mut i = idx; - let mut res = BTreeSet::new(); - while i != self.ids[i] { - res.insert(i); - i = self.ids[i]; - } - res - } - - fn distance(&self, p: usize, q: usize) -> usize { - let ppath = self.path(p); - let qpath = self.path(q); - let common_roots = ppath.intersection(&qpath); - - common_roots - .map(|cr| self.range_to(p, *cr) + self.range_to(q, *cr)) - .min() - .unwrap() - } -} - -fn get_pairs(input: &str) -> Vec> { +fn create_orbit_map(input: &str) -> HashMap { + let mut orbit_map: HashMap = HashMap::new(); input .lines() - .map(|line| line.split(")").map(String::from).collect::>()) - .collect() + .map(|line| line.split(")").map(String::from).collect()) + .for_each(|pair: Vec| { + orbit_map.entry(pair[1].clone()).or_insert(pair[0].clone()); + }); + orbit_map } -fn get_space_objects(input: &str) -> HashMap { - let items = input - .lines() - .map(|line| line.split(")").map(String::from).collect::>()) - .flatten(); +fn part1(input: &str) -> usize { + let orbit_map = create_orbit_map(input); - let mut space_objects: HashMap = HashMap::new(); - let mut n = 0; - items.for_each(|x| { - if !space_objects.contains_key(&x) { - space_objects.insert(x, n); - n += 1; + let mut cnt: usize = 0; + for obj in orbit_map.keys() { + let mut key = obj; + while let Some(val) = orbit_map.get(key) { + cnt += 1; + key = val; } - }); - //println!("{:?}", space_objects); - - space_objects + } + cnt } -fn calculate_map(input: &str) -> usize { - let space_objects = get_space_objects(input); - let pairs = get_pairs(input); - let mut orbit_map = OrbitMap::new(space_objects.len()); +fn part2(input: &str) -> usize { + let orbit_map = create_orbit_map(input); - for pair in pairs { - //println!("{:?}", pair); - let base = space_objects.get(&pair[0]).unwrap(); - let orbiter = space_objects.get(&pair[1]).unwrap(); - orbit_map.orbit_around(*base, *orbiter); + let my_traj: HashMap = HashMap::from_iter( + std::iter::successors(orbit_map.get("YOU").map(|el| (el, 0)), |(nxt, n)| { + (orbit_map.get(*nxt).map(|el| (el, n + 1 as usize))) + }) + .map(|(el, n)| (String::from(el), n)), + ); + + let mut santa_transfers = 0; + let mut santa = orbit_map.get("SAN").unwrap(); + loop { + if my_traj.contains_key(santa) { + return my_traj.get(santa).unwrap() + santa_transfers; + } else { + santa = orbit_map.get(santa).expect("no common orbits found"); + santa_transfers += 1; + } } - //println!("{:?}", orbit_map.ids); - (0..orbit_map.ids.len()).map(|i| orbit_map.range(i)).sum() -} - -fn calculate_distance(input: &str) -> usize { - let space_objects = get_space_objects(input); - let pairs = get_pairs(input); - let mut orbit_map = OrbitMap::new(space_objects.len()); - - for pair in pairs { - //println!("{:?}", pair); - let base = space_objects.get(&pair[0]).unwrap(); - let orbiter = space_objects.get(&pair[1]).unwrap(); - orbit_map.orbit_around(*base, *orbiter); - } - //println!("{:?}", orbit_map.ids); - let me = *space_objects.get("YOU").unwrap(); - let santa = *space_objects.get("SAN").unwrap(); - orbit_map.distance(me, santa) } pub fn main() -> std::io::Result<()> { let input = std::include_str!("../day6-input.txt").trim(); - println!("part1 = {:?}", calculate_map(input)); - println!("part2 = {:?}", calculate_distance(input)); + println!("part1 = {:?}", part1(input)); + println!("part2 = {:?}", part2(input)); Ok(()) } #[test] fn test_day6_part1() { - let input = "COM)B\n\ - B)C\n\ - C)D\n\ - D)E\n\ - E)F\n\ - B)G\n\ - G)H\n\ - D)I\n\ - E)J\n\ - J)K\n\ - K)L"; - assert_eq!(calculate_map(input), 42); + let input = "COM)B\nB)C\nC)D\nD)E\nE)F\nB)G\nG)H\nD)I\nE)J\nJ)K\nK)L"; + assert_eq!(part1(input), 42); } #[test] fn test_day6_part2() { - let input = "COM)B\n\ - B)C\n\ - C)D\n\ - D)E\n\ - E)F\n\ - B)G\n\ - G)H\n\ - D)I\n\ - E)J\n\ - J)K\n\ - K)L\n\ - K)YOU\n\ - I)SAN"; - assert_eq!(calculate_distance(input), 4); + let input = "COM)B\nB)C\nC)D\nD)E\nE)F\nB)G\nG)H\nD)I\nE)J\nJ)K\nK)L\nK)YOU\nI)SAN"; + assert_eq!(part2(input), 4); } From 39235ce0cfac7b7831ca69b02835c0c857238378 Mon Sep 17 00:00:00 2001 From: Vladan Popovic Date: Tue, 14 Jan 2020 15:29:40 +0100 Subject: [PATCH 10/12] Remove redundant into_iter and collect --- src/day1.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/day1.rs b/src/day1.rs index 6204a5b..b7e8600 100644 --- a/src/day1.rs +++ b/src/day1.rs @@ -13,11 +13,11 @@ fn total_fuel(mass: u64) -> u64 { pub fn main() -> io::Result<()> { let f = BufReader::new(File::open("day1-input.txt")?); - let masses: Vec = f + let total: u64 = f .lines() .map(|line| line.unwrap().parse().unwrap()) - .collect(); - let total: u64 = masses.into_iter().map(total_fuel).sum(); + .map(total_fuel) + .sum(); println!("Fuel needed for bringing Santa home is: {}", total); Ok(()) From 4d60fb3e2343da1e4a9f78b8bddc554c86fd06a9 Mon Sep 17 00:00:00 2001 From: Vladan Popovic Date: Tue, 14 Jan 2020 15:31:14 +0100 Subject: [PATCH 11/12] Day 7 --- src/day5.rs | 61 +++++++++++------------ src/day7.rs | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 8 ++- 3 files changed, 176 insertions(+), 32 deletions(-) create mode 100644 src/day7.rs diff --git a/src/day5.rs b/src/day5.rs index aafbb03..2506f72 100644 --- a/src/day5.rs +++ b/src/day5.rs @@ -33,9 +33,10 @@ fn set_param(input: &mut Vec, mode: i32, idx: i32, value: i32) -> () { } } -fn compute_intcode_extended(p: &mut Vec, input: i32) -> (Vec, Vec) { +pub fn compute_intcode_extended(p: &mut Vec, inp: Vec) -> (Vec, Vec) { let mut idx = 0; let mut output: Vec = Vec::new(); + let mut input = inp.into_iter(); while idx < p.len() - 1 { let (opcode, m1, m2, m3) = get_modes(p[idx]); @@ -56,7 +57,7 @@ fn compute_intcode_extended(p: &mut Vec, input: i32) -> (Vec, Vec } 3 => { let new_idx: usize = p[idx as usize + 1].try_into().unwrap(); - p[new_idx] = input; + p[new_idx] = input.next().expect("no next input!"); idx += 2; } 4 => { @@ -110,134 +111,134 @@ pub fn main() -> std::io::Result<()> { .map(|x| x.parse().ok().expect(&format!("{} not a number", x))) .collect(); - let (_, output) = compute_intcode_extended(&mut input.clone(), 1); + let (_, output) = compute_intcode_extended(&mut input.clone(), vec![1]); println!("part 1 = {}", output.last().unwrap()); - let (_, output) = compute_intcode_extended(&mut input.clone(), 5); + let (_, output) = compute_intcode_extended(&mut input.clone(), vec![5]); println!("part 2 = {}", output[0]); Ok(()) } #[test] fn test_halt() { - let (result, _) = compute_intcode_extended(&mut vec![99], 1); + let (result, _) = compute_intcode_extended(&mut vec![99], vec![1]); assert_eq!(result, vec![99]); } #[test] fn test_write_to_memory() { - let (result, _) = compute_intcode_extended(&mut vec![3, 3, 99, 0], 20); + let (result, _) = compute_intcode_extended(&mut vec![3, 3, 99, 0], vec![20]); assert_eq!(20, result[3]); } #[test] fn test_write_to_output() { - let (_, output) = compute_intcode_extended(&mut vec![4, 2, 99], 1); + let (_, output) = compute_intcode_extended(&mut vec![4, 2, 99], vec![1]); assert_eq!(99, output[0]); } #[test] fn test_add() { - let (result, _) = compute_intcode_extended(&mut vec![1, 2, 2, 0, 99], 1); + let (result, _) = compute_intcode_extended(&mut vec![1, 2, 2, 0, 99], vec![1]); assert_eq!(4, result[0]); } #[test] fn test_mul() { - let (result, _) = compute_intcode_extended(&mut vec![2, 2, 4, 0, 99], 1); + let (result, _) = compute_intcode_extended(&mut vec![2, 2, 4, 0, 99], vec![1]); assert_eq!(396, result[0]); } #[test] fn test_immediate_mode() { - let (result, output) = compute_intcode_extended(&mut vec![1102, 2, 4, 0, 99], 1); + let (result, _) = compute_intcode_extended(&mut vec![1102, 2, 4, 0, 99], vec![1]); assert_eq!(8, result[0]); } #[test] fn test_position_mode_equal() { - let (result, output) = - compute_intcode_extended(&mut vec![3, 9, 8, 9, 10, 9, 4, 9, 99, -1, 8], 8); + let (_, output) = + compute_intcode_extended(&mut vec![3, 9, 8, 9, 10, 9, 4, 9, 99, -1, 8], vec![8]); assert_eq!(1, output[0]); } #[test] fn test_position_mode_not_equal() { - let (result, output) = - compute_intcode_extended(&mut vec![3, 9, 8, 9, 10, 9, 4, 9, 99, -1, 8], 10); + let (_, output) = + compute_intcode_extended(&mut vec![3, 9, 8, 9, 10, 9, 4, 9, 99, -1, 8], vec![10]); assert_eq!(0, output[0]); } #[test] fn test_position_mode_less_than() { - let (result, output) = - compute_intcode_extended(&mut vec![3, 9, 7, 9, 10, 9, 4, 9, 99, -1, 8], 3); + let (_, output) = + compute_intcode_extended(&mut vec![3, 9, 7, 9, 10, 9, 4, 9, 99, -1, 8], vec![3]); assert_eq!(1, output[0]); } #[test] fn test_position_mode_greater_than() { - let (result, output) = - compute_intcode_extended(&mut vec![3, 9, 7, 9, 10, 9, 4, 9, 99, -1, 8], 10); + let (_, output) = + compute_intcode_extended(&mut vec![3, 9, 7, 9, 10, 9, 4, 9, 99, -1, 8], vec![10]); assert_eq!(0, output[0]); } #[test] fn test_immediate_mode_equal() { - let (result, output) = compute_intcode_extended(&mut vec![3, 3, 1108, -1, 8, 3, 4, 3, 99], 8); + let (_, output) = compute_intcode_extended(&mut vec![3, 3, 1108, -1, 8, 3, 4, 3, 99], vec![8]); assert_eq!(1, output[0]); } #[test] fn test_immediate_mode_not_equal() { - let (result, output) = compute_intcode_extended(&mut vec![3, 3, 1108, -1, 8, 3, 4, 3, 99], 10); + let (_, output) = compute_intcode_extended(&mut vec![3, 3, 1108, -1, 8, 3, 4, 3, 99], vec![10]); assert_eq!(0, output[0]); } #[test] fn test_immediate_mode_less_than() { - let (result, output) = compute_intcode_extended(&mut vec![3, 3, 1107, -1, 8, 3, 4, 3, 99], 3); + let (_, output) = compute_intcode_extended(&mut vec![3, 3, 1107, -1, 8, 3, 4, 3, 99], vec![3]); assert_eq!(1, output[0]); } #[test] fn test_immediate_mode_greater_than() { - let (result, output) = compute_intcode_extended(&mut vec![3, 3, 1107, -1, 8, 3, 4, 3, 99], 10); + let (_, output) = compute_intcode_extended(&mut vec![3, 3, 1107, -1, 8, 3, 4, 3, 99], vec![10]); assert_eq!(0, output[0]); } #[test] fn test_position_jump_zero() { - let (result, output) = compute_intcode_extended( + let (_, output) = compute_intcode_extended( &mut vec![3, 12, 6, 12, 15, 1, 13, 14, 13, 4, 13, 99, -1, 0, 1, 9], - 0, + vec![0], ); assert_eq!(0, output[0]); } #[test] fn test_position_jump_one() { - let (result, output) = compute_intcode_extended( + let (_, output) = compute_intcode_extended( &mut vec![3, 12, 6, 12, 15, 1, 13, 14, 13, 4, 13, 99, -1, 0, 1, 9], - 100, + vec![100], ); assert_eq!(1, output[0]); } #[test] fn test_immediate_jump_zero() { - let (result, output) = compute_intcode_extended( + let (_, output) = compute_intcode_extended( &mut vec![3, 3, 1105, -1, 9, 1101, 0, 0, 12, 4, 12, 99, 1], - 0, + vec![0], ); assert_eq!(0, output[0]); } #[test] fn test_immediate_jump_one() { - let (result, output) = compute_intcode_extended( + let (_, output) = compute_intcode_extended( &mut vec![3, 3, 1105, -1, 9, 1101, 0, 0, 12, 4, 12, 99, 1], - 100, + vec![100], ); assert_eq!(1, output[0]); } diff --git a/src/day7.rs b/src/day7.rs new file mode 100644 index 0000000..c4dc5af --- /dev/null +++ b/src/day7.rs @@ -0,0 +1,139 @@ +use crate::day5::compute_intcode_extended; + +pub fn permutations(start: usize, size: usize) -> Permutations { + Permutations { + idxs: (start..size).collect(), + swaps: vec![start; size], + i: 0, + } +} + +pub struct Permutations { + idxs: Vec, + swaps: Vec, + i: usize, +} + +impl Iterator for Permutations { + type Item = Vec; + + fn next(&mut self) -> Option { + if self.i > 0 { + loop { + if self.i >= self.swaps.len() { + return None; + } + if self.swaps[self.i] < self.i { + break; + } + self.swaps[self.i] = 0; + self.i += 1; + } + self.idxs.swap(self.i, (self.i & 1) * self.swaps[self.i]); + self.swaps[self.i] += 1; + } + self.i = 1; + Some(self.idxs.clone()) + } +} + +fn compute_thruster(input: &mut Vec, settings: Vec) -> i32 { + let mut signal = 0; + for phase in settings { + signal = compute_intcode_extended(input, vec![phase as i32, signal]).1[0]; + } + signal +} + +fn part1() -> i32 { + let input: Vec = std::include_str!("../day7-input.txt") + .trim() + .split(",") + .map(|x| x.parse().ok().expect(&format!("{} not a number", x))) + .collect(); + + let mut max_thruster = std::i32::MIN; + for settings in permutations(0, 5).collect::>() { + let thrust = compute_thruster(&mut input.clone(), settings); + max_thruster = max_thruster.max(thrust); + } + max_thruster +} + +fn compute_feedback(input: &mut Vec, mut settings: Vec) -> Vec { + settings.push(0); + println!("{:?}", settings); + let signal = compute_intcode_extended(input, settings).1; + println!("{:?}", signal); + signal +} + +fn part2() -> i32 { + let mut input: Vec = std::include_str!("../day7-input.txt") + .trim() + .split(",") + .map(|x| x.parse().ok().expect(&format!("{} not a number", x))) + .collect(); + + let mut max_thruster = std::i32::MIN; + for settings in permutations(5, 5).collect::>() { + let thrust = compute_thruster(&mut input, settings); + max_thruster = max_thruster.max(thrust); + } + max_thruster +} + +pub fn main() { + println!("part1 = {}", part1()); + println!("part2 = {}", part2()); +} + +#[test] +fn test_compute_thruster_1() { + let mut input = vec![ + 3, 15, 3, 16, 1002, 16, 10, 16, 1, 16, 15, 15, 4, 15, 99, 0, 0, + ]; + let settings = vec![4, 3, 2, 1, 0]; + assert_eq!(compute_thruster(&mut input, settings), 43210); +} + +#[test] +fn test_compute_thruster_2() { + let mut input = vec![ + 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, + ]; + let settings = vec![0, 1, 2, 3, 4]; + assert_eq!(compute_thruster(&mut input, settings), 54321); +} + +#[test] +fn test_compute_thruster_3() { + let mut input = vec![ + 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, + ]; + let settings = vec![1, 0, 4, 3, 2]; + assert_eq!(compute_thruster(&mut input, settings), 65210); +} + +#[test] +fn test_compute_feedback_1() { + let mut input = vec![ + 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, + ]; + let settings = vec![5, 6, 7, 8, 9]; + assert_eq!(compute_feedback(&mut input, settings), [139629729]); +} + +#[test] +fn test_compute_feedback_2() { + let mut input = vec![ + 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, + ]; + let settings = vec![9, 7, 8, 5, 6]; + assert_eq!(compute_feedback(&mut input, settings), [18216]); +} diff --git a/src/main.rs b/src/main.rs index b6f489a..b98a548 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,10 +5,14 @@ mod day3; mod day4; mod day5; mod day6; +mod day7; fn main() -> std::io::Result<()> { - println!("========================= DAY 6"); - day6::main()?; + println!("========================= DAY 7"); + day7::main(); + + //println!("========================= DAY 6"); + //day6::main()?; //println!("========================= DAY 5"); //day5::main()?; From cc904a4ea1eb96ebedea334887b064635a565a0f Mon Sep 17 00:00:00 2001 From: Vladan Popovic Date: Wed, 15 Jan 2020 23:57:01 +0100 Subject: [PATCH 12/12] Remove to_vec from day2 More refactoring soon. --- src/day2.rs | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/day2.rs b/src/day2.rs index 8a102c6..b9bdde5 100644 --- a/src/day2.rs +++ b/src/day2.rs @@ -1,6 +1,6 @@ use std; -fn compute_intcode(p: &mut Vec) -> Vec { +fn compute_intcode(p: &mut Vec) { for idx in (0..(p.len())).step_by(4) { match p[idx] { 1 => { @@ -16,10 +16,9 @@ fn compute_intcode(p: &mut Vec) -> Vec { p[res] = p[left] * p[right]; } 99 => break, - _ => panic!("Something went wrong!"), + _ => panic!("invalid opcode"), } } - p.to_vec() } pub fn part_one() { @@ -32,7 +31,9 @@ pub fn part_one() { input[1] = 12; input[2] = 2; - println!("Intcode [0] is: {}", compute_intcode(&mut input)[0]); + compute_intcode(&mut input); + + println!("Intcode [0] is: {}", input[0]); } pub fn part_two() { @@ -52,8 +53,8 @@ pub fn part_two() { input[1] = i; for j in 0..99 { input[2] = j; - let mut input_guess = input.clone(); - let computed = compute_intcode(&mut input_guess); + let mut computed = input.clone(); + compute_intcode(&mut computed); found = computed[0] == lookup_num; @@ -76,20 +77,19 @@ pub fn part_two() { #[test] fn test_part_one() { - assert_eq!( - compute_intcode(&mut vec!(1, 0, 0, 0, 99)), - vec!(2, 0, 0, 0, 99) - ); - assert_eq!( - compute_intcode(&mut vec!(2, 3, 0, 3, 99)), - vec!(2, 3, 0, 6, 99) - ); - assert_eq!( - compute_intcode(&mut vec!(2, 4, 4, 5, 99, 0)), - vec!(2, 4, 4, 5, 99, 9801) - ); - assert_eq!( - compute_intcode(&mut vec!(1, 1, 1, 4, 99, 5, 6, 0, 99)), - vec!(30, 1, 1, 4, 2, 5, 6, 0, 99) - ); + let mut intcode = vec![1, 0, 0, 0, 99]; + compute_intcode(&mut intcode); + assert_eq!(intcode, vec!(2, 0, 0, 0, 99)); + + let mut intcode = vec![2, 3, 0, 3, 99]; + compute_intcode(&mut intcode); + assert_eq!(intcode, vec!(2, 3, 0, 6, 99)); + + let mut intcode = vec![2, 4, 4, 5, 99, 0]; + compute_intcode(&mut intcode); + assert_eq!(intcode, vec!(2, 4, 4, 5, 99, 9801)); + + let mut intcode = vec![1, 1, 1, 4, 99, 5, 6, 0, 99]; + compute_intcode(&mut intcode); + assert_eq!(intcode, vec!(30, 1, 1, 4, 2, 5, 6, 0, 99)); }