Chuyển đổi chuỗi ký hiệu Forsyth-Edwards sang nghệ thuật ASCII


9

Trong cờ vua, Ký hiệu Forsyth-Edwards , thường được gọi là "FEN", là một cách viết văn bản của bảng. Nó mô tả tám hàng của mỗi bảng (được gọi là "hàng ngũ" trong cờ vua) từ trên xuống dưới theo quan điểm của White. Các mảnh được viết là K (vua), Q (nữ hoàng), R (rook), B (giám mục), N (hiệp sĩ), và P (cầm đồ). Các mảnh màu đen sử dụng các chữ cái này bằng chữ thường và các mảnh màu trắng sử dụng các chữ cái này bằng chữ in hoa. Các khoảng trống được biểu thị bằng một số từ 1 đến 8 cho biết có bao nhiêu khoảng trống liên tiếp. Một thứ hạng hoàn toàn trống sẽ là 8, một người da đen duy nhất ở cột ngoài cùng bên phải (được gọi là "tập tin" trong cờ vua) sẽ là 7rhai con cờ trắng ở mỗi đầu của một hàng PP4PP. Các hàng được phân cách bằng một/. Thông thường có các thông tin khác được thêm vào, cho biết bên nào sẽ di chuyển, đúc và quyền người qua đường , số di chuyển và đồng hồ nửa chừng, nhưng chúng tôi sẽ bỏ qua chúng cho mục đích của thách thức này.

Đầu vào

Một chuỗi FEN, từ dòng lệnh hoặc STDIN, như bạn muốn. Bạn có thể cho rằng chuỗi này luôn hợp lệ.

Đầu ra

Viết cho STDOUT một đại diện nghệ thuật ASCII đơn giản của bảng như nó thực sự sẽ xuất hiện:

  • Các mảnh được đại diện bởi nhân vật của họ trong FEN
  • Hình vuông trống được thể hiện bằng khoảng trắng
  • Các mảnh và hình vuông được phân tách bằng một đường ống |và có các đường ống ở mỗi bên của bảng

Vì vậy, một bảng trống, được viết như 8/8/8/8/8/8/8/8trong FEN, sẽ xuất hiện dưới dạng

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

Vị trí bắt đầu của một ván cờ được viết là rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR, và sẽ xuất hiện dưới dạng

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

Vị trí cuối cùng của Anderssen-Kieseritzky 1851 , được gọi là "Trò chơi bất tử" trong cộng đồng cờ vua, được viết dưới dạng r1bk3r/p2pBpNp/n4n2/1p1NP2P/6P1/3P4/P1P1K3/q5b1và chương trình của bạn khi được cung cấp đầu vào đó sẽ xuất ra:

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

Có thể chấp nhận viết một hàm lấy đầu vào và trả về đầu ra, thay vì ghi nó vào STDOUT?
Vụ kiện của Quỹ Monica

@QPaysTaxes Theo mặc định, chúng tôi cho phép nó và thực sự một số giải pháp đã làm điều đó rồi. Cuối cùng, tùy thuộc vào OP mặc dù có vẻ không cần thiết phải ghi đè mặc định của chúng tôi trong trường hợp này.
Alex A.

2
Câu trả lời bạn chấp nhận không phải là câu trả lời ngắn nhất. Bất kể cảm xúc của bạn đối với ngôn ngữ chơi gôn, mã golf có nghĩa là mã ngắn nhất sẽ thắng.
Dennis

3
Bạn cũng không thể phạt họ hoặc chấp nhận một câu trả lời tùy tiện . Toàn bộ trang web được xây dựng xung quanh các tiêu chí chiến thắng khách quan .
Dennis

1
+1cho một thử thách thú vị. -2vì đã chấp nhận câu trả lời sai mà không có lý do chính đáng
James

Câu trả lời:


9

Perl, 28 byte

Bao gồm +2 cho -lp

Cung cấp đầu vào trên STDIN

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

fen.pl:

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

Trên thực tế trong liên minh của một số ngôn ngữ chơi gôn ...

Lưu ý rằng phiên bản dựa trên tệp cần dòng mới cuối cùng trong tệp để một tệp thực sự là 29 byte. Nhưng phiên bản dòng lệnh không cần thêm dòng mới đó và do đó mã được tính là 28 byte:

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

1
Thiếu shebang?
dùng253751

15

Võng mạc, 13 byte

\d
$* 
/
¶

|

Hãy thử trực tuyến!

Giải trình

Phần đầu tiên (lưu ý không gian dấu):

\d
$* 

