קישור לחידה המקורית:
https://adventofcode.com/2018/day/8
פיתרון בשפת רובי:
$part1 = 0
class Metadata
attr_reader :value
def initialize(input)
md = input.match(/^(\d+)/)
@value = md[1].to_i
$part1 += value
input.slice!(0..md.end(0))
end
end
class Node
attr_accessor :header, :children
def initialize(input)
md = input.match(/^(\d+) (\d+)\s*/)
input.slice!(0, md.end(0))
self.header = []
self.children = []
_, @children_size, @header_size = *md.to_a.map(&:to_i)
@children_size.times do
@children << Node.new(input)
end
@header_size.times do
@header << Metadata.new(input)
end
end
def value
return header.map(&:value).sum if children.length == 0
res = 0
header.each do |entry|
ref = entry.value - 1
next if ref < 0
next if ref >= children.length
res += children[ref].value
end
res
end
end
root = Node.new(ARGF.first)
puts root.value
# puts $part1
שימו לב לתבנית של ה Parser בבנאי של Node - כל אוביקט לוקח את מה שהוא צריך מה input ואז מוחק את מה שלקח. בצורה כזאת הילדים יכולים ״לתקשר״ אחד עם השני בעת הבניה שלהם, כל ילד ״מודיע״ דרך העבודה על המידע המשותף כמה מידע הוא לקח.
החיבור הזה יוצר מצד אחד קוד מאוד קצר אבל מצד שני עלול לגרום לבעיות אם ילד אחד לוקח יותר מידע ממה שהיה צריך כי קשה למצוא איפה הטעות.