像巴比伦人一样数数


41

挑战

给定输入的巴比伦数字的ASCII表示,以西方阿拉伯数字输出数字。

巴比伦数字系统

巴比伦人如何计算?有趣的是,他们将Base 60系统与Base 10系统一起使用。让我们首先考虑系统的unit列:

巴比伦人只有三个符号:(T或者,如果您可以渲染它:)𒐕代表1,<(或者,如果您可以渲染它:)𒌋代表10,和\(或者,如果您渲染它:)则𒑊代表零。

注意:从技术上讲,\(或𒑊)不为零(因为巴比伦人没有“零”的概念)。后来发明了“零”,所以后来又\添加了一个占位符以防止歧义。但是,就此挑战而言,将其视为\零就足够了

因此,在每一列中,您只需将符号的值相加即可,例如:

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

每列中不得超过五个<或超过九个T\将始终单独出现在列中。

现在,我们需要扩展它以添加更多列。这与任何其他基数60完全相同,在此基础上,您将最右边的列的值乘以,将左边的一乘以60 1,将左边的一乘以60 2,依此类推。然后,您将每个值相加以获得数字的值。600601602

列将由空格分隔以防止歧义。

一些例子:

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

规则

  • 您可以自由接受ASCII输入(T<\)或Unicode输入(𒐕𒌋𒑊
  • 输入的数字将始终小于107
  • <旨意始终是左边的T每列S
  • \ 将始终单独出现在列中

获奖

以字节为单位的最短代码获胜。


2
@TaylorScott是的,您可以
Beta衰减

2
如果有帮助,则最多需要处理4列:<<<<TTTTTT <TTTTTTT <<<<TTTTTT <<<<
Wernisch,

1
列是否总是始终被一个空格完全隔开?我注意到依赖它的答案。
KRyan

4
带有水烟筒的外来类型说“哦,哦,乳清,哦,哦,乳清”-像巴比伦人一样数。大。现在它卡在了我的头上。
cobaltduck

5
"How did the Babylonians count? Interestingly, they used a Base 60 system with an element of a Base 10 system."今天仍在使用;巴比伦数字系统正是我们用于时钟的系统。分别为秒,分钟和小时的两位十进制数字,分钟为60秒,小时为60分钟。

Answers:


39

JavaScript(ES6),44个字节

将输入作为ASCII字符数组。

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

在线尝试!

怎么样?

巴比伦数字系统可以看作是一种使用单一寄存器的4指令语言-我们称其为累加器。

开始,输入数组a中的每个字符c修改累加器k如下:k=0cak

  • space:乘法60(实现为:ADD 59 ķķk6059kk
  • <:将加到k10k
  • T:增加k
  • \: 没做什么; 这是NOP该语言的指令(实现为:将加到k0k


11

Perl 6,39个字节

-3字节归功于nwellnhof

{: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值的?
Jo King

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 1013Ordinal值获得5351用于<T\分别然后执行整数除法,:通过5获得1010


大声笑,正是因为这个原因,我删除了我的答案,因为我记得我可以使用基本转换,但实际上太懒了,找不到答案。+1
Xcoder先生18年

6

05AB1E,13个字节

8740|Ç%4/O60β

在线尝试!

为了弥补我对果冻答案的懒惰,这里提供了05AB1E xD中的内容。


帮助05AB1E-ers,那里没有压缩数字的方法8740吗?
Xcoder先生18年

2
codegolf.stackexchange.com/a/166851/52210不幸的是,它不会更短:•Yη•(4个字节)
Kevin Cruijssen

2
@KevinCruijssen谢谢!这个问题的答案是非常有用的,我将完全使用它在未来的
Xcoder先生

1
很高兴使用小费。:)在看到使用它们的答案后,我发现了这些问题。字典部分在这里进行了解释。在看到链接的示例回答“ goose”246060之后,我弄清楚了其他字符串或大整数的压缩。
凯文·克鲁伊森

1|Ç7%-13%O60β也是13岁-可以打高尔夫球吗?
乔纳森·艾伦


4

Excel VBA,121字节

仅限于32位Office,因为^LongLong在64位版本中用作类型文字

从单元格获取输入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<'⍳⌽

在线尝试!

编辑: -3字节,感谢ngn

'\ T<'⍳用数字替换字符(它们在字符串常量中的位置),并反转输入,以便最重要的“数字”位于最后。这样可以通过计算遇到空格(字符串常量中的索引2)的+\2=次数来保持所需功率的连续计数60(由施加60*)。

⌊10*⍵-3给出每个字符十的期望幂。字符串常量中的字符顺序和-3偏移量导致'\'和空格变为负数,当这些字符提高到10的幂时会产生分数,从而可以通过消除它们

现在,我们要做的就是将10的幂乘以60的幂乘以位值,然后求和+/


通过避免与' '以下各项进行单独比较来节省一些字节:{+/(⌊10*⍵-3)×60*+\2=⍵}'\ T<'⍳⌽
ngn


3

画布20 17 16 字节

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

在这里尝试!

说明:

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个字符,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输入,据我所知,JS不太擅长通过高尔夫球获取字符代码

为了后人的缘故,我保留了此方法,但这是一个幼稚/愚蠢的解决方案,建议您查看Arnauld的答案,这对于挑战的实现更有趣


@Shaggy看起来对我有用!
Skidsdev

c<'T'工作代替c=='<'
Xcoder先生,18年

替换为&&,再节省1个|
Shaggy

@Shaggy通过使用for...of循环来节省更多,:P
ASCII码,仅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为基数的转换,一次运行一行。计算速度以十进制表示。


我很确定第三行可以<没有+,除非我没有看到任何边缘情况。
凯文·克鲁伊森

1
@KevinCruijssen甚至更好,因为$&现在总是一个字符,所以我可以使用默认字符,再节省两个字节!
尼尔,

很好!:)不知道单个字符可以隐式完成。
凯文·克鲁伊森

@KevinCruijssen好吧,我不在乎角色是什么,因为我只是在讲长度。在Retina 1中,您会花_一会儿时间$*在Retina的早期版本中将默认值设置为1
尼尔,

知道了 您的初始代码将所有内容都<视为一次比赛,并将其重复10倍(长度)(<匹配的数量),而我建议的更改是每<10次重复一次(您使用隐式1和10*)。现在,我更好地了解了为什么+最初出现了。我对Retina内置函数了解不多,一般来说只有正则表达式,因此我建议进行更改,因为我已经读过了,每>10次重复一次。;)
Kevin Cruijssen

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(print)。





1

木炭,26字节

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

在线尝试!链接是详细版本的代码。说明:

≔⁰θ

清除结果。

FS«...»

循环输入字符。该命令被包装在一个块中,以防止其找到“默认”块。

≡ι

切换当前字符...

 ≦×⁶⁰θ

如果是空格,则将结果乘以60 ...

<≦⁺χθ

如果是a <,则将结果加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)

