ASCII Art Maya Ziffern

14

Diese Herausforderung ist einfach. Geben Sie bei einer gegebenen Zahl eine ASCII-Darstellung der Zahl unter Verwendung des Maya-Base-20-Zahlensystems aus.

Was ist das Maya-System?

Die Mayas benutzten die Basis 20, um Zahlen zu speichern, also war die erste Position die 1s-Stelle, die nächste die 20s-Stelle, dann die 400s usw.

So Maya-Nummer 1ist 1in der Basis 10, sondern 10ist tatsächlich 20in der Basis 10, 207ist 807in der Basis 10, etc ..

Und sie stellten ihre Zahlen als Piktogramme dar, mit einem speziellen Symbol für 0.

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

Das war ihre Null. (mindestens die Hälfte Picascii Hälfte meiner künstlerischen Fähigkeiten ASCII Art Version)

Das ist ein echtes Bild des Maya-Null-Symbols. 1

Das waren ihre fünf:

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

Und eine 4:

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

Zum Schluss, um es zusammenzustellen:

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

Sie haben x//5Balken und x%5Punkte auf den Balken. Und wenn x=0, verwenden sie die Schale / das Brot anstelle eines Leerzeichens.

Weitere Bilder finden Sie auf der Wikimedia Commons-Seite mit Bildern von Maya-Nummern .

Dies gilt jedoch nur für Zahlen bis zu 19. Wir dürfen nicht mehr als 4Balken und 4Punkte in einer einzigen "Geschichte" haben ... Also steigen wir auf!

Die Ausgabe für 20 ist:

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



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

Beachten Sie, dass dies normalerweise ungültig ist, da a 1und a 0gleichzeitig vorhanden sind. Aber die 3(beachten Sie, dass Ihre Antwort mindestens 3) Zeilenumbrüche vor dem 0Mittelwert einen neuen Stellenwert benötigt.

Die unterste Geschichte hat Punkte, Bedeutung 1und Balkenbedeutung 5. Aber es hat tatsächlich Punktbedeutung 20^0und Balkenbedeutung 20^0 * 5.

Jede Geschichte geht eine Macht auf. Die Punkte der zweiten Geschichte bedeuten 20( 20^1) und 100( 20^1 * 5).

Die Nummer 506kann also wie folgt dargestellt werden:

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




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




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

Das ist (20^0) * 1 + (20^0 * 5) * 1 + (20^1 * 5) * 1 + (20^2) * 1 = 1 + 5 + 100 + 400 = 506.

Ihre Mission ist es, eine ASCII-Kunst-Darstellung der Basis-10-Zahl auszugeben, falls Sie sich nicht entscheiden oder entscheiden (es spielt keine Rolle).

Andere Regeln:

  • Führende / nachfolgende Leerzeichen sind in Ordnung, solange die Punkte, Balken und Muscheln intakt sind.
  • Die Balken, Punkte und Muscheln müssen genau den Testfällen entsprechen. Keine Größenänderung.
  • Führende Nullen sind in Ordnung. (führende Muscheln am Ausgang)
  • Sie müssen nicht genau 3 Zeilenumbrüche zwischen jedem Platzwert oder jeder Geschichte setzen, sondern nur mindestens 3.

Testfälle:

15

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

12

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



4

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


0

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


24

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




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



33



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




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



20



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




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

1: Sie haben auch die Köpfe der Götter für die Symbole verwendet, aber für diese Herausforderung wird die Muschel- / Brot- / Zelda-Truhe verwendet.

Rɪᴋᴇʀ
quelle
but for this challenge the shell/bread will be used.. Keine Muschel, kein Brot. LOZ Link zur letzten Truhe.
Bald Bantha
@epicTCK .... das ist eigentlich bemerkenswert wie es ...
Rɪᴋᴇʀ
1
Verbunden.
Martin Ender

Antworten:

4

Ruby, 223 180 177 179 Bytes

Anonyme Funktion, gibt eine mehrzeilige Zeichenfolge zurück.

Ich habe vergessen, einen zusätzlichen Abstand hinzuzufügen, der benötigt wurde, und auch die Rekursion. Auch ein bisschen mehr golfen, indem man Dinge umstellt.

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]}
Wert Tinte
quelle
Du bist der Golfspieler. Glückwunsch!
18.
6

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

( Danke an Adnan für einen Tipp zum Sparen von 9 Bytes ( 290->281) und Neil für einen Tipp zum Sparen von 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]]

Probieren Sie es online! (Ideone)

Analyse

Für die Zwecke dieser Analyse verwenden wir den Zeichensatz 0123456789ABCDEFGHIJ, um jede Ziffer in Basis 20 darzustellen.

