Advent Of Code 2022 第二天 - 剪刀石头布
本文是关于 Advent Of Code 2022 的。
编程圣诞日历,圣诞节前每天一个编程问题。
有兴趣的朋友可以在官网答题,用自己喜欢的编程方式去收集星星⭐️。在官网答题需要登陆并下载为你单独生成的谜题输入,每个人的都不一样。
问题
问题是剪刀石头布,总分由两部分组成,第一部分是你出的手势。石头是1,剪刀是2,布是3。
第二部分是输赢。赢了是6,输了是0,平局为3。
最终输出就是每一场总分之和。
第一部分
精灵们开始在海滩上安营扎寨。为了决定谁的帐篷能离零食仓库最近,一场巨大的石头剪刀布
比赛已经开始了。
剪刀石头布
是两个玩家之间的游戏。每场比赛包含很多轮;在每轮比赛中,选手们同时用手形选择石头、布或剪刀中的一种。然后,选出该轮的赢家。石头击败剪刀,剪刀击败布,而布击败石头。如果两个人都选择了相同的形状,那么这一轮就以平局结束。
一个精灵为了感谢你昨天的帮助,给了你一份加密的策略指南
(你的谜题输入),他们说这一定会帮助你获胜。“第一栏是你的对手要玩的东西:A
代表石头,B
代表布,C
代表剪刀。第二栏……”突然,精灵被叫走了,去帮别人搭帐篷。
你觉得,第二栏一定是你应该回应的手势,作为回应。 X
代表石头, Y
代表布, Z
代表剪刀。每次都赢了会让人怀疑,所以这些回应一定是经过精心挑选的。
整个比赛的赢家是得分最高的选手。你的总分是你每一轮的分数之和。单一回合的分数是你选择的 形状的分数
(1代表石头,2代表布,3代表剪刀)加上该回合的 结果的分数(如果你输了,则为0,如果该回合是平局,则为6)。
由于你不能确定精灵是在帮助你还是在欺骗你,所以你应该计算出如果你按照策略指南的要求你会得到的分数。
例如,假设你得到了以下的策略指南:
1 | A Y |
本战略指南预测并建议如下。
- 在第一轮,你的对手将选择石头(
A
),而你应该选择布(Y
)。这以你的胜利而告终,分数为8
(2 因为你选择了布牌 + 6 因为你赢了)。 - 在第二轮中,你的对手将选择布牌(
B
),而你应该选择石头(X
)。这以你的失败告终,分数为1
(1 + 0)。 - 第三轮是平局,双方都选择剪刀,你的得分是 3 + 3 =
6
。
在这个例子中,如果你按照策略指南,你的总分将是 15
(8 + 1 + 6)。
如果一切完全按照你的策略指南进行,你的总分会是多少?
第二部分
精灵完成了对帐篷的帮助,又偷偷地走到你身边。“总之,第二栏说的是这一轮需要如何结束。 X
意味着你需要输掉比赛, Y
意味着你需要以平局结束比赛,而 Z
意味着你需要获胜。祝你好运!“
总分仍然以同样的方式计算,但现在你需要弄清楚选择什么样的形状,以使回合按指示结束。上面的例子现在是这样的。
- 在第一轮,你的对手会选择石(
A
),而你需要这一轮以平局结束(Y
),所以你也选择石。这样你的得分是1 + 3 =4
。 - 在第二轮,你的对手将选择布(
B
),而你选择石,所以你输了(X
),得分是1 + 0 =1
。 - 在第三轮,你将用石头击败对手的剪刀,得分是1 + 6 =
7
。
现在你正确地解密了超绝密战略指南,你会得到一个总分 12
。
按照精灵的指示进行第二栏, 如果一切完全按照你的策略指南进行,你的总分会是多少?
代码
完整的代码可以在 这里 找到。
1 | type Input = Vec<(i8, i8)>; |
解析器
每一行是一组数据,把剪刀石头布变成比较简单的 (0, 1, 2)
。
第一部分
这里使用的是找出一个集合中元素的顺时针距距离。
例如 [1, 2, 3, 4, 5, 6, 7, 8 , 9, 10, 11, 12]
找 11
到 1
的距离就是 2。
这个和剪刀石头布的关系在于,如果你将 Rock, Paper, Scissors 比作 [0, 1, 2]
,往前一个的永远自己是输的,例如石头前面是布。而后一位自然自己永远是赢的,相同就代表平局。
(3 + their - mine) % 3
就是计算这个距离的方法,而 3-(x-1)%3
的原因是为了把结果偏移,因为如果按照上面的说法,1
就是输了,但是我们要的是 0
。
这样就可以用这个方法找到结果 (0, 1, 2)
。再将这个数字乘三就是该局的分数。
第二部分
使用上述的方法只不过反过来,根据结果判断你需要出什么手势。
运行时间
所有时间由我这垃圾笔记本电脑进行(不科学的)测试,均以 --release
启动。
1 | Day 2 |