1
0
Fork 0

Solve day 5 part 1

This commit is contained in:
Lars Martens 2023-12-05 12:08:13 +01:00
parent ed8137d599
commit 5f70c0666c
2 changed files with 159 additions and 0 deletions

33
input/05-test Normal file
View file

@ -0,0 +1,33 @@
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

126
src/bin/05.rs Normal file
View file

@ -0,0 +1,126 @@
use itertools::Itertools;
const INPUT: &str = include_str!("../../input/05");
const TEST_INPUT: &str = include_str!("../../input/05-test");
fn main() {
assert_eq!(part1(TEST_INPUT), 35);
println!("Part 1: {}", part1(INPUT));
assert_eq!(part2(TEST_INPUT), 46);
println!("Part 2: {}", part2(INPUT));
}
fn part1(input: &str) -> u64 {
let garden = Garden::parse(input);
garden
.simple_seeds
.iter()
.copied()
.map(|seed| garden.map(seed))
.min()
.unwrap()
}
fn part2(input: &str) -> u64 {
0
}
#[derive(Debug)]
struct Garden {
simple_seeds: Vec<u64>,
seed_ranges: Vec<SeedRange>,
maps: Vec<Map>,
}
impl Garden {
fn parse(input: &str) -> Self {
let mut blocks = input.split("\n\n");
let seeds = blocks.next().unwrap().strip_prefix("seeds: ").unwrap();
let maps = blocks.map(Map::parse).collect();
let simple_seeds = parse_ws_numbers(seeds);
let seed_ranges = simple_seeds
.iter()
.copied()
.tuples()
.map(|(start, length)| SeedRange { start, length })
.collect();
Self {
simple_seeds,
seed_ranges,
maps,
}
}
/// Look up n in every map.
fn map(&self, mut n: u64) -> u64 {
for map in &self.maps {
n = map.map(n);
}
n
}
}
#[derive(Debug)]
struct SeedRange {
start: u64,
length: u64,
}
#[derive(Debug)]
struct Map {
ranges: Vec<MappedRange>,
}
impl Map {
fn map(&self, n: u64) -> u64 {
for range in &self.ranges {
if let Some(mapped) = range.map(n) {
return mapped;
}
}
n
}
fn parse(block: &str) -> Self {
let lines = block.lines().skip(1);
let ranges = lines.map(MappedRange::parse).collect();
Self { ranges }
}
}
#[derive(Debug)]
struct MappedRange {
destination: u64,
source: u64,
length: u64,
}
impl MappedRange {
fn map(&self, n: u64) -> Option<u64> {
let source_start = self.source;
let source_end = source_start + self.length;
if (source_start..source_end).contains(&n) {
Some(n - source_start + self.destination)
} else {
None
}
}
fn parse(line: &str) -> Self {
let [destination, source, length] = parse_ws_numbers(line).try_into().unwrap();
Self {
destination,
source,
length,
}
}
}
fn parse_ws_numbers(s: &str) -> Vec<u64> {
s.split_ascii_whitespace()
.map(|s| s.parse().unwrap())
.collect()
}