Also hätte ich die Basis 10 mit einem von zwei Algorithmen, die ich habe, in die Basis 20 konvertieren können. Der erste Algorithmus, den ich verwenden wollte, ist der sogenannte Potenzalgorithmus . Dies ist jedoch nicht der, den ich im Code verwendet habe, da es viel länger gedauert hätte, als es hätte sein sollen. Ich werde daher nicht über diesen Code sprechen. Ich habe jedoch ein Python-Skript erstellt, das eine beliebige Ganzzahl in Basis 10 in eine beliebige andere Basis konvertiert, die mit dieser Methode bereitgestellt wird. Diese Methode können Sie hier in repl.it verwenden. Derjenige, den ich stattdessen für diese Herausforderung verwendet habe, ist der sogenannte Divisionsalgorithmus , was ich denke , ist ziemlich gut erklärt hier. Grundsätzlich passiert jedoch, dass die angegebene Zahl der Basis 10 durch die Basis dividiert wird, in die die Zahl konvertiert werden muss, in diesem Fall 20, bis der Rest entweder 0 oder 1 ist. Anschließend werden Quotient und Rest berechnet in dieser Reihenfolge von der letzten Divisionsoperation und dann alle anderen Reste von den anderen Divisionsoperationen in der Reihenfolge von der letzten zur ersten. Alle diese Ziffern werden dann zusammengefügt, und diese zusammengefügte Sequenz ist in umgekehrter Reihenfolge Ihre Basis-10-Nummer in Basis 20! Um dies zu veranschaulichen, nehmen wir an, dass Sie die Zahl der Basis 10 in die Zahl 431der Basis 20 konvertieren möchten.

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

Dann nehmen wir endlich die Liste, die wir haben B11, und kehren sie um, so dass wir sie jetzt haben 11B. Damit haben wir endlich unsere endgültige Antwort! 431 in Basis 10 konvertiert in Basis 20 11B, was mit meinem Python-Skript bestätigt werden kann, das den Potenzalgorithmus verwendet, zu dem ich bereits einen Link oben geteilt habe, aber ich werde es hier noch einmal tun . Hier ist einer, der auch den in dieser Antwort beschriebenen Divisionsalgorithmus verwendet und dieselbe Antwort wie der Potenzalgorithmus zurückgibt.

Dieser gesamte Prozess ist im Wesentlichen , was in diesem in meinem Skript geschieht whileSchleife: while not p or z:p+=[z%20];z=z//20. Der einzige Unterschied ist, dass >9es keine Zahlen gibt als Buchstaben dargestellt , sondern als selbst.

Nachdem die Zahl der Basis 10 in die Zahl der Basis 20 konvertiert wurde, werden für jede Ziffer in der Ganzzahl der Basis 20, die wir nennen werden g, g mod 5Punkte ausgedruckt und dann g//5Balken ausgedruckt. Anschließend druckt das Programm 3 Leerzeilen und geht zur nächsten Ziffer über. Wenn es sich jedoch um eine Ziffer handelt 0, wird ein einzelnes "Brot" gefolgt von drei neuen Zeilen ausgedruckt, und das Programm wechselt zur nächsten Ziffer. Nehmen 11Bwir also die Zahl der Basis 20 , dann gehen wir zur ersten Ziffer. Die erste Ziffer ist 1, und daher würde es 0 Balken seit 1//5=0und 1 Punkt seit drucken 1%5=1. Also würden wir zuerst Folgendes bekommen:

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

und dann 3 neue Zeilen. Wenn wir zur zweiten Ziffer übergehen, sehen wir auch, dass sie 1 ist, also würde sie dasselbe ausgeben:

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

und auch 3 neue Zeilen. Wenn wir schließlich zur letzten Ziffer übergehen, sehen wir, dass es eine ist B. Da B=11in Basis 20 würde das Programm 1 Punkt seit 11%5=1und 2 Balken seit ausgeben 11//5=2. So, jetzt bekommen wir das:

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

Wenn wir all dies zusammenfassen, erhalten wir Folgendes:

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




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




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

Und das ist die Mayaziffer für 431! Sie haben schließlich Ihre Zahl zur Basis 10 in Zahlen zur Basis 20 der Maya dargestellt.

Hinweis: Möglicherweise haben Sie diese lambdaFunktion in meinem Code bemerkt oder nicht . Unabhängig davon wird diese Funktion zur Erzeugung der Punkte verwendet, da mehrere Punkte nebeneinander ausgegeben werden müssen.

R. Kap
quelle
Ich bin mir nicht sicher, ob es möglich ist, aber kannst du es S,N,M,X=' -|\n'stattdessen tun S,N,M,X=' ','-','|','\n'?
Adnan
@Adnan das ist möglich.
29.
@Adnan Wirklich? Wow, das wusste ich nicht. Vielen Dank!
R. Kap
401enthält eine innere Null.
Neil
@ Neil Oh, richtig. Danke für die Warnung. Es ist jetzt behoben.
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)

