24
$\begingroup$

Golf is a form of patience (solitaire) in which you must remove cards from several tableaus, leaving as few as possible. Today, though, we're doing a round of Minigolf instead. Unlike Golf, there are 5 stacks, the cards only go up to 7, and there is no draw pile.

Here is the deal:

6,2,3,5,5; 7,7,1,4,2; 3,1,7,2,4; 4,1,3,3,2; 1,5,5,6,4

To begin, remove any exposed card. After that, remove exposed cards with a value one higher or one lower than the previous card, until you can't remove any more cards.

Note that 'A' is considered to be adjacent to both '7' and '2'.

Try to remove every card and get a hole in one!

$\endgroup$
23
$\begingroup$

Whilst I tried to split things logically into blocks (e.g. working forwards to a point, then working backwards from the end to see what else was left, and thus needed to be used first), this was mostly done by trial and error, so there's not really any "steps" to show beyond the final "hole in one" solution:

solution

Or in animated form for intuitive verification:

animated

| improve this answer | |
$\endgroup$
  • $\begingroup$ What dedication! $\endgroup$ – Ébe Isaac Jan 28 at 7:33
7
$\begingroup$

I found a different answer by writing a python program to brute force find the solution using a depth first search(go as deep as possible until you can't make any more moves and then backtrack). I have't created an animation like they did to show the solution but I will show the output of the program and how to interpret it so that you can verify the solution.

Program output: (True, [3, 3, 1, 3, 1, 0, 4, 0, 4, 4, 2, 0, 2, 1, 1, 3, 2, 2, 0, 2, 3, 4, 0, 1, 4])

The list of numbers represents the index of the stack to pull off at each step. Note that it's 0 indexed, so 0 means pull off the leftmost stack. 2, for example, means pull off the third from the left stack.

Source Code

def duplicate_stacks(stacks):
    return [stack[:] for stack in stacks]

def solve(stacks, last_played=None, past_moves=[]):
    if all(len(stack)==0 for stack in stacks):
        return True, past_moves

    allowed_numbers = []
    if not last_played:
        allowed_numbers = [1,2,3,4,5,6,7]
    else:
        allowed_numbers.append(last_played % 7 + 1) 
        allowed_numbers.append((last_played-1) or 7) 

    allowed_moves = [] 
    for i, stack in enumerate(stacks):
        if len(stack) > 0 and stack[0] in allowed_numbers:
            allowed_moves.append(i)

    for move in allowed_moves:
        new_stacks = duplicate_stacks(stacks)
        last_played = new_stacks[move].pop(0)
        solved, moves = solve(new_stacks, last_played, past_moves + [move])
        if solved:
            return solved, moves

    return False, past_moves

question_stacks = [
    [5,5,3,2,6],
    [2,4,1,7,7],
    [4,2,7,1,3],
    [2,3,3,1,4],
    [4,6,5,5,1]
]

print(solve(question_stacks))
| improve this answer | |
$\endgroup$
  • $\begingroup$ The code shouldn't be considered a spoiler right? $\endgroup$ – Cruncher Jan 28 at 17:27
  • $\begingroup$ I don't think you need a spoiler tag for the code, it's a fairly standard algorithm, and it's no help unless you actually run it. Incidentally, I used a DFS to produce this puzzle as well. $\endgroup$ – Woofmao Jan 28 at 17:53
  • $\begingroup$ @Woofmao How did you do that to guarantee something with a unique solution? $\endgroup$ – Cruncher Jan 28 at 17:56
  • $\begingroup$ The solution isn't unique - your solution and @Alconja differ in the 5th move. I just generated random solvable deals until I found one reasonably difficult to solve by hand. $\endgroup$ – Woofmao Jan 28 at 18:39
  • $\begingroup$ @Woofmao Ah interesting. I didn't actually notice that they differed, I didn't look that closely. Just noticed that the first few moves were the same, so it was likely the same $\endgroup$ – Cruncher Jan 28 at 18:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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