From 1ed36e1e14f980801c9143e59cacae4964f7a810 Mon Sep 17 00:00:00 2001 From: pareronia <49491686+pareronia@users.noreply.github.com> Date: Sat, 9 Dec 2023 23:28:02 +0100 Subject: [PATCH] AoC 2023 Day 5 - java --- README.md | 2 +- src/main/java/AoC2023_05.java | 174 ++++++++++++++++++++++++++++++++++ 2 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 src/main/java/AoC2023_05.java diff --git a/README.md b/README.md index bd27a536..b2d55513 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | | ---| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | python3 | [✓](src/main/python/AoC2023_01.py) | [✓](src/main/python/AoC2023_02.py) | [✓](src/main/python/AoC2023_03.py) | [✓](src/main/python/AoC2023_04.py) | [✓](src/main/python/AoC2023_05.py) | [✓](src/main/python/AoC2023_06.py) | [✓](src/main/python/AoC2023_07.py) | [✓](src/main/python/AoC2023_08.py) | [✓](src/main/python/AoC2023_09.py) | | | | | | | | | | | | | | | | | -| java | [✓](src/main/java/AoC2023_01.java) | [✓](src/main/java/AoC2023_02.java) | [✓](src/main/java/AoC2023_03.java) | [✓](src/main/java/AoC2023_04.java) | | [✓](src/main/java/AoC2023_06.java) | [✓](src/main/java/AoC2023_07.java) | [✓](src/main/java/AoC2023_08.java) | [✓](src/main/java/AoC2023_09.java) | | | | | | | | | | | | | | | | | +| java | [✓](src/main/java/AoC2023_01.java) | [✓](src/main/java/AoC2023_02.java) | [✓](src/main/java/AoC2023_03.java) | [✓](src/main/java/AoC2023_04.java) | [✓](src/main/java/AoC2023_05.java) | [✓](src/main/java/AoC2023_06.java) | [✓](src/main/java/AoC2023_07.java) | [✓](src/main/java/AoC2023_08.java) | [✓](src/main/java/AoC2023_09.java) | | | | | | | | | | | | | | | | | | bash | | | | | | | | | | | | | | | | | | | | | | | | | | | c++ | | | | | | | | | | | | | | | | | | | | | | | | | | | julia | | | | | | | | | | | | | | | | | | | | | | | | | | diff --git a/src/main/java/AoC2023_05.java b/src/main/java/AoC2023_05.java new file mode 100644 index 00000000..8e721b61 --- /dev/null +++ b/src/main/java/AoC2023_05.java @@ -0,0 +1,174 @@ +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Deque; +import java.util.List; +import java.util.function.Function; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +import com.github.pareronia.aoc.LongRange; +import com.github.pareronia.aoc.LongRange.JoinResult; +import com.github.pareronia.aoc.StringOps; +import com.github.pareronia.aoc.solution.Sample; +import com.github.pareronia.aoc.solution.Samples; +import com.github.pareronia.aoc.solution.SolutionBase; + +public final class AoC2023_05 + extends SolutionBase { + + private AoC2023_05(final boolean debug) { + super(debug); + } + + public static AoC2023_05 create() { + return new AoC2023_05(false); + } + + public static AoC2023_05 createDebug() { + return new AoC2023_05(true); + } + + @Override + protected Almanac parseInput(final List inputs) { + return Almanac.fromInput(inputs); + } + + private long solve(final Almanac almanac, final List seedRanges) { + return almanac.getLocation(seedRanges).stream() + .sorted() + .findFirst().orElseThrow() + .iterator().next(); + } + + @Override + public Long solvePart1(final Almanac almanac) { + log(almanac); + final List seedRanges + = almanac.seeds().stream() + .map(s -> LongRange.between(s.longValue(), s.longValue() + 1L)) + .toList(); + return solve(almanac, seedRanges); + } + + @Override + public Long solvePart2(final Almanac almanac) { + final List seeds = almanac.seeds(); + final List seedRanges + = Stream.iterate(0, i -> i < seeds.size(), i -> i + 2) + .map(i -> LongRange.between( + seeds.get(i).longValue(), + seeds.get(i).longValue() + seeds.get(i + 1).longValue())) + .toList(); + return solve(almanac, seedRanges); + } + + @Override + @Samples({ + @Sample(method = "part1", input = TEST, expected = "35"), + @Sample(method = "part2", input = TEST, expected = "46"), + }) + public void samples() { + } + + public static void main(final String[] args) throws Exception { + AoC2023_05.create().run(); + } + + record MappingParams(LongRange range, long diff) {} + + record Mapping(List ranges) { + + public List map(final List inps) { + final List ans = new ArrayList<>(); + final Deque q = new ArrayDeque<>(inps); + while(!q.isEmpty()) { + final LongRange inp = q.pop(); + boolean found = false; + for (final MappingParams r : ranges) { + final JoinResult result = inp.leftJoin(r.range()); + if (result.intersection().isPresent()) { + final LongRange intersection = result.intersection().get(); + ans.add(intersection.translate(r.diff())); + result.others().forEach(o -> q.add(o)); + found = true; + break; + } + } + if (!found) { + ans.add(inp); + } + } + return ans; + } + } + + record Almanac(List seeds, List mappings) { + + public static Almanac fromInput(final List input) { + final List> blocks = StringOps.toBlocks(input); + final List seeds = Arrays.stream( + blocks.get(0).get(0).split(": ")[1].split(" ")) + .map(Long::valueOf) + .toList(); + final Function getMappingParams = s -> { + final long[] x = Arrays.stream(s.split(" ")).mapToLong(Long::valueOf).toArray(); + return new MappingParams(LongRange.between(x[1], x[1] + x[2]), x[0] - x[1]); + }; + final List mappings = IntStream.range(1, blocks.size()) + .mapToObj(i -> { + final List ranges = + blocks.get(i).subList(1, blocks.get(i).size()).stream() + .map(line -> getMappingParams.apply(line)) + .toList(); + return new Mapping(ranges); + }) + .toList(); + return new Almanac(seeds, mappings); + } + + public List getLocation(final List seedRanges) { + List ans = new ArrayList<>(seedRanges); + for (final Mapping mapping : this.mappings) { + ans = mapping.map(ans); + } + return ans; + } + } + + private static final String TEST = """ + 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 + """; +} \ No newline at end of file