ASCII Art Maya Numerals

14

Ce défi est simple. Étant donné un nombre, produire une représentation ascii-art du nombre, en utilisant le système numérique Mayan Base-20.

Qu'est-ce que le système maya?

Les Mayas utilisaient la base 20 pour stocker les nombres, donc la première position était la 1place s, la prochaine 20place s, puis la 400s, etc.

Donc le nombre Maya 1est 1en base 10, mais 10est en fait 20en base 10, 207est 807en base 10, etc.

Et ils ont représenté leurs numéros sous forme de pictogrammes, avec un symbole spécial pour 0.

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

C'était leur zéro. (au moins la moitié picascii la moitié de ma version artistique de l'art ascii)

C'est une vraie image du symbole zéro maya. 1

Ce sont leurs cinq:

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

Et un 4:

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

Enfin, pour le rassembler:

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

Ils ont donc des x//5barres et des x%5points au-dessus des barres. Et si x=0, ils utilisent le shell / pain au lieu d'un espace vide.

Pour plus d'images, essayez la page Wikimedia Commons d'images de nombres mayas .

Mais ce n'est que pour les chiffres jusqu'à 19. On n'a pas le droit d'avoir plus que des 4barres et des 4points dans une seule "histoire" ... Alors on monte!

La sortie pour 20 est:

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



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

Notez que ce serait normalement invalide, car il a un 1et un 0en même temps. Mais le 3(notez que, votre réponse a besoin d'au moins 3) de nouvelles lignes avant la 0moyenne d'une nouvelle valeur de position.

L'histoire du bas a des points, une signification 1et des barres signifiant 5. Mais il a en fait une signification de points 20^0et une signification de barres 20^0 * 5.

Chaque histoire monte en puissance. Les points du deuxième étage signifient 20( 20^1) et 100( 20^1 * 5).

Ainsi, le nombre 506peut être représenté comme:

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




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




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

C'est ça (20^0) * 1 + (20^0 * 5) * 1 + (20^1 * 5) * 1 + (20^2) * 1 = 1 + 5 + 100 + 400 = 506.

Votre mission, si vous choisissez de ne pas le faire ou si vous le souhaitez (peu importe), est de produire une représentation artistique ascii du nombre de base 10.

Autres règles:

  • L'espace de tête / arrière est correct, tant que les points, les barres et les coquilles sont intacts.
  • Les barres, les points et les coquilles doivent être exactement ce que les cas de test ont. Pas de redimensionnement.
  • Les 0 en tête sont corrects. (coques de tête sur la sortie)
  • Vous n'avez pas besoin d'avoir exactement 3 sauts de ligne entre chaque valeur de position ou histoire, juste au moins 3.

Cas de test:

15

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

12

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



4

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


0

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


24

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




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



33



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




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



20



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




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

1: Ils ont également utilisé les têtes de dieux pour les symboles, mais pour ce défi, le coffre de coquille / pain / zelda sera utilisé.

Rɪᴋᴇʀ
la source
but for this challenge the shell/bread will be used.. Pas de coquille, pas de pain. Lien LOZ vers la poitrine passée.
Bald Bantha
@epicTCK .... c'est en fait remarquablement comme ça ...
Rɪᴋᴇʀ
1
En relation.
Martin Ender

Réponses:

4

Rubis, 223 180 177 179 octets

Fonction anonyme, retourne une chaîne multiligne.

J'ai oublié d'ajouter un espacement supplémentaire qui était nécessaire, ainsi que la récursivité. J'ai également joué un peu plus en déplaçant les choses.

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]}
Encre de valeur
la source
Vous êtes le plus golfeur. Félicitations!
Rɪᴋᴇʀ
6

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

( Merci à Adnan pour une astuce pour économiser 9 octets ( 290->281) et Neil pour une astuce pour économiser 4 octets ( 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]]

Essayez-le en ligne! (Ideone)

Une analyse

Aux fins de cette analyse, nous utiliserons le jeu de caractères 0123456789ABCDEFGHIJpour représenter chaque chiffre de la base 20.

