# Hog
已经花了大约 8 个小时
两个人在玩掷骰子的游戏,每次可以选多个骰子但是不能超过 10 。 每轮投掷的分数为骰子的点数累加和,但是如果其中任何一枚骰子出现 1 点,那么该轮的分数就为 1 。 所以骰子选太多虽然能拿很多的分数,但是出现 1 的概率也会非常大。
# Phase 1: Simulator
# Problem 0
问题 0 是让你通过交互式的命令查看源码的,很简单的两个函数。
首先查看 dice.py 文件,理解内容,然后进行测试 python3 ok -q 00 -u --local 判断理解情况。
dice.py 里面就两个函数,其实特别简单。一个用于模拟真实的筛子,另外一个则是用于测试的骰子。
答案:00.py
# Problem 1
这个题很简单!目的是实现 Pig Out 功能。
roll_dice 函数就是来统计分数,只要骰子中含有 1 分数就是 1 ,反之要求和。
根据问题 0 的基础,来实现 roll_dice 函数。注意,需要先了解该函数要实现什么功能。(接下来有我的思考,最好先自己想一遍!)
需要先运行 python3 ok -q 00 -u --local 来确保自己已经理解 roll_dice 函数的功能。
答案:01.py
以下是该功能的代码实现,这是我最开始的思路:
num = 0
for i in range(0, num_rolls):
if dice() == 1:
return 1
num += dice()
return num
2
3
4
5
6
下面这个例子过不去!
>>> roll_dice(2, make_test_dice(4, 6, 1))
? 10
2
改进:
sum, f = 0, 0
for i in range(0, num_rolls):
tmp = dice()
if tmp == 1:
f = 1
sum += tmp
return 1 if f else sum
2
3
4
5
6
7
# Problem 2
这个函数就是实现一个整数三次方后各个位数交错加减再加一。也就是体重所述的 Free Bacon 功能。
看明白题意后,根据 python3 ok -q 02 -u --local 来验证自己的理解。
经过手算这几道题目肯定能够明白代码的实现逻辑。
答案:02.py
free_bacon() 的代码实现如下:
num, sum, i = pow(score, 3), 0, 0
while num != 0:
if i%2 == 1:
sum -= num % 10
else:
sum += num % 10
i += 1
num //= 10
finall = abs(sum) + 1
return finall
2
3
4
5
6
7
8
9
10
# Problem 3
这个函数是用来控制 free bacon 规则的触发条件的,也就是选择骰子数为 0 的话则触发,反之不行。
同样先运行:python3 ok -q 03 -u --local
答案:03.py
代码实现:
if num_rolls == 0:
return free_bacon(opponent_score)
else:
return roll_dice(num_rolls,dice)
2
3
4
# Problem 4
这道题是 Swine Swap 规则的实现方式。
答案:04.py
python3 ok -q 04 --local 通过测试。注意如果用 log10 需要在引入 from math import log10
num = pow(3,player_score + opponent_score)
a = num % 10
b = num // pow(10,int(log10(num)))
return (a == b)
2
3
4
准确的来说不能用 log10 ,因为只能在要求范围内写代码。
不过这个逻辑也很简单,log10 之前没有想到,有点启发。
# Problem 5a
答案:05a.py
代码实现:
# BEGIN PROBLEM 5
while (score0 < goal) and (score1 < goal):
if who == 0:
dice_num = strategy0(score0, score1)
curr_score = take_turn(dice_num, score1, dice)
score0 += curr_score
if who == 1:
dice_num = strategy1(score1, score0)
curr_score = take_turn(dice_num, score0, dice)
score1 += curr_score
if is_swap(score0, score1):
score0, score1 = score1, score0
who = other(who)
# END PROBLEM 5
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Problem 5b
在上一题的基础上需要添加几条规则。
答案:05b.py
实现代码:hog.py
# Phase 2: Commentary
# Problem 6
添加输出,提高交互性。
答案:06.py
def silence(score0, score1):
"""Announce nothing (see Phase 2)."""
print("Player 0 now has", score0, "and Player 1 now has", score1)
return silence
2
3
4
注意缩进!
# BEGIN PROBLEM 6
say = say(score0, score1)
# END PROBLEM 6
2
3
# Problem 7
答案:07.py
# BEGIN PROBLEM 7
def say(score0, score1):
if who:
curr_point = score1 - prev_score
if curr_point > prev_high:
print(str(curr_point)+" point(s)! That's the biggest gain yet for Player "+str(who))
return announce_highest(who,curr_point, score1)
else:
return announce_highest(who,prev_high, score1)
else :
curr_point = score0 - prev_score
if curr_point > prev_high:
print(str(curr_point)+" point(s)! That's the biggest gain yet for Player "+str(who))
return announce_highest(who,curr_point, score0)
else:
return announce_highest(who,prev_high, score0)
return say
# END PROBLEM 7
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Problem 8
答案:08.py
# BEGIN PROBLEM 8
def avg(*args):
i , sum = 0 , 0
while i < num_samples:
sum += g(*args)
i += 1
return sum/num_samples
return avg
# END PROBLEM 8
2
3
4
5
6
7
8
9
# Problem 9
# BEGIN PROBLEM 9
i = 1
max = float("-inf")
max_index = 1
while i <= 10:
averaged_roll_dice = make_averaged(roll_dice, num_samples)
curr_value = averaged_roll_dice(i, dice)
if curr_value > max:
max_index = i
max = curr_value
i += 1
return max_index
# END PROBLEM 9
2
3
4
5
6
7
8
9
10
11
12
13