Bir satranç FEN dizesinden alınan puanın değerlendirilmesi


17

Meydan okuma

Forsyth – Edwards Notasyonu (FEN), bir satranç oyununun belirli bir tahta pozisyonunu tanımlamak için standart bir gösterimdir. Zorluk FEN dizesini kullanarak puanı değerlendirmektir. Bu bir FEN dizesi örneğidir:

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

Bu dizeyi kullanarak, her bir rengin malzeme skorunu aşağıdaki skor tablosuyla hesaplayabilirsiniz:

  • p / P = Piyon = 1 puan
  • n / N = Şövalye = 3 puan
  • b / B = Piskopos = 3 puan
  • r / R = Kale = 5 puan
  • q / Q = Kraliçe = 9 puan
  • k / K = Kral, bunların hiçbir puanı yok çünkü her yasal pozisyonda her iki taraf için bir kral var

Beyaz parçalar büyük harf ("PNBRQK") kullanılarak, siyah parçalar küçük harf ("pnbrqk") kullanır. Boş kareler 1'den 8'e kadar basamaklar (boş karelerin sayısı) kullanılarak not edilir ve "/" sıraları ayırır.

Örnek FEN dizesinden, her bir taraf için malzeme puanlarını hesaplayabiliriz:

Siyah için:

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

Kalan tüm siyah parçalar: p + p + p + p + r, bu toplam 9

Beyaz için:

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

Kalan tüm beyaz parçalar: P + R + P + N + P + P + P, bu toplam 13

Nihai puan aşağıdaki formülle belirlenir: Beyaz puan - Siyah puan = Nihai puan , bu nedenle örnek için son puan şöyle olur: 13 - 9 = 4

Örnek :

Giriş:

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

Çıktı:

4

Burada tüm kuralları geçerlidir, en az bayt içeren çözüm kazanır.


Nasıl gönderilir?

# Language Name, N bytes

 [code]

 [explaination, etc.]

3
Yani gerçek pozisyon önemli değil mi? Sadece dizedeki harfleri mi sayıyorsun?
xnor

4
Nitpick: Bu tam bir FEN dizesi değil. Ayrıca, kr1NQQQQ / 2rNQQQQ / 3NQQQQ / 3NQQQQ / 3NQQQQ / 3NQQQQ / 3NQQQQ / K2NQQQQ beyaz için kazanıyor, siyah taşımak için? : P
Kapı tokmağı

@xnor Evet, eğer değerlendirme stratejik olarak da yapılıyorsa, çok karmaşık hale gelecektir. Ayrıca, tüm girdilerin yasal pozisyonlar olduğunu varsayabilirsiniz, bu yüzden endişelenmeyin.
Adnan

@Doorknob, evet, puan sadece işleri basitleştirmek için malzeme
Adnan

Yanıtlar:


3

CJam, 28 27 26 bayt

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

CJam yorumlayıcısında çevrimiçi deneyin .

Nasıl çalışır

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 bayt

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

(@ El'endiaStarman'ın cevabından ilham alarak -7 bayt, @randomra sayesinde -3 bayt)

açıklama

Program kod kutusunu arama tablosu olarak kullanır. Aralık dışı koymalar / almalar çevrimiçi tercümanla çalışmaz, bu sadece resmi Python tercümanı ile çalışır.

İlk satır parçaları iter, bunu parça değerleri izler. Ayrıca, üçüncü satırın toplamını başlatmak için ilk 0'ı iter.

İkinci çizgi daha sonra karşılık gelen parça hücresine uygun pozitif veya negatif değeri koyar, örneğin -1yerleştirilir ('p', 4)ve 1yerleştirilir ('P', 4). Yığının uzunluğu, döngünün 5 kez çalıştığından emin olmak için kontrol edilir.

Döngü bittikten sonra, yığın ilk satırdaki tek sıfırdan oluşur. Her karakter için tablodaki ilgili hücreye bir arama yapar ve toplamımıza ekleriz. Varsayılan olarak, başlatılmamış hücre değerleri 0'dır, bu da bizim amacımız için mükemmeldir.

Son satır yalnızca sonucu yazdırır.


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:+}

Bu garip ve çirkin ve muhtemelen daha iyi bir yol var, ama iyi.

