Solutions for 2022, as well as 2015-2018 and 2019 up to day 11
This commit is contained in:
commit
1895197c49
722 changed files with 375457 additions and 0 deletions
8
2017/day25-the_halting_problem/Cargo.toml
Normal file
8
2017/day25-the_halting_problem/Cargo.toml
Normal file
|
@ -0,0 +1,8 @@
|
|||
[package]
|
||||
name = "day25-the_halting_problem"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
99
2017/day25-the_halting_problem/challenge.txt
Normal file
99
2017/day25-the_halting_problem/challenge.txt
Normal file
|
@ -0,0 +1,99 @@
|
|||
\--- Day 25: The Halting Problem ---
|
||||
----------
|
||||
|
||||
Following the twisty passageways deeper and deeper into the CPU, you finally reach the core of the computer. Here, in the expansive central chamber, you find a grand apparatus that fills the entire room, suspended nanometers above your head.
|
||||
|
||||
You had always imagined CPUs to be noisy, chaotic places, bustling with activity. Instead, the room is quiet, motionless, and dark.
|
||||
|
||||
Suddenly, you and the CPU's *garbage collector* startle each other. "It's not often we get many visitors here!", he says. You inquire about the stopped machinery.
|
||||
|
||||
"It stopped milliseconds ago; not sure why. I'm a garbage collector, not a doctor." You ask what the machine is for.
|
||||
|
||||
"Programs these days, don't know their origins. That's the *Turing machine*! It's what makes the whole computer work." You try to explain that Turing machines are merely models of computation, but he cuts you off. "No, see, that's just what they *want* you to think. Ultimately, inside every CPU, there's a Turing machine driving the whole thing! Too bad this one's broken. [We're doomed!](https://www.youtube.com/watch?v=cTwZZz0HV8I)"
|
||||
|
||||
You ask how you can help. "Well, unfortunately, the only way to get the computer running again would be to create a whole new Turing machine from scratch, but there's no *way* you can-" He notices the look on your face, gives you a curious glance, shrugs, and goes back to sweeping the floor.
|
||||
|
||||
You find the *Turing machine blueprints* (your puzzle input) on a tablet in a nearby pile of debris. Looking back up at the broken Turing machine above, you can start to identify its parts:
|
||||
|
||||
* A *tape* which contains `0` repeated infinitely to the left and right.
|
||||
* A *cursor*, which can move left or right along the tape and read or write values at its current position.
|
||||
* A set of *states*, each containing rules about what to do based on the current value under the cursor.
|
||||
|
||||
Each slot on the tape has two possible values: `0` (the starting value for all slots) and `1`. Based on whether the cursor is pointing at a `0` or a `1`, the current state says *what value to write* at the current position of the cursor, whether to *move the cursor* left or right one slot, and *which state to use next*.
|
||||
|
||||
For example, suppose you found the following blueprint:
|
||||
|
||||
```
|
||||
Begin in state A.
|
||||
Perform a diagnostic checksum after 6 steps.
|
||||
|
||||
In state A:
|
||||
If the current value is 0:
|
||||
- Write the value 1.
|
||||
- Move one slot to the right.
|
||||
- Continue with state B.
|
||||
If the current value is 1:
|
||||
- Write the value 0.
|
||||
- Move one slot to the left.
|
||||
- Continue with state B.
|
||||
|
||||
In state B:
|
||||
If the current value is 0:
|
||||
- Write the value 1.
|
||||
- Move one slot to the left.
|
||||
- Continue with state A.
|
||||
If the current value is 1:
|
||||
- Write the value 1.
|
||||
- Move one slot to the right.
|
||||
- Continue with state A.
|
||||
|
||||
```
|
||||
|
||||
Running it until the number of steps required to take the listed *diagnostic checksum* would result in the following tape configurations (with the *cursor* marked in square brackets):
|
||||
|
||||
```
|
||||
... 0 0 0 [0] 0 0 ... (before any steps; about to run state A)
|
||||
... 0 0 0 1 [0] 0 ... (after 1 step; about to run state B)
|
||||
... 0 0 0 [1] 1 0 ... (after 2 steps; about to run state A)
|
||||
... 0 0 [0] 0 1 0 ... (after 3 steps; about to run state B)
|
||||
... 0 [0] 1 0 1 0 ... (after 4 steps; about to run state A)
|
||||
... 0 1 [1] 0 1 0 ... (after 5 steps; about to run state B)
|
||||
... 0 1 1 [0] 1 0 ... (after 6 steps; about to run state A)
|
||||
|
||||
```
|
||||
|
||||
The CPU can confirm that the Turing machine is working by taking a *diagnostic checksum* after a specific number of steps (given in the blueprint). Once the specified number of steps have been executed, the Turing machine should pause; once it does, count the number of times `1` appears on the tape. In the above example, the *diagnostic checksum* is *`3`*.
|
||||
|
||||
Recreate the Turing machine and save the computer! *What is the diagnostic checksum* it produces once it's working again?
|
||||
|
||||
Your puzzle answer was `4769`.
|
||||
|
||||
\--- Part Two ---
|
||||
----------
|
||||
|
||||
The Turing machine, and soon the entire computer, springs back to life. A console glows dimly nearby, awaiting your command.
|
||||
|
||||
```
|
||||
> reboot printer
|
||||
Error: That command requires priority 50. You currently have priority 0.
|
||||
You must deposit 50 stars to increase your priority to the required level.
|
||||
|
||||
```
|
||||
|
||||
The console flickers for a moment, and then prints another message:
|
||||
|
||||
```
|
||||
Star accepted.
|
||||
You must deposit 49 stars to increase your priority to the required level.
|
||||
|
||||
```
|
||||
|
||||
The *garbage collector* winks at you, then continues sweeping.
|
||||
|
||||
If you like, you can .
|
||||
|
||||
Both parts of this puzzle are complete! They provide two gold stars: \*\*
|
||||
|
||||
At this point, all that is left is for you to [admire your Advent calendar](/2017).
|
||||
|
||||
If you still want to see it, you can [get your puzzle input](25/input).
|
132
2017/day25-the_halting_problem/src/lib.rs
Normal file
132
2017/day25-the_halting_problem/src/lib.rs
Normal file
|
@ -0,0 +1,132 @@
|
|||
use std::collections::HashSet;
|
||||
|
||||
struct State {
|
||||
write_0: bool,
|
||||
write_1: bool,
|
||||
move_0: isize,
|
||||
move_1: isize,
|
||||
next_0: usize,
|
||||
next_1: usize,
|
||||
}
|
||||
|
||||
impl From<&str> for State {
|
||||
fn from(value: &str) -> Self {
|
||||
let lines: Vec<_> = value.lines().collect();
|
||||
let write_0 = match lines[2].split_whitespace().nth(4) {
|
||||
Some("1.") => true,
|
||||
Some("0.") => false,
|
||||
v => panic!("Illegal value to write on 0: {v:?}"),
|
||||
};
|
||||
let move_0 = match lines[3].split_whitespace().nth(6) {
|
||||
Some("right.") => 1,
|
||||
Some("left.") => -1,
|
||||
v => panic!("Illegal direction to move on 0: {v:?}"),
|
||||
};
|
||||
let next_0 = match lines[4].split_whitespace().nth(4).unwrap().bytes().next() {
|
||||
Some(v) if (b'A'..=b'Z').contains(&v) => (v - b'A') as usize,
|
||||
e => panic!("Illegal state to continue on 0: {e:?}"),
|
||||
};
|
||||
let write_1 = match lines[6].split_whitespace().nth(4) {
|
||||
Some("1.") => true,
|
||||
Some("0.") => false,
|
||||
v => panic!("Illegal value to write on 1: {v:?}"),
|
||||
};
|
||||
let move_1 = match lines[7].split_whitespace().nth(6) {
|
||||
Some("right.") => 1,
|
||||
Some("left.") => -1,
|
||||
v => panic!("Illegal direction to write on 1: {v:?}"),
|
||||
};
|
||||
let next_1 = match lines[8].split_whitespace().nth(4).unwrap().bytes().next() {
|
||||
Some(v) if (b'A'..=b'Z').contains(&v) => (v - b'A') as usize,
|
||||
e => panic!("Illegal state to continue on 1: {e:?}"),
|
||||
};
|
||||
|
||||
Self {
|
||||
write_0,
|
||||
write_1,
|
||||
move_0,
|
||||
move_1,
|
||||
next_0,
|
||||
next_1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct Cpu {
|
||||
tape: HashSet<isize>,
|
||||
cursor: isize,
|
||||
state_machine: Vec<State>,
|
||||
state_ptr: usize,
|
||||
}
|
||||
|
||||
impl Cpu {
|
||||
fn run_for(&mut self, steps: usize) {
|
||||
for _ in 0..steps {
|
||||
self.step();
|
||||
}
|
||||
}
|
||||
|
||||
fn step(&mut self) {
|
||||
let current_state = &self.state_machine[self.state_ptr];
|
||||
match self.tape.contains(&self.cursor) {
|
||||
true => {
|
||||
if !current_state.write_1 {
|
||||
self.tape.remove(&self.cursor);
|
||||
}
|
||||
self.cursor += current_state.move_1;
|
||||
self.state_ptr = current_state.next_1;
|
||||
},
|
||||
false => {
|
||||
if current_state.write_0 {
|
||||
self.tape.insert(self.cursor);
|
||||
}
|
||||
self.cursor += current_state.move_0;
|
||||
self.state_ptr = current_state.next_0;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn checksum(&self) -> usize {
|
||||
self.tape.len()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run(input: &str) -> usize {
|
||||
let states: Vec<_> = input.split("\n\n").collect();
|
||||
let initial = states[0].split_once('\n').unwrap();
|
||||
let initial_state_str = initial.0.split_whitespace().nth(3).unwrap();
|
||||
let initial_state = (initial_state_str.bytes().next().unwrap() - b'A') as usize;
|
||||
let step_count = initial.1.split_whitespace().nth(5).unwrap().parse::<usize>().unwrap();
|
||||
|
||||
let state_machine: Vec<_> = states[1..].iter().map(|s| State::from(*s)).collect();
|
||||
let mut cpu = Cpu {
|
||||
state_machine,
|
||||
state_ptr: initial_state,
|
||||
..Default::default()
|
||||
};
|
||||
cpu.run_for(step_count);
|
||||
cpu.checksum()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::fs::read_to_string;
|
||||
|
||||
fn read_file(name: &str) -> String {
|
||||
read_to_string(name).expect(&format!("Unable to read file: {name}")[..]).trim().to_string()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sample() {
|
||||
let sample_input = read_file("tests/sample_input");
|
||||
assert_eq!(run(&sample_input), 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_challenge() {
|
||||
let challenge_input = read_file("tests/challenge_input");
|
||||
assert_eq!(run(&challenge_input), 4769);
|
||||
}
|
||||
}
|
62
2017/day25-the_halting_problem/tests/challenge_input
Normal file
62
2017/day25-the_halting_problem/tests/challenge_input
Normal file
|
@ -0,0 +1,62 @@
|
|||
Begin in state A.
|
||||
Perform a diagnostic checksum after 12667664 steps.
|
||||
|
||||
In state A:
|
||||
If the current value is 0:
|
||||
- Write the value 1.
|
||||
- Move one slot to the right.
|
||||
- Continue with state B.
|
||||
If the current value is 1:
|
||||
- Write the value 0.
|
||||
- Move one slot to the left.
|
||||
- Continue with state C.
|
||||
|
||||
In state B:
|
||||
If the current value is 0:
|
||||
- Write the value 1.
|
||||
- Move one slot to the left.
|
||||
- Continue with state A.
|
||||
If the current value is 1:
|
||||
- Write the value 1.
|
||||
- Move one slot to the right.
|
||||
- Continue with state D.
|
||||
|
||||
In state C:
|
||||
If the current value is 0:
|
||||
- Write the value 0.
|
||||
- Move one slot to the left.
|
||||
- Continue with state B.
|
||||
If the current value is 1:
|
||||
- Write the value 0.
|
||||
- Move one slot to the left.
|
||||
- Continue with state E.
|
||||
|
||||
In state D:
|
||||
If the current value is 0:
|
||||
- Write the value 1.
|
||||
- Move one slot to the right.
|
||||
- Continue with state A.
|
||||
If the current value is 1:
|
||||
- Write the value 0.
|
||||
- Move one slot to the right.
|
||||
- Continue with state B.
|
||||
|
||||
In state E:
|
||||
If the current value is 0:
|
||||
- Write the value 1.
|
||||
- Move one slot to the left.
|
||||
- Continue with state F.
|
||||
If the current value is 1:
|
||||
- Write the value 1.
|
||||
- Move one slot to the left.
|
||||
- Continue with state C.
|
||||
|
||||
In state F:
|
||||
If the current value is 0:
|
||||
- Write the value 1.
|
||||
- Move one slot to the right.
|
||||
- Continue with state D.
|
||||
If the current value is 1:
|
||||
- Write the value 1.
|
||||
- Move one slot to the right.
|
||||
- Continue with state A.
|
22
2017/day25-the_halting_problem/tests/sample_input
Normal file
22
2017/day25-the_halting_problem/tests/sample_input
Normal file
|
@ -0,0 +1,22 @@
|
|||
Begin in state A.
|
||||
Perform a diagnostic checksum after 6 steps.
|
||||
|
||||
In state A:
|
||||
If the current value is 0:
|
||||
- Write the value 1.
|
||||
- Move one slot to the right.
|
||||
- Continue with state B.
|
||||
If the current value is 1:
|
||||
- Write the value 0.
|
||||
- Move one slot to the left.
|
||||
- Continue with state B.
|
||||
|
||||
In state B:
|
||||
If the current value is 0:
|
||||
- Write the value 1.
|
||||
- Move one slot to the left.
|
||||
- Continue with state A.
|
||||
If the current value is 1:
|
||||
- Write the value 1.
|
||||
- Move one slot to the right.
|
||||
- Continue with state A.
|
Loading…
Add table
Add a link
Reference in a new issue