There seems to be a typo in the post, or an intentional fakeout.
The setup says the cards are
in a pile with their backs facing up
meaning the deck is facing down, but the question asks whether it
will ever have all the cards face up again?
The deck has not previously been facing up, so I'll err on the side of caution and take it that the question asks whether the pile will face up more than once when shuffled in the described manner and starting face down.
EDIT: The following up to and including the C++ code has been proven wrong.
Since we are drawing cards in order, whenever the sum of cards flipped is a multiple of 52, the entire deck will be either facing up or down. The deck starts face down, so it will be face down again only when we've flipped a multiple of 104 cards. Ergo it faces up when the number of cards flipped is divisble by 52 but not 104.
I wrote a short, somewhat optimized C++ snippet to determine when the desired states are reached. Here are the highlights of the output:
All cards are facing down after 49 primes! (last prime: 227)
All cards are facing down after 87 primes! (last prime: 449)
All cards are facing up after 117 primes! (last prime: 643)
All cards are facing down after 119 primes! (last prime: 653)
All cards are facing down after 131 primes! (last prime: 739)
All cards are facing down after 179 primes! (last prime: 1063)
All cards are facing down after 203 primes! (last prime: 1237)
All cards are facing up after 319 primes! (last prime: 2113)
And here the code:
#include <iostream>
// Returns whether the given number n > 3 is a prime.
bool isPrime(long n) {
if(n%2 == 0 || n%3 == 0) return false;
for(int i = 6; (i-2)*i + 1 <= n; i += 6) {
if(n % (i-1) == 0) return false;
if(n % (i+1) == 0) return false;
}
return true;
}
// Returns the closest prime larger than the given number.
int nextPrime(int n) {
while(!isPrime(++n)) { continue; }
return n;
}
int main() {
const short DECK_SIZE = 52;
short faceUp = 5;
unsigned int steps = 2;
long prime = 3;
unsigned short timesDeckWasFaceUp = 0;
while(timesDeckWasFaceUp != 2) {
do { // Run until all cards are facing up again.
prime = nextPrime(prime);
++steps;
// Number of cards to flip this turn.
short flips = prime % DECK_SIZE;
std::cout << "Face up: " << (faceUp > DECK_SIZE ? (DECK_SIZE << 1) - faceUp : faceUp) << "\nPrime: " << prime << "\nFlipping: " << flips << " cards.\n\n";
faceUp = (faceUp + flips) % (DECK_SIZE << 1);
if(faceUp % DECK_SIZE == 0) { // Entire deck faces in one direction
if(faceUp) {
std::cout << "All cards are facing up after " << steps << " primes! (last prime: " << prime << ")\n";
++timesDeckWasFaceUp;
break;
} else {
std::cout << "All cards are facing down after " << steps << " primes! (last prime: " << prime << ")\n";
}
}
} while(faceUp % (DECK_SIZE << 1) != 0);
}
return 0;
}
EDIT: Here the revised code that accounts for the fact that the order of the flipped cards gets reversed.
#include <iostream>
#include <deque>
// Checks if the given number > 3 is a prime.
bool isPrime(unsigned long long n) {
if(n%2 == 0 || n%3 == 0) return false;
for(unsigned long long i = 6; (i-2)*i + 1 <= n; i += 6) {
if(n % (i-1) == 0) return false;
if(n % (i+1) == 0) return false;
}
return true;
}
// Returns the nearest prime larger than the given number.
unsigned long long nextPrime(unsigned long long n) {
while(!isPrime(++n)) { continue; }
return n;
}
void flipCards(int flips, std::deque<bool>& cards, unsigned short& counter) {
// Flip the order of the top cards
std::reverse(cards.begin(), cards.begin() + flips);
// Turn each card around
std::deque<bool> flipped(cards.begin(), cards.begin() + flips);
for(bool& card : flipped) {
counter += (card) ? -1 : 1;
card = !card;
}
// Remove the cards from the top
std::deque<bool>(cards.begin()+flips, cards.end()).swap(cards);
// Add them to the bottom
cards.insert(cards.end(), flipped.begin(), flipped.end());
}
int main() {
const short DECK_SIZE = 52;
// Keep track of how many cards are facing down.
unsigned short faceUp = 0;
std::deque<bool> cards(52);
// Flip the first two primes (2 + 3).
flipCards(5, cards, faceUp);
// Keep track of the number of primes flipped.
unsigned int steps = 2;
unsigned long long prime = 3;
unsigned short timesFaceUp = 0;
while(timesFaceUp != 2) {
// Run until no more cards are facing down.
while(true) {
prime = nextPrime(prime);
++steps;
// Number of cards to flip this turn.
unsigned short flips = prime % 52;
flipCards(flips, cards, faceUp);
if(faceUp % 52 == 0) {
if(faceUp) {
std::cout << "All cards are facing up after " << steps << " primes! (last prime: " << prime << ")\n";
++timesFaceUp;
break;
} else {
std::cout << "All cards are facing down after " << steps << " primes! (last prime: " << prime << ")\n";
}
}
}
}
return 0;
}
I'm afraid Weather Vane's answer may be correct.