バビロニアのように数える


41

チャレンジ

入力としてバビロニア番号のASCII表現が与えられた場合、西アラビア数字で番号を出力します。

バビロニア数字システム

バビロニア人はどのように数えましたか?興味深いことに、彼らはBase 10システムの要素を持つBase 60システムを使用しました。まず、システムの単位列について考えてみましょう。

バビロニア人には3つしかシンボルがありませんでした:(Tまたは、レンダリングできる場合:𒐕)1を表す<(または、レンダリングできる場合:𒌋)10を表す\(またはレンダリングする場合:)𒑊ゼロを表します。

注:技術的には、\(または𒑊)はゼロではありません(バビロニア人には「ゼロ」という概念がなかったため)。「ゼロ」は後で考案されたので\、あいまいさを防ぐために後で追加されたプレースホルダーシンボルでした。ただし、この課題の目的のためには\、ゼロと見なすだけで十分です。

そのため、各列では、シンボルの値を加算するだけです。例:

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

各列に5 <つ以上または9 つ以上あることはありませんT\列に常に単独で表示されます。

次に、列を追加するためにこれを拡張する必要があります。これはまさに、他のベース60と同じ働きどこを乗算することにより右端の列の値が、左に1、左に1のように。次に、それぞれの値を合計して、数値の値を取得します。60 1 60 2600601602

列は、あいまいさを防ぐためにスペースで区切られます。

いくつかの例:

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

ルール

  • ASCII入力(T<\)またはUnicode入力(𒐕𒌋𒑊)を自由に受け入れることができます
  • 入力した数値は常に未満です107
  • <sがいつもの左になりT、各列にS
  • \ 常に列に単独で表示されます

勝ち

バイト単位の最短コードが優先されます。


2
@TaylorScottはい、できます
Beta Decay

2
役立つ場合:処理する必要がある最大値は4列です<<<<TTTTTT <TTTTTTT <<<<TTTTTT <<<<
。–ヴェルニッヒ

1
列は常にそれぞれ1つのスペースで区切られていますか?私はそれに依存する答えに気づきます。
KRyan

4
水ギセルパイプを備えた外国のタイプは、「ああ、ホエー、ああ、ああ、ホエー」と言います-バビロニアのように数えます。すばらしいです。今、それは私の頭の中に詰まっています。
コバルトダック

5
"How did the Babylonians count? Interestingly, they used a Base 60 system with an element of a Base 10 system."現在も使用されています。バビロニアの数値システムは、まさに時計に使用するものです。秒、分、および時間のそれぞれに2桁の10進数、60秒から60分、60分から1時間。
レイ

回答:


39

JavaScript(ES6)、44バイト

入力をASCII文字の配列として受け取ります。

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

オンラインでお試しください!

どうやって?

バビロニア数字システムは、1つのレジスタで動作する4つの命令言語と見なすことができます。これをアキュムレータと呼びましょう。

から開始して、入力配列各文字は、アキュムレータを次のように変更します。c a kk=0cak

  • space:に掛けます(を追加して実装)60 59 k kk6059kk
  • <:にを追加k10k
  • T:インクリメントk
  • \: 何もしない; これはNOPこの言語の命令です(を追加して実装)k0k


11

Perl 6、39バイト

nwellnhofのおかげで-3バイト

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

オンラインでお試しください!

楔形文字を使用します。

説明:

{                                     }   # 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

あなたは数分で私を打ちました。ここに私が思いついたものがあり{:60[.words>>.&{sum (.ords X%151)X%27}]}ます:(40バイト)
-nwellnhof

@nwellnhofとてもよくできました!mod値をどのようにして見つけましたか?
ジョーキング

2
単に総当たりで。
-nwellnhof

11

ゼリー 13  12 バイト

ḲO%7C%13§ḅ60

整数を生成する文字のリストを受け入れる単項リンク。

オンラインでお試しください!

どうやって?

Ḳ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

別の12: ḲO⁽¡€%:5§ḅ60⁽¡€され1013、このモジュロよう1013によってOrdinal値を取得し535及び1ため<T\それぞれその後、分割整数実行:することにより5取得する1010


笑、私は私の答えを削除したまさに私がベースの変換を使用することができます覚えていますが、文字通りだったので、このためにあまりにも怠惰方法を見つけるために。+1
Mr. Xcoder

6

05AB1E、13バイト

8740|Ç%4/O60β

オンラインでお試しください!

私がゼリーの答えにどれだけ怠けていたのを補うために、05AB1E xDに投稿しました。


05AB1E-ersを助けてください、次のような数字を圧縮する方法はありませんでした8740か?
Mr Xcoder

2
codegolf.stackexchange.com/a/166851/52210残念ながら短くはなりません:•Yη•(4バイト)
ケビンクルーイッセン

2
@KevinCruijssenありがとうございます!答えは非常に有用であることを、私は完全に将来的にそれを使用します
ミスターXcoder

1
チップが役に立つことを嬉しく思います。:)私はそれらを使用していくつかの答えを見た後、これらのことを考え出しました。辞書部分はここで説明されました。そして、他の文字列や大きな整数の圧縮については、リンクされた例で「goose」246060に対する回答を見た後、自分自身を見つけました
ケビンCruijssen

