#coding=utf-8

def init_set():
r10=range(10)
return [(i, j, k, l)
for i in r10 for j in r10 for k in r10 for l in r10
if (i != j and i != k and i != l and j != k and j != l and k != l) ] #对给定的两组数,计算xAyB.不知道能不能更快些
def get_match_ab(target, source):
la, lb = 0, 0
for (i, t) in enumerate(target):
for (j, s) in enumerate(source):
if s == t:
if i == j:
la += 1
else:
lb += 1
#break this loop since we already found match
break
return (la, lb) #by lancer
#思路很好,把原来的16次比较变成了8次
#经过timeit验证确实速度有所提高
def get_match_ab2(target, source):
table = [-1] * 10
la, lb = 0, 0
for i in xrange(len(source)):
table[source[i]] = i
for i in xrange(len(target)):
if table[target[i]] == i:
la += 1
elif table[target[i]] != -1:
lb += 1
return (la, lb) #nums: the number_set list to be checked
#guess: last guess
#a, b: the number of aAbB
#@return: the rest number_sets which matche last guess
def check_and_remove(nums, guess, a, b):
rest_nums = []
for num_set in nums:
if (a, b) == get_match_ab(num_set, guess):
rest_nums.append(num_set)
return rest_nums #计算在nums中选择target以后,所有ab分支里面的剩余组合个数
def calc_ab_counts(target, nums):
#a * 10 + b is used to indicate an "a & b" combination
ab_map = {}
#init ab_map
abs = (0, 1, 2, 3, 4, 10, 11, 12, 13, 20, 21, 22, 30, 31, 40)
for ab in abs:
ab_map[ab] = 0
#let's do the calculation
for num_set in nums:
(a, b) = get_match_ab(num_set, target)
ab_map[a * 10 + b] += 1
return [ab_map[ab] for ab in abs] #计算一个选择相对于选择集的“标准差”
def calc_standard_deviation(target, nums):
ab_counts = calc_ab_counts(target, nums)
total = sum(ab_counts)
avg = float(total) / len(ab_counts)
sd = sum([(abc - avg)**2 for abc in ab_counts])
return sd #根据现有集合寻找下一个集合
#采用“最小标准差”作为衡量标准
def next_guess(nums):
min_sd = 0
min_set = ()
touched = False
for num_set in nums:
sd = calc_standard_deviation(num_set, nums)
if not touched or min_sd > sd:
touched = True
min_set = num_set
min_sd = sd
return min_set #根据现有集合寻找下一个集合
#随机选取,会有4-5个超过八次
def next_guess2(nums):
return nums[0] #折衷的方法:小于500用最小标准差
def next_guess3(nums):
if len(nums) > 500:
return大专栏  python猜数字游戏快速求解解决方案> next_guess2(nums)
else:
return next_guess(nums) #计算熵
import math
def calc_entropy(target, nums):
ab_counts = calc_ab_counts(target, nums)
total = sum(ab_counts)
hs = []
for abc in ab_counts:
h = 0
if abc:
p = float(abc) / total
h = p * math.log(p, 2)
hs.append(h)
return sum(hs) #使用信息量作为衡量标准
def next_guess4(nums):
min_sd = 0
min_set = ()
touched = False
for num_set in nums:
sd = calc_entropy(num_set, nums)
if not touched or min_sd > sd:
touched = True
min_set = num_set
min_sd = sd
return min_set def make_decision_tree():
from Queue import Queue
result = ((0, 1, 2, 3), {})
queue = Queue()
rest_nums = init_set()
queue.put((rest_nums, result))
#all xAyB set
abs = [(a, b) for a in range(5) for b in range(5 - a)] while not queue.empty():
(rest_nums, (guess, mapping)) = queue.get()
for (a, b) in abs:
new_rest_nums = check_and_remove(rest_nums, guess, a, b)
length = len(new_rest_nums)
if length == 1:
if a != 4: #b can't be other than 0 when a == 4
mapping[a * 10 + b] = new_rest_nums[0]
elif length > 1:
new_guess = next_guess4(new_rest_nums) #TODO: 替换guess函数调整算法
new_result = (new_guess, {})
mapping[a * 10 + b] = new_result
queue.put((new_rest_nums, new_result))
return result max_level = 0
level7_plus_tups = []
def pprint_result(result, level = 0):
global max_level, max_level_tup
(tup, mapping) = result
print tup
level += 1
if level > max_level:
max_level = level
if len(mapping) == 0:
print
else:
for key in mapping:
val = mapping[key]
#打印前缀
print u"%d|t" * level % tuple(range(1, level + 1)),
print u"%d:" % (level + 1),
#打印xAyB
print u"%dA%dB" % (key / 10, key % 10),
if len(val) == 4: #direct result
#打印结果
print val
if level >= 7:
level7_plus_tups.append((level, val))
else:
pprint_result(val, level) #来玩玩www.iplaypy.com
print u"Notice: 4A0B is NOT included, since it result to Game Over"
pprint_result(make_decision_tree())
print
print u"max level is:", max_level + 1
print u"level7 plus tuples:"
for (level, tup) in level7_plus_tups:
print u"level:", level + 1, u"ttup:", tup
print

