[2020][ruby][20.1]
change ozpztnntkuzrzryupntxmmtmtrrkwktk
commit 21c5ddd4211defa0bbafd268c22281ac25906aa7
author Alpha Chen <alpha@kejadlen.dev>
date
parent szzktvoz
diff --git a/2020/ruby/day_20.rb b/2020/ruby/day_20.rb
new file mode 100644
index 0000000..7c89960
--- /dev/null
+++ b/2020/ruby/day_20.rb
@@ -0,0 +1,55 @@
+class Tile
+  SIZE = 10
+
+  attr_reader :raw
+
+  def initialize(raw)
+    @raw = raw
+  end
+
+  def edges
+    {
+      top: @raw.fetch(0),
+      bottom: @raw.fetch(SIZE-1),
+      left: @raw.transpose.fetch(0),
+      right: @raw.transpose.fetch(SIZE-1),
+    }
+  end
+
+  def to_s
+    @raw.map(&:join).join("\n")
+  end
+end
+
+input = ARGF.read
+  .scan(/Tile (\d+):\n((?:[.#]+\n)+)/m)
+  .to_h
+  .transform_keys(&:to_i)
+  .transform_values {|v| v.split("\n").map {|row| row.chars } }
+  .transform_values {|v| Tile.new(v) }
+
+edges = input.flat_map {|id,tile|
+  tile.edges.map {|edge,data| ["#{id}_#{edge}", data.join] }
+}.to_h
+
+inverted_edges = edges.each.with_object(Hash.new {|h,k| h[k] = [] }) do |(id,data),hash|
+  hash[data] << id
+end
+
+matches = edges.map {|id,data|
+  [
+    id,
+    [
+      inverted_edges[data],
+      inverted_edges[data.reverse],
+    ].flatten.compact.reject {|other| other == id },
+  ]
+}.to_h
+
+corners = input.keys.select {|id|
+  %w[ top bottom left right ].count {|edge|
+    matches.fetch("#{id}_#{edge}").empty?
+  } == 2
+}
+
+p corners.inject(&:*)