Numery Majów ASCII


21

Napisz program lub funkcję, która podając dodatnią liczbę całkowitą jako dane wejściowe, wyświetla reprezentację tej liczby całkowitej w liczbach Maya .

Cyfry Majów

Cyfry Majów to system wigezymalny (podstawa 20), który wykorzystuje tylko 3 symbole:

  • < >for Zero (poprawny symbol to rodzaj powłoki, której nie można łatwo przedstawić za pomocą ASCII).
  • .dla jednego
  • ----za pięć

Liczby są zapisywane pionowo w potęgach 20, a liczby od 0 do 19 są zapisywane jako stosy piątek i jedności . Więcej informacji można znaleźć w artykule w Wikipedii .

Jako przykład podajemy liczby od 0 do 25, oddzielone przecinkami:

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

Wejścia

  • Wejściami są zawsze dodatnie liczby całkowite z zakresu od 0 do 2147483647 (2 ^ 31 - 1).
  • Możesz wziąć dane wejściowe ze STDIN, jako argument wiersza poleceń, parametr funkcji lub coś podobnego.

Wyjścia

  • Każda linia ma maksymalnie 4 znaki. < >i ----zawsze powinien być wydrukowany zgodnie z podanym tutaj (każdy po 4 znaki).
  • Ones ( .) musi być wyśrodkowany na linii. Jeśli jest 1 lub 3 ., ponieważ idealne wyrównanie w poziomie jest niemożliwe, nie ma znaczenia, czy są to jedna kolumna po lewej, czy jedna kolumna po prawej, czy środek.
  • Musi być dokładnie jedna pusta linia między różnymi mocami 20, niezależnie od wysokości stosów w sile 20s. Na przykład poprawne dane wyjściowe dla 25 i 30 to:

            .
     .
           ----
    ----   ----
    
  • Niedozwolone są linie wiodące i końcowe.

  • Wyjścia muszą być wydrukowane dokładnie tak, jak w podanych przykładach.

Przypadki testowe

  • Każda indywidualna liczba od 0 do 25 podana jako przykład powyżej.

  • Wkład: 42

Wydajność:

 .. 

 .. 
  • Wkład: 8000

Wydajność:

 .  

<  >

<  >

<  >
  • Wkład: 8080

Wydajność:

 .  

<  >

....

<  >
  • wkład: 123456789

Wydajność:

 .  

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

 .  
----
----

 .. 
----
----

 .  

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

....
----
  • Wkład: 31415

Wydajność:

... 

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

----
----

----
----
----
  • Wkład: 2147483647

Wydajność:

 .  

... 
----
----

 .  
----
----

 .  

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

....
----

 .. 

 .. 
----

Punktacja

To jest , więc wygrywa najkrótszy kod w bajtach.


15 i 20 wydają się identyczne.
isaacg

@isaacg Dzięki, faktycznie miałem 15 pojawiających się zarówno we właściwym miejscu, jak i między 19 a 20. Naprawiono.
Fatalize

@Fatalize Czy wyjście musi zostać wydrukowane (tj. STDOUT) czy moja funkcja może po prostu zwrócić wynik?
rink.attendant. 6

@ rink.attendant.6 Musi być wydrukowany dokładnie tak, jak w poście.
Fatalize

Czy to w porządku, jeśli 1 to jedna kolumna po prawej, ale 3 to jedna kolumna po lewej?
aragaer

Odpowiedzi:


3

Pyth, 41 bajtów

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

Wypróbuj online: demonstracja

Wyjaśnienie:

                                     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 bajtów

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

Dzięki Dom Hastings za pomoc w oszczędzeniu 8 bajtów.


1
Hej samgak, kilka więcej zapisywania bajtów zmian, niż redo,if(int($i/=20))możesz użyć ~~($i/=20)&&redo. ~~konwertuje na int - możesz także użyć 0|na początku (lub |0na końcu). Zastępując również substr(".... ... .. . ",20-$i%5*5,5)z (' .', ' ..','...','.'x4)[$i%5-1].$/wydaje się OK działać, ale nie testowałem wszystkie przypadki testowe ... Jeśli te prace, jesteś w dół do 114 ... Jeśli myślę o niczym innym dzielić dam Ci znać!
Dom Hastings,

1
Myśląc o tym, jeśli kiedykolwiek będziesz chciał mieć liczbę całkowitą i zignorujesz resztę, możesz użyć magicznej zmiennej, $-która zawsze zostanie obcięta do int ... może zaoszczędzić jeszcze kilka!
Dom Hastings,

1
@DomHastings dzięki, sztuczka konwersji int pozwala zaoszczędzić kilka bajtów, a pozbycie się substratu oszczędza kolejne 4. Nowe znaki muszą wchodzić do stałych ciągu, ponieważ nie ma nowej linii w przypadku, gdy nie ma kropek.
samgak,

