DEVELOPMENT ENVIRONMENT

~liljamo/aoc2025

ref: 44396ade0adbb061dc948f1eb7be84149f6ab230 aoc2025/crates/day1/src/main.rs -rw-r--r-- 3.2 KiB
44396adeJonni Liljamo feat: day3 part one 2 days ago
                                                                                
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#![no_std]

use common::{print, read};

fn main() {
    let buf = [0u8; 65000];
    read(buf.as_ptr(), buf.len());
    let input = str::from_utf8(&buf).unwrap();
    let result_one = one(input);
    let result_two = two(input);
    print!(32, "one: {}\ntwo: {}\n", result_one, result_two);
}

fn one(input: &str) -> u16 {
    let mut zeros: u16 = 0;
    let mut pos: i16 = 50;
    for ins in input.split("\n") {
        // Last entry is all unused bytes.
        if ins.len() > 10 {
            continue;
        }

        let (direction, amount_s) = ins.split_at(1);
        let amount = amount_s.parse::<i16>().unwrap();

        match direction {
            "R" => {
                pos += amount;
                while pos > 99 {
                    pos -= 100;
                }
            }
            "L" => {
                pos -= amount;
                while pos < 0 {
                    pos += 100;
                }
            }
            _ => unreachable!(),
        }

        if pos == 0 {
            zeros += 1;
        }
    }

    zeros
}

fn two(input: &str) -> u16 {
    let mut zeros: u16 = 0;
    let mut pos: i16 = 50;
    for ins in input.split("\n") {
        // Last entry is all unused bytes.
        if ins.len() > 10 {
            continue;
        }

        let (direction, amount_s) = ins.split_at(1);
        let mut amount = amount_s.parse::<i16>().unwrap();

        match direction {
            "R" => {}
            "L" => amount = -amount,
            _ => unreachable!(),
        }

        pos += amount;
        if pos <= 0 && amount != pos {
            zeros += 1;
        }
        let overflows = pos.abs() / 100;
        zeros += overflows as u16;
        pos = pos.rem_euclid(100);
    }

    zeros
}

#[cfg(test)]
mod test {
    use super::*;

    const EXAMPLE_INPUT: &str = r#"L68
L30
R48
L5
R60
L55
L1
L99
R14
L82"#;

    #[test]
    fn example() {
        assert_eq!(one(EXAMPLE_INPUT), 3);
        assert_eq!(two(EXAMPLE_INPUT), 6);
    }

    #[test]
    fn two_1000() {
        assert_eq!(two("R1000"), 10);
    }

    #[test]
    fn two_basics() {
        // Move to zero (!), move one left, should be at 99.
        assert_eq!(two("L50\nL1"), 1);
        // Move to 99, move one right, should be at zero (!).
        assert_eq!(two("R49\nR1"), 1);
        // Move to 5, move ten left (!), should be at 95, move 5 right, should be at zero (!).
        assert_eq!(two("L45\nL10\nR5"), 2);
    }

    #[test]
    fn two_a() {
        let input = r#"R50
L1"#;

        assert_eq!(two(input), 1);
    }

    #[test]
    fn two_b() {
        assert_eq!(two("L100"), 1);
    }

    #[test]
    fn two_c() {
        assert_eq!(two("L120"), 1);
    }

    #[test]
    fn two_d() {
        let input = r#"R250
L1"#;

        assert_eq!(two(input), 3);
    }

    #[test]
    fn two_e() {
        let input = r#"R400"#;

        assert_eq!(two(input), 4);
    }

    #[test]
    fn two_f() {
        let input = r#"L250"#;

        assert_eq!(two(input), 3);
    }

    #[test]
    fn two_g() {
        let input = r#"L50
R200"#;

        assert_eq!(two(input), 3);
    }

    #[test]
    fn two_h() {
        let input = r#"R38
R17"#;

        assert_eq!(two(input), 1);
    }
}