26
\$\begingroup\$

In chess, the Fool's Mate is the fastest possible way to reach checkmate. It is reached with Black's second move. In chess notation, one possible sequence of moves that achieves Fool's Mate is 1.f3 e6 2.g4 Qh4#.

Position after 1.f3 e6 2.g4 Qh4#

This is not the only possible way to achieve this checkmate (in the same number of moves). There are three things that can be varied while still taking the same number of moves:

  1. White can move the f-pawn first or the g-pawn first,
  2. White can move the f-pawn to f3 or f4, and
  3. Black can move the e-pawn to e6 or e5.

This gives 8 possible games that end in Fool's Mate. Print them all in standard chess notation. They are:

1.f3 e5 2.g4 Qh4#
1.f3 e6 2.g4 Qh4#
1.f4 e5 2.g4 Qh4#
1.f4 e6 2.g4 Qh4#
1.g4 e5 2.f3 Qh4#
1.g4 e5 2.f4 Qh4#
1.g4 e6 2.f3 Qh4#
1.g4 e6 2.f4 Qh4#

The order in which the games are printed does not matter, so e.g. this is OK:

1.g4 e5 2.f4 Qh4#
1.f3 e6 2.g4 Qh4#
1.g4 e6 2.f4 Qh4#
1.f4 e5 2.g4 Qh4#
1.f4 e6 2.g4 Qh4#
1.g4 e5 2.f3 Qh4#
1.g4 e6 2.f3 Qh4#
1.f3 e5 2.g4 Qh4#
\$\endgroup\$
6
  • 7
    \$\begingroup\$ Here is a program to validate an output. \$\endgroup\$
    – Arnauld
    Commented Sep 22, 2022 at 16:42
  • 1
    \$\begingroup\$ @Arnauld just curious, why on earth did you use a sha256 hash for that? \$\endgroup\$
    – naffetS
    Commented Sep 23, 2022 at 0:24
  • 4
    \$\begingroup\$ @Steffan Probably because I've spent 90% of my time on a project involving quite a lot of cryptography during the last few months and where almost everything is identified by a hash. :-p \$\endgroup\$
    – Arnauld
    Commented Sep 23, 2022 at 0:49
  • \$\begingroup\$ May we output them as a list of lines? Or is printing each line mandatory? \$\endgroup\$ Commented Sep 23, 2022 at 7:02
  • 1
    \$\begingroup\$ Sort of related. At least interesting so I thought I'd share. There's a version of chess written in Javascript that is under 1,024 bytes in length. Yes under 1KB for a full chess engine. You can play it here: vole.wtf/kilobytes-gambit \$\endgroup\$
    – Paul
    Commented Sep 23, 2022 at 13:25

14 Answers 14

12
\$\begingroup\$

Bash, 61

This is a pretty good challenge for bash brace expansions

printf '1.%s Qh4#
' f{3,4}\ e{5,6}\ 2.g4 g4\ e{5,6}\ 2.f{3,4}

Try it online!

\$\endgroup\$
6
\$\begingroup\$

JavaScript (V8), 80 bytes

-2 bytes by using a full program, as suggested by @dingledooper
-2 bytes thanks to @Kevin Cruijssen

for(n=8;n--;)print(`1.${n&2?G='g4':F} e${6-n%2} 2.${n&2?F=`f${n&4||3}`:G} Qh4#`)

Try it online!

How?

We iterate from \$n=7\$ to \$n=0\$ and use each bit to decide what should be displayed:

bit : 2 1 0
      | | |
      | | +--> use 'e5' if set, use 'e6' if clear
      | +----> g-pawn first if set, f-pawn first if clear
      +------> use 'f4' if set, use 'f3' if clear
\$\endgroup\$
6
  • 1
    \$\begingroup\$ It'd be 82 bytes in V8 as a full program. \$\endgroup\$ Commented Sep 22, 2022 at 22:27
  • \$\begingroup\$ Out of curiosity: why does n&2?G='g4':F and n&2?F:G work without giving an ReferenceError: G is not defined error at the second one? I would have expected F=`f${n&4||3}`,n&2?G='g4':F to be F=`f${n&4||3}`,G='g4',n&2?G:F instead. If I compare it to Java, that's the error I would get. Why is JS fine with that second G in this case? \$\endgroup\$ Commented Sep 23, 2022 at 8:46
  • 1
    \$\begingroup\$ @KevinCruijssen G is initialized in the first iteration (at n=7), so in all subsequent iterations G will have already been defined. \$\endgroup\$ Commented Sep 23, 2022 at 9:11
  • 1
    \$\begingroup\$ @dingledooper Ah ok. But if I understand it correctly then: changing the second n&2?F:G to n&2?F=`f${n&4||3}`:G works for 80 bytes then? \$\endgroup\$ Commented Sep 23, 2022 at 9:29
  • \$\begingroup\$ @KevinCruijssen It does indeed! Thank you. \$\endgroup\$
    – Arnauld
    Commented Sep 23, 2022 at 9:49
