DEV Community

Keff
Keff

Posted on

[Challenge] Add numbers without (+-*/)

Time for another casual little challenge.

For this one there are only 2 rules:

  • you must add numbers a and b together
  • you must NOT use the +-*/ operators

Apart from that there are no more rules, and can be done with any language you want!

Pseudocode:

a = 2
b = 32

add(a, b) => 34
Enter fullscreen mode Exit fullscreen mode

Test:

add(a, b) == a + b
Enter fullscreen mode Exit fullscreen mode

Have fun! Let's see what you come up with!

Latest comments (30)

Collapse
 
konung profile image
konung

Crystal or Ruby

def add(a, b)
  while b != 0
    carry = a & b
    a = a ^ b
    b = carry << 1
  end
  return a
end
Enter fullscreen mode Exit fullscreen mode
Collapse
 
migsarnavarro profile image
Migsar Navarro

js

const toArr = x => Array.from({ length: x });
const add = (a,b) =>  [...toArr(a), ...toArr(b)].length

add(2, 32); // return 34;
Enter fullscreen mode Exit fullscreen mode
Collapse
 
jonrandy profile image
Jon Randy 🎖️

Dangerous one:

const add = (a,b)=>eval(`${a}${String.fromCharCode(43)}${b}`)
Enter fullscreen mode Exit fullscreen mode
Collapse
 
jonrandy profile image
Jon Randy 🎖️ • Edited
const add=(a,b,c)=>{for(;b;c=a&b,a=a^b,b=c<<1);return a}
Enter fullscreen mode Exit fullscreen mode

A bit shorter (if you don't mind polluting namespace):

const add=(a,b)=>{for(;b;c=a&b,a=a^b,b=c<<1);return a}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
pyrsmk profile image
Aurélien Delogu

Here's another, more serious, attempt (still in Ruby) :

def add(a, b)
  (-a...b).size
end
Enter fullscreen mode Exit fullscreen mode

Some explanations : in Ruby 0..10 is called a range. It is really useful to make arbitrary loops or splice an array, for example. Simply, a range is a suite of values. The syntax I used here is 0...10 (note the three dots) which is an exclusive range : the suite of values goes from 0 to 9. So the trick is to have a range going from -a to b and excluding b because 0 is included in the suite.

Collapse
 
naveennamani profile image
naveennamani
a.__add__(b)
Enter fullscreen mode Exit fullscreen mode

In python

Collapse
 
pyrsmk profile image
Aurélien Delogu

Nice cheat :p

Collapse
 
object_required profile image
Nikolai Kim

Thank you for the challenge, I finally got into WebAssembly 🎉

async function makeAdd() {
  /*
   * (module
   *   (func $add (;0;) (export "add") (param $var0 f64) (param $var1 f64) (result f64)
   *     local.get $var0
   *     local.get $var1
   *     f64.add
   *   )
   * )
   */
  const response = await fetch("data:application/octet;base64,AGFzbQEAAAABBwFgAnx8AXwDAgEABwcBA2FkZAAACgkBBwAgACABoAs=")
  const buffer = await response.arrayBuffer()
  const { instance } = await WebAssembly.instantiate(buffer)

  return instance.exports.add
}

;(async function () {
  const add = await makeAdd()

  for (var a = -1; a <= 1; a += 1) {
    for (var b = -1; b <= 1; b += 1) {
      var s = add(a, b)
      var ok = s === a + b

      console[ok ? 'info' : 'warn'](`${ok ? '' : ''} add(${a}, ${b}) = ${s}`)
    }
  }
}())
Enter fullscreen mode Exit fullscreen mode
Collapse
 
armousness profile image
Sean Williams

I spent an unfortunate amount of time on this...

fn add(a: u32, b: u32) -> u32 {
    let mut carry = false;
    let mut result = 0;
    for i in 0..32 {
        let mask = 1 << i;
        let a_in = (a & mask) > 0;
        let b_in = (b & mask) > 0;
        let s =
            match (a_in, b_in, carry) {
                (false, false, true) => 1,
                (false, true, false) => 1,
                (true, false, false) => 1,
                (true, true, true) => 1,
                _ => 0,
            } << i;
        result = result | s;
        carry =
            match (a_in, b_in, &carry) {
                (false, true, true) => true,
                (true, false, true) => true,
                (true, true, false) => true,
                (true, true, true) => true,
                _ => false,
            };
    }
    result
}

fn main() {
    let a = 10521;
    let b = 830127;
    println!("the usual algorithm: {} + {} = {}", a, b, a + b);
    println!("the funky algorithm: {} + {} = {}", a, b, add(a, b));
}
Enter fullscreen mode Exit fullscreen mode

Output:

the usual algorithm: 10521 + 830127 = 840648
the funky algorithm: 10521 + 830127 = 840648
Enter fullscreen mode Exit fullscreen mode

This currently only works on unsigned integers. I don't feel like spending the time now to remember how two's complement works.

Collapse
 
armousness profile image
Sean Williams

Though I guess I'll be a bit more pedantic with this one: for i in 0..32 smuggles in some integer addition. So here's the set theoretic implementation, which has—less reliance on plus signs:

#[derive(Debug)]
enum Num {
    S(Box<Num>),
    Z,
}

fn s(n: Num) -> Num {
    Num::S(Box::new(n))
}

fn z() -> Num {
    Num::Z
}

fn set_add(a: Num, b: Num) -> Num {
    let mut result = a;
    let mut work = b;
    loop {
        match work {
            Num::S(next) => {
                result = s(result);
                work = *next;
            },
            Num::Z => return result,
        }
    }
}

fn main() {
    let a = s(s(s(z()))); // i.e., 3
    let b = s(s(s(s(s(z()))))); // i.e., 5
    println!("3 + 5 = {:?}", set_add(a, b));
}
Enter fullscreen mode Exit fullscreen mode

Output:

3 + 5 = S(S(S(S(S(S(S(S(Z))))))))
Enter fullscreen mode Exit fullscreen mode

Z means zero, and S means increment. So this is zero incremented eight times.

Collapse
 
lexlohr profile image
Alex Lohr
const add = (a, b) => Array(a).fill(0).concat(Array(b).fill(0)).length
Enter fullscreen mode Exit fullscreen mode
Collapse
 
lexlohr profile image
Alex Lohr
const add = (a, b) => `${' '.repeat(a)}${' '.repeat(b)}`.length
Enter fullscreen mode Exit fullscreen mode
Collapse
 
nombrekeff profile image
Keff

It kinda is nasty 🤣 I like it though