Números mayas de arte ASCII

14

Este desafío es simple. Dado un número, genera una representación ascii-art del número, utilizando el sistema de numeración Maya Base 20.

¿Qué es el sistema maya?

Los mayas usaban la base 20 para almacenar números, por lo que la primera posición era el 1lugar 20s, luego el lugar s, luego el 400s, etc.

Entonces, el número maya 1está 1en la base 10, pero en 10realidad está 20en la base 10, 207está 807en la base 10, etc.

Y representaron sus números como pictogramas, con un símbolo especial para 0.

 -------------------
|    |    |    |    |
|    |    |    |    |
|-------------------|
|                   |
|                   |
 ------------------- 

Ese era su cero. (Al menos la mitad picascii la mitad de mi artística ascii versión artística)

Esa es una imagen real del símbolo maya cero. 1

Estos fueron sus cinco:

--------------------------------
|                              |
--------------------------------

Y un 4:

 ----   ----   ----   ----  
|    | |    | |    | |    | 
|    | |    | |    | |    | 
 ----   ----   ----   ----  

Finalmente, para armarlo:

 ----   ----   ----  
|    | |    | |    | 
|    | |    | |    | 
 ----   ----   ----  
--------------------------------
|                              |
--------------------------------
--------------------------------
|                              |
--------------------------------

Entonces tienen x//5barras y x%5puntos en la parte superior de las barras. Y si x=0, usan el shell / loaf en lugar de un espacio en blanco.

Para obtener más imágenes, prueba la página Wikimedia Commons de imágenes de números mayas .

Pero esto es solo para números hasta 19. No se nos permite tener más que 4barras y 4puntos en una sola 'historia' ... ¡Así que subimos!

La salida para 20 es:

 ----
|    |
|    |
 ----



 -------------------
|    |    |    |    |
|    |    |    |    |
|-------------------|
|                   |
|                   |
 ------------------- 

Tenga en cuenta que esto normalmente no sería válido, ya que tiene a 1y 0a al mismo tiempo. Pero 3(tenga en cuenta que su respuesta necesita al menos 3) nuevas líneas antes de la 0media de un nuevo valor posicional.

La historia inferior tiene puntos, significado 1y barras de significado 5. Pero en realidad tiene puntos 20^0y barras de significado 20^0 * 5.

Cada historia sube a un poder. Los puntos de la segunda historia significan 20( 20^1) y 100( 20^1 * 5).

Entonces el número 506se puede representar como:

 ----  
|    | 
|    | 
 ----  




--------------------------------
|                              |
--------------------------------




 ----  
|    | 
|    | 
 ----  
--------------------------------
|                              |
--------------------------------

Esto es (20^0) * 1 + (20^0 * 5) * 1 + (20^1 * 5) * 1 + (20^2) * 1 = 1 + 5 + 100 + 400 = 506.

Su misión, si elige no elegir (no importa), es generar una representación de arte ascii del número de base 10.

Otras reglas:

  • El espacio inicial / final está bien, siempre y cuando los puntos, barras y conchas estén intactos.
  • Las barras, puntos y conchas deben ser exactamente lo que tienen los casos de prueba. Sin cambio de tamaño.
  • Los primeros 0 están bien. (shells principales en la salida)
  • No tiene que tener exactamente 3 líneas nuevas entre cada valor posicional o historia, solo al menos 3.

Casos de prueba:

15

--------------------------------
|                              |
--------------------------------
--------------------------------
|                              |
--------------------------------
--------------------------------
|                              |
--------------------------------  

12

 ----   ----  
|    | |    | 
|    | |    | 
 ----   ----  
--------------------------------
|                              |
--------------------------------
--------------------------------
|                              |
--------------------------------



4

 ----   ----   ----   ----  
|    | |    | |    | |    | 
|    | |    | |    | |    | 
 ----   ----   ----   ----  


0

 -------------------
|    |    |    |    |
|    |    |    |    |
|-------------------|
|                   |
|                   |
 ------------------- 


24

 ----  
|    | 
|    | 
 ----  




 ----   ----   ----   ----  
|    | |    | |    | |    | 
|    | |    | |    | |    | 
 ----   ----   ----   ----  



33



 ----  
|    |  
|    | 
 ----  




 ----   ----   ----  
|    | |    | |    | 
|    | |    | |    | 
 ----   ----   ----  
--------------------------------
|                              |
--------------------------------
--------------------------------
|                              |
--------------------------------



20



 ----  
|    | 
|    | 
 ----  




 -------------------
|    |    |    |    |
|    |    |    |    |
|-------------------| 
|                   |
|                   |
 -------------------  

