22
\$\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\$
1
  • 4
    \$\begingroup\$ I think the output is a bit biased towards the English-speaking golfing audience: en.wikipedia.org/wiki/… \$\endgroup\$
    – hallvabo
    Mar 15, 2011 at 11:23

5 Answers 5

5
\$\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\$
1
  • 3
    \$\begingroup\$ you may try ideone for python3 and input - ideone.com/clone/ZZyzu \$\endgroup\$
    – YOU
    Apr 4, 2011 at 4:28
4
\$\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\$
1
  • \$\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, 2011 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\$
1
  • \$\begingroup\$ 314 bytes \$\endgroup\$
    – user100411
    Apr 7, 2021 at 11:21
3
\$\begingroup\$

AWK, 422 bytes

I think it took me over a week to solve this problem.

function l(x){return length(x)}{P=9(d=$2);gsub(".",FS,P);N=l(L=n=$1);gsub(".","-",L);O(0,q=int($1/$2));Q=l(q);print P L RS d"|"n}function O(i,x){printf"%"l(d)+N-Q+1+i"d\n",x}m=substr(q,1,1)*d{for(i=1;i<=Q;){O(i,m);print P substr(L,1,N-Q+1);for(_=l(j=n)-l(n-=m*10**(Q-i));_--;)P=P FS;if(!n)exit;match(q,".0*");i+=R=RLENGTH;sub(".{"R"}",E,q);b=q+0?substr(n,1,M=l(m=substr(q,1,1)*d)):n;if(b<m)b=substr(n,1,M+1);O(i-(i>Q),b)}}

Try it online!

Usage

  • Input is given from STDIN, as single line.
  • Two natural numbers are on same line.
  • Output is returned to STDOUT.
  • This program does never handle overflow; fails on huge values.
  • This program does not handle multiple lines of input correctly; only the first line is handled correctly.

Formatted

function l(x){
  return length(x)}
{
  P=9(d=$2);gsub(".",FS,P);
  N=l(L=n=$1);gsub(".","-",L);
  O(0,q=int($1/$2));
  Q=l(q);
  print P L RS d"|"n}
function O(i,x){
  printf"%"l(d)+N-Q+1+i"d\n",x}
m=substr(q,1,1)*d{
  for(i=1;i<=Q;){
    O(i,m);
    print P substr(L,1,N-Q+1);
    for(_=l(j=n)-l(n-=m*10**(Q-i));_--;)
      P=P FS;
    if(!n)
      exit;
    match(q,".0*");
    i+=R=RLENGTH;
    sub(".{"R"}",E,q);
    b=q+0?substr(n,1,M=l(m=substr(q,1,1)*d)):n;
    if(b<m)
      b=substr(n,1,M+1);
    O(i-(i>Q),b)}}
\$\endgroup\$
2
\$\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\$
1
  • 1
    \$\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, 2011 at 16:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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