5
\$\begingroup\$

Vyxal j, 36 bytes

\f43f+56fẊ‛g4vJ:RJƛ÷`1.Π eΠ 2.Π Qh4#

Try it Online!

This was... annoying

         Ẋ                           # Cartesian product of...
\f43f+                               # ["f3", "f4"]               
      56f                            # and [5, 6]
          ‛g4vJ                      # Append "g4" to each
               :RJ                   # Reverse each and append to the original 
                  ƛ                  # Over each...
                   ÷                 # Push each into the stack
                    `1.Π eΠ 2.Π Qh4# # Format into the final output.
\$\endgroup\$
5
\$\begingroup\$

C (gcc), 104 99 90 89 bytes

f(i){for(i=9;--i;printf("1.%c%d e%d 2.%c%d Qh4#\n",102+i/5,4+3/~i,6-i%2,103-i/5,4-i/7));}

Try it online!

-3 bytes thanks to Steffan

-1 byte thanks to Arnauld

-9 bytes thanks to AZTECCO

-1 byte thanks to c--

\$\endgroup\$
5
  • \$\begingroup\$ Shoot, didn't notice yours until mine was posted. \$\endgroup\$ Commented Sep 22, 2022 at 17:12
  • 1
    \$\begingroup\$ (i&2)/2 => i%4/2 for -2, i;f() => f(i) for -1: Try it online! \$\endgroup\$
    – naffetS
    Commented Sep 22, 2022 at 18:33
  • \$\begingroup\$ save another byte with i=8;f(j){for(;i--;: Try it online! \$\endgroup\$
    – naffetS
    Commented Sep 22, 2022 at 18:36
  • \$\begingroup\$ oh, for some reason, I thought this was a full program. you can still do the (i&2)/2 => i%4/2 tho \$\endgroup\$
    – naffetS
    Commented Sep 22, 2022 at 19:58
  • 1
    \$\begingroup\$ 90 rearranging the output? \$\endgroup\$
    – AZTECCO
    Commented Sep 23, 2022 at 0:41
3
\$\begingroup\$

Regenerate -a, 42 bytes

1.(f[34] e[56] 2.g4|g4 e[56] 2.f[34]) Qh4#

Attempt This Online!

Explanation

The logic is a bit clunkier than I'd like, but Regenerate doesn't have any string-based conditionals (yet).

1.(f[34] e[56] 2.g4|g4 e[56] 2.f[34]) Qh4#
1.                                          Match 1.
  (                |                )       Then match one of these two patterns:
   f[34]                                      f3 or f4
         e[56]                                followed by e5 or e6
               2.g4                           followed by 2.g4
                                            or
                    g4                        g4
                       e[56]                  followed by e5 or e6
                             2.f[34]          followed by 2.f3 or 2.f4
                                      Qh4#  Finally, match Qh4#
                                            The -a flag outputs all possible matches
\$\endgroup\$
1
  • \$\begingroup\$ Yea that giant (...|...) spanning most of the string stopped me from attempting this :P \$\endgroup\$ Commented Sep 22, 2022 at 18:04
3
\$\begingroup\$

Retina 0.8.2, 62 60 bytes


g4#f3¶f3#g4
#
 e5 2.
.+
1.$& Qh4#
3
$&$%'¶$%`4
5
$&$%'¶$%`6

Try it online! Edit: Saved 2 bytes thanks to @DLosc. Explanation:


g4#f3¶f3#g4

Insert the two pawn orders for White.

#
 e5 2.

Insert Black's first move in between each pair.

.+
1.$& Qh4#

Append Black's second move to each pair.

3
$&$%'¶$%`4

Duplicate each game but with f3 changed to f4.

5
$&$%'¶$%`6

Duplicate each game but with e5 changed to e6.

\$\endgroup\$
1
  • \$\begingroup\$ 60 bytes \$\endgroup\$
    – DLosc
    Commented Sep 22, 2022 at 18:48
3
\$\begingroup\$

Python 3, 76 bytes

print('1.%s%s e%%s 2.%s%s Qh4#\n'*4%(*'g4f3g4f4f4g4f3g4',)*2%(*'55556666',))

Try it online!

Can definitely be improved.

Python 3, 73 bytes

for x in 5,6:print(f'1.%c%c e{x} 2.%c%c Qh4#\n'*4%(*'g4f3g4f4f3g4f4g4',))

Try it online!

This is 3 bytes shorter, but prints an empty line in the middle.

\$\endgroup\$
3
  • \$\begingroup\$ @solid.py the 4%( isn't a single phrase; it can be more accurately broken down into <string1>*4%<string2>, where the string1 is first multiplied by 4 (i.e. repeated four times), then the string formatting operator % is used to replace the %ss in string1 with string2. \$\endgroup\$ Commented Sep 23, 2022 at 22:12
  • \$\begingroup\$ @97.100.97.109 I think that fails Arnauld's checker. I wish something like that worked though! \$\endgroup\$ Commented Sep 23, 2022 at 22:34
  • \$\begingroup\$ Yeah, my apologies. \$\endgroup\$ Commented Sep 23, 2022 at 22:37
3
\$\begingroup\$

Whitespace, 380 378 bytes

[S S S T    S S S N
_Push_n=8][N
S S N
_Create_Label_LOOP][S S S T N
_Push_1][T  S S T   _Subtract:_n=n-1][S N
S _Duplicate_n][N
T   T   S N
_If_negative_Jump_to_Label_EXIT][S S S T    N
_Push_1][T  N
S T _Print_as_number][S S S T   S T T   T   S N
_Push_46_.][T   N
S S _Print_as_character][S N
S _Duplicate_n][S S S T S S N
_Push_4][T  S T S _Integer_divide][S S S T  T   S S T   T   S N
_Push_102][T    S S S _Add][T   N
S S _Print_as_character][S S S T    S S N
_Push_4][S S S T    T   N
_Push_3][S T    S S T   S N
_Copy_0-based_2nd:_n][S S S T   S N
_Push_2][T  S S S _Add][T   S T S _Integer_divide][T    S S T   _Subtract][T    N
S T _Print_as_number][S S S T   S S S S S N
_Push_32_<space>][T N
S S _Print_as_character][S S S T    T   S S T   S T N
_Push_101_e][T  N
S S _Print_as_character][S N
S _Duplicate_n][S S S T S N
_Push_2][T  S T T   _Modulo][S S S T    T   S N
_Push_6][S N
T   _Swap_top_two][T    S S T   _Subtract][T    N
S T _Print_as_number][S S S T   S S S S S N
_Push_32_<space>][T N
S S _Print_as_character][S S S T    S N
_Push_2][T  N
S T _Print_as_number][S S S T   S T T   T   S N
_Push_46_.][T   N
S S _Print_as_character][S N
S _Duplicate_n][S S S T S S N
_Push_4][T  S T S _Integer_divide][S S S T  T   S S T   T   T   N
_Push_103][S N
T   _Swap_top_two][T    S S T   _Subtract][T    N
S S _Print_as_character][S N
S _Duplicate_n][S S S T T   S N
_Push_6][T  S T S _Integer_divide][S S S T  S S N
_Push_4][S N
T   _Swap_top_two][T    S S T   _Subtract][T    N
S T _Print_as_number][S S S T   S S S S S N
_Push_32_<space>][T N
S S _Print_as_character][S S S T    S T S S S T N
_Push_81_Q][T   N
S S _Print_as_character][S S S T    T   S T S S S N
_Push_108_h][T  N
S S _Print_as_character][S S S T    S S N
_Push_4][T  N
S T _Print_as_number][S S S T   S S S T T   N
_Push_35_#][T   N
S S _Print_as_character][S S S T    S T S N
_Push_10_\n][T  N
S S _Print_as_character][N
S N
N
_Jump_to_Label_LOOP]

Letters S (space), T (tab), and N (new-line) added as highlighting only.
[..._some_action] added as explanation only.

Try it online (with raw spaces, tabs and new-lines only).

Explanation in pseudo-code:

Port of @jdt's C answer, with 3+(i>1) replaced with 4-3/(n+2):

Integer n = 8
Start LOOP:
  n = n - 1
  If (n < 0):
    Stop program with an error, by jumping to an undefined label
  Print "1."
  Print n//4+102 as character
  Print 4-3//(n+2) as integer
  Print " e"
  Print 6-n%2 as integer
  Print " 2."
  Print 103-n//4 as character
  Print 6-n//4 as integer
  Print " Qh4#\n"
  Go to next iteration of LOOP
\$\endgroup\$
2
\$\begingroup\$

05AB1E, 37 36 bytes

56āÌ'fìâ„g4δšDí«ε`"1.ÿ eÿ 2.ÿ Qh4#",

Try it online.

If outputting as a list of lines is allowed, the trailing ", can be removed for -2 bytes: try it online.

Explanation:

56            # Push 56
  ā           # Push a list in the range [1,length] (without popping): [1,2]
   Ì          # Increase each by 2: [3,4]
    'fì      '# Prepend an "f" to each: ["f3","f4"]
       â      # Get the cartesian product of these two:
              #  [[5,"f3"],[5,"f4"],[6,"f3"],[6,"f4"]]
          δ   # Map over each inner list:
        „g4 š #  Prepend string "g4" to the list
              #   [["g4",5,"f3"],["g4",5,"f4"],["g4",6,"f3"],["g4",6,"f4"]]
D             # Duplicate this list of lists
 í            # Reverse each inner list:
              #  [["f3",5,"g4"],["f4",5,"g4"],["f3",6,"g4"],["f4",6,"g4"]]
  «           # Merge the two lists together
ε             # Foreach over each inner list:
 `            #  Pop and push the items of the list to the stack
  "1.ÿ eÿ 2.ÿ Qh4#"
              #  Push this string, where the `ÿ` are automatically one by one filled
              #  with the items
    ,         #  Pop and print it with trailing newline
\$\endgroup\$
1
\$\begingroup\$

Charcoal, 37 bytes

FE34⁺g4fιF⪪ι²E56⪫⟦1.⁻ικ eλ 2.κ Qh4#⟧ω

Try it online! Link is to verbose version of code. Explanation:

FE34⁺g4fι

Loop over the strings g4f3 and g4f4 representing the alternatives for White's pairs of moves.

F⪪ι²

Loop over each of White's possible moves from the current pair.

E56⪫⟦1.⁻ικ eλ 2.κ Qh4#⟧ω

Map over the characters 5 and 6 and output the following joined together for each line:

  • The literal string 1.
  • The other move for White from the current pair
  • The literal string e
  • The character 5 or 6 from the innermost loop
  • The literal string 2.
  • The move for White from the inner loop
  • The literal string Qh4#
\$\endgroup\$
1
\$\begingroup\$

Jelly, 37 bytes

“ḲṚẉċ‘ḤD“feg”żⱮ;Ṛ€$“1.““2.“Qh4#”żⱮK€Y

A full program that prints the eight games.

Try it online!

“ḲṚẉċ‘ḤD“feg”żⱮ;Ṛ€$“1.““2.“Qh4#”żⱮK€Y - Main Link: no arguments
“ḲṚẉċ‘                                - code-page indices = [177,182,227,232]
      Ḥ                               - double           -> [354,364,454,464]
       D                              - decimal digits   -> [[3,5,4],[3,6,4],[4,5,4],[4,6,4]]
        “feg”                         - "feg"
             żⱮ                       - map with zip     -> [[['f',3],['e',5],['g',4]],[['f',3],['e',6],['g',4]],[['f',4],['e',5],['g',4]],[['f',4],['e',6],['g',4]]]
                  $                   - last two links as a monad:
                Ṛ€                    -   reverse each   -> [[['g',4],['e',5],['f',3]],[['g',4],['e',6],['f',3]],[['g',4],['e',5],['f',4]],[['g',4],['e',6],['f',4]]]
               ;                      -   concatenate    -> [[['f',3],['e',5],['g',4]],[['f',3],['e',6],['g',4]],[['f',4],['e',5],['g',4]],[['f',4],['e',6],['g',4]],[['g',4],['e',5],['f',3]],[['g',4],['e',6],['f',3]],[['g',4],['e',5],['f',4]],[['g',4],['e',6],['f',4]]]
                   “1.““2.“Qh4#”      - ["1.","","2.","Qh4#"]
                                żⱮ    - map with zip     -> [[["1.",['f',3]],[[],['e',5]],["2.",['g',4]],["Qh4#"]],[["1.",['f',3]],[[],['e',6]],["2.",['g',4]],["Qh4#"]],[["1.",['f',4]],[[],['e',5]],["2.",['g',4]],["Qh4#"]],[["1.",['f',4]],[[],['e',6]],["2.",['g',4]],["Qh4#"]],[["1.",['g',4]],[[],['e',5]],["2.",['f',3]],["Qh4#"]],[["1.",['g',4]],[[],['e',6]],["2.",['f',3]],["Qh4#"]],[["1.",['g',4]],[[],['e',5]],["2.",['f',4]],["Qh4#"]],[["1.",['g',4]],[[],['e',6]],["2.",['f',4]],["Qh4#"]]]
                                  K€  - space-join each  -> [["1.",['f',3],' ',[],['e',5],' ',"2.",['g',4],' ',"Qh4#"],["1.",['f',3],' ',[],['e',6],' ',"2.",['g',4],' ',"Qh4#"],["1.",['f',4],' ',[],['e',5],' ',"2.",['g',4],' ',"Qh4#"],["1.",['f',4],' ',[],['e',6],' ',"2.",['g',4],' ',"Qh4#"],["1.",['g',4],' ',[],['e',5],' ',"2.",['f',3],' ',"Qh4#"],["1.",['g',4],' ',[],['e',6],' ',"2.",['f',3],' ',"Qh4#"],["1.",['g',4],' ',[],['e',5],' ',"2.",['f',4],' ',"Qh4#"],["1.",['g',4],' ',[],['e',6],' ',"2.",['f',4],' ',"Qh4#"]]
                                    Y - newline-join     -> ["1.",['f',3],' ',[],['e',5],' ',"2.",['g',4],' ',"Qh4#",'\n',"1.",['f',3],' ',[],['e',6],' ',"2.",['g',4],' ',"Qh4#",'\n',"1.",['f',4],' ',[],['e',5],' ',"2.",['g',4],' ',"Qh4#",'\n',"1.",['f',4],' ',[],['e',6],' ',"2.",['g',4],' ',"Qh4#",'\n',"1.",['g',4],' ',[],['e',5],' ',"2.",['f',3],' ',"Qh4#",'\n',"1.",['g',4],' ',[],['e',6],' ',"2.",['f',3],' ',"Qh4#",'\n',"1.",['g',4],' ',[],['e',5],' ',"2.",['f',4],' ',"Qh4#",'\n',"1.",['g',4],' ',[],['e',6],' ',"2.",['f',4],' ',"Qh4#"]
                                      - implicit, smashing print
\$\endgroup\$
1
\$\begingroup\$

MATLAB, 72 bytes

Somewhat straight-forward, but it's not how the tutorial tells you to do it. Uses this little-known syntax.

function a b

is equivalent to

function('a','b')

Which means that two string inputs 'a' and 'b' can be entered a b instead of ('a','b'), saving 6 bytes.


First make a string template that is equal to a row, but with "wild cards" for the characters that varies. All strings have 1., e, 2., Qh4#\n. All other characters are stored in the string in the end.

I tried to find a way to use the pattern with similarities between rows, but string manipulation is verbose in Octave.

printf 1.%c%c e%c 2.%c%c Qh4#\n f35g4f36g4f45g4f46g4g45f3g45f4g46f3g46f4

Try it online!

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

C (gcc), 156 131 130 111 105 103 90 bytes

Some bytes lost because of @Steffan.

main(i){for(;i++<9;printf("1.%c%d e%d 2.%c%d Qh4#\n",102|i>5,4-3/i,5+i%2,102|i<6,4-i/8));}

Explained:

  • import modules
  • declare main
  • declare iterator
  • keep looping 8 times
    • print according to the format specifiers
      • if i is lesser than 5, the first character is f, else g
      • if i is less than 3, the first number is 3, else 4
      • if i is odd and is less than six, or is six, then 5, else 6
      • if i is less than 5, then 'g', else 'f'
      • if i is less than 5 or is even, then 4, else 3.
    • add a newline
\$\endgroup\$
2
  • \$\begingroup\$ 111 bytes \$\endgroup\$
    – naffetS
    Commented Sep 22, 2022 at 18:30
  • 1
    \$\begingroup\$ it may look like bitwise tricks, but not really: ~i&1 is the same as !(i%2), I changed some ||s to |, and also, like, at first, I golfed i<5?'f':'g' to 102+(i>4) (charcodes), but then golfed it more to 102|i>4 because of precedence. \$\endgroup\$
    – naffetS
    Commented Sep 22, 2022 at 18:31
0
\$\begingroup\$

Python 3, 118 bytes

for f in 0,1:
 x='f3','f4';y='g4',
 if f:y,x=x,y
 [print(f'1.{w} e{r} 2.{W} Qh4#')for w in x for W in y for r in[5,6]]

Try it 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.