Skip to content

Commit c80fdb8

Browse files
committedSep 22, 2023
Year 2019 Day 19
1 parent 6f7dd2c commit c80fdb8

File tree

8 files changed

+112
-0
lines changed

8 files changed

+112
-0
lines changed
 

‎README.md

+1
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ pie
211211
| 16 | [Flawed Frequency Transmission](https://adventofcode.com/2019/day/16) | [Source](src/year2019/day16.rs) | 4124 |
212212
| 17 | [Set and Forget](https://adventofcode.com/2019/day/17) | [Source](src/year2019/day17.rs) | 425 |
213213
| 18 | [Many-Worlds Interpretation](https://adventofcode.com/2019/day/18) | [Source](src/year2019/day18.rs) | 1077 |
214+
| 19 | [Tractor Beam](https://adventofcode.com/2019/day/19) | [Source](src/year2019/day19.rs) | 817 |
214215

215216
## 2015
216217

‎benches/benchmark.rs

+1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ mod year2019 {
6767
benchmark!(year2019, day16);
6868
benchmark!(year2019, day17);
6969
benchmark!(year2019, day18);
70+
benchmark!(year2019, day19);
7071
}
7172

7273
mod year2020 {

‎input/year2019/day19.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
109,424,203,1,21102,11,1,0,1105,1,282,21102,1,18,0,1105,1,259,1201,1,0,221,203,1,21101,0,31,0,1105,1,282,21102,38,1,0,1106,0,259,21001,23,0,2,22101,0,1,3,21101,0,1,1,21102,1,57,0,1105,1,303,2101,0,1,222,21001,221,0,3,20102,1,221,2,21102,259,1,1,21101,80,0,0,1106,0,225,21101,0,111,2,21102,1,91,0,1105,1,303,2102,1,1,223,20101,0,222,4,21102,1,259,3,21102,1,225,2,21102,1,225,1,21101,0,118,0,1105,1,225,20101,0,222,3,21102,148,1,2,21102,1,133,0,1106,0,303,21202,1,-1,1,22001,223,1,1,21102,148,1,0,1106,0,259,2101,0,1,223,20102,1,221,4,21001,222,0,3,21101,0,17,2,1001,132,-2,224,1002,224,2,224,1001,224,3,224,1002,132,-1,132,1,224,132,224,21001,224,1,1,21101,0,195,0,106,0,109,20207,1,223,2,20102,1,23,1,21102,-1,1,3,21101,0,214,0,1105,1,303,22101,1,1,1,204,1,99,0,0,0,0,109,5,2102,1,-4,249,22101,0,-3,1,21202,-2,1,2,21202,-1,1,3,21102,1,250,0,1105,1,225,22102,1,1,-4,109,-5,2106,0,0,109,3,22107,0,-2,-1,21202,-1,2,-1,21201,-1,-1,-1,22202,-1,-2,-2,109,-3,2105,1,0,109,3,21207,-2,0,-1,1206,-1,294,104,0,99,22102,1,-2,-2,109,-3,2106,0,0,109,5,22207,-3,-4,-1,1206,-1,346,22201,-4,-3,-4,21202,-3,-1,-1,22201,-4,-1,2,21202,2,-1,-1,22201,-4,-1,1,21202,-2,1,3,21101,0,343,0,1105,1,303,1105,1,415,22207,-2,-3,-1,1206,-1,387,22201,-3,-2,-3,21202,-2,-1,-1,22201,-3,-1,3,21202,3,-1,-1,22201,-3,-1,2,21201,-4,0,1,21102,384,1,0,1106,0,303,1105,1,415,21202,-4,-1,-4,22201,-4,-3,-4,22202,-3,-2,-2,22202,-2,-4,-4,22202,-3,-2,-3,21202,-4,-1,-2,22201,-3,-2,1,21202,1,1,-4,109,-5,2106,0,0

‎src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ pub mod year2019 {
192192
pub mod day16;
193193
pub mod day17;
194194
pub mod day18;
195+
pub mod day19;
195196
pub mod intcode;
196197
}
197198

‎src/main.rs

+1
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ fn all_solutions() -> Vec<Solution> {
105105
solution!(year2019, day16),
106106
solution!(year2019, day17),
107107
solution!(year2019, day18),
108+
solution!(year2019, day19),
108109
// 2020
109110
solution!(year2020, day01),
110111
solution!(year2020, day02),

‎src/year2019/day19.rs

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
//! # Tractor Beam
2+
//!
3+
//! Finds the approximate boundary of the upper and lower edges of the beam expressed as a slope.
4+
//! We then skip the relatively expensive intcode test if the x and y coordinates lie outside.
5+
use super::intcode::*;
6+
use crate::util::parse::*;
7+
8+
pub struct Input {
9+
code: Vec<i64>,
10+
lower: i64,
11+
upper: i64,
12+
}
13+
14+
pub fn parse(input: &str) -> Input {
15+
let code: Vec<_> = input.iter_signed().collect();
16+
let mut lower = 0;
17+
let mut upper = 0;
18+
19+
// Find slope of lower and upper edges, rounding down to prevent false negatives.
20+
while !test(&code, lower + 1, 50) {
21+
lower += 1;
22+
}
23+
while !test(&code, 50, upper + 1) {
24+
upper += 1;
25+
}
26+
27+
Input { code, lower, upper }
28+
}
29+
30+
pub fn part1(input: &Input) -> i64 {
31+
let code = &input.code;
32+
// Handle origin specially
33+
let mut result = test(code, 0, 0) as i64;
34+
35+
// The beam is continuous so we only need to find the left and right edges.
36+
for y in 0..50 {
37+
let mut left = i64::MAX;
38+
let mut right = i64::MIN;
39+
40+
for x in 0..50 {
41+
if precheck(input, x, y) && test(code, x, y) {
42+
left = x;
43+
break;
44+
}
45+
}
46+
for x in (0..50).rev() {
47+
if precheck(input, x, y) && test(code, x, y) {
48+
right = x;
49+
break;
50+
}
51+
}
52+
if left <= right {
53+
result += right - left + 1;
54+
}
55+
}
56+
57+
result
58+
}
59+
60+
pub fn part2(input: &Input) -> i64 {
61+
let code = &input.code;
62+
let mut x = 0;
63+
let mut y = 0;
64+
let mut moved = true;
65+
66+
// Increase the right and bottom edges of our box until they are both inside the beam.
67+
while moved {
68+
moved = false;
69+
70+
while !precheck(input, x, y + 99) || !test(code, x, y + 99) {
71+
x += 1;
72+
moved = true;
73+
}
74+
75+
while !precheck(input, x + 99, y) || !test(code, x + 99, y) {
76+
y += 1;
77+
moved = true;
78+
}
79+
}
80+
81+
10000 * x + y
82+
}
83+
84+
/// Quick check with some false positives but no false negatives.
85+
fn precheck(input: &Input, x: i64, y: i64) -> bool {
86+
50 * y > input.upper * x && 50 * x > input.lower * y
87+
}
88+
89+
/// Definitive but slower check.
90+
fn test(code: &[i64], x: i64, y: i64) -> bool {
91+
let mut computer = Computer::new(code);
92+
computer.input(x);
93+
computer.input(y);
94+
95+
let State::Output(result) = computer.run() else { unreachable!() };
96+
result == 1
97+
}

‎tests/test.rs

+1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ mod year2019 {
6060
mod day16_test;
6161
mod day17_test;
6262
mod day18_test;
63+
mod day19_test;
6364
}
6465

6566
mod year2020 {

‎tests/year2019/day19_test.rs

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#[test]
2+
fn part1_test() {
3+
// No example data
4+
}
5+
6+
#[test]
7+
fn part2_test() {
8+
// No example data
9+
}

0 commit comments

Comments
 (0)