42
votes
\$\begingroup\$

The problem:

I am the lead developer for a big company, we are making Skynet. I have been assigned to

Write a function that inputs and returns their sum

RULES: No answers like

function sum(a,b){
    return "their sum";
}

EDIT: The accepted answer will be the one with the most upvotes on January 1st, 2014

Note: This is a question. Please do not take the question and/or answers seriously. More information here.

\$\endgroup\$

closed as too broad by TheDoctor, WallyWest, Justin, user80551, squeamish ossifrage May 7 '14 at 12:42

Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

locked by Doorknob May 11 '14 at 22:35

This question exists because it has historical significance, but it is not considered a good, on-topic question for this site so please do not use it as evidence that you can ask similar questions here. This question and its answers are frozen and cannot be changed. See the help center for guidance on writing a good question.

Read more about locked posts here.

  • 31
    \$\begingroup\$ You can use my lightweight jQuery plugin: $.sum=function(a,b){return a+b};. \$\endgroup\$ – Blender Dec 28 '13 at 13:51
  • 5
    \$\begingroup\$ I knew I'd get a jQuery reference sometime \$\endgroup\$ – scrblnrd3 Dec 28 '13 at 13:51
  • 5
    \$\begingroup\$ Brilliant English :p \$\endgroup\$ – Martijn Courteaux Dec 28 '13 at 17:39
  • 5
    \$\begingroup\$ Question suggestion (not sure if it's any good): "GUISE HALP, I need a fast algorithm to generate bitcoin blocks!!!!! It's super urgent!" \$\endgroup\$ – user11485 Dec 28 '13 at 18:42
  • 5
    \$\begingroup\$ These answers are quite involved. I suggest opening a connection to your database and issuing 'SELECT ' + a + ' + ' + b + ';'. It's simple and understandable. \$\endgroup\$ – Nick Chammas Dec 28 '13 at 20:57

75 Answers 75

0
votes
\$\begingroup\$

Two's complement is overrated. This uses seven's complement with eleven digits, because seven and eleven are my favorite prime numbers and should be yours too.

// Adds two numbers -- beware of overflow for numbers greater than (7^11 - 7^10)!
function sum(a, b) {
    // Convert to seven's complement.
    var A = toSeven(a).split('');
    var B = toSeven(b).split('');

    // Addition algorithm.
    var sum = new Array(11);
    var carry = 0;
    for (var i = 10; i >= 0; i--) {
        sum[i] = (+A[i] + +B[i] + carry) % 7;
        carry = (+A[i] + +B[i] + carry) >= 7;
    }

    // Translate negative numbers.
    if (sum[0] === 6)
        return parseInt(sum.join(''), 7) - Math.pow(7, 11);
    return parseInt(sum.join(''), 7);
}

// Converts a number to seven's complement.
function toSeven(x) {
    if (x < 0)
        return toSeven(x + Math.pow(7, 11));
    return ('00000000000' + x.toString(7)).slice(-11);
}
\$\endgroup\$
0
votes
\$\begingroup\$

Python

You should never name a function sum, that will override the built-in function, sum()!

Have you looked at itertools? Itertools is always your answer

import itertools
def add(a, b):
    zipped = itertools.izip_longest(str(a), str(b))
    return itertools.starmap(lambda x, y: int.__add__(int(x), int(y)), zipped)

print ''.join(itertools.imap(str, list(add(3, 4))))
\$\endgroup\$
0
votes
\$\begingroup\$

The best way is to physically add a objects to b other objects. Then you can't go wrong. Here is a C function to do that. Note that o[] should be put outside the function to avoid stack overflow, because we want to use stack exchange.

#include<string.h>
char o[16777216];
int add(int a,int b)
{
    int c=0;
    strcpy(o,"");
    for(int i=0;i<a;i++) strcat(o,"a");
    for(int i=0;i<b;i++) strcat(o,"b");
    return strlen(o);
}
\$\endgroup\$
0
votes
\$\begingroup\$

C#

PS: The sum returned might not be correct depending on the input and the timing. If you think the sum is incorrect, please try to call it again until it returns correct result.

public static int Sum(int[] inputs) {
    return new Random().Next(inputs.Max() * 3);
}
\$\endgroup\$
0
votes
\$\begingroup\$

This is a very complicated task. I solved it using a new algorithm called Binary Column Addition. This Perl script takes the first two command line arguments and returns the sum:

#!/usr/bin/perl -w
use strict;
use warnings;

sub binarsum {
    my $first = $_[0];
    my $second = $_[1];

    if ($first == 0 && $second == 0) {
        return (0,0);
    }
    if (($first == 0 && $second == 1) || ($first == 1 && $second == 0)) {
        return (1,0);
    }
    if ($first == 1 && $second == 1) {
        return (1,1);
    }
}

sub tbr {
    my $first = $_[0];
    my @out = (0,0,0,0,0,0,0,0);

    my $rot = 0b00000001;

    foreach my $i (@out) {
        my $tmp = $first & $rot;

        if ($tmp == 0) {
            $i = 0;
        } else {
            $i = 1;
        }

        $rot = $rot << 1;
    }

    return @out;
}

sub fbr {
    my @in = @_;
    my $out = 0;

    foreach my $i (0..7) {
        if ($in[$i] == 1) {
            if ($i == 0) {
                $out += 1;
            }
            if ($i == 1) {
                $out += 2;
            }
            if ($i == 2) {
                $out += 4;
            }
            if ($i == 3) {
                $out += 8;
            }
            if ($i == 4) {
                $out += 16;
            }
            if ($i == 5) {
                $out += 32;
            }
            if ($i == 6) {
                $out += 64;
            }
            if ($i == 7) {
                $out += 128;
            }
        }
    }

    return $out;
}

sub sum {
    my @first = tbr($_[0]);
    my @second = tbr($_[1]);
    my @out = (0,0,0,0,0,0,0,0);
    my $overflow = 0;

    foreach my $i (0..7) {
        my $f = $first[$i];
        my $s = $second[$i];

        my @sum = binarsum($f,$s);

        if ($sum[0] == 0 && $overflow > 0) {
            $overflow--;
            $out[$i] = 1;
        }

        if ($sum[0] == 1 && $sum[1] == 0) {
            if($overflow % 2 == 0) {$out[$i] = 1;} else {$out[$i] = 0;};
        }

        if ($sum[0] == 1 && $sum[1] == 1) {
            if($overflow % 2 == 0) {$out[$i] = 0;$overflow++;} else {$out[$i] = 1};
        }
    }

    return fbr(@out);
}


print sum($ARGV[0],$ARGV[1]);
\$\endgroup\$
0
votes
\$\begingroup\$

This is a very complicated task. I solved it using a new algorithm called Binary Column Addition. This Perl script takes the first two command line arguments and returns the sum:

#!/usr/bin/perl -w
use strict;
use warnings;

sub binarsum {
    my $first = $_[0];
    my $second = $_[1];

    if ($first == 0 && $second == 0) {
        return (0,0);
    }
    if (($first == 0 && $second == 1) || ($first == 1 && $second == 0)) {
        return (1,0);
    }
    if ($first == 1 && $second == 1) {
        return (1,1);
    }
}

sub tbr {
    my $first = $_[0];
    my @out = (0,0,0,0,0,0,0,0);

    my $rot = 0b00000001;

    foreach my $i (@out) {
        my $tmp = $first & $rot;

        if ($tmp == 0) {
            $i = 0;
        } else {
            $i = 1;
        }

        $rot = $rot << 1;
    }

    return @out;
}

sub fbr {
    my @in = @_;
    my $out = 0;

    foreach my $i (0..7) {
        if ($in[$i] == 1) {
            if ($i == 0) {
                $out += 1;
            }
            if ($i == 1) {
                $out += 2;
            }
            if ($i == 2) {
                $out += 4;
            }
            if ($i == 3) {
                $out += 8;
            }
            if ($i == 4) {
                $out += 16;
            }
            if ($i == 5) {
                $out += 32;
            }
            if ($i == 6) {
                $out += 64;
            }
            if ($i == 7) {
                $out += 128;
            }
        }
    }

    return $out;
}

sub sum {
    my @first = tbr($_[0]);
    my @second = tbr($_[1]);
    my @out = (0,0,0,0,0,0,0,0);
    my $overflow = 0;

    foreach my $i (0..7) {
        my $f = $first[$i];
        my $s = $second[$i];

        my @sum = binarsum($f,$s);

        if ($sum[0] == 0 && $overflow > 0) {
            $overflow--;
            $out[$i] = 1;
        }

        if ($sum[0] == 1 && $sum[1] == 0) {
            if($overflow % 2 == 0) {$out[$i] = 1;} else {$out[$i] = 0;};
        }

        if ($sum[0] == 1 && $sum[1] == 1) {
            if($overflow % 2 == 0) {$out[$i] = 0;$overflow++;} else {$out[$i] = 1};
        }
    }

    return fbr(@out);
}


print sum($ARGV[0],$ARGV[1]);
\$\endgroup\$
0
votes
\$\begingroup\$

Ruby

I suggest an Object Oriented approach. The base class could be something like:

class Summer   
  attr_accessor :a, :b

  def initialize(a, b)
    @a = a
    @b = b
  end

  def sum
    @a.coerce(@b).inject(0, &:+)
  end

end

And then it's just a case of creating an instance of the Summer class with the proper arguments and send it the sum message.

\$\endgroup\$
0
votes
\$\begingroup\$

C++

Hello,

I see that you have received only answers ment to throw you off. What you have to understand is that computers represent numbers by binary digits and so they add the numbers by adding bit by bit.

Here is how you add 2 numbers. I wrote this as clean as possible and I have commented each line so that it is easy for you to understand the code.

#include <cstdint>

#include <iostream>
#include <vector>
#include <type_traits>

using std::cin;
using std::cout;
using std::endl;

// type for binary digit
using bit = uint8_t;

// class to represent an integral number as a vector of binary digits
// Integral template must be an Integral type
template <class Integral, class Enable = void>
class DigitsNumber;

// class to represent an integral number as a vector of binary digits
// Integral template must be an Integral type
template <typename Integral>
class DigitsNumber<Integral, typename std::enable_if<std::is_integral<Integral>::value>::type>{
  public:
    // the number of binary digits
    static const int kNumDigits = sizeof(Integral) * 8;

  private:
    // the vector of binary digits
    // index 0 is the index of  LSB the least significant bit
    std::vector<bit> digits = std::vector<bit>(kNumDigits);

  public:
    // default constructor, initializes to 0
    DigitsNumber();

    // copy constructor
    DigitsNumber(const DigitsNumber<Integral> &o2);
    // copy assignment
    DigitsNumber<Integral> &operator=(const DigitsNumber<Integral> &o2);

    // move constructor
    DigitsNumber(DigitsNumber<Integral> &&o2);
    // move assignment
    DigitsNumber<Integral> &operator=(DigitsNumber<Integral> &&o2);

    // constructor (and conversion) from Integral type
    DigitsNumber(Integral n);
    // conversion to Integral type
    operator Integral() const;

    // Sum
    template <class Integral>
    friend DigitsNumber<Integral> operator+(const DigitsNumber<Integral> &n1, const DigitsNumber<Integral> &n2);
};

// Sum
template <class Integral>
DigitsNumber<Integral> operator+(const DigitsNumber<Integral> &n1, const DigitsNumber<Integral> &n2);

// write to ostream
template <class Integral>
std::ostream &operator<<(std::ostream &os, const DigitsNumber<Integral> &n);

// default constructor, initializes to 0
template <class Integral>
DigitsNumber<Integral, typename std::enable_if<std::is_integral<Integral>::value>::type>::DigitsNumber()
    : DigitsNumber<Integral>(0) {
};

// copy constructor
template <class Integral>
DigitsNumber<Integral, typename std::enable_if<std::is_integral<Integral>::value>::type>::DigitsNumber(
      const DigitsNumber<Integral> &o2) : digits(o2.digits) {
}
// copy assignment
template <class Integral>
DigitsNumber<Integral> &DigitsNumber<Integral, typename std::enable_if<std::is_integral<Integral>::value>::type>::operator=(
      const DigitsNumber<Integral> &o2) {
  if (this == &o2) {
    return this;
  }
  digits = o2.digits;
  return *this;
}

// move constructor
template <class Integral>
DigitsNumber<Integral, typename std::enable_if<std::is_integral<Integral>::value>::type>::DigitsNumber(
      DigitsNumber<Integral> &&o2) : digits(std::forward<std::vector<bit> &&>(o2.digits)) {
}
// move assignment
template <class Integral>
DigitsNumber<Integral> &DigitsNumber<Integral, typename std::enable_if<std::is_integral<Integral>::value>::type>::operator=(
      DigitsNumber<Integral> &&o2) {
  digits = std::forward<std::vector<bit> &&>(o2.digits);
  return *this;
}

// constructor (and conversion) from Integral type
template <class Integral>
DigitsNumber<Integral, typename std::enable_if<std::is_integral<Integral>::value>::type>::DigitsNumber(Integral n) {
  for (int i = 0; i < kNumDigits; ++i) {
    digits[i] = n & 0x01;
    n >>= 1;
  }
}

// conversion to Integral type
template <class Integral>
DigitsNumber<Integral, typename std::enable_if<std::is_integral<Integral>::value>::type>::operator Integral() const {
  Integral n = 0;
  for (int i = kNumDigits - 1; i >= 0; --i) {
    n = (n << 1) | digits[i];
  }
  return n;
}

// Full binary adder
void AddWithCarry(bit op1, bit op2, bit carry_in, bit &sum, bit &carry_out) {
  sum =  op1 ^ (op2 ^ carry_in);
  carry_out = (op2 & carry_in) | (op1 & carry_in) | (op1 & op2);

}

// sum two DigitsNumber objects
template <class Integral>
DigitsNumber<Integral> operator+(const DigitsNumber<Integral> &n1, const DigitsNumber<Integral> &n2) {
  DigitsNumber<Integral> n;
  bit carry = 0;
  bit new_carry;


  for (int i = 0; i < n.kNumDigits; ++i) {
    AddWithCarry(n1.digits[i], n2.digits[i], carry, n.digits[i], new_carry);
    carry = new_carry;
  }
  return n;
}

// write DigitsNumber to ostream
template <class Integral>
std::ostream &operator<<(std::ostream &os, const DigitsNumber<Integral> &n) {
  os << (Integral) n;
  return os;
}

// Function to add 2 numbers
template <class Integral>
Integral Sum(Integral a, Integral b) {
  DigitsNumber<Integral> da = a;
  DigitsNumber<Integral> db = b;

  return da + db;
}

int main() {
  // Basic usage example of the Sum function
  cout << Sum(3, 10) << endl;
  cout << Sum(3, -10) << endl;

  return 0;
}

Bullet Points:

  • The class DigitsNumber is used to represent a number by a vector of it's binary digits.
  • The function void AddWithCarry(bit op1, bit op2, bit carry_in, bit &sum, bit &carry_out) implements a Full Adder http://en.wikipedia.org/wiki/Adder_(electronics)#Full_adder for binary digits using boolean algebra. That's how computers do it.
\$\endgroup\$
0
votes
\$\begingroup\$

jQuery / Backbone.js

Due to the complex nature of this problem, I will be employing high-level jQuery techniques. In addition to this, the function cannot be properly managed without a robust MVC-based architecture to handle server-side validation.

function sum(a, b, callback) {

  callback = callback || function(){};

  // As polluting the global namespace
  // would be unspeakable, it is best
  // advised to wrap all of your
  // code in 3 (three) self-executing
  // anonymous functions.
  function(a2, b2){
    function(a3, b3){
      function(a4, b4){

        // Run an initial validation on the numbers
        // to be sure we are actually dealing with numbers.
        // If we weren't, that would be very bad, and might
        // end up with....
        // NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN Watman!
        var NumberValidator = function(number) {

          var valid = false;

          if (!isNaN(number)) {

            if (number !== undefined) {

              if  (String(number).trim() !== '') {

                if (String(number).trim().toLowerCase().substr(0, 18) !== 'GREEN-EGGS-AND-HAM') {

                  // Okay, we're really good now.
                  valid = true;

                };

              };

            };

          };

          return valid;

        };

        // Set constants to make validity clear.
        var VALID_STATE_VALID = true;
        var VALID_STATE_INVALID = false;

        var aNumberIsValid, bNumberIsValid;
        aNumberIsValid = NumberValidator(a4);
        bNumberIsValid = NumberValidator(b4);

        // If we are invalid, ensure the caller of the function knows.
        if (aNumberIsValid === VALID_STATE_VALID && bNumberIsValid === VALID_STATE_VALID) {

          var responseMessage = {
            response: 'ERROR',
            data: 'Could not validate due to an invalidation of VALID_STATE_VALID'),
            message: 'INVALID_STATE_VALID',
          };

          callback(responseMessage);

        };

        // Fire the numbers off to a more complex server-side
        // validation service that ensures we are dealing with real
        // numbers and not somebody's trickery.
        var NumberIntegrityModel = Backbone.Model.extend({

          url: '/number-validation-service/transaction-persistor/execute',

          defaults: {
            a: false,
            b: false,
            valid: false,
          },

          parse: function(response) {

            if (response[0][0][1][6][5].response.transactionState !== 'ERROR') {

              return response[0][0][1][6][5].payload.transaction.results;
            }
          },

        });

        var numberIntegrityModel = new NumberIntegrityModel();

        numberIntegrityModel.on('save', function(){

          var valid = this.get('valid');

          if (val !== true) {

            var responseMessage = {
              response: 'ERROR',
              data: 'There is something seriously sketchy going on with those numbers. Investigate.'),
              message: 'INVALID_INTEGRITY_CHECK',
            };

            callback(responseMessage);

          } else {

            // Okay, we're actually dealing with two 
            // perfectly valid numbers. Now let's get to the 
            // number crunching.
            var varianceSpectrum = .5;
            var result = (a4 * (Math.floor(Math.sqrt(64) + (varianceSpectrum * (varianceSpectrum/2))) - (Math.pow(2, 3) - 1)) + b4);

            // I think this part is right.
            try() {
              'NaNNaNNaNNaNNaNNaN';
            } catch(e) {

              // Yeah, it must be. Works every time.
              callback({
                response: 'SUCCESS',
                data: result,
                message: 'LIKE_A_CHARM',
              });

            };

          };

        });

        numberIntegrityModel.save({
          a: a4,
          b: b4
        });

      }(a3, b3);
    }(a2, b2);
  }(a, b);
}

