Numeri Maya di arte ASCII


14

Questa sfida è semplice. Dato un numero, produce una rappresentazione ASCII-art del numero, usando il sistema numerico Maya Base-20.

Qual è il sistema Maya?

I Maya usarono la base 20 per memorizzare i numeri, quindi la prima posizione era il 1posto di s, il successivo il 20posto di s, quindi la 400s, ecc.

Quindi il numero Maya 1è 1nella base 10, ma in 10realtà è 20nella base 10, 207è 807nella base 10, ecc.

E rappresentavano i loro numeri come pittogrammi, con un simbolo speciale per 0.

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

Quello era il loro zero. (almeno la metà picascii metà della mia arte artistica ascii art version)

Questa è una vera immagine del simbolo zero Maya. 1

Erano i loro cinque:

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

E un 4:

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

Infine, per metterlo insieme:

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

Quindi hanno x//5barre e x%5punti in cima alle barre. E se x=0, usano la shell / pagnotta invece di uno spazio vuoto.

Per altre immagini, prova la pagina Wikimedia Commons delle immagini numerate Maya .

Ma questo è solo per i numeri fino a 19. Non ci è permesso avere più di 4barre e 4punti in una singola "storia" ... Quindi saliamo!

L'output per 20 è:

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



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

Nota che normalmente non sarebbe valido, perché ha a 1e 0a allo stesso tempo. Ma la 3(nota che, la tua risposta ha bisogno di almeno 3) newline prima della 0media di un nuovo valore di luogo.

La storia in basso ha punti, significato 1e significato di barre 5. Ma in realtà ha un significato a punti 20^0e un significato a barre 20^0 * 5.

Ogni storia aumenta di potenza. I punti della seconda storia significano 20( 20^1) e 100( 20^1 * 5).

Quindi il numero 506può essere rappresentato come:

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




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




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

Questo è (20^0) * 1 + (20^0 * 5) * 1 + (20^1 * 5) * 1 + (20^2) * 1 = 1 + 5 + 100 + 400 = 506.

La tua missione, se scegli di non farlo o no (non importa), è quella di produrre una rappresentazione ASCII art del numero base-10.

Altre regole:

  • Lo spazio iniziale / finale va bene, purché i punti, le barre e le conchiglie siano intatti.
  • Le barre, i punti e i gusci devono essere esattamente ciò che hanno i casi di test. Nessun ridimensionamento.
  • I primi 0 vanno bene. (shell principali sull'output)
  • Non devi avere esattamente 3 nuove righe tra ogni valore di luogo o storia, solo almeno 3.

Casi test:

15

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

12

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



4

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


0

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


24

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




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



33



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




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



20



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




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

1: Hanno anche usato le teste degli dei per i simboli, ma per questa sfida verrà usato il baule shell / bread / zelda .


but for this challenge the shell/bread will be used.. Non conchiglia, non con pane. Collegamento LOZ al petto passato.
Bald Bantha,


@epicTCK .... che in realtà è straordinariamente simile ...
Rɪᴋᴇʀ

Risposte:


4

Rubino, 223 180 177 179 byte

Funzione anonima, restituisce una stringa multilinea.

Ho dimenticato di aggiungere un po 'di spazio extra necessario e anche la ricorsione. Ho anche giocato un po 'di più spostando le cose.

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]}

Sei il più golfista. Congratulazioni!
Rɪᴋᴇʀ

6

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

( Grazie ad Adnan per un suggerimento sul salvataggio di 9 byte ( 290->281) e Neil per un suggerimento sul salvataggio di 4 byte ( 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]]

Provalo online! (Ideone)

Analisi

Ai fini di questa analisi, useremo il set di caratteri 0123456789ABCDEFGHIJper rappresentare ogni cifra nella base 20.