Diskussion

n//20and m(n//20)ruft m()rekursiv auf, wenn höhere Potenzen von 20 zu behandeln sind. Die Rekursion erfolgt vor dem Drucken des aktuellen Stellenwerts, sodass höhere Potenzen zuerst gedruckt werden.

Wenn der aktuelle Stellenwert ungleich Null ist (r! = 0), for a,b,fdruckt die Schleife die Einheiten und dann die Fünfer. aist die erste / vierte Reihe und bist die zweite / dritte Reihe. Der Trick liegt in der print(*((a,b,b,a)*f),sep=x). Für die Einheiten ergibt sich f = 1 print(*(a,b,b,a),sep=x), wodurch die 4 Zeilen gedruckt werden, aus denen die Einheitensymbole bestehen (x ist ein '\ n'). Für die Fünfer ist f = die Anzahl der zu druckenden Fünfer (r // 5), sodass das Tupel (a, b, b, a) mit der Anzahl der zu druckenden Fünfer multipliziert (dh wiederholt) wird. Wenn f = 2, erhalten wir print(*(a,b,b,a,a,b,b,a),sep=x), was zwei Symbole für fünf druckt.

Wenn der aktuelle Stellenwert 0 ist, wird das Nullsymbol gedruckt.

RootTwo
quelle
Ich musste R. Kap das Kopfgeld belohnen, aber das könnte seine eigene Kopfgeld verdienen! Gut gemacht!
22.
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'

Ich habe dies erstellt, um Testfälle zu generieren. Sie können es als Benchmark verwenden. Sorta spielte Golf.

Rɪᴋᴇʀ
quelle
Sie könnten 26 Bytes entfernen, indem Sie Whitespace entfernen, und weitere 4, indem Sie tun s=math.sqrtund an s(s(w))Stelle vonmath.sqrt(math.sqrt(w))
DJMcMayhem aufrufen.
@ DrGreenEggsandHamDJ danke. Ich glaube nicht, dass ich 26 Bytes von Whitespace abbekommen habe?
29.
Oh, sorry, Zählfehler meinte ich 25. Auch w**0.25ist noch besser als s(s(w)). Obwohl es länger wurde?
DJMcMayhem
@ DrGreenEggsandHamDJ Ja, ich habe irgendwie die Shell-Null-Zeichenfolge verloren, als ich von der Datei zur Antwort ging.
29.
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}
`)
Neil
quelle
Ich kann das nicht zum Laufen bringen? Es Fehler mit Missing } in template expression. Ich weiß nicht sehr viel, wie kann ich das beheben?
29.
@ EᴀsᴀIᴛᴇʀʟʏ Meine schlechte, ich habe etwas Code verschoben und ihn versehentlich an der falschen Stelle eingefügt. Es ist jetzt behoben.
Neil
1

Python 3, 213 Bytes

Fand eine noch kürzere Version mit einem anderen Ansatz:

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

Erläuterung

Die ersten 9 Zeilen bilden Zeichenfolgen, aus denen die Symbole bestehen

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

Der Kern der Lösung ist die rekursive Funktion m, die eine Liste von Zeichenfolgen erstellt, eine Zeichenfolge für jede Zeile in der Ausgabe. Schematisch msieht es so aus:

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

m kann wie folgt umgeschrieben werden:

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

Der rekursive Aufruf m(n//20)steht an erster Stelle, sodass die wichtigsten Ziffern zuerst eingegeben werden.

[n%5*a,n%5*b,n%5*b,n%5*a]sind die Zeichenfolge für die Symbole. aist die oberste Zeile für ein einzelnes Symbol. n%5ist die Nummer von einem Symbol für diese Ziffer. Ist n%5*aalso eine Zeichenfolge für die oberste (und unterste) Reihe von n%5Einsen. In ähnlicher Weise ist "n% 5 * b" eine Zeichenfolge für die zweite (und dritte) Zeile.

Der Ausdruck [:n%5*4]verhält sich wie einif , um zusätzliche Leerzeilen in der Ausgabe zu vermeiden, wenn keine 'Einsen' ausgegeben werden sollen. Es wird nicht benötigt, sorgt aber dafür, dass die Ausgabe besser aussieht.

n%20//5ist die Anzahl der Symbole für fünf, die benötigt werden. [c,d,d,c]sind die Zeichenketten, um ein Symbol für fünf zu bilden.

[t,w,w,v+h*19+v,y,y,t] sind die Zeichenketten für das Null-Symbol

[x,x] Fügt mindestens drei Leerzeilen zwischen Gruppen von Maya-Ziffern ein

RootTwo
quelle
Können Sie erklären, wie das funktioniert?
5.