Mengevaluasi skor berdasarkan string FEN catur

17

Tantangan

Forsyth – Edwards Notation (FEN) adalah notasi standar untuk menggambarkan posisi papan tertentu dari permainan catur. Tantangan Anda adalah untuk mengevaluasi skor menggunakan string FEN. Ini adalah contoh string FEN:

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

Dengan menggunakan string ini, Anda dapat menghitung skor materi untuk setiap warna dengan tabel skor berikut:

  • p / P = Gadai = 1 poin
  • n / N = Ksatria = 3 poin
  • b / B = Uskup = 3 poin
  • r / R = Benteng = 5 poin
  • q / Q = Ratu = 9 poin
  • k / K = Raja, ini tidak memiliki poin karena setiap posisi hukum berisi raja untuk setiap sisi

Potongan putih ditunjuk menggunakan huruf besar ("PNBRQK") sementara potongan hitam menggunakan huruf kecil ("pnbrqk"). Kotak kosong dicatat menggunakan angka 1 hingga 8 (jumlah kotak kosong), dan "/" memisahkan peringkat.

Dari contoh string FEN, kita dapat menghitung skor materi untuk setiap sisi:

Untuk hitam:

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

Semua potongan hitam tersisa: p + p + p + p + r, ini adalah total 9

Untuk putih:

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

Semua bagian putih yang tersisa: P + R + P + N + P + P + P, ini total 13

Skor akhir ditentukan dengan rumus berikut: Skor putih - Skor hitam = Skor akhir , jadi misalnya skor akhir adalah: 13 - 9 = 4

Contoh :

Memasukkan:

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

Keluaran:

4

Semua aturan berlaku di sini, solusi dengan jumlah byte terkecil yang menang.


Cara memposting

# Language Name, N bytes

 [code]

 [explaination, etc.]
Adnan
sumber
3
Jadi posisi sebenarnya tidak masalah? Anda hanya menghitung huruf dalam string?
xnor
4
Nitpick: Itu bukan string FEN lengkap. Juga, kr1NQQQQ / 2rNQQQQ / 3NQQQQ / 3NQQQQ / 3NQQQQ / 3NQQQQ / 3NQQQQ / K2NQQQQ menang untuk putih, dengan hitam untuk pindah? : P
Doorknob
@ xnor Ya, saya pikir jika evaluasi ini juga berbasis strategis, itu akan menjadi terlalu rumit. Anda juga dapat berasumsi bahwa semua input adalah posisi legal, jadi jangan khawatir tentang itu.
Adnan
@Doorknob, ya, skornya hanya berdasarkan materi untuk menyederhanakan hal
Adnan

Jawaban:

3

CJam, 28 27 26 byte

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

Cobalah online di juru bahasa CJam .

Bagaimana itu bekerja

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#
Dennis
sumber
5

> <> , 64 57 56 53 byte

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

