Números mayas ASCII


21

Escriba un programa o función que, dado un entero positivo como entrada, genere la representación de ese entero en números mayas .

Números mayas

Los números mayas son un sistema vigesimal (base 20) que usa solo 3 símbolos:

  • < >para cero (el símbolo correcto es algún tipo de shell que no se puede representar fácilmente con ASCII).
  • .para uno
  • ----para cinco

Los números se escriben verticalmente en potencias de 20, y los números entre 0 y 19 se escriben como pilas de cinco y unos . Deberá consultar el artículo de Wikipedia. para obtener más detalles.

Como ejemplo, aquí están los números entre 0 y 25, separados por comas:

                                                                                 .    ..  ...  ....
                                                        .    ..  ...  .... ---- ---- ---- ---- ----  .    .    .    .    .    .
                               .    ..  ...  .... ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
<  >, .  , .. ,... ,....,----,----,----,----,----,----,----,----,----,----,----,----,----,----,----,<  >, .  , .. ,... ,....,----

Entradas

  • Las entradas siempre son enteros positivos entre 0 y 2147483647 (2 ^ 31 - 1).
  • Puede tomar la entrada de STDIN, como argumento de línea de comando, parámetro de función o algo similar.

Salidas

  • Cada línea tiene como máximo 4 caracteres de longitud. < >y---- siempre debe imprimirse como se indica aquí (4 caracteres de largo cada uno).
  • Unos ( .) deben estar centrados en la línea. Si hay 1 o 3 ., ya que la alineación horizontal perfecta es imposible, no importa si son una columna a la izquierda o una columna a la derecha o al centro.
  • Debe haber exactamente una línea vacía entre las diferentes potencias de 20, independientemente de la altura de las pilas en la potencia de 20 años. Por ejemplo, la salida correcta para 25 y 30 son:

            .
     .
           ----
    ----   ----
    
  • No se permiten líneas iniciales o finales.

  • Las salidas deben imprimirse exactamente como están en los ejemplos dados.

Casos de prueba

  • Cada número individual entre 0 y 25 se da como ejemplo arriba.

  • Entrada: 42

Salida:

 .. 

 .. 
  • Entrada: 8000

Salida:

 .  

<  >

<  >

<  >
  • Entrada: 8080

Salida:

 .  

<  >

....

<  >
  • entrada: 123456789

Salida:

 .  

... 
----
----
----

 .  
----
----

 .. 
----
----

 .  

....
----
----
----

....
----
  • Entrada: 31415

Salida:

... 

... 
----
----
----

----
----

----
----
----
  • Entrada: 2147483647

Salida:

 .  

... 
----
----

 .  
----
----

 .  

----
----
----

....
----

 .. 

 .. 
----

Tanteo

Este es el , por lo que gana el código más corto en bytes.


15 y 20 parecen ser idénticos.
isaacg

@isaacg Gracias, en realidad tuve 15 apareciendo en el lugar correcto y también entre 19 y 20. Solucionado.
Fatalize

@Fatalize ¿Es necesario imprimir la salida (es decir, STDOUT) o puede mi función simplemente devolver la salida?
rink.attendant.6

@ rink.attendant.6 Debe imprimirse exactamente como está en la publicación.
Fatalize

¿Está bien si 1 es una columna a la derecha, pero 3 es una columna a la izquierda?
aragaer

Respuestas:


3

Pyth, 41 bytes