Not only is the architecture of my solution a jaw-dropping aesthetic, the implementation could not be bested.

sum(4, 5, function(result) {

  if (result.response == 'SUCCESS') {

    var sum = result.data;
    console.log(sum);
  }
});
\$\endgroup\$
0
votes
\$\begingroup\$

C++

#include <iostream>
#include <stdio.h>
#include <string.h>

std::string sum(std::string n1,std::string n2)
{
    int r1=0,d1,p;
    int size2 = n2.size()-1;
    char* ar = new char [size2+2];
    memset(ar,'0',size2+2);
    p= size2+1;

    for(int i= n1.size()-1; i >=0 ; --i)
    {
        d1 = n2.at(size2) + n1.at(i) - 96 + r1;
        ar[p--] += d1 % 10;
        r1 = d1 / 10;
        --size2;
    }

    for(int i=size2;i >=0;--i)
    {
        d1 = n2.at(i) + r1 - 48;
        ar[p--] += d1 % 10;
        r1 = d1 / 10;
    }

    ar[p--] += r1;

    std::string res = std::string(ar);
    delete [] ar;

    return res;
}

int main ()
{


    std::string n1;
    std::string n2;

    std::cout<< "First Number :" ;
    std::cin>> n1;
    std::cout<< "Second Number :" ;
    std::cin>> n2;




    if(n1.length()<n2.length())
        std::cout<< "Sum:" sum(n1,n2);
    else
        std::cout<< "Sum:" sum(n2,n1);

  return 0;
}
\$\endgroup\$
0
votes
\$\begingroup\$

