ASCII Арт майя цифры

14

Этот вызов прост. Учитывая число, выведите ascii-art представление числа, используя систему счисления Basean-20 майя.

Что такое система майя?

Майя использовали базу 20 для хранения чисел, поэтому первая позиция была 1s, следующая 20s, затем 400s и т. Д.

Так майя число 1находится 1в основании 10, но 10на самом деле 20в базе 10, 207находится 807в основании 10, и т.д ..

И они представляли свои номера в виде пиктограмм со специальным символом для 0.

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

Это был их ноль. (по крайней мере, половина picascii половина моей художественной версии ascii art)

Это реальная картина нулевого символа майя. 1

Это была их пятерка:

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

И 4:

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

Наконец, чтобы собрать это вместе:

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

Таким образом, у них есть x//5бары и x%5точки сверху баров. И если x=0они используют оболочку / буханку вместо пробела.

Для большего количества изображений, попробуйте страницу Wikimedia Commons с изображениями майя .

Но это только для номеров до 19. Нам не разрешено иметь больше, чем 4бары и 4точки в одной «истории» ... Итак, мы идем вверх!

Выход за 20:

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



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

Обратите внимание, что обычно это неверно, потому что is имеет a 1и a 0одновременно. Но 3(обратите внимание, что вашему ответу нужно как минимум 3) переводы строки перед 0средним значением места.

Нижняя история имеет точки, значения 1и значения баров 5. Но на самом деле это имеет значение точек 20^0и баров 20^0 * 5.

Каждая история поднимается силой. Вторая история точки означают 20( 20^1) и 100( 20^1 * 5).

Таким образом, число 506может быть представлено как:

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




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




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

Это (20^0) * 1 + (20^0 * 5) * 1 + (20^1 * 5) * 1 + (20^2) * 1 = 1 + 5 + 100 + 400 = 506.

Ваша миссия, если вы не захотите или не захотите (это не имеет значения), состоит в том, чтобы вывести ascii art представление числа base-10.

Другие правила:

  • Начальное / конечное пространство в порядке, если точки, бары и оболочки не повреждены.
  • Столбцы, точки и оболочки должны быть точно такими же, как в тестовых примерах. Без изменения размера.
  • «0» - это нормально. (ведущие снаряды на выходе)
  • Вам не нужно иметь ровно 3 символа новой строки между каждым значением места или историей, по крайней мере, 3.

Тестовые случаи:

15

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

12

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



4

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


0

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


24

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




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



33



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




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



20



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




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

1: Они также использовали головы богов для символов, но для этого испытания будет использован сундук с ракушками / хлебом / зельдой .

Rɪᴋᴇʀ
источник
but for this challenge the shell/bread will be used., Не скорлупа, не хлеб. ЛОЗ ссылка на прошлый сундук.
Лысая банта
youtube.com/watch?v=69AyYUJUBTg
Лысая банта
@epicTCK .... это действительно замечательно ...
R
1
Связанный.
Мартин Эндер

Ответы:

4

Рубин, 223 180 177 179 байт

Анонимная функция, возвращает многострочную строку.

Забыл добавить дополнительный интервал, который был необходим, а также рекурсию. Также играю в гольф немного больше, перемещая вещи вокруг.

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]}
Значение чернил
источник
Вы самый гольфист. Congrats!
Rɪᴋᴇʀ
6

Python 3.5, 404 400 392 312 311 308 290 281 285 281 байт:

( Спасибо Аднану за подсказку по экономии 9 байт ( 290->281) и Нейлу за подсказку по экономии 4 байт ( 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]]

Попробуйте онлайн! (Ideone)

Анализ

Для целей этого анализа мы будем использовать набор символов 0123456789ABCDEFGHIJдля представления каждой цифры в базе 20.

Итак, я мог бы пойти и преобразовать базу 10 в базу 20, используя один из двух моих алгоритмов. Первый алгоритм, который я подумал использовать, это то, что я называю алгоритмом степеней . Это не тот, который я использовал в коде, хотя он сделал бы его длиннее, чем следовало бы, поэтому я не буду говорить об этом. Тем не менее, я создал скрипт Python, который преобразует любое целое число в базе 10 в любую другую базу, предоставленную с использованием этого метода, которую вы можете использовать здесь на repl.it. Вместо этого я использовал для этого испытания то, что я называю алгоритмом деления , которое, я думаю, объясняется здесь довольно хорошо., Но в основном происходит то, что он берет предоставленное число 10 оснований и делит его на основание, в которое нужно преобразовать число, в которое в данном случае равно 20, пока остаток не будет равен 0 или 1. Затем он берет частное и остаток в этом порядке от последней операции деления, а затем все остальные остатки от других операций деления в порядке от последней к первой. Все эти цифры затем соединяются вместе, и эта объединенная последовательность является обратной цифрой 10 в базе 20! Чтобы проиллюстрировать это, предположим, что вы хотите преобразовать число 10 431в базу 20. Итак, что бы мы сделали, это:

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

Затем, наконец, мы возьмем список, который у нас есть, который в этом случае содержит B11, и перевернем его, чтобы мы теперь имели 11B. При этом мы наконец получили наш окончательный ответ! 431 в базе 10 преобразована в базу 20 is 11B, что может быть подтверждено с помощью моего скрипта Python, использующего алгоритм степеней, на который я уже поделился ссылкой выше, но я сделаю это снова здесь . Вот тот, который также использует алгоритм деления, описанный в этом ответе, и возвращает тот же ответ, что и степенной.

Весь этот процесс, по существу , что происходит в моем сценарии в этом whileцикле: while not p or z:p+=[z%20];z=z//20. Разница лишь в том, что цифры >9представлены не буквами, а самими собой.

