class NumberWithUncertainty
  def initialize(number, error)
    @num = number
    @err = error.abs
  end
  attr_reader :num, :err

  def +(other)
    if other.kind_of?(self.class)
      self.class.new(num + other.num, Math::hypot(err, other.err))
    else
      self.class.new(num + other, err)
    end
  end

  def -(other)
    if other.kind_of?(self.class)
      self.class.new(num - other.num, Math::hypot(err, other.err))
    else
      self.class.new(num - other, err)
    end
  end

  def *(other)
    if other.kind_of?(self.class)
      prod = num * other.num
      e = Math::hypot((prod * err / num), (prod * other.err / other.num))
      self.class.new(prod, e)
    else
      self.class.new(num * other, (err * other).abs)
    end
  end

  def /(other)
    if other.kind_of?(self.class)
      quo = num / other.num
      e = Math::hypot((quo * err / num), (quo * other.err / other.num))
      self.class.new(quo, e)
    else
      self.class.new(num / other, (err * other).abs)
    end
  end

  def **(exponent)
    Float(exponent) rescue raise ArgumentError, 
    prod = num ** exponent
    self.class.new(prod, (prod * exponent * err / num).abs)
  end

  def sqrt
    self ** 0.5
  end

  def to_s
    
  end
end

x1 = NumberWithUncertainty.new(100, 1.1)
y1 = NumberWithUncertainty.new( 50, 1.2)
x2 = NumberWithUncertainty.new(200, 2.2)
y2 = NumberWithUncertainty.new(100, 2.3)

puts ((x1 - x2) ** 2 + (y1 - y2) ** 2).sqrt