Cyfry Majów ASCII Art

14

To wyzwanie jest proste. Biorąc pod uwagę liczbę, wyślij ascii-artową reprezentację liczby, korzystając z systemu liczbowego Mayan Base-20.

Co to jest system Majów?

Majowie używali bazy 20 do przechowywania liczb, więc pierwszą pozycją było 1miejsce, następne 20miejsce, potem 400s itd.

Więc liczba Majów 1jest 1w bazie 10, ale 10tak naprawdę jest 20w bazie 10, 207jest 807w bazie 10 itd.

I przedstawiali swoje liczby jako piktogramy, ze specjalnym symbolem dla 0.

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

To było ich zero. (przynajmniej połowa picascii połowa mojej artystyczności ascii art version)

To prawdziwy obraz majskiego symbolu zero. 1

To było ich pięć:

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

I 4:

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

Wreszcie, aby złożyć to w całość:

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

Więc mają x//5paski i x%5kropki na górze pasków. A jeśli x=0użyją skorupy / bochenka zamiast pustego miejsca.

Aby uzyskać więcej zdjęć, wypróbuj stronę Wikimedia Commons zdjęć z liczbą Maya .

Ale dotyczy to tylko liczb 19. Nie możemy mieć więcej niż 4paski i 4kropki w jednej „historii” ... Więc idziemy w górę!

Wynik dla 20 to:

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



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

Zauważ, że normalnie byłoby to nieprawidłowe, ponieważ ma on 1ai 0jednocześnie. Ale 3(pamiętaj, że twoja odpowiedź wymaga co najmniej 3) nowych wierszy, zanim 0oznacza nową wartość miejsca.

Dolna historia ma kropki, znaczenie 1i słupki 5. Ale w rzeczywistości ma znaczenie kropek 20^0i słupków 20^0 * 5.

Każda historia rośnie w siłę. Kropki z drugiego wątku oznaczają 20( 20^1) i 100( 20^1 * 5).

Tak więc liczbę 506można przedstawić jako:

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




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




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

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

Twoim zadaniem, jeśli zdecydujesz się nie lub nie (nie ma to znaczenia), jest uzyskanie ascii artystycznej reprezentacji liczby base-10.

Inne zasady:

  • Wiodące / końcowe spacje są w porządku, o ile kropki, słupki i skorupy są nienaruszone.
  • Słupki, kropki i powłoki muszą być dokładnie takie, jakie mają przypadki testowe. Bez zmiany rozmiaru.
  • Wiodące „0” są w porządku. (wiodące powłoki na wyjściu)
  • Nie musisz mieć dokładnie 3 nowych wierszy między każdą wartością miejsca lub historią, tylko co najmniej 3.

Przypadki testowe:

15

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

12

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



4

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


0

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


24

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




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



33



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




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



20



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




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

1: Użyli także głów bogów do symboli, ale do tego wyzwania zostanie użyta skrzynia ze skorupą / chlebem / zeldą .

Rɪᴋᴇʀ
źródło
but for this challenge the shell/bread will be used.. Nie muszla, nie chleb. Link LOZ do poprzedniej skrzyni.
Bald Bantha
@epicTCK .... to naprawdę bardzo podoba ...
Rɪᴋᴇʀ
1
Związane z.
Martin Ender

Odpowiedzi:

4

Rubinowy, 223 180 177 179 bajtów

Funkcja anonimowa zwraca ciąg wielowierszowy.

Zapomniałem dodać trochę potrzebnych odstępów, a także rekurencji. Grałem też trochę więcej, zmieniając rzeczy.

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]}
Wartość tuszu
źródło
Jesteś najbardziej golfistą. Gratulacje!
Rɪᴋᴇʀ
6

Python 3.5, 404 400 392 312 311 308 290 281 285 281 bajtów:

( Podziękowania dla Adnana za wskazówkę dotyczącą oszczędzania 9 bajtów ( 290->281) i Neila za wskazówkę dotyczącą oszczędzania 4 bajtów ( 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]]

Wypróbuj online! (Ideone)

Analiza

Do celów tej analizy użyjemy zestawu znaków 0123456789ABCDEFGHIJdo przedstawienia każdej cyfry w bazie 20.

