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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
use std::env;
use std::io::BufReader;
use std::io::BufRead;
use std::fs::File;
use std::process;
use std::collections::HashMap;
type State = Vec<(i64, char)>;
type RuleKey = (char, char, char, char, char);
type Rules = HashMap<RuleKey, char>;
static ITERATIONS: usize = 20;
fn parse_initial_state(line: &String) -> State {
let initial: Vec<char> = line[15..].chars().collect();
let mut slice: State = Vec::new();
for i in -(ITERATIONS as i64) - 2..0 {
slice.push((i, '.'));
}
for (i, ch) in initial.iter().enumerate() {
slice.push((i as i64, *ch));
}
for i in initial.len()..initial.len() + ITERATIONS + 2 {
slice.push((i as i64, '.'));
}
for (i, _) in &slice {
print!("{} ", i);
}
print!("\n");
slice
}
fn parse_rule(rules: &mut Rules, line: &String) {
let chs: Vec<char> = line.chars().collect();
let res: char = chs[chs.len() - 1];
let p = chs[0..6].to_vec();
let rule_key = (p[0], p[1], p[2], p[3], p[4]);
rules.insert(rule_key, res);
}
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() != 2 {
println!("Wrong number of arguments. Provide a file name and worker count.");
process::exit(1);
}
let filename = &args[1];
println!("Using file {} as input.", filename);
let f = match File::open(filename) {
Ok(file) => file,
Err(e) => {
println!("Failed to open file {}. {:?}", filename, e);
process::exit(1);
}
};
let file = BufReader::new(&f);
let lines: Vec<String> = file.lines()
.map(|line| line.expect("Could not parse line."))
.collect();
let mut initial_state: State = Vec::new();
let mut rules: Rules = HashMap::new();
for (i, line) in lines.iter().enumerate() {
match i {
0 => { initial_state = parse_initial_state(&line); }
1 => { }
_ => { parse_rule(&mut rules, &line); }
}
}
assert_ne!(initial_state.len(), 0);
let state_len = initial_state.len();
let mut states: Vec<State> = vec![initial_state];
for iteration in 0..ITERATIONS {
let mut new_state: State = vec![(-999, '.'); state_len];
{
let prev_state = &states[states.len() - 1];
for (i, _) in prev_state.iter().enumerate() {
if i < 2 || i >= state_len - 2 { continue; }
let rule_key = (prev_state[i-2].1, prev_state[i-1].1, prev_state[i].1, prev_state[i+1].1, prev_state[i+2].1);
let value = rules[&rule_key];
new_state[i] = (prev_state[i].0, value);
}
}
if iteration % 1000 == 0 {
println!("Iteration: {}", iteration);
}
states.push(new_state);
}
for (i, state) in states.iter().enumerate() {
print!("{}: ", i);
for tupl in state {
let ch = tupl.1;
print!("{}", ch);
}
print!("\n");
}
let mut total = 0;
let last_i = states.len() - 1;
let last_state = &states[last_i];
for (_, &tupl) in last_state.iter().enumerate() {
let (i, ch) = tupl;
if ch == '#' {
total += i;
}
}
println!("Result: {}", total);
}
|