From 4d0fd9c17ecda29b80e9e828957df389868a20a6 Mon Sep 17 00:00:00 2001 From: lukasbicus Date: Fri, 11 Oct 2024 08:37:32 +0200 Subject: [PATCH 1/5] Add puzzle1 --- scripts/aoc2015/day24/input.txt | 28 +++++++++++++ scripts/aoc2015/day24/puzzle1.ts | 58 +++++++++++++++++++++++++++ scripts/aoc2015/day24/simpleInput.txt | 10 +++++ 3 files changed, 96 insertions(+) create mode 100644 scripts/aoc2015/day24/input.txt create mode 100644 scripts/aoc2015/day24/puzzle1.ts create mode 100644 scripts/aoc2015/day24/simpleInput.txt diff --git a/scripts/aoc2015/day24/input.txt b/scripts/aoc2015/day24/input.txt new file mode 100644 index 0000000..67ab0c3 --- /dev/null +++ b/scripts/aoc2015/day24/input.txt @@ -0,0 +1,28 @@ +1 +3 +5 +11 +13 +17 +19 +23 +29 +31 +37 +41 +43 +47 +53 +59 +67 +71 +73 +79 +83 +89 +97 +101 +103 +107 +109 +113 \ No newline at end of file diff --git a/scripts/aoc2015/day24/puzzle1.ts b/scripts/aoc2015/day24/puzzle1.ts new file mode 100644 index 0000000..ce53fc6 --- /dev/null +++ b/scripts/aoc2015/day24/puzzle1.ts @@ -0,0 +1,58 @@ +/* +--- Day 24: It Hangs in the Balance --- +It's Christmas Eve, and Santa is loading up the sleigh for this year's deliveries. However, there's one small problem: he can't get the sleigh to balance. If it isn't balanced, he can't defy physics, and nobody gets presents this year. + +No pressure. + +Santa has provided you a list of the weights of every package he needs to fit on the sleigh. +The packages need to be split into three groups of exactly the same weight, + and every package has to fit. + The first group goes in the passenger compartment of the sleigh, and the second and third go in containers on either side. + Only when all three groups weigh exactly the same amount will the sleigh be able to fly. + Defying physics has rules, you know! + +Of course, that's not the only problem. +The first group - the one going in the passenger compartment - needs as few packages as possible so that Santa has some legroom left over. + It doesn't matter how many packages are in either of the other two groups, so long as all of the groups weigh the same. + +Furthermore, Santa tells you, if there are multiple ways to arrange the packages such that the fewest possible are in the first group, +you need to choose the way where the first group has the smallest quantum entanglement to reduce the chance of any "complications". +The quantum entanglement of a group of packages is +the product of their weights, that is, the value you get when you multiply their weights together. + Only consider quantum entanglement if the first group has the fewest possible number of packages in it and all groups weigh the same amount. + +For example, suppose you have ten packages with weights 1 through 5 and 7 through 11. +For this situation, some of the unique first groups, their quantum entanglements, and a way to divide the remaining packages are as follows: + +Group 1; Group 2; Group 3 +11 9 (QE= 99); 10 8 2; 7 5 4 3 1 +10 9 1 (QE= 90); 11 7 2; 8 5 4 3 +10 8 2 (QE=160); 11 9; 7 5 4 3 1 +10 7 3 (QE=210); 11 9; 8 5 4 2 1 +10 5 4 1 (QE=200); 11 9; 8 7 3 2 +10 5 3 2 (QE=300); 11 9; 8 7 4 1 +10 4 3 2 1 (QE=240); 11 9; 8 7 5 +9 8 3 (QE=216); 11 7 2; 10 5 4 1 +9 7 4 (QE=252); 11 8 1; 10 5 3 2 +9 5 4 2 (QE=360); 11 8 1; 10 7 3 +8 7 5 (QE=280); 11 9; 10 4 3 2 1 +8 5 4 3 (QE=480); 11 9; 10 7 2 1 +7 5 4 3 1 (QE=420); 11 9; 10 8 2 +Of these, although 10 9 1 has the smallest quantum entanglement (90), the configuration with only two packages, 11 9, in the passenger compartment gives Santa the most legroom and wins. +In this situation, the quantum entanglement for the ideal configuration is therefore 99. Had there been two configurations with only two packages in the first group, the one with the smaller quantum entanglement would be chosen. + +What is the quantum entanglement of the first group of packages in the ideal configuration? + + + */ +// read packages weights in input +// sum weights and get weight for one group +// split packages to 3 groups, so common heights of packages is equal (several solutions possible) +// based on packages weights and group weight +// -> find first combination of packages, that +// -> should give GroupWeight together +// -> rest packages can be split to 2 equal groups + +// mark all combinations with lowest count of packages as group A +// compute quantum entanglement (QE) for all combinations +// pick lowest QE -> result diff --git a/scripts/aoc2015/day24/simpleInput.txt b/scripts/aoc2015/day24/simpleInput.txt new file mode 100644 index 0000000..957cf3a --- /dev/null +++ b/scripts/aoc2015/day24/simpleInput.txt @@ -0,0 +1,10 @@ +1 +2 +3 +4 +5 +7 +8 +9 +10 +11 \ No newline at end of file From 1041273ac9c58e6fbde7388bdedd7ad496fc9854 Mon Sep 17 00:00:00 2001 From: lukasbicus Date: Fri, 11 Oct 2024 09:15:51 +0200 Subject: [PATCH 2/5] Implement getPackagesGroupsWithSmallestLengths --- scripts/aoc2015/day24/puzzle1.ts | 33 ++++++++++++++- scripts/aoc2015/day24/utils.test.ts | 33 +++++++++++++++ scripts/aoc2015/day24/utils.ts | 62 +++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 scripts/aoc2015/day24/utils.test.ts create mode 100644 scripts/aoc2015/day24/utils.ts diff --git a/scripts/aoc2015/day24/puzzle1.ts b/scripts/aoc2015/day24/puzzle1.ts index ce53fc6..1785793 100644 --- a/scripts/aoc2015/day24/puzzle1.ts +++ b/scripts/aoc2015/day24/puzzle1.ts @@ -46,7 +46,38 @@ What is the quantum entanglement of the first group of packages in the ideal con */ // read packages weights in input -// sum weights and get weight for one group +const simpleInput = [1, 2, 3, 4, 5, 7, 8, 9, 10, 11]; +const input = [ + 1, + 3, + 5, + 11, + 13, + 17, + 19, + 23, + 29, + 31, + 37, + 41, + 43, + 47, + 53, + 59, + 67, + 71, + 73, + 79, + 83, + 89, + 97, + 101, + 103, + 107, + 109, + 113, +]; + // split packages to 3 groups, so common heights of packages is equal (several solutions possible) // based on packages weights and group weight // -> find first combination of packages, that diff --git a/scripts/aoc2015/day24/utils.test.ts b/scripts/aoc2015/day24/utils.test.ts new file mode 100644 index 0000000..288516e --- /dev/null +++ b/scripts/aoc2015/day24/utils.test.ts @@ -0,0 +1,33 @@ +import { assertEquals, assertThrows } from "@std/assert"; +import { describe, it } from "@std/testing/bdd"; +import { + getPackagesGroupsWithSmallestLengths, + isThereACombinationOfPackagesWithGivenWeight, +} from "./utils.ts"; + +describe("getPackagesGroupsWithSmallestLengths", function () { + it("should return one group for input", function () { + const simpleInput = [1, 2, 3, 4, 5, 7, 8, 9, 10, 11]; + assertEquals(getPackagesGroupsWithSmallestLengths(simpleInput), [[9, 11]]); + }); +}); + +describe("isThereACombinationOfPackagesWithGivenWeight", function () { + it("should return true for valid combination", function () { + assertEquals( + isThereACombinationOfPackagesWithGivenWeight([1, 2, 3, 4], 7), + true, + ); + assertEquals( + isThereACombinationOfPackagesWithGivenWeight([1, 2, 3, 4], 9), + true, + ); + }); + + it("should return false for valid combination", function () { + assertEquals( + isThereACombinationOfPackagesWithGivenWeight([1, 5, 7, 9], 4), + false, + ); + }); +}); diff --git a/scripts/aoc2015/day24/utils.ts b/scripts/aoc2015/day24/utils.ts new file mode 100644 index 0000000..43a1758 --- /dev/null +++ b/scripts/aoc2015/day24/utils.ts @@ -0,0 +1,62 @@ +// sum weights and get weight for one group +import { generateCombinationsWithoutRepetition } from "../day17/utils.ts"; + +function getWeightOfGroup(input: number[]): number { + return input.reduce(function (acc, i) { + return acc + i; + }, 0); +} + +export function isThereACombinationOfPackagesWithGivenWeight( + packages: number[], + givenWeight: number, +): boolean { + for (const combination of generateCombinationsWithoutRepetition(packages)) { + const combinationWeight = getWeightOfGroup(combination); + if (combinationWeight === givenWeight) { + return true; + } + } + return false; +} + +// split packages to 3 groups, so common heights of packages is equal (several solutions possible) +// based on packages weights and group weight +// -> find first combination of packages, that +// -> should give GroupWeight together +// -> rest packages can be split to 2 equal groups + +export function getPackagesGroupsWithSmallestLengths( + packages: number[], +): number[][] { + // return []; + const groupWeight = getWeightOfGroup(packages) / 3; + if (groupWeight !== Math.round(groupWeight)) { + throw new Error("Unable to form groups"); + } + const validCombinations: number[][] = []; + for ( + const combination of generateCombinationsWithoutRepetition( + [...packages].sort((a, b) => b - a), + ) + ) { + if (validCombinations.length > 0) { + if (combination.length > validCombinations[0].length) { + break; + } + } + const combinationWeight = getWeightOfGroup(combination); + if (combinationWeight !== groupWeight) { + continue; + } + const restPackages = packages.filter((p) => !combination.includes(p)); + // look for such a combination of rest packages, that it makes groupWeight again + if ( + isThereACombinationOfPackagesWithGivenWeight(restPackages, groupWeight) + ) { + validCombinations.push(combination.sort((a, b) => a - b)); + console.log(combination); + } + } + return validCombinations; +} From 613d079ce67586f18d7f917b1556aa4aee111c9c Mon Sep 17 00:00:00 2001 From: lukasbicus Date: Fri, 11 Oct 2024 09:21:18 +0200 Subject: [PATCH 3/5] Solve for simple input --- scripts/aoc2015/day24/puzzle1.ts | 21 +++++++++++++-------- scripts/aoc2015/day24/utils.ts | 6 ++++++ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/scripts/aoc2015/day24/puzzle1.ts b/scripts/aoc2015/day24/puzzle1.ts index 1785793..8ae6734 100644 --- a/scripts/aoc2015/day24/puzzle1.ts +++ b/scripts/aoc2015/day24/puzzle1.ts @@ -46,6 +46,8 @@ What is the quantum entanglement of the first group of packages in the ideal con */ // read packages weights in input +import { getPackagesGroupsWithSmallestLengths, getQEOfGroup } from "./utils.ts"; + const simpleInput = [1, 2, 3, 4, 5, 7, 8, 9, 10, 11]; const input = [ 1, @@ -78,12 +80,15 @@ const input = [ 113, ]; -// split packages to 3 groups, so common heights of packages is equal (several solutions possible) -// based on packages weights and group weight -// -> find first combination of packages, that -// -> should give GroupWeight together -// -> rest packages can be split to 2 equal groups +function getLowestQE(packages: number[]) { + // split packages to 3 groups, so common heights of packages is equal (several solutions possible) + // mark all combinations with lowest count of packages as group A + const theAGroups = getPackagesGroupsWithSmallestLengths(packages); + // compute quantum entanglement (QE) for all combinations + const QEs = theAGroups.map((group) => getQEOfGroup(group)); + // pick lowest QE -> result + console.log("minimum QE is: ", Math.min(...QEs)); +} -// mark all combinations with lowest count of packages as group A -// compute quantum entanglement (QE) for all combinations -// pick lowest QE -> result +// simpleInput test +getLowestQE(simpleInput); diff --git a/scripts/aoc2015/day24/utils.ts b/scripts/aoc2015/day24/utils.ts index 43a1758..151adc9 100644 --- a/scripts/aoc2015/day24/utils.ts +++ b/scripts/aoc2015/day24/utils.ts @@ -60,3 +60,9 @@ export function getPackagesGroupsWithSmallestLengths( } return validCombinations; } + +export function getQEOfGroup(input: number[]): number { + return input.reduce(function (acc, i) { + return acc * i; + }); +} From e2be3e5e572f2b60028349f03a76b69991bcc3a6 Mon Sep 17 00:00:00 2001 From: lukasbicus Date: Fri, 11 Oct 2024 09:35:07 +0200 Subject: [PATCH 4/5] Solve puzzle1 --- scripts/aoc2015/day24/puzzle1.ts | 6 +++++- scripts/aoc2015/day24/utils.ts | 18 +++++++++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/scripts/aoc2015/day24/puzzle1.ts b/scripts/aoc2015/day24/puzzle1.ts index 8ae6734..68f57d9 100644 --- a/scripts/aoc2015/day24/puzzle1.ts +++ b/scripts/aoc2015/day24/puzzle1.ts @@ -84,6 +84,8 @@ function getLowestQE(packages: number[]) { // split packages to 3 groups, so common heights of packages is equal (several solutions possible) // mark all combinations with lowest count of packages as group A const theAGroups = getPackagesGroupsWithSmallestLengths(packages); + + console.log("theAGroups", theAGroups); // compute quantum entanglement (QE) for all combinations const QEs = theAGroups.map((group) => getQEOfGroup(group)); // pick lowest QE -> result @@ -91,4 +93,6 @@ function getLowestQE(packages: number[]) { } // simpleInput test -getLowestQE(simpleInput); +// getLowestQE(simpleInput); +// solve for input +getLowestQE(input); diff --git a/scripts/aoc2015/day24/utils.ts b/scripts/aoc2015/day24/utils.ts index 151adc9..6b3b186 100644 --- a/scripts/aoc2015/day24/utils.ts +++ b/scripts/aoc2015/day24/utils.ts @@ -35,14 +35,15 @@ export function getPackagesGroupsWithSmallestLengths( throw new Error("Unable to form groups"); } const validCombinations: number[][] = []; + let theShortestCombinationLength: number | null = null; for ( const combination of generateCombinationsWithoutRepetition( [...packages].sort((a, b) => b - a), ) ) { - if (validCombinations.length > 0) { - if (combination.length > validCombinations[0].length) { - break; + if (theShortestCombinationLength !== null) { + if (combination.length > theShortestCombinationLength) { + continue; } } const combinationWeight = getWeightOfGroup(combination); @@ -55,10 +56,17 @@ export function getPackagesGroupsWithSmallestLengths( isThereACombinationOfPackagesWithGivenWeight(restPackages, groupWeight) ) { validCombinations.push(combination.sort((a, b) => a - b)); - console.log(combination); + if ( + theShortestCombinationLength === null || + combination.length < theShortestCombinationLength + ) { + theShortestCombinationLength = combination.length; + } + // console.log(combination); } } - return validCombinations; + const smallestLength = Math.min(...validCombinations.map((c) => c.length)); + return validCombinations.filter((c) => c.length === smallestLength); } export function getQEOfGroup(input: number[]): number { From 6d1e40048cc4595df12399681b4231b6447122bc Mon Sep 17 00:00:00 2001 From: lukasbicus Date: Fri, 11 Oct 2024 10:55:41 +0200 Subject: [PATCH 5/5] Solve puzzle2 --- scripts/aoc2015/day24/puzzle1.ts | 9 ++++++--- scripts/aoc2015/day24/utils.ts | 3 ++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/scripts/aoc2015/day24/puzzle1.ts b/scripts/aoc2015/day24/puzzle1.ts index 68f57d9..de6bf74 100644 --- a/scripts/aoc2015/day24/puzzle1.ts +++ b/scripts/aoc2015/day24/puzzle1.ts @@ -80,10 +80,10 @@ const input = [ 113, ]; -function getLowestQE(packages: number[]) { +function getLowestQE(packages: number[], groupCount = 3) { // split packages to 3 groups, so common heights of packages is equal (several solutions possible) // mark all combinations with lowest count of packages as group A - const theAGroups = getPackagesGroupsWithSmallestLengths(packages); + const theAGroups = getPackagesGroupsWithSmallestLengths(packages, groupCount); console.log("theAGroups", theAGroups); // compute quantum entanglement (QE) for all combinations @@ -95,4 +95,7 @@ function getLowestQE(packages: number[]) { // simpleInput test // getLowestQE(simpleInput); // solve for input -getLowestQE(input); +// getLowestQE(input); + +// solve puzzle2 for input +getLowestQE(input, 4); diff --git a/scripts/aoc2015/day24/utils.ts b/scripts/aoc2015/day24/utils.ts index 6b3b186..7c5bae1 100644 --- a/scripts/aoc2015/day24/utils.ts +++ b/scripts/aoc2015/day24/utils.ts @@ -28,9 +28,10 @@ export function isThereACombinationOfPackagesWithGivenWeight( export function getPackagesGroupsWithSmallestLengths( packages: number[], + groupCount = 3, ): number[][] { // return []; - const groupWeight = getWeightOfGroup(packages) / 3; + const groupWeight = getWeightOfGroup(packages) / groupCount; if (groupWeight !== Math.round(groupWeight)) { throw new Error("Unable to form groups"); }