-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Sheikh Mehdi
committed
Dec 19, 2024
1 parent
222cda3
commit 7995330
Showing
6 changed files
with
200 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
/* | ||
* BSD Zero Clause License | ||
* | ||
* Copyright (c) 2021-2024 zodac.me | ||
* | ||
* Permission to use, copy, modify, and/or distribute this software for any | ||
* purpose with or without fee is hereby granted. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR | ||
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
*/ | ||
|
||
package me.zodac.advent; | ||
|
||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
/** | ||
* Solution for 2024, Day 19. | ||
* | ||
* @see <a href="https://adventofcode.com/2024/day/19">[2024: 19] Linen Layout</a> | ||
*/ | ||
public final class Day19 { | ||
|
||
private Day19() { | ||
|
||
} | ||
|
||
/** | ||
* Given a {@link List} of values (representing a final 'design'), and a {@link List} of keys (representing a single 'towel' which is part of the | ||
* full design), find which values have a possible valid combination from the provided keys. | ||
* | ||
* @param towels the input keys (towels to make the designs) | ||
* @param finalDesigns the input values (designs) | ||
* @return the number of valid designs that can be created | ||
*/ | ||
public static long countPossibleDesigns(final List<String> towels, final List<String> finalDesigns) { | ||
return finalDesigns | ||
.stream() | ||
.filter(design -> hasDesignAnyValidCombinations(design, towels)) | ||
.count(); | ||
} | ||
|
||
/** | ||
* Given a {@link List} of values (representing a final 'design'), and a {@link List} of keys (representing a single 'towel' which is part of the | ||
* full design), find which values have a possible valid combination from the provided keys. For each of these, find the total number of possible | ||
* combinations of towels that can make the design. | ||
* | ||
* @param towels the input keys (towels to make the designs) | ||
* @param finalDesigns the input values (designs) | ||
* @return the total number of towel combinations to create valid designs | ||
*/ | ||
public static long countAllCombinationsOfValidDesigns(final List<String> towels, final List<String> finalDesigns) { | ||
return finalDesigns | ||
.stream() | ||
.filter(design -> hasDesignAnyValidCombinations(design, towels)) | ||
.mapToLong(design -> countCombinationsForDesign(design, towels, new HashMap<>())) | ||
.sum(); | ||
} | ||
|
||
private static boolean hasDesignAnyValidCombinations(final String value, final List<String> keys) { | ||
return keys | ||
.stream() | ||
.anyMatch(key -> value.equals(key) || (value.startsWith(key) && hasDesignAnyValidCombinations(value.substring(key.length()), keys))); | ||
} | ||
|
||
private static long countCombinationsForDesign(final String design, final List<String> towels, final Map<String, Long> cache) { | ||
if (cache.containsKey(design)) { | ||
return cache.get(design); | ||
} | ||
|
||
long numberOfCombinations = 0L; | ||
for (final String towel : towels) { | ||
if (design.equals(towel)) { | ||
numberOfCombinations++; | ||
} else if (design.startsWith(towel)) { | ||
numberOfCombinations += countCombinationsForDesign(design.substring(towel.length()), towels, cache); | ||
} | ||
} | ||
|
||
cache.put(design, numberOfCombinations); | ||
return numberOfCombinations; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
/* | ||
* BSD Zero Clause License | ||
* | ||
* Copyright (c) 2021-2024 zodac.me | ||
* | ||
* Permission to use, copy, modify, and/or distribute this software for any | ||
* purpose with or without fee is hereby granted. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR | ||
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
*/ | ||
|
||
package me.zodac.advent; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.Comparator; | ||
import java.util.List; | ||
import me.zodac.advent.input.InputReader; | ||
import org.junit.jupiter.api.Test; | ||
|
||
/** | ||
* Tests to verify answers for {@link Day19}. | ||
*/ | ||
class Day19Test { | ||
|
||
private static final String INPUT_FILENAME = "day19.txt"; | ||
|
||
@Test | ||
void example() { | ||
final List<List<String>> valuesRaw = InputReader | ||
.forExample(INPUT_FILENAME) | ||
.asStrings() | ||
.grouped() | ||
.byDelimiter(String::isBlank); | ||
|
||
final List<String> keys = parseKeys(valuesRaw); | ||
final List<String> values = valuesRaw.getLast(); | ||
|
||
final long part1Result = Day19.countPossibleDesigns(keys, values); | ||
assertThat(part1Result) | ||
.isEqualTo(6L); | ||
|
||
final long part2Result = Day19.countAllCombinationsOfValidDesigns(keys, values); | ||
assertThat(part2Result) | ||
.isEqualTo(16L); | ||
} | ||
|
||
@Test | ||
void part1() { | ||
final List<List<String>> valuesRaw = InputReader | ||
.forPuzzle(INPUT_FILENAME) | ||
.asStrings() | ||
.grouped() | ||
.byDelimiter(String::isBlank); | ||
|
||
final List<String> keys = parseKeys(valuesRaw); | ||
final List<String> values = valuesRaw.getLast(); | ||
|
||
final long part1Result = Day19.countPossibleDesigns(keys, values); | ||
assertThat(part1Result) | ||
.isEqualTo(263L); | ||
} | ||
|
||
@Test | ||
void part2() { | ||
final List<List<String>> valuesRaw = InputReader | ||
.forPuzzle(INPUT_FILENAME) | ||
.asStrings() | ||
.grouped() | ||
.byDelimiter(String::isBlank); | ||
|
||
final List<String> keys = parseKeys(valuesRaw); | ||
final List<String> values = valuesRaw.getLast(); | ||
|
||
final long part2Result = Day19.countAllCombinationsOfValidDesigns(keys, values); | ||
assertThat(part2Result) | ||
.isEqualTo(723_524_534_506_343L); | ||
} | ||
|
||
private static List<String> parseKeys(List<List<String>> valuesRaw) { | ||
final String[] keys = valuesRaw.getFirst().getFirst().split(", "); | ||
return new ArrayList<>(Arrays.asList(keys)).stream().sorted(Comparator.comparingInt(String::length).reversed()).toList(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
r, wr, b, g, bwu, rb, gb, br | ||
|
||
brwrr | ||
bggr | ||
gbbr | ||
rrbgbr | ||
ubwu | ||
bwurrg | ||
brgr | ||
bbrgwb |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Submodule advent-of-code-inputs
updated
from b9bd7d to 646437
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters