Visualisez la division longue avec l'art ASCII

16

Écrivez un programme qui visualise une longue division avec l'art ASCII. L'entrée se compose de deux entiers, un numérateur et un dénominateur, en utilisant le format d'entrée de votre choix.

Exemples:

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

Règles:

  • L'utilisation de l'opérateur de division du langage de programmation est autorisée.
  • L'utilisation de la prise en charge des grands nombres entiers est également autorisée.
  • Pour la cohérence:
    • Si le quotient est zéro, imprimez un seul zéro à la fin du plongeoir.
    • Si le reste est nul, ne l'imprimez pas.
    • N'imprimez pas de zéros non significatifs sur aucun nombre.
  • Les sauts de ligne à la fin et les espaces de fin à droite sont autorisés.
  • La solution avec le moins de personnages gagne.

Limites:

  • 0 <= numérateur <= 10 72 - 1
  • 1 <= dénominateur <= 9999999

Cela implique que la sortie ne dépassera jamais 80 colonnes.

Suite de tests et exemple d'implémentation:

Vous pouvez utiliser long-division.c ( gist ) pour tester votre programme. Il s'agit en fait d'un script bash avec un programme C à l'intérieur. Ajustez-le pour appeler votre programme dans la suite de tests. Regardez le code C en bas pour voir l'implémentation de référence. Veuillez me faire savoir s'il y a des problèmes avec l'exemple de programme ou la suite de tests.

$ ./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: Sur demande, je mets l' entrée de la suite de tests et la sortie attendue dans des fichiers texte ( gist ). Exemple d'utilisation (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

Les commandes sed étranges filtrent les nouvelles lignes et les espaces en fin de sortie du programme.

Joey Adams
la source
J'ai découvert une faille mineure dans l'implémentation de référence, à savoir dans le cas de 123000123000123 ÷ 123. Les lignes de soustraction couvraient un espace vide, mais elles ne devraient couvrir que la longueur des chiffres visibles du minuend. C'est réparé maintenant.
Joey Adams
2
Je pense que la sortie est un peu biaisée envers le public de golf anglophone: en.wikipedia.org/wiki/…
hallvabo
Pouvez-vous simplement créer un fichier qui montre la sortie attendue de tous les tests et y lier?
mellamokb
@mellamokb: Ajouté, merci!
Joey Adams
Et accepter? La question est assez vieille ...
Oleh Prypin

Réponses:

3

Python 3, 284 257 caractères

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

Utilisation: python3 div.py
entrée: à partir du clavier

test.py

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

correspond à la sortie attendue

Versions:
 1. 284
 2. 257 : s,z,f=0,0,0s=z=f=0; z and fz*f; meilleure boucle; supprimé quelques nouvelles lignes.

Oleh Prypin
la source
2
vous pouvez essayer ideone pour python3 et entrer - ideone.com/clone/ZZyzu
VOUS
3

Haskell, 320 caractères

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

Réussit tous les tests. Bien que ce soit assez golfé - je pense qu'il reste encore beaucoup à faire ici ...


  • Edit: (344 -> 339) retarde les readappels, ce qui réduit le besoin d'appeler show, suffisamment d'abréviation showcar cela sne vaut pas la peine.
  • Modifier: (339 -> 320) réécrit les fonctions de formatage des champs de chaîne
MtnViewMark
la source
Soigné! J'ai fait une solution Haskell avec 344 caractères, mais je ne l'ai pas publiée. De plus, je ne savais pas que vous pouviez utiliser des symboles Unicode pour les opérateurs (sans -XUnicodeSyntax).
Joey Adams du
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)}

REMARQUE: Aussi tentant que cela puisse paraître de raser quelques caractères en les remplaçant c=(c==0)?par c=!c?, il n'est pas utilisable car il provoque des bogues liés aux virgules flottantes.

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

Exemple d'exécution:

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 : corrections de bugs mineurs, nombreuses optimisations de code.

Edit 2 : Correction d'un bug avec 1/7 générant une sortie supplémentaire.

mellamokb
la source
Le script de test a révélé un problème. d(1,7)(et tests similaires) répéter le dénominateur plutôt que de ne rien imprimer. C'est faux car ce nombre doit être le chiffre du quotient multiplié par le dénominateur, qui est zéro.
Joey Adams
Tous les tests passent maintenant.
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}

Appelez en utilisant i (diviseur, nombre). CodeGolfed JS: http://jsfiddle.net/puckipedia/EP464/ Ungolfed (néerlandais) JS: http://jsfiddle.net/puckipedia/M82VM/

Renvoie la division longue (au format néerlandais tel que je l'ai appris):

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

Cas de test:

document.write("<pre>"+i(5,25)+"</pre>");
document.write("<pre>"+i(7,65669726752476)+"</pre>");
puckipedia
la source
Hé, ce n'est pas le même que requis!
Oleh Prypin
@BlaXpirit Je sais, je l'ai appris de cette façon.
puckipedia
Intéressant. Bien que, comme le dit @BlaXpirit, il ne respecte pas les spécifications. La spécification est censée être une norme de comparaison équitable pour déterminer l'efficacité du code golfé par code, vous ne pouvez donc pas modifier arbitrairement la spécification même si vous n'êtes pas d'accord avec le format de sortie :)
mellamokb