Accordion Solitaire: Which First Moves Can I Make?

1

1

Introduction:

Unfortunately an Accordion Solitaire Solver challenge already exists (Solve a game of Accordion), so instead this easier related challenge.

Let's start by explaining how Accordion Solitaire works:

  1. You start with all 52 cards (or 53 if you add a Joker) in one big row.
  2. You pile up cards from right to left that are either adjacent, or have two cards in between them.
    1. This can either be when they are the same suit
    2. Or when they have the same value

For example, let's say we start with this: HK S8 SK DK, then you'd have these possible game scenarios:

  1. S8←SK, resulting in HK SK DK; SK←DK, resulting in HK DK; HK←DK, resulting in DK.
  2. SK←DK, resulting in HK S8 DK.
  3. HK←DK, resulting in DK S8 SK; S8←SK, resulting in DK SK; DK←SK, resulting in SK.

You win when every card is in a single pile in the end, so the game scenarios 1 and 3 would be a won Accordion Solitaire, but in scenario 2 you would have lost.

NOTE: Symbols used are as follows: H=Hearts; S=Spades; D=Diamonds; C=Clubs. T=10; J=Jack; Q=Queen; K=King; A=Ace. J=Joker.

PS: Irrelevant for this challenge, but added for informational purposes for those interested: if you play Accordion Solitaire with Jokers, you can only use each Joker once. The Joker will be put at the bottom of the pile when paired up. I.e. H4 C4 S4 J could have for example the following game scenario: S4←J, resulting in H4 C4 S4 (so NOT H4 C4 J); C4←S4 resulting in H4 S4; H4←S4 resulting in S4.

Challenge:

Given a row of cards, output all first steps we can make. So with the example HK S8 SK DK above, the result would be ["S8←SK","SK←DK","HK←DK"].

Challenge rules:

  • Not all inputs can have a move. So a test case like H3 C7 S5 CQ will result in an empty output, because no moves can be made.
  • Jokers will be added, which can be used as any wild card, so it can always pair up with up to four other cards (depending on its position).
  • Input and output formats are flexible, but you'll have to use the formats specific (with optionally 10 instead of T). Input can be a single space-delimited string; list of strings, characters; map with suit + value; etc. Output can be a single delimited string, pairs output to STDOUT, list of pairs, etc. (the character to indicate moves - for which I've used in the example above - can also be anything you'd like, and the order of the pairs could also be reversed (i.e. ["SK→S8","DK→SK","DK→HK"])). Please state what you've used in your answer!
  • Order of the list in the output doesn't matter (i.e. ["SK←DK","S8←SK","HK←DK"] is valid as well).
  • There won't be any test cases with duplicated cards (including Jokers). So we can assume the test cases use a single Deck of 53 cards (52 + 1 Joker). (So you could use a set instead of list for the output if it would save bytes, since all pairs will be unique.)
  • You are allowed to use 10 instead of T if that's what you prefer. You are not allowed to use JJ (or anything else of 2 characters) for the Jokers; Jokers will always be a single J.

General rules:

  • This is , so shortest answer in bytes wins.
    Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
  • Standard rules apply for your answer, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return-type, full programs. Your call.
  • Default Loopholes are forbidden.
  • If possible, please add a link with a test for your code (i.e. TIO).
  • Also, adding an explanation for your answer is highly recommended.

Test cases:

Input                       Output

"HK S8 SK DK"               ["S8←SK","SK←DK","HK←DK"]
"HA H3 ST"                  ["HA←H3"]
"H3 C7 S5 CQ"               []
"HK S8 J C8 CK"             ["S8←J","J←C8","C8←CA"]
"H5 CA SQ C9 H9 C2 CQ HJ CT SK D3 H8 HA HQ S4 DA H7 SA DK"
                            ["C9←H9","C9←CQ","H9←HJ","C2←CQ","C2←CT","H8←HA","HA←HQ","HA←DA","HQ←H7","S4←SA","DA←DK"]
"CA C2 C3 J H2 H3 D4 H4"    ["CA←C2","CA←J","C2←C3","C2←H2","C3←J","C3←H3","J←H2","J←D4","H2←H3","H2←H4","D4←H4"]
"H4 C4 S4 J"                ["H4←C4","H4←J","C4←S4","S4←J"]
"H3 S3"                     ["H3←S3"]

Kevin Cruijssen

Posted 2018-10-11T11:43:37.487

Reputation: 67 575

Can't the CQ be piled onto the C9 or the C2? – Neil – 2018-10-11T12:06:51.907

@Neil Ah, I somehow completely forgot about the CQ when I created the test case.. Fixed, thanks. – Kevin Cruijssen – 2018-10-11T12:09:47.373

Answers

2

Retina, 60 bytes

L$w`((\bJ)|(\w)(\w)) (\w+ \w+ )?((?(2)..|(J|\3.|.\4)))
$1<$6

Try it online! Link includes test cases. Explanation:

L$
$1<$6

Output the appropriate captures from each match.

w`

Find all overlapping matches (not just simple overlaps).

\b((\bJ)|(\w)(\w)) (\w+ \w+ )?((?(2)..|(J|\3.|.\4)))

Match either the Joker or a two-letter card, then two optional cards, then if the Joker was matched then any other card otherwise either the Joker or a card that matches either in suit or value. (I don't have to check for letters here as there can only be one Joker and the suit and rank can only match another card.)

Neil

Posted 2018-10-11T11:43:37.487

Reputation: 95 035

Nice answer! The only part I don't really understand how it works is ?(2)... Everything else is clear. It checks for each card (((\bJ)|(\w)(\w))) if the one next to it (or optionally with two cards in between ((\w+ \w+ )?)) is a Joker, the same value, or the same suit ((J|\3.|.\4)). But what is the purpose of the ?(2)..? EDIT: I guess it's for when the first card is a Joker? – Kevin Cruijssen – 2018-10-11T12:31:29.193

1@KevinCruijssen (?(2)...|...) is conditional regex; it matches the first alternation if $2 was captured previously and the second alternatiion if not. You could probably do something similar with lookarounds, because you can only look for \2 if it matched earlier. – Neil – 2018-10-11T13:24:03.880

1

Python 3, 124 119 bytes

lambda c:[[v,c[j]]for i,v in enumerate(c)for j in[i+1,i+3]if j<len(c)and any(d[0]==d[1]or"J"in d for d in zip(v,c[j]))]

Try it online!

Credits

  • From 124 to 119 bytes by ovs.

Neil

Posted 2018-10-11T11:43:37.487

Reputation: 2 417