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
|
use aoc::fetch::fetch;
struct Checker {
first: usize,
last: usize,
}
impl Checker {
fn new(first: usize, last: usize) -> Result<Self, ()> {
if first
.to_string()
.chars()
.next()
.unwrap()
== '0'
{
return Err(());
}
Ok(
Self {
first,
last,
},
)
}
fn parse_section_part1(num: usize) -> usize {
let s = num.to_string();
let len = s.len();
for substr_len in 1..=len / 2 {
if len % substr_len == 0 {
let first = &s[0..substr_len];
if s.as_bytes()
.chunks(substr_len)
.all(|chunk| chunk == first.as_bytes())
{
return num;
}
}
}
0
}
fn parse_section_part2(num: usize) -> usize {
let s = num.to_string();
if s.len() % 2 != 0 {
return 0;
}
if s[0..s.len() / 2] == s[s.len() / 2..s.len()] {
return num;
}
0
}
fn parse(self, part2: bool) -> usize {
let mut ans = 0;
for i in self.first..=self.last {
ans += if part2 {
Self::parse_section_part2(i)
} else {
Self::parse_section_part1(i)
};
}
ans
}
}
fn run(part2: bool) {
let input = fetch(
2, ',',
);
let mut ans = 0;
for s in input {
let s = s.replace(
'\n', "",
);
if s.is_empty() {
continue;
}
let split = s.split('-');
let first = split
.clone()
.next()
.unwrap()
.parse()
.unwrap();
let last = split
.clone()
.nth(1)
.unwrap()
.parse()
.unwrap();
ans += &Checker::new(
first, last,
)
.unwrap()
.parse(part2);
}
println!("{ans}");
}
pub fn part1() {
run(false);
}
pub fn part2() {
run(true);
}
|