(-7 byte dengan beberapa inspirasi dari jawaban @ El'endiaStarman, -3 byte terima kasih kepada @randomra)

Penjelasan

Program ini menggunakan kotak kode sebagai tabel pencarian. Put / get out of range tidak berfungsi dengan juru bahasa online, jadi ini hanya bekerja dengan juru bahasa Python resmi.

Baris pertama mendorong potongan, diikuti dengan nilai potongan. Ini juga mendorong 0 awal untuk memulai total untuk baris ketiga.

Baris kedua kemudian menempatkan nilai positif atau negatif yang sesuai pada potongan sel yang sesuai, misalnya -1ditempatkan di ('p', 4)dan1 ditempatkan ('P', 4). Panjang tumpukan diperiksa untuk memastikan loop berjalan 5 kali.

Setelah loop selesai, stack terdiri dari nol tunggal kami dari baris pertama. Untuk setiap karakter kami melakukan pencarian pada sel yang sesuai dalam tabel dan menambahkannya ke total kami. Secara default, nilai sel tidak diinisialisasi adalah 0, yang sempurna untuk tujuan kami.

Baris terakhir hanya mencetak hasilnya.

Sp3000
sumber
4

Ruby, 88 karakter

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

Ini aneh dan jelek, dan mungkin ada cara yang lebih baik, tapi oh well.

{foo: 'bar'}Sintaks Ruby sebenarnya hanya gula untuk {:foo => 'bar'}— ini menjengkelkan untuk golf karena itu berarti saya harus mengonversi kunci menjadi simbol sebelum menggunakannya untuk mengakses elemen hash ( :"#{x}"satu karakter lebih pendek dari x.to_sym).

Gagang pintu
sumber
4

Pip, 39 byte

Saya akan mengambil giliran singkat dalam memimpin sebelum jawaban CJam dan Pyth datang ...

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

Mengambil string FEN sebagai argumen baris perintah. Berikut penjelasan untuk versi yang sedikit tidak ungolfed:

$+({(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
DLosc
sumber
4

Perl, 44 byte

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

Menghitung shebang sebagai satu, input diambil dari stdin.


Contoh Penggunaan

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

Penjelasan

Potongan ditransliterasikan dengan nilainya masing-masing. Jika potongan dikapitalisasi (yaitu kurang dari a), nilainya ditambahkan ke jumlah, jika tidak dikurangi.

primo
sumber
3

JavaScript ES7, 79 byte 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)

Sesingkat yang saya bisa. Menggunakan pemahaman array mewah, untuk mengulang melalui string.

Penjelasan

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
Downgoat
sumber
3

Minkolang 0,9 , 72 65 64 60 44 42 41 byte

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

Coba di sini.

Terima kasih banyak kepada Sp3000 karena menunjukkan cara yang lebih efisien untuk melakukan ini!

Penjelasan

13359"QRBNP"mdorongan skor dan karakter yang sesuai mereka, maka interleaves mereka, sehingga terlihat tumpukan seperti ini: [1,80,3,78,3,66,5,82,9,81]. Kemudian 5[d3~c~$r48*+0p0p]letakkan skor setiap karakter, baik huruf kecil dan besar, di lokasinya dalam ruang kode. Akhirnya, $I[o0q+]N.loop melalui input sampai kosong, menambahkan skor saat berjalan.

El'endia Starman
sumber
2

CJam, 33 byte

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

Inilah cara mencari string yang super naif. Cobalah online .

Sp3000
sumber
2

Ouroboros , 82

Ouroboros adalah esolang yang saya rancang minggu ini. Saatnya untuk berputar!

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

Setiap baris perintah single-char 1 mewakili ular ouroboros, di mana eksekusi berlangsung dari kepala (mulai) hingga ekor (ujung) dan loop kembali ke kepala. The (dan )perintah membiarkan Anda makan bagian dari ekor atau memuntahkan itu, sehingga mengubah apa perintah dijalankan. Jika penunjuk instruksi pernah ditelan, ular mati (berhenti mengeksekusi). Program Ouroboros terdiri dari satu atau lebih ular yang dieksekusi secara paralel. Setiap ular memiliki tumpukan sendiri, dan ada juga tumpukan bersama.

1 Satu pengecualian, yang membedakan Ouroboros dari banyak bahasa 2D: angka multi-digit dapat ditulis dengan mudah, tanpa harus melakukan matematika atau menekan angka 0 terlebih dahulu.

Ular 1

Ular pertama membaca karakter ( i) dan memeriksa apakah itu -1 / EOF ( .1+!). Jika demikian, ia memakan sebagian besar ekornya, hingga dan termasuk M( 57*().

Ular kemudian menukar kode karakter dengan penghitungan yang di atasnya pada stack ( \), memindahkan penghitungan ke stack bersama ( m), dan menelan karakter lain ( 1(). Jika sudah menelan banyak, ini berarti menelan (bahwa IP saat ini hidup dan mati. Jika tidak, eksekusi akan dilanjutkan dengan menggerakkan penghitungan kembali ke tumpukan ular 1, menukar dengan kode char, dan memuntahkan karakter yang sebelumnya ditelan ( M\1)).

Kami kemudian menggunakan operasi matematika dan tumpukan untuk menghasilkan skor yang sesuai untuk karakter. .96>menguji apakah huruf kecil atau tidak; 32*-konversi selanjutnya ke huruf besar. Kemudian bentangan panjang dari .80=ke 81=9*++++peta P-> 1, N-> 3, dll. Akhirnya, \2*1\-*meniadakan skor jika huruf itu huruf kecil, dan +menambahkannya ke penghitungan berjalan. Ular itu kemudian loop dan membaca karakter lain.

Ular 2

Ular kedua dimulai dengan operasi memuntahkan ( )), yang tidak melakukan apa pun pertama kali melalui (karena belum ada yang ditelan, dan juga sejak muncul tumpukan memberi kosong 0). Selanjutnya, ia mendorong panjang tumpukan bersama ke tumpukannya sendiri dan secara logis meniadakan ( L!). Ini memberi 1jika tumpukan kosong, 0jika tidak. Ular itu bertambah banyak dengan 4 dan memakan banyak karakter ( 4*().

Jika tumpukan bersama kosong, ini berarti ular sekarang berakhir sebelum S. Ini mendorong 4dan loop kembali ke ), di mana ia memuntahkan karakter yang baru saja ditelan dan mulai lagi.

Namun, jika ada nilai pada tumpukan bersama, tidak ada karakter yang ditelan dan eksekusi berlanjut. Ular beralih ke tumpukan bersama dan menampilkan nomor di sana ( Sn); kemudian ia menelan karakter terakhirnya dan mati ( 1().

Sinkronisasi

Kedua ular harus disinkronkan dengan hati-hati sehingga tidak pernah ada nilai pada tumpukan bersama ketika ular 2 melakukan pemeriksaannya, sampai akhir input tercapai. Snake 1 memberi nilai pada stack yang dibagikan secara singkat pada setiap pass melalui loop-nya. Dengan demikian, Lperintah snake 2 tidak boleh dieksekusi antara perintah mdan Mdi snake 1. Untungnya, ular berbaris dengan sangat baik. Yang terpenting, panjang lingkaran ular 1 (70 instruksi) adalah kelipatan lingkaran ular 2 (7 instruksi), sehingga keduanya tidak akan pernah keluar dari sinkronisasi:

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

Jika angkanya tidak berjalan dengan sempurna, saya akan memberi satu atau dua ular dengan spasi untuk membuatnya sejajar yang diperlukan.

Semua ini sangat baik, tetapi saya ingin melihatnya beraksi!

Berikut adalah program di atas via Stack Snippet. Bahkan pada 1000 operasi per detik, dibutuhkan sekitar 10 detik untuk mengeluarkan jawaban untuk input sampel - tetapi ia sampai di sana!

DLosc
sumber
2

JavaScript ES6, 71

Sebagai fungsi anonim

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

Perl 5, 71 63 byte

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

Ini memodifikasi $\(pemisah baris untuk print, yang dimulai false) untuk setiap alfanumerik dalam string yang merupakan kunci dari hash yang %aditentukan di awal. Itu bertambah $\dengan nilai hash jika surat itu adalah kunci seperti apa adanya; jika tidak, itu bertambah dengan negatif nilai hash jika huruf besar adalah kunci; selain itu tidak menambah apa-apa.

Banyak terima kasih kepada Primo karena telah menyelamatkan saya delapan byte (dalam komentar tentang jawaban ini).


Saya dapat menyimpan byte lain dengan saran lain dari primo (terima kasih!): Ubah $a{$_}||-$a{uc$_}ke $a{$_}-$a{$"^$_}. Tapi itu jawaban yang agak berbeda dari saya, saya pikir, jadi saya tidak akan mengambil "kredit" (dari −1 byte) untuk itu.

msh210
sumber
1

Clojure / ClojureScript, 63 karakter

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

Ditulis menggunakan ClojureScript REPL, juga harus Clojure yang valid. Coba di sini . Masukkan, lalu panggil menggunakan(*1 "FEN_string_here")

Cukup mudah. {"P"1..."q"-9}adalah struktur data literal untuk peta "P" ke 1, "N" ke 3, dll. mapmengambil fungsi sebagai argumen pertama dan struktur data untuk diproses sebagai yang kedua - dalam hal ini, ia menggunakan fitur yang struktur data (peta literal) dapat bertindak sebagai fungsi pengakses sendiri. Parameter string ( %dari fungsi makro) dapat diperlakukan sebagai daftar string karakter individu. Karakter apa pun yang tidak ada di peta akan berakhir seperti nildalam daftar yang dihasilkan, yang +dengan senang hati mengabaikannya.

MattPutnam
sumber
1

Pyth, 25 byte

-Fmsmhy/4@S5%Ck12@Gd_rBz2

Demonstrasi

Ini menggunakan rumus pemetaan berikut untuk huruf dalam pbnrq, jika khuruf:

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

Ini diwakili dalam Pyth sebagai:

hy/4@S5%Ck12

Pertama, program membuat versi input kasus yang ditukar, kemudian pada kedua filter string untuk huruf kecil, kemudian menerapkan rumus di atas, lalu menjumlahkan dan mengurangi nilai hitam dari nilai putih.

isaacg
sumber
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()))
Morgan Thrapp
sumber