class Vector

def self.[](x, y)

def self.[](x, y)
  new x, y
end

def *(scalar)

def *(scalar)
  Vector[@x * scalar, @y * scalar]
end

def +(other)

def +(other)
  Vector[@x + other.x, @y + other.y]
end

def +@

def +@
  self
end

def -(other)

def -(other)
  Vector[@x - other.x, @y - other.y]
end

def -@

def -@
  self * -1
end

def /(scalar)

def /(scalar)
  Vector[@x / scalar, @y / scalar]
end

def angle

def angle
  Math::atan2 @y, @x
end

def cross(other)

def cross(other)
  perp.dot other
end

def dot(other)

def dot(other)
  @x * other.x + @y * other.y
end

def initialize(x, y)

def initialize(x, y)
  @x, @y = x, y
  freeze
end

def inspect

def inspect
  "{%s, %s}" % [@x, @y]
end

def norm

def norm
  Math::sqrt(dot self)
end

def normalised

def normalised
  self / norm
end

def perp

def perp
  Vector[-@y, @x]
end

def proj(other)

def proj(other)
  dot(other) / other.norm
end

def rotate_by(angle)

def rotate_by(angle)
  cos = Math::cos(angle)
  sin = Math::sin(angle)
  Vector[@x * cos - @y * sin, @x * sin + @y * cos]
end

def rotate_by_degrees(angle)

def rotate_by_degrees(angle)
  rotate_by(angle * Math::PI / 180.0)
end

def to_ary

def to_ary
  [@x, @y]
end

def to_d

def to_d
  Vector[@x.to_d, @y.to_d]
end

def to_f

def to_f
  Vector[@x.to_f, @y.to_f]
end