Visualisasikan pembagian panjang dengan seni ASCII

16

Tulis sebuah program yang memvisualisasikan pembagian panjang dengan seni ASCII. Input terdiri dari dua bilangan bulat, pembilang dan penyebut, menggunakan format input pilihan Anda.

Contoh:

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

Aturan:

  • Penggunaan divisi operator bahasa pemrograman ini adalah diperbolehkan.
  • Penggunaan dukungan integer besar juga diperbolehkan.
  • Untuk konsistensi:
    • Jika hasil bagi adalah nol, cetak satu nol di ujung papan selam.
    • Jika sisanya nol, jangan cetak.
    • Jangan cetak angka nol di depan pada nomor apa pun.
  • Kelebihan baris baru di ujung dan spasi tambahan ke kanan diizinkan.
  • Solusi dengan karakter paling sedikit menang.

Batas:

  • 0 <= pembilang <= 10 72 - 1
  • 1 <= penyebut <= 9999999

Ini menyiratkan bahwa output tidak akan pernah lebih luas dari 80 kolom.

Test suite dan implementasi sampel:

Anda dapat menggunakan long-division.c ( intisari ) untuk menguji program Anda. Ini sebenarnya adalah skrip bash dengan program C di dalamnya. Tweak untuk menjalankan program Anda di test suite. Lihatlah kode C di bagian bawah untuk melihat implementasi referensi. Tolong beri tahu saya jika ada masalah dengan program sampel atau 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!

Sunting: Atas permintaan, saya memasukkan input suite tes dan output yang diharapkan ke dalam file teks ( inti ). Contoh penggunaan (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

Perintah sed yang aneh menyaring jejak dan spasi baru dari keluaran program.

Joey Adams
sumber
Saya menemukan cacat kecil dalam implementasi referensi, yaitu dalam kasus 123000123000123 ÷ 123. Garis-garis pengurangan mencakup ruang kosong, tetapi mereka hanya boleh menjangkau panjang angka yang terlihat dari minuend. Sudah diperbaiki sekarang.
Joey Adams
2
Saya pikir hasilnya agak bias terhadap penonton golf berbahasa Inggris: en.wikipedia.org/wiki/…
hallvabo
Bisakah Anda membuat file yang menunjukkan hasil yang diharapkan dari semua tes dan tautan ke sana?
mellamokb
@mellamokb: Ditambahkan, terima kasih!
Joey Adams
Bagaimana dengan menerima? Pertanyaannya sudah cukup tua ...
Oleh Prypin

Jawaban:

3

Python 3, 284 257 karakter

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

Penggunaan: python3 div.py
Input: dari keyboard

test.py

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

pencocokan output diharapkan

Versi:
 1. 284
 2. 257 : s,z,f=0,0,0s=z=f=0; z and fz*f; perulangan yang lebih baik; menghapus beberapa baris baru.

Oleh Prypin
sumber
2
Anda dapat mencoba ideone untuk python3 dan memasukkan - ideone.com/clone/ZZyzu
YOU
3

Haskell, 320 karakter

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

Lewati semua tes. Sementara golf cantik ini - saya pikir masih banyak yang harus dilakukan di sini ...


  • Sunting: (344 -> 339) menunda readpanggilan, yang mengurangi kebutuhan untuk menelepon show, cukup disingkat showkarena stidak layak.
  • Edit: (339 -> 320) tulis ulang fungsi pemformatan bidang string
MtnViewMark
sumber
Rapi! Saya melakukan solusi Haskell dengan 344 karakter, tetapi tidak mempostingnya. Juga, saya tidak tahu Anda bisa menggunakan simbol Unicode untuk operator (tanpa -XUnicodeSyntax).
Joey Adams
3

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)}

CATATAN: Sebagai menggoda seperti yang terlihat untuk mencukur habis beberapa karakter dengan mengganti c=(c==0)?dengan c=!c?, itu tidak dapat digunakan karena menyebabkan mengambang bug yang berhubungan dengan titik.

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

Eksekusi sampel:

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>");

Sunting 1 : Perbaikan bug minor, berbagai optimasi kode.

Sunting 2 : Perbaiki bug dengan 1/7 menghasilkan output tambahan.

mellamokb
sumber
Script tes mengungkapkan satu masalah. d(1,7)(dan tes serupa) ulangi penyebut daripada mencetak apa-apa. Ini salah karena angka ini harus menjadi digit hasil bagi dikali penyebut, yaitu nol.
Joey Adams
Semua tes lulus sekarang.
Joey Adams
1

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}

Diminta menggunakan i (pembagi, angka). Codegolfed JS: http://jsfiddle.net/puckipedia/EP464/ Ungolfed (belanda) JS: http://jsfiddle.net/puckipedia/M82VM/

Mengembalikan divisi panjang (dalam format Belanda seperti yang saya pelajari):

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

Kasus cobaan:

document.write("<pre>"+i(5,25)+"</pre>");
document.write("<pre>"+i(7,65669726752476)+"</pre>");
puckipedia
sumber
Hei, ini tidak sama dengan yang disyaratkan!
Oleh Prypin
@BlaXpirit Saya tahu, saya mempelajarinya seperti itu.
puckipedia
Menarik. Meskipun seperti yang dikatakan @BlaXpirit, itu tidak mengikuti spek. Spesifikasi ini dimaksudkan sebagai standar perbandingan yang adil untuk menentukan efisiensi kode kode-golf, sehingga Anda tidak dapat mengubah spesifikasi secara acak bahkan jika Anda tidak setuju dengan format output :)
mellamokb