Teach me how to add!

Dyalog APL, 90 bytes

{⌽↑(⊂⌽s),⍨↓⌽(' + ',⍨' 1'⊃⍨l<⍴s),'-'⍪⍨w⍪⍨' 1'[10|(⍎¨(-l←⍴⍉w)↑s←⍕+/⍵)-(+/0 10⊤⍎)¨⊂[0]w←⍕⍪⍵]}

Takes list of two numbers as argument. Needs ⎕IO←0 which is default on many systems.

      f←{⌽↑(⊂⌽s),⍨↓⌽(' + ',⍨' 1'⊃⍨l<⍴s),'-'⍪⍨w⍪⍨' 1'[10|(⍎¨(-l←≢⍉w)↑s←⍕+/⍵)-(+/0 10⊤⍎)¨⊂[0]w←⍕⍪⍵]}
      f¨(17282 1342)(1596 8404)(1776 76)(123 456)
┌──────┬─────┬─────┬────┐
│   1  │1111 │  11 │    │
│ 17282│ 1596│ 1776│ 123│
│+ 1342│+8404│+  76│+456│
│ -----│ ----│ ----│ ---│
│ 18624│10000│ 1852│ 579│
└──────┴─────┴─────┴────┘

TryAPL online! Note that ⎕IO has been set and has been emulated with e as is banned from TryAPL for security reasons.

Ungolfed and explained

{ An anonymous function

w ← ⍕ ⍪⍵ w gets the textified vertical arrangement of the argument (the numbers to be added)

l ← ≢ ⍉w s gets the count of rows in the transposed w (i.e. the number of columns in w)

s ← ⍕ +/⍵ s gets the textified sum of the argument

' 1'[... index into the string " 1", so zeros give spaces, and ones give character 1s.

⊂[0] w enclose down, gets list of pairs of corresponding digits in the numbers

(+/ 0 10 ⊤ ⍎)¨ for each pair; make into digit(s), then sum

(⍎¨ (-l) ↑ s)- chop left-most digit of grand total to the width of the longest input, then make each character into separate number and subtract the column sums (if the sum does not add up to the total, the discrepancies are due to carrys, so this gives us each column's carry)

10| division remainder when divided by 10

] [end of indexing]

w⍪⍨ stack the input numbers below

'-'⍪⍨ stack a minus below each column

(' + ',⍨' 1'⊃⍨l<⍴s), prepend a space to the 2nd line, a plus to the 3nd, a space to the 4rd, and a one or space to the 1st – depending on if the sum is wider than the widest input (meaning we need a carry high over the plus )

mirror right-left (so left-justification will be to the right)

make table into list of lines (so that differing line lengths are allowed

(⊂⌽s),⍨ append the sum

combine list of lines into table (padding the right with spaces as needed)

mirror back to normal

} [end of function]`


Python 2.7, 201 192 161 155 167 164 182 bytes:

(Saved 2 bytes (192->190) thanks to TheBikingViking)

def Q(T,Y):O,D=sorted([T,Y]);E=len(`D`);print'%s\n %s\n+%*s\n %s\n %d'%(''.join([' ',i[0]][len(i)>1]for i in[`sum(map(int,u))`for u in zip(`D`,'%0*d'%(E,O))]),D,E,O,'-'*E,sum([T,Y]))

A named function that takes input in any order while outputting the correct answer in order of magnitude from top to bottom.

Try it Online! (Ideone)


Alternatively, if allowed to take input in order of magnitude (i.e. bigger number first, then smallest), then here is a much smaller solution which also uses a named function at 164 bytes:

def Q(T,Y):E=len(`T`);print'%s\n %d\n+%*d\n %s\n %d'%(''.join([' ',i[0]][len(i)>1]for i in[`sum(map(int,u))`for u in zip(`T`,`Y`.zfill(E))]),T,E,Y,'-'*E,sum([T,Y]))

Try this Version Online! (Ideone)


Ruby, 192 191 bytes

Returns a multiline string. Input is an array with two strings.

Try it online!

->o{x,y=o.sort_by!(&:to_i).map{|e|e.reverse.chars}
a,b=o.map &:to_i
k=' '
y.zip(x).map{|z|i,j=z.map &:to_i
k=i+j+k.to_i<10?' ':1}.reverse*''+"
 %s
+%#{s=y.size}s
 %s
%#{s+1}s"%[b,a,?-*s,a+b]}