Skip to content

Commit

Permalink
Year 2019 Day 2
Browse files Browse the repository at this point in the history
  • Loading branch information
maneatingape committed Aug 30, 2023
1 parent f177178 commit bc058ce
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ pie
| Day | Problem | Solution | Benchmark (μs) |
| --- | --- | --- | --: |
| 1 | [The Tyranny of the Rocket Equation](https://adventofcode.com/2019/day/1) | [Source](src/year2019/day01.rs) | 1 |
| 2 | [1202 Program Alarm](https://adventofcode.com/2019/day/2) | [Source](src/year2019/day02.rs) | 1 |

## 2015

Expand Down
1 change: 1 addition & 0 deletions benches/benchmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ mod year2020 {

mod year2019 {
benchmark!(year2019, day01);
benchmark!(year2019, day02);
}

mod year2015 {
Expand Down
1 change: 1 addition & 0 deletions input/year2019/day02.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1,0,0,3,1,1,2,3,1,3,4,3,1,5,0,3,2,10,1,19,1,6,19,23,1,23,13,27,2,6,27,31,1,5,31,35,2,10,35,39,1,6,39,43,1,13,43,47,2,47,6,51,1,51,5,55,1,55,6,59,2,59,10,63,1,63,6,67,2,67,10,71,1,71,9,75,2,75,10,79,1,79,5,83,2,10,83,87,1,87,6,91,2,9,91,95,1,95,5,99,1,5,99,103,1,103,10,107,1,9,107,111,1,6,111,115,1,115,5,119,1,10,119,123,2,6,123,127,2,127,6,131,1,131,2,135,1,10,135,0,99,2,0,14,0
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ pub mod year2020 {
/// # Rescue Santa from deep space with a solar system adventure.
pub mod year2019 {
pub mod day01;
pub mod day02;
}

/// # Help Santa by solving puzzles to fix the weather machine's snow function.
Expand Down
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ fn all_solutions() -> Vec<Solution> {
solution!(year2020, day25),
// 2019
solution!(year2019, day01),
solution!(year2019, day02),
// 2015
solution!(year2015, day01),
solution!(year2015, day02),
Expand Down
71 changes: 71 additions & 0 deletions src/year2019/day02.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
//! # 1202 Program Alarm
//!
//! Substituting symbols instead of numbers into the program shows that it calculates the value of
//!
//! `a * noun + b * verb + c`
//!
//! We can isolate the value of the constants a, b, c in order to speed up subsequent calculations.
//!
//! As the equation is monotonically increasing in both noun and verb, we can efficiently solve
//! part two by binary searching in two dimensions, instead of a slow brute force check of all
//! possible 10,000 combinations.
use crate::util::parse::*;
use std::cmp::Ordering::*;

type Input = [i32; 3];

pub fn parse(input: &str) -> Input {
let code: Vec<_> = input.iter_unsigned().collect();

let c = check(&code, 0, 0) as i32;
let a = check(&code, 1, 0) as i32;
let b = check(&code, 0, 1) as i32;

[a - c, b - c, c]
}

pub fn part1([a, b, c]: &Input) -> i32 {
a * 12 + b * 2 + c
}

pub fn part2(input: &Input) -> i32 {
search(input, 0, 99, 0, 99).unwrap()
}

fn check(input: &[usize], first: usize, second: usize) -> usize {
let code = &mut input.to_vec();
code[1] = first;
code[2] = second;

execute(code)
}

fn execute(code: &mut [usize]) -> usize {
let mut pc = 0;

loop {
match code[pc] {
1 => code[code[pc + 3]] = code[code[pc + 1]] + code[code[pc + 2]],
2 => code[code[pc + 3]] = code[code[pc + 1]] * code[code[pc + 2]],
_ => break code[0],
}
pc += 4;
}
}

fn search(input: &Input, x1: i32, x2: i32, y1: i32, y2: i32) -> Option<i32> {
if x1 > x2 || y1 > y2 {
return None;
}

let x = (x1 + x2) / 2;
let y = (y1 + y2) / 2;
let [a, b, c] = input;
let result = a * x + b * y + c;

match result.cmp(&19690720) {
Equal => Some(100 * x + y),
Less => search(input, x + 1, x2, y1, y2).or_else(|| search(input, x1, x2, y + 1, y2)),
Greater => search(input, x1, x - 1, y1, y2).or_else(|| search(input, x1, x2, y1, y - 1)),
}
}
1 change: 1 addition & 0 deletions tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ mod year2020 {

mod year2019 {
mod day01_test;
mod day02_test;
}

mod year2015 {
Expand Down
40 changes: 40 additions & 0 deletions tests/year2019/day02_test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use aoc::year2019::day02::*;

const EXAMPLE: &str = "\
1, 0, 0, 0,
2, 32, 0, 0,
2, 33, 1, 1,
2, 34, 2, 2,
1, 35, 0, 0,
1, 1, 0, 0,
1, 2, 0, 0,
99, 0, 0, 0,
0, 1000000, 10000, 7350720,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0";

#[test]
fn part1_test() {
let input = parse(EXAMPLE);
assert_eq!(part1(&input), 19370720);
}

#[test]
fn part2_test() {
let input = parse(EXAMPLE);
assert_eq!(part2(&input), 1234);
}

0 comments on commit bc058ce

Please sign in to comment.