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.

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

answered Apr 3, 2011 at 13:43
\$\endgroup\$
1
  • 3
    \$\begingroup\$ you may try ideone for python3 and input - ideone.com/clone/ZZyzu \$\endgroup\$ Commented 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
answered Apr 5, 2011 at 6:43
\$\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\$ Commented 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.

answered Mar 15, 2011 at 6:39
\$\endgroup\$
1
  • \$\begingroup\$ 314 bytes \$\endgroup\$ Commented 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)}}
answered Apr 8, 2021 at 7:33
\$\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/2505円
 0
 --
 2
 25
 --
 0

Testcase:

document.write("<pre>"+i(5,25)+"</pre>");
document.write("<pre>"+i(7,65669726752476)+"</pre>");
answered Apr 3, 2011 at 7:25
\$\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\$ Commented Apr 4, 2011 at 16:40

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.