19
\$\begingroup\$

Task

A reverse checkers position is a chess position where every piece for one player is on one colour and every piece for the other player is on the other colour. Your task is to find if the given (valid) position meets these criteria.

For example, this position does (click for larger images). Every white piece is on a light square, while every black piece is on a dark square:

reverse checkers 1

This position is also a reverse checkers position. Every white piece is on a dark square, while every black piece is on a light square:

reverse checkers 2

Input

Your input will be a valid chess position. You choose whether it'll be a FEN (for the purpose of this challenge, we'll only consider the first field, piece placement), or an 8x8 grid (with spaces or not between). If the latter, mention in your answer what characters you used to denote empty squares and the pieces.


The examples below will use upper-case letters for white pieces and lower-case for black. Empty squares are represented by dots (.).

  1. The first position above:

    5r1k/2p3b1/1p1p1r2/p2PpBp1/P1P3Pp/qP1Q1P1P/4R1K1/7R
    
    . . . . . r . k
    . . p . . . b .
    . p . p . r . .
    p . . P p B p .
    P . P . . . P p
    q P . Q . P . P
    . . . . R . K .
    . . . . . . . R
    

    is a reverse checkers position.

  2. The second position above:

    r3r3/5pBk/p3nPp1/1p1pP2p/2pPb1p1/P1P1N1P1/1P3R1P/R5K1
    
    r...r...
    .....pBk
    p...nPp.
    .p.pP..p
    ..pPb.p.
    P.P.N.P.
    .P...R.P
    R.....K.
    

    is a reverse checkers position as well.

  3. The starting position:

    rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR
    
    bbbbbbbb
    bbbbbbbb
    ........
    ........
    ........
    ........
    wwwwwwww
    wwwwwwww
    

    is not a reverse checkers position.