Bash

Add the following lines to a file called .bashrc in your home directory.

add() {
    buffer=`mktemp -t addbuffer`
    seq $1 > $buffer
    yes | head -n $2 >> $buffer
    wc $buffer | sed -E 's/\s*([0-9]+).*/\1/'
    rm -f $buffer                                                                                                       
}

Now restart your system so that the changes can take effect.

Once you have rebooted you can do for instance add 1 2 and you will presented the answer 3.

\$\endgroup\$
0
votes
\$\begingroup\$

R (increment-decrement approach)

Let's first define the increment and decrement functions:

"-<-"<-function(x, value) x <- x-value
"+<-"<-function(x, value) x <- x+value

The first will be used to decrement a variable's value, and the second to increment it. Ok so far so good. Now the trick is to increment B and decrement A until very little is left.

addTwo <- function(A, B, STEP = 1) {
   while(A>=1) -A <- STEP -> + B
   c(sum = B, remainder= A)
   }

This approach works with all positive numbers. For those who care: the little something that remains in A after decrementing it, is also returned for future use. If you want, you can re-run the function with a smaller STEP (maybe start with 0.1) until the returned remainder is so small that you don't care any more.

\$\endgroup\$
0
votes
\$\begingroup\$

Python

This is the only obvious way to do it:

def add2nums(n1, n2):
    ''' # is the symbol for number '''
    return len(''.join('#' for _ in range(n1)) + ''.join('#' for _ in range(n2)))
\$\endgroup\$
0
votes
\$\begingroup\$

PYTHON

def sum(list):
    total = 0
    for i in list:
        total += i
    return total
\$\endgroup\$
  • \$\begingroup\$ How does this code troll the OP? \$\endgroup\$ – luser droog Jan 3 '14 at 6:10
0
votes
\$\begingroup\$

C++

#include <iostream>
using namespace std;
int main()
{
  int a, b, sum; 
  cin >> a >> b; 
  sum = a; 
  for(int i = 0; i < b; i++)
  {sum++;} 
  cout << sum << endl; 
  return 0;
}

This doesn't work on doubles, though.

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.