Quindi, avrei potuto andare e convertire la base 10 in base 20 usando uno dei due algoritmi che ho. Il primo algoritmo che ho pensato di usare è quello che chiamo algoritmo di poteri . Questo non è quello che ho usato nel codice, dato che avrebbe reso il tutto più lungo di quanto avrebbe dovuto essere, quindi non parlerò di questo. Tuttavia, ho creato uno script Python che converte qualsiasi numero intero nella base 10 in qualsiasi altra base fornita utilizzando questo metodo, che puoi utilizzare qui su repl.it. Quello che ho usato invece per questa sfida è quello che chiamo algoritmo di divisione , che penso sia spiegato abbastanza bene qui. Ma fondamentalmente ciò che accade è che prende il numero di base 10 fornito e lo divide per la base in cui deve convertire il numero, che in questo caso è 20, fino a quando il resto è 0 o 1. Prende quindi il quoziente e il resto , in quell'ordine, dall'ultima operazione di divisione, e poi tutti gli altri resti delle altre operazioni di divisione nell'ordine dall'ultima alla prima. Tutte queste cifre vengono quindi unite e quella sequenza unita invertita è il numero della tua base 10 nella base 20! Per illustrare questo, supponiamo che tu voglia convertire il numero 431di base 10 in base 20. Quindi, ciò che vorremmo fare è questo:

[]=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]

Quindi, infine, prendiamo l'elenco che abbiamo, che in questo caso contiene B11, e lo invertiamo in modo che ora abbiamo 11B. In questo modo, abbiamo finalmente ottenuto la nostra risposta finale! 431 in base 10 convertito in base 20 è 11B, il che può essere confermato usando il mio script Python che utilizza l'algoritmo dei poteri con cui ho già condiviso un link sopra, ma lo farò di nuovo qui . Eccone uno che utilizza anche l'algoritmo di divisione descritto in questa risposta e restituisce la stessa risposta di quella dei poteri.

L'intero processo è essenzialmente ciò che accade nel mio script in questo whileciclo: while not p or z:p+=[z%20];z=z//20. L'unica differenza è che i numeri non>9 sono rappresentati come lettere ma invece come se stessi.

Passando, dopo che il numero di base 10 è stato convertito in base 20, per ogni cifra nell'intero di base 20, che chiameremo g, i g mod 5punti vengono stampati e quindi le g//5barre vengono stampate. Quindi il programma stampa 3 righe vuote e passa alla cifra successiva. Tuttavia, se la cifra è 0, viene stampata una singola "pagnotta" seguita da 3 nuove righe, quindi il programma passa alla cifra successiva. Quindi, prendendo il numero base 20 11B, andiamo alla prima cifra. La prima cifra è 1e quindi stampa 0 barre da allora 1//5=0e 1 punto da allora 1%5=1. Quindi, per prima cosa vorremmo ottenere questo:

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

e poi 3 nuove linee. Passando alla seconda cifra, vediamo anche che è 1, quindi produrrebbe la stessa cosa:

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

e anche 3 nuove linee. Infine, spostandoci sull'ultima cifra, vediamo che è a B. Poiché B=11nella base 20, il programma avrebbe prodotto 1 punto da allora 11%5=1e 2 barre da allora 11//5=2. Quindi ora otteniamo questo:

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

Infine, mettendo tutto insieme, otteniamo questo:

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




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




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

E questo è il numero Maya per 431! Alla fine hai il tuo numero di base 10 rappresentato nei numeri Maya base 20.

Nota: potresti aver notato o meno questa lambdafunzione nel mio codice. Indipendentemente da ciò, questa funzione viene utilizzata per la creazione di punti poiché più punti devono essere emessi uno accanto all'altro.


Non sono sicuro che sia possibile, ma puoi farlo S,N,M,X=' -|\n'invece di S,N,M,X=' ','-','|','\n'?
Adnan,

@Adnan che è possibile.
Rɪᴋᴇʀ

@Adnan Davvero? Wow, non lo sapevo. Grazie!
R. Kap,

401contiene uno zero interno.
Neil,

@Neil Oh, giusto. Grazie per il testa a testa. Ora è riparato.
R. Kap

3

Python 3, 243 byte

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)

Discussione

n//20and m(n//20)chiama m()ricorsivamente se ci sono poteri più alti di 20 da gestire. La ricorsione viene eseguita prima di stampare il valore del luogo corrente, in modo che vengano stampati prima i poteri più elevati.

Se il valore del luogo corrente è diverso da zero (r! = 0), for a,b,f-loop stampa le unità e quindi i cinque. aè la prima / quarta riga ed bè la seconda / terza riga. Il trucco sta nel print(*((a,b,b,a)*f),sep=x). Per le unità, risultante f = 1 print(*(a,b,b,a),sep=x), che stampa le 4 righe che compongono i simboli delle unità (x è una '\ n'). Per i cinque, f = il numero di cinque da stampare (r // 5), quindi la tupla (a, b, b, a) viene moltiplicata (cioè ripetuta) per il numero di cinque da stampare. Se f = 2, otteniamo print(*(a,b,b,a,a,b,b,a),sep=x), che stampa due simboli per cinque.

Se il valore del luogo corrente è 0, viene stampato il simbolo zero.


Ho dovuto premiare la generosità a R. Kap, ma questo potrebbe meritare la sua stessa grazia! Bel lavoro!
Rɪᴋᴇʀ

2

Python, 411 byte

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'

Ho creato questo per generare casi di test, puoi usarlo come punto di riferimento. Sorta ha giocato a golf.


Puoi togliere 26 byte rimuovendo gli spazi bianchi e altri 4 facendo s=math.sqrte chiamando s(s(w))invece dimath.sqrt(math.sqrt(w))
James

@DrGreenEggsandHamDJ grazie. Non credo di aver rimosso 26 byte dallo spazio bianco?
Rɪᴋᴇʀ

Oh, scusa, contando l'errore volevo dire 25. Inoltre, w**0.25è anche meglio di s(s(w)). Anche se è diventato più lungo?
James,

@DrGreenEggsandHamDJ sì, in qualche modo ho perso la stringa zero della shell in transito dal file per rispondere.
Rɪᴋᴇʀ

2

JavaScript (ES6), 254 byte

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}
`)

Non riesco a farlo funzionare? Errori con Missing } in template expression. Non conosco molto js, ​​come posso ripararlo?
Rɪᴋᴇʀ

@ EᴀsᴛᴇʀʟʏIʀᴋ Mio male, ho spostato un po 'di codice e incollato accidentalmente nel posto sbagliato. Ora è riparato.
Neil,

1

Python 3, 213 byte

È venuto con una versione ancora più breve usando un approccio diverso:

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[]

spiegazione

Le prime 9 righe circa costruiscono stringhe utilizzate per creare i simboli

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 = '|                   |'

Il nucleo della soluzione è la funzione ricorsiva m, che crea un elenco di stringhe, una stringa per ogni riga nell'output. Schematicamente, si mpresenta come:

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

m può essere riscritto come:

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 chiamata ricorsiva m(n//20)viene prima in modo che le cifre più significative vengano eseguite per prime.

[n%5*a,n%5*b,n%5*b,n%5*a]sono la stringa di quei simboli. aè la riga superiore per un singolo simbolo. n%5è il numero di un simbolo per questa cifra. Quindi, n%5*aè una stringa per la riga superiore (e inferiore) di n%5quelle. Allo stesso modo, 'n% 5 * b` è una stringa per la seconda (e terza) riga.

L'espressione si [:n%5*4]comporta come unaif per evitare ulteriori righe vuote nell'output se non ci sono "uno" per l'output. Non è necessario, ma rende l'aspetto migliore.

n%20//5è il numero di simboli per cinque necessari. [c,d,d,c]sono le stringhe per creare un simbolo per cinque.

[t,w,w,v+h*19+v,y,y,t] sono le stringhe per creare il simbolo zero

[x,x] mette almeno tre righe vuote tra gruppi di cifre Maya


Puoi dare una spiegazione su come funziona?
Rɪᴋᴇʀ
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.