1
\$\begingroup\$

As mentioned in @rolfl comment. What this program does is that it "resequences the cards using a fixed system and count the number of times the resequencing happens before the output is the same as the input."

I was wondering how I could make this program faster or perhaps use less memory. I thought about using dictionaries instead of lists as they have faster look ups. I'm not sure how to decrease the memory size of this program.

num_cards = input("Please enter the number of cards in the deck: ")
def num_of_round(num_cards):
 rounds = 0
 orig_order = range(1,num_cards + 1)
 card_list = list(orig_order)
 table_list = []
 while 1:
 while len(card_list) > 0:
 table_list.append(card_list[0]) # STEP 1: add top card to table
 card_list.remove(card_list[0]) # remove top card from deck
 if len(card_list) == 0: 
 break
 card_list.append(card_list[0]) # STEP 2: after removal of card, put top card on bottom of deck
 card_list.remove(card_list[0]) # update ordering of deck
 rounds += 1 # a round has passed
 table_list.reverse()
 card_list, table_list = table_list, card_list 
 if card_list == orig_order:
 break
 print rounds
num_of_round(num_cards)
200_success
145k22 gold badges190 silver badges478 bronze badges
asked Nov 18, 2013 at 2:16
\$\endgroup\$
4
  • \$\begingroup\$ Is this 'shuffle' code? It appears to resequence the cards using a fixed system and count the number of times the resequencing happens before the output is the same as the input.... right? \$\endgroup\$ Commented Nov 18, 2013 at 2:22
  • \$\begingroup\$ @rolfl yes it is \$\endgroup\$ Commented Nov 18, 2013 at 2:23
  • 1
    \$\begingroup\$ Sounds like if you wanted to, you could reduce this to essentially no memory, and no time, by working out what the function is that describes the problem, and then just do the math rather than doing the actual work \$\endgroup\$ Commented Nov 18, 2013 at 2:27
  • \$\begingroup\$ @rolfl that is something I also considered. I thought it would be too hard to come up with a formula to compute this. \$\endgroup\$ Commented Nov 18, 2013 at 2:31

1 Answer 1

3
\$\begingroup\$

Here is a good opportunity to break out a couple of tools from the standard library.

collections.deque offers fast appends and pops on both ends and is thus perfect to represent your deck of cards, when you take cards from the top and put some back to the bottom.

itertools.cycle can be used to switch between the two destinations of the cards: the top of the pile (table_list.appendleft) and the bottom of the deck (card_list.append). Using appendleft there avoids the need to reverse the pile each round.

Also, a while True loop with a round += 1 inside could be a for round ... loop instead.

from collections import deque
from itertools import cycle, count
def num_of_round(num_cards):
 orig_order = deque(xrange(num_cards))
 card_list = deque(orig_order)
 table_list = deque()
 for rounds in count(1):
 appendfunc = cycle((table_list.appendleft, card_list.append))
 while card_list:
 append = next(appendfunc)
 append(card_list.popleft())
 card_list, table_list = table_list, card_list 
 if card_list == orig_order:
 return rounds
answered Nov 19, 2013 at 21:43
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.