Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Given an input of four integers x1, y1, x2, and y2, output whether a white king in chess (with coordinates (x1, y1)) could catch a black pawn (with coordinates (x2, y2)) and capture it if the pawn is moving to promote to a queen as fast as possible.

The coordinates of the board are as follows:

       first coordinate (x)
             12345678

           1 .#.#.#.#
           2 #.#.#.#.
           3 .#.#.#.#
  second   4 #.#.#.#.
coordinate 5 .#.#.#.#
    (y)    6 #.#.#.#.
           7 .#.#.#.#
           8 #.#.#.#.

Assume it is white to move (the king's turn) and that both players play optimally (the king will move as fast as possible to catch the pawn, and the pawn will move as fast as possible to promote). The input coordinates will always be distinct, and the pawn will never start with a y-coordinate of 8.

The king moves one square in any direction every turn (it can move diagonally), and the pawn can only move one space forwards (decrease its y-coordinate), unless it's at its initial position (with our coordinate system, y-coordinate of 7), in which case it can move two spaces forwards.

The input can be given as a whitespace-/comma-separated string, an array of strings/integers, or four function/command line/etc arguments. The coordinates can be given in whichever order is most convenient/golfy (so, accepting input as [y2, y1, x1, y2] is okay as long as it's consistent). The output must be a truthy or falsy value.

Since this is , the shortest code in bytes wins.

Truthy test cases:

5 3 3 2

6 1 1 7

3 3 3 2

4 1 4 7

7 7 1 7

1 8 1 7

Falsy test cases:

6 4 3 2

8 8 1 7

3 4 3 2

share|improve this question
    
Can we chose the order of the coordinates or does it have to be x1 y1 x2 y2? – Dennis Jan 7 at 3:04
    
@Dennis I suppose whichever order is most convenient (i.e. golfiest) is okay. I'll edit the quesiton. – Doorknob Jan 7 at 3:05
    
The write-up says that the pawn's starting position is in row 2, which suggests it's moving down the board, but the pictures have it moving up. Which is correct? (In other words, is the pawn's goal to reach 1 or 8?) – Jack Brounstein Jan 7 at 3:08
10  
I suggest the test case 1 8 1 7, where the king captures before the pawn can move two spaces. I think all of the answers now get it wrong. This situation makes the problem a lot harder. – xnor Jan 7 at 5:58
1  
@kaine The pawn doesn't pose a significant threat to the king unless the king can't take it on or before the move it promotes. The king doesn't have to move into check because there is always an equally good move that it can make. – Neil Jan 8 at 0:48
up vote 2 down vote accepted

Jelly, 33 bytes

‘»Ɠ_2<®
Ɠ©<7
:5+Ɠ>7$¤<1.4
Ɠ_ƓA2£Ŀ

This program reads the coordinates as x2\nx1\ny2\ny1 from STDIN. Try it online!

Non-competing version

Unfortunately, the Jelly interpreter had a bug when this question was posted. Said bug prevented it from accepting more than two command-line arguments. The newest version of Jelly can solve the given task in 23 bytes.

⁶>7×5
_A+⁵>6$¤+¢’»⁶_2<⁵

Try it online!

share|improve this answer

Python 2, 53 40

lambda x,y,p,q:y-2<q>=abs(x-p)+q/7+y/8*5

The king has coordinates (x, y) and the pawn (p, q).

There are three significant cases:

  1. The pawn is on rank 7 and the king on rank 8. To capture the pawn, the king must be on the same file or an adjacent one.

    Result: q = 7 ⋀ y = 8 → |x - p| ≤ 1

  2. The pawn is on rank 7. To capture the pawn, the king must be within six files.

    Result: q = 7 → |x - p| ≤ 6

  3. The pawn is on a lower rank. To capture the pawn, the king must be able to reach the promotion square at most one move after the pawn.

    Result: q < 7 → |x - p| ≤ q ⋀ y - 1 ≤ q

My solution is just these conditions golfed down. Hopefully there aren't mistakes this time.

share|improve this answer
2  
How about cutting the abs with max(y-1,x-p,p-x)? – xnor Jan 7 at 5:42
    
Shouldn't f(1,8,1,7) be True because the king immediately captures the pawn? I think there's a subtlety where pawn row 7 cannot be treated as row 6 if the king captures immediately. – xnor Jan 7 at 5:51
    
@xnor I think it's fixed now (in a badly golfed way). – grc Jan 7 at 6:13
1  
If you reversed the last condition, you can remove the space between the or and -2. – xsot Jan 7 at 12:16
    
@xsot thanks for the tip. I've changed my approach and got it down a bit more now. – grc Jan 7 at 14:03

Prolog, 48 42 bytes

Code:

p(X,Y,P,Q):-Y-2<Q,Q>=abs(X-P)+Q//7+Y//8*5.

Examples:

p(1,8,1,7).
true

p(3,4,3,2).
false

Not a bad challenge for Prolog compared to most.

Edit: Saved 6 bytes by switching to the formula used in grc's Python 2 answer.
Unfortunately Prolog can't chain comparisons as python can and integer division is 1 byte longer than float division.

Try it online here

share|improve this answer

JavaScript (ES6), 52

(x,y,u,t,d=x>u?x-u:u-x)=>(d>=y?d:y-1)<=(d<2|t<7?t:6)

I hope to have saved bytes not using Math.abs, Math.min, Math.max

The pawn at row seven can escape moving 2 spaces, if and only if the king is not in a near column - that's why there is a check on d before substituting 7 with 6.

Test case to run in console:

;[f(5,3,3,2),f(6,1,1,7),f(3,3,3,2),f(1,8,1,7),f(6,4,3,2),f(8,8,1,7),f(3,4,3,2)]

Result: [true, true, true, true, false, false, false]

share|improve this answer

Ruby, 50 bytes

def f(a,b,c,d)(a-c).abs<=(d==7?6-b/8*5:d)&&b-d<2;end

Arguments are (king x, king y, pawn x, pawn y), all integers.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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