Angka Seni ASCII Maya

14

Tantangan ini sederhana. Diberi nomor, keluaran representasi ascii-art dari angka, menggunakan sistem angka Maya-20 Base.

Apa itu sistem Maya?

Bangsa Maya menggunakan basis 20 untuk menyimpan angka, jadi posisi pertama adalah 1tempat, berikutnya 20tempat, kemudian 400, dll.

Jumlah Jadi Maya 1adalah 1dalam basis 10, tapi 10sebenarnya 20dalam basis 10, 207adalah 807dalam basis 10, dll ..

Dan mereka mewakili jumlah mereka sebagai piktograf, dengan simbol khusus untuk 0.

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

Itu nol mereka. (Setidaknya setengah picascii setengah artistikness ascii art version)

Itu adalah gambaran nyata dari simbol nol Maya. 1

Ini adalah lima mereka:

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

Dan 4:

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

Akhirnya, untuk menyatukannya:

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

Jadi mereka memiliki x//5bar, dan x%5titik di atas bar. Dan jika x=0, mereka menggunakan shell / roti bukannya ruang kosong.

Untuk lebih banyak gambar, coba halaman Wikimedia Commons dari gambar angka Maya .

Tapi ini hanya untuk angka hingga 19. Kami tidak diizinkan memiliki lebih dari satu 4bar dan 4titik dalam satu 'cerita' ... Jadi, kami naik!

Output untuk 20 adalah:

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



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

Perhatikan ini biasanya tidak valid, karena memiliki 1dan 0pada saat yang sama. Tetapi 3(perhatikan bahwa, jawaban Anda memerlukan setidaknya 3) baris baru sebelum nilai 0tempat baru.

Cerita dasar memiliki titik, makna 1, dan makna batangan 5. Tetapi sebenarnya memiliki makna titik 20^0dan makna bar 20^0 * 5.

Setiap cerita naik kekuatan. Titik-titik cerita kedua berarti 20( 20^1) dan 100( 20^1 * 5).

Jadi jumlahnya 506dapat direpresentasikan sebagai:

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




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




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

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

Misi Anda, jika Anda memilih tidak atau memilih untuk (tidak masalah), adalah untuk menghasilkan representasi seni ASCI dari nomor base-10.

Aturan lain:

  • Leading / trailing space tidak apa-apa, selama titik, bar, dan cangkang utuh.
  • Batang, titik, dan cangkang harus persis seperti apa yang dimiliki oleh uji kasus. Tidak mengubah ukuran.
  • Memimpin '0 tidak apa-apa. (shell terkemuka pada output)
  • Anda tidak harus memiliki persis 3 baris baru antara setiap nilai tempat atau cerita, cukup setidaknya 3.

Kasus uji:

15

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

12

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



4

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


0

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


24

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




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



33



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




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



20



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




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

1: Mereka juga menggunakan kepala para dewa untuk simbol-simbol, tetapi untuk tantangan ini peti / roti / zelda akan digunakan.

Rɪᴋᴇʀ
sumber
but for this challenge the shell/bread will be used.. Bukan kulit, bukan roti. Tautan LOZ ke dada sebelumnya.
Botak Bantha
@epicTCK .... yang sebenarnya sangat seperti itu ...
R
1
Terkait
Martin Ender

Jawaban:

4

Ruby, 223 180 177 179 byte

Fungsi anonim, mengembalikan string multiline.

Lupa menambahkan spasi tambahan yang diperlukan, dan juga rekursi. Juga bermain golf sedikit lebih dengan menggeser sesuatu di sekitar.

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]}
Nilai Tinta
sumber
Anda yang paling golf. Selamat!
R
6

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

( Terima kasih kepada Adnan untuk tip menghemat 9 byte ( 290->281) dan Neil untuk tip menghemat 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]]

Cobalah online! (Ideone)

Analisis

Untuk keperluan analisis ini, kita akan menggunakan set karakter 0123456789ABCDEFGHIJuntuk mewakili setiap digit dalam basis 20.

Jadi, saya bisa saja mengubah basis 10 menjadi basis 20 menggunakan salah satu dari dua algoritma yang saya miliki. Algoritma pertama yang saya pikirkan untuk digunakan adalah apa yang saya sebut algoritma kekuatan . Ini bukan yang saya gunakan dalam kode karena itu akan membuatnya lebih lama dari yang seharusnya, jadi saya tidak akan berbicara tentang ini. Namun, saya memang membuat skrip python yang mengubah bilangan bulat apa pun di basis 10 menjadi basis lain yang disediakan menggunakan metode ini, yang dapat Anda gunakan di sini di repl.it. Yang saya gunakan sebagai gantinya untuk tantangan ini adalah apa yang saya sebut algoritma pembagian , yang menurut saya dijelaskan cukup baik di sini. Tetapi pada dasarnya apa yang terjadi adalah bahwa dibutuhkan nomor basis 10 yang disediakan dan membaginya dengan basis yang perlu dikonversi ke angka, yang dalam hal ini adalah 20, sampai sisanya adalah 0 atau 1. Kemudian diperlukan kuotiant dan sisanya , dalam urutan itu, dari operasi divisi terakhir , dan kemudian semua sisa lainnya dari operasi divisi lainnya dalam urutan dari yang terakhir hingga yang pertama. Semua digit ini kemudian disatukan, dan urutan yang digabungkan itu dibalik adalah nomor basis 10 Anda di basis 20! Untuk mengilustrasikan ini, anggap Anda ingin mengonversi nomor basis 10 431ke basis 20. Jadi, apa yang akan kami lakukan adalah ini:

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

Kemudian, akhirnya kita akan mengambil daftar yang kita miliki, yang dalam hal ini berisi B11, dan membalikkannya sehingga sekarang kita miliki 11B. Dalam melakukan ini, kami akhirnya mendapatkan jawaban akhir kami! 431 di basis 10 dikonversi ke basis 20 adalah 11B, yang dapat dikonfirmasi menggunakan skrip Python saya yang menggunakan algoritma kekuatan yang sudah saya bagikan tautan di atas, tetapi saya akan melakukannya lagi di sini . Berikut ini adalah salah satu yang juga menggunakan algoritma pembagian yang dijelaskan dalam jawaban ini dan mengembalikan jawaban yang sama dengan yang kekuatan.

Seluruh proses ini pada dasarnya apa yang terjadi dalam naskah saya dalam whilelingkaran: while not p or z:p+=[z%20];z=z//20. Satu-satunya perbedaan adalah bahwa nomor >9yang tidak direpresentasikan sebagai huruf melainkan sebagai diri mereka sendiri.

Pindah, setelah nomor basis 10 telah dikonversi ke basis 20, untuk setiap digit dalam basis 20 integer, yang akan kita panggil g, g mod 5titik-titik dicetak dan g//5bar kemudian dicetak. Kemudian program mencetak 3 baris kosong dan beralih ke digit berikutnya. Namun, jika digitnya adalah 0, maka satu "roti" dicetak diikuti oleh 3 baris baru, dan kemudian program bergerak ke digit berikutnya. Jadi, dengan mengambil nomor basis 20 11B, kita pergi ke digit pertama. Digit pertama adalah 1, dan karena itu akan mencetak 0 bar sejak 1//5=0, dan 1 titik sejak 1%5=1. Jadi, pertama-tama kita akan mendapatkan ini:

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

dan kemudian 3 baris baru. Beralih ke digit kedua, kita juga melihat bahwa itu adalah 1, sehingga akan menghasilkan hal yang sama:

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

dan juga 3 baris baru. Akhirnya, pindah ke digit terakhir, kita melihat bahwa itu a B. Sejak B=11di base 20, program akan menghasilkan 1 dot sejak 11%5=1dan 2 bar sejak 11//5=2. Jadi sekarang, kita dapatkan ini:

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

Akhirnya, menyatukan semua ini, kita mendapatkan ini:

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




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




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

Dan, itulah angka utama untuk 431! Anda akhirnya memiliki nomor basis 10 Anda yang diwakili dalam angka 20 angka Maya dasar.

Catatan: Anda mungkin atau mungkin tidak memperhatikan lambdafungsi itu dalam kode saya. Apapun, fungsi ini digunakan untuk pembuatan titik-titik karena banyak titik harus dihasilkan bersebelahan.

R. Kap
sumber
Saya tidak yakin apakah itu mungkin, tetapi Anda dapat melakukan S,N,M,X=' -|\n'bukan S,N,M,X=' ','-','|','\n'?
Adnan
@ Adnan itu mungkin.
Rɪᴋᴇʀ
@ Adnan Benarkah? Wow, saya tidak tahu itu. Terima kasih!
R. Kap
401mengandung nol di dalam.
Neil
@Neil Oh, benar. Terimakasih atas peringatannya. Sudah diperbaiki sekarang.
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)

