You have to take 2 string inputs and output the sum of these two strings without converting them to int or using any numeric data type.


string one = "123";
string two = "456";    
string sum = "579";

Assume the strings won't be larger than 10 digits.

This is code golf and shortest answer in characters wins. An edit to the answer in C# will make me smile :).

Edit: Converting to int can be defined as anything of this nature

Int.TryParse, (int), Convert.ToInt etc

  • 2
    \$\begingroup\$ Can we use numbers elsewhere in our code as long as we are not converting the strings to numbers ? \$\endgroup\$
    – Optimizer
    Commented Nov 24, 2014 at 20:52
  • 6
    \$\begingroup\$ What is defined as converting them to int, as opposed to interpreting them as int? \$\endgroup\$
    – Compass
    Commented Nov 24, 2014 at 20:57
  • 5
    \$\begingroup\$ I'm still not entirely clear how much we can do with character codes? Can we subtract character codes? Can we convert individual digits to their character codes? \$\endgroup\$ Commented Nov 24, 2014 at 21:40
  • 6
    \$\begingroup\$ @user15681218 Sure it can. But it's not entirely clear from your rules what exactly we can and cannot do. \$\endgroup\$ Commented Nov 24, 2014 at 21:56
  • 2
    \$\begingroup\$ I don't think that this question is a dupe of Add without addition (or any of the 4 basic arithmetic operators) . In fact, this question is more similar to this multiply without numbers question than the add without addition. The multiply question was also initially considered as a dupe of add without addition. \$\endgroup\$
    – Optimizer
    Commented Nov 25, 2014 at 7:17

15 Answers 15


80836 Assembly (57 53 bytes)

53 55 89 E5 8B 4D 0C 8B 55 10 B0 0A 30 DB 88 CF 00 C1 00 C2 49 4A 8A 01 8A 22 00 E0 00 D8 2C 30 30 DB 3C 39 7E 04 B3 01 2C 0A 88 01 88 22 38 CF 75 E2 5D 5B C3

This adds, digit by digit, right to left, without converting ascii digits '0'-'9' to the integers 0-9, and carrying over as needed. The bytecode is the code for a function, which may be called in C (see below).

The above bytecode was written by hand, from the following assembly (NASM-style, commented):

; save ebx, ebp
push ebx        ; 53
push ebp        ; 55
; copy esp
mov ebp, esp    ; 8B EC
; load arguments
mov ecx, [ebp+0x0C] ; 8B 4D 0C
mov edx, [ebp+0x10] ; 8B 55 10
; initialize stuff
mov al, 10      ; B0 0A
xor bl, bl      ; 30 DB
mov bh, cl      ; 88 CF
; send edx, ecx to end of string
add cl, al     ; 00 C1
add dl, al     ; 00 C2

; decrement everything
dec ecx         ; 49
dec edx         ; 4A

; get rightmost unprocessed digit of each number
mov al, [ecx]   ; 8A 01
mov ah, [edx]   ; 8A 22

; add two ascii digits
add al, ah      ; 00 E0
; add carry if needed
add al, bl      ; 00 D8
; subtract 0x30 ('0') to get the resulting ascii digit
sub al, 0x30    ; 2C 30

; set bl to 0
xor bl, bl      ; 30 DB

; if greater than '9': must carry over to next place
cmp al, 0x39    ; 3C 39
jle $+6         ; 7E 04
; set bl to 1 if carrying over
mov bl, 1       ; B3 01
; subtract 10 from ascii digit if carrying over
sub al, 0x0A    ; 2C 0A

mov [ecx], al   ; 88 01
mov [edx], ah   ; 88 22

; check if loop has ended
cmp bh, cl      ; 38 CF
jne $-28        ; 75 E2

; restore ebx, ebp
pop ebp         ; 5D
pop ebx         ; 5B
; return
ret             ; C3

To try this in C (gcc, linux, intel processor):

#include <stdio.h>
#include <string.h>
#include <sys/mman.h>

