Skip to content

Commit e103123

Browse files
committed
[rs] 2024:01: Solve day01
1 parent 2e26a0a commit e103123

File tree

1 file changed

+97
-0
lines changed

1 file changed

+97
-0
lines changed

2024/day01/day01.rs

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
use std::fs;
2+
use std::collections::HashMap;
3+
use std::hash::Hash;
4+
5+
struct Lists {
6+
left: Vec<u32>,
7+
right: Vec<u32>,
8+
}
9+
10+
impl Lists {
11+
fn new(mut left: Vec<u32>, mut right: Vec<u32>) -> Self {
12+
left.sort(); right.sort();
13+
14+
let len = left.len();
15+
if right.len() != len { panic!("Lists differ in length?") }
16+
Self { left, right }
17+
}
18+
19+
fn nth_left(&self, inx: usize) -> &u32 {
20+
self.left.get(inx).expect("Out of bounds read (l)")
21+
}
22+
fn nth_right(&self, inx: usize) -> &u32 {
23+
self.right.get(inx).expect("Out of bounds read (r)")
24+
}
25+
26+
fn left(&self) -> &Vec<u32> { &self.left }
27+
fn right(&self) -> &Vec<u32> { &self.right }
28+
fn len(&self) -> usize { self.left.len() }
29+
}
30+
31+
fn read_input(filename: &str) -> Vec<String> {
32+
if let Ok(input_text) = fs::read_to_string(filename) {
33+
input_text
34+
.trim()
35+
.split("\n")
36+
.map(|line| line.trim().to_owned())
37+
.collect()
38+
} else {
39+
panic!("Unable to read input from file: {}", filename);
40+
}
41+
}
42+
43+
fn parse_lists(input_lines: Vec<String>) -> Lists {
44+
let mut left: Vec<u32> = Vec::new();
45+
let mut right: Vec<u32> = Vec::new();
46+
47+
for input_line in input_lines {
48+
let mut nums = input_line.split(" ");
49+
left.push(nums.next().expect("Missing left number").parse().expect("Invalid left number"));
50+
right.push(nums.next().expect("Missing right number").parse().expect("Invalid right number"));
51+
}
52+
53+
Lists::new(left, right)
54+
}
55+
56+
fn part1(lists: &Lists) -> u64 {
57+
let mut diff_score: u64 = 0;
58+
for inx in 0..lists.len() {
59+
let left: i32 = *lists.nth_left(inx) as i32;
60+
let right: i32 = *lists.nth_right(inx) as i32;
61+
let diff = (left - right).abs();
62+
diff_score += diff as u64;
63+
}
64+
diff_score
65+
}
66+
67+
fn get_or_default<'a, K, V>(
68+
map: &'a HashMap<K, V>,
69+
key: &K,
70+
default_value: &'static V
71+
) -> &'a V where K: Eq+Hash {
72+
return match map.get(key) {
73+
Some(value) => value,
74+
None => default_value
75+
}
76+
}
77+
78+
fn part2(lists: &Lists) -> u64 {
79+
let mut similar_score: u64 = 0;
80+
let mut count_map: HashMap<u32, usize> = HashMap::new();
81+
for right_num in lists.right() {
82+
count_map.insert(*right_num, get_or_default(&count_map, right_num, &0) + 1);
83+
}
84+
for left_num in lists.left() {
85+
similar_score += (*left_num as u64) * (*get_or_default(&count_map, left_num, &0) as u64);
86+
}
87+
similar_score
88+
}
89+
90+
pub fn main() {
91+
let input_text = read_input("input");
92+
let lists: Lists = parse_lists(input_text);
93+
94+
let solution1 = part1(&lists);
95+
let solution2 = part2(&lists);
96+
println!("Part 1: {}\nPart 2: {}", solution1, solution2);
97+
}

0 commit comments

Comments
 (0)