Diskusi

n//20and m(n//20)panggilan m()secara rekursif jika ada kekuatan yang lebih tinggi dari 20 untuk ditangani. Rekursi dilakukan sebelum mencetak nilai tempat saat ini, sehingga kekuatan yang lebih tinggi dapat dicetak terlebih dahulu.

Jika nilai tempat saat ini adalah nol (r! = 0), maka for a,b,f -loop mencetak unit dan kemudian lima. aadalah baris pertama / keempat dan baris bkedua / ketiga. Kuncinya ada di print(*((a,b,b,a)*f),sep=x). Untuk unit, f = 1 menghasilkan print(*(a,b,b,a),sep=x), yang mencetak 4 baris yang membentuk simbol satuan (x adalah a '\ n'). Untuk balita, f = jumlah balita untuk dicetak (r // 5), sehingga tupel (a, b, b, a) dikalikan (yaitu, diulang) dengan jumlah balita yang akan dicetak. Jika f = 2, kita dapatkan print(*(a,b,b,a,a,b,b,a),sep=x), yang mencetak dua simbol untuk lima.

Jika nilai tempat saat ini adalah 0, maka simbol nol dicetak.

RootTwo
sumber
Saya memang harus memberi hadiah kepada R. Kap, tetapi ini mungkin layak untuk hadiah itu sendiri! Pekerjaan yang baik!
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'

Saya membuat ini untuk menghasilkan kasus uji, Anda dapat menggunakannya sebagai patokan. Agak golf.

Rɪᴋᴇʀ
sumber
Anda bisa melepas 26 byte dengan menghapus spasi, dan 4 lainnya dengan melakukan s=math.sqrtdan memanggil s(s(w))alih-alihmath.sqrt(math.sqrt(w))
DJMcMayhem
@DrGreenEggsandHamDJ terima kasih. Saya tidak berpikir saya mendapat 26 byte off dari spasi?
Rɪᴋᴇʀ
Oh, maaf, menghitung kesalahan yang saya maksud 25. Juga, w**0.25bahkan lebih baik daripada s(s(w)). Meski sudah lebih lama?
DJMcMayhem
@DrGreenEggsandHamDJ ya, saya entah bagaimana kehilangan string shell nol saat transit dari file untuk menjawab.
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}
`)
Neil
sumber
Saya tidak bisa mendapatkan ini berfungsi? Kesalahan dengan Missing } in template expression. Saya tidak tahu banyak. Bagaimana cara memperbaikinya?
Rɪᴋᴇʀ
@ EᴀsᴛᴇʀʟʏIʀᴋ Buruk saya, saya memindahkan beberapa kode dan tidak sengaja menempelnya di tempat yang salah. Sudah diperbaiki sekarang.
Neil
1

Python 3, 213 byte

Datang dengan versi yang lebih pendek menggunakan pendekatan yang berbeda:

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

penjelasan

9 baris pertama atau lebih, buat string yang digunakan untuk membuat simbol

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

Inti dari solusi adalah fungsi rekursif m, yang membangun daftar string, satu string untuk setiap baris dalam output. Secara skematis, mterlihat seperti:

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

m dapat ditulis ulang seperti:

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

Panggilan rekursif didahulukan m(n//20)sehingga angka yang paling signifikan dilakukan terlebih dahulu.

[n%5*a,n%5*b,n%5*b,n%5*a] adalah string untuk simbol seseorang. aadalah baris teratas untuk satu simbol. n%5adalah jumlah satu simbol untuk digit ini. Jadi, n%5*aadalah string untuk baris atas (dan bawah) n%5. Demikian pula, 'n% 5 * b` adalah string untuk baris ke-2 (dan ke-3).

Ekspresi [:n%5*4] bertindak sepertiif untuk menghindari garis kosong tambahan dalam output jika tidak ada 'yang' untuk output. Itu tidak diperlukan, tetapi membuat output terlihat lebih baik.

n%20//5 adalah jumlah simbol untuk lima yang dibutuhkan. [c,d,d,c]adalah string untuk membuat satu simbol untuk lima.

[t,w,w,v+h*19+v,y,y,t] adalah string untuk membuat simbol nol

[x,x] menempatkan setidaknya tiga garis kosong antara kelompok digit Maya

RootTwo
sumber
Bisakah Anda memberikan penjelasan tentang cara kerjanya?
Rɪᴋᴇʀ