Rules

  • The chess position will always be valid.
  • You may use two characters for the pieces, one for white pieces and one for black pieces (i.e. you don't have to use a different character for every piece).
  • You can receive input through any of the standard IO methods.
  • This is , so shortest code in bytes wins!
\$\endgroup\$
9
  • \$\begingroup\$ Can we take input as an \$8\times 8\$ matrix of integers 0, 1, 2? \$\endgroup\$ Commented Jan 4, 2022 at 19:28
  • \$\begingroup\$ @cairdcoinheringaahing yes, just mention which is empty, white or black. \$\endgroup\$ Commented Jan 4, 2022 at 19:32
  • \$\begingroup\$ How loose can the output format be? Can I output [1] for "is a reverse checkers position" and [1,1] for "is not", or does the output have to be a truthy value and a falsey value, or does it have to be 0/1, etc.? \$\endgroup\$ Commented Jan 4, 2022 at 20:11
  • \$\begingroup\$ May we take input as a 64-element list instead of a matrix? \$\endgroup\$
    – chunes
    Commented Jan 4, 2022 at 20:15
  • 2
    \$\begingroup\$ I suggest adding a test case where there are two kings left, both on dark squares \$\endgroup\$ Commented Jan 4, 2022 at 21:11

12 Answers 12

17
\$\begingroup\$

Python, 34 bytes

lambda p:{*p[::2]}<{*p}>{*p[1::2]}

Attempt This Online!

Accepts a single string. Works for any distinct 4 characters for empty,black,white,newline.

How?

Uses the fact that including the linebreak lines have odd length, hence going over the entire string skipping every other character separates black and white squares. Both subsets must contain newlines and empty squares (we can't legally put all 32 initial pieces on the same colour squares because of the bishops). Iff there are pieces of both players on the same kind of square that subset will be the full set and the corresponding inequality fail.

Old Python, 40 bytes

lambda p:{*p[::2]}<{*"bw.\n"}>{*p[1::2]}

Attempt This Online!

Accepts a single string. ".bw\n" for empty,black,white,newline.

Wrong Python, 36 bytes

lambda p:len({*p[::2]}&{*p[1::2]})<3

Attempt This Online!

Accepts a single string. Works for any distinct 4 characters for empty,black,white,newline.

\$\endgroup\$
8
\$\begingroup\$

R, 68 50 40 bytes

function(x)sd((z=rbind(x,0)*.5:-1)[!!z])

Try it online!

Input is 8x8 matrix with 1s and -1s representing black and white pieces (or the other way around), and 0s representing empty positions. Outputs zero (falsy) for not-reverse-checkers positions, non-zero (truthy) for reverse-checkers positions (or +2 bytes for single-character input 0, 2 & 1 as black, white & empty).

Multiplies black squares by -0.5 and white squares by 0.5, and then uses the standard deviation (sd) to check if all the resulting nonzero [!!z] values are the same (in which case the standard deviation is zero). In many challenges, the sd approach could fail for inputs with zero or one items (which would yield a standard deviation of NA), but luckily this can't happen here for a valid chess position.

\$\endgroup\$
3
  • \$\begingroup\$ Looks like it's enough to check whether z has any negative elements, or am I missing something? Try it online! \$\endgroup\$
    – pajonk
    Commented Jan 5, 2022 at 5:22
  • \$\begingroup\$ @pajonk - I didn't think that approach would work if you swap the black & white pieces, leaving the reverse-checkers-ness unchanged... \$\endgroup\$ Commented Jan 5, 2022 at 7:28
  • \$\begingroup\$ I see, thanks for correcting me. \$\endgroup\$
    – pajonk
    Commented Jan 5, 2022 at 7:45
6
\$\begingroup\$

Jelly, 9 bytes

ŒJ§ḂṬƙFṀḊ

Try it online!

Takes input as an \$8 \times 8\$ matrix, with 0 being empty space, 1 being white and 2 being black. Outputs an empty list [] for truthy, and a non-empty list [1] for falsey.

Additionally, if we really want to stretch the output format, we can have this 8 byter

ŒJ§ḂṬƙFṀ

Try it online!

which outputs [1] for truthy, and [1, 1] for falsey.

How it works

ŒJ§ḂṬƙFṀḊ - Main link. Takes a matrix M on the left
ŒJ        - 8x8 grid of coordinates [x, y] between 1 and 8
  §       - Sum of each coordinate
   Ḃ      - Bit
      F   - Flatten M
     ƙ    - Over the lists formed by grouping the flattened M by the bit of the coordinate:
    Ṭ     -   Yield a boolean list, with 1s at the indices in the list
       Ṁ  - Maximum
        Ḋ - Dequeue, remove the first element
\$\endgroup\$
5
  • \$\begingroup\$ @double-beep Still working on golfing, I'll add an explanation shortly \$\endgroup\$ Commented Jan 4, 2022 at 19:51
  • \$\begingroup\$ @double-beep Added a full explanation of both \$\endgroup\$ Commented Jan 4, 2022 at 20:46
  • 1
    \$\begingroup\$ "a board is in a reverse checkers position if no diagonal contains both 1 and 2" -- Nice insight! \$\endgroup\$
    – Jonah
    Commented Jan 4, 2022 at 20:46
  • \$\begingroup\$ But what if you had two kings left, say, both on a dark square, neither on a diagonal? \$\endgroup\$
    – Jonah
    Commented Jan 4, 2022 at 20:53
  • 1
    \$\begingroup\$ @Jonah Good point, corrected \$\endgroup\$ Commented Jan 4, 2022 at 21:11
4
\$\begingroup\$

Factor, 43 bytes

[ 2 group unzip [ cardinality 3 = ] both? ]

Try it online!

Takes input as a string with any three distinct values representing black pieces, white pieces, and empty spaces and relies on the trick from @loopy walt's Python answer: namely, that because of newlines, even and odd indices of the string correspond to black and white squares. However, all we need to do is check if the cardinality of both groups is three.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ BQN translation: {∧´3=≠∘⍷˘⍉⌽‿2⥊𝕩} \$\endgroup\$
    – Razetime
    Commented Jan 5, 2022 at 9:23
3
\$\begingroup\$

J, 23 22 21 16 15 bytes

6 e.]*.//.~2|#\

Try it online!

Test cases taken from caird's Jelly answer

Input: Single list with space & newline = 1, black = 2, white = 3.

Output: 0 for valid, 1 for invalid.

how

  • 2|#\ Creates list 1 0 1 0 1 0 ... to length of input.

  • ]*.//.~ Partitions input according to that, taking LCM of each partition. Only an invalid board will have a partition containing both 2 and 3, and hence an LCM of 42.

  • 6 e. Is 6 an element of that? Only possible on invalid boards.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ You could’ve chosen 5 for a newline and I respect your decision not to. \$\endgroup\$
    – cole
    Commented Jan 5, 2022 at 3:00
  • 1
    \$\begingroup\$ Your comment also made me realize I could just use 1 for newline as well and save a byte. \$\endgroup\$
    – Jonah
    Commented Jan 5, 2022 at 3:49
