Is this a losing square?

19

2

There is a game called Get Home that is played on the a chess board. In this game there is a single piece that is moved by both players in turns. There are some rules to how the piece can be moved. On a turn a player must make one of the following moves for positive n.

  • n spaces up

  • n spaces to the left

  • n spaces up and to the left (a diagonal)

The player who moves the piece into the top left corner of the board wins the game.

Now we will define the concept of a losing square. In this video (from where I got the idea) a losing square is defined as a square on which, any player starting their turn will be forced to make a move allowing their opponent to force a win. The simplest example of a losing square would be the square at (1,2). A piece at (1,2) can move to any of the following places.

Illustration

All of which have a direct path to victory for the next player.

It also follows that any square that has a one move path to a losing square allows the player starting on that square to force a win. This means that any square that is not one move away from a losing square is also a losing square.

This brings us to this rather neat definition of a losing square:

A losing square is a square from which no move can arrive on another losing square and (0,0) is a losing square.

Task

Given the coordinates of a square on an arbitrarily sized chess board determine if it is a losing square. Output two values one for losing squares and one for others.

This is so answers will be scored in bytes with less bytes being better.

Test Cases

Here are all the losing squares on a regular 8 by 8 chess board (marked with 0).

0 1 1 1 1 1 1 1
1 1 0 1 1 1 1 1
1 0 1 1 1 1 1 1
1 1 1 1 1 0 1 1
1 1 1 1 1 1 1 0
1 1 1 0 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 0 1 1 1

Here is an image of a 100 by 100 board with losing squares marked in black (each square is 2 pixels by 2 pixels).

100 by 100 board

Post Rock Garf Hunter

Posted 2017-08-17T16:56:20.837

Reputation: 55 382

2I don't think there are enough test cases to find a pattern.I think I see a pattern, but I couldn't say for sure. Is 10, 7 a losing square? Is 10, 8? What about 15, 11? – James – 2017-08-17T17:04:54.880

@DJMcMayhem I will update with an image showing the pattern. The current test cases are there to verify answers. I believe you are correct in your assertions of further losing squares. – Post Rock Garf Hunter – 2017-08-17T17:12:38.053

1@WheatWizard Do you mind making the image a bit larger? – Erik the Outgolfer – 2017-08-17T17:27:14.277

@EriktheOutgolfer Its now 100 by 100, is that better? It takes a while to do this because I'm making the image by hand. – Post Rock Garf Hunter – 2017-08-17T17:31:17.123

1@WheatWizard I meant larger pixels...e.g. 5x5 pixels instead of 1x1, possibly some grid too if not too hard (btw thanks for the 100x100) – Erik the Outgolfer – 2017-08-17T17:32:11.100

@EriktheOutgolfer I've made each pixel 2x2. I felt 5x5 was way too large. Unfortunately I am not skilled enough with gimp to make a grid. – Post Rock Garf Hunter – 2017-08-17T17:36:37.270

Correction: this is closely related to https://codegolf.stackexchange.com/q/95604/194 , but that's a heuristic rather than an exact question.

– Peter Taylor – 2017-08-17T17:36:43.117

2Also related (return optimal move or signal that the position is losing). – Zgarb – 2017-08-17T17:42:55.097

Is the "arbitrary size" allowed to be limited by floating point inaccuracies (i.e. if we are using a square root or a floating-point golden ratio) or must we really support arbitrary size (up to physical limitations) if our language supports arbitrarily large integers? – Jonathan Allan – 2017-08-17T19:11:34.353

@JonathanAllan I don't know at the moment if you can give me a bit to think it over I can make a binding ruling. But until I permit it I will say it is not allowed. Is there a meta about floats? This seems to be a common issue, if there is one I'll go with the consensus. – Post Rock Garf Hunter – 2017-08-17T19:16:07.720

1I think it is normal to allow floating point inaccuracies to hinder performance even with arbitrarily large integer capability... – Jonathan Allan – 2017-08-17T19:30:39.727

I don't know about the meta consensus, but a reasonable argument to allow it was given to me by Dennis here for a similar task.

– Jonathan Allan – 2017-08-17T19:35:22.993

