Policz jak babilończyk


41

Wyzwanie

Biorąc pod uwagę reprezentację ASCII liczby babilońskiej jako danych wejściowych, wypisz liczbę cyframi zachodnioafrykańskimi.

Babiloński system liczbowy

Jak liczą się Babilończycy? Co ciekawe, zastosowali system Base 60 z elementem systemu Base 10. Rozważmy najpierw kolumnę jednostki w systemie:

Babilończycy mieli tylko trzy symbole: T(lub, jeśli potrafisz to wyrenderować:), 𒐕które reprezentowały 1, i <(lub, jeśli możesz to renderować:), 𒌋które reprezentowały 10, i \(lub, jeśli renderujesz:), 𒑊które reprezentowały zero.

Uwaga: Technicznie \(lub 𒑊) nie jest zerowy (ponieważ Babilończycy nie mieli pojęcia „zero”). „Zero” zostało wynalezione później, podobnie \jak symbol zastępczy dodano później, aby zapobiec dwuznaczności. Jednak do celów tego wyzwania wystarczy uznać \za zero

Tak więc w każdej kolumnie dodajesz tylko wartość symboli, np .:

<<< = 30
<<<<TTTTTT = 46
TTTTTTTTT = 9
\ = 0

W każdej kolumnie nigdy nie będzie więcej niż pięć <lub więcej niż dziewięć T. \zawsze pojawi się sam w kolumnie.

Teraz musimy rozszerzyć to na dodawanie kolejnych kolumn. Działa to dokładnie tak samo, jak każda inna podstawa sześćdziesiąt, gdzie mnożymy wartość skrajnej prawej kolumny przez , tej po lewej przez , tej po lewej przez i tak dalej. Następnie dodajesz wartość każdego z nich, aby uzyskać wartość liczby.60 1 60 2600601602

Kolumny zostaną oddzielone spacjami, aby zapobiec dwuznaczności.

Kilka przykładów:

<< <TT = 20*60 + 12*1 = 1212
<<<TT \ TTTT = 32*60^2 + 0*60 + 4*1 = 115204

Zasady

  • Możesz zaakceptować wejście ASCII ( T<\) lub wejście Unicode ( 𒐕𒌋𒑊)
  • Wprowadzona liczba zawsze będzie mniejsza niż107
  • <Y zawsze będzie w lewą stronę z TS w każdej kolumnie
  • \ zawsze pojawi się sam w kolumnie

Zwycięski

Najkrótszy kod w bajtach wygrywa.


2
@TaylorScott Tak, możesz
Beta Decay

2
W przypadku, gdy to pomaga: Maks., Które należy obsłużyć, to 4 kolumny:<<<<TTTTTT <TTTTTTT <<<<TTTTTT <<<<
Wernisch,

1
Czy kolumny są zawsze oddzielone dokładnie jedną spacją ? Zauważam, że odpowiedzi na tym polegają.
KRyan

4
Obce typy z fajkami mówią: Ach, och, och, och, och, och - och, licz się jak Babilończyk. Wspaniały. Teraz utknęło mi w głowie.
cobaltduck

5
"How did the Babylonians count? Interestingly, they used a Base 60 system with an element of a Base 10 system."Który jest nadal w użyciu; babiloński system liczbowy jest dokładnie tym, czego używamy do zegarów. Dwie cyfry dziesiętne każda na sekundę, minutę i godzinę, 60 sekund na minutę, 60 minut na godzinę.
Ray

Odpowiedzi:


39

JavaScript (ES6), 44 bajty

Pobiera dane wejściowe jako tablicę znaków ASCII.

a=>a.map(c=>k+=c<1?k*59:c<'?'?10:c<{},k=0)|k

Wypróbuj online!

W jaki sposób?

Babiloński system liczbowy może być postrzegany jako język 4-instrukcji współpracujący z jednym rejestrem - nazwijmy go akumulatorem.

Począwszy od , każdy znak tablicy wejściowej modyfikuje akumulator w następujący sposób:c a kk=0cak

  • space: pomnóż przez (zaimplementowane jako: dodaj do )60 59 k kk6059kk
  • <: dodaj dotys10k
  • T: przyrostk
  • \: nic nie robić; to jest NOPinstrukcja tego języka (zaimplementowana jako: dodaj do )tys0k


