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.


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.


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

¡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.


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

¡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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.