Skip to content

Commit 25330c8

Browse files
committed
chore: day 2 part 1
Signed-off-by: markkovari <kovarimarkofficial@gmail.com>
1 parent f29f04d commit 25330c8

3 files changed

Lines changed: 203 additions & 0 deletions

File tree

2025/src/2_input

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
9595822750-9596086139,1957-2424,88663-137581,48152-65638,12354817-12385558,435647-489419,518494-609540,2459-3699,646671-688518,195-245,295420-352048,346-514,8686839668-8686892985,51798991-51835611,8766267-8977105,2-17,967351-995831,6184891-6331321,6161577722-6161678622,912862710-913019953,6550936-6625232,4767634976-4767662856,2122995-2257010,1194-1754,779-1160,22-38,4961-6948,39-53,102-120,169741-245433,92902394-92956787,531-721,64-101,15596-20965,774184-943987,8395-11781,30178-47948,94338815-94398813

2025/src/day2.rs

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
use std::str::FromStr;
2+
3+
type Id = u64;
4+
5+
#[derive(Debug, Clone, Copy)]
6+
struct Range {
7+
lower: Id,
8+
upper: Id,
9+
}
10+
11+
fn is_double(n: Id) -> bool {
12+
let s = n.to_string();
13+
let len = s.len();
14+
if len % 2 != 0 {
15+
return false;
16+
}
17+
18+
let mid = len / 2;
19+
&s[..mid] == &s[mid..]
20+
}
21+
22+
impl Range {
23+
pub fn get_doubles(&self) -> Vec<Id> {
24+
(self.lower..=self.upper).into_iter().filter(|&e|is_double(e)).collect()
25+
}
26+
}
27+
28+
#[derive(Debug)]
29+
enum ParseRangeError {
30+
CannotParseRange,
31+
NotExactlyTwoNumbers
32+
}
33+
34+
impl FromStr for Range {
35+
type Err = ParseRangeError;
36+
37+
fn from_str(s: &str) -> Result<Self, Self::Err> {
38+
let parts = s.split('-').collect::<Vec<&str>>();
39+
if parts.len() != 2 {
40+
return Err(ParseRangeError::NotExactlyTwoNumbers);
41+
}
42+
43+
if let [lower, upper] = parts.as_slice() {
44+
match ( lower.parse::<Id>(), upper.parse::<Id>()) {
45+
(Ok(lower_number), Ok(upper_number)) => {
46+
return Ok(Range { lower: lower_number, upper: upper_number});
47+
},
48+
_ => Err(ParseRangeError::CannotParseRange)
49+
}
50+
} else {
51+
return Err(ParseRangeError::CannotParseRange)
52+
}
53+
}
54+
55+
}
56+
57+
fn parse_ranges(input: &str) -> Option<Vec<Range>> {
58+
input
59+
.trim()
60+
.split(',')
61+
.map(|line|line.parse())
62+
.collect::<Result<Vec<_>, _>>()
63+
.ok()
64+
}
65+
66+
fn solve_1(ranges: &Vec<Range>) -> Id {
67+
ranges.into_iter().map(|range| range.get_doubles().iter().sum::<Id>()).sum()
68+
}
69+
70+
pub fn run() {
71+
let input = include_str!("2_input");
72+
73+
if let Some(ranges) = parse_ranges(input) {
74+
println!("Day 2 Part 1: {}", solve_1(&ranges));
75+
}
76+
}
77+
78+
#[cfg(test)]
79+
mod tests {
80+
use super::*;
81+
82+
#[test]
83+
fn test_is_double_valid() {
84+
assert!(is_double(11));
85+
assert!(is_double(22));
86+
assert!(is_double(99));
87+
assert!(is_double(1010));
88+
assert!(is_double(6464));
89+
assert!(is_double(123123));
90+
assert!(is_double(222222));
91+
assert!(is_double(446446));
92+
assert!(is_double(1188511885));
93+
assert!(is_double(38593859));
94+
}
95+
96+
#[test]
97+
fn test_is_double_invalid() {
98+
assert!(!is_double(101)); // Not a double, has leading zero if split
99+
assert!(!is_double(100));
100+
assert!(!is_double(123));
101+
assert!(!is_double(1234));
102+
assert!(!is_double(98));
103+
assert!(!is_double(1011));
104+
}
105+
106+
#[test]
107+
fn test_is_double_odd_length() {
108+
assert!(!is_double(1));
109+
assert!(!is_double(111));
110+
assert!(!is_double(12345));
111+
}
112+
113+
#[test]
114+
fn test_range_11_22() {
115+
let range = Range { lower: 11, upper: 22 };
116+
assert_eq!(range.get_doubles(), vec![11, 22]);
117+
}
118+
119+
#[test]
120+
fn test_range_95_115() {
121+
let range = Range { lower: 95, upper: 115 };
122+
assert_eq!(range.get_doubles(), vec![99]);
123+
}
124+
125+
#[test]
126+
fn test_range_998_1012() {
127+
let range = Range { lower: 998, upper: 1012 };
128+
assert_eq!(range.get_doubles(), vec![1010]);
129+
}
130+
131+
#[test]
132+
fn test_range_1188511880_1188511890() {
133+
let range = Range { lower: 1188511880, upper: 1188511890 };
134+
assert_eq!(range.get_doubles(), vec![1188511885]);
135+
}
136+
137+
#[test]
138+
fn test_range_222220_222224() {
139+
let range = Range { lower: 222220, upper: 222224 };
140+
assert_eq!(range.get_doubles(), vec![222222]);
141+
}
142+
143+
#[test]
144+
fn test_range_1698522_1698528() {
145+
let range = Range { lower: 1698522, upper: 1698528 };
146+
assert_eq!(range.get_doubles(), Vec::<Id>::new());
147+
}
148+
149+
#[test]
150+
fn test_range_446443_446449() {
151+
let range = Range { lower: 446443, upper: 446449 };
152+
assert_eq!(range.get_doubles(), vec![446446]);
153+
}
154+
155+
#[test]
156+
fn test_range_38593856_38593862() {
157+
let range = Range { lower: 38593856, upper: 38593862 };
158+
assert_eq!(range.get_doubles(), vec![38593859]);
159+
}
160+
161+
#[test]
162+
fn test_range_565653_565659() {
163+
let range = Range { lower: 565653, upper: 565659 };
164+
assert_eq!(range.get_doubles(), Vec::<Id>::new());
165+
}
166+
167+
#[test]
168+
fn test_range_824824821_824824827() {
169+
let range = Range { lower: 824824821, upper: 824824827 };
170+
assert_eq!(range.get_doubles(), Vec::<Id>::new());
171+
}
172+
173+
#[test]
174+
fn test_range_2121212118_2121212124() {
175+
let range = Range { lower: 2121212118, upper: 2121212124 };
176+
assert_eq!(range.get_doubles(), Vec::<Id>::new());
177+
}
178+
179+
#[test]
180+
fn test_parse_ranges() {
181+
let input = "11-22,95-115,998-1012";
182+
let ranges = parse_ranges(input).unwrap();
183+
assert_eq!(ranges.len(), 3);
184+
assert_eq!(ranges[0].lower, 11);
185+
assert_eq!(ranges[0].upper, 22);
186+
assert_eq!(ranges[1].lower, 95);
187+
assert_eq!(ranges[1].upper, 115);
188+
}
189+
190+
#[test]
191+
fn test_example_sum() {
192+
let input = "11-22,95-115,998-1012,1188511880-1188511890,222220-222224,1698522-1698528,446443-446449,38593856-38593862,565653-565659,824824821-824824827,2121212118-2121212124";
193+
let ranges = parse_ranges(input).unwrap();
194+
let sum: u64 = ranges.iter()
195+
.flat_map(|r| (r.lower..=r.upper).filter(|&n| is_double(n)))
196+
.map(|n| n as u64)
197+
.sum();
198+
assert_eq!(sum, 1227775554);
199+
}
200+
}

2025/src/main.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
mod day1;
2+
mod day2;
23

34
fn main() {
45
println!("Advent of Code 2025");
56
println!("===================\n");
67

78
day1::run();
9+
day2::run();
810
}

0 commit comments

Comments
 (0)