11

Perl 6 , 39 bajtów

-3 bajty dzięki nwellnhof

{:60[.words>>.&{sum .ords X%151 X%27}]}

Wypróbuj online!

Wykorzystuje znaki klinowe.

Wyjaśnienie:

{                                     }   # Anonymous code block
     .words  # Split input on spaces
           >>.&{                    }  # Convert each value to
                sum   # The sum of:
                    .ords # The codepoints
                          X%151 X%27   # Converted to 0,1 and 10 through modulo
 :60[                                ]  # Convert the list of values to base 60

Pokonałeś mnie o kilka minut. Oto, co wymyśliłem: {:60[.words>>.&{sum (.ords X%151)X%27}]}(40 bajtów)
nwellnhof,

@nwellnhof Bardzo dobra robota! Jak znalazłeś wartości modów?
Jo King,

2
Po prostu brutalną siłą.
nwellnhof,

11

Galaretka ,  13  12 bajtów

ḲO%7C%13§ḅ60

Monadyczny link akceptujący listę znaków, który daje liczbę całkowitą.

Wypróbuj online!

W jaki sposób?

ḲO%7C%13§ḅ60 - Link: list of characters   e.g. "<<<TT \ TTTT"
Ḳ            - split at spaces                 ["<<<TT", "\", "TTTT"]
 O           - cast to ordinals                [[60,60,60,84,84],[92],[84,84,84,84]]
  %7         - modulo by seven (vectorises)    [[4,4,4,0,0],[1],[0,0,0,0]]
    C        - compliment (1-X)                [[-3,-3,-3,1,1],[0],[1,1,1,1]]
     %13     - modulo by thirteen              [[10,10,10,1,1],[0],[1,1,1,1]]
        §    - sum each                        [32,0,4]
         ḅ60 - convert from base sixty         115204

Kolejne 12: ḲO⁽¡€%:5§ḅ60( ⁽¡€jest 1013, więc modulos 1013przez The Owartości rdinal się 53, 5i 1na <, T, \odpowiednio, po czym przeprowadza całkowitą podziału :przez 5uzyskać 10, 1i 0)


Lol, właśnie dlatego usunąłem swoją odpowiedź , ponieważ przypomniałem sobie, że mogę użyć konwersji bazowej, ale dosłownie byłem zbyt leniwy, aby dowiedzieć się, jak to zrobić. +1
Mr. Xcoder,

6

05AB1E , 13 bajtów

8740|Ç%4/O60β

Wypróbuj online!

Aby zrekompensować lenistwo związane z moją odpowiedzią na żelki, oto zgłoszenie w 05AB1E xD.


Pomóżcie 05AB1E-tam, czy nie było sposobu na kompresowanie liczb takich jak 8740?
Pan Xcoder,

2
codegolf.stackexchange.com/a/166851/52210 Niestety nie byłby krótszy: •Yη•(4 bajty)
Kevin Cruijssen

2
@KevinCruijssen Dziękujemy! Ta odpowiedź jest bardzo przydatna, całkowicie ją wykorzystam w przyszłości
Mr. Xcoder,

1
Cieszę się, że końcówka jest przydatna. :) Zrozumiałem te rzeczy po tym, jak zobaczyłem odpowiedzi, które ich używały. Słownik został tutaj wyjaśniony . I kompresję innych ciągów znaków lub dużych liczb całkowitych wymyśliłem sam po obejrzeniu połączonego przykładu odpowiedzi na „gęś” i 246060 .
Kevin Cruijssen

1|Ç7%-13%O60βma również 13 lat - czy można grać w golfa?
Jonathan Allan,


4

Excel VBA, 121 bajtów

Ograniczony do 32-bitowego pakietu Office, ponieważ ^służy jako LongLongliterał typu w wersjach 64-bitowych

Pobiera dane wejściowe z komórki A1i dane wyjściowe do bezpośredniego okna vbe.

