Solve day 5 part 1
This commit is contained in:
parent
ed8137d599
commit
5f70c0666c
2 changed files with 159 additions and 0 deletions
33
input/05-test
Normal file
33
input/05-test
Normal 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
126
src/bin/05.rs
Normal 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()
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue