Ocena wyniku na podstawie szachowego ciągu FEN


17

Wyzwanie

Notacja Forsyth – Edwards (FEN) to standardowa notacja opisująca konkretną pozycję na planszy w szachach. Twoim zadaniem jest ocena wyniku za pomocą ciągu FEN. To jest przykład ciągu FEN:

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

Za pomocą tego ciągu możesz obliczyć ocenę materiału dla każdego koloru za pomocą następującej tabeli wyników:

  • p / P = pionek = 1 punkt
  • n / N = rycerz = 3 punkty
  • b / B = Biskup = 3 punkty
  • r / R = Wieża = 5 punktów
  • q / Q = królowa = 9 punktów
  • k / K = król, nie mają one żadnych punktów, ponieważ każda pozycja prawna zawiera króla z każdej strony

Białe elementy są oznaczone dużymi literami („PNBRQK”), a czarne - małymi literami („pnbrqk”). Puste kwadraty są zapisywane za pomocą cyfr od 1 do 8 (liczba pustych kwadratów), a „/” rozdziela szeregi.

Na podstawie przykładowego ciągu FEN możemy obliczyć oceny materiałowe dla każdej strony:

Dla czerni:

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

Wszystkie pozostałe czarne kawałki: p + p + p + p + r, w sumie jest to 9

Dla bieli:

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

Zostały wszystkie białe pionki: P + R + P + N + P + P + P, w sumie 13

Wynik końcowy określa się według następującego wzoru: Wynik biały - wynik czarny = wynik końcowy , więc na przykład wynik końcowy to: 13 - 9 = 4

Przykład :

Wejście:

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

Wynik:

4

Wszystko w tutaj zasady , wygrywa rozwiązanie z najmniejszą liczbą bajtów.


Jak publikować

# Language Name, N bytes

 [code]

 [explaination, etc.]

3
Więc rzeczywista pozycja nie ma znaczenia? Po prostu liczysz litery w ciągu?
xnor

4
Nitpick: To nie jest pełny ciąg FEN. Również kr1NQQQQ / 2rNQQQQ / 3NQQQQ / 3NQQQQ / 3NQQQQ / 3NQQQQ / 3NQQQQ / K2NQQQQ wygrywa dla białego, z czarnym, aby się poruszyć? : P
Klamka

@xnor Tak, myślę, że jeśli ocena jest również strategiczna, stanie się zbyt skomplikowana. Możesz również założyć, że wszystkie dane wejściowe są zgodne z prawem, więc nie przejmuj się tym.
Adnan

@Doorknob, tak, wynik jest tylko materiałem opartym na uproszczeniu
Adnan

Odpowiedzi:


3

CJam, 28 27 26 bajtów

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

Wypróbuj online w interpretatorze CJam .

Jak to działa

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 bajtów

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

(-7 bajtów z pewną inspiracją z odpowiedzi @ El'endiaStarman, -3 bajty dzięki @randomra)

Wyjaśnienie

Program używa codbox jako tabeli przeglądowej. Pozycje poza zasięgiem nie działają z tłumaczem online, więc działa to tylko z oficjalnym tłumaczem w języku Python.

Pierwszy wiersz popycha kawałki, a następnie wartości kawałków. Przesuwa również początkowe 0, aby rozpocząć sumę dla trzeciej linii.

Drugi wiersz następnie umieszcza odpowiednią wartość dodatnią lub ujemną w odpowiedniej komórce kawałka, np. -1Umieszcza się w ('p', 4)i1 umieszcza ('P', 4). Długość stosu jest sprawdzana, aby upewnić się, że pętla działa 5 razy.

Po zakończeniu pętli stos składa się z naszego pojedynczego zera z pierwszej linii. Dla każdego znaku wykonujemy wyszukiwanie odpowiedniej komórki w tabeli i dodajemy ją do naszej sumy. Domyślnie niezainicjowane wartości komórek wynoszą 0, co jest idealne do naszych celów.

Ostatnia linia po prostu wypisuje wynik.


4

Ruby, 88 znaków

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

To niezręczne i brzydkie, i prawdopodobnie jest lepszy sposób, ale no cóż.

{foo: 'bar'}Składnia Ruby'ego jest po prostu cukrem dla {:foo => 'bar'}- jest to denerwujące dla golfa, ponieważ oznacza, że ​​muszę przekonwertować klucz na symbol przed użyciem go do uzyskania dostępu do elementu skrótu ( :"#{x}"jest o jeden znak krótszy niż x.to_sym).


4

Pip, 39 bajtów

Przejdę moją krótką kolejkę, zanim nadejdą odpowiedzi CJam i Pyth ...

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

Pobiera ciąg FEN jako argument wiersza polecenia. Oto wyjaśnienie nieco nie golfowej wersji:

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

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

Licząc shebang jako jeden, dane wejściowe są pobierane ze standardowego wejścia.


Przykładowe użycie

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

Wyjaśnienie

Kawałki są transliterowane z ich odpowiednimi wartościami. Jeśli utwór jest pisany wielką literą (tzn. Mniej niż a), jego wartość jest dodawana do sumy, jeśli nie, jest odejmowana.


3

JavaScript ES7, 79 bajtów 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)

