How to think like a Computer Scientist: 課後習題第十四章5

#-------------------------------------------------------------------------------
# Name:        module2
# Purpose:
#
# Author:      penglaixy
#
# Created:     31/08/2013
# Copyright:   (c) penglaixy 2013
# Licence:     <your licence>
#-------------------------------------------------------------------------------
import sys
import time
import random
import copy
import math

choose_ball_range = 49
choose_ball_num = 6
compare_num = 5 #4,5
my_tickets = [
    [7,17,37,19,23,43],
    [7,2,13,41,31,43],
    [2,5,7,11,13,17],
    [13,17,37,19,23,43]]

def test(did_pass):
    '''print the result of a test '''
    linenum=sys._getframe(1).f_lineno
    if did_pass:
        msg = "Test at line{0} ok".format(linenum)
    else:
        msg = "Test at line{0} failed".format(linenum)
    print msg

def get_lotto_draw():
    rng = random.Random()
    result = []
    for i in range(6):
        while True:
            num = rng.randint(1,49)
            if num not in result:
                break
        result.append(num)
    return result

def lotto_match(lotto_draw, ticket):
    lotto_draw.sort()
    ticket.sort()
    idx_one = 0
    idx_two = 0
    match_num = 0
    while True:
        if idx_one == 6 or idx_two == 6:
            return match_num
        if  lotto_draw[idx_one] > ticket[idx_two]:
            idx_two += 1
        elif lotto_draw[idx_one] == ticket[idx_two]:
            match_num += 1
            idx_one += 1
            idx_two += 1
        else:
            idx_one += 1

def lotto_matches(draw,tickets):
    match_list = []
    for one_tick in tickets:
        match_list.append(lotto_match(draw,one_tick))
    return match_list

def is_prime(vn):
    if vn == 1:
        return False
    for i in range(2,int(math.sqrt(vn)+1)):
        if vn%i == 0:
            return False
    return True

def primes_in(vs):
    count = 0
    for n in vs:
        if is_prime(n):
            count += 1
    return count

def get_all_primes():
    global choose_ball_range
    result = []
    for i in range(1,choose_ball_range+1):
        if is_prime(i):
            result.append(i)
    return result

def in_second_not_in_first(chosen_ticks,all_primes):
    idx_one = 0
    idx_two = 0
    len_one = len(chosen_ticks)
    len_two = len(all_primes)
    result = []
    tick_one = None
    prim_two = None

    while True:
        if idx_one == len_one:
            result.extend(all_primes[idx_two:])
            return result
        if idx_two == len_two:
            return result

        tick_one = chosen_ticks[idx_one]
        prim_two = all_primes[idx_two]

        if tick_one > prim_two:
            result.append(prim_two)
            idx_two += 1
        elif tick_one == prim_two:
            idx_one += 1
            idx_two += 1
        else:
            idx_one += 1

def elimite_dups(tickets):
    result = []
    prev = None
    for v in tickets:
        if v != prev:
            result.append(v)
            prev = v

    return result

def prime_misses(my_tickets):
    all_prime = get_all_primes()
    chosen_prime = []
    for tick in my_tickets:
        chosen_prime += tick
    chosen_prime.sort()
    chosen_prime = elimite_dups(chosen_prime)
    return in_second_not_in_first(chosen_prime,all_prime)

def is_random_satisfied():
    #global compare_num
    #global my_tickets

    draw = get_lotto_draw()
    #print draw
    result_list = lotto_matches(draw,my_tickets)
    for i in result_list:
        if i >= compare_num:
            print draw
            return True
    return False

def count_times_until_satisfied():
    count = 0
    while True:
        count += 1
        if is_random_satisfied():
            print "Times needed until compared num {1} satisfied is {0}".format(
            count, compare_num)
            return

def average_times_need():
    tries_count = 20
    count_ok = 0
    for i in range(tries_count):
        if is_random_satisfied():
            count_ok += 1
    #print count_ok
    if count_ok != 0:
        print "In trying times:{0}, only {1} succeeded,average \
needed:{2}!".format(tries_count,count_ok,tries_count//count_ok)
    else:
        print "All trying times:{0} falied.".format(tries_count)

    return

def main():

    test(lotto_match([42,4,7,11,1,13],[2,5,7,11,13,17]) == 3)
    test(lotto_matches([42,4,7,11,1,13], my_tickets) == [1,2,3,1])
    test(primes_in([42,4,7,11,1,13]) == 3)

    test(prime_misses(my_tickets) == [3,29,47])
    count_times_until_satisfied()
    average_times_need()

if __name__ == '__main__':
    main()
Test at line179 ok
Test at line180 ok
Test at line181 ok
Test at line183 ok
[5, 7, 11, 13, 17, 39]
Times needed until compared num 5 satisfied is 10247
All trying times:20 falied.


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章