Bewertung der Punktzahl anhand einer Schach-FEN-Saite


17

Herausforderung

Die Forsyth-Edwards-Notation (FEN) ist eine Standardnotation zur Beschreibung einer bestimmten Brettposition eines Schachspiels. Ihre Herausforderung besteht darin, die Punktzahl mit der FEN-Zeichenfolge zu bewerten. Dies ist ein Beispiel für eine FEN-Zeichenfolge:

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

Mit dieser Zeichenfolge können Sie die Materialbewertung für jede Farbe anhand der folgenden Bewertungstabelle berechnen:

  • p / P = Bauer = 1 Punkt
  • n / N = Ritter = 3 Punkte
  • b / B = Bischof = 3 Punkte
  • r / R = Turm = 5 Punkte
  • q / Q = Dame = 9 Punkte
  • k / K = König, diese haben keine Punkte, weil jede Rechtsposition einen König für jede Seite enthält

Weiße Teile werden mit Großbuchstaben ("PNBRQK") gekennzeichnet, während schwarze Teile mit Kleinbuchstaben ("pnbrqk") gekennzeichnet sind. Leere Quadrate werden mit den Ziffern 1 bis 8 (der Anzahl der leeren Quadrate) angegeben und durch "/" voneinander getrennt.

Aus dem Beispiel-FEN-String können wir die Materialbewertungen für jede Seite berechnen:

Für schwarz:

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

Alle schwarzen Teile übrig: p + p + p + p + r, das sind insgesamt 9

Für weiß:

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

Alle weißen Teile übrig: P + R + P + N + P + P + P, das sind insgesamt 13

Das Endergebnis wird mit der folgenden Formel ermittelt: Weißes Ergebnis - Schwarzes Ergebnis = Endergebnis . Für das Beispiel wäre das Endergebnis also: 13 - 9 = 4

Beispiel :

Eingang:

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

Ausgabe:

4

Hier gelten alle Regeln, die Lösung mit der geringsten Anzahl von Bytes gewinnt.


Wie poste ich

# Language Name, N bytes

 [code]

 [explaination, etc.]

3
Also spielt die aktuelle Position keine Rolle? Zählst du nur Buchstaben in der Zeichenfolge?
xnor

4
Nitpick: Das ist keine vollständige FEN-Saite. Außerdem gewinnt kr1NQQQQ / 2rNQQQQ / 3NQQQQ / 3NQQQQ / 3NQQQQ / 3NQQQQ / 3NQQQQ / K2NQQQQ, wenn sich Schwarz bewegt? : P
Türklinke

@xnor Ja, ich denke, wenn die Bewertung auch strategisch ist, wird es zu kompliziert. Sie können auch davon ausgehen, dass alle Eingaben Rechtspositionen sind, machen Sie sich also keine Sorgen.
Adnan

@Doorknob, ja, die Partitur basiert nur auf Material zur Vereinfachung
Adnan

Antworten:


3

CJam, 28 27 26 Bytes

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

Probieren Sie es online im CJam-Interpreter aus .

Wie es funktioniert

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 Bytes

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

