チェスのFEN文字列に基づいてスコアを評価する


17

チャレンジ

Forsyth–Edwards Notation(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 =キング、これらのポイントはありません

白い部分は大文字( "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はい、評価も戦略に基づいている場合、複雑になりすぎると思います。また、すべての入力が正当なポジションであると想定することもできますので、心配する必要はありません。
アドナン

@Doorknob、はい、スコアは物事を簡素化するためにのみ材料に基づいています
アドナン

回答:


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

(@ El'endiaStarmanの回答からインスピレーションを得た-7バイト、@ randomraのおかげで-3バイト)

説明

プログラムは、コードボックスをルックアップテーブルとして使用します。範囲外のputs / getsはオンラインインタープリターでは機能しないため、これは公式のPythonインタープリターでのみ機能します。

最初の行はピースをプッシュし、ピースの値が続きます。また、最初の0をプッシュして、3行目の合計を開始します。

2行目は、次いで、例えば、対応するピースのセルに適切な正または負の値を置き-1に配置され('p', 4)かつ1配置されています('P', 4)。ループが5回実行されるように、スタックの長さがチェックされます。

ループが終了すると、スタックは最初の行からの単一のゼロで構成されます。各文字について、テーブル内の対応するセルでルックアップを実行し、合計に追加します。デフォルトでは、初期化されていないセル値は0であり、これは目的に最適です。

最後の行は結果を出力するだけです。


4

ルビー、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}{

シバンを1つとしてカウントすると、入力は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

ウロボロス、82

ウロボロスは今週私がデザインしたエソランです。試してみましょう!

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

単一文字コマンド1の各行はウロボロス蛇を表し、実行は先頭(開始)から末尾(終了)に進み、先頭にループバックします。(そして)コマンドは、このようにコマンドが実行され得るもの変え、あなたは尾の一部を食べたり、それを逆流してみましょう。命令ポインターが飲み込まれると、ヘビは死にます(実行を停止します)。ウロボロスプログラムは、並行して実行される1つ以上のヘビで構成されます。各スネークには独自のスタックがあり、共有スタックもあります。

1 例外として、ウロボロスと多くの2D言語を区別しています。複数桁の数字は、数学を実行したり0を先にプッシュしたりすることなく、簡単に記述できます。

ヘビ1

最初のヘビはキャラクター(i)を読み取り、-1 / EOF(.1+!)かどうかをチェックします。もしそうなら、M57*()までの尾のほとんどを食べます。

次に、ヘビはスタック上の文字コードをその上にある集計と交換し(\)、集計を共有スタックに移動し(m)、別の文字を飲み込みます(1()。すでに束を飲み込んでいた場合、これは(IPが現在オンになっていることを飲み込んで死ぬことを意味します。それ以外の場合、集計はsnake 1のスタックに戻され、charコードと交換され、以前に飲み込まれた文字が逆流されます(M\1))。

次に、数学およびスタック操作を使用して、キャラクターに適切なスコアを生成します。.96>小文字かどうかをテストします。その後32*-は大文字に変換されます。その後の長いストレッチ.80=81=9*++++マップP- > 1N- > 3、などは最後に、\2*1\-*文字が小文字れた場合は、スコアを否定し、+実行中の集計に追加します。その後、ヘビはループして別のキャラクターを読みます。

ヘビ2

2番目のヘビは逆流操作())で始まりますが、これは最初は何もしません(まだ何も飲み込まれていないため、空のスタックをポップするとが得られるため0)。次に、共有スタックの長さを独自のスタックにプッシュし、論理的に否定します(L!)。これは1、スタックが空の場合に与えられ、0そうでない場合に与えます。ヘビは4倍になり、その数のキャラクターを食べます(4*()。

共有スタックが空だった場合、これはスネークがの前に終了することを意味しSます。にプッシュ4してループし、)飲み込んだばかりの文字を逆流し、最初からやり直します。

ただし、共有スタックに値があった場合、文字は飲み込まれず、実行は継続されます。スネークは共有スタックに切り替えて、そこに番号を出力します(Sn)。その後、最後のキャラクターを飲み込んで死にます(1()。

同期

2つのスネークは慎重に同期する必要があります。そうすることで、スネーク2がチェックを行うときに、入力の最後に到達するまで共有スタックに値が存在しなくなります。Snake 1は、ループを通過するたびに、共有スタックに値を短時間置きます。したがって、snake 2のLコマンドは、snake 1のコマンドmとの間で実行しないでくださいM。幸いなことに、ヘビは非常にうまく並んでいます。重要なことは、蛇1のループ(70命令)の長さは蛇2のループ(7命令)の倍数であるため、2つは決して同期しなくなります。

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

数字がそれほど完璧に機能していなかった場合、必要に応じて1つまたは両方のヘビにスペースを埋めて、それらを揃えます。

これらはすべて非常にうまくいきますが、実際に動作したいです!

以下は、スタックスニペットを介した上記のプログラムです。1秒あたり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

これは、先頭で定義されたハッシュのキーである文字列内のすべての英数字の(falseで始まる$\行区切り文字)を変更します。文字がそのままキーである場合、ハッシュの値だけ増加します。そうでない場合、大文字がキーである場合、ハッシュの値をマイナスでインクリメントします。それ以外の場合は何も追加されません。print%a$\

8バイトの節約をしてくれた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最初の引数として関数を使用し、2番目として処理するデータ構造を使用します。この場合、次の機能を使用しています。データ構造(マップリテラル)は、独自のアクセサー関数として機能できます。文字列パラメーター(%関数マクロから)は、個々の文字列のリストとして扱うことができます。マップにない文字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

最初に、プログラムは入力の大文字と小文字を入れ替えたバージョンを作成し、両方の文字列で小文字のフィルターを適用し、上記の式を適用してから、白の値から黒の値を合計および減算します。


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