根据国际象棋FEN字符串评估分数


17

挑战

福赛斯·爱德华兹符号(FEN)是一种标准符号,用于描述国际象棋游戏中特定的棋盘位置。您面临的挑战是使用FEN字符串评估分数。这是FEN字符串的示例:

5k2/ppp5/4P3/3R3p/6P1/1K2Nr2/PP3P2/8

使用此字符串,您可以使用以下得分表来计算每种颜色的材料得分:

  • p / P =典当= 1点
  • n / N =骑士= 3分
  • b / B =主教= 3分
  • r / R =白嘴鸦= 5分
  • q / Q =皇后= 9分
  • k / K = King,这些没有任何意义,因为每个法律职位的每一侧都包含King

白色部分使用大写字母(“ PNBRQK”)指定,而黑色部分使用小写字母(“ pnbrqk”)指定。使用1到8的数字(空白方块的数量)标注空白方块,“ /”分隔等级。

从示例FEN字符串中,我们可以计算每一面的材料得分:

对于黑色:

5 k 2 / ppp 5 / 4P3 / 3R3 p / 6P1 / 1K2N r 2 / PP3P2 / 8

剩下的所有黑色块:p + p + p + p + r,总共9个

对于白色:

5k2 / ppp5 / 4 P 3/3 R 3p / 6 P 1/1 K 2 N r2 / PP 3 P 2/8

剩下的所有白色小块:P + R + P + N + P + P + P,总共13

最终分数由以下公式确定:白色分数 - 黑色分数 = 最终分数,因此对于该示例,最终分数将为:13-9 = 4

范例

输入:

5k2/ppp5/4P3/3R3p/6P1/1K2Nr2/PP3P2/8

输出:

4

所有规则都适用于此,以最少的字节数获胜的解决方案。


如何发布

# Language Name, N bytes

 [code]

 [explaination, etc.]

3
那么实际位置没关系吗?您只计算字符串中的字母?
xnor

4
Nitpick:这不是完整的FEN字符串。另外,kr1NQQQQ / 2rNQQQQ / 3NQQQQ / 3NQQQQ / 3NQQQQ / 3NQQQQ / 3NQQQQ / K2NQQQQ赢得了白色,黑色动了吗?:P
门把手

@xnor是的,我认为如果评估也是基于策略的,它将变得过于复杂。您还可以假设所有输入都是合法位置,因此不必担心。
阿德南(Adnan)2015年

@Doorknob,是的,分数仅是基于材料来简化事情
Adnan

Answers:


3

CJam,28 27 26字节

