Add solutions to day21 and day22.
This commit is contained in:
parent
32895b3e17
commit
94ddabc590
31
day21.cr
Normal file
31
day21.cr
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
require "advent"
|
||||||
|
input = input(2020, 21).lines.map do |line|
|
||||||
|
data = line.match(/^([a-z ]+) \(contains (.+)\)$/).not_nil!
|
||||||
|
{data[1].split(" ").to_set, data[2].split(", ").to_set}
|
||||||
|
end
|
||||||
|
|
||||||
|
allergens = input.flat_map(&.last.to_a).to_set
|
||||||
|
ingredients = input.flat_map(&.first.to_a).to_set
|
||||||
|
|
||||||
|
allergen_sets = {} of String => Set(String)
|
||||||
|
allergens.each do |a|
|
||||||
|
input.each do |ings, als|
|
||||||
|
next unless als.includes? a
|
||||||
|
allergen_sets[a] ||= ings
|
||||||
|
allergen_sets[a] &= ings
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
safe = ingredients.reject { |i| allergen_sets.any? &.last.includes?(i) }
|
||||||
|
puts "Part 1: #{input.sum &.first.count { |i| safe.includes? i }}"
|
||||||
|
|
||||||
|
known_allergens = {} of String => String
|
||||||
|
while allergen_sets.size > known_allergens.size
|
||||||
|
allergen_sets.each do |a, s|
|
||||||
|
next unless s.size == 1
|
||||||
|
new_known = s.first
|
||||||
|
known_allergens[a] = new_known
|
||||||
|
allergen_sets.each &.last.delete(new_known)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
puts "Part 2: #{known_allergens.to_a.sort_by(&.first).map(&.last).join(",")}"
|
66
day22.cr
Normal file
66
day22.cr
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
require "advent"
|
||||||
|
first, second = input(2020, 22).split("\n\n")
|
||||||
|
first = first.lines[1..].map &.to_i32
|
||||||
|
second = second.lines[1..].map &.to_i32
|
||||||
|
|
||||||
|
class Array(T)
|
||||||
|
def pop_left
|
||||||
|
delete_at(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
def score
|
||||||
|
total = 0
|
||||||
|
s = size
|
||||||
|
each_with_index do |n, i|
|
||||||
|
total += n * (s - i)
|
||||||
|
end
|
||||||
|
total
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def no_rec(deck1, deck2)
|
||||||
|
while !deck1.empty? && !deck2.empty?
|
||||||
|
f, s = deck1.delete_at(0), deck2.delete_at(0)
|
||||||
|
if f > s
|
||||||
|
deck1 << f << s
|
||||||
|
else
|
||||||
|
deck2 << s << f
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return !deck1.empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
def rec(deck1, deck2)
|
||||||
|
seen = Set({Int32, Int32}).new
|
||||||
|
while !deck1.empty? && !deck2.empty?
|
||||||
|
key = {deck1.score, deck2.score}
|
||||||
|
return true if seen.includes?(key)
|
||||||
|
seen << key
|
||||||
|
|
||||||
|
f = deck1.delete_at(0)
|
||||||
|
s = deck2.delete_at(0)
|
||||||
|
|
||||||
|
p1wins = (f <= deck1.size) && (s <= deck2.size) ? rec(deck1[0..f-1], deck2[0..s-1]) : f > s
|
||||||
|
if p1wins
|
||||||
|
deck1 << f << s
|
||||||
|
else
|
||||||
|
deck2 << s << f
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return !deck1.empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
def run(first, second, proc)
|
||||||
|
((proc.call(first, second)) ? first : second).score
|
||||||
|
end
|
||||||
|
|
||||||
|
def part1(input)
|
||||||
|
run(input[0], input[1], ->no_rec(Array(Int32), Array(Int32)))
|
||||||
|
end
|
||||||
|
|
||||||
|
def part2(input)
|
||||||
|
run(input[0], input[1], ->rec(Array(Int32), Array(Int32)))
|
||||||
|
end
|
||||||
|
|
||||||
|
puts part1({first, second}.clone)
|
||||||
|
puts part2({first, second}.clone)
|
Loading…
Reference in New Issue
Block a user