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
|
fn generate_data(input: &str, length: usize) -> String {
let mut a = String::from(input);
while a.len() < length {
let mut b = String::new();
// Fill `b' with reversed and bit-flipped `a'
for c in a.chars().rev() {
b.push(if c == '0' { '1' } else { '0' });
}
a = format!("{}0{}", a, b);
}
a.truncate(length);
a
}
fn get_checksum(data: &str) -> String {
let mut chars: Vec<char> = data.chars().collect();
while chars.len() % 2 == 0 {
let mut next = Vec::new();
// For each pair of characters (length is even due to `while')
for i in 0..chars.len() / 2 {
// If both chars in this pair are equal
if chars[2 * i] == chars[2 * i + 1] {
next.push('1');
} else {
next.push('0');
}
}
chars = next;
}
chars.into_iter().collect()
}
fn solve_puzzle(input: &str, length: usize) -> String {
let data = generate_data(input, length);
get_checksum(&data)
}
fn main() {
// My personal puzzle input
let input = "11011110011011101";
// Part 1 gives 00000100100001100 for me
println!("Part 1 solution: {}", solve_puzzle(input, 272));
// Part 1 gives 00011010100010010 for me
println!("Part 2 solution: {}", solve_puzzle(input, 35651584));
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_data() {
assert_eq!(generate_data("1", 3), "100");
assert_eq!(generate_data("0", 3), "001");
assert_eq!(generate_data("11111", 11), "11111000000");
assert_eq!(
generate_data("111100001010", 25),
"1111000010100101011110000"
);
}
#[test]
fn test_checksum() {
assert_eq!(get_checksum("110010110100"), "100");
}
#[test]
fn part1_example1() {
assert_eq!(solve_puzzle("10000", 20), "01100");
}
}
|