Mogłem więc przekształcić bazę 10 w bazę 20 przy użyciu jednego z dwóch algorytmów, które posiadam. Pierwszym algorytmem, o którym pomyślałem, jest algorytm mocy . Nie tego użyłem w kodzie, ponieważ byłby o wiele dłuższy niż powinien, więc nie będę o tym mówić. Jednak stworzyłem skrypt Pythona, który konwertuje dowolną liczbę całkowitą w bazie 10 na dowolną inną bazę podaną przy użyciu tej metody, której można użyć tutaj na repl.it. Tym, którego użyłem do tego wyzwania, jest algorytm podziału , który moim zdaniem jest tutaj całkiem dobrze wyjaśniony. Ale w zasadzie dzieje się tak, że bierze podaną liczbę podstawową 10 i dzieli ją przez bazę, na którą musi przekonwertować liczbę, która w tym przypadku wynosi 20, aż reszta będzie równa 0 lub 1. Następnie bierze iloraz i resztę , w tej kolejności, od ostatniej operacji podziału, a następnie wszystkie pozostałe pozostałości z pozostałych operacji podziału w kolejności od ostatniej do pierwszej. Wszystkie te cyfry są następnie łączone razem, a ta odwrócona sekwencja połączona jest liczbą podstawową 10 w bazie 20! Aby to zilustrować, załóżmy, że chcesz przekonwertować liczbę podstawową 10 431na bazę 20. Więc zrobilibyśmy to:

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

Następnie, w końcu, wzięlibyśmy listę, którą mamy, która w tym przypadku zawiera B11, i odwróciliśmy ją, abyśmy już mieli 11B. Czyniąc to, w końcu otrzymaliśmy ostateczną odpowiedź! 431 w bazie 10 jest przekonwertowane na bazę 20 11B, co można potwierdzić za pomocą mojego skryptu Python, który korzysta z algorytmu mocy, do którego już udostępniłem link powyżej, ale zrobię to ponownie tutaj . Oto taki, który wykorzystuje również algorytm podziału opisany w tej odpowiedzi i zwraca tę samą odpowiedź, co moc.

Cały ten proces jest w zasadzie to, co dzieje się w moim scenariuszu w tej whilepętli: while not p or z:p+=[z%20];z=z//20. Jedyną różnicą jest to, że liczby nie>9 są reprezentowane jako litery, ale jako same.

Przechodząc dalej, po przekonwertowaniu numeru bazy 10 na bazę 20, dla każdej cyfry w liczbie całkowitej bazy 20, którą nazwiemy g, g mod 5drukowane są kropki, a następnie g//5paski. Następnie program drukuje 3 puste linie i przechodzi do następnej cyfry. Jeśli jednak cyfra jest 0, to drukowany jest pojedynczy „bochenek”, a następnie 3 nowe wiersze, a następnie program przechodzi do następnej cyfry. Tak więc, biorąc podstawową liczbę 20 11B, przechodzimy do pierwszej cyfry. Pierwszą cyfrą jest 1, a zatem wydrukowałby 0 słupków od 1//5=0i 1 kropkę od 1%5=1. Najpierw otrzymalibyśmy to:

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

a następnie 3 nowe linie. Przechodząc do drugiej cyfry, widzimy również, że jest to 1, więc wyświetli to samo:

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

a także 3 nowe linie. Wreszcie, przechodząc do ostatniej cyfry, widzimy, że jest to B. Ponieważ B=11w bazie 20 program wyświetli 1 kropkę od 11%5=1i 2 słupki od 11//5=2. Teraz otrzymujemy to:

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

Wreszcie, łącząc to wszystko, otrzymujemy to:

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




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




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

I to jest liczba Majów dla 431! Nareszcie masz swoją podstawową liczbę 10 reprezentowaną przez podstawowe 20 liczb Majów.

Uwaga: Być może zauważyłeś tę lambdafunkcję w moim kodzie. Niezależnie od tego, funkcja ta jest używana do tworzenia kropek, ponieważ wiele kropek musi być wyprowadzonych obok siebie.

R. Kap
źródło
Nie jestem pewien, czy to możliwe, ale czy możesz to zrobić S,N,M,X=' -|\n'zamiast S,N,M,X=' ','-','|','\n'?
Adnan
@Adnan to możliwe.
Rɪᴋᴇʀ
@Adnan Naprawdę? Wow, nie wiedziałem tego. Dzięki!
R. Kap
401zawiera wewnętrzne zero.
Neil
@Neil Oh, racja. Dzięki za zgłoszenie się. Teraz jest naprawione.
R. Kap
3

Python 3, 243 bajty

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)

Dyskusja

