Visualice una división larga con arte ASCII

16

Escriba un programa que visualice una división larga con el arte ASCII. La entrada consta de dos enteros, un numerador y un denominador, utilizando el formato de entrada que elija.

Ejemplos:

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

Reglas:

  • El uso del operador de división del lenguaje de programación es permitido.
  • El uso de soporte de enteros grandes también está permitido.
  • Por consistencia:
    • Si el cociente es cero, imprima un solo cero al final del trampolín.
    • Si el resto es cero, no lo imprima.
    • No imprima ceros a la izquierda en ningún número.
  • Se permiten líneas nuevas en exceso al final y espacios finales a la derecha.
  • La solución con la menor cantidad de personajes gana.

Límites:

  • 0 <= numerador <= 10 72 - 1
  • 1 <= denominador <= 9999999

Esto implica que el resultado nunca será más ancho que 80 columnas.

Conjunto de pruebas e implementación de muestra:

Puede usar long-division.c ( gist ) para probar su programa. En realidad es un script bash con un programa en C dentro. Ajústelo para invocar su programa en el conjunto de pruebas. Mire el código C en la parte inferior para ver la implementación de referencia. Avíseme si hay algún problema con el programa de muestra o el conjunto de pruebas.

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

Editar: a pedido, pongo la entrada del conjunto de pruebas y la salida esperada en archivos de texto ( gist ). Uso de muestra (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

Los comandos sed extraños filtran las nuevas líneas y espacios finales de la salida del programa.

Joey Adams
fuente
Descubrí un pequeño defecto en la implementación de referencia, es decir, en el caso de 123000123000123 ÷ 123. Las líneas de resta abarcaban el espacio en blanco, pero solo deberían abarcar la longitud de los dígitos visibles del minuendo. Ya está arreglado.
Joey Adams
2
Creo que la salida está un poco sesgada hacia la audiencia de golf de habla inglesa: en.wikipedia.org/wiki/…
hallvabo
¿Puedes crear un archivo que muestre el resultado esperado de todas las pruebas y vincularlo?
mellamokb
@mellamokb: Añadido, ¡gracias!
Joey Adams
¿Qué hay de aceptar? La pregunta tiene edad suficiente ...
Oleh Prypin

Respuestas:

3

Python 3, 284 257 caracteres

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

Uso: python3 div.py
Entrada: desde el teclado

prueba.py

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

salida partidos esperada

Versiones:
 1. 284
 2. 257 : s,z,f=0,0,0s=z=f=0; z and fz*f; mejor bucle; eliminado algunas líneas nuevas.

Oleh Prypin
fuente
2
puede probar ideone para python3 y entrada - ideone.com/clone/ZZyzu
USTED
3

Haskell, 320 caracteres

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

Pasa todas las pruebas. Si bien es esto bastante golf, creo que todavía hay mucho más por hacer aquí ...


  • Editar: (344 -> 339) retrasar las readllamadas, lo que reduce la necesidad de llamar show, lo suficiente showcomo para abreviar ya sque no vale la pena.
  • Editar: (339 -> 320) reescribió las funciones de formato de campo de cadena
MtnViewMark
fuente
¡Ordenado! Hice una solución de Haskell con 344 caracteres, pero no la publiqué. Además, no sabía que podía usar símbolos Unicode para operadores (sin -XUnicodeSyntax).
Joey Adams
3

JavaScript ( 400394 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)}

NOTA: por tentador que parezca eliminar algunos caracteres reemplazándolos c=(c==0)?con c=!c?, no es utilizable porque causa errores relacionados con el punto flotante.

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

Ejecución de muestra:

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

Edición 1 : correcciones de errores menores, numerosas optimizaciones de código.

Edición 2 : corrige el error con 1/7 generando salida adicional.

mellamokb
fuente
El guión de prueba reveló un problema. d(1,7)(y pruebas similares) repite el denominador en lugar de no imprimir nada. Esto está mal porque este número debe ser el dígito del cociente multiplicado por el denominador, que es cero.
Joey Adams
Todas las pruebas pasan ahora.
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}

Invocar usando i (divisor, número). Codegolfed JS: http://jsfiddle.net/puckipedia/EP464/ Ungolfed (holandés) JS: http://jsfiddle.net/puckipedia/M82VM/

Devuelve la división larga (en formato holandés como la aprendí):

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

Caso de prueba:

document.write("<pre>"+i(5,25)+"</pre>");
document.write("<pre>"+i(7,65669726752476)+"</pre>");
puckipedia
fuente
¡Hey, esto no es lo mismo que se requiere!
Oleh Prypin
@BlaXpirit Lo sé, lo aprendí de esa manera.
puckipedia
Interesante. Aunque como dice @BlaXpirit, no sigue las especificaciones. La especificación está destinada a ser un estándar de comparación justo para determinar la eficiencia del código con código de golf, por lo que no puede cambiar arbitrariamente la especificación incluso si no está de acuerdo con el formato de salida :)
mellamokb