|
| 1 | +package com.macasaet; |
| 2 | + |
| 3 | +import org.junit.jupiter.api.Test; |
| 4 | + |
| 5 | +import java.util.ArrayList; |
| 6 | +import java.util.Collections; |
| 7 | +import java.util.HashSet; |
| 8 | +import java.util.List; |
| 9 | +import java.util.Set; |
| 10 | +import java.util.stream.Stream; |
| 11 | +import java.util.stream.StreamSupport; |
| 12 | + |
| 13 | +/** |
| 14 | + * --- Day 3: Rucksack Reörganisation --- |
| 15 | + * https://adventofcode.com/2022/day/3 |
| 16 | + */ |
| 17 | +public class Day03 { |
| 18 | + |
| 19 | + protected static int priority(final char c) { |
| 20 | + if (c >= 'a' && c <= 'z') { |
| 21 | + return c - 'a' + 1; |
| 22 | + } |
| 23 | + return c - 'A' + 27; |
| 24 | + } |
| 25 | + |
| 26 | + protected Stream<Rucksack> getInput() { |
| 27 | + return StreamSupport |
| 28 | + .stream(new LineSpliterator("day-03.txt"), |
| 29 | + false) |
| 30 | + .map(Rucksack::parse); |
| 31 | + } |
| 32 | + |
| 33 | + @Test |
| 34 | + public final void part1() { |
| 35 | + final var result = getInput().mapToInt(Rucksack::priority).sum(); |
| 36 | + |
| 37 | + System.out.println("Part 1: " + result); |
| 38 | + } |
| 39 | + |
| 40 | + @Test |
| 41 | + public final void part2() { |
| 42 | + final var groups = new ArrayList<List<Rucksack>>(); |
| 43 | + var currentGroup = new ArrayList<Rucksack>(3); |
| 44 | + |
| 45 | + for (final var i = getInput().iterator(); i.hasNext(); ) { |
| 46 | + final var rucksack = i.next(); |
| 47 | + if (currentGroup.size() == 3) { |
| 48 | + groups.add(Collections.unmodifiableList(currentGroup)); |
| 49 | + currentGroup = new ArrayList<>(3); |
| 50 | + } |
| 51 | + currentGroup.add(rucksack); |
| 52 | + } |
| 53 | + if (currentGroup.size() == 3) { |
| 54 | + groups.add(Collections.unmodifiableList(currentGroup)); |
| 55 | + } |
| 56 | + final var result = groups.stream().map(this::getBadge).mapToInt(Day03::priority).sum(); |
| 57 | + |
| 58 | + System.out.println("Part 2: " + result); |
| 59 | + } |
| 60 | + |
| 61 | + protected char getBadge(final List<? extends Rucksack> group) { |
| 62 | + final var first = group.get(0); |
| 63 | + for (final var item : first.allItems()) { |
| 64 | + if (group.get(1).allItems().contains(item) && group.get(2).allItems().contains(item)) { |
| 65 | + return item; |
| 66 | + } |
| 67 | + } |
| 68 | + throw new IllegalStateException(); |
| 69 | + } |
| 70 | + |
| 71 | + /** |
| 72 | + * An Elf's container of supplies for a jungle journey. "Each rucksack has two large compartments. All items of a |
| 73 | + * given type are meant to go into exactly one of the two compartments." |
| 74 | + * |
| 75 | + * @param firstCompartment All the items in one compartment |
| 76 | + * @param secondCompartment All the items in one compartment |
| 77 | + * @param allItems All the items |
| 78 | + */ |
| 79 | + public record Rucksack(Set<Character> firstCompartment, Set<Character> secondCompartment, Set<Character> allItems) { |
| 80 | + |
| 81 | + public static Rucksack parse(final String line) { |
| 82 | + final var chars = line.toCharArray(); |
| 83 | + if (chars.length % 2 != 0) { |
| 84 | + throw new IllegalArgumentException(); |
| 85 | + } |
| 86 | + final var firstCompartment = new HashSet<Character>(chars.length / 2); |
| 87 | + final var secondCompartment = new HashSet<Character>(chars.length / 2); |
| 88 | + for (int i = 0; i < chars.length / 2; i++) { |
| 89 | + firstCompartment.add(chars[i]); |
| 90 | + } |
| 91 | + for (int i = chars.length / 2; i < chars.length; i++) { |
| 92 | + secondCompartment.add(chars[i]); |
| 93 | + } |
| 94 | + final var union = new HashSet<Character>(chars.length); |
| 95 | + union.addAll(firstCompartment); |
| 96 | + union.addAll(secondCompartment); |
| 97 | + return new Rucksack(Collections.unmodifiableSet(firstCompartment), |
| 98 | + Collections.unmodifiableSet(secondCompartment), |
| 99 | + Collections.unmodifiableSet(union)); |
| 100 | + } |
| 101 | + |
| 102 | + public int priority() { |
| 103 | + final var intersection = new HashSet<Character>(); |
| 104 | + for (final char c : firstCompartment) { |
| 105 | + if (secondCompartment.contains(c)) { |
| 106 | + intersection.add(c); |
| 107 | + } |
| 108 | + } |
| 109 | + if (intersection.size() != 1) { |
| 110 | + throw new IllegalStateException("There should only be one common item between compartments"); |
| 111 | + } |
| 112 | + return Day03.priority(intersection.iterator().next()); |
| 113 | + } |
| 114 | + |
| 115 | + |
| 116 | + } |
| 117 | +} |
0 commit comments