(-7 Bytes mit Inspiration von @ El'endiaStarmans Antwort, -3 Bytes dank @randomra)

Erläuterung

Das Programm verwendet die Codebox als Nachschlagetabelle. Out-of-Range-Puts / Gets funktionieren nicht mit dem Online-Interpreter, daher funktioniert dies nur mit dem offiziellen Python-Interpreter.

In der ersten Zeile werden die Stücke gefolgt von den Stückwerten verschoben. Es drückt auch eine anfängliche 0, um die Gesamtsumme für die dritte Zeile abzulösen.

Die zweite Zeile setzt dann den entsprechenden positiven oder negativen Wert an die entsprechende Stückzelle, z. B. -1wird an ('p', 4)und 1platziert ('P', 4). Die Länge des Stapels wird überprüft, um sicherzustellen, dass die Schleife fünfmal ausgeführt wird.

Nachdem die Schleife beendet ist, besteht der Stapel aus unserer einzelnen Null aus der ersten Zeile. Für jedes Zeichen führen wir eine Suche in der entsprechenden Zelle in der Tabelle durch und addieren sie zu unserer Gesamtsumme. Standardmäßig sind nicht initialisierte Zellenwerte 0, was für unsere Zwecke perfekt ist.

Die letzte Zeile gibt lediglich das Ergebnis aus.


4

Rubin, 88 Zeichen

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

Das ist umständlich und hässlich, und es gibt wahrscheinlich einen besseren Weg, aber na ja.

Rubys {foo: 'bar'}Syntax ist eigentlich nur Zucker für {:foo => 'bar'}- das ist ärgerlich für Golf, weil ich den Schlüssel in ein Symbol umwandeln muss, bevor ich damit auf ein Hash-Element zugreifen kann ( :"#{x}"ist ein Zeichen kürzer als x.to_sym).


4

Pip, 39 Bytes

Ich werde kurz die Führung übernehmen, bevor die Antworten von CJam und Pyth folgen ...

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

Nimmt die FEN-Zeichenfolge als Befehlszeilenargument. Hier ist eine Erklärung für eine leicht ungolfederte Version:

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

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

Zählt man den Shebang als einen, wird die Eingabe von stdin übernommen.


Beispielnutzung

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

Erläuterung

Die Stücke werden mit ihren jeweiligen Werten transliteriert. Wenn das Stück groß geschrieben ist (dh kleiner als a), wird sein Wert zur Summe addiert, wenn nicht, wird er subtrahiert.


3

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

So kurz ich kann. Verwendet ein ausgefallenes Array-Verständnis, um die Zeichenfolge zu durchlaufen.

Erläuterung

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 Bytes

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

Probieren Sie es hier aus.

Vielen Dank an Sp3000 für den Hinweis auf eine effizientere Vorgehensweise!

Erläuterung

13359"QRBNP"mdrückt die Werte und ihre entsprechenden Zeichen, dann verschachtelt sie, so der Stapel sieht wie folgt aus : [1,80,3,78,3,66,5,82,9,81]. Dann 5[d3~c~$r48*+0p0p]setzt die Punktzahl der einzelnen Zeichen, sowohl Groß- und Kleinbuchstaben, an seiner Stelle im Code - Raum. Schließlich $I[o0q+]N.durchlaufen Sie die Eingabe, bis sie leer ist, und addieren die Ergebnisse nacheinander.



2

Ouroboros , 82

Ouroboros ist ein Esolang, den ich diese Woche entworfen habe. Zeit für eine Spritztour!

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

Jede Zeile von Einzelzeichenbefehlen 1 stellt eine Ouroboros-Schlange dar, bei der die Ausführung von Kopf (Anfang) bis Ende (Ende) erfolgt und zurück zum Kopf geschleift wird. Mit den Befehlen (und )können Sie einen Teil des Schwanzes essen oder wieder aufstoßen und so ändern, welche Befehle ausgeführt werden. Wird der Befehlszeiger jemals verschluckt, stirbt die Schlange (stoppt die Ausführung). Ein Ouroboros-Programm besteht aus einer oder mehreren Schlangen, die parallel ausgeführt werden. Jede Schlange hat einen eigenen Stapel, und es gibt auch einen gemeinsamen Stapel.

1 Eine Ausnahme, die Ouroboros von vielen 2D-Sprachen unterscheidet: Mehrstellige Zahlen können direkt geschrieben werden, ohne dass zuerst eine 0 eingegeben werden muss.

Schlange 1

Die erste Schlange liest ein Zeichen ( i) und prüft, ob es -1 / EOF ( .1+!) ist. Wenn ja, frisst es den größten Teil seines Schwanzes, bis einschließlich M( 57*().

Die Schlange tauscht dann den Zeichencode mit dem darüber liegenden Zählwert auf dem Stapel ( \) aus, verschiebt den Zählwert auf den gemeinsam genutzten Stapel ( m) und verschluckt ein anderes Zeichen ( 1(). Wenn es schon ein paar verschluckt hat, bedeutet dies, dass es das verschluckt (, was die IP gerade aktiviert hat und stirbt. Andernfalls wird die Ausführung fortgesetzt, indem die Strichliste zurück zum Stapel von Schlange 1 verschoben, mit dem Zeichencode ausgetauscht und das zuvor verschluckte Zeichen ( M\1)) wiederhergestellt wird .

Wir verwenden dann Mathematik- und Stapeloperationen, um die entsprechende Punktzahl für den Charakter zu erzeugen. .96>testet, ob es sich um Kleinbuchstaben handelt oder nicht; der nachfolgende 32*-konvertiert in Großbuchstaben. Dann die lange Strecke von .80=zu 81=9*++++Karten P-> 1, N-> 3, etc. Zum Schluss \2*1\-*negiert die Punktzahl, wenn der Buchstabe in Kleinbuchstaben geschrieben war, und +fügt sie der laufenden Liste hinzu. Die Schlange durchläuft dann eine Schleife und liest ein anderes Zeichen.

Schlange 2

Die zweite Schlange beginnt mit einer Regurgitate-Operation ( )), die beim ersten Mal nichts durchmacht (da noch nichts geschluckt wurde und auch seit dem Platzen einen leeren Stapel gibt 0). Als nächstes wird die Länge des gemeinsam genutzten Stapels auf seinen eigenen Stapel verschoben und logisch negiert ( L!). Dies gibt an, 1wenn der Stapel 0sonst leer ist . Die Schlange multipliziert mit 4 und frisst so viele Zeichen ( 4*().

Wenn der gemeinsam genutzte Stapel leer war, bedeutet dies, dass die Schlange jetzt vor dem endet S. Es schiebt 4und schleift zurück zu ), wo es die Zeichen, die es gerade geschluckt hat, wieder auffliegen lässt und von vorne beginnt.

Wenn sich jedoch ein Wert auf dem gemeinsam genutzten Stapel befand, werden keine Zeichen verschluckt und die Ausführung fortgesetzt. Die Schlange wechselt zum gemeinsamen Stapel und gibt dort die Nummer aus ( Sn); dann schluckt es seinen letzten Charakter und stirbt ( 1().

Synchronisation

Die beiden Schlangen müssen sorgfältig synchronisiert werden, damit auf dem gemeinsam genutzten Stapel kein Wert vorhanden ist, wenn Schlange 2 seine Prüfung durchführt, bis das Ende der Eingabe erreicht ist. Schlange 1 legt bei jedem Durchlauf durch die Schleife kurz einen Wert auf den gemeinsam genutzten Stapel. Daher Ldarf der Befehl von Schlange 2 niemals zwischen den Befehlen mund Min Schlange 1 ausgeführt werden. Glücklicherweise sind die Schlangen sehr gut ausgerichtet. Entscheidend ist, dass die Länge der Schleife von Schlange 1 (70 Anweisungen) ein Vielfaches der Schleife von Schlange 2 (7 Anweisungen) ist, sodass die beiden niemals aus der Synchronität geraten:

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

Wenn die Zahlen nicht so perfekt geklappt hätten, hätte ich eine oder beide Schlangen mit Leerzeichen aufgefüllt, um sie nach Bedarf auszurichten.

Das alles ist sehr gut, aber ich möchte es in Aktion sehen!

Hier ist das obige Programm über Stack Snippet. Selbst bei 1000 Vorgängen pro Sekunde dauert es ungefähr 10 Sekunden, bis die Antwort für die Probeneingabe ausgegeben wird - aber es kommt an!


2

JavaScript ES6, 71

Als anonyme Funktion

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 Bytes

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

Dies ändert $\(das Zeilentrennzeichen für print, das mit false beginnt) für jede alphanumerische Zeichenfolge, die ein Schlüssel des %aam Anfang definierten Hashs ist. Es wird $\um den Wert des Hash erhöht, wenn der Buchstabe wie er ist ein Schlüssel ist. Andernfalls wird der Wert des Hashwerts um einen negativen Wert erhöht, wenn der Großbuchstabe ein Schlüssel ist. sonst fügt es nichts hinzu.

Vielen Dank an primo, dass er mir acht Bytes gespart hat (in einem Kommentar zu dieser Antwort).


Ich kann ein weiteres Byte mit einem anderen Vorschlag von primo speichern (danke!): Ändere $a{$_}||-$a{uc$_}auf $a{$_}-$a{$"^$_}. Aber das ist eine etwas andere Antwort als meine, also nehme ich nicht die "Gutschrift" (von -1 Byte) dafür.


1

Clojure / ClojureScript, 63 Zeichen

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

Mit einem ClojureScript REPL geschrieben, sollte auch Clojure gültig sein. Probieren Sie es hier aus . Geben Sie es ein und rufen Sie es mit auf(*1 "FEN_string_here")

Ziemlich einfach. {"P"1..."q"-9}Ist ein Datenstrukturliteral für eine Zuordnung von "P" zu 1, "N" zu 3 usw. mapNimmt die Funktion als erstes Argument und die zu verarbeitende Datenstruktur als zweites - in diesem Fall wird die Funktion verwendet, die Eine Datenstruktur (das Kartenliteral) kann als eigene Accessorfunktion fungieren. Der Zeichenkettenparameter ( %aus dem Funktionsmakro) kann als Liste einzelner Zeichenketten behandelt werden. Alle Zeichen, die nicht in der Karte enthalten sind, werden wie nilin der Ergebnisliste aufgeführt, die +ignoriert wird.


1

Pyth, 25 Bytes

-Fmsmhy/4@S5%Ck12@Gd_rBz2

Demonstration

Dabei wird die folgende Zuordnungsformel für Buchstaben verwendet pbnrq, sofern kes sich um den Buchstaben handelt:

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

Dies wird in Pyth dargestellt als:

hy/4@S5%Ck12

Zuerst erstellt das Programm die in Groß- und Kleinschreibung getauschte Version der Eingabe, filtert dann nach Kleinbuchstaben in beiden Zeichenfolgen, wendet dann die obige Formel an und summiert und subtrahiert dann die Schwarzwerte von den Weißwerten.


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()))
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.