바빌로니아처럼 센다


41

도전

입력으로 바빌로니아 숫자를 ASCII로 표시하면 숫자를 서부 아라비아 숫자로 출력하십시오.

바빌로니아 숫자 체계

바빌론 사람들은 어떻게 계산 했습니까? 흥미롭게도 그들은 Base 10 시스템의 요소가있는 Base 60 시스템을 사용했습니다. 먼저 시스템의 단위 열을 고려해 봅시다 :

: 바벨론은 세 가지 상징을했다 T: (당신이 그것을 렌더링 할 수있는 경우, 또는 𒐕1을 표현하고있는) <: (또는, 당신이 그것을 렌더링 할 수있는 경우 𒌋(10)를 표현하고 있음) \(당신이 그것을 렌더링하는 경우, 또는 : 𒑊)는 0을 표현한다.

참고 : 기술적으로 \(또는 𒑊)는 0이 아닙니다 (바빌론 사람들은 '0'이라는 개념을 가지지 않았기 때문에). '제로'는 나중에 발명되었으므로 \모호성을 방지하기 위해 나중에 자리 표시 자 기호가 추가되었습니다. 그러나이 과제의 목적을 위해 \0 으로 간주 하면 충분 합니다.

따라서 각 열에 기호 값을 더하면 다음과 같습니다.

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

각 열에 는 5 개 <또는 9 개가 넘지 않습니다 T. \열에 항상 혼자 표시됩니다.

이제 더 많은 열을 추가하도록 확장해야합니다. 이것은 가장 오른쪽 열의 값에 , 왼쪽에 60 1 , 왼쪽에 60 2 등 을 곱하는 다른 기본 60과 동일하게 작동합니다 . 그런 다음 각 값을 더하여 숫자 값을 얻습니다.600601602

모호성을 방지하기 위해 열은 공백으로 구분됩니다.

몇 가지 예 :

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

규칙

  • ASCII 입력 ( T<\) 또는 유니 코드 입력 ( 𒐕𒌋𒑊)을 자유롭게 사용할 수 있습니다.
  • 입력 한 숫자는 항상 10 7 미만입니다107
  • <들 항상의 왼쪽에있을 것입니다 T각 열에의
  • \ 항상 열에 혼자 나타납니다

승리

바이트 단위의 최단 코드가 이깁니다.


2
@TaylorScott 네, 가능합니다
Beta Decay

2
도움이되는 경우 : 처리해야하는 최대 값은 4 개의 열입니다.<<<<TTTTTT <TTTTTTT <<<<TTTTTT <<<<
Wernisch

1
열은 항상 정확히 하나의 공백으로 구분 됩니까? 나는 그것에 의존하는 대답을 발견합니다.
KRyan

4
물 담뱃대 파이프가있는 외국 유형은 Ay oh whey oh, ay oh whey oh라고 말합니다-바빌로니아처럼 계산하십시오. 큰. 이제 내 머리에 붙어 있습니다.
cobaltduck

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 분에서 시간.
Ray

답변:


39

자바 스크립트 (ES6), 44 바이트

ASCII 문자 배열로 입력을받습니다.

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

온라인으로 사용해보십시오!

어떻게?

바빌로니아 숫자 체계는 단일 레지스터로 작동하는 4 명령어 언어로 볼 수 있습니다. 이것을 누산기라고합시다.

시작 하여 입력 배열 a 의 각 문자 c 는 다음과 같이 누산기 k 를 수정합니다 .케이=0에이케이

  • space: 곱하기 에 의해 60 (: 추가로 구현 59 K 에 대한 K를 )케이6059케이케이
  • <: k더하다10케이
  • T: 증분 케이
  • \: 아무것도하지 마세요; 이것은 NOP이 언어 의 지시 사항입니다 : ( k를 추가 하여 구현 )0케이


11

펄 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}]}
해낸 것들이있다