1|Ç7%-13%O60β13でもある-それはゴルフ可能ですか?
ジョナサンアラン

6

パイソン296の 93 87 85バイト

lambda s:sum(60**i*sum(8740%ord(c)/4for c in v)for i,v in enumerate(s.split()[::-1]))

オンラインでお試しください!


保存済み:

  • -1バイト、Mr。Xcoderのおかげ
  • -4バイト、Poon Leviのおかげ
  • -2バイト、マシュージェンセンのおかげ

1
95:(ord(c)%5/2or 11)-1
Mr Xcoder

@ Mr.Xcoderありがとう:)
TFeld

2
87:8740%ord(c)/4
プーンレビ

-2 2番目のsum()の周りの括弧を削除して、オンラインで試してみてください!
マシュージェンセン

@MatthewJensenありがとう:)
TFeld

4

Excel VBA、121バイト

64ビットバージョンで型リテラルとして^機能する32ビットOfficeに制限LongLong

セルから入力A1を受け取り、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

非ゴルフとコメント

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 APL33 30バイト

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

オンラインでお試しください!

編集:ngnのおかげで-3バイト

'\ T<'⍳文字を数字(文字列定数内の位置)に置き換え、入力を逆にして、最上位の「数字」が最後になるようにします。これにより、スペース(文字列定数のインデックス2)が出現する回数をカウントすること+\2=により、60の望ましい累乗の実行カウント(で適用60*)を維持できます。

⌊10*⍵-3各キャラクターに10のべき乗を与えます。文字列定数内の文字の順序と-3オフセットにより、「\」とスペースが負の数になり、それらの文字が10の累乗になったときに小数になり、で削除できるようになります

今やらなければならないのは、10のべき乗の桁に60のべき乗の場所の値を掛けて、ロットを合計すること+/です。


別の比較を回避することによって、数バイトの保存' '{+/(⌊10*⍵-3)×60*+\2=⍵}'\ T<'⍳⌽
NGN



3

APL(NARS⎕io←0)、28文字、56バイト

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

型チェック付きのテスト:

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

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

各タイプの結果は数値です。


2

JavaScript(Node.js)122 114 107 106 83バイト

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

オンラインでお試しください!

私は、「関数型」配列操作に少し夢中になっていて、ASCII入力を使用しています。

私は後世のためにこれを維持していますが、これはナイーブ/ダムソリューションであり、私はあなたがチェックアウトをお勧めアルノーの答えはるかに挑戦の実装を興味深いです


@Shaggyは私にはうまくいくようです!
スキッドデフ

c<'T'代わりに動作しますc=='<'
Mr. Xcoder

に置き換えて&&、さらに1つ節約します|
シャギー

@Shaggy、for...ofループを使用してさらに節約:P
ASCIIのみ

2

網膜29 26 23バイト

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

オンラインでお試しください!改行区切りを使用しますが、リンクには便宜上ヘッダーを含めてスペースを使用します。編集:@KevinCruijssenの助けを借りて3バイトを保存しました。@FryAmTheEggmanのおかげでさらに3バイト節約できました。説明:

<
10*T

それぞれ<を10 T秒で置き換えます。

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

最初の行に60を掛けて、次の行を追加します。次に、1行だけになるまで繰り返します。

T

Tsを数えます。

より高速な51バイトバージョン:

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

オンラインでお試しください!改行区切りを使用しますが、リンクには便宜上ヘッダーを含めてスペースを使用します。説明:

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

各行を個別に一致させ、Ts の数と10倍の数を数えます<。これにより、各行がbase-60の「数字」値に変換されます。

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

Base 60変換。一度に1行ずつ実行します。計算は、速度のために10進数で行われます。


私はかなり3行目はちょうどことがことができると確信してい<なくて+、私はエッジケースのいくつかの種類が表示されません場合を除き、。
ケビンクルーッセン

1
@KevinCruijssenさらに良いことに、$&今では常に1文字なので、デフォルトの文字を使用して、さらに2バイト節約できます!
ニール

あ、いいね!:)単一の文字に対して暗黙のうちにそれができることを知りませんでした。
ケビンCruijssen

@KevinCruijssenまあ、私は長さだけを取っているので、キャラクターが何であるかは気にしません。Retina 1 では、Retinaの以前のバージョンでは_しばらく時間$*がかかり1ます。
ニール

ああ、分かった。あなたの最初のコードはすべて<単一のマッチとして取り、それらを10倍の長さ(<マッチの量)で繰り返し、私の提案された変更は<10回ごとに繰り返します(暗黙の1を使用してさらに2バイトゴルフしました)10*)。なぜ+最初にそこにあったのか、私はよく理解できました。Retinaビルトインについてはあまり知らず、一般的には正規表現だけです。したがって、提案された変更は、すでに>10回ごとに繰り返し読まれているためです。;)
ケビンクルーッセン

2

Bash(sedおよびdcを使用)、50バイト

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

からスペース区切りの入力を受け取りstdin、出力をstdout

