class Array(T) def zip_with(other : Array(R), &block : T, R -> U) forall R, U dest = [] of U zip(other) do |l, r| dest << yield l, r end dest end def reduce_elementwise(&block) reduce do |l, r| l.zip_with(r) { |a, b| yield a, b } end end def union reduce(T.new) do |l, r| l | r end end def intersect reduce do |l, r| l & r end end def draw(width, maps) self.each_slice(width) do |slice| slice.each do |c| print maps[c] end puts end end def find_indices into = [] of Int32 each_with_index do |v, i| into << i if yield v end into end end struct Tuple(*T) def add(other : Tuple(*T)) {% begin %} { {% for t, i in T %} self[{{i}}] + other[{{i}}], {% end %} } {% end %} end def neg {% begin %} { {% for t, i in T %} -self[{{i}}], {% end %} } {% end %} end def sub(other : Tuple(*T)) add other.neg end def dot(other : Tuple(*T)) {% begin %} {% for t, i in T %} self[{{i}}] * other[{{i}}] + {% end %} 0 {% end %} end def reduce_fraction gcd = self[0].gcd self[1] return self if gcd == 0 { self[0]//gcd, self[1]//gcd} end def signum {% begin %} { {% for t, i in T %} self[{{i}}].signum, {% end %} } {% end %} end def abs end end struct Number def signum return 0 if self == 0 self // self.abs end end class Hash(K, V) def draw(maps) min_x, max_x = keys.minmax_of &.[0] min_y, max_y = keys.minmax_of &.[1] (max_y-min_y+1).times do |y| (max_x-min_x+1).times do |x| next unless has_key?({x,y}) print maps[self[{x,y}]] end puts end end end