Day 5
This commit is contained in:
parent
f23334c962
commit
7bbd5ff22c
3 changed files with 255 additions and 9 deletions
|
@ -6,14 +6,14 @@ use crate::utils::Day;
|
||||||
pub struct Day4 {
|
pub struct Day4 {
|
||||||
pub input: String,
|
pub input: String,
|
||||||
pub acc: usize,
|
pub acc: usize,
|
||||||
pub cards: HashMap::<usize /* Card # */, Vec<usize> /* (won card indexes) */>
|
pub cards: HashMap<usize /* Card # */, Vec<usize> /* (won card indexes) */>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Day4 {
|
impl Day4 {
|
||||||
fn recurse(&mut self, cards: &Vec<usize>) {
|
fn recurse(&mut self, cards: &Vec<usize>) {
|
||||||
for card in cards {
|
for card in cards {
|
||||||
self.acc += 1;
|
self.acc += 1;
|
||||||
|
|
||||||
if let Some(won_cards) = self.cards.get(card) {
|
if let Some(won_cards) = self.cards.get(card) {
|
||||||
self.recurse(&won_cards.clone())
|
self.recurse(&won_cards.clone())
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ impl Day4 {
|
||||||
impl Day for Day4 {
|
impl Day for Day4 {
|
||||||
fn part1(&mut self) -> String {
|
fn part1(&mut self) -> String {
|
||||||
let mut sum = 0usize;
|
let mut sum = 0usize;
|
||||||
|
|
||||||
for line in self.input.lines() {
|
for line in self.input.lines() {
|
||||||
let (winning, numbers) = line.split_once(": ").unwrap().1.split_once(" | ").unwrap();
|
let (winning, numbers) = line.split_once(": ").unwrap().1.split_once(" | ").unwrap();
|
||||||
let winning = winning.split_whitespace().collect::<Vec<_>>();
|
let winning = winning.split_whitespace().collect::<Vec<_>>();
|
||||||
|
@ -37,7 +37,10 @@ impl Day for Day4 {
|
||||||
}
|
}
|
||||||
|
|
||||||
if winning_numbers.len() != 0 {
|
if winning_numbers.len() != 0 {
|
||||||
sum += winning_numbers.iter().skip(1).fold(1usize, |acc, _| acc * 2);
|
sum += winning_numbers
|
||||||
|
.iter()
|
||||||
|
.skip(1)
|
||||||
|
.fold(1usize, |acc, _| acc * 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +60,14 @@ impl Day for Day4 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.cards.insert(i + 1, winning_numbers.into_iter().enumerate().map(|(j, _)| (i + 1) + (j + 1)).collect());
|
self.cards.insert(
|
||||||
|
i + 1,
|
||||||
|
winning_numbers
|
||||||
|
.into_iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(j, _)| (i + 1) + (j + 1))
|
||||||
|
.collect(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.recurse(&self.cards.keys().map(|e| *e).collect::<Vec<_>>());
|
self.recurse(&self.cards.keys().map(|e| *e).collect::<Vec<_>>());
|
||||||
|
@ -98,9 +108,9 @@ Card 4: 41 92 73 84 69 | 59 84 76 51 58 5 54 83
|
||||||
Card 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36
|
Card 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36
|
||||||
Card 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11"#
|
Card 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11"#
|
||||||
.to_string(),
|
.to_string(),
|
||||||
acc: 0usize,
|
acc: 0usize,
|
||||||
cards: HashMap::new()
|
cards: HashMap::new()
|
||||||
}
|
}
|
||||||
.solve(2));
|
.solve(2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
233
src/day5/mod.rs
Normal file
233
src/day5/mod.rs
Normal file
|
@ -0,0 +1,233 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use crate::utils::Day;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Day5 {
|
||||||
|
pub input: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Day for Day5 {
|
||||||
|
fn part1(&mut self) -> String {
|
||||||
|
let groups = self.input.split("\n\n").skip(1).map(|g| {
|
||||||
|
let mut lines = g.lines();
|
||||||
|
(lines.next().unwrap(), lines.collect::<Vec<_>>())
|
||||||
|
});
|
||||||
|
|
||||||
|
let seeds = self
|
||||||
|
.input
|
||||||
|
.lines()
|
||||||
|
.next()
|
||||||
|
.unwrap()
|
||||||
|
.split_once(": ")
|
||||||
|
.unwrap()
|
||||||
|
.1
|
||||||
|
.split_whitespace()
|
||||||
|
.map(|s| s.parse::<usize>().unwrap());
|
||||||
|
let groups = groups
|
||||||
|
.map(|(name, list)| {
|
||||||
|
(
|
||||||
|
name.split_once(' ').unwrap().0.split_once("-to-").unwrap(),
|
||||||
|
list.into_iter().map(|line| {
|
||||||
|
let nums = line.split_whitespace()
|
||||||
|
.map(|n| n.parse::<usize>().unwrap())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
(nums[0], nums[1], nums[2])
|
||||||
|
}).collect::<Vec<_>>(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.map(|((from, to), mappings)| (
|
||||||
|
from,
|
||||||
|
(
|
||||||
|
to,
|
||||||
|
mappings
|
||||||
|
)
|
||||||
|
))
|
||||||
|
.collect::<HashMap<&str, (&str, Vec<(usize, usize, usize)>)>>();
|
||||||
|
|
||||||
|
let mut locations = Vec::<usize>::new();
|
||||||
|
|
||||||
|
for seed in seeds {
|
||||||
|
let (mut category, mut value) = ("seed", seed);
|
||||||
|
while category != "location" {
|
||||||
|
let (new_category, mappings) = groups.get(category).unwrap();
|
||||||
|
category = new_category;
|
||||||
|
|
||||||
|
for (destination_start, source_start, length) in mappings {
|
||||||
|
if (source_start..&(source_start + length)).contains(&&value) {
|
||||||
|
let delta = *source_start as isize - *destination_start as isize;
|
||||||
|
value = (value as isize - delta) as usize;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
locations.push(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
locations.into_iter().min().unwrap().to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Yes my solution was to brute force it
|
||||||
|
/// Yes it worked
|
||||||
|
/// Yes it only took 13m and 31s to solve
|
||||||
|
/// No I will not elaborate on why I felt the need to do it this way
|
||||||
|
/// Yes I should probably solve it correctly at some point
|
||||||
|
fn part2(&mut self) -> String {
|
||||||
|
let groups = self.input.split("\n\n").skip(1).map(|g| {
|
||||||
|
let mut lines = g.lines();
|
||||||
|
(lines.next().unwrap(), lines.collect::<Vec<_>>())
|
||||||
|
});
|
||||||
|
|
||||||
|
let seeds = self
|
||||||
|
.input
|
||||||
|
.lines()
|
||||||
|
.next()
|
||||||
|
.unwrap()
|
||||||
|
.split_once(": ")
|
||||||
|
.unwrap()
|
||||||
|
.1
|
||||||
|
.split_whitespace()
|
||||||
|
.map(|s| s.parse::<usize>().unwrap())
|
||||||
|
.collect::<Vec<usize>>();
|
||||||
|
let seeds = seeds
|
||||||
|
.as_slice()
|
||||||
|
.chunks(2);
|
||||||
|
|
||||||
|
let groups = groups
|
||||||
|
.map(|(name, list)| {
|
||||||
|
(
|
||||||
|
name.split_once(' ').unwrap().0.split_once("-to-").unwrap(),
|
||||||
|
list.into_iter().map(|line| {
|
||||||
|
let nums = line.split_whitespace()
|
||||||
|
.map(|n| n.parse::<usize>().unwrap())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
(nums[0], nums[1], nums[2])
|
||||||
|
}).collect::<Vec<_>>(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.map(|((from, to), mappings)| (
|
||||||
|
from,
|
||||||
|
(
|
||||||
|
to,
|
||||||
|
mappings
|
||||||
|
)
|
||||||
|
))
|
||||||
|
.collect::<HashMap<&str, (&str, Vec<(usize, usize, usize)>)>>();
|
||||||
|
|
||||||
|
let mut location = 100000000usize;
|
||||||
|
let seedslen = seeds.len();
|
||||||
|
|
||||||
|
for (i, chunk) in seeds.enumerate() {
|
||||||
|
let (initial, range) = (chunk[0], chunk[1]);
|
||||||
|
for (j, seed) in (initial..(initial + range)).enumerate() {
|
||||||
|
if j % 1000 == 0 {
|
||||||
|
println!("Chunk {}/{}, Seed {}/{} ({:.2}%)", i, seedslen, j, range, j as f64 / range as f64 * 100.0);
|
||||||
|
}
|
||||||
|
let (mut category, mut value) = ("seed", seed);
|
||||||
|
while category != "location" {
|
||||||
|
let (new_category, mappings) = groups.get(category).unwrap();
|
||||||
|
category = new_category;
|
||||||
|
|
||||||
|
for (destination_start, source_start, length) in mappings {
|
||||||
|
if (source_start..&(source_start + length)).contains(&&value) {
|
||||||
|
let delta = *source_start as isize - *destination_start as isize;
|
||||||
|
value = (value as isize - delta) as usize;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if location > value { location = value }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
location.to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::{day5::Day5, utils::Day};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn passes_example_1() {
|
||||||
|
dbg!(Day5 {
|
||||||
|
input: r#"seeds: 79 14 55 13
|
||||||
|
|
||||||
|
seed-to-soil map:
|
||||||
|
50 98 2
|
||||||
|
52 50 48
|
||||||
|
|
||||||
|
soil-to-fertilizer map:
|
||||||
|
0 15 37
|
||||||
|
37 52 2
|
||||||
|
39 0 15
|
||||||
|
|
||||||
|
fertilizer-to-water map:
|
||||||
|
49 53 8
|
||||||
|
0 11 42
|
||||||
|
42 0 7
|
||||||
|
57 7 4
|
||||||
|
|
||||||
|
water-to-light map:
|
||||||
|
88 18 7
|
||||||
|
18 25 70
|
||||||
|
|
||||||
|
light-to-temperature map:
|
||||||
|
45 77 23
|
||||||
|
81 45 19
|
||||||
|
68 64 13
|
||||||
|
|
||||||
|
temperature-to-humidity map:
|
||||||
|
0 69 1
|
||||||
|
1 0 69
|
||||||
|
|
||||||
|
humidity-to-location map:
|
||||||
|
60 56 37
|
||||||
|
56 93 4"#.to_string(),
|
||||||
|
}
|
||||||
|
.solve(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn passes_example_2() {
|
||||||
|
dbg!(Day5 {
|
||||||
|
input: r#"seeds: 79 14 55 13
|
||||||
|
|
||||||
|
seed-to-soil map:
|
||||||
|
50 98 2
|
||||||
|
52 50 48
|
||||||
|
|
||||||
|
soil-to-fertilizer map:
|
||||||
|
0 15 37
|
||||||
|
37 52 2
|
||||||
|
39 0 15
|
||||||
|
|
||||||
|
fertilizer-to-water map:
|
||||||
|
49 53 8
|
||||||
|
0 11 42
|
||||||
|
42 0 7
|
||||||
|
57 7 4
|
||||||
|
|
||||||
|
water-to-light map:
|
||||||
|
88 18 7
|
||||||
|
18 25 70
|
||||||
|
|
||||||
|
light-to-temperature map:
|
||||||
|
45 77 23
|
||||||
|
81 45 19
|
||||||
|
68 64 13
|
||||||
|
|
||||||
|
temperature-to-humidity map:
|
||||||
|
0 69 1
|
||||||
|
1 0 69
|
||||||
|
|
||||||
|
humidity-to-location map:
|
||||||
|
60 56 37
|
||||||
|
56 93 4"#.to_string(),
|
||||||
|
}
|
||||||
|
.solve(2));
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,12 +6,13 @@ use std::{
|
||||||
|
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
|
|
||||||
use crate::{day1::Day1, day2::Day2, day3::Day3, day4::Day4, utils::Day};
|
use crate::{day1::Day1, day2::Day2, day3::Day3, day4::Day4, day5::Day5, utils::Day};
|
||||||
|
|
||||||
pub mod day1;
|
pub mod day1;
|
||||||
pub mod day2;
|
pub mod day2;
|
||||||
pub mod day3;
|
pub mod day3;
|
||||||
pub mod day4;
|
pub mod day4;
|
||||||
|
pub mod day5;
|
||||||
pub mod fetcher;
|
pub mod fetcher;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
|
||||||
|
@ -91,6 +92,7 @@ async fn main() {
|
||||||
acc: 0usize,
|
acc: 0usize,
|
||||||
cards: HashMap::new(),
|
cards: HashMap::new(),
|
||||||
}),
|
}),
|
||||||
|
5 => Box::new(Day5 { input: response }),
|
||||||
_ => panic!("Invalid day #"),
|
_ => panic!("Invalid day #"),
|
||||||
};
|
};
|
||||||
let start = std::time::Instant::now();
|
let start = std::time::Instant::now();
|
||||||
|
@ -140,6 +142,7 @@ async fn main() {
|
||||||
acc: 0usize,
|
acc: 0usize,
|
||||||
cards: HashMap::new(),
|
cards: HashMap::new(),
|
||||||
}),
|
}),
|
||||||
|
5 => Box::new(Day5 { input: response }),
|
||||||
_ => panic!("Invalid day #"),
|
_ => panic!("Invalid day #"),
|
||||||
};
|
};
|
||||||
let mut timings = Vec::<Duration>::new();
|
let mut timings = Vec::<Duration>::new();
|
||||||
|
|
Loading…
Reference in a new issue