Wizualizuj długi podział dzięki sztuce ASCII

16

Napisz program, który wizualizuje długi podział ze sztuką ASCII. Dane wejściowe składają się z dwóch liczb całkowitych, licznika i mianownika, przy użyciu wybranego formatu wejściowego.

Przykłady:

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

Zasady:

  • Używanie operatora podziału języka programowania toDozwolone użycie .
  • Dozwolone jest także użycie obsługi dużej liczby całkowitej.
  • Dla spójności:
    • Jeśli iloraz wynosi zero, wydrukuj jedno zero na końcu trampoliny.
    • Jeśli reszta to zero, nie drukuj jej.
    • Nie drukuj zer wiodących na żadnych liczbach.
  • Dozwolone są nadmierne znaki nowej linii na końcu i końcowe spacje po prawej stronie.
  • Rozwiązanie z najmniejszą liczbą postaci wygrywa.

Limity:

  • 0 <= licznik <= 10 72 - 1
  • 1 <= mianownik <= 9999999

Oznacza to, że wynik nigdy nie będzie szerszy niż 80 kolumn.

Pakiet testowy i przykładowa implementacja:

Możesz użyć long-division.c ( gist ), aby przetestować swój program. W rzeczywistości jest to skrypt bash z programem C. Ulepsz go, aby wywołać program w pakiecie testowym. Spójrz na kod C na dole, aby zobaczyć implementację referencyjną. Daj mi znać, jeśli występują problemy z programem przykładowym lub pakietem testowym.

$ ./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!

Edycja: Na żądanie umieszczam dane wejściowe zestawu testów i oczekiwane dane wyjściowe w plikach tekstowych ( gist ). Przykładowe użycie (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

Dziwne polecenia sed odfiltrowują końcowe znaki nowej linii i spacje z wyników programu.

Joey Adams
źródło
Odkryłem niewielką wadę w referencyjnej implementacji, a mianowicie w przypadku 123000123000123 ÷ 123. Linie odejmowania obejmowały puste miejsce, ale powinny one obejmować tylko długość widocznych cyfr minuend. Teraz jest naprawione.
Joey Adams,
2
Myślę, że wyniki są nieco tendencyjne w stosunku do anglojęzycznej publiczności golfowej: en.wikipedia.org/wiki/...
hallvabo
Czy możesz po prostu utworzyć plik, który pokazuje oczekiwany wynik wszystkich testów i link do niego?
mellamokb
@mellamokb: Dodano, dziękuję!
Joey Adams,
Co z akceptacją? Pytanie jest wystarczająco stare ...
Oleh Prypin

Odpowiedzi:

3

Python 3, 284 257 znaków

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

Stosowanie: python3 div.py
Wejście: z klawiatury

test.py

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

oczekiwane dopasowania wyjściowe

Wersje:
 1. 284
 2. 257 :s,z,f=0,0,0s=z=f=0; z and fz*f; lepsze zapętlenie; usunąłem kilka nowych linii.

Oleh Prypin
źródło
2
możesz wypróbować ideone dla python3 i wprowadzania - ideone.com/clone/ZZyzu
TY
3

Haskell, 320 znaków

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

Przechodzi wszystkie testy. Chociaż jest to dość golfa - myślę, że jest jeszcze wiele do zrobienia ...


  • Edycja: (344 -> 339) opóźnia readpołączenia, co zmniejsza potrzebę dzwonienia show, showco sjest wystarczające, jeśli nie warto.
  • Edycja: (339 -> 320) przepisał funkcje formatowania pól ciągów
MtnViewMark
źródło
Schludny! Zrobiłem rozwiązanie Haskell z 344 znakami, ale go nie opublikowałem. Nie wiedziałem też, że możesz używać symboli Unicode dla operatorów (bez -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)}

UWAGA: kuszące, jak się wydaje, aby ogolić kilka znaków, zamieniając c=(c==0)?je nac=!c? to nie jest użyteczny, ponieważ powoduje pływających błędy związane punktowych.

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

Przykładowe wykonanie:

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

Edycja 1 : Drobne poprawki błędów, liczne optymalizacje kodu.

Edycja 2 : Napraw błąd z 1/7 generującym dodatkowe wyjście.

mellamokb
źródło
Skrypt testowy ujawnił jeden problem. d(1,7)(i podobne testy) powtórz mianownik, zamiast drukować nic. Jest to błędne, ponieważ liczba ta powinna być cyfrą ilorazową razy mianownik, który wynosi zero.
Joey Adams,
Wszystkie testy przeszły teraz.
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}

Wywołaj za pomocą i (dzielnik, liczba). Codegolfed JS: http://jsfiddle.net/puckipedia/EP464/ Ungolfed (holenderski) JS: http://jsfiddle.net/puckipedia/M82VM/

Zwraca długi podział (w formacie holenderskim, gdy się go nauczyłem):

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

Testcase:

document.write("<pre>"+i(5,25)+"</pre>");
document.write("<pre>"+i(7,65669726752476)+"</pre>");
puckipedia
źródło
Hej, to nie to samo, co wymagane!
Oleh Prypin
@BlaXpirit Wiem, nauczyłem się tego w ten sposób.
puckipedia,
Ciekawy. Chociaż, jak mówi @BlaXpirit, nie jest zgodny ze specyfikacją. Specyfikacja ma być uczciwym standardem porównawczym do określania wydajności kodu golfowego, więc nie można arbitralnie zmienić specyfikacji, nawet jeśli nie zgadzasz się z formatem wyjściowym :)
mellamokb