From 5382b4b0f14b80b05064d96947c20c43b89fefa9 Mon Sep 17 00:00:00 2001 From: Patrick Auernig Date: Wed, 3 Mar 2021 16:30:18 +0100 Subject: [PATCH] Update solution for 2015 day 17 Remove redundant recursion step in solution for part 1 This speeds up the solution and makes the marshalling unnecessary --- 2015/day-17/.gitignore | 1 - 2015/day-17/main.rb | 37 +++++++++---------------------------- 2 files changed, 9 insertions(+), 29 deletions(-) delete mode 100644 2015/day-17/.gitignore diff --git a/2015/day-17/.gitignore b/2015/day-17/.gitignore deleted file mode 100644 index bbd4ef0..0000000 --- a/2015/day-17/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.rbdump diff --git a/2015/day-17/main.rb b/2015/day-17/main.rb index 59a9137..ca67dbd 100755 --- a/2015/day-17/main.rb +++ b/2015/day-17/main.rb @@ -6,39 +6,18 @@ require "set" Container = Struct.new(:id, :cap) -# dumps result of previous solution to avoid recomputing -def memo(file) - dump_path = "#{file.basename}.rbdump" - - if File.exist?(dump_path) - File.open(dump_path, "rb") { |df| Marshal.load(df) } - else - File.open(dump_path, "wb") do |dumpfile| - result = yield - dumpfile.write(Marshal.dump(result)) - result - end - end -end - -# quite inefficient, probably needs a DP solution def combinations(amount, containers, stack = [], results = Set[]) - stack_sum = stack.sum { |x| x.cap } - - if stack_sum > amount - return results - elsif stack_sum == amount - results.add(stack.dup) - return results - end + next_sum = stack.sum(&:cap) + return results if next_sum > amount + return results.add(stack.dup) if next_sum == amount return results if containers.empty? containers.each_with_index do |container, idx| combinations(amount, containers[(idx+1)..], [*stack, container], results) end - combinations(amount, containers[1..], [], results) + results end def main(amount, file_paths) @@ -49,13 +28,15 @@ def main(amount, file_paths) containers = file_path.each_line.with_index.map { |x, i| Container.new(i, x.to_i) }.freeze - result = memo(file_path) { combinations(amount, containers) } + result = combinations(amount, containers) solution1 = result.size puts " Solution 1: #{solution1}" - solution2 = result.min_by { |x| x.size }.size - .then { |mincomb| result.select { |x| x.size == mincomb } } + solution2 = result + .group_by { |x| x.size } + .min { |(a, _), (b, _)| a <=> b } + .last .size puts " Solution 2: #{solution2}" end