Tak krótko, jak tylko mogę. Używa fantazyjnych interpretacji tablic, aby przewijać ciąg.

Wyjaśnienie

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 bajtów

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

Wypróbuj tutaj.

Ogromne podziękowania dla Sp3000 za wskazanie znacznie bardziej wydajnego sposobu na zrobienie tego!

Wyjaśnienie

13359"QRBNP"mpopycha wyniki oraz odpowiadające im znaki, to przeplata je, więc wygląda jak stos to: [1,80,3,78,3,66,5,82,9,81]. Następnie 5[d3~c~$r48*+0p0p]umieszcza wynik każdego znaku, zarówno małymi, jak i dużymi, w swoim miejscu w obszarze kodu. Wreszcie, $I[o0q+]N.pętle przechodzą przez dane wejściowe, aż będą puste, dodając wyniki w miarę upływu czasu.



2

Ouroboros , 82

Ouroboros to esolang, który zaprojektowałem w tym tygodniu. Czas na wyprawę!

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

Każda linia poleceń 1 -znakowych 1 reprezentuje węża usoboros, w którym wykonywanie przebiega od głowy (początek) do ogona (koniec) i zapętla się z powrotem do głowy. (i) umożliwiają zjedzenie części ogona lub cofnięcie go, zmieniając w ten sposób, które polecenia zostaną wykonane. Jeśli wskaźnik instrukcji zostanie kiedykolwiek połknięty, wąż umiera (przestaje działać). Program Ouroboros składa się z jednego lub więcej węży wykonujących się równolegle. Każdy wąż ma własny stos, a także wspólny stos.

1 Jeden wyjątek, który odróżnia Ouroboros od wielu języków 2D: liczby wielocyfrowe można pisać prosto, bez konieczności wykonywania obliczeń matematycznych lub wypychania 0.

Snake 1