1
@DomHastings rzeczywiście tak jest, dzięki jeszcze raz! To chyba oznacza, że ​​muszę pozbyć się żartu z końca świata
samgak

4

JavaScript ES6, 143 bajty

Mnóstwo bajtów dodane, ponieważ trzeba console.log, może zaoszczędzić kolejne 23 bajty bez niego.

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

Po zapisaniu 18 bajtów dzięki sugestii Arcinde do korzystania z anonimowych funkcji,

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

Przykład

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

wydajność


Kontrola

Liczba dziesiętna 31415 wyrażona w podstawie 20. Mathematica stosuje do tego małe litery.

BaseForm[31415, 20]

podstawa 20


Cyfry dziesiętne odpowiadające powyższej podstawowej liczbie 20.

IntegerDigits[31415,20]

{3, 18, 10, 15}


Inny przykład

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]&za pomocą anonimowych funkcji.
jcai

@Arcinde, dzięki. Stare dobre anonimowe funkcje.
DavidC,

3

JavaScript (ES6), 157 bajtów

Nowe znaki są znaczące i są liczone jako 1 bajt. Ponieważ wymagane jest drukowanie do STDOUT, console.logkosztuje mnie tam kilka bajtów.

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

Próbny

Dla celów demonstracyjnych napiszę wersję ES5, która działa we wszystkich przeglądarkach:

// 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>


Czy ostatni .joinpotrzebuje nawiasu?
Downgoat


@vihan To nic nie wyświetla, po prostu zwraca.
rink.attendant. 6

nie wiedziałem, że to wymaganie, ponieważ dane wejściowe mogą być przekazywane przez funkcję. pastebin.com/0pS0XtJa jest 3 bajty krótszy
Downgoat

2

Python 2.x, 142 bajty:

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]

Przykład:

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

<  >

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

Edycja: linia końcowa ...


Mam kilka ulepszeń do zasugerowania. Najpierw zmień [n%20==0]na [n%20<1]. Po drugie, zmiana [[""," "*(2-n%5/2)+"."*(n%5)+"\n"][n%5!=0]do h=[(" "*(2-a/2)+"."*a+"\n")*(a>0)+"----\n"*(n%20/5),"< >\n"][n%20<1]z a=n%5, który porusza wszystkie n%5s, i zmienia warunkowy do *(a>0)którego zwraca pusty ciąg na a==0uzyskanie tego samego efektu.
Sherlock9,

Wreszcie, umieścić a, hi nna jednej linii, tak jak poniżej: a=n%5;h=[(" "*(2-a/2)+"."*a+"\n")*(a>0)+"----\n"*(n%20/5),"< >\n"][n%20<1];n/=20. Wszystko to powinno dać ci 131 bajtów.
Sherlock9,

2

CJam, 82 76 bajtów

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

Mój pierwszy program CJam, w zasadzie tylko transliteracja mojej odpowiedzi Perla na CJam.

Wypróbuj online

Wielowierszowy z komentarzami:

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 bajtów

Takie samo podejście jak moja odpowiedź JavaScript. PHP ma wbudowane funkcje do wszystkiego.

Pobiera 1 dane wejściowe z wiersza poleceń (tj. STDIN), jak widać przy $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

C - 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("<  >");}

Używa rekurencji, aby najpierw wydrukować najbardziej znaczące liczby. Następnie drukuje zero lub drukuje wszystkie kropki za pomocą jednego sprytnego printf i wszystkich piątki w pętli. Nie jestem pewien, czy mogę uniknąć używania if-else tutaj.

Minusem sprytnego printf jest to, że 1 i 3 nie są do siebie wyrównane:

Wynik dla 23 to:

  .

...

119 nieprawidłowe rozwiązanie - końcowy znak nowej linii

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 bajtów

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");

Pobiera dane wejściowe z pierwszego argumentu wiersza poleceń.

Pełny kod źródłowy wraz z komentarzami i testami jest dostępny na github .


\nma dwa znaki - ale nowa linia w środku ciągu to tylko jeden.
fisharebest

1

Python 2, 114 bajtów

Ta odpowiedź jest oparta na odpowiedzi Pythona Jakube'a i odpowiedzi Locoluis na Python 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

Galaretka , 50 49 47 bajtów

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

Wypróbuj online!

... jest teraz wyrównany do lewej dzięki punktowi user202729.

Kiedy oszukujesz się, myślenie < >jest palindromem ...


Dlaczego wyrównujesz do prawej ......
user202729

@ user202729 Dla .i ..musi być spacja, więc ja też postawiłem .... Czy istnieje krótsza droga?
dylnan

Myślę, że zgodnie z wyzwaniem specyfikacja ...nie powinna być wyrównana do prawej. Po prostu zmień <4na <3?
user202729,

@ user202729 Masz rację, myślę, że źle odczytałem specyfikację. Nie sądzę, żeby to określało ... ale mogę to zmienić na <2
dylnan
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.