2
\$\begingroup\$

JavaScript (Node.js), 66 bytes

a=>a.map(t=r=>r.map(c=>t|=5+(g=-g)*(c>{}?-1:c>'@'),g=-g),g=3)^15^t

Try it online!

Input 2d array of characters in rnbqpRNBQP.. Output truthy vs falsy. 52 bytes if input as 2d array of +1, 0, -1.

\$\endgroup\$
1
\$\begingroup\$

Python3, 245 bytes:

lambda b:g({(x,y):b[x][y]for x in r(8)for y in r(8)})
r=range
g=lambda p:len(set(w:=[(x%2==0 and y%2==0)or(x%2 and y%2)for x,y in p if p[(x,y)]==1]))==1 and len(set(b:=[(x%2==0 and y%2==0)or(x%2 and y%2)for x,y in p if p[(x,y)]==0]))==1 and w!=b

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Perl 5, 48 bytes

y,/2468,1,d;$_=/^(([w\d][b\d])+|([b\d][w\d])+)$/

Try it online!

Takes preprosessed FEN-input: blacks becomes b and whites w. Deletes 2, 4, 6 and 8 empty squares since they don't change the result, odd empties 1, 3, 5 and 7 are treated as 1 (no difference in result). Flattens the board so the newlines / become one invisible empty square. The regex tests if all 36 pairs (9x8/2) of the flattened board consist of either white|empty then black|empty or the opposite. Returns 1 for truthy and "" (empty string) for falsey.

\$\endgroup\$
1
\$\begingroup\$

Pari/GP, 50 bytes

a->sum(n=0,1,!matrix(8,,i,j,(i+j+n+t=a[i,j])%2*t))

Try it online!

Takes input as an 8x8 matrix of 0s (empty), 1s (black), 2s (white).

\$\endgroup\$
0
\$\begingroup\$

Retina 0.8.2, 35 32 bytes

T`L`0
T`l`1
s`(\d).(..)*(?!\1)\d

Try it online! Takes input as a board but link is to test suite which converts from FEN to a compatible board, so if you want to test board input then delete the contents of the header first. Outputs 0 for a reverse draughts position and non-zero if not (+1 byte to always output 1). Explanation: Maps pieces to 0 or 1 depending on their colour (-12 bytes for a custom input format) and then checks whether opposite colour pieces are on two squares of the same colour.

\$\endgroup\$
2
  • \$\begingroup\$ Does this pass the test 8/8/8/8/8/8/8/4K1k1 suggested by @caird coinheringaahing ? \$\endgroup\$
    – Kjetil S
    Commented Jan 5, 2022 at 12:04
  • \$\begingroup\$ @KjetilS. Whoops, it doesn't. The right check is whether two squares of the same colour have opposite colour pieces. \$\endgroup\$
    – Neil
    Commented Jan 5, 2022 at 12:08
0
\$\begingroup\$

Charcoal, 32 bytes

F²⊞υ⟦⟧F⁸UMS⊞O§υ⁺ιλ⁻№ακ№βκ⊙υ×⌈ι⌊ι

Try it online! Takes input as a board and outputs nothing for a reverse draughts position and - if not. Explanation:

F²⊞υ⟦⟧

Start collecting the colour of pieces on squares of each colour.

F⁸

Loop over the rows.

UMS⊞O§υ⁺ιλ⁻№ακ№βκ

Push 1, 0, or -1 to the appropriate square colour list depending on the colour of the piece or 0 if there is no piece.

⊙υ×⌈ι⌊ι

See whether any square colours contain pieces of both colours. Since there can only be 15 pieces of the same colour on squares of one colour, there will be at least one zero in the array, but this will not be the minimum or the maximum if this is not a reverse draughts position.

\$\endgroup\$
0
\$\begingroup\$

Ruby -n0, 47 bytes

a={}
gsub(/\d/){a[[$`.size%2,_1]]=1}
p a.size<3

Attempt This Online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.