summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Worthe <justin@worthe-it.co.za>2017-12-25 07:45:07 +0200
committerJustin Worthe <justin@worthe-it.co.za>2017-12-25 07:45:07 +0200
commit24fb5e0204a4d69286473b660fd64a8d4a254eaf (patch)
treef05ffc3c09ebc9da7602ed66f78877148ca74d1b
parent25d33a1bb819f749c421e76bb36e694fa2830162 (diff)
Day 25: The Turing machine
-rw-r--r--inputs/day_25.txt62
-rw-r--r--src/bin/day_25.rs119
2 files changed, 181 insertions, 0 deletions
diff --git a/inputs/day_25.txt b/inputs/day_25.txt
new file mode 100644
index 0000000..892ee98
--- /dev/null
+++ b/inputs/day_25.txt
@@ -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.
diff --git a/src/bin/day_25.rs b/src/bin/day_25.rs
index 1fc3eca..8d7b0da 100644
--- a/src/bin/day_25.rs
+++ b/src/bin/day_25.rs
@@ -1,6 +1,125 @@
extern crate advent_of_code_2017;
use advent_of_code_2017::*;
+extern crate regex;
+use regex::Regex;
+
+use std::slice::Iter;
+use std::collections::HashSet;
+
fn main() {
let args = AdventArgs::init();
+ let program = parse(&args.input);
+
+ let mut position: i32 = 0;
+ let mut state = program.state(program.start).expect("Started out of program bounds");
+ let mut tape = HashSet::new();
+
+ for _ in 0..program.iterations {
+ let instruction = if tape.contains(&position) {
+ &state.if1
+ } else {
+ &state.if0
+ };
+ if instruction.write {
+ tape.insert(position);
+ } else {
+ tape.remove(&position);
+ }
+ position += instruction.offset;
+ state = program.state(instruction.next).expect("Redirected to unknown state");
+ }
+
+ println!("{}", tape.len());
+}
+
+fn parse(input: &Vec<String>) -> Program {
+ let state_re = Regex::new(r"state (\w)").unwrap();
+ let iterations_re = Regex::new(r"(\d+) steps").unwrap();
+ let write_re = Regex::new(r"Write the value (\d)").unwrap();
+ let move_re = Regex::new(r"Move one slot to the (\w+)").unwrap();
+
+ let mut lines = input.iter();
+ let start = parse_char(&mut lines, &state_re);
+ let iterations = parse_number(&mut lines, &iterations_re);
+
+ let mut states = Vec::new();
+ while let Some(heading) = lines.next() {
+ states.push(State {
+ id: state_re.captures(heading).unwrap()[1].chars().next().unwrap(),
+ if0: parse_instruction(&mut lines, &write_re, &move_re, &state_re),
+ if1: parse_instruction(&mut lines, &write_re, &move_re, &state_re)
+ });
+ }
+
+ Program {
+ start: start,
+ iterations: iterations,
+ states: states
+ }
+}
+
+fn parse_char(lines: &mut Iter<String>, re: &Regex) -> char {
+ re.captures(
+ lines.next().unwrap()
+ ).unwrap()[1].chars().next().unwrap()
}
+
+fn parse_number(lines: &mut Iter<String>, re: &Regex) -> u32 {
+ re.captures(
+ lines.next().unwrap()
+ ).unwrap()[1].parse().unwrap()
+}
+fn parse_direction(lines: &mut Iter<String>, re: &Regex) -> i32 {
+ if re.captures(
+ lines.next().unwrap()
+ ).unwrap()[1] == *"left" {
+ -1
+ } else {
+ 1
+ }
+}
+
+fn parse_bool(lines: &mut Iter<String>, re: &Regex) -> bool {
+ re.captures(
+ lines.next().unwrap()
+ ).unwrap()[1] == *"1"
+}
+
+fn parse_instruction(lines: &mut Iter<String>, write_re: &Regex, offset_re: &Regex, next_re: &Regex) -> Instruction {
+ lines.next();
+ Instruction {
+ write: parse_bool(lines, &write_re),
+ offset: parse_direction(lines, &offset_re),
+ next: parse_char(lines, &next_re)
+ }
+}
+
+#[derive(Debug)]
+struct Program {
+ start: char,
+ iterations: u32,
+ states: Vec<State>
+}
+
+impl Program {
+ fn state(&self, i: char) -> Option<&State> {
+ self.states.iter().find(|s| s.id == i)
+ }
+}
+
+#[derive(Debug)]
+struct State {
+ id: char,
+ if0: Instruction,
+ if1: Instruction
+}
+
+#[derive(Debug)]
+struct Instruction {
+ write: bool,
+ offset: i32,
+ next: char
+}
+
+