Forsyth-Edwards Notation文字列をASCIIアートに変換する


9

チェスでは、Forsyth-Edwards Notation(より一般的には「FEN」と呼ばれます)は、ボードを転写するテキストによる方法です。ホワイトの観点から、ボードの8つの列(チェスでは「ランク」と呼ばれます)を上から下に説明しています。ピースは、K(キング)、Q(クイーン)、R(ルーク)、B(ビショップ)、N(ナイト)、P(ポーン)と書かれています。黒い部分はこれらの文字を小文字で使用し、白い部分はこれらの文字を大文字で使用します。空のスペースは、連続する空のスペースの数を示す1〜8の数字で示されます。完全に空のランクは8、右端の列にある1つの黒いルーク(チェスでは「ファイル」と呼ばれます)になり7r、行の両端にある2つの白いポーンはになりますPP4PP。ランクは/。添加される他の情報は、移動キャスリングとすることでどちら側を示し、通常はありアンパッサン権利、移動の数、およびhalfmoveクロックが、我々はこの課題の目的のためにそれらを無視します。

入力

コマンドラインまたはSTDINからのFEN文字列。この文字列は常に有効であると想定できます。

出力

実際に表示されるボードの単純なASCIIアート表現をSTDOUTに書き込みます。

  • 作品はFENで彼らのキャラクターによって表されます
  • 空の正方形はスペースで表されます
  • ピースと正方形はパイプで区切られて|おり、ボードの両側にパイプがあります

したがって、8/8/8/8/8/8/8/8FENのように書かれた空のボードは、次のように表示されます。

| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |

チェスのゲームの開始位置はと書かれrnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR、次のように表示されます

|r|n|b|q|k|b|n|r|
|p|p|p|p|p|p|p|p|
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
|P|P|P|P|P|P|P|P|
|R|N|B|Q|K|B|N|R|

Anderssen-Kieseritzky 1851のチェスコミュニティでの「The Immortal Game」と呼ばれる最終的な位置はと記述されr1bk3r/p2pBpNp/n4n2/1p1NP2P/6P1/3P4/P1P1K3/q5b1、その入力が与えられると、プログラムは次のように出力します。

|r| |b|k| | | |r|
|p| | |p|B|p|N|p|
|n| | | | |n| | |
| |p| |N|P| | |P|
| | | | | | |P| |
| | | |P| | | | |
|P| |P| |K| | | |
|q| | | | | |b| |

STDOUTに書き込むのではなく、入力を取得して出力を返す関数を作成することはできますか?
モニカの訴訟に資金

@QPaysTaxesデフォルトでは許可されており、実際にいくつかのソリューションですでに許可されています。最終的にはOPに依存しますが、この場合、デフォルトをオーバーライドする必要はありません。
Alex A.

2
あなたが受け入れた答えは最短のものではありません。ゴルフ言語に対するあなたの気持ちに関係なく、コードゴルフは最短のコードが勝つことを意味します
Dennis

3
またそれらにペナルティを課したり、任意の回答を受け入れることもできません。サイト全体は客観的な勝利基準を中心に構築されています。
Dennis

1
+1興味深い挑戦のために。正当な理由なしに-2間違った答えを受け入れた
James

回答:


9

Perl、28バイト

+2を含む -lp

STDINに入力する

fen.pl <<< "r1bk3r/p2pBpNp/n4n2/1p1NP2P/6P1/3P4/P1P1K3/q5b1"

fen.pl

#!/usr/bin/perl -lp
s/\d/$"x$&/eg;s/|/|/g;y;/;

実際にはいくつかのゴルフ言語のリーグで...

ファイルベースのバージョンでは、実際に29バイトになるように、ファイルの最後の改行が必要であることに注意してください。ただし、コマンドラインバージョンでは余分な改行は必要ないため、コードは28バイトとしてカウントされます。

perl -lpe 's/\d/$"x$&/eg;s/|/|/g;y;/;' <<< "r1bk3r/p2pBpNp/n4n2/1p1NP2P/6P1/3P4/P1P1K3/q5b1"

1
シバンがありませんか?
user253751 2016

15

Retina、13バイト

\d
$* 
/
¶

|

オンラインでお試しください!

説明

最初の部分(末尾のスペースに注意):

\d
$* 

aを特定の数のスペースに変換することです。網膜には$*繰り返す機能があります。それが機能する方法は:<num>$*<char>がない場合<num>、Retinaは仮定します$&または一致した文字列(この場合は一致した番号)します。

次の部分:

/
¶

かなりシンプルで、すべて/をに置き換えます。

最後の部分も同じように機能します。

    
|

