16
\$\begingroup\$

Write a program that visualizes long division with ASCII art. Input consists of two integers, a numerator and a denominator, using the input format of your choice.

Examples:

1234 ÷ 56:

     22
   ----
56|1234
   112
   ---
    114
    112
    ---
      2

1002012 ÷ 12:

     83501
   -------
12|1002012
    96
   ---
     42
     36
     --
      60
      60
      --
        12
        12
        --

0 ÷ 35

   0
   -
35|0

Rules:

  • Use of the programming language's division operator is allowed.
  • Use of big integer support is also allowed.
  • For consistency:
    • If the quotient is zero, print a single zero at the end of the diving board.
    • If the remainder is zero, do not print it.
    • Do not print leading zeros on any numbers.
  • Excess newlines at the end and trailing spaces to the right are allowed.
  • Solution with the fewest characters wins.

Limits:

  • 0 <= numerator <= 1072 - 1
  • 1 <= denominator <= 9999999

This implies that the output will never be wider than 80 columns.

Test suite and sample implementation:

You can use long-division.c (gist) to test your program. It is actually a bash script with a C program inside. Tweak it to invoke your program in the test suite. Look at the C code at the bottom to see the reference implementation. Please let me know if there are any problems with the sample program or test suite.

$ ./long-division.c 10 7
   1
  --
7|10
   7
  --
   3
$ ./long-division.c
PASS 1234 ÷ 56
PASS 1002012 ÷ 12
PASS 1 ÷ 1
--- snip ---

Score: 35 / 35
All tests passed!

Edit: By request, I put the test suite input and expected output into text files (gist). Sample usage (bash):

cat input | while read nd; do
    ./program $nd |
        sed 's/\s*$//' | sed -e :a -e '/^\n*$/{$d;N;};/\n$/ba'
done > output

diff -u expected output

The weird sed commands filter out trailing newlines and spaces from the program output.

\$\endgroup\$
  • \$\begingroup\$ I discovered a minor flaw in the reference implementation, namely in the case of 123000123000123 ÷ 123. The subtraction lines were spanning blank space, but they should only be spanning the length of the visible digits of the minuend. It's fixed now. \$\endgroup\$ – Joey Adams Mar 15 '11 at 1:22
  • 2
    \$\begingroup\$ I think the output is a bit biased towards the English-speaking golfing audience: en.wikipedia.org/wiki/… \$\endgroup\$ – hallvabo Mar 15 '11 at 11:23
  • \$\begingroup\$ Can you just create a file that shows the expected output of all the tests and link to it? \$\endgroup\$ – mellamokb Mar 15 '11 at 14:43
  • \$\begingroup\$ @mellamokb: Added, thanks! \$\endgroup\$ – Joey Adams Mar 15 '11 at 15:28
  • \$\begingroup\$ What about accepting? The question is old enough... \$\endgroup\$ – Oleh Prypin Apr 6 '11 at 16:57
3
\$\begingroup\$

Python 3, 284 257 characters

div.py

