Numeri Maya ASCII


21

Scrivi un programma o una funzione che, dato un numero intero positivo come input, genera la rappresentazione di quel numero intero in numeri Maya .

Numeri Maya

I numeri Maya sono un sistema vigesimale (base 20) che utilizza solo 3 simboli:

  • < >per Zero (il simbolo corretto è una sorta di shell che non può essere facilmente rappresentata usando ASCII).
  • .per Uno
  • ----per cinque

I numeri sono scritti verticalmente con potenze di 20, e i numeri tra 0 e 19 sono scritti come pile di cinque e uno . Far riferimento all'articolo di Wikipedia per maggiori dettagli.

Ad esempio, ecco i numeri tra 0 e 25, separati da virgole:

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

ingressi

  • Gli ingressi sono sempre numeri interi positivi compresi tra 0 e 2147483647 (2 ^ 31 - 1).
  • È possibile prendere l'input da STDIN, come argomento della riga di comando, parametro della funzione o qualcosa di simile.

Uscite

  • Ogni riga è lunga al massimo 4 caratteri. < >e ----dovrebbe essere sempre stampato come indicato qui (lungo 4 caratteri ciascuno).
  • Uno ( .) deve essere centrato sulla linea. Se ce ne sono 1 o 3 ., poiché è impossibile un perfetto allineamento orizzontale, non importa se sono una colonna a sinistra o una colonna a destra o al centro.
  • Ci deve essere esattamente una linea vuota tra potenze diverse di 20, indipendentemente dall'altezza delle pile nella potenza di 20s. Ad esempio, l'output corretto per 25 e 30 sono:

            .
     .
           ----
    ----   ----
    
  • Non sono consentite linee iniziali o finali.

  • Gli output devono essere stampati esattamente come negli esempi forniti.

Casi test

  • Ogni singolo numero compreso tra 0 e 25 fornito come esempio sopra.

  • Ingresso: 42

Produzione:

 .. 

 .. 
  • Ingresso: 8000

Produzione:

 .  

<  >

<  >

<  >
  • Ingresso: 8080

Produzione:

 .  

<  >

....

<  >
  • ingresso: 123456789

Produzione:

 .  

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

 .  
----
----

 .. 
----
----

 .  

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

....
----
  • Ingresso: 31415

Produzione:

... 

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

----
----

----
----
----
  • Ingresso: 2147483647

Produzione:

 .  

... 
----
----

 .  
----
----

 .  

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

....
----

 .. 

 .. 
----

punteggio

Questo è , quindi vince il codice più breve in byte.


15 e 20 sembrano identici.
isaacg,

@isaacg Grazie, in realtà ne ho mostrati 15 sia nel punto giusto che tra 19 e 20. Risolto.
Fatalizza il

@Fatalize L'output deve essere stampato (ad es. STDOUT) o la mia funzione può semplicemente restituire l'output?
rink.attendant.6

@ rink.attendant.6 Deve essere stampato esattamente come nel post.
Fatalizza il

Va bene se 1 è una colonna a destra, ma 3 è una colonna a sinistra?
Aragaer,

Risposte:


3

Pyth, 41 byte

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

Provalo online: dimostrazione

Spiegazione:

                                     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 byte

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

Grazie a Dom Hastings per avermi aiutato a salvare 8 byte.


1
Ehi Samgak, un altro paio di modifiche al salvataggio dei byte, piuttosto che redo,if(int($i/=20))puoi usarle ~~($i/=20)&&redo. ~~converte in int: puoi anche usarlo 0|all'inizio (o |0alla fine). Anche la sostituzione substr(".... ... .. . ",20-$i%5*5,5)con (' .', ' ..','...','.'x4)[$i%5-1].$/sembra funzionare bene, ma non ho testato tutti i casi di test ... Se quelli funzionano, sei giù a 114 ... Se penso a qualcos'altro da condividere ti farò sapere!
Dom Hastings,

1
Pensandoci, se vuoi sempre avere un numero intero e ignorare il resto, puoi usare la variabile magica $-che troncerà sempre in un int ... potrebbe salvarne un altro!
Dom Hastings,

1
@DomHastings grazie, il trucco di conversione int salva un paio di byte e liberarsi del substr ne salva un altro 4. Le newline devono andare all'interno delle costanti della stringa perché non ci deve essere una nuova riga nel caso in cui non ci siano punti.
Samgak,

