From 524656c9f93b67f48e73d4e9cd2c9e268adb52f9 Mon Sep 17 00:00:00 2001 From: Andrej Orsula Date: Tue, 5 Dec 2023 23:38:50 +0100 Subject: [PATCH] aoc2023/day5: Refactor code Signed-off-by: Andrej Orsula --- README.md | 14 +++++----- aoc2023/Cargo.toml | 1 + aoc2023/src/day5.rs | 68 +++++++++++++++++++++------------------------ 3 files changed, 40 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index 5ac521a..6b59f6a 100644 --- a/README.md +++ b/README.md @@ -17,13 +17,13 @@ My solutions to [Advent of Code](https://adventofcode.com) puzzles. DayPart 1 PerformancePart 2 Performance -| D | Puzzle | Code | -| :---: | ---------------------------------------------------------------------- | :------------------------------: | -| 1 | [Trebuchet?!](https://adventofcode.com/2023/day/1) | [`day1.rs`](aoc2023/src/day1.rs) | -| 2 | [Cube Conundrum](https://adventofcode.com/2023/day/2) | [`day2.rs`](aoc2023/src/day2.rs) | -| 3 | [Gear Ratios](https://adventofcode.com/2023/day/3) | [`day3.rs`](aoc2023/src/day3.rs) | -| 4 | [Scratchcards](https://adventofcode.com/2023/day/4) | [`day4.rs`](aoc2023/src/day4.rs) | -| 5 | [If You Give A Seed A Fertilizer](https://adventofcode.com/2023/day/5) | [`day5.rs`](aoc2023/src/day5.rs) | +| D | Puzzle | Code | +| :---: | ------------------------------------------------------------- | :------------------------------: | +| 1 | [Trebuchet?!](https://adventofcode.com/2023/day/1) | [`day1.rs`](aoc2023/src/day1.rs) | +| 2 | [Cube Conundrum](https://adventofcode.com/2023/day/2) | [`day2.rs`](aoc2023/src/day2.rs) | +| 3 | [Gear Ratios](https://adventofcode.com/2023/day/3) | [`day3.rs`](aoc2023/src/day3.rs) | +| 4 | [Scratchcards](https://adventofcode.com/2023/day/4) | [`day4.rs`](aoc2023/src/day4.rs) | +| 5 | [If You Give A Seed ...](https://adventofcode.com/2023/day/5) | [`day5.rs`](aoc2023/src/day5.rs) | diff --git a/aoc2023/Cargo.toml b/aoc2023/Cargo.toml index f4e7857..325df9a 100644 --- a/aoc2023/Cargo.toml +++ b/aoc2023/Cargo.toml @@ -15,6 +15,7 @@ aoc-runner = { workspace = true } aoc-runner-derive = { workspace = true } indoc = { workspace = true } +itertools = { version = "0.12" } rayon = { version = "1.8" } regex = { version = "1.10" } smallvec = { version = "1.11" } diff --git a/aoc2023/src/day5.rs b/aoc2023/src/day5.rs index f3de5cf..7e15332 100644 --- a/aoc2023/src/day5.rs +++ b/aoc2023/src/day5.rs @@ -2,6 +2,8 @@ use aoc_runner_derive::{aoc, aoc_generator}; #[aoc_generator(day5)] fn parse(input: &str) -> utils::Almanac { + use itertools::Itertools; + let mut input_caterogies = input.split("\n\n"); let seeds = input_caterogies .next() @@ -14,13 +16,15 @@ fn parse(input: &str) -> utils::Almanac { .collect(); let mappings = input_caterogies .map(|category| { - let lines = category.lines().skip(1); - lines + category + .lines() + .skip(1) .map(|line| { - let mut numbers = line.split_ascii_whitespace(); - let destination_start = numbers.next().unwrap().parse().unwrap(); - let source_start = numbers.next().unwrap().parse().unwrap(); - let range_length = numbers.next().unwrap().parse().unwrap(); + let (destination_start, source_start, range_length) = line + .split_ascii_whitespace() + .map(|s| s.parse().unwrap()) + .next_tuple() + .unwrap(); utils::RangeMap { from: std::ops::Range { start: source_start, @@ -56,20 +60,14 @@ fn part1(input: &utils::Almanac) -> u64 { seeds .iter() .map(|&seed| { - let mut value = seed; - let mut min_location = u64::MAX; - for i in 0..mappings.len() { - for range_map in &mappings[i] { - if range_map.from.contains(&value) { - value = range_map.to.start + (value - range_map.from.start); - break; - } - } - if i == mappings.len() - 1 && value < min_location { - min_location = value; - } - } - min_location + mappings.iter().fold(seed, |value, mapping| { + mapping + .iter() + .find(|&range_map| range_map.from.contains(&value)) + .map_or(value, |range_map| { + value + range_map.to.start - range_map.from.start + }) + }) }) .min() .unwrap() @@ -82,24 +80,22 @@ fn part2(input: &utils::Almanac) -> u64 { let utils::Almanac { seeds, mappings } = input; seeds .chunks(2) - .map(|w| { - (w[0]..=w[0] + w[1]) + .map(|chunk| { + let (seed_range_start, seed_range_end) = (chunk[0], chunk[0] + chunk[1]); + seed_range_start..seed_range_end + }) + .map(|seed_range| { + seed_range .into_par_iter() .map(|seed| { - let mut value = seed; - let mut min_location = u64::MAX; - for i in 0..mappings.len() { - for range_map in &mappings[i] { - if range_map.from.contains(&value) { - value = range_map.to.start + (value - range_map.from.start); - break; - } - } - if i == mappings.len() - 1 && value < min_location { - min_location = value; - } - } - min_location + mappings.iter().fold(seed, |value, mapping| { + mapping + .iter() + .find(|&range_map| range_map.from.contains(&value)) + .map_or(value, |range_map| { + value + range_map.to.start - range_map.from.start + }) + }) }) .min() .unwrap()