my solutions to advent of code
aoc
advent-of-code
1use std::collections::HashSet;
2
3struct Range {
4 start: u64,
5 end: u64,
6}
7
8const MAX_LENGTH: usize = 10;
9
10fn main() {
11 let input: Vec<Range> = include_str!("../../input.txt")
12 .trim()
13 .split(",")
14 .map(|v| {
15 let range = v.split_once("-");
16 match range {
17 Some((start, end)) => Range {
18 start: start.parse().expect("invalid number"),
19 end: end.parse().expect("invalid number"),
20 },
21 _ => panic!("bad input!"),
22 }
23 })
24 .collect();
25
26 let powers_of_ten: Vec<u64> =
27 (0..=MAX_LENGTH as u32).map(|i| 10_u64.pow(i)).collect();
28
29 let [invalid_part_1, invalid_part_2] = {
30 let mut part_1: HashSet<u64> = HashSet::new();
31 let mut part_2: HashSet<u64> = HashSet::new();
32
33 for len in 1..=MAX_LENGTH / 2 {
34 // 1-9, 10-99, 100-999, 100000-999999
35 for combination in *powers_of_ten.get(len - 1).unwrap_or(&1)
36 ..*powers_of_ten.get(len).unwrap()
37 {
38 let mut number = 0;
39 // 0 is just the number (9), 1 is one repetition (99)
40 for repeat in 0..MAX_LENGTH / len {
41 number += combination
42 * powers_of_ten.get((len * repeat) as usize).unwrap();
43 if repeat > 0 {
44 part_2.insert(number);
45 }
46 if repeat == 1 {
47 part_1.insert(number);
48 }
49 }
50 }
51 }
52
53 [part_1, part_2]
54 };
55
56 let part_1 = invalid_part_1.iter().fold(0, |acc, number| {
57 if input.iter().any(|r| *number >= r.start && *number <= r.end) {
58 acc + number
59 } else {
60 acc
61 }
62 });
63 println!("{}", part_1);
64
65 let part_2 = invalid_part_2.iter().fold(0, |acc, number| {
66 if input.iter().any(|r| *number >= r.start && *number <= r.end) {
67 acc + number
68 } else {
69 acc
70 }
71 });
72 println!("{}", part_2);
73}