@WheatWizard I believe the consensus is approximately that the algorithm should work if the language didn't have limitations. So an answer which says (0,0) is a losing square and all other inputs are not, with the justification being "The language doesn't support integers, only bits" would be invalid, but if an algorithm that works for arbitrary numbers but is implemented in a language that only supports 8-bit integers would be valid. – Kamil Drakari – 2017-08-17T19:35:29.220

@JonathanAllan I don't think Dennis' argument caries over here but I will allow it. So long as answers work for values under 500. – Post Rock Garf Hunter – 2017-08-17T19:46:17.140

@WheatWizard Here is the relevant post in forbidden loopholes. Perhaps concluding from there that floating point inaccuracies don't need to be handled unless specifically relevant is a stretch, but it indicates that answers that would need more than trivial modification if their language suddenly improved the data type are invalid and otherwise you can keep the limits to what your language supports

– Kamil Drakari – 2017-08-17T19:46:26.743

Strangely related – xnor – 2017-08-17T21:34:18.393

I'm not sure how to interpret the task: "Output two values one for losing squares and one for others." Wouldn't the output simply be yes/no? Oh, I think I get it now, the output should be one of two possible values. You don't want us to output two values, only one. – Octopus – 2017-08-17T22:20:50.917

@Octopus Yes. This is a decision problem. Yes and no are fine. – Post Rock Garf Hunter – 2017-08-17T22:42:12.643

The name of this game in formal mathematics is Wythoff's game – boboquack – 2017-08-18T00:25:36.023

Answers

8

Python 3, 112 50 46 42 bytes

-4 bytes thanks to Jonathan Allan!

-2 bytes thanks to xnor!

lambda r,c:abs(r-c)*(3+5**.5)//2==max(r,c)

Try it online!

Based on the formula for cold positions in Wythoff's game and making some modifications in order to produce an explicit formula. Explanation inbound once I actually finish a proper methodology for the derivation of the formula.

notjagan

Posted 2017-08-17T16:56:20.837

Reputation: 4 011

Could not you change 0<=x to x>0 and save a byte or two? – Jonathan Frech – 2017-08-17T19:09:05.693

@JonathanFrech It has to be either <= or >= in order to include position 0, 0. – notjagan – 2017-08-17T19:11:42.063

You are right, only one byte can be saved.

– Jonathan Frech – 2017-08-17T19:20:34.710

@JonathanFrech I was a little weary of changing that <= because as the pairs get larger, the calculated quantity approaches 4/(1+5**.5)**2. As such, I was unsure of whether to make it < - although I guess it will never reach that point. – notjagan – 2017-08-17T19:24:55.123

1One less byte with a different implementation of the same: lambda r,c:int(abs(r-c)*(5**.5+1)**2/4)==max(r,c) – Jonathan Allan – 2017-08-17T19:37:25.463

@JonathanAllan Honestly, I'm sort of struggling to formalize an explanation of why this works - could you help me out here? – notjagan – 2017-08-17T19:53:11.967

1/2//1 looks the same as //2. – xnor – 2017-08-17T19:56:13.533

See my Jelly answer, I hope it explains it. – Jonathan Allan – 2017-08-17T20:33:20.580

Why can't (3+5**.5)//2 be replaced by its value? – Mr. Xcoder – 2017-08-17T22:35:21.943

@Mr.Xcoder The order of operations dictates that the absolute difference is multiple by the quantity in parentheses before being halved, so evaluating that portion gets a different result entirely. – notjagan – 2017-08-17T22:37:02.737

Oh thanks! That's... interesting. – Mr. Xcoder – 2017-08-17T22:38:39.197

5

Jelly, 8 bytes

ạ/×ØpḞ⁼Ṃ

Try it online!, or see the top-left 60 by 60 as a grid.

How?

A cold position in Wythoff's game is a losing position. The coordinates [n,m] give a cold position when n = floor(kφ) = floor(mφ) - m or m = floor(kφφ) = ceil(nφ) = n + k for some natural number, k, and the golden ratio, φ. The former holds when n is less than m; the latter when m is less than n (both holding at 0,0).