Pierwszy wąż czyta znak ( i) i sprawdza, czy jest to -1 / EOF ( .1+!). Jeśli tak, zjada większość ogona, aż do M( 57*().

Wąż następnie zamienia kod znakowy z licznikiem znajdującym się nad nim na stosie ( \), przenosi licznik do wspólnego stosu ( m) i połyka inny znak ( 1(). Jeśli już połknął pęczek, oznacza to, że połyka, (że adres IP jest aktualnie włączony i umiera. W przeciwnym razie wykonanie przebiega przez przesunięcie licznika z powrotem do stosu węża 1, zamianę go kodem char i ponowne zwrócenie znaku, który został wcześniej połknięty ( M\1)).

Następnie używamy operacji matematycznych i operacji na stosie, aby wygenerować odpowiedni wynik dla postaci. .96>sprawdza, czy ma małe litery, czy nie; kolejne są 32*-konwertowane na wielkie litery. Następnie długi odcinek od .80=do 81=9*++++map P-> 1, N-> 3itd. Wreszcie, \2*1\-*neguje wynik, jeśli litera była pisana małymi literami, i +dodaje go do licznika wyników. Wąż zapętla się i czyta inną postać.

Snake 2

Drugi wąż zaczyna się od operacji regurgitacji ( )), która za pierwszym razem nic nie robi (ponieważ nic nie zostało jeszcze połknięte, a także odkąd wyskakuje pusty stos 0). Następnie wypycha długość współdzielonego stosu do własnego stosu i logicznie neguje ( L!). Daje to, 1jeśli stos jest pusty, w 0przeciwnym razie. Wąż mnoży się przez 4 i zjada tyle znaków ( 4*().

Jeśli wspólny stos był pusty, oznacza to, że wąż kończy się przed S. Odsuwa się 4i zapętla z powrotem do miejsca ), w którym powraca do postaci, które właśnie połknął i zaczyna od nowa.

Jeśli jednak na stosie wspólnym znajdowała się wartość, żadne znaki nie są połykane i wykonywanie jest kontynuowane. Wąż przełącza się na wspólny stos i wypisuje tam liczbę ( Sn); następnie połyka swój ostatni znak i umiera ( 1().

Synchronizacja

Dwa węże muszą być dokładnie zsynchronizowane, aby nigdy nie było wartości na stosie wspólnym, gdy wąż 2 sprawdza, aż do osiągnięcia końca danych wejściowych. Snake 1 umieszcza wartość na wspólnym stosie na krótko przy każdym przejściu przez swoją pętlę. Dlatego Lpolecenie węża 2 nie może być nigdy wykonywane między poleceniami mi Mw wężu 1. Na szczęście węże układają się bardzo dobrze. Co najważniejsze, długość pętli węża 1 (70 instrukcji) jest wielokrotnością pętli węża 2 (7 instrukcji), więc obie nigdy się nie zsynchronizują:

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

Gdyby liczby nie wyszły tak idealnie, wybrałbym jednego lub oba węże spacjami, aby dopasować je w razie potrzeby.

Wszystko to bardzo dobrze, ale chcę to zobaczyć w akcji!

Oto powyższy program za pośrednictwem Stack Snippet. Nawet przy 1000 operacjach na sekundę potrzeba około 10 sekund, aby wypluć odpowiedź na przykładowe dane wejściowe - ale tak się dzieje!


2

JavaScript ES6, 71

Jako funkcja anonimowa

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 bajtów

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

Zmienia to $\(separator linii print, od którego zaczyna się fałsz) dla każdego alfanumerycznego ciągu, który jest kluczem skrótu %azdefiniowanego na początku. Zwiększa $\wartość skrótu, jeśli litera jest kluczem; w przeciwnym razie zwiększa wartość ujemną wartości skrótu, jeśli wielka litera jest kluczem; w przeciwnym razie nic nie dodaje.

Ogromne podziękowania dla primo za uratowanie mi ośmiu bajtów (w komentarzu do tej odpowiedzi).


Mogę zapisać kolejny bajt z inną sugestią od primo (dzięki!): Zmień $a{$_}||-$a{uc$_}na $a{$_}-$a{$"^$_}. Ale to chyba inna odpowiedź niż moja, więc nie wezmę za to „kredytu” (-1 bajtu).


1

Clojure / ClojureScript, 63 znaków

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

Napisany przy użyciu ClojureScript REPL, powinien być również prawidłowym Clojure. Wypróbuj tutaj . Wpisz go, a następnie zadzwoń, używając(*1 "FEN_string_here")

Całkiem proste. {"P"1..."q"-9}jest dosłowną strukturą danych dla mapy „P” na 1, „N” na 3 itd. mapprzyjmuje tę funkcję jako pierwszy argument, a strukturę danych jako drugą - w tym przypadku używa funkcji struktura danych (dosłowna mapa) może działać jako własna funkcja akcesora. Parametr ciągu ( %z makra funkcji) można traktować jako listę pojedynczych ciągów znaków. Każda postać, której nie ma na mapie, znajdzie się nilna liście wynikowej, co na +szczęście ignoruje.


1

Pyth, 25 bajtów

-Fmsmhy/4@S5%Ck12@Gd_rBz2

Demonstracja

Używa następującej formuły mapowania dla liter w pbnrq, jeśli kjest to litera:

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

Jest to reprezentowane w Pyth jako:

hy/4@S5%Ck12

Najpierw program tworzy wersję danych z zamienianą wielkością liter, a następnie na obu ciągach filtrów dla małych liter, następnie stosuje powyższą formułę, a następnie sumuje i odejmuje wartości czarne od wartości białych.


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()))
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.