Forsyth-Edwards 표기법 문자열을 ASCII 아트로 변환


9

체스에서 더 일반적으로 "FEN"이라고하는 Forsyth-Edwards Notation 은 텍스트를 작성하는 보드 방식입니다. 화이트의 관점에서 보드의 8 개 행 (체스에서 "랭크"라고 함)을 위에서 아래로 설명합니다. 조각은 K (킹), Q (퀸), R (루크), B (주교), N (기사) 및 P (폰)로 작성됩니다. 검은 색 조각은이 문자를 소문자로 사용하고 흰색 조각은이 문자를 대문자로 사용합니다. 빈 공간은 연속 된 빈 공간이 몇 개인지를 나타내는 1에서 8까지의 숫자로 표시됩니다. 완전히 비어있는 순위는 맨 8오른쪽 열의 검은 색 루크 (체스에서 "파일"이라고 함)가되며 7r행의 양쪽 끝에있는 두 개의 흰색 폰이됩니다 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 의 최종 위치 는로 기록되어 있으며 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

펄, 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
Shebang이 없습니까?
user253751

15

레티 나, 13 바이트

\d
$* 
/
¶

|

온라인으로 사용해보십시오!

설명

첫 번째 부분 (후행 공백 참고) :

\d
$* 

를 특정 수의 공백으로 변환하는 것입니다. Retina에는 $*반복 기능이 있습니다. 작동 방식은 다음과 같습니다. <num>$*<char>이 없으면 <num>Retina는 $&일치하는 문자열 또는이 경우 일치하는 숫자를 가정합니다.

다음 부분 :

/
¶

이 모든 대체, 아주 간단 /함께 있는이 줄 바꿈이다.

마지막 부분은 동일하게 작동합니다.

    
|

이것은 모든 것을 대체합니다 (따라서 첫 번째 줄에 아무것도없는 이유) |. |사방에 퍼팅 .


1
S`/두 번째 단계 와 동일한 바이트 수에 대해 ASCII로 모든 작업을 수행 할 수도 있습니다 .
Martin Ender

12

루비 -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}...

이것은 모든 숫자를 그 많은 공백으로 바꿉니다. 여기서 줄 바꿈을 찾아서 몇 바이트를 절약 할 수 있습니다. hex문자열이 유효한 숫자가 아닌 경우 0을 반환 하기 때문에 개행 (즉, 결과의 끝에있는 행)을 찾으면 gets이를 0 길이 문자열로 대체하여 효과적으로 삭제합니다. 이것이 없으면 후행 파이프가있을 것입니다.

$&은 최신 변수 일치의 전체 텍스트를 나타내는 마술 변수이므로을 제거하여 바이트를 저장할 수 있습니다 |d|. 모든 숫자가 9보다 작기 때문에 작동하는 16 진수 .hex대신 다른 바이트를 저장할 수 있습니다 .to_i. 이는 16 진수와 10 진수가 동일한 값을 갖음을 의미합니다.

.chars*?|

이것은 모든 캐릭터 사이에 파이프를 배치합니다. 이것은 슬래시가 결국 개행으로 바뀌고 문자 tr로 계산되므로 파이프로 둘러싸여 있기 때문에 파이프를 줄의 양쪽에 배치하는 것입니다 (첫 번째와 마지막 제외) . ?|단지 수단 "한 - 문자열 "|"".

그리고 그게 다야. 솔직히 말해서 간단한 프로그램입니다. 그것은 단지 많은 비열한 구문 트릭을 사용합니다.


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

Pyth, 23 바이트

VT=:Q`N*dN;jc.i*\|72Q\/

온라인으로 사용해보십시오!

작동 방식 :

VT=:Q`N*dN;jc.i*\|72Q\/
VT        ;                for N in range(10):
  =:Q`N*dN                     Q = Q.replace(`N`,repeat(' ',N))
             .i*\|72Q      temp = interweave(repeat('|',72), Q)
            c        \/    temp = chop(temp,'/')
           j               temp = join(temp,'\n')
                           print temp

4

자바 스크립트 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
사실은 그렇습니다. 배열 이해 ( [x for(x of a)])는 ES7입니다.
Conor O'Brien

사양에서 제거되지 배열 함축이 있었, MDN은 그들이 있었다 말한다
MayorMonty

3

줄리아, 62 바이트

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

이것은 문자열을 받아들이고 문자열 배열을 반환하는 익명 함수입니다. 호출하려면 변수에 지정하십시오.

이 접근 방식은 QPaysTaxes의 영리한 Ruby 답변 과 동일 합니다. 입력의 각 숫자를 많은 공백으로 바꾸고, |각 문자 사이를 배치 |하고, 앞뒤로 고정 하고에 배열로 분할합니다 /.

온라인으로 사용해보십시오!


예, 저는 영감을 받았습니다 : D
Fund Monica의 소송

@QPaysTaxes 당신은 정말로했다. 좋은 해결책!
Alex A.


2

자바 스크립트 (ES6), 69 67 62 바이트

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

여분의 쉼표는 외부 분할에 빈 값을 만들어 시작 및 끝 |문자 를 만듭니다 . 후미 쉼표는 목록 끝에서 선택 사항이므로 첫 번째는 여전히 이전 항목의 일부이므로 두 개의 후행 쉼표가 필요합니다.

편집 : @ user81655 덕분에 5 바이트가 절약되었습니다.


시겠습니까 /[\d/]/g,c=>+c?` `.repeat(c):`\n`일?
user81655

1
@ user81655 감사합니다.하지만 이모티콘이 마음에 들지 않아서 안경을 쓴 얼굴로 바 꾸었습니다.
Neil

1

망막 , 50 45 바이트

재미있었습니다. 나는 레티 나뿐만 아니라 일반적으로 정규 표현식에서도 멍청한 놈일 것입니다. 아마 골프를 많이 할 수 있으므로 더 많은 연구를 할 것입니다.

암호:

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

자바 스크립트 (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

루아, 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 바이트입니다
Leaky Nun

1

R (경쟁에서)

이것을 게시하는 것이 적절하지 않다면 미안하지만 실제로 편집하지 않고이 질문에 대해 작동하는 함수를 가지고있는 것이 멋지다고 생각했습니다! 그러나 ascii가 아닌 유니 코드 출력을 인쇄합니다. 나는 왜 그것을 썼는지 기억이 나지 않지만 도전에 대답하는 것은 아닙니다.

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

엄밀히 말하면 골프입니다. 아주 잘하지 않습니다.
Flounderer

0

하스켈, 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

자바 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

파이크, 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

파이썬, 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.