k is thus the absolute difference between n and m and if floor(abs(n-m)φ)=min(n,m) the condition is met.

ạ/×ØpḞ⁼Ṃ - Link: list, c ([n,m])
 /       - reduce c by:
ạ        -   absolute difference = abs(n-m)
   Øp    - golden ratio yield
  ×      - multiply
     Ḟ   - floor
       Ṃ - minimum of c = min(n,m)
      ⁼  - equal?

Jonathan Allan

Posted 2017-08-17T16:56:20.837

Reputation: 67 804

2

JavaScript (ES6), 64 bytes

f=(x,y,p=5**.5/2+.5)=>x<y?f(y,x):y/p%p<1&(y/p%p-x*p%++p)**2<1e-9

I see now that this is not the best technique, but I had to come up with it myself because I lost internet shortly after loading this page. (Would've posted a while ago if not for these internet issues...)

In a perfect world, float precision wouldn't be an issue and I could save 9 bytes:

f=(x,y,p=5**.5/2+.5)=>x<y?f(y,x):y/p%p<1&y/p%p==x*p%++p

6 more bytes could be saved if JS supported Python's comparison chaining:

f=(x,y,p=5**.5/2+.5)=>x<y?f(y,x):y/p%p==x*p%++p<1

ETHproductions

Posted 2017-08-17T16:56:20.837

Reputation: 47 880

0

Pyth, 39 Bytes

=SQL?!b0-byytb;q@myd+0.fqyZytZ@Q1)-F_Qh

I wrote this with a named function (ew), and was extremely lazy with golfing. Planning to golf off quite a number of bytes later tonight

Try it online, with my own generated tests, meant to alternate True / False

Explanation:

Diagonals of the solution matrix have a losing square according to the sequence of repeated numbers in OEIS A005206. From L through ; is pretty straightforward polish notation to define y(b)=b-y(y(b-1)).

The rest of the explanation follows

=SQL?!b0-byytb;q@myd+0.fqyZytZ@Q1)-F_Qh    Full program, take stdin as [x, y], output True or False to stdout
=SQ                                        Sort input
   L?!b0-byytb;                            Named lambda as explained above
                    +0.f                   Make sequence of first max(x, y) numbers, starting with 0, 
                        qy y               For which are equal 
                          Z tZ             each element and the previous are equal
                myd                        Map this sequence to the y(index), not just index numbers
             q                             Check if are equal 
              @                  )-F_Q     the x-yth element of sequence (x-y represents which diagonal) 
                                     h(Q)  and the lower of [x,y] (Q is added by the interpreter to fix arity issues

Dave

Posted 2017-08-17T16:56:20.837

Reputation: 432

0

Batch, 204 bytes

@if %1 lss %2 %0 %2 %1
@if %1==0 exit/b0
@set/au=l=i=0
:g
@set/au+=2+i%%2,l+=1+i%%2
@if %1==%n% if %2==%m% exit/b0
@if %1 leq %n% exit/b1
:l
@set/a"k=3*i^2*i^i,i+=1
@if %k%==0 goto g
@goto l

Returns via exit code. Explanation: Since Batch only has integer arithmetic I had to devise a purely arithmetical solution. Excluding the 0,0 entry, the pairs of losing square coordinates follow the following rule: if the next 11-free binary number is even then add 3,2 otherwise add 2,1. A test for a 11-free binary number is if there are no carries when it is multiplied by three, in other words that (i*2)+i==(i*2)^i. Here are the first few 11-free binary numbers and their coordinates:

   0     2,1  + 3,2 =  5,3
   1     5,3  + 2,1 =  7,4
  10     7,4  + 3,2 = 10,6
 100    10,6  + 3,2 = 13,8
 101    13,8  + 2,1 = 15,9
1000    15,9  + 3,2 = 18,11
1001    18,11 + 2,1 = 20,12
1010    20,12 + 3,2 = 23,14

etc. Mysteriously this rule suffices to make the sequences complementary. It then remains to compute the sequence until it reaches the larger coordinate, at which point we can determine whether the square is losing.

Neil

Posted 2017-08-17T16:56:20.837

Reputation: 95 035