ASCII Нові майя


21

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

Цифри майя

Цифри майя - це двозначна система (основа 20), що використовує лише 3 символи:

  • < >for Zero (Правильний символ - це якась оболонка, яку неможливо легко представити за допомогою 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

@isaacg Дякую, у мене насправді було 15 людей, які з'явилися в потрібному місці, а також між 19 і 20. Виправлено.
Фаталізувати

@Fatalize Чи потрібно друкувати вихідний результат (тобто STDOUT) чи може моя функція просто повернути результат?
rink.attendant.6

@ rink.attendant.6 Повинен бути надрукований так, як вони є у дописі.
Фаталізувати

Чи добре, якщо 1 - один стовпчик праворуч, а 3 - один стовпець зліва?
араґер

Відповіді:


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

Дякую Дому Гастінгсу за те, що він допомагає мені зберегти 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
Думаючи про це, якщо ви хочете коли-небудь мати ціле число і ігнорувати залишок, ви можете використовувати магічну змінну, $-яка завжди буде скорочуватися до int ... може заощадити ще кілька!
Дом Гастінгс

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

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]

ex2


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дужки?
Пуховик


@vihan Що нічого не видає, воно просто повертається.
rink.attendant.6

не знав, що це вимога, оскільки введення даних може здійснюватися через функцію. pastebin.com/0pS0XtJa на 3 байти коротше
Пуховик

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]з a=n%5, яка переміщує всі n%5S поза, і змінює умовну на *(a>0)який повертає порожній рядок в a==0протягом того ж ефекту.
Шерлок9

І, нарешті, поставив 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 байт.
Шерлок9

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 байт

Ця відповідь ґрунтується на відповіді Якубе Піта і відповіді Локолуїса Пітона 2.

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

@ user202729 Бо .і ..там має бути пробіл, тож я поставив і його .... Чи є коротший шлях?
ділнан

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

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