105 lines
1.7 KiB
Crystal
105 lines
1.7 KiB
Crystal
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
|