Link to home
Start Free TrialLog in
Avatar of nachtmsk
nachtmskFlag for United States of America

asked on

Perl/Python -- probability

Hi,
My  7th grader has a probability problem I am trying to write a small script for.

"If you have a spinner with three letters on on (K,V and H) and you spin it three times, list all possible outcomes."
The number of outcomes is 27. I won't list them all here, but it's along the lines of KKK, KVH, VHK, VVK, etc... you get the idea. We have them all listed out already and the HW problem is solved.

I was thinking a small perl script would be fun to write to calculate this. But it's harder then I anticipated. I created an AOA but I can't figure out how to loop through it to get every combo.

I tried a nested for loop but that's not working.

@letters = (
['K','V','H'],
['K','V','H'],
['K','V','H'],
);

for ($i=0; $i<3; $i++){


        for ($j=0; $j<3; $j++){
        print "i=$i, j=$j\n";
        print $letters[$i][$j];
        }
print "\n";
}

I am posting this in Python also as I could do it in python if I can get the logic right.

Thanks!
Nacht
ASKER CERTIFIED SOLUTION
Avatar of gelonida
gelonida
Flag of France image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of nachtmsk

ASKER

Thanks! Would love to see the manual solution later. I'm still working on it myself.
This is one potential explicit solution:
#!/usr/bin/env python

# make print identical for python 2 and 3
from __future__ import print_function 

letters = [
 ['K', 'V', 'H'],   # spinner 1
 ['k', 'v', 'h'],   # spinner 2
 ['<K>', '<V>', '<H>'],   # spinner 3
]

current_indexes = [0] * len(letters)
# in this example we would start with [0, 0, 0]


def show_combination(indexes):
    # displays the current combination
    current_letters = []
    # for debugging
    print(indexes, end=": ")
    for index, letter_set in zip(indexes, letters):
        print(letter_set[index], end=" ")
    print("")

def next_combination():
    for i in range(len(current_indexes)):
        # increment one index by one
        current_indexes[i] += 1
    
        # just for debugging:
        print("dbg: increment pos %d by 1 and got %d (%s)" %
            (i, current_indexes[i], current_indexes))

        # if index in range we found a new combination
        if current_indexes[i] < len(letters[i]):
            return True
        current_indexes[i] = 0
        print("dbg: reset pos %d to 0 (%s)" %
            (i, current_indexes))
    # if we are here we exhausted all possibilities
    return False

while True:
    show_combination(current_indexes)
    if not next_combination():
        break

Open in new window

net use * \\computername\sharename password /user:computername\username
@David Johnson: ????
David Johnson must have been posting an answer to a different question
Think so as well. Just thought if he gets an answer, then he sees he posted to the wrong group and can post to the right one.
The other person will probably very happy to get this reply.
Thanks for your code. Won't get to try it until later today. Weekend stuff taking over right now.
No issues don't hesitate to ask any questions in case you want some clarification about the code:

One function, that you might not know is zip:
https://docs.python.org/2/library/functions.html#zip

There could also be an recursive implementation. which is probably a little shorter, but perhaps slower and more difficult to get your head around.
And here just for fun a recursive solution with generators:
#!/usr/bin/env python

example_letter_sets = [
 ['K', 'V', 'H'],   # spinner 1
 ['k', 'v', 'h'],   # spinner 2
 ['<K>', '<V>', '<H>'],   # spinner 3
]

def allcombinations(letter_sets):
    if letter_sets == []:
        yield []
    else:
        first_letterset = letter_sets[0]
        other_lettersets = letter_sets[1:]
        for letter in first_letterset:
            for other_combination in allcombinations(other_lettersets):
                yield [ letter ] + other_combination

for combination in allcombinations(example_letter_sets):
    print(combination)

Open in new window


Relevant links
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks to both of you for the perl and Python solutions. In the end I like the itertools solution best just because it's easiest and I don't really need to wrap my head around recursion which is something I haven't had to do in a while. But I really appreciate the full code example and they will come in handy in the near future when I have some time to think about them.