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
|
extern crate advent_of_code_2017;
use advent_of_code_2017::*;
extern crate regex;
use regex::Regex;
fn main() {
let args = AdventArgs::init();
let spin_re = Regex::new(r"s(\d+)").unwrap();
let exchange_re = Regex::new(r"x(\d+)/(\d+)").unwrap();
let partner_re = Regex::new(r"p(\w)/(\w)").unwrap();
let input: Vec<Instruction> = args.input[0]
.split(',')
.map(|instruction| {
if let Some(caps) = spin_re.captures(instruction) {
let spin_amount: usize = caps[1].parse().unwrap();
Instruction::Spin(spin_amount)
} else if let Some(caps) = exchange_re.captures(instruction) {
let position_a: usize = caps[1].parse().unwrap();
let position_b: usize = caps[2].parse().unwrap();
Instruction::Exchange(position_a, position_b)
} else if let Some(caps) = partner_re.captures(instruction) {
let program_a = caps[1].chars().next().unwrap();
let program_b = caps[2].chars().next().unwrap();
Instruction::Partner(program_a, program_b)
} else {
panic!("Unhandled instruction: {}", instruction)
}
})
.collect();
let mut states = vec!("abcdefghijklmnop".chars().collect());
if args.part == 1 {
let answer = run(&input, &states.last().unwrap());
println!("{}", answer.iter().collect::<String>());
} else {
let repetitions = 1_000_000_000;
let mut cycle_found = false;
let mut cycle_start = 0;
while !cycle_found {
let next = run(&input, &states.last().unwrap());
if let Some(i) = states.iter().position(|&ref x| *x == next) {
cycle_found = true;
cycle_start = i;
} else {
states.push(next);
}
}
println!("Cycle found after pushing {} states", states.len());
println!("Cycle starts at {} states", cycle_start);
let solution_index = (repetitions - cycle_start) % (states.len() - cycle_start);
println!("{}", states[solution_index].iter().collect::<String>());
}
}
enum Instruction {
Spin(usize),
Exchange(usize, usize),
Partner(char, char)
}
fn run(instructions: &[Instruction], start: &Vec<char>) -> Vec<char> {
let mut programs = start.clone();
for instruction in instructions {
match instruction {
&Instruction::Exchange(a, b) => {
programs.swap(a, b);
},
&Instruction::Spin(spin_amount) => {
for _ in 0..spin_amount {
//this may be slow, but will suffice for right now
let end = programs.pop().unwrap();
programs.insert(0, end);
}
},
&Instruction::Partner(program_a, program_b) => {
let position_a: usize = programs.iter().position(|&x| x == program_a).unwrap();
let position_b: usize = programs.iter().position(|&x| x == program_b).unwrap();
programs.swap(position_a, position_b);
}
}
}
programs
}
|