Rolling Dice Python

Question:

I’m trying to solve the following problem:

From the input you will get a number. Find all the ways you can get this number when throwing two dice. Print the result as a list of tuples. In each tuple print the smaller number first. Sort the tuples by the first number. If there is no way to get the given number when throwing two dice, simply print an empty list.
With Input: 8
Output: [(2, 6), (3, 5), (4, 4)]

My code is the following:

dice = tuple(n for n in range(0,7))
dice2 = tuple(n for n in range(0,7)) 
value = int(input())
dice_values = []
def dice_calc(value):
    for x in dice:
        for x1 in dice2:
            if x + x1 == value or x1 + x == value:
                dice_values.append((x, x1))
    return dice_values

print(dice_calc(value))

but I’m receiving the following output:

[(2, 6), (3, 5), (4, 4), (5, 3), (6, 2)]

How can I modify my code in the way that the output is the same of the requested one?

Asked By: Disobey1991

||

Answers:

Starting with the output you’ve been able to generate so far:

>>> result = [(2, 6), (3, 5), (4, 4), (5, 3), (6, 2)]

let’s sort the individual pairs:

>>> [sorted(t) for t in result]
[[2, 6], [3, 5], [4, 4], [3, 5], [2, 6]]

and turn them back into tuples:

>>> [tuple(sorted(t)) for t in result]
[(2, 6), (3, 5), (4, 4), (3, 5), (2, 6)]

Now let’s get rid of the duplicates by putting them in a set instead of a list (note that we had to convert them to tuples first because you can have a set of tuples but you can’t have a set of lists):

>>> {tuple(sorted(t)) for t in result}
{(4, 4), (2, 6), (3, 5)}

and turn that set into a sorted list:

>>> sorted({tuple(sorted(t)) for t in result})
[(2, 6), (3, 5), (4, 4)]

producing the final desired output.

Answered By: Samwise

To be a bit more efficient(actually half the calculations), as you know that the second dice should be larger you can shift the loop:

dice = range(1,7) # you want to start at 1
# dice two will be dynamicly choosen
value = int(input())
dice_values = []
def dice_calc(value):
    for x in range(1,7):
        for x1 in range(x, 7):
            if x + x1 == value:
                dice_values.append((x, x1))
    return dice_values

print(dice_calc(value))

With list comprehensions you can further improve the performance but on cost on readability.

Output
[(2, 6), (3, 5), (4, 4)]

Answered By: Daraan

I would use a dictionary with setdefault (or a defaultdict) to build a list of the pairs without duplicates:

d = {}
for d1 in range(1, 7):
    for d2 in range(d1, 7):
        d.setdefault(d1+d2, []).append((d1, d2))

d[desired_sum]

Example:

d[8]
# [(2, 6), (3, 5), (4, 4)]

d:

{2: [(1, 1)],
 3: [(1, 2)],
 4: [(1, 3), (2, 2)],
 5: [(1, 4), (2, 3)],
 6: [(1, 5), (2, 4), (3, 3)],
 7: [(1, 6), (2, 5), (3, 4)],
 8: [(2, 6), (3, 5), (4, 4)],
 9: [(3, 6), (4, 5)],
 10: [(4, 6), (5, 5)],
 11: [(5, 6)],
 12: [(6, 6)]}
Answered By: mozway

Replace

for x1 in dice2:
  if x + x1 == value or x1 + x == value:

with

for x1 in range(x:7):
  if x + x1 == value:

Reason you can not tell the difference between dice one and two after they are played. Hence (2,1) is the same thing as (1,2).

Answered By: Luca Furrer
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.