これにより、すべてが(したがって、最初の行に何もない)がに置き換えられます||どこにでも置く。


1
S`/2番目のステージと同じバイトカウントに対して、すべてASCIIで行うこともできます。
マーティンエンダー

12

Ruby- 75 82 78 76 75 62 59 58 57 56バイト

->n{"|#{n.gsub(/\d|
/){' '*$&.hex}.chars*?|}|".tr'/',$/}

Venteroのおかげで数バイトを節約

説明しましょう(\nリテラルの改行を置き換えて):

->n{"...".tr'/',$/}

これは暗黙的に文字列の値を返し、それぞれ/が改行で置き換えられます(デフォルトで$/は、改行が含まれます)

"|#{...}|"

これはとても簡単です。これは、パイプ、文字列補間、および別のパイプを含む単なる文字列です。文字列補間が評価されます

n.gsub(/\d|\n/){' '*$&.hex}...

これにより、すべての数値がその数のスペースに置き換えられます。ここで改行も見つけることで、数バイトを節約できます。なぜならhex0を返す文字列は、それは改行を見つける有効な数値でない場合-結果の終わりに、すなわち1gets -それは結果的に削除、長さ0の文字列に置き換えます。これがなければ、後続のパイプが存在します。

$&は、最新の変数一致の完全なテキストを表す魔法の変数です。これにより、を削除して1バイトを節約できます|d|。の.hex代わりにを使用して別のバイトを保存できます.to_i。これは、すべての数値が9未満であるため、16進数と10進数が同じ値であることを意味します。

.chars*?|

これは、すべてのキャラクターの間にパイプを置きます。これは、パイプを行のどちらかの側(最初と最後を除く)に配置するものであることに注意してくださいtr?|ただ手段「1文字の文字列"|"」。

以上です。それは率直にスキャンダラスに単純なプログラムです。それは、多くの卑劣な構文トリックを使用しています。


2
いくつかの簡単なトリックを適用することで、さらに4文字を保存できますputs"|#{gets.gsub(/\d|\n/){' '*$&.hex}.chars*?|}|".split'/'(もちろん、を\n再びリテラルの改行で置き換えます)。
Ventero

5

Pyth- 24 22 21バイト

.i*\|72jcu:G`H*Hd9z\/

テストスイート

+                     Concatenate
 K\|                  Store "|" in K and use value
