Codegolf — Преобразовать Строку Нотации Форсайта-Эдвардса В Формат Ascii.

  • Автор темы Makit
  • Обновлено
  • 23, Oct 2024
  • #1

В шахматах нотация Форсайта-Эдвардса, чаще называемая «FEN», представляет собой текстовый способ расшифровки доски. Он описывает каждый из восьми рядов доски (в шахматах называемых «рангами») сверху вниз с точки зрения белых. Фигуры записываются как K (король), Q (ферзь), R (ладья), B (слон), N (конь) и P (пешка). Черные фигуры используют эти буквы в нижнем регистре, а белые фигуры используют эти буквы в верхнем регистре. Пустые места обозначаются цифрами от 1 до 8, указывающими количество последовательных пустых мест. Совершенно пустой ранг был бы

 
 
 |r| |b|k| | | |r|
|p| | |p|B|p|N|p|
|n| | | | |n| | |
| |p| |N|P| | |P|
| | | | | | |P| |
| | | |P| | | | |
|P| |P| |K| | | |
|q| | | | | |b| |
 
, a single black rook in the rightmost column (called "files" in chess) would be r1bk3r/p2pBpNp/n4n2/1p1NP2P/6P1/3P4/P1P1K3/q5b1 , и две белые пешки на каждом конце ряда будут |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| . Ranks are separated by a rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR . Обычно добавляется другая информация, указывающая, на какую сторону следует двигаться, рокировку и на проходе права, номер хода и часы полухода, но мы проигнорируем их для целей этой задачи.

Вход

Строка FEN из командной строки или STDIN, как вам будет угодно. Вы можете предположить, что эта строка всегда действительна.

Выход

Напишите в STDOUT простое ASCII-изображение платы, как она выглядит на самом деле:

  • Фигуры представлены в FEN своим характером.
  • Пустые квадраты представлены пробелами
  • Фигуры и квадраты разделены трубой. | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | and there are pipes on each side of the board

Итак, пустая доска, написанная как 8/8/8/8/8/8/8/8 in FEN, would appear as

|

Начальная позиция шахматной партии записывается как / , and would appear as

PP4PP

Окончательное положение Андерсен-Кизерицкий 1851 г., называемая в шахматном сообществе «Бессмертной игрой», записывается как 7r , and your program when fed that input would output:

8

#код-гольф #строка #ascii-art #chess

Makit


Рег
01 Oct, 2015

Тем
71

Постов
198

Баллов
563
  • 26, Oct 2024
  • #2

Ретина, 13 байт

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
|

Попробуйте онлайн!

Объяснение

Первая часть (обратите внимание на пробел в конце):

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

^~?="0":-1o" "<
 