Donc, j'aurais pu convertir la base 10 en base 20 en utilisant l'un des deux algorithmes que j'ai. Le premier algorithme que j'ai pensé utiliser est ce que j'appelle l' algorithme des puissances . Ce n'est pas celui que j'ai utilisé dans le code car il l'aurait rendu beaucoup plus long qu'il n'aurait dû l'être, donc je ne vais pas parler de celui-ci. Cependant, j'ai créé un script python qui convertit tout entier de la base 10 en toute autre base fournie à l'aide de cette méthode, que vous pouvez utiliser ici sur repl.it. Celui que j'ai utilisé à la place pour ce défi est ce que j'appelle l' algorithme de division , qui je pense est expliqué assez bien ici. Mais fondamentalement, ce qui se passe, c'est qu'il prend le nombre de base 10 fourni et le divise par la base dont il a besoin pour convertir le nombre, qui dans ce cas est 20, jusqu'à ce que le reste soit 0 ou 1. Il prend ensuite le quotiant et le reste , dans cet ordre, de la dernière opération de division, puis tous les autres restes des autres opérations de division dans l'ordre du dernier au premier. Tous ces chiffres sont ensuite réunis, et cette séquence jointe inversée est votre numéro de base 10 en base 20! Pour illustrer cela, supposons que vous souhaitiez convertir le nombre 431de base 10 en base 20. Donc, ce que nous ferions est le suivant:

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

Ensuite, finalement, nous prendrions la liste que nous avons, qui dans ce cas contient B11, et l' inverser pour que nous ayons maintenant 11B. Ce faisant, nous avons enfin obtenu notre réponse finale! 431 en base 10 converti en base 20 est 11B, ce qui peut être confirmé en utilisant mon script Python qui utilise l'algorithme de pouvoirs auquel j'ai déjà partagé un lien ci-dessus, mais je le referai ici . En voici un qui utilise également l'algorithme de division décrit dans cette réponse et renvoie la même réponse que celle des puissances.

Ce processus est essentiellement ce qui se passe dans mon script dans cette whileboucle: while not p or z:p+=[z%20];z=z//20. La seule différence est que les chiffres ne>9 sont pas représentés comme des lettres mais plutôt comme eux-mêmes.

Ensuite, après que le nombre de base 10 a été converti en base 20, pour chaque chiffre de l'entier de base 20, que nous appellerons g, les g mod 5points sont imprimés puis les g//5barres sont imprimées. Ensuite, le programme imprime 3 lignes vides et passe au chiffre suivant. Cependant, si le chiffre est 0, alors un seul "pain" est imprimé suivi de 3 nouvelles lignes, puis le programme passe au chiffre suivant. Donc, en prenant le nombre de base 20 11B, nous passons au premier chiffre. Le premier chiffre est 1, et donc il afficherait 0 barre depuis 1//5=0, et 1 point depuis 1%5=1. Donc, nous obtiendrions d'abord ceci:

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

puis 3 nouvelles lignes. En passant au deuxième chiffre, nous voyons également qu'il s'agit de 1, donc il produirait la même chose:

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

et aussi 3 nouvelles lignes. Enfin, en passant au dernier chiffre, nous voyons que c'est un B. Depuis la B=11base 20, le programme afficherait 1 point depuis 11%5=1et 2 barres depuis 11//5=2. Alors maintenant, nous obtenons ceci:

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

Enfin, en rassemblant tout cela, nous obtenons ceci:

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




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




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

Et, c'est le chiffre maya pour 431! Vous avez enfin votre numéro de base 10 représenté en chiffres mayas de base 20.

Remarque: Vous pouvez ou non avoir remarqué cette lambdafonction dans mon code. Quoi qu'il en soit, cette fonction est utilisée pour la création des points car plusieurs points doivent être sortis côte à côte.

R. Kap
la source
Je ne sais pas si c'est possible, mais pouvez-vous faire à la S,N,M,X=' -|\n'place de S,N,M,X=' ','-','|','\n'?
Adnan
@Adnan c'est possible.
Rɪᴋᴇʀ
@Adnan vraiment? Wow, je ne savais pas ça. Merci!
R. Kap
401contient un zéro intérieur.
Neil
@Neil Oh, c'est vrai. Merci pour l'information. C'est réparé maintenant.
R. Kap
3