n,t=input().split()
d=int(t)
l=lambda x:len(str(x))
s=l(n)
def p(x):print(' '*(l(d)+s-l(x)+1)+str(x))
p(int(n)//d)
p('-'*s)
p(t+'|'+n)
s=z=f=0
while t:
 try:
  while z<d:z=z*10+int(n[s]);s+=1
 except:t=0
 if z*f:p(z)
 if t:f=1;t=z//d*d;p(t);p('-'*l(z));z-=t

Usage: python3 div.py
Input: from keyboard

test.py

import sys
sys.stdin=open('input'); sys.stdout=open('output','w')
for line in open('input'): exec(open('div.py').read())

output matches expected

Versions:
 1. 284
 2. 257: s,z,f=0,0,0s=z=f=0; z and fz*f; better looping; removed a few newlines.

\$\endgroup\$
  • 2
    \$\begingroup\$ you may try ideone for python3 and input - ideone.com/clone/ZZyzu \$\endgroup\$ – YOU Apr 4 '11 at 4:28
3
\$\begingroup\$

Haskell, 320 characters

l=length
(®)=replicate
p!v=p&show v
p&s=(p-l s)®' '++s
0§_=[];_§l=l
d[m,n]=l c!(read m`div`e):l c&(l m®'-'):c:drop 1(g 0(map(toInteger.fromEnum)m)$1+l n)where
 e=read n;c=n++'|':m
 g r(d:z)p=i§[o!k,o!(i*e),o&(l(show k)®'-')]++g j z o where k=r*10+d-48;(i,j)=k`divMod`e;o=1+p
 g r[]p=r§[p!r]
main=interact$unlines.d.words

Passes all tests. While is this pretty golf'd -- I think there is still yet more to be done here...


  • Edit: (344 -> 339) delay read calls, which reduces need to call show, enough that abbreviating show as s isn't worth it.
  • Edit: (339 -> 320) rewrote string field formatting functions
\$\endgroup\$
  • \$\begingroup\$ Neat! I did a Haskell solution with 344 characters, but didn't post it. Also, I didn't know you could use Unicode symbols for operators (without -XUnicodeSyntax). \$\endgroup\$ – Joey Adams Apr 5 '11 at 17:00
3
\$\begingroup\$

JavaScript (400 394 418)

function d(n,d){t=parseInt;p=function(v){return(s+v).substring(v.length)};a=function(v,c){return v.replace(/\d/g,c)};w='\n';q=b=o=c=e='';s=a(d,' ')+' ';f=true;i=-1;z='0';while(++i<n.length){s+=' ';if(t(c+=n[i])>=t(d)){q+=r=Math.floor(t(c)/t(d));o+=(!f?p(c)+w:e)+p(''+r*t(d))+w+p(a(c,'-'))+w;c=t(c)%t(d);f=false}else if(!f){q+=z;}c=(c==0)?e:e+c}return p(!q?z:q)+w+p(a(n,'-'))+w+d+'|'+n+w+o+(q?p(c):e)}

NOTE: As tempting as it looks to shave off a few chars by replacing c=(c==0)? with c=!c?, it is not usable because it causes floating point-related bugs.

http://jsfiddle.net/nLzYW/9/

Sample Execution:

document.writeln("<pre>");
document.writeln(d("1234","56"));
document.writeln();
document.writeln(d("1002012","12"));
document.writeln();
document.writeln(d("0","35"));
document.writeln();
document.writeln(d("123000123000123","123"));
document.writeln("</pre>");

Edit 1: Minor bug fixes, numerous code optimizations.

Edit 2: Fix bug with 1/7 generating extra output.

\$\endgroup\$
  • \$\begingroup\$ The test script revealed one problem. d(1,7) (and similar tests) repeat the denominator rather than printing nothing. This is wrong because this number should be the quotient digit times the denominator, which is zero. \$\endgroup\$ – Joey Adams Mar 15 '11 at 15:32
  • \$\begingroup\$ All tests pass now. \$\endgroup\$ – Joey Adams Apr 4 '11 at 19:47
1
\$\begingroup\$

Javascript: (372)

function g(a){for(var c="",e=0;e<a;e++)c=" "+c;return c}function i(a,c){for(var e=a+"/"+c+"\\",j=(""+c).split(""),k="",d=0,b=0;b<j.length;b++){d*=10;d+=parseInt(j[b],10);var f=d>9?b-1:b,h=0;h=Math.floor(d/a);d%=a;f=g(f+a.toString().split("").length);f+=h*a+"\n"+g(b+a.toString().split("").length)+"--\n"+g(b+a.toString().split("").length)+d+"\n";k+=f;e+=h}return e+"\n"+k}

Invoke by using i(divider,number). Codegolfed JS: http://jsfiddle.net/puckipedia/EP464/ Ungolfed (dutch) JS: http://jsfiddle.net/puckipedia/M82VM/

Returns the long division (in dutch format as i learned it):

5/25\05
 0
 --
 2
 25
  --
  0

Testcase:

document.write("<pre>"+i(5,25)+"</pre>");
document.write("<pre>"+i(7,65669726752476)+"</pre>");
\$\endgroup\$
  • \$\begingroup\$ Hey, this isn't the same as required! \$\endgroup\$ – Oleh Prypin Apr 3 '11 at 13:53
  • \$\begingroup\$ @BlaXpirit I know, i learned it that way. \$\endgroup\$ – puckipedia Apr 3 '11 at 16:57
  • \$\begingroup\$ Interesting. Though as @BlaXpirit says, it doesn't follow the spec. The spec is intended to be a fair standard of comparison for determining efficiency of code-golfed code, so you can't arbitrarily change the spec even if you don't agree with the output format :) \$\endgroup\$ – mellamokb Apr 4 '11 at 16:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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