diff options
author | Justin Wernick <justin@worthe-it.co.za> | 2024-10-21 19:39:24 +0200 |
---|---|---|
committer | Justin Wernick <justin@worthe-it.co.za> | 2024-10-21 19:39:24 +0200 |
commit | 893421f95f86c0ae61862b1014388a471693c5cf (patch) | |
tree | 6592582bb453f4f40dca69f977c22d8222bdf04f /2015/day24.exs | |
parent | 9fb42bf830560502aaf5acb3241c3bc8b53a35c2 (diff) |
Day 24
Diffstat (limited to '2015/day24.exs')
-rw-r--r-- | 2015/day24.exs | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/2015/day24.exs b/2015/day24.exs new file mode 100644 index 0000000..576b8e8 --- /dev/null +++ b/2015/day24.exs @@ -0,0 +1,96 @@ +packages = + File.stream!("inputs/day24.txt") + |> Enum.map(fn line -> + {num, ""} = String.trim(line) |> Integer.parse() + num + end) + +defmodule SleighPacker do + def canMakeSecondPile(_, 0) do + true + end + + def canMakeSecondPile([], _) do + false + end + + def canMakeSecondPile([next | remainingPackages], remainingWeight) do + canMakeSecondPile(remainingPackages, remainingWeight - next) || + canMakeSecondPile(remainingPackages, remainingWeight) + end + + def packagesCanBeSplitEvenly(rejectedPackages, piles) do + weightPerPile = div(Enum.sum(rejectedPackages), piles) + # This gave me the right answer for part 2, but that seems to just be a + # lucky detail. You probably need to make sure that you can make all of the + # remaining piles until it's the last two being split. + canMakeSecondPile(rejectedPackages, weightPerPile) + end + + def findBestSmallestPile(remainingPackages, 0, rejectedPackages, piles) do + if packagesCanBeSplitEvenly(remainingPackages ++ rejectedPackages, piles - 1) do + [] + else + nil + end + end + + def findBestSmallestPile([], _, _, _) do + nil + end + + def findBestSmallestPile([next | remainingPackages], remainingWeight, rejectedPackages, piles) + when next > remainingWeight do + findBestSmallestPile(remainingPackages, remainingWeight, [next | rejectedPackages], piles) + end + + def findBestSmallestPile([next | remainingPackages], remainingWeight, rejectedPackages, piles) do + withNextTail = + findBestSmallestPile(remainingPackages, remainingWeight - next, rejectedPackages, piles) + + withNext = + if withNextTail == nil do + nil + else + [next | withNextTail] + end + + withoutNext = + findBestSmallestPile(remainingPackages, remainingWeight, [next | rejectedPackages], piles) + + cond do + withNext == nil && withoutNext == nil -> + nil + + withNext == nil -> + withoutNext + + withoutNext == nil -> + withNext + + length(withNext) == length(withoutNext) -> + if Enum.product(withNext) < Enum.product(withoutNext) do + withNext + else + withoutNext + end + + length(withNext) < length(withoutNext) -> + withNext + + true -> + withoutNext + end + end + + def packTheSleigh(packages, piles) do + weightPerPile = div(Enum.sum(packages), piles) + findBestSmallestPile(packages, weightPerPile, [], piles) + end +end + +threePack = SleighPacker.packTheSleigh(packages, 3) +IO.puts("Product with three piles: #{Enum.product(threePack)}") + +fourPack = SleighPacker.packTheSleigh(packages, 4) +IO.puts("Product with four piles: #{Enum.product(fourPack)}") |