在线尝试!

由于字符串解析,时间太长了。感谢Giusppe删除了16个不必要的字节。

定义yunicode输入的字节码值,然后R = y("T<\") = y("𒐕𒌋𒑊")

观察一下R%%3 = 1,2,0R%%6 = 1,5,0...如此R%%3 * R%%6 = 1,10,0

其余的很容易:每列求和,然后以60的幂降序进行点积运算。


使用Reduce移植Arnauld的附加服务可能会更加困难。
JayCe

不会scan(,"")自动分割空格?
朱塞佩

1
但是,mod的技巧很不错!我试图弄清楚,但找不到它...并且/60可以-1在指数表达式中替换为另一个字节,并且<-可以将其替换为=括号,因为它全都用括号括起来了。
朱塞佩

@Giuseppe我尝试了%% 3,它很有希望,所以我一直在寻找...也使用了点积产品才为我节省了一个额外的字节:)
JayCe



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;}

-4个字节,感谢@ceilingcat

在线尝试。 说明:

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.mapFoldBack结合Seq.mapSeq.foldBackSeq.mapFoldBack向后迭代该序列,并在该序列中穿插一个累加器值(在本例中为i)。

对于序列中的每个元素,都会计算出巴比伦数(通过Seq.sumBy,将每个字符映射到一个数字并将结果相加),然后乘以ii然后将其乘以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,这意味着你需要或者INITIALISE或功能施放的所有值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(使用-all正则表达式选项)和递增自然的,因为60力量。

正确版本(请参阅评论)


看来我没有通过这个,因为最后一个数字是\。我应该regsub {\\} $l0 l在foreach循环之前添加一个。...–
david

0

APL(Dyalog扩展),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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.