-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy path17.rs
More file actions
122 lines (109 loc) · 7.79 KB
/
17.rs
File metadata and controls
122 lines (109 loc) · 7.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
use std::time::Instant;
use itertools::Itertools;
use intcoder::{IntCoder, ExitCode};
const PROGRAM: [i64; 1439] = [2,330,331,332,109,3546,1101,1182,0,15,1101,1439,0,24,1002,0,1,570,1006,570,36,1001,571,0,0,1001,570,-1,570,1001,24,1,24,1106,0,18,1008,571,0,571,1001,15,1,15,1008,15,1439,570,1006,570,14,21101,0,58,0,1105,1,786,1006,332,62,99,21102,1,333,1,21102,73,1,0,1106,0,579,1101,0,0,572,1101,0,0,573,3,574,101,1,573,573,1007,574,65,570,1005,570,151,107,67,574,570,1005,570,151,1001,574,-64,574,1002,574,-1,574,1001,572,1,572,1007,572,11,570,1006,570,165,101,1182,572,127,1001,574,0,0,3,574,101,1,573,573,1008,574,10,570,1005,570,189,1008,574,44,570,1006,570,158,1105,1,81,21102,340,1,1,1105,1,177,21101,0,477,1,1106,0,177,21102,514,1,1,21101,0,176,0,1105,1,579,99,21101,184,0,0,1106,0,579,4,574,104,10,99,1007,573,22,570,1006,570,165,102,1,572,1182,21102,375,1,1,21101,0,211,0,1106,0,579,21101,1182,11,1,21101,0,222,0,1106,0,979,21101,0,388,1,21102,233,1,0,1105,1,579,21101,1182,22,1,21101,244,0,0,1105,1,979,21102,1,401,1,21101,0,255,0,1106,0,579,21101,1182,33,1,21102,266,1,0,1106,0,979,21102,414,1,1,21102,1,277,0,1105,1,579,3,575,1008,575,89,570,1008,575,121,575,1,575,570,575,3,574,1008,574,10,570,1006,570,291,104,10,21101,0,1182,1,21102,1,313,0,1106,0,622,1005,575,327,1101,1,0,575,21101,327,0,0,1106,0,786,4,438,99,0,1,1,6,77,97,105,110,58,10,33,10,69,120,112,101,99,116,101,100,32,102,117,110,99,116,105,111,110,32,110,97,109,101,32,98,117,116,32,103,111,116,58,32,0,12,70,117,110,99,116,105,111,110,32,65,58,10,12,70,117,110,99,116,105,111,110,32,66,58,10,12,70,117,110,99,116,105,111,110,32,67,58,10,23,67,111,110,116,105,110,117,111,117,115,32,118,105,100,101,111,32,102,101,101,100,63,10,0,37,10,69,120,112,101,99,116,101,100,32,82,44,32,76,44,32,111,114,32,100,105,115,116,97,110,99,101,32,98,117,116,32,103,111,116,58,32,36,10,69,120,112,101,99,116,101,100,32,99,111,109,109,97,32,111,114,32,110,101,119,108,105,110,101,32,98,117,116,32,103,111,116,58,32,43,10,68,101,102,105,110,105,116,105,111,110,115,32,109,97,121,32,98,101,32,97,116,32,109,111,115,116,32,50,48,32,99,104,97,114,97,99,116,101,114,115,33,10,94,62,118,60,0,1,0,-1,-1,0,1,0,0,0,0,0,0,1,22,42,0,109,4,1201,-3,0,587,20101,0,0,-1,22101,1,-3,-3,21102,1,0,-2,2208,-2,-1,570,1005,570,617,2201,-3,-2,609,4,0,21201,-2,1,-2,1105,1,597,109,-4,2106,0,0,109,5,2101,0,-4,629,21002,0,1,-2,22101,1,-4,-4,21101,0,0,-3,2208,-3,-2,570,1005,570,781,2201,-4,-3,652,21002,0,1,-1,1208,-1,-4,570,1005,570,709,1208,-1,-5,570,1005,570,734,1207,-1,0,570,1005,570,759,1206,-1,774,1001,578,562,684,1,0,576,576,1001,578,566,692,1,0,577,577,21102,1,702,0,1105,1,786,21201,-1,-1,-1,1105,1,676,1001,578,1,578,1008,578,4,570,1006,570,724,1001,578,-4,578,21102,731,1,0,1106,0,786,1105,1,774,1001,578,-1,578,1008,578,-1,570,1006,570,749,1001,578,4,578,21101,756,0,0,1105,1,786,1105,1,774,21202,-1,-11,1,22101,1182,1,1,21102,1,774,0,1106,0,622,21201,-3,1,-3,1105,1,640,109,-5,2106,0,0,109,7,1005,575,802,21002,576,1,-6,21002,577,1,-5,1106,0,814,21102,1,0,-1,21101,0,0,-5,21102,0,1,-6,20208,-6,576,-2,208,-5,577,570,22002,570,-2,-2,21202,-5,49,-3,22201,-6,-3,-3,22101,1439,-3,-3,1201,-3,0,843,1005,0,863,21202,-2,42,-4,22101,46,-4,-4,1206,-2,924,21101,0,1,-1,1105,1,924,1205,-2,873,21102,1,35,-4,1105,1,924,2102,1,-3,878,1008,0,1,570,1006,570,916,1001,374,1,374,2102,1,-3,895,1102,2,1,0,1201,-3,0,902,1001,438,0,438,2202,-6,-5,570,1,570,374,570,1,570,438,438,1001,578,558,921,21001,0,0,-4,1006,575,959,204,-4,22101,1,-6,-6,1208,-6,49,570,1006,570,814,104,10,22101,1,-5,-5,1208,-5,43,570,1006,570,810,104,10,1206,-1,974,99,1206,-1,974,1102,1,1,575,21101,0,973,0,1105,1,786,99,109,-7,2106,0,0,109,6,21101,0,0,-4,21102,0,1,-3,203,-2,22101,1,-3,-3,21208,-2,82,-1,1205,-1,1030,21208,-2,76,-1,1205,-1,1037,21207,-2,48,-1,1205,-1,1124,22107,57,-2,-1,1205,-1,1124,21201,-2,-48,-2,1106,0,1041,21102,1,-4,-2,1106,0,1041,21102,1,-5,-2,21201,-4,1,-4,21207,-4,11,-1,1206,-1,1138,2201,-5,-4,1059,1202,-2,1,0,203,-2,22101,1,-3,-3,21207,-2,48,-1,1205,-1,1107,22107,57,-2,-1,1205,-1,1107,21201,-2,-48,-2,2201,-5,-4,1090,20102,10,0,-1,22201,-2,-1,-2,2201,-5,-4,1103,2102,1,-2,0,1106,0,1060,21208,-2,10,-1,1205,-1,1162,21208,-2,44,-1,1206,-1,1131,1105,1,989,21102,1,439,1,1106,0,1150,21101,477,0,1,1106,0,1150,21101,0,514,1,21101,0,1149,0,1106,0,579,99,21101,1157,0,0,1105,1,579,204,-2,104,10,99,21207,-3,22,-1,1206,-1,1138,2102,1,-5,1176,2102,1,-4,0,109,-6,2105,1,0,26,5,44,1,3,1,44,1,3,1,44,1,3,1,44,1,3,1,44,1,3,1,44,7,46,1,1,1,44,11,38,1,1,1,1,1,5,1,28,13,1,1,5,1,28,1,9,1,3,1,5,1,28,1,9,7,3,1,28,1,13,1,1,1,3,1,28,1,13,1,1,1,3,1,28,1,13,1,1,1,3,1,16,13,13,1,1,1,3,1,16,1,25,1,1,1,3,1,10,11,21,7,10,1,5,1,3,1,23,1,14,1,5,1,3,1,23,1,3,7,4,1,5,1,3,1,23,1,3,1,5,1,4,7,3,1,23,1,3,1,5,1,14,1,23,1,3,1,5,1,14,1,23,11,14,1,27,1,20,1,27,1,3,7,10,1,27,1,3,1,5,1,10,1,25,5,1,1,5,1,10,1,25,1,1,1,1,1,1,1,5,1,10,7,19,1,1,11,16,1,19,1,3,1,1,1,22,1,13,13,22,1,13,1,5,1,3,1,24,1,13,1,5,1,3,1,24,1,13,1,9,1,24,1,13,1,9,1,24,1,13,1,9,1,24,1,13,11,24,1,48,1,48,1,48,7,26];
const H: usize = 43;
const W: usize = 49;
type Map = [[char; W]; H];
fn turn(dir: char, turn: char) -> char {
match dir {
'U' => if turn == 'L' {'L'} else {'R'}
'D' => if turn == 'L' {'R'} else {'L'}
'L' => if turn == 'L' {'D'} else {'U'}
'R' => if turn == 'L' {'U'} else {'D'}
_ => unreachable!()
}
}
fn scaffold_at(map: &Map, x:i64, y:i64) -> bool {
let (x,y) = (x as usize, y as usize);
(0..W).contains(&x) &&
(0..H).contains(&y) &&
map[y][x] == '#'
}
fn get_instructions(map: &Map) -> String {
let mut instructions = String::new();
let (mut x, mut y) = (22,42);
let mut dir = 'U';
loop {
let ( (dx,dy), (tx,ty) ) = match dir {
'U' => ( ( 0,-1), (-1, 0) ),
'D' => ( ( 0, 1), ( 1, 0) ),
'L' => ( (-1, 0), ( 0, 1) ),
'R' => ( ( 1, 0), ( 0,-1) ),
_ => unreachable!()
};
let mut dist = 0;
while scaffold_at(&map, x+dx, y+dy) {
x += dx;
y += dy;
dist += 1;
}
instructions += &dist.to_string();
let mut turn_dir = None;
if scaffold_at(&map, x+tx, y+ty) { turn_dir = Some('L'); }
if scaffold_at(&map, x-tx, y-ty) { turn_dir = Some('R'); }
match turn_dir {
Some(c) => {
dir = turn(dir, c);
instructions.push(c);
}
None => break,
}
}
instructions[1..].to_string()
}
fn fetch_print_map(cpu: &mut IntCoder) -> Map {
let mut map = [[' '; W]; H];
for i in 0..H {
for j in 0..W {
let o = cpu.execute_until_output();
map[i][j] = (o as u8) as char;
print!("{}", map[i][j]);
}
cpu.execute_until_output();
println!();
}
map
}
fn part_one(map: &Map) -> usize {
(1..(H-1)).cartesian_product(1..(W-1))
.filter(|&(i,j)|
map[i ][j ] == '#' &&
map[i-1][j ] == '#' &&
map[i+1][j ] == '#' &&
map[i ][j-1] == '#' &&
map[i ][j+1] == '#'
)
.map(|(i,j)| i*j)
.sum()
}
fn part_two(cpu: &mut IntCoder) -> i64 {
// Total instructions needed calculated via the 'get_instructions' function gives:
// L6R12L6R12L10L4L6L6R12L6R12L10L4L6L6R12L6L10L10L4L6R12L10L4L6L10L10L4L6L6R12L6L10L10L4L6
//
// Then we need to find three substrings that together can make the string above.
// We can easily do this by hand and find the following:
cpu.push_str("A,B,A,B,A,C,B,C,A,C");
cpu.push_str("L,6,R,12,L,6");
cpu.push_str("R,12,L,10,L,4,L,6");
cpu.push_str("L,10,L,10,L,4,L,6");
cpu.push_str("n");
let mut part_two = 0;
loop {
match cpu.execute() {
ExitCode::Output(o) => part_two = o,
ExitCode::Halted => break,
ExitCode::AwaitInput => unreachable!(),
}
}
part_two
}
fn main() {
let now = Instant::now();
let mut cpu = IntCoder::new(&PROGRAM);
let map = fetch_print_map(&mut cpu);
println!("Instructions needed:\n{}", get_instructions(&map));
println!("Part one: {}", part_one(&map));
println!("Part two: {}", part_two(&mut cpu));
println!("Time: {}ms", now.elapsed().as_millis());
}