From 24fb5e0204a4d69286473b660fd64a8d4a254eaf Mon Sep 17 00:00:00 2001 From: Justin Worthe Date: Mon, 25 Dec 2017 07:45:07 +0200 Subject: Day 25: The Turing machine --- inputs/day_25.txt | 62 ++++++++++++++++++++++++++++ src/bin/day_25.rs | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 181 insertions(+) create mode 100644 inputs/day_25.txt 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) -> 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, re: &Regex) -> char { + re.captures( + lines.next().unwrap() + ).unwrap()[1].chars().next().unwrap() } + +fn parse_number(lines: &mut Iter, re: &Regex) -> u32 { + re.captures( + lines.next().unwrap() + ).unwrap()[1].parse().unwrap() +} +fn parse_direction(lines: &mut Iter, re: &Regex) -> i32 { + if re.captures( + lines.next().unwrap() + ).unwrap()[1] == *"left" { + -1 + } else { + 1 + } +} + +fn parse_bool(lines: &mut Iter, re: &Regex) -> bool { + re.captures( + lines.next().unwrap() + ).unwrap()[1] == *"1" +} + +fn parse_instruction(lines: &mut Iter, 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 +} + +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 +} + + -- cgit v1.2.3