1
@DomHastings sì, grazie ancora! Immagino che ciò significhi che devo liberarmi della mia battuta sulla fine del mondo
samgak,

4

JavaScript ES6, 143 byte

Carichi di byte aggiunti perché necessari console.log, potrebbero salvare altri 23 byte senza di essa.

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 byte salvati grazie al suggerimento di Arcinde di utilizzare funzioni anonime,

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

Esempio

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

produzione


verifica

Il numero decimale, 31415, espresso in base 20. Mathematica impiega lettere minuscole per questo.

BaseForm[31415, 20]

base 20


Le cifre decimali corrispondenti al precedente numero base 20.

IntegerDigits[31415,20]

{3, 18, 10, 15}


Un altro esempio

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]&utilizzando funzioni anonime.
jcai,

@Arcinde, grazie. Buone vecchie funzioni anonime.
DavidC,

3

JavaScript (ES6), 157 byte

Le newline sono significative e vengono contate come 1 byte ciascuna. Poiché è richiesta la stampa su STDOUT, console.logmi costa qualche byte lì.

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

dimostrazione

A scopo dimostrativo scriverò una versione ES5 in modo che funzioni in tutti i browser:

// 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>


L'ultima .joinnecessita di parentesi?
Downgoat,


@vihan Questo non produce nulla, ma semplicemente ritorna.
rink.attendant.6

non sapevo che fosse un requisito dato che l'input può essere attraverso una funzione. pastebin.com/0pS0XtJa è più corto di 3 byte
Downgoat il

2

Python 2.x, 142 byte:

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]

Esempio:

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

<  >

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

Modifica: linea finale ...


Ho alcuni miglioramenti da suggerire. Innanzitutto, cambia [n%20==0]in [n%20<1]. In secondo luogo, cambia [[""," "*(2-n%5/2)+"."*(n%5)+"\n"][n%5!=0]in h=[(" "*(2-a/2)+"."*a+"\n")*(a>0)+"----\n"*(n%20/5),"< >\n"][n%20<1]con a=n%5, che sposta tutte le n%5s fuori, e cambia il condizionale al *(a>0)quale restituisce una stringa vuota a==0per lo stesso effetto.
Sherlock9,

Infine, mettere a, he nsu una linea, in questo modo: a=n%5;h=[(" "*(2-a/2)+"."*a+"\n")*(a>0)+"----\n"*(n%20/5),"< >\n"][n%20<1];n/=20. Tutto ciò dovrebbe lasciarti con 131 byte.
Sherlock9,

2

CJam, 82 76 byte

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

Il mio primo programma CJam, sostanzialmente solo una traslitterazione della mia risposta Perl a CJam.

Prova online

Multiriga con commenti:

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 byte

Stesso approccio della mia risposta JavaScript. PHP ha funzioni integrate per tutto.

Prende 1 input dalla riga di comando (cioè STDIN), come visto 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("<  >");}

Utilizza la ricorsione per stampare prima i numeri più significativi. Quindi stampa zero o stampa tutti i punti con uno intelligente printf e tutti i cinque in un ciclo. Non sono sicuro di poter evitare di usare if-else qui.

Il rovescio della medaglia di printf intelligente è che 1 e 3 non sono allineati tra loro:

Il risultato per 23 è:

  .

...

119 soluzione errata - newline finale

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 byte

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

Ottiene l'input dal primo argomento della riga di comando.

Il codice sorgente completo, con commenti e test, è disponibile su github .


\nè composto da due caratteri, ma una nuova riga nel mezzo di una stringa è solo una.
fisharebest,

1

Python 2, 114 byte

Questa risposta si basa sulla risposta Pyth di Jakube e sulla risposta Python 2 di 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

Gelatina , 50 49 47 byte

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

Provalo online!

... ora è allineato a sinistra grazie al punto di user202729.

Quando ti inganni a pensare < >è un palindromo ...


Perché allineare a destra ......
user202729

@ user202729 Per .e ..ci deve essere uno spazio, quindi ne metto uno ...anche io . C'è un modo più breve?
dylnan,

Penso che secondo le specifiche della sfida ...non dovrebbe essere allineato a destra. Passa <4a <3?
user202729

@ user202729 Hai ragione, penso di aver letto male le specifiche. Non credo che specifichi per ... ma posso cambiarlo in <2
dylnan
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.