int main(){
    // bytecode from earlier
    char code[] = {
        0x53, 0x55, 0x8B, 0xEC, 0x8B, 0x4D, 0x0C, 0x8B, 
        0x55, 0x10, 0x31, 0xC0, 0xB0, 0x09, 0x30, 0xDB, 
        0x01, 0xC1, 0x01, 0xC2, 0x40, 0x50, 0x8A, 0x01,
        0x8A, 0x22, 0x00, 0xE0, 0x00, 0xD8, 0x2C, 0x30,
        0x30, 0xDB, 0x3C, 0x39, 0x7E, 0x04, 0xB3, 0x01,
        0x2C, 0x0A, 0x88, 0x01, 0x88, 0x22, 0x58, 0x48,
        0x49, 0x4A, 0x85, 0xC0, 0x75, 0xDF, 0x5D, 0x5B,
    // allocate executable memory to a function pointer called 'add'
    void __attribute__( (__cdecl__) ) (*add)(char*,char*) = mmap(0,sizeof code,PROT_WRITE|PROT_EXEC,MAP_ANON|MAP_PRIVATE,-1,0);
    memcpy(add, code, sizeof code);

    // test inputs
    char number1[] = "0878295272", number2[] = "8184206821";


    // call the bytecode as a c function
    add(number1, number2);

    // output is in the first argument

    // release allocated memory
    munmap(add, sizeof code);

    return 0;

Ruby, 109 71

Cheesy. If you can't bring Mohammad to the mountain....

n+=1)until d>1
p r.to_s


  1. Compare an int's string representation to input 1 and input 2.
  2. Add that int to the result per match.
  3. Increment and repeat until you've done it twice.
  4. Vomit on yourself


71 shorter as an array.

85 removed method declaration and consolidate calls to n.to_s

92 applied some tips

101 save a char

102 use x for incrementing

109 initial commit

  • 2
    \$\begingroup\$ @DigitalTrauma Oh, I think it's a terrible answer, but it certainly meets the criteria. \$\endgroup\$ Commented Nov 24, 2014 at 22:11
  • 1
    \$\begingroup\$ @DigitalTrauma my even cheesier answer uses succ or prev.... but that's not even fun to golf. \$\endgroup\$ Commented Nov 24, 2014 at 22:12
  • 1
    \$\begingroup\$ "...without converting them to int or using any numeric data type." In your answer, r, n, d, and x are all numeric. Plus, checking each integer to see if its string representation matches the entered string is essentially just a slow brute-force way to convert to int. \$\endgroup\$ Commented Nov 25, 2014 at 15:25
  • 1
    \$\begingroup\$ @TreyThomas See OP's comment at codegolf.stackexchange.com/questions/41833/… \$\endgroup\$ Commented Nov 25, 2014 at 18:32
  • 1
    \$\begingroup\$ @TreyThomas : I think it's impossible to combine two quantities without quantifying them in some way. Any code to answer this question has to do the i+j calculation and know when it has the right answer to stop, so any correct answer is a slow brute-force way to convert to int disguised in some way. \$\endgroup\$ Commented Nov 25, 2014 at 21:22

sed, 359 bytes (without the fancy formatting)

I'm still not sure if this is a dup of Add without addition (or any of the 4 basic arithmetic operators). In the meantime, let me cross post my answer for that question. It's not going to win any golfing, but its a start, and I think easily meets the spec:

                       s/([^ ]+) ([^ ]+)/\1:0::\2:/
                       :d /^([^:]+):\1::([^:]+):/tx
                       s/:(_+:)/:1\1/g; y/_/0/; # #
                       bd;  :x  s/.*::([^:]+):/\1/;
                       # # # # # # #  # # # # # # #

Input is taken from STDIN in the form "x y". That is first transformed to "x:0::y:". Then we increment all numbers that come after ":" characters, until we get "x:x::(x+y):". Then we finally return (x+y).


$ printf "%s\n" "0 0" "0 1" "1 0" "9 999" "999 9" "12345 67890" "123 1000000000000000000000"  | sed -rf add.sed

Note that this only works for the natural numbers. However (in theory at least) it works for arbitrarily large integers. Because we are doing x increment operations on y, ordering can make a big difference to speed: x < y will be faster than x > y.

  • \$\begingroup\$ Not sure, but how do you know when to stop incrementing ? Since you cannot read X as an int.. \$\endgroup\$
    – Optimizer
    Commented Nov 24, 2014 at 21:36
  • \$\begingroup\$ @Optimizer The increment algorithm is based of this: codegolf.stackexchange.com/questions/38033/… which is purely regex substitutions and no arithmetic. We start with a triple {x, 0, y}, then increment elements 2 and 3 until elements 1 and 2 are equal (again regex-tested). At that point the 3rd element will be the required sum. \$\endgroup\$ Commented Nov 24, 2014 at 21:42
  • 2
    \$\begingroup\$ Oh! So y is converted to y+1 using just regex ? and no actual addition ? Nice! \$\endgroup\$
    – Optimizer
    Commented Nov 24, 2014 at 21:51

Ruby - 485 432 265

This seems more in the spirit of what you were looking for in the question.

It basically solves the problem how a human would on paper -- by "memorizing" all single digit addition results, adding each column, and understanding how to "carry the one" when necessary.

This is also using one "numeric data type" (variable i), which is prohibited by the question, but its only for string indexing. I'll try removing this and edit my answer.

def s p
(y=(?0..?9).to_a).product(y).map{|x|/#{x.join}/}.zip((?0..'18').to_a.each_cons(10).to_a.flatten).each{|k,v|return v if k=~p.sort.join}
(0..9).each{|i|d=s [a[i],b[i]]
puts r+c

Somewhat ungolfed:

def s p
  y = (?0..?9).to_a
  y.product(y).map{ |x|
  ).each{ |k,v|
    return v if k =~ p.sort.join

a,b=$*.map{ |n| n.rjust(10,?0).reverse }

r = ?0
c = ''

(0..9).each { |i|
  d = s [ a[i], b[i] ]
  c = s([ d[-1], r ]) + c
  r = d[-2] || '0'

puts r+c

EDIT: Used some ideas from the comments to generate the "memorized" mapping table instead of just hardcoding it.

  • 1
    \$\begingroup\$ You can probably make your "addition map" calculated somehow... maybe [?1..?9].zip([?1..?9]).map{|x,y| Regex.new(x+y)}.map{/*something based on the order of results*/} \$\endgroup\$ Commented Nov 25, 2014 at 16:42
  • \$\begingroup\$ product is better than zip \$\endgroup\$ Commented Nov 25, 2014 at 16:55
  • 1
    \$\begingroup\$ /#{x+y}/ is shorter than Regexp.new(x+y). ;) \$\endgroup\$
    – Jordan
    Commented Nov 25, 2014 at 18:40
  • 1
    \$\begingroup\$ i=-1;(s=(?0..?9).to_a).product(s).map{|x,y|i+=1;/#{x+y}/=>(?0..'18').each_cons(10).to_a[i/10][i%10]} gives you your regex array. \$\endgroup\$ Commented Nov 25, 2014 at 20:50
  • \$\begingroup\$ ah... but that uses a numeric (i)... there must be another way around that... maybe just use each_cons(10) as an enumerator and next through the set? \$\endgroup\$ Commented Nov 25, 2014 at 20:59

CJam, 95 92 80 72 70 44 characters


which translates to


This can definitely be golfed a lot. I really don't know if my approach is optimal or not yet.

UPDATE - Inline the sum matrix creation to save bytes. Due to this, the program now runs 10 times slower, but still a constant time for any kind of input.

Try it online here

Reads the line containing two numbers from STDIN as string and outputs as a array of characters which is a string itself.

For example:

123 4567

The output contains preceding 0. Let me know if that is an issue.


C# - 128 108 104

Thanks to Compass, BMac and Shawn for suggesting improvements.

First try at Code Golf, and using C# seems to be a handicap here...

By using .Compute() you can use the string values and sum them directly. As a bonus this works for other operators aside from just "+".


static void t(string a,string b){System.Console.Write(new System.Data.DataTable().Compute(a+"+"+b,""));}


static void t(string a, string b)
    System.Console.Write(new System.Data.DataTable().Compute(a+"+"+b,""));

Calling t("123","456"); gets you 579.

  • 7
    \$\begingroup\$ Nice try, and welcome to PPCG. In code-golf, we remove all unnecessary white space and say how many bytes we used. \$\endgroup\$
    – user10766
    Commented Nov 24, 2014 at 23:00
  • 2
    \$\begingroup\$ If you think C# is a handicap, wait until you start fiddling with Java... \$\endgroup\$ Commented Nov 25, 2014 at 13:15
  • 1
    \$\begingroup\$ You can save lines by moving a+"+"+b into the compute call and ignoring declaration. \$\endgroup\$
    – Compass
    Commented Nov 25, 2014 at 15:34
  • 1
    \$\begingroup\$ You can save more by not 'using' the namespaces and instead System.Console.WriteLine(new System.Data.DataTable()... \$\endgroup\$
    – BMac
    Commented Nov 25, 2014 at 16:40
  • 1
    \$\begingroup\$ Nothing says the output needs to end with a newline, consider using Console.Write to save 4 bytes \$\endgroup\$
    – SLuck49
    Commented Nov 25, 2014 at 20:33

GNU sed, 266 bytes

Uses a different approach than DigitalTrauma's solution. As an effect, this one performs even poorer, using O(m+n). Convert both operands to unary, concatenate, convert back to decimal (all using regex of course—sed doesn't have the concept of an integer).

As a bonus, this program sums up all the natural integers given on stdin (in the first line), meaning you can feed it nothing, one number or ten numbers and it'll do the right thing regardless.

The idea behind this code is vaguely inspired by an old PPCG sed submission of mine, though I don't remember for what question it is an answer.

Here it is, "pretty"-printed for your "convenience", to borrow another idea from DigitalTrauma. :D


(To obtain the 266-byte version, remove trailing semicolons, leading whitespace and the final comment, preferably using sed.)

Borrowing some tests from DigitalTrauma:

% printf "%s\n" "0 0" "0 1" "1 0" "9 999" "999 9" "12345 6789" "123 100" | while read l; do sed -rf /tmp/sum.sed <<<"$l"; done 

I tweaked the really large tests a bit because of the terrible space (in)efficiency. Due to the use of q only the first line is processed, hence the while loop in the test.


Java 6 (181 characters)

Not to be outdone by the handicap known as C#, Java in all its glory. So much boilerplate! Usage is providing the arguments separated by a space, i.e. 123 456

import javax.script.*;class T {public static void main(String[] a) throws Exception {System.out.print(new ScriptEngineManager().getEngineByName("JavaScript").eval(a[0]+"+"+a[1]));}}


import javax.script.*;

class T {
    public static void main(String[] a) throws Exception {
        System.out.print(new ScriptEngineManager()
                .getEngineByName("JavaScript").eval(a[0] + "+" + a[1]));

By using the JavaScript engine available in javax, we can make another language do the work for us, and technically follow the rules of not using any numeric types in the native language, or converting.

Justification for using eval

We have not converted the values to int for JavaScript to eval. We've created a String that is "123+456" which is not a number. JS Engine digests the formula and evaluates the String as number literals, which are not numeric data types. Java cheesy logic! As an aside, this also works for double math.

  • \$\begingroup\$ You're just asking for a bash version like dc -e"$1 $2+p" technically I haven't used a number type in the native bash it's just passing a string to some implementation detail \$\endgroup\$ Commented Nov 26, 2014 at 4:30

APL (61)

I think this falls within the rules.


This is a function that takes two string arguments, and returns a string:

      ⍝ show dimensions (if it was a number, this would give the empty list)

It's reasonably fast too, it adds the number formed by 999999 9s to itself in an instant.

It finds the index of each character in ⎕D (which is the string '0123456789'), then does grade school addition on each index separately, carrying as needed, then looks up the resulting digits in ⎕D. (I think the ⎕D lookup falls within the rules, it's basically just doing 'x'-48).


  • ⎕D∘⍳¨⍺⍵: look up the indices in ⎕D for each character in both strings.
  • ¯1+: subtract 1 from each, because the arrays are 1-based by default.
  • ⌽↑⌽¨: reverse both, turn into a matrix (filling empty squares with zeroes), then reverse the matrix.
  • +⌿: sum the columns of the matrix
  • {...}: carry over:
    • ∨/T←9<Z←0,⍵: add an extra 0 in front of the list. Find out which 'digits' are higher than 9, and store this in T. If any digits were higher than 10:
      • Z-10×T: subtract 10 from each position that is higher than 10,
      • T←(1⌽T)+: add 1 to each position next to each position that was higher than 10, and store in T.
      • T↓⍨~×⊃T: if T starts with a zero, remove it,
      • : apply the carry function to the result.
    • ⋄⍵: otherwise, return the value unchanged
  • 1+: add one to each position (because the array is 1-indexed)
  • ⎕D[...]: use the result as indices into ⎕D.

Perl - 136 119 115 bytes

I'm learning Perl, this seemed like good practice. Tips are appreciated!

Cheesy answer, to get that out of the way:

print$ARGV[0]+$ARGV[1]; #Adding strings

Actual answer:



  • 2
    \$\begingroup\$ Nice. You might investigate these tips to cut down your numbers a bit. At a glance, replacing your first line with ($x,$y)=@ARGV and using say instead of print will shave off a few characters. \$\endgroup\$
    – Mark
    Commented Nov 25, 2014 at 20:55
  • \$\begingroup\$ Thanks! I did that and took out some parens (I love Perl's approach to punctuation). I couldn't get say to work though. \$\endgroup\$
    – BMac
    Commented Nov 26, 2014 at 3:54
  • \$\begingroup\$ Ah. say is a Perl 6 thing (or you could use it in Perl 5 with these instructions, but that would be too long). Instead of say, use warn to shave a character. That will output to STDERR instead of STDOUT, but that's not against the rules of this one. :-) \$\endgroup\$
    – Mark
    Commented Nov 26, 2014 at 20:28

Java 7, Score = 252

Uses no integers, longs, bytes, shorts, doubles, floats, or any built in library functions for adding. Wrap in a class body and call with t(String1,String2). Please pad strings with 0's so that they have equal length.

t("123","234") returns "0357".


char c,d,e,f,g,k;String t(String a,String b){g++;char[]h=a.toCharArray(),i=b.toCharArray(),j=new char[h.length + 1];for(d=(char)h.length;d>f;)j[--d+1]=(c=(e=(char)(h[d]+i[d]-'0'+c))>'9'?g:f)==g?(char)(e-'\n'):e;j[0]=(char)('0'+c);return new String(j);}

Golfed Expanded with class:

public class T{

    public static void main(String[] args){
        System.out.println(new T().t(args[0],args[1]));

    char c,d,e,f,g,k;
    String t(String a,String b){
        char[]h=a.toCharArray(),i=b.toCharArray(),j=new char[h.length + 1];
        return new String(j);

Partially golfed expanded:

public class TrickSum{

    public static void main(String[] args){
        System.out.println(new TrickSum().trickSum(args[0], args[1]));

    char carry, i, aSum,nullChar,oneChar;
    public String trickSum(String a, String b){
        char[] number1 = toCharArray(a), number2 = toCharArray(b), sum = new char[number1.length + 1];
        for (i = (char) number1.length; i > nullChar;)
            sum[--i + 1] = (carry = (aSum = (char) (number1[i] + number2[i] - '0' + carry)) > '9' ? oneChar : nullChar) == oneChar ? (char) (aSum - '\n') : aSum;
        sum[0] = (char)('0' + carry);
        return new String(sum);

    char[] toCharArray(String string){
        return string.toCharArray();

100% Expanded:

public class TrickSum{

    public static void main(String[] args){
        System.out.println(trickSum(args[0], args[1]));

    public static String trickSum(String a, String b){
        char[] number1 = a.toCharArray();
        char[] number2 = b.toCharArray();
        char[] sum = new char[number1.length + 1];
        char carry = '\u0000';
        for (char i = (char)(number1.length - 1); i != '\uFFFF'; i--){
            char aSum = (char) (number1[i] + number2[i] - '0' + carry);
            carry = aSum > '9' ? '\u0001' : '\u0000';
            aSum = (carry == '\u0001') ? (char) (aSum - '\n') : aSum;
            sum[i + 1] = aSum;
        sum[0] = (char)('0' + carry);
        return new String(sum);
  • 1
    \$\begingroup\$ Technically, java char is a numeric data type ._. \$\endgroup\$
    – Compass
    Commented Nov 25, 2014 at 16:13
  • \$\begingroup\$ @Compass Internally it is. But if I convert the char \u0030 to a string, I get "0" not "48". \$\endgroup\$ Commented Nov 25, 2014 at 16:21

Java - 257 Characters

as everyone knows java there is no better language for golfing than java

    class A{public static void main(String[]s){char[]a=s[0].toCharArray();char[]b=s[1].toCharArray();int c=a.length;int d=b.length;int e=0;String f="";for(int i=0;i<Math.max(c,d);i++){f=f+(((i<c?a[i]-48:0)+(i<d?b[i]-48:0)+e)%10);e/=10;}System.out.println(f);}}

this is ungolfed solution

public static void main(String[] args) {
        char[] aa = args[0].toCharArray();
        char[] bb = args[1].toCharArray();
        int aal = aa.length;
        int bbl = bb.length;
        int reminder = 0;
        String result ="";
        for(int i=0;i<Math.max(aal,bbl);i++){

Haskell - 98 94 bytes

 let c d=last$takeWhile(\e->d/=(show$e-1))[0..]
 print$c a+c b

JavaScript (ES6), 55 66 59*

 f=x=>{for(i=0;i+[]!=x;i++);return i};f((p=prompt)())+f(p())

*This makes a few assumptions:

  • We're in an ES6 REPL environment (ex. FireFox 33.1 browser console)
  • Performance does not matter (seriously, '9999999999','9999999999' took about 20 minutes to return)
  • Converting from Integer to String is allowed
  • Input is defined in variables a and b, ex: var a='123',b=321'; Changed to getting input from prompt (+11).
  • Input has no leading zeros.
  • \$\begingroup\$ @Optimizer Fair enough, updated to pull from prompt \$\endgroup\$
    – SLuck49
    Commented Nov 25, 2014 at 18:29
  • \$\begingroup\$ You can use ES6 to bring down those chars a lot! \$\endgroup\$
    – Optimizer
    Commented Nov 25, 2014 at 18:32
  • \$\begingroup\$ I do bellieve that 'or using any numeric data type' means you arent even allowed to use for loops. \$\endgroup\$
    – CSharpie
    Commented Nov 25, 2014 at 18:58
  • \$\begingroup\$ @CSharpie OP commented that numbers in the code are fine \$\endgroup\$
    – SLuck49
    Commented Nov 25, 2014 at 19:24

Python 2.7, 196 137 chars

version 2 (shorter by initialising the dictionary with code):

for i in range(10):n[`i`]=i*' '
def q(a,b):f=lambda x:''.join([10**p*n[s] for p,s in enumerate(reversed(x))]);return len(f(a)+f(b))

Previous version 1 (196 chars):

def q(a,b):n,f={0:'','1':' ','2':'  ','3':'   ','4':4*' ','5':5*' ','6':6*' ','7':7*' ','8':8*' ','9':9*' '}, lambda x:''.join(
    [10**p*n[s] for p,s in enumerate(reversed(x))]);return len(f(a)+f(b))


>>> print q('123','111')

The dictionary keys are strings, the dictionary values only include number constants to shorten the code, and the calculation is done by concatenating two strings and getting the resulting length, so I hope it counts as "not converting them to ints".

Python small-print rule-cheat version

class z(int):0
def s(a,b): return z(a)+z(b)


>>> type(z('4'))
<class '__main__.z'>

Type z is a custom type I define as: definitely not a numeric type by whatever definition the questioner uses, but behaves close enough to a numeric type to be useful in limited circumstances. Type z behaviours are only partially implemented in this code sample, and if the CPython interpreter uses 'int' to implement z, that's an merely an implementation detail and not related to the problem at hand.


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