summaryrefslogtreecommitdiff
path: root/2025/d2.rs
blob: 9c2b06090c37cd319e1ce8c3c38da9c809323913 (plain)
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);
}