n//20and m(n//20)dzwoni m()rekurencyjnie, jeśli trzeba obsłużyć wyższe uprawnienia o wartości 20. Rekurencja jest wykonywana przed wydrukowaniem bieżącej wartości miejsca, aby najpierw wydrukować wyższe moce.

Jeśli bieżąca wartość miejsca jest różna od zera (r! = 0), symbol for a,b,f opcja -loop drukuje jednostki, a następnie piątki. ajest pierwszym / czwartym rzędem i bjest drugim / trzecim rzędem. Sztuką jest print(*((a,b,b,a)*f),sep=x). Dla jednostek f = 1 powoduje print(*(a,b,b,a),sep=x), że wypisuje 4 rzędy, które składają się na symbole jednostek (x jest „\ n”). W przypadku piątek f = liczba piątek do wydrukowania (r // 5), więc krotka (a, b, b, a) zostaje pomnożona (tj. Powtórzona) przez liczbę piątek do wydrukowania. Jeśli f = 2, otrzymujemy print(*(a,b,b,a,a,b,b,a),sep=x), który wypisuje dwa symbole na pięć.

Jeśli bieżąca wartość miejsca wynosi 0, to drukowany jest symbol zero.

RootTwo
źródło
Musiałem wynagrodzić nagrodę R. Kapowi, ale może to zasługiwać na nagrodę! Dobra robota!
Rɪᴋᴇʀ
2

Python, 411 bajtów

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'

Stworzyłem to do generowania przypadków testowych, możesz użyć go jako wzorca. Trochę golfa.

Rɪᴋᴇʀ
źródło
Możesz usunąć 26 bajtów, usuwając spacje, a kolejne 4, wykonując s=math.sqrti dzwoniąc s(s(w))zamiastmath.sqrt(math.sqrt(w))
James
@DrGreenEggsandHamDJ dzięki. Ale nie sądzę, że mam 26 bajtów wolnego od białych znaków?
Rɪᴋᴇʀ
Och, przepraszam, liczenie błędu miałem na myśli 25. w**0.25Jest jeszcze lepszy niż s(s(w)). Chociaż stało się dłużej?
James
@DrGreenEggsandHamDJ tak, jakoś zgubiłem ciąg zerowy powłoki podczas przesyłania z pliku do odpowiedzi.
Rɪᴋᴇʀ
2

JavaScript (ES6), 254 bajty

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
źródło
Nie mogę tego uruchomić? Błąd z Missing } in template expression. Nie wiem bardzo dużo js, ​​jak mogę to naprawić?
Rɪᴋᴇʀ
@ EᴀsᴛᴇʀʟʏIʀᴋ Mój zły, przesunąłem trochę kodu i przypadkowo wkleiłem go w niewłaściwym miejscu. Teraz jest naprawione.
Neil
1

Python 3, 213 bajtów

Wymyślili jeszcze krótszą wersję, stosując inne podejście:

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

wyjaśnienie

Około pierwszych 9 wierszy tworzy ciągi, które są używane do tworzenia symboli

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

Rdzeniem rozwiązania jest funkcja rekurencyjna m, która buduje listę ciągów, po jednym dla każdego wiersza wyniku. Schematycznie mwygląda następująco:

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

m można przepisać jak:

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

Wywołanie rekurencyjne m(n//20)jest na pierwszym miejscu, tak że najbardziej znaczące cyfry są wykonywane jako pierwsze.

[n%5*a,n%5*b,n%5*b,n%5*a]są ciągiem symboli. ato górny wiersz dla pojedynczego symbolu. n%5to liczba jeden symboli dla tej cyfry. Jest więc n%5*aciągiem dla górnego (i dolnego) rzędu n%5jednych. Podobnie „n% 5 * b” jest łańcuchem dla drugiego (i trzeciego) wiersza.

Wyrażenie [:n%5*4]działa jakif aby uniknąć dodatkowych pustych linii na wyjściu, jeśli nie ma żadnych „jednych” do wyjścia. Nie jest to konieczne, ale poprawia wygląd.

n%20//5oznacza liczbę potrzebnych pięciu symboli. [c,d,d,c]to ciągi znaków, które tworzą jeden symbol na pięć.

[t,w,w,v+h*19+v,y,y,t] to ciągi znaków, które tworzą symbol zerowy

[x,x] umieszcza co najmniej trzy puste linie między grupami cyfr Majów

RootTwo
źródło
Czy możesz wyjaśnić, jak to działa?
Rɪᴋᴇʀ