j+bbm|jb_m.[\ 4kc:*d\.*5\.*4\-4"<  >"jQ20

Pruébelo en línea: demostración

Explicación:

                                     jQ20   convert input to base 20
    m                                       map each value d to:
                  *d\.                         string of d points
                 :    *5\.*4\-                 replace 5 points by 4 -s
                c             4                split into groups of 4
         m.[\ 4k                               center each group
        _                                      invert order
      jb                                       join by newlines
     |                         "<  >"          or if 0 use "<  >"
j+bb                                        join by double newlines

5

Perl, 125 117 bytes

$-=<>;{$_=($-%20?(""," .
"," ..
","...
","....
")[$-%5]."----
"x($-/5&3):"<  >
").$_;($-/=20)&&($_=$/.$_,redo)}print

Gracias a Dom Hastings por ayudarme a ahorrar 8 bytes.


1
Hola samgak, un par de bytes más guardando cambios, en lugar de lo redo,if(int($i/=20))que puedes usar ~~($i/=20)&&redo. ~~se convierte en int: también se puede usar 0|al principio (o |0al final). También reemplazar substr(".... ... .. . ",20-$i%5*5,5)con (' .', ' ..','...','.'x4)[$i%5-1].$/parece funcionar bien, pero no he probado todos los casos de prueba ... Si esos funcionan, tienes 114 ... Si pienso en otra cosa para compartir, ¡te lo haré saber!
Dom Hastings

1
Pensando en ello, si solo desea tener un número entero e ignorar el resto, puede usar la variable mágica $-que siempre se truncará en un int ... ¡podría ahorrar algunos más!
Dom Hastings

1
@DomHastings gracias, el truco de conversión int ahorra un par de bytes, y deshacerse de substr ahorra otros 4. Las nuevas líneas deben ir dentro de las constantes de cadena porque no debe haber una nueva línea en el caso de que no haya puntos.
samgak

1
@DomHastings, de hecho, ¡gracias de nuevo! Supongo que eso significa que tengo que deshacerme de mi broma del fin del mundo
samgak

4

JavaScript ES6, 143 bytes

Un montón de bytes agregados porque es necesario console.log, podrían ahorrar otros 23 bytes sin él.

n=>console.log((d=(x,s='',l=1,j=x/l|0)=>s+(j>19?d(x,s,l*20)+`

`:'')+((j=j%20)?(' '+`.`.repeat(j%5)).slice(-4)+`
----`.repeat(j/5):'<  >'))(n))

4

Mathematica 185 182 171 153

Con 18 bytes guardados gracias a la sugerencia de Arcinde de usar funciones anónimas,

c=Column;c[If[#>0,{q,r}=#~QuotientRemainder~5;c@{{""," ."," .."," ...","...."}[[r+1]],c@{{""},{d="----"},{d,d},{d,d,d}}[[q+1]]},"< >"]&/@#~IntegerDigits~20]&

Ejemplo

c[If[# > 0, {q, r} = #~QuotientRemainder~5; c@{{"", " .", " ..", " ...", "...."}[[r + 1]], c@{{""}, {d = "----"}, {d, d}, {d, d, d}}[[q + 1]]}, "< >"] & /@ #~IntegerDigits~20] &[31415]

salida


Comprobación

El número decimal, 31415, expresado en la base 20. Mathematica emplea minúsculas para esto.

BaseForm[31415, 20]

base 20


Los dígitos decimales correspondientes al número base 20 anterior.

IntegerDigits[31415,20]

{3, 18, 10, 15}


Otro ejemplo

IntegerDigits[2147483607, 20]

{1, 13, 11, 1, 15, 9, 0, 7}

c[If[# > 0, {q, r} = #~QuotientRemainder~5;c@{{"", " .", " ..", " ...","...."}[[r + 1]], c@{{""}, {d = "----"}, {d, d}, {d, d, d}}[[q + 1]]},"< >"] & /@ #~IntegerDigits~20] &[2147483607]

ex2


c=Column;c[If[#>0,{q,r}=#~QuotientRemainder~5;c@{{""," ."," .."," ...","...."}[[r+1]],c@{{""},{d="----"},{d,d},{d,d,d}}[[q+1]]},"< >"]&/@#~IntegerDigits~20]&utilizando funciones anónimas.
jcai

@Arcinde, gracias. Buenas funciones anónimas.
DavidC

3

JavaScript (ES6), 157 bytes

Las nuevas líneas son significativas y se cuentan como 1 byte cada una. Como se requiere imprimir en STDOUT, console.logme costó unos pocos bytes allí.

f=i=>console.log([...i.toString(20)].map(j=>(!(j=parseInt(j,20))||j%5?[`<  >`,` .`,` ..`,`...`,`....`][j%5]+`
`:'')+`----
`.repeat(j/5)).join`
`.slice(0,-1))

Manifestación

Para fines de demostración, escribiré una versión ES5 para que funcione en todos los navegadores:

// Snippet stuff
console.log = function(x) {
  O.innerHTML = x;
}
document.getElementById('I').addEventListener('change', function() {
  f(this.valueAsNumber);
}, false);

// Actual function
f = function(i) {
  console.log(i.toString(20).split('').map(function(j) {
    return (! (j = parseInt(j, 20)) || j % 5 ? ['<  >', ' .', ' ..', '...', '....'][j % 5] + '\n' : '') + '----\n'.repeat(j / 5);
  }).join('\n').slice(0,-1));
}
<input type=number min=0 max=2147483647 value=0 id=I>

<pre><output id=O></output></pre>


¿El último .joinnecesita paréntesis?
Downgoat


@vihan Eso no genera nada, solo regresa.
rink.attendant.6

no sabía que era un requisito ya que la entrada puede ser a través de una función. pastebin.com/0pS0XtJa es 3 bytes más corto
Downgoat

2

Python 2.x, 142 bytes:

def m(n):
 h=[[""," "*(2-n%5/2)+"."*(n%5)+"\n"][n%5!=0]+"----\n"*(n%20/5),"<  >\n"][n%20==0]
 n/=20
 if n>0:
  h=m(n)+"\n\n"+h
 return h[:-1]

Ejemplo:

>>> print m(2012)
----

<  >

 ..
----
----
>>> 

Editar: línea final ...


Tengo algunas mejoras que sugerir. Primero, cambie [n%20==0]a [n%20<1]. En segundo lugar, cambie [[""," "*(2-n%5/2)+"."*(n%5)+"\n"][n%5!=0]a h=[(" "*(2-a/2)+"."*a+"\n")*(a>0)+"----\n"*(n%20/5),"< >\n"][n%20<1]con a=n%5, que mueve todos los n%5correos electrónicos y cambia el condicional al *(a>0)que devuelve una cadena vacía en a==0para el mismo efecto.
Sherlock9

Por último, poner a, hy nen una sola línea, así: a=n%5;h=[(" "*(2-a/2)+"."*a+"\n")*(a>0)+"----\n"*(n%20/5),"< >\n"][n%20<1];n/=20. Todo esto debería dejarte con 131 bytes.
Sherlock9

2

CJam, 82 76 bytes

li{_K%[""" .
"" ..
""...
""....
"]1$5%='-4*N+2$5/3&*+"<  >
"?N+L+:L;K/}h;L);

Mi primer programa CJam, básicamente solo una transcripción de mi respuesta de Perl a CJam.

Probar en línea

Multilínea con comentarios:

li            # read input
{             # start of do-while loop
  _K%         # check if this base-20 digit is a zero
    [""" .
    "" ..
    ""...
    ""....
    "]1$5%=   # push dots for 1s onto stack
    '-4*N+2$5/3&*+    # push lines for 5s onto stack

    "<  >
    "         # push zero on stack
  ?           # ternary if test (for digit equals zero)
  N+L+:L;     # pre-concatenate string with output plus newline
  K/          # divide by 20
}h            # end of do while loop
;L);          # push output string on stack, chop off trailing newline

1

PHP, 220 bytes

El mismo enfoque que mi respuesta de JavaScript. PHP tiene funciones integradas para todo.

Toma 1 entrada de la línea de comando (es decir, STDIN), como se ve con $argv[1]:

<?=rtrim(implode("\n",array_map(function($j){return(!($j=base_convert($j,20,10))||$j%5?['<  >', ' .', ' ..', '...', '....'][$j%5]."\n":'').str_repeat("----\n",$j/5);},str_split(base_convert($argv[1],10,20)))));

1

C - 149

f(v){v/20&&(f(v/20),puts("\n"));if(v%=20)for(v%5&&printf("%3s%s","...."+4-v%5,v/5?"\n":""),v/=5;v--;v&&puts(""))printf("----");else printf("<  >");}

Utiliza la recursividad para imprimir primero los números más significativos. Luego, imprime cero o imprime todos los puntos con uno inteligente printf y todos los cinco en un bucle. No estoy seguro si puedo evitar usar if-else aquí.

La desventaja de smart printf es que 1 y 3 no están alineados entre sí:

El resultado para 23 es:

  .

...

119 solución incorrecta - nueva línea final

f(v){v/20&&(f(v/20),puts(""));if(v%=20)for(v%5&&printf("%3s\n","...."+4-v%5),v/=5;v--;)puts("----");else puts("<  >");}


1

PHP, 202 192 bytes

function m($n){return(($c=($n-($r=$n%20))/20)?m($c)."\n":"").
($r?(($q=$r%5)?substr(" .   .. ... ....",$q*4-4,4)."\n":"").
str_repeat("----\n",($r-$q)/5):"<  >\n");}
echo rtrim(m($argv[1]),"\n");

Obtiene la entrada del primer argumento de línea de comando.

El código fuente completo, con comentarios y pruebas, está disponible en github .


\ntiene dos caracteres, pero una nueva línea en el medio de una cadena es solo uno.
fisharebest

1

Python 2, 114 bytes

Esta respuesta se basa en la respuesta Pyth de Jakube y la respuesta Python 2 de Locoluis.

def f(n):d,m=divmod(n%20,5);h=[" "*(2-m/2)+"."*m+"\n----"*d,"<  >"][n%20<1];n/=20;return(f(n)+"\n\n"if n else"")+h

0

Jalea , 50 49 47 bytes

b5µṪ”.x⁶;$L<3Ɗ¡ṭ⁾--;UW¤ẋ$Ẏ$L¡Ṛø“<  >”WµẸ?
b20Ç€

Pruébalo en línea!

... ahora queda alineado gracias al punto user202729.

Cuando te engañas para pensar < >es un palíndromo ...


¿Por qué alineas bien ......
User202729

@ user202729 Para .y ..debe haber un espacio, así que pongo uno para ...también. ¿Hay un camino más corto?
dylnan

Creo que de acuerdo con la especificación del desafío ...no debería estar alineado a la derecha. Solo cambia <4a <3?
user202729

@ user202729 Tienes razón, creo que leí mal las especificaciones. No creo que especifique para ... pero puedo cambiarlo a <2
dylnan
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.