Ruby'nin {foo: 'bar'}sözdizimi aslında sadece şekerdir {:foo => 'bar'}- bu golf için can sıkıcıdır, çünkü bir karma öğeye erişmek için kullanmadan önce anahtarı bir sembole dönüştürmem gerektiği anlamına gelir ( :"#{x}"daha kısa bir karakterdir x.to_sym).


4

Pip, 39 bayt

CJam ve Pyth cevapları gelmeden önce kısa bir süre öndeyim ...

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

FEN dizesini komut satırı bağımsız değişkeni olarak alır. İşte biraz ungolfed sürümü için bir açıklama:

$+({(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 bayt

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

Mesele bir olarak sayılır, girdi stdin'den alınır.


Örnek Kullanımı

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

açıklama

Parçalar ilgili değerleriyle harf çevirisi yapılır. Eğer parça büyük harfle yazılırsa (yani küçüktür a), değeri çıkarılmamışsa toplama eklenir.


3

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

Olabildiğince kısa. Dize boyunca döngü için süslü dizi anlayışları kullanır.

açıklama

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.9 , 72 65 64 60 44 42 41 bayt

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

Burada deneyin.

Bunu yapmanın çok daha etkili bir yolunu işaret ettiği için Sp3000'e çok teşekkürler!

açıklama

13359"QRBNP"miter puanları ve bunlara karşılık gelen karakterler, daha sonra serpiştirecek , onları böyle yığın görünüyor böylece: [1,80,3,78,3,66,5,82,9,81]. Daha sonra 5[d3~c~$r48*+0p0p], her karakterin, hem küçük hem de büyük harfin puanını, kod alanındaki yerine koyar. Son olarak, $I[o0q+]N.boş olana kadar girdi boyunca dolaşır ve puanları ilerlerken toplar.



2

Ouroboros , 82

Ouroboros bu hafta tasarladığım bir esolang. Sıkma zamanı!

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

Tek karakterlik komutların ( 1) her satırı, yürütmenin baştan (başlangıç) kuyruğa (uç) ilerlediği ve başa geri döndüğü bir ouroboros yılanını temsil eder. (ve) komutlar böylece komutlar idam neyi değiştirerek, kuyruk kısmını yemek ya da kusar sağlar. Talimat işaretçisi yutulursa, yılan ölür (yürütmeyi durdurur). Bir Ouroboros programı, paralel olarak çalışan bir veya daha fazla yılandan oluşur. Her yılanın kendi yığını vardır ve ayrıca paylaşılan bir yığın vardır.

1 Ouroboros'u birçok 2B dilden ayıran bir istisna: çok basamaklı sayılar, matematik yapmadan veya 0'a ilk basmadan doğrudan yazılabilir.

Yılan 1

İlk yılan bir karakteri ( i) okur ve -1 / EOF ( .1+!) olup olmadığını kontrol eder . Eğer öyleyse, M( 57*() dahil olmak üzere kuyruğunun çoğunu yer .

Yılan, karakter kodunu yığının ( \) üzerindeki üstünde bulunan çetele ile değiştirir, çeteyi paylaşılan yığına ( m) taşır ve başka bir karakteri ( 1() yutar . Zaten bir demet yutmuşsa, (bu IP'nin açık olduğu ve öldüğü anlamına gelir . Aksi takdirde, işlem, çeteleyi yılan 1'in yığınına geri taşıyarak, char koduyla değiştirerek ve önceden yutulan karakterden ( M\1)) yeniden işlem yaparak devam eder .

Daha sonra karakter için uygun puanı oluşturmak için matematik ve yığın işlemlerini kullanırız. .96>küçük harf olup olmadığını test eder; sonraki 32*-büyük harfe dönüşür. Sonra uzun streç .80=için 81=9*++++harita P-> 1, N-> 3vb Son olarak, \2*1\-*mektup küçük harfli olsaydı skor ortadan kaldırır ve+ çalışan taksitli ekler. Yılan daha sonra döngüler ve başka bir karakter okur.

Yılan 2

İkinci yılan ), ilk kez hiçbir şey yapmayan (henüz hiçbir şey yutulmadığından ve aynı zamanda boş bir yığını patlattığından beri) bir regürjitasyon işlemi ( ) ile başlar 0. Daha sonra, paylaşılan yığının uzunluğunu kendi yığınına iter ve mantıksal olarak negatiftir ( L!). Bu 1, yığının boş olup olmadığını verir , 0aksi takdirde. Yılan 4 ile çarpılır ve bu kadar çok karakter ( 4*() yer.

Paylaşılan yığın boşsa, bu yılan şimdi S. Sadece yuttuğu karakterleri yeniden canlandırdığı ve yeniden başladığı yere 4geri iter ).

Bununla birlikte, paylaşılan yığın üzerinde bir değer varsa, hiçbir karakter yutulmaz ve yürütme devam eder. Yılan paylaşılan yığına geçer ve oradaki sayıyı çıkarır ( Sn); sonra son karakterini yutar ve ölür (1( ).

Senkronizasyon

İki yılan dikkatlice senkronize edilmelidir, böylece yılan 2 kontrolünü yaptığında giriş sonuna ulaşılana kadar paylaşılan yığın üzerinde hiçbir zaman bir değer kalmaz. Yılan 1, döngüden her geçişte kısa bir süre paylaşılan yığın üzerine bir değer koyar. Bu nedenle, yılan 2'nin Lkomutu asla yılan 1'deki mve Mkomutları arasında yürütülmemelidir . Neyse ki, yılanlar çok iyi sıralanır. En önemlisi, yılan 1'in döngüsünün uzunluğu (70 talimat) yılan 2'nin döngüsünün katlarıdır (7 talimat), bu yüzden ikisi asla senkronizasyondan çıkmaz:

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

Rakamlar bu kadar mükemmel bir şekilde çalışmasaydı, gerektiğinde hizalamak için bir veya iki yılanı boşluklarla doldururdum.

Bütün bunlar çok iyi, ama eylemde görmek istiyorum!

Stack Snippet üzerinden yukarıdaki program. Saniyede 1000 işlemde bile, örnek girişi için cevabı vermek yaklaşık 10 saniye sürer - ancak oraya ulaşır!


2

JavaScript ES6, 71

Anonim bir işlev olarak

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 bayt

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

Bu , başlangıçta tanımlanan karmanın anahtarı olan dizedeki her alfasayısal için (yanlış başlayan $\satır ayırıcı) değiştirir . Harf olduğu gibi bir anahtar ise, karma değerine göre artar ; Aksi takdirde, negatif olarak artarprint%a$\ büyük harf bir anahtarsa, karma değerini ; aksi halde hiçbir şey katmaz.

Bana sekiz bayt kurtardığı için primo'ya çok teşekkürler (bu cevap üzerine bir yorumda).


Ben primo başka öneriyle başka byte kaydedebilirsiniz (teşekkürler!): Değişikliği $a{$_}||-$a{uc$_}için $a{$_}-$a{$"^$_}. Ama bu benimkinden oldukça farklı bir yanıt, sanırım, bu yüzden onun için "kredi" (credit1 bayt) almayacağım.


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}%))

ClojureScript REPL kullanılarak yazılır, geçerli Clojure da olmalıdır. Burada deneyin . Girin, ardından şunu kullanarak arayın:(*1 "FEN_string_here")

Oldukça basit. {"P"1..."q"-9}"P" ila 1, "N" ila 3, vb. bir harita için bir veri yapısı değişmezidir map. işlevi ilk bağımsız değişken olarak alır ve ikinci yapı olarak işlenecek veri yapısını alır - bu durumda, bir veri yapısı (harita değişmezi) kendi erişimci işlevi olarak işlev görebilir. String parametresi ( %işlev makrosundan) ayrı karakter dizelerinin bir listesi olarak değerlendirilebilir. Haritada olmayan herhangi bir karakter nil, sonuç listesindeki gibi sona erer ve bu da +mutlu bir şekilde yok sayar.


1

Pyth, 25 bayt

-Fmsmhy/4@S5%Ck12@Gd_rBz2

gösteri

Bu, harf ise pbnrq, içindeki harfler için aşağıdaki eşleme formülünü kullanır k:

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

Bu Pyth'de şu şekilde temsil edilir:

hy/4@S5%Ck12

İlk olarak, program girişin büyük / küçük harf değiştirilmiş sürümünü oluşturur, ardından her iki dizede de küçük harfler için filtreler kullanır, sonra yukarıdaki formülü uygular, ardından siyah değerleri beyaz değerlerden toplar ve çıkarır.


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()))
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.