Skip to content

Commit dcfcdd6

Browse files
2016: Day 25
1 parent e866789 commit dcfcdd6

File tree

4 files changed

+176
-0
lines changed

4 files changed

+176
-0
lines changed

2016/day25/.vscode/settings.json

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"[rust]": {
3+
"editor.defaultFormatter": "rust-lang.rust-analyzer",
4+
"editor.formatOnSave": true
5+
},
6+
"rust-analyzer.check.command": "clippy"
7+
}

2016/day25/Cargo.lock

+7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

2016/day25/Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[package]
2+
name = "day23"
3+
version = "0.1.0"
4+
edition = "2021"

2016/day25/src/main.rs

+158
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
use std::fs;
2+
3+
#[derive(PartialEq, Eq, Debug)]
4+
enum Instruction {
5+
Cpy,
6+
Inc,
7+
Dec,
8+
Jnz,
9+
Tgl,
10+
Out,
11+
}
12+
13+
enum Param {
14+
Reg(usize),
15+
Num(i32),
16+
}
17+
18+
fn main() {
19+
let input = fs::read_to_string("input.txt").expect("Could not read file");
20+
21+
let mut instructions = input
22+
.lines()
23+
.map(|l| {
24+
let mut parts = l.split(' ');
25+
let i = match parts.next().unwrap() {
26+
"cpy" => Instruction::Cpy,
27+
"inc" => Instruction::Inc,
28+
"dec" => Instruction::Dec,
29+
"jnz" => Instruction::Jnz,
30+
"tgl" => Instruction::Tgl,
31+
"out" => Instruction::Out,
32+
_ => unreachable!(),
33+
};
34+
let params = parts
35+
.map(|p| {
36+
if let Ok(n) = p.parse::<i32>() {
37+
Param::Num(n)
38+
} else {
39+
Param::Reg((p.as_bytes()[0] - b'a') as usize)
40+
}
41+
})
42+
.collect::<Vec<_>>();
43+
(i, params)
44+
})
45+
.collect::<Vec<_>>();
46+
47+
// we assume 10000 is enough to check if the sequence is infinite
48+
let max_steps = 10000;
49+
50+
for i in 0..i32::MAX {
51+
let mut registers = vec![0i32; 26];
52+
53+
registers[0] = i;
54+
55+
let mut pointer = 0;
56+
let mut steps = 0;
57+
let mut current = 1i32;
58+
while steps < max_steps && pointer < instructions.len() {
59+
let (i, params) = &instructions[pointer];
60+
match i {
61+
Instruction::Cpy => {
62+
let v = match params[0] {
63+
Param::Num(n) => n,
64+
Param::Reg(r) => registers[r],
65+
};
66+
if let Param::Reg(r) = params[1] {
67+
registers[r] = v;
68+
}
69+
}
70+
Instruction::Inc => {
71+
let Param::Reg(r) = params[0] else { unreachable!() };
72+
registers[r] += 1;
73+
}
74+
Instruction::Dec => {
75+
let Param::Reg(r) = params[0] else { unreachable!() };
76+
registers[r] -= 1;
77+
}
78+
Instruction::Jnz => {
79+
let v = match params[0] {
80+
Param::Num(n) => n,
81+
Param::Reg(r) => registers[r],
82+
};
83+
if v != 0 {
84+
let d = match params[1] {
85+
Param::Num(n) => n,
86+
Param::Reg(r) => registers[r],
87+
};
88+
if d == -2
89+
&& pointer > 1
90+
&& instructions[pointer - 2].0 == Instruction::Inc
91+
&& instructions[pointer - 1].0 == Instruction::Dec
92+
{
93+
let Param::Reg(r2) = instructions[pointer - 2].1[0] else { unreachable!() };
94+
let Param::Reg(r1) = instructions[pointer - 1].1[0] else { unreachable!() };
95+
registers[r2] += v;
96+
registers[r1] -= v;
97+
pointer += 1;
98+
} else if d == -2
99+
&& pointer > 1
100+
&& instructions[pointer - 2].0 == Instruction::Dec
101+
&& instructions[pointer - 1].0 == Instruction::Inc
102+
{
103+
let Param::Reg(r2) = instructions[pointer - 2].1[0] else { unreachable!() };
104+
let Param::Reg(r1) = instructions[pointer - 1].1[0] else { unreachable!() };
105+
registers[r2] -= v;
106+
registers[r1] += v;
107+
pointer += 1;
108+
} else {
109+
pointer = (pointer as i32 + d) as usize;
110+
}
111+
continue;
112+
}
113+
}
114+
Instruction::Tgl => {
115+
let v = match params[0] {
116+
Param::Num(n) => n,
117+
Param::Reg(r) => registers[r],
118+
};
119+
let j = (pointer as i32 + v) as usize;
120+
if j < instructions.len() {
121+
let target_instr = &instructions[j].0;
122+
let target_params = &instructions[j].1;
123+
if target_params.len() == 1 {
124+
if *target_instr == Instruction::Inc {
125+
instructions[j].0 = Instruction::Dec;
126+
} else {
127+
instructions[j].0 = Instruction::Inc;
128+
}
129+
} else if *target_instr == Instruction::Jnz {
130+
instructions[j].0 = Instruction::Cpy;
131+
} else {
132+
instructions[j].0 = Instruction::Jnz;
133+
}
134+
}
135+
}
136+
Instruction::Out => {
137+
let v = match params[0] {
138+
Param::Num(n) => n,
139+
Param::Reg(r) => registers[r],
140+
};
141+
if (current == 0 && v == 1) || (current == 1 && v == 0) {
142+
current = v;
143+
steps += 1;
144+
} else {
145+
break;
146+
}
147+
}
148+
}
149+
150+
pointer += 1;
151+
}
152+
153+
if steps == max_steps {
154+
println!("{}", i);
155+
break;
156+
}
157+
}
158+
}

0 commit comments

Comments
 (0)