1: También usaron las cabezas de dioses para los símbolos, pero para este desafío se usará el cofre de concha / pan / zelda .

Rɪᴋᴇʀ
fuente
but for this challenge the shell/bread will be used.. Sin cáscara, no pan. Enlace LOZ al cofre pasado.
Bald Bantha
@epicTCK .... que es en realidad muy parecido ...
Rɪᴋᴇʀ
1
Relacionado.
Martin Ender

Respuestas:

4

Ruby, 223 180 177 179 bytes

Función anónima, devuelve una cadena multilínea.

Olvidé agregar algo de espacio extra que era necesario, y también la recursividad. También jugué un poco más al cambiar las cosas.

f=->n{s=?|;e=' ';n<20?(n<1?[t=e+d=?-*19,a=s+(e*4+s)*4,a,s+d+s,b=s+e*19+s,b,t]:((r=n%5)>0?[t=" ----  "*r,m="|    | "*r,m,t]:[])+[a=?-*32,s+e*30+s,a]*(n/5))*$/:f[n/20]+$/*5+f[n%20]}
Tinta de valor
fuente
Eres el más golfista. ¡Felicidades!
Rɪᴋᴇʀ
6

Python 3.5, 404 400 392 312 311 308 290 281 285 281 bytes:

Gracias a Adnan por un consejo sobre el ahorro de 9 bytes ( 290->281) y Neil por un consejo sobre el ahorro de 4 bytes ( 285->281)! )

def u(z):
 p=[];P=print;S,N,M,X=' -|\n'
 while not p or z:p+=[z%20];z=z//20
 E=lambda i:(S+N*4+S)*i+X+((M+S*4+M)*i+X)*2+(S+N*4+S)*i+X;F=N*32+X+M+S*30+M+X+N*32+X;[P(S+N*19+S+X+M+((S*4+M)*4+X+M)*2+N*19+M+X+(M+S*19+M+X)*2+S+N*19+S+X*3)if y<1else P(E(y%5)+F*(y//5)+X*3)for y in p[::-1]]

Pruébalo en línea! (Ideona)

Análisis

Para los fines de este análisis, utilizaremos el conjunto de caracteres 0123456789ABCDEFGHIJpara representar cada dígito en la base 20.

Entonces, podría haber ido y convertir la base 10 en base 20 usando uno de los dos algoritmos que tengo. El primer algoritmo que pensé en usar es lo que llamo . Pero básicamente, lo que sucede es que toma el número base 10 proporcionado y lo divide por la base a la que necesita convertir el número, que en este caso es 20, hasta que el resto sea 0 o 1. Luego toma el cociente y el resto , en ese orden, desde la última operación de división, y luego todos los demás restos de las otras operaciones de división en el orden de último a primero. Todos estos dígitos se unen, y esa secuencia unida algoritmo de poderes . Sin embargo, este no es el que utilicé en el código, ya que habría sido mucho más largo de lo que debería haber sido, por lo que no voy a hablar sobre este. Sin embargo, creé un script de Python que convierte cualquier número entero en la base 10 en cualquier otra base proporcionada usando este método, que puede usar aquí en repl.it. El que utilicé para este desafío es lo que llamo el algoritmo de división , que creo que se explica bastante bien aquí invertida es su número de base 10 en la base 20! Para ilustrar esto, suponga que desea convertir el número de base 10 431en base 20. Entonces, lo que haríamos es esto:

[]=list we will put all remainders and the last quotient in
R = Remainder

1. 431/20 = 21 R11 [B (B=11 in base 20)]
2. 21/20 = 1 R1 [Add the remainder and quotient: B11]

Luego, finalmente tomaríamos la lista que tenemos, que en este caso contiene B11, y la revertiríamos para que ahora la tengamos 11B. Al hacer esto, finalmente tenemos nuestra respuesta final. 431 en base 10 convertido a base 20 es 11B, lo que se puede confirmar usando mi script Python que usa el algoritmo de poderes con el que ya he compartido un enlace anterior, pero lo volveré a hacer aquí . Aquí hay uno que también usa el algoritmo de división descrito en esta respuesta y devuelve la misma respuesta que la potencia.

Todo este proceso es esencialmente lo que sucede en mi script en este whileciclo:while not p or z:p+=[z%20];z=z//20 . La única diferencia es que los números >9son no representan como letras, sino más bien como ellos mismos.

Continuando, después de que el número de base 10 se haya convertido a base 20, para cada dígito en el entero de base 20, al que llamaremos g, g mod 5se imprimen puntos y luego g//5se imprimen barras. Luego, el programa imprime 3 líneas en blanco y pasa al siguiente dígito. Sin embargo, si el dígito es 0, entonces se imprime un solo "pan" seguido de 3 líneas nuevas, y luego el programa pasa al siguiente dígito. Entonces, tomando el número base 20 11B, pasamos al primer dígito. El primer dígito es 1y, por lo tanto, imprimiría 0 barras desde entonces 1//5=0y 1 punto desde entonces 1%5=1. Entonces, primero obtendríamos esto:

 ---- 
|    |
|    |
 ---- 

y luego 3 nuevas líneas. Pasando al segundo dígito, también vemos que es 1, por lo que generaría lo mismo:

 ---- 
|    |
|    |
 ---- 

y también 3 nuevas líneas. Finalmente, pasando al último dígito, vemos que es un B. Dado que B=11en la base 20, el programa generaría 1 punto desde 11%5=1y 2 barras desde entonces 11//5=2. Entonces, obtenemos esto:

 ---- 
|    |
|    |
 ---- 
--------------------------------
|                              |
--------------------------------
--------------------------------
|                              |
--------------------------------

Finalmente, juntando todo esto, obtenemos esto:

 ---- 
|    |
|    |
 ---- 




 ---- 
|    |
|    |
 ---- 




 ---- 
|    |
|    |
 ---- 
--------------------------------
|                              |
--------------------------------
--------------------------------
|                              |
--------------------------------

¡Y ese es el número maya para 431! Finalmente tienes tu número base 10 representado en números mayas base 20.

Nota: Puede o no haber notado esa lambdafunción en mi código. Independientemente, esta función se utiliza para la creación de puntos, ya que se deben generar varios puntos uno al lado del otro.

R. Kap
fuente
No estoy seguro de si es posible, pero ¿puedes hacerlo en S,N,M,X=' -|\n'lugar de hacerlo S,N,M,X=' ','-','|','\n'?
Adnan
@Adnan eso es posible.
Rɪᴋᴇʀ
@Adnan ¿En serio? Wow, no lo sabía. ¡Gracias!
R. Kap
401contiene un cero interior.
Neil
@Neil Oh, cierto. Gracias por el aviso. Ya está arreglado.
R. Kap
3

Python 3, 243 bytes

s,v,h,x=' |-\n';P=print
t=s+h*19+s+x
def m(n):
 n//20and m(n//20);r=n%20
 if r:
  for a,b,f in[(r%5*' ----  ',r%5*'|    | ',1),('-'*32,'|'+' '*30+'|',r//5)]:P(*((a,b,b,a)*f),sep=x)
 else:P(t+2*(v+(4*s+v)*4+x)+v+h*19+v+x+2*(v+s*19+v+x)+t)
 P(x)

Discusión

n//20and m(n//20)llama m()recursivamente si hay poderes superiores de 20 para ser manejados. La recursión se realiza antes de imprimir el valor posicional actual, de modo que las potencias más altas se impriman primero.

Si el valor posicional actual no es cero (r! = 0), el for a,b,fbucle imprime las unidades y luego los cinco. aes la primera / cuarta fila y bes la segunda / tercera fila. El truco está en el print(*((a,b,b,a)*f),sep=x). Para las unidades, f = 1 resulta en print(*(a,b,b,a),sep=x), que imprime las 4 filas que componen los símbolos de las unidades (x es un '\ n'). Para los cinco, f = el número de cinco para imprimir (r // 5), por lo que la tupla (a, b, b, a) se multiplica (es decir, se repite) por el número de cinco para imprimir. Si f = 2, obtenemos print(*(a,b,b,a,a,b,b,a),sep=x), que imprime dos símbolos para cinco.

Si el valor posicional actual es 0, se imprime el símbolo cero.

RootTwo
fuente
Tuve que recompensar la recompensa a R. Kap, ¡pero esto podría merecer su propia recompensa! ¡Buen trabajo!
Rɪᴋᴇʀ
2

Python, 411 bytes

w,m=input(),[]
for i in[20**i for i in range(int(w**0.25))][::-1]:m.append(w/i);w=w%i
for i in m or[0]:print(lambda x,y='\n',w=' ----  ',z='|    | ':w*(x%5)+y+z*(x%5)+y+z*(x%5)+y+w*(x%5)+y+('-'*32+'\n|'+' '*30+'|\n'+'-'*32+y)*(x/5)if x else''' -------------------
|    |    |    |    |
|    |    |    |    |
|-------------------|
|                   |
|                   |
 ------------------- ''')(i),'\n\n\n'

Creé esto para generar casos de prueba, puede usarlo como punto de referencia. Sorta golf.

Rɪᴋᴇʀ
fuente
Puede quitar 26 bytes eliminando espacios en blanco, y otros 4 haciendo s=math.sqrty llamando en s(s(w))lugar demath.sqrt(math.sqrt(w))
DJMcMayhem
@DrGreenEggsandHamDJ gracias. Sin embargo, ¿no creo que tenga 26 bytes de espacio en blanco?
Rɪᴋᴇʀ
Oh, lo siento, contando el error que quise decir 25. Además, w**0.25es incluso mejor que s(s(w)). Aunque se hizo más largo?
DJMcMayhem
@DrGreenEggsandHamDJ sí, de alguna manera perdí la cadena de shell cero en tránsito del archivo a la respuesta.
Rɪᴋᴇʀ
2

JavaScript (ES6), 254 bytes

f=(n,r=(s,n=19)=>s.repeat(n))=>(n>19?f(n/5>>2)+`


`:``)+(n%5?`${r(s=` ----  `,n%5)}
${t=r(`|    | `,n%5)}
${t}
${s}
`:``)+r(`${s=r(`-`,32)}
|${r(` `,30)}|
${s}
`,n/5&3)+(n%20?``:` ${s=r(`-`)}
${t=r(`|    `,4)}|
${t}|
|${s}|
|${t=r(` `)}|
|${t}|
 ${s}
`)
Neil
fuente
¿No puedo hacer que esto funcione? Se equivoca con Missing } in template expression. No sé mucho js, ​​¿cómo puedo solucionarlo?
Rɪᴋᴇʀ
@ EᴀsᴛᴇʀʟʏIʀᴋ Lo malo, moví un código y lo pegué accidentalmente en el lugar equivocado. Ya está arreglado.
Neil
1

Python 3, 213 bytes

Se le ocurrió una versión aún más corta con un enfoque diferente:

s,v,h,x=' |-\n'
t=s+h*19+s
k=4*s+v
w=v+4*k
y=v+s*19+v
a=' ----  '
b=v+k+s
c=h*32
d=v+s*30+v
m=lambda n:m(n//20)+([n%5*a,n%5*b,n%5*b,n%5*a][:n%5*4]+n%20//5*[c,d,d,c]if n%20else[t,w,w,v+h*19+v,y,y,t])+[x,x]if n else[]

explicación

Las primeras 9 líneas más o menos, crean cadenas que se utilizan para hacer los símbolos.

s,v,h,x = ' |-\n'
k = '    |'

    # parts for a unit
a = ' ----  '
b = '|    | '

    # parts for a five
c = '--------------------------------'
d = '|                              |'

    # parts for a zero
t = ' ------------------- '
w = '|    |    |    |    |'
y = '|                   |'

El núcleo de la solución es la función recursiva m, que construye una lista de cadenas, una cadena para cada línea en la salida. Esquemáticamente, se mve así:

m(n//20) + (ones + fives if n%20 else zero) + [x,x] if n else []

m puede reescribirse como:

def m(n):
  if n:
    ans = m(n//20)                             # process high digits first

    if n%20:                                   # if there is a base-20 digit
      ans += [n%5*a,n%5*b,n%5*b,n%5*a][:n%5*4] # add strings for the 'ones' if any
      ans += n%20//5 * [c, d, d, c]            # add strings for the 'fives' if any

    else:
      ans += [t,w,w,v+h*19+v,y,y,t]            # otherwise, add strings for a `zero`

    ans += [x,x]                               # blank lines between digit groups

  else:
    ans = []                                   # base case

  return ans

La llamada recursiva m(n//20)viene primero para que los dígitos más significativos se hagan primero.

[n%5*a,n%5*b,n%5*b,n%5*a]son la cadena de unos símbolos. aes la fila superior para un solo símbolo. n%5es el número de un símbolo para este dígito. Entonces, n%5*aes una cadena para la fila superior (e inferior) de n%5unos. Del mismo modo, 'n% 5 * b` es una cadena para la segunda (y tercera) fila.

La expresión [:n%5*4]actúa como unif para evitar líneas en blanco adicionales en la salida si no hay 'unos' para la salida. No es necesario, pero hace que la salida se vea mejor.

n%20//5es la cantidad de símbolos para cinco que se necesitan. [c,d,d,c]son las cadenas para hacer un símbolo para cinco.

[t,w,w,v+h*19+v,y,y,t] son las cadenas para hacer el símbolo cero

[x,x] pone al menos tres líneas en blanco entre grupos de dígitos mayas

RootTwo
fuente
¿Puedes dar una explicación de cómo funciona esto?
Rɪᴋᴇʀ