Числа майя ASCII


21

Напишите программу или функцию, которая, учитывая положительное целое число в качестве входных данных, выводит представление этого целого числа в числах майя .

Цифры майя

Цифры майя - это образная система (основание 20), использующая только 3 символа:

  • < >для нуля (правильный символ - это своего рода оболочка, которую трудно представить с помощью ASCII).
  • .для одного
  • ----для пяти

Числа записаны вертикально в степенях 20, а числа от 0 до 19 написаны как стеки по пять и единицы . Вы должны обратиться к статье Википедии для более подробной информации.

Например, вот цифры от 0 до 25, разделенные запятыми:

                                                                                 .    ..  ...  ....
                                                        .    ..  ...  .... ---- ---- ---- ---- ----  .    .    .    .    .    .
                               .    ..  ...  .... ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
<  >, .  , .. ,... ,....,----,----,----,----,----,----,----,----,----,----,----,----,----,----,----,<  >, .  , .. ,... ,....,----

входные

  • Входные данные всегда являются положительными целыми числами от 0 до 2147483647 (2 ^ 31 - 1).
  • Вы можете использовать входные данные из STDIN в качестве аргумента командной строки, параметра функции или чего-либо подобного.

Выходы

  • Каждая строка длиной не более 4 символов. < >и ----всегда должен быть напечатан, как указано здесь (4 символа каждый).
  • Ones ( .) должен быть центрирован на линии. Если их 1 или 3 ., поскольку идеальное горизонтальное выравнивание невозможно, не имеет значения, находятся ли они на один столбец слева или на один столбец справа или по центру.
  • Должна быть ровно одна пустая строка между различными степенями 20, независимо от высоты стеков в степени 20 с. Например, правильные выходные данные для 25 и 30:

            .
     .
           ----
    ----   ----
    
  • Не допускаются ни ведущие, ни конечные линии.

  • Выходные данные должны быть напечатаны точно так же, как в приведенных примерах.

Контрольные примеры

  • Каждое отдельное число от 0 до 25 приведено в качестве примера выше.

  • Входные данные: 42

Выход:

 .. 

 .. 
  • Входные данные: 8000

Выход:

 .  

<  >

<  >

<  >
  • Входные данные: 8080

Выход:

 .  

<  >

....

<  >
  • вход: 123456789

Выход:

 .  

... 
----
----
----

 .  
----
----

 .. 
----
----

 .  

....
----
----
----

....
----
  • Входные данные: 31415

Выход:

... 

... 
----
----
----

----
----

----
----
----
  • Входные данные: 2147483647

Выход:

 .  

... 
----
----

 .  
----
----

 .  

----
----
----

....
----

 .. 

 .. 
----

счет

Это , поэтому выигрывает самый короткий код в байтах.


15 и 20 кажутся идентичными.
Исаак

@isaacg Спасибо, у меня на самом деле было 15 появлений как в нужном месте, так и между 19 и 20. Исправлено.
Fatalize

@Fatalize Нужно ли выводить вывод (т.е. STDOUT) или моя функция просто возвращает вывод?
rink.attendant.6

@ rink.attendant.6 Должен быть напечатан точно так, как они есть в посте.
Fatalize

Это нормально, если 1 - один столбец справа, а 3 - один столбец слева?
aragaer

Ответы:


3

Pyth, 41 байт