Python 3, 243 octets

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)

Discussion

n//20and m(n//20)appelle m()récursivement s'il y a des puissances supérieures à 20 à gérer. La récursivité est effectuée avant d'imprimer la valeur de position actuelle, de sorte que les puissances supérieures soient imprimées en premier.

Si la valeur de position actuelle est différente de zéro (r! = 0), le for a,b,f-loop imprime les unités puis les cinq. aest la première / quatrième ligne et best la deuxième / troisième ligne. L'astuce est dans le print(*((a,b,b,a)*f),sep=x). Pour les unités, f = 1 résultant print(*(a,b,b,a),sep=x), qui imprime les 4 lignes qui composent les symboles des unités (x est un '\ n'). Pour les cinq, f = le nombre de cinq à imprimer (r // 5), donc le tuple (a, b, b, a) est multiplié (c'est-à-dire répété) par le nombre de cinq à imprimer. Si f = 2, nous obtenons print(*(a,b,b,a,a,b,b,a),sep=x), qui imprime deux symboles pour cinq.

Si la valeur de position actuelle est 0, le symbole zéro est imprimé.

RootTwo
la source
J'ai dû récompenser la prime à R. Kap, mais cela mérite peut-être sa propre prime! Bon travail!
Rɪᴋᴇʀ
2

Python, 411 octets

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'

J'ai créé cela pour générer des cas de test, vous pouvez l'utiliser comme référence. Sorta joua au golf.

Rɪᴋᴇʀ
la source
Vous pouvez retirer 26 octets en supprimant les espaces blancs et 4 autres en faisant s=math.sqrtet en appelant à la s(s(w))place demath.sqrt(math.sqrt(w))
James
@DrGreenEggsandHamDJ merci. Je ne pense pas que j'ai obtenu 26 octets de blanc?
Rɪᴋᴇʀ
Oh, désolé, erreur de comptage 25. Je voulais dire aussi, w**0.25est encore mieux que s(s(w)). Même si c'est devenu plus long?
James
@DrGreenEggsandHamDJ ouais, j'ai en quelque sorte perdu la chaîne shell zéro en transit du fichier à la réponse.
Rɪᴋᴇʀ
2

JavaScript (ES6), 254 octets

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
la source
Je n'arrive pas à faire fonctionner ça? Il contient des erreurs Missing } in template expression. Je ne connais pas grand chose js, comment puis-je le réparer?
Rɪᴋᴇʀ
@ EᴀsᴛᴇʀʟʏIʀᴋ Mon mauvais, j'ai déplacé du code et l'ai accidentellement collé au mauvais endroit. C'est réparé maintenant.
Neil
1

Python 3, 213 octets

Entré avec une version encore plus courte en utilisant une approche différente:

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

explication

Les 9 premières lignes environ, construisent des chaînes qui sont utilisées pour créer les symboles

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

Le cœur de la solution est la fonction récursive m, qui construit une liste de chaînes, une chaîne pour chaque ligne dans la sortie. Schématiquement, mressemble à:

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

m peut être réécrit comme:

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

L'appel récursif m(n//20) vient en premier afin que les chiffres les plus significatifs soient effectués en premier.

[n%5*a,n%5*b,n%5*b,n%5*a]sont la chaîne des symboles. aest la ligne supérieure d'un seul symbole. n%5est le nombre d'un symbole pour ce chiffre. Donc,n%5*a c'est une chaîne pour la rangée supérieure (et inférieure) de n%5uns. De même, «n% 5 * b» est une chaîne pour la 2e (et 3e) ligne.

L'expression [:n%5*4]agit comme unif pour éviter les lignes vierges supplémentaires dans la sortie s'il n'y en a pas de «une». Ce n'est pas nécessaire, mais améliore la sortie.

n%20//5est le nombre de symboles nécessaires pour cinq. [c,d,d,c]sont les chaînes pour faire un symbole pour cinq.

[t,w,w,v+h*19+v,y,y,t] sont les chaînes pour faire le symbole zéro

[x,x] met au moins trois lignes vides entre les groupes de chiffres mayas

RootTwo
la source
Pouvez-vous expliquer comment cela fonctionne?
Rɪᴋᴇʀ