DEV Community

Cover image for Can you…? - Calculator
Medea
Medea

Posted on

Can you…? - Calculator

Can you make a calculator in any language which DOES NOT use the +, -, *, / operators.

Anyone who does will get a shoutout on my next Can you post.

Oldest comments (11)

Collapse
 
ben profile image
Ben Halpern

Too lazy to figure out how to deal with the remainder in division, but here is a cut at a calculator in Ruby that doesn't use math operators.

def add(num_1, num_2)
  [num_1, num_2].sum
end

def multiply(num_1, num_2)
  arr = []
  num_1.times do |n|
    arr << num_2
  end
  arr.sum
end

def subtract(num_1, num_2)
  subtractable = num_2.positive? ? "-#{num_2}".to_i : num_2.to_s.gsub("-", "").to_i
  [num_1, subtractable].sum
end

def divide(num_1, num_2)
  arr = []
  while num_1 >= num_2
    arr << "whatever"
    num_1 = subtract(num_1, num_2)
  end
  arr.size
end
Enter fullscreen mode Exit fullscreen mode
Collapse
 
vulcanwm profile image
Medea

Wow .sum is a function in Ruby? That made it so easy.

Collapse
 
ben profile image
Ben Halpern

Yeah, that's sort of a cheat — but Ruby's like that 🤣

eval("10 + 10") also would have been a quick answer here, but that seemed just a bit too easy.

Thread Thread
 
vulcanwm profile image
Medea • Edited

Oh- wow

Collapse
 
katafrakt profile image
Paweł Świątkowski • Edited

Okay, let's do this without using sum or eval then 🙃

module Calculator
  DivisionByZero = Class.new(RuntimeError)

  module_function

  def add(x,y) = y.abs.times.
    reduce(x) {|acc,_| y > 0 ? acc.next : acc.pred }

  def sub(x,y) = y.abs.times.
    reduce(x) {|acc,_| y > 0 ? acc.pred : acc.next }

  def mult(x,y) = y.abs.times.
    reduce(0) {|acc,_| add(acc,x)}.
    then {|num| y < 0 ? invert(num) : num } 

  def div(x,y) 
    raise DivisionByZero if y.zero?

    divisor = y.abs
    val = x.abs
    times = 0
    while sub(val,divisor) >= 0
      val = sub(val,divisor)
      times = times.next
    end
    times = x >= 0 ? times : invert(times)
    y >= 0 ? times : invert(times)
  end

  def invert(x) = x > 0 ? sub(0,x) : x.abs
end

require 'rspec'

RSpec.describe(Calculator) do
  specify { expect(Calculator.add(5,6)).to eq(11) } 
  specify { expect(Calculator.add(5,0)).to eq(5) } 
  specify { expect(Calculator.add(0,5)).to eq(5) } 
  specify { expect(Calculator.add(-5,5)).to eq(0) } 

  specify { expect(Calculator.sub(5,6)).to eq(-1) }
  specify { expect(Calculator.sub(5,1)).to eq(4) }
  specify { expect(Calculator.sub(0,1)).to eq(-1) }
  specify { expect(Calculator.sub(-5,2)).to eq(-7) }
  specify { expect(Calculator.sub(-5,-2)).to eq(-3) }
  specify { expect(Calculator.sub(5,-2)).to eq(7) }

  specify { expect(Calculator.mult(2,3)).to eq(6) }
  specify { expect(Calculator.mult(2,0)).to eq(0) }
  specify { expect(Calculator.mult(0,10)).to eq(0) }
  specify { expect(Calculator.mult(0,-10)).to eq(0) }
  specify { expect(Calculator.mult(1,-10)).to eq(-10) }
  specify { expect(Calculator.mult(-1,-10)).to eq(10) }

  specify { expect(Calculator.div(6,2)).to eq(3) }
  specify { expect(Calculator.div(6,6)).to eq(1) }
  specify { expect(Calculator.div(7,3)).to eq(2) }
  specify { expect(Calculator.div(-6,3)).to eq(-2) }
  specify { expect(Calculator.div(0,3)).to eq(0) }
  specify { expect(Calculator.div(6,-5)).to eq(-1) }
  specify { expect{ Calculator.div(6,0) }.to raise_error(Calculator::DivisionByZero) }
end
Enter fullscreen mode Exit fullscreen mode

I'm kind of not happy with div, but hard to do it nicely without introducing fractions.

cc @ben

Collapse
 
vulcanwm profile image
Medea

Woah this is really nice!

Collapse
 
ben profile image
Ben Halpern

Nice stuff!

Collapse
 
vulcanwm profile image
Medea

Is that a cheat lmao?

 
vulcanwm profile image
Medea

Great!!!