Двигаясь дальше, после того, как число из базовых 10 было преобразовано в основание 20, для каждой цифры в целых числах из базовых 20, которые мы будем называть g, g mod 5печатаются точки, а затем g//5выводятся столбцы. Затем программа печатает 3 пустые строки и переходит к следующей цифре. Однако, если это цифра 0, то распечатывается одна «буханка», за которой следуют 3 новые строки, а затем программа переходит к следующей цифре. Итак, взяв базовое число 20 11B, мы переходим к первой цифре. Первая цифра 1, и поэтому она будет печатать 0 баров с тех пор 1//5=0и 1 точку с тех пор 1%5=1. Итак, мы сначала получили бы это:

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

а затем 3 новые строки. Переходя ко второй цифре, мы также видим, что она равна 1, поэтому она выдает то же самое:

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

а также 3 новые строки. Наконец, переходя к последней цифре, мы видим, что это B. Поскольку B=11в базе 20 программа выдаст 1 точку с 11%5=1и 2 бара с тех пор 11//5=2. Итак, теперь мы получаем это:

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

Наконец, собрав все это вместе, мы получим следующее:

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




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




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

И это число майя для 431! Наконец, у вас есть 10 базовых чисел, представленных цифрами 20 майя.

Примечание. Вы можете заметить или не заметить эту lambdaфункцию в моем коде. В любом случае, эта функция используется для создания точек, поскольку несколько точек должны выводиться рядом друг с другом.

Р. Кап
источник
Я не уверен, если это возможно, но вы можете сделать S,N,M,X=' -|\n'вместо S,N,M,X=' ','-','|','\n'?
Аднан
@ Аднан, это возможно.
Rɪᴋᴇʀ
@ Adnan Действительно? Вау, я этого не знал. Благодарность!
Р. Кап
401содержит внутренний ноль.
Нил
@ Нил О, верно. Спасибо за хедз-ап. Это сейчас исправлено.
Р. Кап
3

Python 3, 243 байта

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)

обсуждение

n//20and m(n//20)вызывает m()рекурсивно, если есть более высокие полномочия 20, которые будут обработаны. Рекурсия выполняется перед печатью текущего значения места, чтобы сначала печатались более высокие полномочия.

Если текущее значение места не равно нулю (r! = 0), for a,b,f-loop печатает единицы, а затем пятерки. aпервый / четвертый ряд и bвторой / третий ряд. Хитрость в print(*((a,b,b,a)*f),sep=x). Для единиц, f = 1, в результате print(*(a,b,b,a),sep=x)чего печатаются 4 строки, которые составляют символы единиц (x является '\ n'). Для пятерок f = количество пятерок для печати (r // 5), поэтому кортеж (a, b, b, a) умножается (т.е. повторяется) на количество пятерок для печати. Если f = 2, мы получаем print(*(a,b,b,a,a,b,b,a),sep=x), что печатает два символа для пяти.

Если текущее значение места равно 0, то печатается символ нуля.

RootTwo
источник
Я должен был наградить награду Р. Капу, но это может заслужить его собственную награду! Хорошая работа!
Rɪᴋᴇʀ
2

Python, 411 байт

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'

Я создал это для генерации тестовых случаев, вы можете использовать его в качестве эталона. Сорта в гольф.

Rɪᴋᴇʀ
источник
Вы можете удалить 26 байт, удалив пробелы, и еще 4, выполнив s=math.sqrtи позвонив s(s(w))вместоmath.sqrt(math.sqrt(w))
Джеймс
@DrGreenEggsandHamDJ спасибо. Я не думаю, что я получил 26 байтов от пробела, хотя?
Rɪᴋᴇʀ
Ой, извините, ошибка подсчета я имела в виду 25. Кроме того, w**0.25даже лучше, чем s(s(w)). Хотя это стало длиннее?
Джеймс
@DrGreenEggsandHamDJ да, я как-то потерял нулевую строку оболочки при передаче из файла в ответ.
Rɪᴋᴇʀ
2

JavaScript (ES6), 254 байта

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}
`)
Нил
источник
Я не могу заставить это работать? Это ошибки с Missing } in template expression. Я не очень хорошо знаю JS, как я могу это исправить?
Rɪᴋᴇʀ
@ EᴀsᴛᴇʀʟʏIʀᴋ Плохо, я переместил код и случайно вставил его не в то место. Это сейчас исправлено.
Нил
1

Python 3, 213 байт

Придумали еще более короткую версию, используя другой подход:

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

объяснение

Первые 9 строк или около того, строят строки, которые используются для создания символов

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

Ядром решения является рекурсивная функция m, которая создает список строк, по одной строке на каждую строку в выводе. Схематично mвыглядит так:

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

m можно переписать так:

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

m(n//20)Сначала идет рекурсивный вызов, поэтому самые важные цифры выполняются первыми.

[n%5*a,n%5*b,n%5*b,n%5*a]являются строкой для одних символов. aверхняя строка для одного символа. n%5количество символов для этой цифры Итак, n%5*aстрока для верхнего (и нижнего) ряда из n%5них. Точно так же 'n% 5 * b` является строкой для 2-й (и 3-й) строки.

Выражение [:n%5*4]действует как an, ifчтобы избежать лишних пустых строк в выводе, если нет никаких «выводимых». Это не нужно, но делает вывод лучше.

n%20//5количество символов для пяти, которые необходимы. [c,d,d,c]строки, чтобы сделать один символ для пяти.

[t,w,w,v+h*19+v,y,y,t] строки для создания нулевого символа

[x,x] ставит как минимум три пустые строки между группами цифр майя

RootTwo
источник
Можете ли вы объяснить, как это работает?
Rɪᴋᴇʀ