MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn moreOpportunities for recent engineering grads.

Apply TodayImplement the solitaire cipher.

Since this is from Wikipedia, I am capturing the algorithm now in case there are edits.

**Keystream Algorithm**

This algorithm assumes that the user has a deck of cards and two jokers which are distinguishable from each other. For simplicity's sake, only two suits will be used in this example. Each card will be assigned a numerical value: the first suit of cards will be numbered from 1 to 13 (Ace through King) and the second suit will be numbered 14 through 26 in the same manner. The jokers will be assigned the values of 27 and 28. Thus, a 5 from the first suit would have the value 5 in our combined deck, the value 1 in the second suit would have the value 14 in the combined deck.

The deck will be assumed to be a circular array, meaning that should a card ever need to advance below the bottom card in the deck, it will simply rotate back to the top (in other words, the first card follows the last card).

Arrange the deck of cards face-up according to a specific key. This is the most important part as anyone who knows the deck's starting value can easily generate the same values from it. How the deck is initialized is up to the recipients, shuffling the deck perfectly randomly is preferable, although there are many other methods. For this example, the deck will simply start at 1 and count up by 3's, modulo 28. Thus the starting deck will look like this:

1 4 7 10 13 16 19 22 25 28 3 6 9 12 15 18 21 24 27 2 5 8 11 14 17 20 23 26

Locate the first joker (value 27) and move it down the deck by one place, basically just exchanging with the card below it. Notice that if it is the last card, it becomes the second card. There is no way to become the first card. The deck now looks like this:

1 4 7 10 13 16 19 22 25 28 3 6 9 12 15 18 21 24 2 *27* 5 8 11 14 17 20 23 26

Locate the second joker (value 28) and move it down the deck by two places. Notice that if it is the second to last card, it becomes the second card by wrapping around. If it is the last card, it becomes the third card. There is no way to become the first card.

1 4 7 10 13 16 19 22 25 3 6 *28* 9 12 15 18 21 24 2 27 5 8 11 14 17 20 23 26

Perform a triple-cut on the deck. That is, split the deck into three sections. Everything above the top joker (which, after several repetitions, may not necessarily be the first joker) and everything below the bottom joker will be exchanged. The jokers themselves, and the cards between them, are left untouched.

*5 8 11 14 17 20 23 26* 28 9 12 15 18 21 24 2 27 *1 4 7 10 13 16 19 22 25 3 6*

Observe the value of the card at the bottom of the deck, if the card is either joker let the value just be 27. Take that number of cards from the top of the deck and insert them back to the bottom of the deck just above the last card.

23 26 28 9 12 15 18 21 24 2 27 1 4 7 10 13 16 19 22 25 3 *5 8 11 14 17 20* 6

Note the value of the top card. Count this many places into the deck and take the value of the card there. This value is the next value in the keystream, in this example it would be 8. (Note that no cards are changing places in this step, this step simply determines the value).

Repeat steps 2 through 6 for as many keystream values as required.

It is worth noting that because steps 2 and 3 have the wrap around feature, there are two configurations that can lead the same configuration on a step. For instance when the little joker is on the bottom or top of the deck it will become the second card. This means the algorithm is not always reversible.

Given a starting set of numbers, deck, generate N values for the keystream.

109 correct solutions
61 incorrect solutions

Last solution submitted on Dec 19, 2014

2 players like this problem

3 Comments

Jan Orwat
on 17 Sep 2014

Sorry for resubmitting an old regexp solution. Seems, that previous one disappeared. I have to solve this problem the proper way.

Paul Berglund
on 18 Sep 2014

I think that this solution is perfectly legitimate. Why try to solve it "properly"? It's not like you are using eval or something like that. regexprep is a perfectly legitimate tool to use.

Jan Orwat
on 18 Sep 2014

I agree with your point of view. Regexprep is a powerful function here.
Unfortunately I've used also '(??@some_code)'. In this case, it's not as bad as playing 'size=11' solution, but it is still a kind of size-cheating for me. I used to play solutions like that, but now I try to avoid this.

1 Comment

Jon
on 17 Sep 2014

At the time of submission, all better scores use either a lookup table or regexp.

1 player likes this solution

1 Comment

Christopher
on 1 Feb 2013

Whoops! forgot to add in semicolons to supress 'debugging' output.

13 Comments