@nwellnhof 아주 잘 했어요! 모드 값을 어떻게 찾았습니까?
조 왕

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이 modulos 있도록 1013바이 Ordinal 값을 얻고 53, 5그리고 1<, T, \는 각각 다음을 수행 분할 정수 :의해 5얻을 10, 10)


롤, 나는 이것 때문에 내 대답을 정확하게 삭제 했습니다. 왜냐하면 나는 기본 변환을 사용할 수 있다는 것을 기억했지만 말 그대로 너무 게으르다 . +1
Mr. Xcoder

6

05AB1E , 13 바이트

8740|Ç%4/O60β

온라인으로 사용해보십시오!

제 젤리 답변 에 얼마나 게으른 지 보충하기 위해 05AB1E xD에 제출했습니다.


05AB1E를 도와주세요. 같은 숫자를 압축하는 방법이 없었 8740습니까?
Mr. Xcoder

2
codegolf.stackexchange.com/a/166851/52210 불행히도 짧지 않을 것입니다 : •Yη•(4 바이트)
Kevin Cruijssen

2
@KevinCruijssen 감사합니다! 그 답변은 매우 유용합니다. 앞으로 완전히 사용할 것입니다.
Mr. Xcoder

1
팁이 사용되어 다행입니다. :) 나는 그것들을 사용하여 몇 가지 대답을 본 후에 이것들을 알아 냈습니다. 사전 부분은 여기 에 설명되어 있습니다 . 그리고 다른 문자열이나 큰 정수의 압축은 링크 된 예제가 "goose"246060에 대한 답변을보고 나서 스스로 알아 냈습니다 .
Kevin Cruijssen

1|Ç7%-13%O60β13도-골프를 할 수 있습니까?
Jonathan Allan

6

파이썬 2 , 96 93 87 85 바이트

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

온라인으로 사용해보십시오!


저장 됨 :

  • Mr. Xcoder 덕분에 -1 바이트
  • Poon Levi 덕분에 -4 바이트
  • Matthew Jensen 덕분에 -2 바이트

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

@ Mr.Xcoder 감사 :)
TFeld

2
87 :8740%ord(c)/4
풍 레비

-2 두 번째 sum () 주위의 괄호를 제거하여 온라인으로 사용해보십시오!
Matthew Jensen

@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

Ungolfed 및 댓글 달기

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 바이트

{+/(⌊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

자바 스크립트 (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)

온라인으로 사용해보십시오!

나는 "function-style"배열 연산에 약간 집착하고 ASCII 입력을 사용한다. JS는 골프를 잘하는 데 능숙하지 않다.

나는 후손을 위해 이것을 유지하고 있지만 이것은 순진 / 바보 솔루션입니다. 아르 날드의 대답 을 확인하는 것이 좋습니다.이 도전은 훨씬 더 도전적인 구현입니다.


@Shaggy는 나에게 효과가있는 것처럼 보입니다!
Skidsdev

c<'T'대신에 작동c=='<'
Mr. Xcoder

로 교체 &&하여 1을 더 절약하십시오 |.
Shaggy

@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을 곱한 후 다음 줄을 추가하십시오. 그런 다음 한 줄만 남을 때까지 반복하십시오.

T

계산 Ts를 .

빠른 51 바이트 버전 :

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

온라인으로 사용해보십시오! 줄 바꿈 구분을 사용하지만 링크에는 편의를 위해 공백을 사용하는 헤더가 포함되어 있습니다. 설명:

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

각 줄을 개별적으로 일치시키고 Ts 수와 s 수의 10 배를 계산하십시오 <. 이것은 각 줄을 기본 60 "숫자"값으로 변환합니다.

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

한 번에 한 줄씩 실행되는 기본 60 변환. 속도는 10 진수로 계산됩니다.


나는 꽤 세 번째 줄은 단지 수 있습니다 확신 <를 빼고 +난 가장자리 경우 어떤 종류의 보이지 않아요하지 않는 한,.
Kevin Cruijssen

1
@KevinCruijssen 더 나은 $&지금은 항상 한 문자이므로 기본 문자를 사용하여 2 바이트를 더 절약 할 수 있습니다!
Neil

아 좋아! :) 단일 문자에 대해 암시 적으로 수행 될 수 있다는 것을 몰랐습니다.
Kevin Cruijssen

@KevinCruijssen 글쎄, 나는 길이 만 가지고 있기 때문에 캐릭터가 무엇인지 상관하지 않습니다. 망막 일에 당신은 얻을 _반면 $*에 망막의 기본값은 이전 버전을 1.
Neil

아, 알겠습니다 초기 코드는 모두 <단일 일치 로 가져 와서 길이의 10 배 ( <일치 하는 양 )를 반복하고 제안 된 변경 사항은 <10 회 마다 반복됩니다 (암시 적 1을 사용하여 2 바이트 더 골프를 쳤습니다) 10*). 이제는 왜 +처음에 있었 는지 더 잘 이해합니다 . 나는 Retina 내장에 대해 너무 많이 알지 못하고 일반적으로 정규 표현식 만 사용합니다. 따라서 이미 제안 된 변경 사항을 이미 >10 번 반복하여 읽었 기 때문에 제안 된 변경 사항 입니다. ;)
Kevin Cruijssen