a=Split([A1]):u=UBound(a):For i=0 To u:v=a(i):j=InStrRev(v,"<"):s=s+(j*10-(InStr(1,v,"T")>0)*(Len(v)-j))*60^(u-i):Next:?s

Niegolfowany i komentowany

a=Split([A1])       '' Split input into array
u=UBound(a)         '' Get length of array
For i=0 To u        '' Iter from 0 to length
v=a(i)              '' Get i'th column of input
j=InStrRev(v,"<")   '' Get count of <'s in input
                    '' Multiply count of <'s by 10; check for any T's, if present
                    ''   add count of T's
t=t+(j*10-(InStr(1,v,"T")>0)*(Len(v)-j))
    *60^(u-i)       '' Multiply by base
Next                '' Loop
?s                  '' Output to the VBE immediate window

4

Dyalog APL , 33 30 bajtów

{+/(⌊10*⍵-360*+\2=⍵}'\ T<'⍳⌽

Wypróbuj online!

Edycja: -3 bajty dzięki ngn

'\ T<'⍳zastępuje znaki cyframi (ich pozycja w stałej ciągu) i odwraca dane wejściowe, aby najbardziej znaczące „cyfry” były ostatnie. Pozwala +\2=to zachować bieżącą liczbę pożądanej mocy 60 (zastosowaną przez 60*) poprzez zliczenie liczby napotkanych spacji (indeks 2 w stałej ciągu).

⌊10*⍵-3daje pożądaną moc dziesięciu dla każdej postaci. Kolejność znaków w stałej łańcucha i przesunięcie -3 powodują, że „\” i spacja przechodzą do liczb ujemnych, co powoduje ułamki, gdy znaki te są podnoszone do potęgi 10, co pozwala na ich wyeliminowanie .

Wszystko, co musimy teraz zrobić, to pomnożyć cyfry potęgi-10 przez wartości potęgi -60-miejsca i zsumować los +/.


zaoszczędź kilka bajtów, unikając osobnego porównania z ' ':{+/(⌊10*⍵-3)×60*+\2=⍵}'\ T<'⍳⌽
ngn


3

Płótno , 20 17 16 bajtów

S{{<≡AײT≡]∑]<c┴

Wypróbuj tutaj!

Wyjaśnienie:

E{          ]     map over input split on spaces
  {       ]         map over the characters
   <≡A×               (x=="<") * 10
       ²T≡            x=="T"
           ∑        sum all of the results
             <c┴  and encode from base (codepoint of "<") to 10

3

APL (NARS ⎕io ← 0), 28 znaków, 56 bajtów

{60⊥{+/⍵⍳⍨10⍴'\T'}¨⍵⊂⍨⍵≠' '}

niektóre testy z kontrolą typu:

  q←{60⊥{+/⍵⍳⍨10⍴'\T'}¨⍵⊂⍨⍵≠' '}

  o←⎕fmt
  o q '<< <TT'
1212
~~~~
  o q '<<<TT \ TTTT'
115204
~~~~~~

Wynik każdego typu jest liczbą.


2

JavaScript (Node.js) , 122 114 107 106 83 bajtów

a=>a.split` `.map(b=>[...b].map(c=>x+=c<'T'?10:c<'U',x=0)&&x).reduce((a,b)=>a*60+b)

Wypróbuj online!

Mam obsesję na punkcie operacji tablicowych w „funkcjonalnym stylu”, używam danych ASCII, o ile mogę stwierdzić, JS nie jest zbyt dobry w golfowym uzyskiwaniu znaków

Trzymam to ze względu na potomstwo, ale jest to naiwne / głupie rozwiązanie, proponuję sprawdzić odpowiedź Arnaulda, która jest znacznie bardziej interesująca w realizacji wyzwania


@Shaggy wygląda na to, że mi to działa!
Skidsdev,

c<'T'pracuje zamiastc=='<'
Mr. Xcoder,

Zapisz 1 więcej zastępując &&z |.
Shaggy

@ Shaggy i oszczędzaj dużo więcej, używając for...ofpętli: P
tylko ASCII,

2

Retina , 29 26 23 bajtów

<
10*T
+`^(.*)¶
60*$1
T

Wypróbuj online! Używa separacji nowego wiersza, ale link zawiera nagłówek, aby zamiast tego używać spacji dla wygody. Edycja: Zapisano 3 bajty przy pomocy @KevinCruijssen. Zaoszczędź kolejne 3 bajty dzięki @FryAmTheEggman. Wyjaśnienie:

<
10*T

Zastąp każdy <z 10 Ts.

+`^(.*)¶
60*$1

Weź pierwszą linię, pomnóż ją przez 60 i dodaj następną linię. Następnie powtarzaj, aż pozostanie tylko jedna linia.

T

Policz Ts.

Szybsza wersja 51-bajtowa:

%`^(<*)(T*).*
$.(10*$1$2
+`^(.+)¶(.+)
$.($1*60*_$2*

Wypróbuj online! Używa separacji nowego wiersza, ale link zawiera nagłówek, aby zamiast tego używać spacji dla wygody. Wyjaśnienie:

%`^(<*)(T*).*
$.(10*$1$2

Dopasuj każdą linię osobno i policz liczbę Ts oraz 10-krotność liczby <s. Konwertuje to każdy wiersz na jego podstawową wartość „cyfrową” 60.

+`^(.+)¶(.+)
$.($1*60*_$2*

Konwersja bazy 60, prowadzenie linii na raz. Obliczenia dokonywane są dziesiętnie dla prędkości.


Jestem prawie pewien, że trzecia linia może być po prostu <bez +, chyba że nie widzę żadnego przypadku krawędzi.
Kevin Cruijssen

1
@KevinCruijssen Jeszcze lepiej, ponieważ $&teraz jest zawsze jeden znak, mogę użyć znaku domyślnego, oszczędzając kolejne dwa bajty!
Neil,

Ach miło! :) Nie wiedziałem, że można to zrobić niejawnie dla pojedynczych znaków.
Kevin Cruijssen

@KevinCruijssen Cóż, nie dbam o to, jaka jest postać, ponieważ biorę tylko długość; w Retina 1 masz trochę _czasu $*we wcześniejszych wersjach Retina domyślnie na 1.
Neil,

O, rozumiem. Twój początkowy kod przyjmował wszystko <jako pojedynczy mecz i powtarzał je 10 razy długość (ilość <w meczu), a moja proponowana zmiana powtarza się <osobno 10 razy (co grałeś w golfa o 2 bajty więcej, używając domyślnego 1 z 10*). Teraz lepiej rozumiem, dlaczego to +było na początku. Nie wiem zbyt wiele o wbudowanych Retina, tylko regexy w ogóle, stąd moja proponowana zmiana, ponieważ czytam już to jako powtarzanie co >10 razy. ;)
Kevin Cruijssen

2

Bash (z sed i dc), 50 bajtów

sed 's/</A+/g
s/T/1+/g
s/ /60*/g
s/\\//g'|dc -ez?p

Pobiera rozdzielone spacjami dane wejściowe stdin, dane wyjściowe dostdout

Wypróbuj online!

Wyjaśnienie

Używa sed do transformacji danych wejściowych za pomocą szeregu dopasowań wyrażeń regularnych, dopóki na przykład dane wejściowe <<<TT \ TTTTnie zostaną przekształcone A+A+A+1+1+60*60*1+1+1+1+. Następnie dane wejściowe są podawane do dc za pomocą jawnego polecenia wykonania danych wejściowych ?, poprzedzone z(wypycha długość stosu (0) do stosu, abyśmy mieli miejsce na uziemienie dodatku), a następnie p(drukuj).





1

Węgiel drzewny , 26 bajtów

≔⁰θFS«≡ι ≦×⁶⁰θ<≦⁺χθT≦⊕θ»Iθ

Wypróbuj online! Link jest do pełnej wersji kodu. Wyjaśnienie:

≔⁰θ

Wyczyść wynik.

FS«...»

Pętla nad znakami wejściowymi. Komenda jest owinięty w bloku, aby zapobiec jej znalezieniu „domyślny” blok.

≡ι

Przełącz obecną postać ...

 ≦×⁶⁰θ

jeśli jest to spacja, pomnóż wynik przez 60 ...

<≦⁺χθ

jeśli to <a, dodaj 10 do wyniku ...

T≦⊕θ

jeśli jest Tto przyrost wyniku.

Iθ

Wydrukuj wynik.


1

R , 98 81 bajtów

(u=sapply(scan(,""),function(x,y=utf8ToInt(x))y%%3%*%(y%%6)))%*%60^(sum(u|1):1-1)

Wypróbuj online!

Śmiesznie długi z powodu parsowania łańcucha. Dzięki Giusppe za zgolenie 16 niepotrzebnych bajtów.

Zdefiniuj ywartość kodu bajtowego wejścia Unicode iR = y("T<\") = y("𒐕𒌋𒑊")

Obserwuj to R%%3 = 1,2,0i R%%6 = 1,5,0... tak R%%3 * R%%6 = 1,10,0!

Reszta jest łatwa: suma na kolumnę, a następnie iloczyn iloczynu o malejących mocach 60.


Przeniesienie odpowiedzi Arnaulda za pomocą Reduce prawdopodobnie będzie bardziej golfowe.
JayCe,

nie scan(,"")dzieli się automatycznie na spacje?
Giuseppe,

1
fajna sztuczka z modami! Próbowałem to rozgryźć, ale nie mogłem tego znaleźć ... i /60można je zastąpić -1wyrażeniem wykładniczym dla kolejnego bajtu, a dodatkowo <-można je zastąpić, =ponieważ wszystko jest w nawiasach.
Giuseppe,

@Giuseppe Próbowałem %% 3 i było obiecująco, więc szukałem ... również użycie produktu kropkowego właśnie uratowało mi jeden dodatkowy bajt :)
JayCe

1

Rubinowy , 50 46 bajtów

->a{x=0;a.bytes{|c|x+=[59*x,10,0,1][c%9%5]};x}

Wypróbuj online!

Podstawowy port odpowiedzi Arnaulda poprawiony o GB dla -4 bajtów.


1
45 bajtów - w rzeczywistości 47, jeśli użyjesz „bajtów” zamiast „mapy”
GB,

Dzięki @GB, prawdopodobnie pozostanę przy dłuższej wersji, ponieważ przyjmowanie danych wejściowych jako surowych kodów bajtowych wydaje się nieco zbyt liberalne dla języka, który normalnie obsługuje łańcuchy.
Kirill L.,

1
Kolejny bajt wyłączony: 46 bajtów
GB


1

Java 8, 64 60 bajtów

a->{int r=0;for(int c:a)r+=c<33?r*59:c<63?10:84/c;return r;}

-4 bajty dzięki @ceilingcat .

Wypróbuj online. Wyjaśnienie:

a->{            // Method with character-array parameter and integer return-type
  int r=0;      //  Result-integer, starting at 0
  for(int c:a)  //  Loop over each character `c` of the input-array
    r+=         //   Increase the result by:
       c<33?    //    Is the current character `c` a space:
        r*59    //     Increase it by 59 times itself
       :c<63?   //    Else-if it's a '<':
        10      //     Increase it by 10
       :c<85?   //    Else (it's a 'T' or '\'):
        84/c;   //     Increase it by 84 integer-divided by `c`,
                //     (which is 1 for 'T' and 0 for '\')
  return r;}    //  Return the result

0

Perl -F // -E, 39 bajtów

$w+=/</?10:/T/?1:/ /?59*$w:0for@F;say$w

Odczytuje liczbę do konwersji z STDIN.

Jest to niezbędne to samo rozwiązanie, co podane przez @Arnauld przy użyciu JavaScript.


0

F #, 128 bajtów

let s(v:string)=Seq.mapFoldBack(fun r i->i*Seq.sumBy(fun c->match c with|'<'->10|'T'->1|_->0)r,i*60)(v.Split ' ')1|>fst|>Seq.sum

Wypróbuj online!

Bez golfa wyglądałoby to tak:

let s (v:string) =
    Seq.mapFoldBack(fun r i ->
        i * Seq.sumBy(fun c ->
            match c with
                | '<' -> 10
                | 'T' ->1
                | _ -> 0
        ) r, 
        i * 60) (v.Split ' ') 1
    |> fst
    |> Seq.sum

Seq.mapFoldBackłączy Seq.mapi Seq.foldBack. Seq.mapFoldBackiteruje sekwencję do tyłu i przerzuca wartość akumulatora przez sekwencję (w tym przypadku, i).

Dla każdego elementu w sekwencji liczba babilońska jest obliczana (przez Seq.sumBy, która odwzorowuje każdy znak na liczbę i sumuje wynik), a następnie mnożona przez i. ijest następnie mnożony przez 60, a ta wartość jest następnie przekazywana do następnego elementu w sekwencji. Stan początkowy akumulatora wynosi 1.

Na przykład kolejność wywołań i wyników Seq.mapFoldBackdla wprowadzania <<<TT \ TTTTbyłaby następująca:

(TTTT, 1)     -> (4, 60)
(\, 60)       -> (0, 3600)
(<<<TT, 3600) -> (115200, 216000)

Funkcja zwróci krotkę seq<int>, int. fstZwraca pierwszy element w tej krotki, a Seq.sumnie rzeczywistą sumowanie.

Dlaczego nie użyć Seq.mapilub podobnego?

Seq.mapimapuje każdy element w sekwencji i zapewnia indeks funkcji mapowania. Stamtąd możesz zrobić 60 ** index(gdzie **jest operator mocy w F #).

**Wymaga jednak floatsnie ints, co oznacza, że ​​musisz zainicjować lub rzutować wszystkie wartości w funkcji as float. Cała funkcja zwróci a float, co (moim zdaniem) jest trochę niechlujne.

Korzystanie Seq.mapimożna to zrobić w ten sposób do 139 bajtów :

let f(v:string)=v.Split ' '|>Seq.rev|>Seq.mapi(fun i r->Seq.sumBy(fun c->match c with|'<'->10.0|'T'->1.0|_->0.0)r*(60.0**float i))|>Seq.sum

0

Tcl , 134 bajty

proc B l {regsub {\\} $l 0 l
lmap c [lreverse $l] {incr s [expr 60**([incr i]-1)*([regexp -all < $c]*10+[regexp -all T $c])]}
expr $s}

Wypróbuj online!

Na odwróconej liście zapętlam inkrementując wynik liczenia <i T(z -allopcją regexp) i inkrementując naturalną moc 60.

Prawidłowa wersja (patrz komentarz)


Wygląda na to, że zawiodłem ten, ponieważ \ w ostatnim numerze ... powinienem mieć regsub {\\} $l0 lpętlę przed foreach ....
David

0

APL (Dyalog Extended) , 18 bajtów SBCS

Anonimowa ukryta funkcja prefiksu.

60⊥10⊥¨≠'<T'∘⍧¨⍤⊆⊢

Wypróbuj online!

                  ⊢  the argument; "<<<TT \ TTTT"
       ≠             mask where different from space; [1,1,1,1,1,0,1,0,1,1,1,1]
                ⊆    enclose runs of 1; ["<<<TT","\","TTTT"]
               ⍤     on that
              ¨      for each one
             ⍧       Count the occurrences In it of the elements
            ∘        of the entire list
        '<T'         ["<","T"]; [[3,2],[0,0],[0,4]]
      ¨              for each one
   10⊥               evaluate as base-10 digits
60⊥                  evaluate as base-60 digits

0

05AB1E (starsza wersja) , 10 bajtów

#Ç9%5BO60β

Wypróbuj online!

#               # split input on spaces
 Ç              # convert each character to its codepoint
  9%            # modulo 9 (maps 𒌋 to 5, 𒐕 to 1, 𒑊 to 0)
    5B          # convert each to base 5 (5 becomes 10, 0 and 1 unchanged)
      O         # sum each column
       60β      # convert from base 60

05AB1E , 11 bajtów

#Ç9%5B€O60β

Wypróbuj online!

Ten sam algorytm, ale we współczesnym 05AB1E Onie działa na listach mieszanych int i list, więc potrzebujemy €Ozamiast tego.

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.