заключается в преобразовании a в определенное количество пробелов. сетчатка имеет 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 feature to repeat. The way it works is: lambda a:"".join(c*c.isalpha()or"\n"*(c=="/")or" "*int(c)for c in a).replace("","|") если нет F ( - for char in input: D~u{RI - if char in '0123456789': bd* - char = " "*int(char) s - sum(^) \/n: - ^.replace("/","\n") k\|: - ^.replace("", "|") , Retina will assume FD~u{RIbd*(s\/n:k\|: или совпавшая строка, в данном случае совпавший номер.

Следующая часть:

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

довольно просто, он заменяет все 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+"|";} with 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 что является новой строкой.

Последняя часть работает так же:

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

Это заменит все (следовательно, в первой строке ничего нет) на 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) } . Putting a 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 повсюду.

 

GuessWho


Рег
08 Dec, 2017

Тем
74

Постов
204

Баллов
604
  • 26, Oct 2024
  • #3

Рубин — 75 82 78 76 75 62 59 58 57 56 байт

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

Сэкономлено несколько байт благодаря Вентеро.

Поясню (с. <pre id=O></pre> replacing the literal newline):

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

Это неявно возвращает значение строки, причем каждое f=>'|'+[for(c of f)+c?' |'.repeat(c):c<'A'?` |`:c+'|'].join`` replaced with a newline (by default, // 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; } содержит новую строку)

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

Это очень просто; это просто строка, содержащая канал, интерполяцию строки и еще один канал. Строковая интерполяция оценивается

def r(o):print(''.join(['| '*8if h=='8'else'| '*int(h)if h.isdigit()else'|\n'if h=='/'else'|'+h for h in o])+'|')

Это заменяет каждое число таким количеством пробелов. Я могу сэкономить несколько байтов, найдя здесь переводы строк; потому что \x05 returns 0 if the string isn't a valid number, when it finds a newline –- i.e. the one at the end of the result of -- он заменяет ее строкой нулевой длины, фактически удаляя ее. Без этого была бы висячая труба.

RΜGi'/dΆγ'|RGρH«\d»d*♣PHEγγS is a magic variable which represents the complete text of the latest variable match, which lets me save a byte by eliminating 8 44 7 34 6 42 5 4 4 22 3 2 2 1 / ¶ | . Я могу сохранить еще один байт, используя | instead of s=>[,...s.replace(/[/-8]/g,c=>+c?' '.repeat(c):` `),,].join`|` , что работает, поскольку каждое число меньше 9, а это означает, что шестнадцатеричное и десятичное число имеют одинаковые значения.

'|¹9GNNð×:}S'|«JJ'/¶:

Это помещает трубу между каждым символом. Обратите внимание, что это то, что помещает трубы по обе стороны от строк (кроме первой и последней), потому что косые черты, которые в конечном итоге превращаются в символы новой строки через 9GNNð×:}S'|ý"|ÿ|"'/¶: , count as characters, and are therefore surrounded by pipes. The / просто означает «строка из одного символа | ".

И... всё. Это откровенно скандально простая программа. Он просто использует множество хитрых синтаксических уловок.

 

Nobody.gu3st


Рег
13 Feb, 2014

Тем
72

Постов
191

Баллов
551
  • 26, Oct 2024
  • #4

Перл, 28 байт

Включает +2 за |

Введите данные по STDIN

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

... :

[,...that,"\n"]

На самом деле в лиге некоторых гольф-языков...

Обратите внимание, что файловой версии требуется последняя новая строка в файле, чтобы она действительно составляла 29 байт. Но версия для командной строки не требует дополнительной новой строки, поэтому код занимает 28 байт:

/ ||answer||

Пиф — 24 22 21 байт

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

Тестовый набор.

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

Пиф, 23 байта

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

Попробуйте онлайн!

Как это работает:

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

JavaScript ES7, 80 70 байт

Анонимная функция, принимающая на вход строку.

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

80-байтовый подход только для ES6.

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

Объяснение

Мы используем понимание массива для перебора списка:

+ 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

Это эквивалентно:

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

Если это число, у нас есть такое количество пробелов. Если это perl -lpe 's/\d/$"x$&/eg;s/|/|/g;y;/;' <<< "r1bk3r/p2pBpNp/n4n2/1p1NP2P/6P1/3P4/P1P1K3/q5b1" , we have a newline. Otherwise, we have the character. Then, we join the comprehension with nothing to make a string.

Затем мы создаем массив длиной 3 #!/usr/bin/perl -lp s/\d/$"x$&/eg;s/|/|/g;y;/; . fen.pl разбивает объединенное понимание на символы. Присоединение к этому дает результат.

 

Doshka


Рег
19 Apr, 2010

Тем
88

Постов
168

Баллов
618
  • 26, Oct 2024
  • #5

Юля, 62 байта

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

Это анонимная функция, которая принимает строку и возвращает массив строк. Чтобы вызвать его, присвойте его переменной.

Подход тот же, что и в умном Ruby от QPaysTaxes. отвечать. Мы заменяем каждую цифру во входных данных таким количеством пробелов, помещаем -lp between each character, tack "|" на переднюю и заднюю часть и разделился на массив на ?| .

Попробуйте онлайн!

 

Cichecync19


Рег
25 Oct, 2024

Тем
74

Постов
190

Баллов
580
  • 26, Oct 2024
  • #6

05AB1E, 21 байт

Код:

tr

Также 21 байт: .chars*?| .

Использование CP-1252 кодировка. Попробуйте онлайн!.

 

AleksandrBaus


Рег
30 Oct, 2011

Тем
75

Постов
207

Баллов
602
  • 26, Oct 2024
  • #7

JavaScript (ES6), 69 67 62 байта

.to_i

Дополнительные запятые создают пустые значения во внешнем разделении, которое создает начало и конец. .hex characters. You need two trailing commas because trailing commas are optional at the end of lists, so the first one is still part of the previous item.

Изменить: сохранено 5 байт благодаря @user81655.

 

D.S.N


Рег
13 May, 2006

Тем
74

Постов
196

Баллов
596
  • 26, Oct 2024
  • #8

сетчатка, 50 45 байт

Это было весело, хаха. Я не только нуб в Retina, но и в регулярных выражениях в целом... Вероятно, это можно сыграть в гольф много, поэтому я проведу еще несколько исследований.

Код:

|d|

Попробуйте онлайн!

 

Zlhduuxxnz


Рег
06 Nov, 2019

Тем
74

Постов
207

Баллов
607
  • 26, Oct 2024
  • #11

С, 252 байта

"|#{...}|"

Подробный попробовать онлайн

$/ ||answer||

JavaScript (FireFox 30+), 61

Использование понимания массива, которое больше не является стандартным EcmaScript

/

Тест

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

Biggreeder


Рег
02 Sep, 2006

Тем
61

Постов
182

Баллов
527
  • 26, Oct 2024
  • #12

Луа, 106 байт

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

без гольфа

| ||answer||

Р (вне конкурса)

Извините, если это неуместно публиковать, но я подумал, что это здорово, что у меня случайно оказалась функция, которая действительно работает для этого вопроса без редактирования! Однако он печатает вывод в формате Unicode, а не в формате ascii. Я не могу точно вспомнить, почему я написал это, но это было не для того, чтобы ответить на вызов.

| ||answer||

Хаскелл, 110 байт

Негольфед:

/ ||answer||

Java 7, 190 184 байт

/ ¶

Подробный попробовать онлайн

$& ||answer||

Пайк, 25 20 байт

<num>

Объяснение:

<num>$*<char>

Попробуйте здесь!

 

Polymet


Рег
06 Nov, 2010

Тем
70

Постов
236

Баллов
626
  • 26, Oct 2024
  • #13

Питон, 84 байта

$*

Объяснение:

\d $* ||answer||

><>, 64 байта

\d $* / ¶ |

4 потерянных байта из-за проблем с выравниванием, но не знаю, как их вытащить. ¯\_(ツ)_/¯

 

WwwsoftimageBery


Рег
27 Mar, 2014

Тем
72

Постов
194

Баллов
574
Тем
403,760
Комментарии
400,028
Опыт
2,418,908

Интересно