+         K           Concatenate to end
 jK                   Join string by K, this puts "|" between each char
  :                   String substitution
        \/            Replace "/"
         b            With newline
   u                  Reduce
        9             Over [0, 9)
         z            With input as base case
    :G                String substitution current val
     `H               Replace stringifyed int from list we're looping through
     *Hd              With " "*that int


4

JavaScriptのES7、80の 70バイト

文字列を入力として受け入れる無名関数です。

a=>[,...[+t?" ".repeat(t):t<"0"?`
`:t for(t of a)].join``,`
`].join`|`

80バイトのES6のみのアプローチ。

a=>a.split`/`.map(x=>[,...x.replace(/\d/g,t=>" ".repeat(t)),`
`].join`|`).join``

説明

配列内包表記を使用して、リストをループします。

[+t?" ".repeat(t):t<"0"?`
`:t for(t of a)]

これは次と同等です。

[!isNaN(parseInt(t, 10)) ? " ".repeat(parseInt(t, 10)) : t === "/" ? "\n" : t for(t of a)]

数字の場合、その数のスペースがあります。であれば/、改行します。それ以外の場合は、キャラクターがあります。次に、理解を結合して文字列を作成します。

次に、長さ3の配列を作成します[,...that,"\n"]...結合された内包表記を文字にスプラットします。これに参加すると、結果が得られます。


ES6のことですか?ES7はまだリリースされていません。
ericw31415

@ ericw31415正確ではありませんが、一部のブラウザーはES7仕様の一部の実装を開始しています。
Conor O'Brien

ああ。しかし、それでもあなたのコードはES7の機能を使用していませんよね?
ericw31415

1
@ ericw31415実際にはそうです。配列内包表記([x for(x of a)])はES7です。
Conor O'Brien


3

ジュリア、62バイト

s->split("|"join(replace(s,r"\d",d->" "^parse(d)),"|")"|","/")

これは、文字列を受け取り、文字列の配列を返す無名関数です。これを呼び出すには、変数に割り当てます。

このアプローチは、QPaysTaxesの巧妙なRubyの回答と同じです。入力の各桁をその数のスペースに置き換え|、各文字の間に配置|し、表と裏に貼り付け、の配列に分割し/ます。

オンラインでお試しください!


イェーイインスピレーションを受けた:D
モニカの訴訟に資金を提供する

@QPaysTaxesあなたは確かにやった。素敵な解決策!
Alex A.


2

JavaScript(ES6)、69 67 62バイト

s=>[,...s.replace(/[/-8]/g,c=>+c?' '.repeat(c):`
`),,].join`|`

余分なコンマは、開始と終了を作成する外側の分割に空の値を作成します |文字。末尾のコンマはリストの最後では省略可能であるため、2つの末尾のコンマが必要です。最初のコンマは前のアイテムの一部です。

編集:@ user81655のおかげで5バイト節約されました。


うまくいくでしょう/[\d/]/g,c=>+c?` `.repeat(c):`\n`か?
user81655

1
@ user81655ありがとう、でも私はあなたの絵文字が気に入らなかったので、私はそれをメガネの付いたイライラした顔に置き換えました。
Neil、

1

Retina50 45バイト

楽しかったです。私はRetinaの初心者だけでなく、一般的な正規表現でもあります...これはおそらく多くのゴルフをすることができるので、さらに調査を行います。

コード:

8
44
7
34
6
42
5
 4
4
22
3
 2
2

1

/
¶

|

オンラインでお試しください!


$*機能を使用してみてください:)
Leaky Nun



1

C、252バイト

i=-1,j,s=1,x;C(char*n){while(n[++i])s+=isdigit(n[i])?n[i]*2+1:2;char*m=(char*)malloc(s);for(i=j=-1;n[++i]&(m[++j]='|');)if(n[i]=='/')m[++j]='\n';else if(isdigit(n[i]))for(x=n[i]-'0';x;--x&&(m[++j]='|'))m[++j]=' ';else m[++j]=n[i];m[++j]='\0';return m;}

詳細な オンライン試用

// input-string, input-string-size
char* C(char*n)
{
    int i=-1,j,s=1,x;

    // figure out required grid size
    while(n[++i])s+=isdigit(n[i])?n[i]*2+1:2;
    char*m=(char*)malloc(s);

    i=j=-1;
    while(n[++i]) // while not end of string
    {
        m[++j]='|'; // seperator

        if (n[i]=='/') // end of row
            m[++j]='\n';
        else if (isdigit(n[i])) // fill spaces
            for(x=n[i]-'0';x;--x&&(m[++j]='|')) m[++j]=' ';
        else
            m[++j]=n[i]; // single literals
    }

    m[++j]='|';
    m[++j]='\0';
    return m;
}

1

JavaScript(FireFox 30 +)、61

標準のEcmaScriptではない配列内包表記の使用

f=>'|'+[for(c of f)+c?' |'.repeat(c):c<'A'?`
|`:c+'|'].join``

テスト

F=f=>'|'+[for(c of f)+c?' |'.repeat(c):c<'A'?`\n|`:c+'|'].join``

console.log=x=>O.textContent+=x+'\n'

;['8/8/8/8/8/8/8/8','rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR',
'r1bk3r/p2pBpNp/n4n2/1p1NP2P/6P1/3P4/P1P1K3/q5b1']
.forEach(t=>console.log(F(t)+'\n'))
<pre id=O></pre>


1

Lua、106バイト

print("|"..(...):gsub(".",function(c)return c:find("%d")and(" |"):rep(c)or c=="/"and"\n|"or c.."|"end),'')

未ゴルフ

print("|"..                   -- prepend | to the following string
  (...):gsub(".",function(c)  -- iterate over each character in the argument
    return                    -- replaces in the argument
           c:find("%d")       -- if c is a number
             and(" |"):rep(c) --   replace by " |"*c
           or c=="/"          -- elseif c is a slash
             and"\n|"         -- replace by "\n|"
           or c.."|"          -- else (case letter)replace by c
  end)                        -- return the modified string
,'')                          -- add an empty parameter to print
                              -- it suppresses the second output of gsub

print((...):gsub(".",function(c)return(c:find("%d")and("| "):rep(c)or c=="/"and"|\n"or"|"..c)end).."|")
Leaky Nun

print((...):gsub("%d",function(c)return("| "):rep(c)end):gsub("/","|\n"):gsub("([^%d%s|])","|%1").."|")同じバイト数の場合。
Leaky Nun

print((...):gsub("%d",function(c)return("| "):rep(c)end):gsub("([^%d |])","|%1"):gsub("/","\n").."|")101バイトである
漏洩ヌン

1

R(競合外)

これを投稿するのが適切ではない場合は申し訳ありませんが、編集せずにこの質問に対して実際に機能する関数がたまたまあるだけだったのはクールだと思いました!ただし、ASCIIではなくUnicode出力を出力します。なぜ書いたのかはよくわかりませんが、チャレンジに答えることではありませんでした。

function(x){
# x = FEN position, a string
# can be split with / or ,
# example: forsythe("rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R")

allowed <- c(paste(1:64), 
c("k", "q", "r", "b", "n", "p", "K", "Q", "R", "B", "N", "P"))
chars <- strsplit(x, "")[[1]]
chars <- chars[-which(!(chars %in% allowed))]
out <- c()
for (i in 1:length(chars)){
  if (chars[i] %in% paste(1:64)){
    out <- c(out, rep(" ", as.numeric(chars[i])))
  }
  else{
    out <- c(out, chars[i])
  }
}
if (length(out) < 64) out <- c(out, rep(" ", 64-length(out)))

pieces <- strsplit("KQRBNPkqrbnp", "")[[1]]
unicode <- c("\u2654", "\u2655", "\u2656", 
"\u2657", "\u2658", "\u2659", "\u265A", "\u265B", 
"\u265C", "\u265D", "\u265E", "\u265F")

for (i in 1:64){
  if (out[i] %in% pieces){
    out[i] <- unicode[which(pieces==out[i])]
  }
  else{
  }
}
out <- matrix(out, nc=8, byrow=T)
#print(out)

plot(0, xlim=c(0, 8), ylim=c(0, 8), type="n", xaxt="n", yaxt="n",
xlab="", ylab="")
for (i in 0:7){ for (j in 0:7){ rect(i, j, i+1, j+1,
col=ifelse(((i+j) %% 2) == 0, grey(0.95), "white"), border=F) }}

for (i in 0:7){ for (j in 0:7){
  text(i+0.5, j+0.5, out[8-j, i+1], cex=2)  
}}

axis(1, labels=letters[1:8], at=1:8 - 0.5, tick=F)
axis(2, labels=paste(1:8), at=1:8-0.5, las=2, tick=F)

}

ヘルプセンターで概説されているルールでは、課題に対するすべてのソリューションは、使用されている勝利基準の深刻な候補である必要があると述べています。コードゴルフの場合、これはすべての答えがゴルフでなければならないことを意味します。
Dennis

技術的にはゴルフです。あまりよくない。
ヒラメ

0

Haskell、110バイト

p '/'="\n"
p c|'1'<=c&&c<='8'=replicate(read[c])' '
p c=[c]
main=getLine>>=putStrLn.('|':).(>>=(:"|")).(>>=p)

非ゴルフ:

p c | c=='/'           = "\n"
    | '1'<=c && c<='8' = replicate (read [c]) ' '
    | otherwise        = [c]
addPipes string = "|" ++ concatMap (\c -> [c] ++ "|") string
main = getLine >>= putStrLn . addPipes . concatMap p

0

Javaの7、190の 184バイト

String Z(int c){String m="";if(c==47)m+="|\n";else if(c>57)m+="|"+c;else while(c-->48)m+="| ";return m;}String C(String n){String m="";for(char x:n.toCharArray())m+=Z(x);return m+"|";}

詳細な オンライン試用

public static String Z(char c)
{
    String m="";
    if(c=='/')m+="|\n";
    else if(c>'9')m+="|"+c;
    else while(c-->'0')m+="| ";
    return m;
}

public static String C(String n)
{
    String m="";
    for(char x:n.toCharArray())m+=Z(x);
    return m+"|";
}

比較でcharリテラルの代わりに整数を使用すると、数バイトを節約できます
Blue

@Blueノートが取られた
Khaled.K

0

Pyke、25 20バイト

FD~u{RIbd*(s\/n:k\|:

説明:

F         (          -    for char in input:
 D~u{RI              -     if char in '0123456789': 
       bd*           -      char = " "*int(char)
           s         -   sum(^)
            \/n:     -  ^.replace("/","\n")
                k\|: - ^.replace("", "|")

ここでお試しください!


0

Python、84バイト

lambda a:"".join(c*c.isalpha()or"\n"*(c=="/")or" "*int(c)for c in a).replace("","|")

説明:

        c*c.isalpha()                                                       - if c is alphabetical, use c
                       "\n"*(c=="/")                                        - if it's "|", replace it with a newline
                                      " "*int(c)                            - else its an int.
"".join(                                                  ).replace("","|") - interweave "|" between the chars

0

> <>、64バイト

<v?(0:i
r\
"<o-*=@"%/":   v?*(@)@":/"::;?(0:o"|
 ^~?="0":-1o" "<

アライメントの問題により4バイトが無駄になりましたが、どのようにゴルフをするのかわかりません。¯\ _(ツ)_ /¯

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