advent/src/advent/util.cr

65 lines
1.0 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 union
reduce(T.new) do |l, r|
l | r
end
end
def intersect
reduce do |l, r|
l & r
end
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
end
struct Number
def signum
return 0 if self == 0
self // self.abs
end
end