0l{i32mdD%[5ZZX9]=\3%(*+}/

CJam解释器中在线尝试。

怎么运行的

0l         e# Push a 0 (accumulator) and a line from STDIN.
{          e# For each character of that line:
  i32md    e#   Divide its code point by 32; push quotient and residue.
           e#   This serves two purposes:
           e#     1. The quotient will let us distinguish between uppercase
           e#        letters, lowercase letters and non-letters.
           e#     2. The residue will be the same for uppercase and lowercase
           e#        variants of the same letter.
  D%       e#   Take the residue modulo 13.
           e#   This maps R,N,B,P,Q -> 5,1,2,3,4
  [5ZZX9]= e#   Select the element at that index (5 ≡ 0) from [5 3 3 1 9].
  \        e#   Swap the quotient on top of the stack.
           e#   1 is digit or slash, 1 is uppercase, 2 is lowercase.
  3%(      e#   Take the quotient modulo 3 and subtract 1 from the result.
           e#   This maps 1,2,3 -> 0,1,-1.
  *+       e#   Multiply the generated integers.
  +        e#   Add the product to the accumulator.
}/         e#

5

> <>64 57 56 53字节

"QRBNP"013359v
$0p4}:{:v?=1l<p4+' '{-
g4v?(0:i<+
n~<;

(-7个字节从@ El'endiaStarman的答案中得到一些启发,-3个字节感谢@randomra)

说明

该程序将代码箱用作查找表。超出范围的放置/获取不适用于在线解释器,因此仅适用于官方的Python解释器。

第一行将压片,然后是压片值。它还推一个初始0,以开始第三行的总数。

然后,第二行在相应的单元格处放置适当的正值或负值,例如 -1放置在('p', 4)1放置('P', 4)。检查堆栈的长度以确保循环运行5次。

循环结束后,堆栈由第一行的单个零组成。对于每个字符,我们在表中的相应单元格上进行查找,并将其添加到总计中。默认情况下,未初始化的单元格值为0,非常适合我们的目的。

最后一行仅打印结果。


4

Ruby,88个字符

->s{s.chars.map{|c|({P:1,N:3,B:3,R:5,Q:9}[:"#{c.upcase}"]||0)*(c.ord<90?1:-1)}.inject:+}

这很尴尬和丑陋,也许还有更好的方法,但是哦。

Ruby的{foo: 'bar'}语法实际上只是糖,{:foo => 'bar'}对于高尔夫来说这很烦人,因为这意味着我必须在使用键访问哈希元素之前将键转换为符号(:"#{x}"比短1个字符x.to_sym)。


4

点,39个字节

在CJam和Pyth的答案出现之前,我将先简短介绍一下...

$+Y(95<=>A_)*013359@{"KPNBRQ"@?UCa|0}Ma

将FEN字符串作为命令行参数。这是一个略微偏离版本的解释:

$+({(95<=>Aa)*013359@("KPNBRQ"@?UCa|0)}Ma)

   {                                  }Ma   Map this function to each character in input:
                                UCa          Uppercase version of character
                      "KPNBRQ"@?             Its index in this string, nil if not present
                                   |0        Logical or with 0 (to turn nil into 0)
              013359@(               )       Index into this number to get piece's score
          Aa                                 ASCII value of character
     95<=>                                   1 if less than 95, -1 if greater than 95
    (       )*                               Multiply by the score
$+(                                      )  Sum all scores and autoprint result

4

Perl,44个字节

#!perl -p
$\+=lc=~y/pnbrq/13359/r*(a cmp$_)for/\D/g}{

将shebang视为一个,输入来自stdin。


样品用量

$ echo 5k2/ppp5/4P3/3R3p/6P1/1K2Nr2/PP3P2/8 | perl fen-score.pl
4

说明

作品将以其各自的值进行音译。如果小写大写(即小于a),则将其值加到总和上,否则将其减去。


3

的JavaScript ES7,79字节124 131

s=>(i=0,[for(q of s)i+={P:1,N:3,B:3,R:5,Q:9,p:-1,n:-3,b:-3,r:-5,q:-9}[q]||0],i)

尽我所能。使用奇特的数组理解来遍历字符串。

说明

s=>(     // Define function with an argument

    i=0, // this var will store the score

    [for(q of s)   // Loops through input
      i+=          // Adds to score by...

         {P:1,...,   // Defines value of each letter
          p:-1,...}  // Negative value instead, which will subtract
         || 0        // Otherwise add 0

    ], i           // Return score

3

Minkolang 0.972个 65 64 60 44 42 41字节

13359"QRBNP"m5[d3~c~$r48*+0p0p]$I[o0q+]N.

在这里尝试。

非常感谢Sp3000指出了一种更有效的方法!

说明

13359"QRBNP"m推入乐谱及其对应的字符,然后将其交织,因此堆栈如下所示:[1,80,3,78,3,66,5,82,9,81]。然后5[d3~c~$r48*+0p0p]将每个字符(小写和大写)的分数放在代码空间中的位置。最后,$I[o0q+]N.循环遍历输入,直到输入为空,然后将输入的分数相加。


2

CJam,33个字节

q{"PNBRQ"_el+#13359Ab_Wf*+0+=}%:+

这是超级幼稚的字符串查找方式。在线尝试


2

衔尾蛇,82

Ouroboros是我本周设计的一种梭口。是时候花点时间了!

i.1+!57*(\m1(M\1).96>.@32*-.80=\.78=3*\.66=3*\.82=5*\81=9*++++\2*1\-*+
)L!4*(4Sn1(

单字符命令1的每一行代表一条蛇尾蛇,其中执行从头(开始)到尾(结束)进行,然后循环回到头。该()命令让你吃尾巴的一部分,或者吐出它,从而改变命令得到执行的。如果吞没了指令指针,则蛇死亡(停止执行)。衔尾蛇程序由一个或多个并行执行的蛇组成。每条蛇都有自己的堆栈,也有共享的堆栈。

1 一个例外,它使Ouroboros与许多2D语言区分开:可以直接编写多位数字,而无需进行数学运算或先输入0即可。

蛇1

第一条蛇读取一个字符(i),并检查它是否为-1 / EOF(.1+!)。如果是这样,它会吃掉大部分的尾巴,直到M(包括57*()为止。

然后,蛇将字符代码与堆栈上位于其上方的提示符交换(\),将提示符移至共享堆栈(m),然后吞下另一个字符(1()。如果它已经吞下了一大堆,则意味着它吞下(了IP当前所在的位置并死亡。否则,通过将计数返回到蛇1的堆栈,将其与char代码交换,然后重新进行先前吞下的字符(M\1)),继续执行。

然后,我们使用数学和堆栈运算为角色生成适当的分数。.96>测试是否为小写;随后的32*-转换为大写。然后是从.80=81=9*++++地图P-> 1N-> 3等的长距离拉伸。最后,\2*1\-*如果字母是小写字母,则将分数取反,+并将其添加到正在运行的提示中。蛇然后循环并读取另一个字符。

蛇2

第二条蛇以反流操作())开头,该操作在第一次执行时不执行任何操作(因为尚未吞咽任何内容,并且由于弹出空堆栈而给出0)。接下来,它将共享堆栈的长度推入其自己的堆栈,并在逻辑上取反(L!)。这给出1堆栈是否为空,0否则。蛇乘以4并吃掉那么多字符(4*()。

如果共享堆栈为空,则这意味着蛇现在在之前结束S。它将推入4并循环回到),在该处重新输入刚刚吞下的字符,然后重新开始。

但是,如果共享堆栈上有一个值,则不会吞下任何字符,并且继续执行。蛇切换到共享堆栈并在其中输出数字(Sn);然后它将吞下最后一个字符并死亡(1()。

同步化

必须仔细同步两条蛇,以使蛇2进行检查时共享堆栈上永远不会有值,直到到达输入结束为止。每次循环时,Snake 1都会在共享堆栈上短暂地放置一个值。因此,蛇2的L命令绝不能在蛇1 的mM命令之间执行。幸运的是,蛇的排列非常好。至关重要的是,snake 1的循环(70条指令)的长度是snake 2的循环(7条指令)的倍数,因此这两个永远不会不同步:

i.1+!57*(\m1(M\1).96>.@32*-.80=\.78=3*\.66=3*\.82=5*\81=9*++++\2*1\-*+
)L!5*(5)L!5*(5)L!5*(5)L!5*(5)L!5*(5)L!5*(5)L!5*(5)L!5*(5)L!5*(5)L!5*(5
          |__|
       Danger zone

如果这些数字不是很理想,我会在一条或两条蛇上填充空格以使它们根据需要对齐。

所有这些都很好,但是我想看到它的实际效果!

这是通过堆栈片段的上述程序。即使每秒进行1000次操作,也要花大约10秒钟来吐出示例输入的答案,但是确实可以达到目的!


2

JavaScript ES6、71

作为匿名功能

n=>[...n].map(x=>t+=~(y='q   rnb p PBN R   Q'.search(x))?y-9|1:0,t=0)|t

2

Perl 5,71 63字节

%a=(P,1,N,3,B,3,R,5,Q,9);$\+=$a{$_}||-$a{uc$_}for<>=~/./g;print

这会修改字符串中每个字母数字(开头是的哈希键)(该字符串的$\分隔符print,从false %a开始)。$\如果字母原样是键,则按哈希值递增;否则,如果大写字母是键,则将哈希值增加负数;否则,将哈希值增加负数。否则,它什么也不会添加。

非常感谢primo为我节省了八个字节(对此答案进行评论)。


我可以用primo的另一个建议保存另一个字节(谢谢!):更改$a{$_}||-$a{uc$_}$a{$_}-$a{$"^$_}。但是,我认为这是与我的答案完全不同的答案,因此我不会为此而使用“信用”(-1个字节)。


1

Clojure / ClojureScript,63个字符

#(apply +(map{"P"1"N"3"B"3"R"5"Q"9"p"-1"n"-3"b"-3"r"-5"q"-9}%))

使用ClojureScript REPL编写的,也应该是有效的Clojure。在这里尝试。输入它,然后使用(*1 "FEN_string_here")

非常简单。 {"P"1..."q"-9}是“ P”到1,“ N”到3等的映射的数据结构文字。 map将函数作为第一个参数,将数据结构作为第二个参数-在这种情况下,它使用的功能是数据结构(地图文字)可以充当其自己的访问器函数。字符串参数(%来自函数宏)可以视为单个字符串的列表。没有出现在地图中的任何字符都将最终出现nil在结果列表中,该列表将被+忽略。


1

Pyth,25个字节

-Fmsmhy/4@S5%Ck12@Gd_rBz2

示范

pbnrq如果k是字母,则对字母中的字母使用以下映射公式:

(4 / (((chr(k) % 12) % 5) + 1) * 2 + 1

在Pyth中表示为:

hy/4@S5%Ck12

首先,程序创建输入的大小写转换版本,然后在两个字符串过滤器上均使用小写字母,然后应用上述公式,然后从白色值中求和并减去黑色值。


1

Python 3、93

v=dict(zip('pbnrqPBNRQ',[1,3,3,5,9]*2))
print(sum(v.get(c,0)*(-1)**(c>'Z')for c in input()))
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.