Skip to content

Instantly share code, notes, and snippets.

@wconrad
Created December 16, 2015 01:57
Show Gist options
  • Select an option

  • Save wconrad/f6ea3e84eb30a1752fbc to your computer and use it in GitHub Desktop.

Select an option

Save wconrad/f6ea3e84eb30a1752fbc to your computer and use it in GitHub Desktop.
Advent of Code, day 15
# http://adventofcode.com/day/15
require "forwardable"
Ingredient = Struct.new(:coefficients, :calories)
class Ingredients
extend Forwardable
def initialize
@ingredients = []
end
def_delegators :@ingredients, :<<, :size
def score(amounts)
amounts.zip(@ingredients).map do |amount, ingredient|
ingredient.coefficients.map do |coefficient|
amount * coefficient
end
end.transpose.map do |a|
a.reduce(&:+)
end.map do |factor|
[factor, 0].max
end.reduce(&:*)
end
def calories(amounts)
amounts.zip(@ingredients).map do |amount, ingredient|
amount * ingredient.calories
end.reduce(&:+)
end
end
def digits_adding_up_to(num_digits:, sum:)
f = ->(yielder, digits = []) do
if digits.size == num_digits - 1
yielder.yield(digits + [sum - digits.reduce(0, &:+)])
else
digit_max = sum - digits.reduce(0, &:+)
(1..(digit_max - 1)).each do |digit|
f.(yielder, digits + [digit])
end
end
end
Enumerator.new { |yielder| f.(yielder) }
end
def amounts_enum
digits_adding_up_to(num_digits: @ingredients.size, sum: 100)
end
def parse(file)
ingredients = Ingredients.new
file.each_line.each do |line|
*coefficients, calories = line.scan(/-?\d+/).map do |s|
Integer(s)
end
ingredients << Ingredient.new(coefficients, calories)
end
ingredients
end
@ingredients = File.open("input", "r") { |file| parse(file) }
# part 1
best_score = amounts_enum.map do |amounts|
@ingredients.score(amounts)
end.max
puts best_score
# part 2
best_score = amounts_enum.select do |amounts|
@ingredients.calories(amounts) == 500
end.map do |amounts|
@ingredients.score(amounts)
end.max
puts best_score
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment