Goal
You're playing a computerised chess game. The display is in black and white only and the pixels are chunky. White pixels use a lot power compared to black pixels and you're concerned about your carbon footprint.
Given a square and a piece in chess notation, return the number of white pixels displayed in the square.
The solution may be in the form of a function or a complete program.
Input
A 4-character string defining:
- One of
wbfor a white or black piece. (Not part of normal Chess notation, but required for this puzzle.) - One of
KQBNRPfor a King, Queen, Bishop, kNight, Rook or Pawn. - One of
abcdefghfor the piece's file (column). - One of
12345678for the piece's rank (row).
Output
The number of white pixels used to draw the chess piece and the underlying square.
Requirements
- Chess squares are 8x8 pixels and are either all white or all black.
a1is a black square.- White chess pieces are drawn as white with a black outline. Black pieces are black with a white outline. All pieces have transparent pixels which show the underlying square.
- Input is case-sensitive.
- Assume the input is valid.
The chess pieces have sprites as follows.
. is the piece's colour.
# is the inverse of the piece's colour.
/ is the underlying square's colour.
King Queen Bishop
//////// //////// ////////
///#.#// /#.#.#.# ///#.#//
//#...#/ //#...#/ //##..#/
///#.#// ///###// //#.#.#/
///###// //#...#/ ///###//
//#...#/ //#...#/ //#...#/
//#...#/ //#...#/ //#...#/
//#.#.#/ //#.#.#/ //#.#.#/
kNight Rook Pawn
//////// //////// ////////
//////// /#.#.#.# ////////
//#..#// /#.....# ////////
/#....#/ /##...## ///#.#//
///#..#/ //#...#/ //#...#/
//#..#// //#...#/ ///#.#//
//#...#/ //#...#/ //#...#/
//#...#/ //#...#/ //#...#/
The number of pixels in the piece's colour, piece's outline and underlying square for each piece is:
Piece Fill Outline Square
==============================
King 13 16 35
Queen 17 18 29
Bishop 13 18 33
Knight 16 12 36
Rook 23 18 23
Pawn 11 10 43
Test Cases
Input Output
wRa1 23
bRa1 18
wPc2 54
bKg8 51
Scoring
The shortest code in bytes by Christmas Day gets a little something extra in their stocking.
7 Answers 7
C#6, 107 bytes
Here's my own answer. I don't expect any points being the one who posed the challenge.
I have taken some inspiration from user81655's answer.
long P(string a)=>(a[0]>99?12201284685:11042628752)+(a[2]+a[3])%2*46566348643>>"KQBNRP".IndexOf(a[1])*6&63;
The pixel counts are encoded in 6-bit blocks. The outline or fill is added to the square (if it's white). Finally, the 6-bit block for the appropriate piece is extracted.
Thankfully, operation precedence worked heavily in my favor.
JavaScript (ES6), 106
As an anonymous function.
x=>(o=+'137999'[p='PNKBQR'.search(x[1])],f=+'262149'[p]+p,(parseInt(x[2]+x[3],19)%2?9:55-f-o)+(x>'w'?f:o))
By now, I'm following the simplest way of find the answer with a calculation - this could be not the best way.
Over a black square, the answer is the size of fill for white pieces and the size of outline for black pieces. Over a white square, you need to add the free space. See the table below (inside the snippet)
I keep the size of fill and outline for each piece, the free space inside the square can be found subtracting from 64. To save space, the outline in stored as a single digit afer subtracing 9. The fill is trickier as the range is wider, check the code (that's way the pieces are sorted by occupied space)
Test snippet:
F=x=>(
o=+'137999'[p='PNKBQR'.search(x[1])], // get outline - 9
f=+'262149'[p]+p, // get fill -9
(
parseInt(x[2]+x[3],19) // parse with an odd base the differentiate between odd and even rows
%2?9:55-f-o // black square if odd,, white if even so calc free space
) +(x>'w'?f:o) // add fill or outline based on piece color
)
// Test suite
console.log=x=>O.innerHTML+=x+'\n'
for(i=0; z='PNKBQR'[i]; i++)
{
o = '';
t = 'w'+z+'c2'; // white piece, white square
o += t+' '+F(t)+', '
t = 'b'+z+'c2'; // black piece, white square
o += t+' '+F(t)+', '
t = 'w'+z+'a1'; // white piece, black square
o += t+' '+F(t)+', '
t = 'b'+z+'a1'; // black piece, black square
o += t+' '+F(t)
console.log(o);
}
<pre>
Piece Fill Outline Free w/w b/w w/b b/b
=============================================
Pawn 11 10 43 54 53 11 10
Knight 16 12 36 52 48 16 12
King 13 16 35 48 51 13 16
Bishop 13 18 33 46 51 13 18
Queen 17 18 29 46 47 17 18
Rook 23 18 23 46 41 23 18
</pre>
<pre id=O></pre>
JavaScript (ES6), (削除) 135 (削除ここまで) 112 bytes
s=>(c={K:`\u000a\u0010\u0023`,Q:`\u0011\u0012\u001d`,B:`\u000a\u0012\u0021`,N:`\u0010\u000c\u0024`,R:`\u0017\u0012\u0017`,P:`\u000b\u000a\u002b`}[s[1]])[f="charCodeAt"](s<"w")+((s[f](2)-s[3])%2&&c[f](2))
Every \u00xx should be a single one-byte character. They are represented here as codes because Stack Exchange automatically removes unreadable characters from posts.
Explanation
s=>
// c = string of three (mostly unreadable) characters, the ASCII code of each character
// represents the number of pixels in the fill, outline and square respectively
(c={
K:`\u000a\u0010\u0023`,
Q:`\u0011\u0012\u001d`,
B:`\u000a\u0012\u0021`,
N:`\u0010\u000c\u0024`,
R:`\u0017\u0012\u0017`,
P:`\u000b\u000a\u002b`
}[s[1]])
[f="charCodeAt"](s<"w") // if piece is black add outline pixels, else add fill pixels
+((s[f](2)-s[3])%2 // this returns 1 if the square is white or 0 if black
&&c[f](2)) // if the square is white add the square's pixels
Test
var solution = s=>(c={K:`\u000a\u0010\u0023`,Q:`\u0011\u0012\u001d`,B:`\u000a\u0012\u0021`,N:`\u0010\u000c\u0024`,R:`\u0017\u0012\u0017`,P:`\u000b\u000a\u002b`}[s[1]])[f="charCodeAt"](s<"w")+((s[f](2)-s[3])%2&&c[f](2))
<input type="text" id="input" value="bKg8" />
<button onclick="result.textContent=solution(input.value)">Go</button>
<pre id="result"></pre>
Pyth, (削除) 54 (削除ここまで) 53 bytes
The code contains unprintable characters, so here is a reversible xxd hexdump:
0000000: 732a 562b 5f57 2543 687a 322c 3031 2573 s*V+_W%Chz2,01%s
0000010: 434d 7474 7a32 4063 434d 2e22 0a2b 011e CMttz2@cCM.".+..
0000020: d699 71d0 c6dc 3db8 eeae 2233 252a 4368 ..q...=..."3%*Ch
0000030: 747a 5433 31 tzT31
Alternatively, here's a copy-paste friendly version, which you can also try online or use the test suite:
s*V+_W%Chz2,01%sCMttz2@cCM."\n+\x01\x1e\xd6\x99q\xd0\xc6\xdc=\xb8\xee\xae"3%*ChtzT31
JavaScript (Node.js), 84 bytes
s=>[a=~"0628"[[C,P,F,R]=Buffer(s),i=P%11%7],b=-"63682"[i]||4][C&1]+(F+R&1?45-a-b:19)
How?
The color, the piece, the file and the rank characters are turned into ASCII codes which are saved into \$C\$, \$P\$, \$F\$ and \$R\$ respectively.
We compute the piece index \$i=(P \bmod 11)\bmod 7\$:
char. | code | mod 11 | mod 7
-------+------+--------+-------
'B' | 66 | 0 | 0 Reordered by index:
'K' | 75 | 9 | 2
'N' | 78 | 1 | 1 0 | 1 | 2 | 3 | 4 | 5
'P' | 80 | 3 | 3 ---+---+---+---+---+---
'Q' | 81 | 4 | 4 B | N | K | P | Q | R
'R' | 82 | 5 | 5
We compute \$a\$, which is the number of outline squares for the piece, minus \19ドル\$:
a = ~"0628"[i]
We compute \$b\$, which is the number of filled squares for the piece, minus \19ドル\$:
b = -"63682"[i] || 4
We use C & 1 to figure out the color of the piece and F + R & 1 to figure out the color of the square.
The final result is:
[a, b][C & 1] // use outline squares if the piece is black
+ // or filled squares if the piece is white
( //
F + R & 1 ? // if the square is white:
45 - a - b // add 19 + (64 - ((a + 19) + (b + 19)))
// = 45 - a - b
: // else:
19 // just add 19
) //
Lua, (削除) 158 (削除ここまで) 155 Bytes
c,p,l,n=(...):byte(1,4)m="KQBNRP"d={}d[1]={13,17,13,16,23,11}d[0]={16,18,18,12,18,10}p=m:find(string.char(p))print(d[c%2][p]+(l+n)%2*(64-d[0][p]-d[1][p]))
Could probably reduce the byte count by encoding the data, but I kinda like the current table method.
Bases color of the square on the ASCII value of 'w' or 'b' taking advantage of the fact that one is even and one is odd. Assigns integer value of the piece based on the position of the piece's symbol in the m string variable. Whether a square is dark or light is handled by (l+n)%2 taking advantage of ASCII value again.
Ungolfed
c,p,l,n=(...):byte(1,4) --stores input of all characters into variables
m="KQBNRP" --piece encoded string
d={} --data table
d[1]={13,17,13,16,23,11} --fill
d[0]={16,18,18,12,18,10} --outline
p=m:find(string.char(p)) --position in string for position in tables
print(d[c%2][p] + --takes data element from corresponding table according to color of piece and type of piece
(l+n)%2 * --is square black or white? 0 if back, 1 if white
(64-d[0][p]-d[1][p]) --if white, pixels not used by piece would be area (64) minus pixels used by piece, or corresponding data in the tables
)
-3 Bytes by removing c=c%2 before the print and using d[c%2][p] instead of d[c][p].
05AB1E, 41 bytes
Ç`+É•wH ̃OÝ•44в*s11%©è•2ĀpakΩÕðβ•2в2ä+sè®è
Try it online or verify all test cases.
Explanation:
Ç # Convert the (implicit) input to a list of codepoint integers
` # Pop and push the four integers separated to the stack
+ # Add the top two together (column+row)
É # Check if this is odd (1 if odd/white; 0 if even/black)
•wH ̃OÝ• # Push compressed integer 245530244740
44в # Convert it to base-44 as list: [33,36,35,43,29,23,0]
* # Multiply each value by the odd-check
s # Swap so the piece is at the top of the stack
11% # Modulo-11 on that integer
© # Store it in variable `®` (without popping)
è # Index (0-based modulair) it into the list
•2ĀpakΩÕðβ• # Push compressed integer 45866137874521319810
2в # Convert it to base-26 as list:
# [18,12,16,10,18,18,0,13,16,13,11,17,23,0]
2ä # Split it into two equal-sized parts:
# [[18,12,16,10,18,18,0],[13,16,13,11,17,23,0]]
+ # Add the earlier indexed value to each
s # Swap to get the final integer at the top (square-color)
è # Index (0-based modulair) it into this pair of lists
®è # And then index `®` (piece%11) into this list
# (after which the result is output implicitly)
See this 05AB1E tip of mine (sections How to compress large integers? and How to compress integer lists?) to understand why •wH ̃OÝ• is 245530244740; •wH ̃OÝ•44в is [33,36,35,43,29,23,0]; •2ĀpakΩÕðβ• is 45866137874521319810; and •2ĀpakΩÕðβ•2в is [18,12,16,10,18,18,0,13,16,13,11,17,23,0].
The modulo-11 trick on the piece codepoint was inspired by @Arnauld's JavaScript answer. The trailing 0s in the lists are just fillers, since 05AB1E indexes modulair, so we don't need the modulo-7 that Arnauld uses.
Explore related questions
See similar questions with these tags.