Advent of Code 2024, Day 1
This commit is contained in:
parent
febbf4c709
commit
b0966e5b39
|
@ -0,0 +1,7 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aoc-2024"
|
||||
version = "0.1.0"
|
|
@ -0,0 +1,6 @@
|
|||
[package]
|
||||
name = "aoc-2024"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,157 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
const INPUT: &'static str = include_str!("../data/day1.txt");
|
||||
|
||||
pub fn day1a() -> String {
|
||||
let (left_list, right_list) = parse_lists(INPUT);
|
||||
|
||||
let left_list = sort_list_asc(left_list);
|
||||
let right_list = sort_list_asc(right_list);
|
||||
|
||||
let zipped = zip_lists(left_list, right_list);
|
||||
|
||||
format!("{}", total_distance(zipped))
|
||||
}
|
||||
|
||||
pub fn day1b() -> String {
|
||||
let (left_list, right_list) = parse_lists(INPUT);
|
||||
format!("{}", total_similarity(left_list, right_list))
|
||||
}
|
||||
|
||||
fn total_distance(pairs: Vec<(i32, i32)>) -> i32 {
|
||||
pairs.into_iter().fold(0, |acc, pair| acc + distance(pair))
|
||||
}
|
||||
|
||||
fn total_similarity(left_list: Vec<i32>, right_list: Vec<i32>) -> i32 {
|
||||
let left_frequency = frequency_count(left_list);
|
||||
let right_frequency = frequency_count(right_list);
|
||||
|
||||
let mut similarity = 0;
|
||||
|
||||
for (key, count) in left_frequency.into_iter() {
|
||||
let right_occurences = right_frequency.get(&key).cloned().unwrap_or(0);
|
||||
|
||||
println!("[{}] {} * {}", key, count, right_occurences);
|
||||
|
||||
similarity += key * count * right_occurences;
|
||||
}
|
||||
|
||||
similarity
|
||||
}
|
||||
|
||||
fn distance(pair: (i32, i32)) -> i32 {
|
||||
(pair.0 - pair.1).abs()
|
||||
}
|
||||
|
||||
fn parse_lists(input: &str) -> (Vec<i32>, Vec<i32>) {
|
||||
let mut left_list = vec![];
|
||||
let mut right_list = vec![];
|
||||
|
||||
input.lines().for_each(|text| {
|
||||
let values = text.split(' ').filter(|t| !t.is_empty()).map(|t| t.parse::<i32>().unwrap()).collect::<Vec<i32>>();
|
||||
left_list.push(values[0]);
|
||||
right_list.push(values[1]);
|
||||
});
|
||||
|
||||
(left_list, right_list)
|
||||
}
|
||||
|
||||
fn sort_list_asc(mut input: Vec<i32>) -> Vec<i32> {
|
||||
input.sort();
|
||||
input
|
||||
}
|
||||
|
||||
fn zip_lists(left: Vec<i32>, right: Vec<i32>) -> Vec<(i32, i32)> {
|
||||
left.into_iter().zip(right).collect::<Vec<(i32, i32)>>()
|
||||
}
|
||||
|
||||
type FrequencyCount = HashMap<i32, i32>;
|
||||
|
||||
fn frequency_count(lst: Vec<i32>) -> FrequencyCount {
|
||||
let mut cnt = HashMap::new();
|
||||
|
||||
for number in lst {
|
||||
cnt.entry(number).and_modify(|e| {*e += 1; }).or_insert(1);
|
||||
}
|
||||
|
||||
cnt
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
const TEST_INPUT: &'static str = "3 4
|
||||
4 3
|
||||
2 5
|
||||
1 3
|
||||
3 9
|
||||
3 3";
|
||||
|
||||
#[test]
|
||||
fn it_figures_out_smallest_numbers() {
|
||||
let (left_list, right_list) = parse_lists(TEST_INPUT);
|
||||
|
||||
assert_eq!(left_list.len(), 6);
|
||||
assert_eq!(right_list.len(), 6);
|
||||
|
||||
assert_eq!(left_list, vec![3, 4, 2, 1, 3, 3]);
|
||||
assert_eq!(right_list, vec![4, 3, 5, 3, 9, 3]);
|
||||
|
||||
let left_list = sort_list_asc(left_list);
|
||||
let right_list = sort_list_asc(right_list);
|
||||
|
||||
assert_eq!(left_list[0], 1);
|
||||
assert_eq!(right_list[0], 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_zips_two_lists() {
|
||||
let (left_list, right_list) = parse_lists(TEST_INPUT);
|
||||
|
||||
let left_list = sort_list_asc(left_list);
|
||||
let right_list = sort_list_asc(right_list);
|
||||
|
||||
let zipped = zip_lists(left_list, right_list);
|
||||
|
||||
assert_eq!(zipped[0], (1, 3));
|
||||
assert_eq!(zipped[1], (2, 3));
|
||||
assert_eq!(zipped[2], (3, 3));
|
||||
assert_eq!(zipped[3], (3, 4));
|
||||
assert_eq!(zipped[4], (3, 5));
|
||||
assert_eq!(zipped[5], (4, 9));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_finds_difference_between_pairs() {
|
||||
let (left_list, right_list) = parse_lists(TEST_INPUT);
|
||||
|
||||
let left_list = sort_list_asc(left_list);
|
||||
let right_list = sort_list_asc(right_list);
|
||||
|
||||
let zipped = zip_lists(left_list, right_list);
|
||||
|
||||
assert_eq!(distance(zipped[0]), 2);
|
||||
assert_eq!(distance(zipped[1]), 1);
|
||||
|
||||
assert_eq!(total_distance(zipped), 11);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_counts_frequencies() {
|
||||
let (left_list, _right_list) = parse_lists(TEST_INPUT);
|
||||
|
||||
let frequencies = frequency_count(left_list);
|
||||
|
||||
assert_eq!(frequencies.get(&1), Some(&1));
|
||||
assert_eq!(frequencies.get(&2), Some(&1));
|
||||
assert_eq!(frequencies.get(&3), Some(&3));
|
||||
assert_eq!(frequencies.get(&4), Some(&1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_calculates_total_similarity() {
|
||||
let (left_list, right_list) = parse_lists(TEST_INPUT);
|
||||
assert_eq!(total_similarity(left_list, right_list), 31);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
mod day1;
|
||||
|
||||
fn main() {
|
||||
let day = std::env::args().skip(1).next();
|
||||
|
||||
let result = match day.as_ref().map(|v| v.as_ref()) {
|
||||
Some("1a") => day1::day1a(),
|
||||
Some("1b") => day1::day1b(),
|
||||
_ => panic!("unrecognized day"),
|
||||
};
|
||||
|
||||
println!("[{}] {}", day.unwrap(), result);
|
||||
}
|
|
@ -1,3 +1,2 @@
|
|||
[toolchain]
|
||||
channel = "1.73.0"
|
||||
targets = [ "wasm32-unknown-unknown" ]
|
||||
channel = "1.81.0"
|
||||
|
|
Loading…
Reference in New Issue