j+bbm|jb_m.[\ 4kc:*d\.*5\.*4\-4"<  >"jQ20

Попробуйте онлайн: демонстрация

Объяснение:

                                     jQ20   convert input to base 20
    m                                       map each value d to:
                  *d\.                         string of d points
                 :    *5\.*4\-                 replace 5 points by 4 -s
                c             4                split into groups of 4
         m.[\ 4k                               center each group
        _                                      invert order
      jb                                       join by newlines
     |                         "<  >"          or if 0 use "<  >"
j+bb                                        join by double newlines

5

Perl, 125 117 байт

$-=<>;{$_=($-%20?(""," .
"," ..
","...
","....
")[$-%5]."----
"x($-/5&3):"<  >
").$_;($-/=20)&&($_=$/.$_,redo)}print

Спасибо Dom Hastings за помощь в экономии 8 байтов.


1
Эй, самгак, пара изменений байтов больше, чем redo,if(int($i/=20))ты можешь использовать ~~($i/=20)&&redo. ~~преобразует в int - вы также можете использовать 0|в начале (или |0в конце). Кроме того, замена substr(".... ... .. . ",20-$i%5*5,5)на, (' .', ' ..','...','.'x4)[$i%5-1].$/кажется, работает нормально, но я не проверял все контрольные примеры ... Если они сработают, вы упадете до 114 ... Если я подумаю о чем-нибудь еще, чтобы поделиться, я дам вам знать!
Дом Гастингс

1
Подумав об этом, если вы когда-нибудь захотите иметь целое число и игнорировать остаток, вы можете использовать магическую переменную, $-которая всегда будет усечена до целого ... может сэкономить еще несколько!
Дом Гастингс

1
Спасибо @DomHastings, трюк преобразования int экономит пару байтов, а избавление от substr сохраняет еще 4. Новые строки должны идти внутри строковых констант, потому что в случае, когда нет точек, не должно быть новой строки.
Самгак

1
@DomHastings действительно так, спасибо еще раз! Я предполагаю, что это означает, что я должен избавиться от своей шутки о конце света
samgak

4

JavaScript ES6, 143 байта

Нагрузка байтов добавлена, потому что нужно console.log, может сохранить еще 23 байта без него.

n=>console.log((d=(x,s='',l=1,j=x/l|0)=>s+(j>19?d(x,s,l*20)+`

`:'')+((j=j%20)?(' '+`.`.repeat(j%5)).slice(-4)+`
----`.repeat(j/5):'<  >'))(n))

4

Mathematica 185 182 171 153

Благодаря сохранению 18 байтов благодаря предложению Arcinde использовать анонимные функции,

c=Column;c[If[#>0,{q,r}=#~QuotientRemainder~5;c@{{""," ."," .."," ...","...."}[[r+1]],c@{{""},{d="----"},{d,d},{d,d,d}}[[q+1]]},"< >"]&/@#~IntegerDigits~20]&

пример

c[If[# > 0, {q, r} = #~QuotientRemainder~5; c@{{"", " .", " ..", " ...", "...."}[[r + 1]], c@{{""}, {d = "----"}, {d, d}, {d, d, d}}[[q + 1]]}, "< >"] & /@ #~IntegerDigits~20] &[31415]

выход


проверка

Десятичное число 31415, выраженное в базе 20. Mathematica использует строчные буквы для этого.

BaseForm[31415, 20]

база 20


Десятичные цифры, соответствующие вышеуказанному основанию 20 числа.

IntegerDigits[31415,20]

{3, 18, 10, 15}


Другой пример

IntegerDigits[2147483607, 20]

{1, 13, 11, 1, 15, 9, 0, 7}

c[If[# > 0, {q, r} = #~QuotientRemainder~5;c@{{"", " .", " ..", " ...","...."}[[r + 1]], c@{{""}, {d = "----"}, {d, d}, {d, d, d}}[[q + 1]]},"< >"] & /@ #~IntegerDigits~20] &[2147483607]

ех2


c=Column;c[If[#>0,{q,r}=#~QuotientRemainder~5;c@{{""," ."," .."," ...","...."}[[r+1]],c@{{""},{d="----"},{d,d},{d,d,d}}[[q+1]]},"< >"]&/@#~IntegerDigits~20]&используя анонимные функции.
jcai

@ Arcinde, спасибо. Старые добрые анонимные функции.
DavidC

3

JavaScript (ES6), 157 байт

Новые строки значимы и считаются по 1 байту каждая. Поскольку печать в STDOUT обязательна, console.logстоит мне несколько байтов.

f=i=>console.log([...i.toString(20)].map(j=>(!(j=parseInt(j,20))||j%5?[`<  >`,` .`,` ..`,`...`,`....`][j%5]+`
`:'')+`----
`.repeat(j/5)).join`
`.slice(0,-1))

демонстрация

Для демонстрации я напишу версию ES5, чтобы она работала во всех браузерах:

// Snippet stuff
console.log = function(x) {
  O.innerHTML = x;
}
document.getElementById('I').addEventListener('change', function() {
  f(this.valueAsNumber);
}, false);

// Actual function
f = function(i) {
  console.log(i.toString(20).split('').map(function(j) {
    return (! (j = parseInt(j, 20)) || j % 5 ? ['<  >', ' .', ' ..', '...', '....'][j % 5] + '\n' : '') + '----\n'.repeat(j / 5);
  }).join('\n').slice(0,-1));
}
<input type=number min=0 max=2147483647 value=0 id=I>

<pre><output id=O></output></pre>


Нужна ли последняя .joinскобка?
Downgoat


@vihan Это ничего не выводит, просто возвращает.
rink.attendant.6

не знал, что это было требованием, так как ввод может быть через функцию. pastebin.com/0pS0XtJa на 3 байта короче
Downgoat

2

Python 2.x, 142 байта:

def m(n):
 h=[[""," "*(2-n%5/2)+"."*(n%5)+"\n"][n%5!=0]+"----\n"*(n%20/5),"<  >\n"][n%20==0]
 n/=20
 if n>0:
  h=m(n)+"\n\n"+h
 return h[:-1]

Пример:

>>> print m(2012)
----

<  >

 ..
----
----
>>> 

Редактировать: завершающая линия ...


У меня есть несколько улучшений, чтобы предложить. Во-первых, измените [n%20==0]на [n%20<1]. Во-вторых, измените [[""," "*(2-n%5/2)+"."*(n%5)+"\n"][n%5!=0]на h=[(" "*(2-a/2)+"."*a+"\n")*(a>0)+"----\n"*(n%20/5),"< >\n"][n%20<1]with a=n%5, что перемещает все n%5s и изменяет условное *(a>0)выражение, в которое возвращается пустая строка a==0для того же эффекта.
Sherlock9

И, наконец, поставил a, hи nна одной линии, например , так: a=n%5;h=[(" "*(2-a/2)+"."*a+"\n")*(a>0)+"----\n"*(n%20/5),"< >\n"][n%20<1];n/=20. Все это должно оставить у вас 131 байт.
Sherlock9

2

CJam, 82 76 байт

li{_K%[""" .
"" ..
""...
""....
"]1$5%='-4*N+2$5/3&*+"<  >
"?N+L+:L;K/}h;L);

Моя первая программа CJam, в основном, просто транслитерация моего Perl-ответа на CJam.

Попробуй онлайн

Многострочный с комментариями:

li            # read input
{             # start of do-while loop
  _K%         # check if this base-20 digit is a zero
    [""" .
    "" ..
    ""...
    ""....
    "]1$5%=   # push dots for 1s onto stack
    '-4*N+2$5/3&*+    # push lines for 5s onto stack

    "<  >
    "         # push zero on stack
  ?           # ternary if test (for digit equals zero)
  N+L+:L;     # pre-concatenate string with output plus newline
  K/          # divide by 20
}h            # end of do while loop
;L);          # push output string on stack, chop off trailing newline

1

PHP, 220 байт

Такой же подход, как мой ответ JavaScript. PHP имеет встроенные функции для всего.

Принимает 1 ввод из командной строки (т.е. STDIN), как видно с $argv[1]:

<?=rtrim(implode("\n",array_map(function($j){return(!($j=base_convert($j,20,10))||$j%5?['<  >', ' .', ' ..', '...', '....'][$j%5]."\n":'').str_repeat("----\n",$j/5);},str_split(base_convert($argv[1],10,20)))));

1

С - 149

f(v){v/20&&(f(v/20),puts("\n"));if(v%=20)for(v%5&&printf("%3s%s","...."+4-v%5,v/5?"\n":""),v/=5;v--;v&&puts(""))printf("----");else printf("<  >");}

Использует рекурсию для печати наиболее значимых чисел в первую очередь. Затем либо печатает ноль, либо печатает все точки одним умным printf и всеми пятерками в цикле. Я не уверен, смогу ли я избежать использования if-else здесь.

Недостатком умного printf является то, что 1 и 3 не выровнены друг с другом:

Результат для 23 это:

  .

...

119 неправильное решение - завершающий перевод строки

f(v){v/20&&(f(v/20),puts(""));if(v%=20)for(v%5&&printf("%3s\n","...."+4-v%5),v/=5;v--;)puts("----");else puts("<  >");}


1

PHP, 202 192 байта

function m($n){return(($c=($n-($r=$n%20))/20)?m($c)."\n":"").
($r?(($q=$r%5)?substr(" .   .. ... ....",$q*4-4,4)."\n":"").
str_repeat("----\n",($r-$q)/5):"<  >\n");}
echo rtrim(m($argv[1]),"\n");

Он получает входные данные из первого аргумента командной строки.

Полный исходный код с комментариями и тестами доступен на github .


\nэто два символа - но новая строка в середине строки - только один.
fisharebest

1

Python 2, 114 байт

Этот ответ основан на ответе Pyak Якуба и ответе Python 2 Locoluis.

def f(n):d,m=divmod(n%20,5);h=[" "*(2-m/2)+"."*m+"\n----"*d,"<  >"][n%20<1];n/=20;return(f(n)+"\n\n"if n else"")+h

0

Желе , 50 49 47 байт

b5µṪ”.x⁶;$L<3Ɗ¡ṭ⁾--;UW¤ẋ$Ẏ$L¡Ṛø“<  >”WµẸ?
b20Ç€

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

... теперь выровнен по левому краю благодаря точке user202729.

Когда вы обманываете себя мышлением < >, это палиндром ...


Почему вы выравниваете по правому ...
краю

@ user202729 Для .и ..должен быть пробел, поэтому я поставил один для .... Есть ли более короткий путь?
Дилнан

Я думаю, что в соответствии со спецификацией задачи ...не должно быть правильное выравнивание. Просто поменять <4на <3?
user202729

@ user202729 Вы правы, я думаю, что неправильно прочитал спецификацию. Я не думаю, что это указывает на ... но я могу изменить его на <2
dylnan
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.