là để chuyển đổi một số lượng không gian cụ thể. Retina có một $*tính năng để lặp lại. Cách thức hoạt động là: <num>$*<char>nếu không có <num>, Retina sẽ giả sử $&hoặc chuỗi khớp, trong trường hợp này là số khớp.

Phần tiếp theo:

/
¶

là khá đơn giản, nó thay thế tất cả /với một dòng mới.

Phần cuối cùng hoạt động như nhau:

    
|

Điều này sẽ thay thế mọi thứ (do đó tại sao không có gì trên dòng đầu tiên) với |. Đặt một |nơi.


1
Bạn thậm chí có thể làm tất cả trong ASCII cho cùng một số byte với S`/giai đoạn thứ hai.
Martin Ender

12

Ruby - 75 82 78 76 75 62 59 58 57 56 byte

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

Đã lưu một vài byte nhờ Ventero

Hãy để tôi giải thích (với việc \nthay thế dòng mới theo nghĩa đen):

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

Điều này ngầm trả về giá trị của chuỗi, với mỗi chuỗi được /thay thế bằng một dòng mới (theo mặc định, $/chứa một dòng mới)

"|#{...}|"

Điều này là siêu đơn giản; nó chỉ là một chuỗi chứa một đường ống, nội suy chuỗi và một đường ống khác. Nội suy chuỗi được đánh giá

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

Điều này thay thế mọi số với nhiều không gian. Tôi có thể lưu một vài byte bằng cách tìm dòng mới ở đây; bởi vì hextrả về 0 nếu chuỗi không phải là số hợp lệ, khi nó tìm thấy một dòng mới - tức là chuỗi ở cuối kết quả của gets- nó thay thế nó bằng chuỗi có độ dài 0, xóa nó một cách hiệu quả. Không có điều này, sẽ có một đường ống.

$&là một biến ma thuật đại diện cho văn bản hoàn chỉnh của biến khớp mới nhất, cho phép tôi lưu một byte bằng cách loại bỏ |d|. Tôi có thể lưu một byte khác bằng cách sử dụng .hexthay vì .to_i, hoạt động vì mọi số nhỏ hơn 9, có nghĩa là hex và thập phân có cùng giá trị.

.chars*?|

Điều này đặt một đường ống giữa mỗi nhân vật. Lưu ý rằng đây là những gì đặt các đường ống ở hai bên của dòng (ngoại trừ đầu tiên và cuối cùng) bởi vì các dấu gạch chéo, cuối cùng chuyển thành dòng mới tr, được tính là ký tự và do đó được bao quanh bởi các đường ống. Các ?|chỉ có nghĩa là "chuỗi một nhân vật "|"".

Và ... đó là nó. Đó là một chương trình đơn giản một cách thẳng thắn. Nó chỉ sử dụng rất nhiều thủ thuật cú pháp lén lút.


2
Bạn có thể lưu thêm 4 ký tự bằng cách áp dụng một vài thủ thuật đơn giản: puts"|#{gets.gsub(/\d|\n/){' '*$&.hex}.chars*?|}|".split'/'(tất nhiên, thay thế \nbằng một dòng mới theo nghĩa đen một lần nữa).
Ventero

5

Pyth - 24 22 21 byte

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

Phòng thử nghiệm .

+                     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

Bình thường, 23 byte

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

Hãy thử trực tuyến!

Làm thế nào nó hoạt động:

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

JavaScript ES7, 80 70 byte

Là một hàm ẩn danh chấp nhận một chuỗi làm đầu vào.

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

Thẩm định chỉ ES6 80 byte.

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

Giải trình

Chúng tôi sử dụng một sự hiểu biết mảng để lặp qua danh sách:

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

Điều này tương đương với:

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

Nếu đó là một số, chúng ta có số lượng không gian đó. Nếu đó là một /, chúng tôi có một dòng mới. Nếu không, chúng ta có nhân vật. Sau đó, chúng tôi tham gia hiểu không có gì để tạo ra một chuỗi.

Sau đó, chúng tôi tạo ra một mảng có chiều dài 3 [,...that,"\n"]. ...splats sự hiểu biết tham gia vào ký tự. Tham gia này mang lại kết quả.


Ý bạn là ES6? ES7 vẫn chưa ra mắt.
ericw31415

@ ericw31415 Không phải vậy, bạn đã đúng, nhưng một số trình duyệt đã bắt đầu triển khai một phần của thông số ES7.
Conor O'Brien

Ồ được thôi. Nhưng mã của bạn vẫn không sử dụng bất kỳ tính năng ES7 nào, phải không?
ericw31415

1
@ ericw31415 Thật ra thì có. [x for(x of a)]Hiểu mảng ( ) là ES7.
Conor O'Brien

Không hiểu mảng đã bị xóa khỏi thông số kỹ thuật, MDN nói rằng chúng là
MayorMonty

3

Julia, 62 byte

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

Đây là một hàm ẩn danh chấp nhận một chuỗi và trả về một chuỗi các chuỗi. Để gọi nó, gán nó cho một biến.

Cách tiếp cận giống như trong câu trả lời Ruby thông minh của QPaysTaxes . Chúng tôi thay thế từng chữ số trong đầu vào bằng nhiều khoảng trắng, đặt |giữa mỗi ký tự, |giải quyết ở mặt trước và mặt sau và chia thành một mảng trên đó /.

Hãy thử trực tuyến!


Yay tôi đã truyền cảm hứng cho mọi thứ: D
Vụ kiện của Quỹ Monica

@QPaysTaxes Bạn thực sự đã làm. Giải pháp tốt đẹp!
Alex A.


2

JavaScript (ES6), 69 67 62 byte

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

Dấu phẩy phụ tạo ra các giá trị trống trong phần tách ngoài tạo ra các |ký tự bắt đầu và kết thúc . Bạn cần hai dấu phẩy kéo dài vì dấu phẩy dấu là tùy chọn ở cuối danh sách, vì vậy dấu phẩy đầu tiên vẫn là một phần của mục trước.

Chỉnh sửa: Đã lưu 5 byte nhờ @ user81655.


Sẽ /[\d/]/g,c=>+c?` `.repeat(c):`\n`làm việc?
dùng81655

1
@ user81655 Cảm ơn, nhưng tôi không thích biểu tượng cảm xúc của bạn, vì vậy tôi đã thay thế nó bằng một khuôn mặt khó chịu bằng kính.
Neil

1

Võng mạc , 50 45 byte

Đây là niềm vui haha. Tôi không chỉ là một người mới ở Retina, mà còn trong regex nói chung ... Điều này có thể có thể được đánh gôn rất nhiều , vì vậy tôi sẽ nghiên cứu thêm.

Mã số:

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

1

/
¶

|

Hãy thử trực tuyến!


Hãy thử sử dụng $*chức năng :)
Leaky Nun



1

C, 252 byte

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;}

Thử chi tiết trực tuyến

// 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

Sử dụng hiểu mảng không còn là tiêu chuẩn EcmaScript nữa

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

Kiểm tra

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 byte

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

Ung dung

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).."|")
Rò rỉ Nun

print((...):gsub("%d",function(c)return("| "):rep(c)end):gsub("/","|\n"):gsub("([^%d%s|])","|%1").."|")cho cùng một số đếm byte.
Nữ tu bị rò rỉ

print((...):gsub("%d",function(c)return("| "):rep(c)end):gsub("([^%d |])","|%1"):gsub("/","\n").."|")là 101 byte
Leaky Nun

1

R (không thi đấu)

Xin lỗi nếu không thích hợp để đăng bài này, nhưng tôi nghĩ thật tuyệt khi tôi tình cờ có một chức năng nằm xung quanh thực sự hoạt động cho câu hỏi này mà không cần chỉnh sửa! Nó in đầu ra unicode chứ không phải ascii, mặc dù. Tôi không thể nhớ rõ tại sao tôi viết nó, nhưng nó không phải là để trả lời một thách thức.

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)

}

Các quy tắc được nêu trong trung tâm trợ giúp của chúng tôi nêu rõ rằng tất cả các giải pháp cho các thách thức phải là một ứng cử viên nghiêm trọng cho các tiêu chí chiến thắng được sử dụng. Đối với mã golf, điều này có nghĩa là tất cả các câu trả lời phải được đánh gôn.
Dennis

Về mặt kỹ thuật, nó là golf. Chỉ là không tốt lắm.
Flounderer

0

Haskell, 110 byte

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

Ung dung:

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 byte

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+"|";}

Thử chi tiết trực tuyến

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+"|";
}

Bạn có thể lưu một vài byte bằng cách sử dụng số nguyên thay vì ký tự char trong các phép so sánh
Blue

@Blue ghi chú
Khaled.K


0

Python, 84 byte

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

Giải trình:

        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 byte

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

4 byte bị lãng phí do các vấn đề liên kết, mặc dù không biết làm thế nào để loại bỏ chúng. ¯ \ _ (ツ) _ /

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.