オンラインでお試しください!

説明

sedを使用して、たとえば入力<<<TT \ TTTTがに変換されるまで、一連の正規表現一致で入力を変換しA+A+A+1+1+60*60*1+1+1+1+ます。次に、明示的な入力実行コマンドを使用して?、この入力をdcに送ります。前にz(スタックの長さ(0)をスタックにプッシュして、追加を接地する場所ができるようにします)、その後にp(印刷)を続けます。





1

、26バイト

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

オンラインでお試しください!リンクは、コードの詳細バージョンです。説明:

≔⁰θ

結果をクリアします。

FS«...»

入力文字をループします。コマンドは「デフォルト」のブロックを見つけることから、それを防ぐためにブロックに包まれています。

≡ι

現在のキャラクターを切り替える...

 ≦×⁶⁰θ

それがスペースの場合、結果に60を掛けます...

<≦⁺χθ

それはだ場合<、結果に10を追加します...

T≦⊕θ

の場合T、結果をインクリメントします。

Iθ

結果を印刷します。


1

R98 81バイト

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

オンラインでお試しください!

文字列の解析のために途方もなく長い。16個の不要なバイトを削り取ってくれたGiusppeに感謝します。

yUnicode入力のバイトコード値を定義し、R = y("T<\") = y("𒐕𒌋𒑊")

それを観察R%%3 = 1,2,0し、R%%6 = 1,5,0そう... R%%3 * R%%6 = 1,10,0

残りは簡単です。列ごとの合計、60の累乗の減少を伴う内積です。


Reduceを使用してArnauldのasnwerをポーティングすると、よりゴルフがしやすくなります。
JayCe

scan(,"")スペースで自動的に分割されませんか?
ジュゼッペ

1
ただし、MODを使用した素敵なトリックです!私はそれを把握しようとしていたが、それを見つけることができませんでした...と/60置き換えることができ-1、別のバイトオフのための指数表現で、プラス<-に置き換えることができ=、それは括弧内のすべてだから。
ジュゼッペ

@Giuseppe私は%% 3を試してみましたが、期待していましたので、探し続けました...また、ドット製品を使用して1バイト追加しました:)
JayCe

1

ルビー50 46バイト

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

オンラインでお試しください!

Arnauldの回答の基本ポートは、-4バイトでGB改善されました。



@GBのおかげで、おそらくより長いバージョンに固執するでしょう。なぜなら、入力を生のバイトコードとして受け取ることは、通常文字列をサポートする言語にとっては少し自由すぎると感じるからです。
キリルL.

1
:オフ別のバイト46バイト
GB


1

Java 8、64 60バイト

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

@ceilingcatのおかげで-4バイト。

オンラインでお試しください。 説明:

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バイト

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

これにより、STDINから変換される数値が読み取られます。

これは、JavaScriptを使用して@Arnauldが提供するものと同じソリューションに不可欠です。


0

F#、128バイト

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

オンラインでお試しください!

ゴルフを解かれると、次のようになります。

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と結合Seq.mapSeq.foldBackます。Seq.mapFoldBackシーケンスを逆方向に反復し、シーケンス(この場合はi)でアキュムレータ値をスレッド化します。

シーケンス内の各要素について、バビロニアの数値が計算され(Seq.sumBy各文字を数値にマッピングし、結果を合計する)、その後で乗算されiます。iその後、60が乗算され、この値はシーケンス内の次のアイテムに渡されます。アキュムレーターの初期状態は1です。

たとえばSeq.mapFoldBack、入力の呼び出しと結果の順序は次のようになり<<<TT \ TTTTます。

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

関数はのタプルを返しseq<int>, intます。fst関数は、そのタプルの最初の項目を返し、Seq.sum実際の加算を行います。

なぜ使用Seq.mapiまたは類似しないのですか?

Seq.mapiシーケンス内の各要素をマッピングし、マッピング関数にインデックスを提供します。そこからできます60 ** index**F#のパワーオペレータはどこですか)。

しかし、**必要でfloatsはなく、intsあなたはどちらか初期化する必要があるか、などの機能のすべての値をキャストすることを意味し、float。関数全体がを返しますがfloat、これは(私の意見では)少し厄介です。

139バイトの場合、次のSeq.mapiように使用できます

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バイト

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}

オンラインでお試しください!

逆一覧で、Iループは、カウントに結果をインクリメント<し、T(と-all正規表現オプション)及び60の電源として自然をインクリメントします。

正しいバージョン(コメントを参照)


理由は、\最後の数に...私が持っていなければならないのは、私はこの1つを失敗したようだregsub {\\} $l0 l.... foreachループの前に
デヴィッド・

0

APL(Dyalog Extended)、18 バイトSBCS

匿名の暗黙の接頭辞関数。

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

オンラインでお試しください!

                  ⊢  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(レガシー)、10バイト

#Ç9%5BO60β

オンラインでお試しください!

#               # 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バイト

#Ç9%5B€O60β

オンラインでお試しください!

同じアルゴリズムですが、現代の05AB1E Oでは、intとリストが混在したリストでは機能しないため、€O代わりに必要になります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.