python猜数字游戏快速求解解决方案的更多相关文章

  1. python猜数字游戏console版本

    加入python学习小组后的第一次作业,python GUI写猜数字游戏.由于加班比较多,第一步先实现console版本,下一步再实现GUI版本. 虽然猜数字游戏是个小游戏,但是涉及到的基础知识点还是 ...

  2. java & python猜数字游戏对比

    1.java版 package day03; import java.util.Random;import java.util.Scanner; /** * 猜数字游戏 * 随机生成一个1-100之间 ...

  3. python 猜数字游戏

    import random print('==============学无止境==========') secret=random.randint(1,10) print('sec:',secret) ...

  4. 猜数字游戏--基于python

    """题目:练习使用python写一个猜数字的游戏,数字范围0-100,每次猜错,需要给出缩小后的范围,每个人只有10次的猜测机会,猜测机会用完游戏结束!"&q ...

  5. python学习:猜数字游戏

    猜数字游戏   系统生成一个100以内的随机整数, 玩家有6次机会进行猜猜看,每次猜测都有反馈(猜大了,猜小了,猜对了-结束) 6次中,猜对了,玩家赢了. 否则系统赢了   #!/usr/bin/en ...

  6. Python实现猜数字游戏1.0版

    本文由荒原之梦原创,原文链接:http://zhaokaifeng.com/?p=702 """ 功能: 随机生成一个数字,最多有3次猜测机会,如果第一次没有猜对,则从第 ...

  7. [易学易懂系列|rustlang语言|零基础|快速入门|(23)|实战1:猜数字游戏]

    [易学易懂系列|rustlang语言|零基础|快速入门|(23)|实战1:猜数字游戏] 项目实战 实战1:猜数字游戏 我们今天来来开始简单的项目实战. 第一个简单项目是猜数字游戏. 简单来说,系统给了 ...

  8. 通过游戏学python 3.6 第一季 第九章 实例项目 猜数字游戏--核心代码--猜测次数--随机函数和屏蔽错误代码--优化代码及注释--简单账号密码登陆--账号的注册查询和密码的找回修改--锁定账号--锁定次数--菜单功能'menufile

      通过游戏学python 3.6 第一季 第九章 实例项目 猜数字游戏--核心代码--猜测次数--随机函数和屏蔽错误代码--优化代码及注释--简单账号密码登陆--账号的注册查询和密码的找回修改--锁 ...

  9. 通过游戏学python 3.6 第一季 第八章 实例项目 猜数字游戏--核心代码--猜测次数--随机函数和屏蔽错误代码--优化代码及注释--简单账号密码登陆--账号的注册查询和密码的找回修改--锁定账号--锁定次数

    通过游戏学python 3.6 第一季 第八章 实例项目 猜数字游戏--核心代码--猜测次数--随机函数和屏蔽错误代码--优化代码及注释--简单账号密码登陆--账号的注册查询和密码的找回修改--锁定账 ...

随机推荐

  1. ZJNU 1067 - 约瑟夫——中级

    打表处理(否则Case 1超时) 对m进行枚举,每次枚举进行一次判断 因为好人坏人均为k个,那么只要让下一个死亡的人的位置p保证在1~剩余坏人数量之间即可,不满足则直接break枚举下一个m 实际上对 ...

  2. 电影评论分类:二分类问题(IMDB数据集)

    IMDB数据集是Keras内部集成的,初次导入需要下载一下,之后就可以直接用了. IMDB数据集包含来自互联网的50000条严重两极分化的评论,该数据被分为用于训练的25000条评论和用于测试的250 ...

  3. 测试Java程序执行耗费的时间

    package test; public class Main { public static void main(String[] args) { long start = System.curre ...

  4. Window RabbitMq安装

    rabbitMQ是一个在AMQP协议标准基础上完整的,可服用的企业消息系统.它遵循Mozilla Public License开源协议,采用 Erlang 实现的工业级的消息队列(MQ)服务器,Rab ...

  5. keras中保存自定义层和loss

    在keras中保存模型有几种方式: (1):使用callbacks,可以保存训练中任意的模型,或选择最好的模型 logdir = './callbacks' if not os.path.exists ...

  6. DispatcherServlet和ContextLoaderListener,还有spring+servlet3.0 无web.xml启动问题

    上篇提到: 关于spring +springmvc中两个spring应用上下文(DispatcherServlet和ContextLoaderListener)的问题,挺让人迷糊的. 他们都是加载Be ...

  7. 关于volatile关键字

    来源:衡阳网站优化 在java核心卷1中对volatile关键字是这么描述的: volatile关键字为实例域的同步访问提供了一种免锁机制.如果声明一个域为volatile,那么编译器和虚拟机就知道该 ...

  8. mysql 数据库保存\n 微信分享时不能换行

    主要因为保存的是\n 但是查询出来是\\n 所以需要把\\n替换为\n即可(不转换的话不会换行并且显示\n)

  9. [CTS2019]珍珠(NTT+生成函数+组合计数+容斥)

    这题72分做法挺显然的(也是我VP的分): 对于n,D<=5000的数据,可以记录f[i][j]表示到第i次随机有j个数字未匹配的方案,直接O(nD)的DP转移即可. 对于D<=300的数 ...

  10. 一、linux-mysql 运维DBA介绍

    一.DBA数据库管理人员需要在整个架构中解决数据库的压力,前端业务通过扩展,加机器就可以很好的解决,但是存储.数据库就不是很好的可以进行扩展,数据也是分配不均的,所以,1)通过在数据库前面添加Memc ...