2

배쉬 (sed 및 dc 포함), 50 바이트

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

에서 공백으로 구분 된 입력을 받아 stdin출력stdout

온라인으로 사용해보십시오!

설명

예를 들어 입력 <<<TT \ TTTT이로 변환 될 때까지 sed를 사용하여 정규 표현식 일치로 입력 을 변환합니다 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

R , 98 81 바이트

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

온라인으로 사용해보십시오!

문자열 파싱으로 인해 엄청나게 길다. 불필요한 16 바이트를 제거해 준 Giusppe에게 감사드립니다.

밝히다 y유니 코드 입력의 바이트 코드 값을 하고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
그래도 개조와 좋은 트릭! 나는 알아 내려고했지만 그것을 찾을 수 없습니다 ... 그리고 /60교체 할 수 있습니다 -1떨어져 다른 바이트 지수 발현 플러스는 <-교체 할 수 =는 괄호 안에 전부 때문이다.
주세페

@ 주세페 나는 % % 3을 시도하고 유망했다 그래서 계속 찾고 ... 또한 도트 제품을 사용하면 하나의 추가 바이트를 절약 :)
JayCe

1

루비 , 50 46 바이트

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

온라인으로 사용해보십시오!

Arnauld의 답변 의 기본 포트는 -4 바이트 동안 GB만큼 향상되었습니다.


1
"map"대신 "bytes"를 사용하는 경우 45 바이트 – 실제로 47
GB

@GB 덕분에 원시 바이트 코드로 입력하는 것이 일반적으로 문자열을 지원하는 언어에 비해 너무 자유 로워지기 때문에 더 긴 버전을 고수 할 것입니다.
Kirill L.

1
다른 바이트 오프 : 46 바이트
GB


1

자바 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에서 변환 될 번호를 읽습니다.

이것은 @Arnauld가 JavaScript를 사용하여 제공 한 것과 동일한 솔루션입니다.


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.mapFoldBackSeq.map와 결합 Seq.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(내 의견으로는) 약간 지저분한 을 반환합니다 .

사용 Seq.mapi이이 같이 할 수있는 139 바이트 :

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}

온라인으로 사용해보십시오!

반대 목록에서, 계산에서 결과를 증가 <시키고 T( -allregexp 옵션 사용) 자연을 60의 거듭 제곱으로 증가시킵니다.

올바른 버전 (주석 참조)


마지막 숫자의 \ 때문에이 방법이 실패한 것 같습니다 ... regsub {\\} $l0 lforeach 루프 이전에 있어야했습니다 ...
david

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에서는 혼합 정수 및 목록 목록에서 작동하지 않으므로 €O대신 필요 합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.