代码高尔夫:倒计时数字游戏
挑战
这是受英国著名电视游戏节目 Countdown 启发的任务。即使没有任何游戏知识,挑战也应该非常清楚,但请随时要求澄清。
如果您想观看该游戏的实际操作片段,请观看此 YouTube 片段。它的主角是 1997 年已故的理查德·怀特利 (Richard Whitely)。
您将获得从集合 {1, 2, 3, 4, 5, 6, 8, 9, 10, 25, 50, 75, 100} 中随机选择的 6 个数字,以及 100 之间的随机目标数字和 999。目标是使用六个给定数字和四种常见算术运算(加法、减法、乘法、除法;所有有理数)来生成目标 - 或尽可能接近任一方。每个数字最多只能使用一次,而每个算术运算符可以使用任意次数(包括零)。请注意,使用多少个数字并不重要。
编写一个函数,该函数接受目标数字和 6 个数字的集合(可以表示为列表/集合/数组/序列)并以任何标准数字表示法(例如中缀、前缀、后缀)返回解决方案。该函数必须始终返回最接近目标的结果,并且必须在标准 PC 上最多运行 1 分钟。请注意,在存在多个解决方案的情况下,任何单一解决方案就足够了。
示例:
{50, 100, 4, 2, 2, 4},目标 203
例如 100 * 2 + 2 + (4 / 4) (精确)
例如 (100 + 50) * 4 * 2 / (4 + 2) (精确){25, 4, 9, 2, 3, 10},目标 465
例如 (25 + 10 - 4) * (9 * 2 - 3) (精确){9, 8, 10, 5, 9, 7},目标 241
例如 ((10 + 9) * 9 * 7) + 8) / 5 (精确){3, 7, 6, 2, 1, 7},目标 824< /strong>
例如 ((7 * 3) - 1) * 6 - 2) * 7 (= 826; 相差 2)
规则
除了问题陈述中提到的之外,没有其他限制。您可以用任何标准语言编写该函数(不需要标准 I/O)。一如既往的目标是用最少的代码字符来解决任务。
话虽如此,我可能不会简单地接受最短代码的答案。我还将研究代码的优雅性和算法的时间复杂度!
我的解决方案
当我找到空闲时间时,我正在尝试 F# 解决方案 - 当我有东西时会将其发布在这里!
格式
请按照以下格式发布所有答案,以便于比较:
语言
字符数:???
完全混淆的函数:
(此处为代码)
清晰的(最好是注释的)函数:
(此处为代码)
有关算法/巧妙快捷方式的任何注释。
Challenge
Here is the task, inspired by the well-known British TV game show Countdown. The challenge should be pretty clear even without any knowledge of the game, but feel free to ask for clarifications.
And if you fancy seeing a clip of this game in action, check out this YouTube clip. It features the wonderful late Richard Whitely in 1997.
You are given 6 numbers, chosen at random from the set {1, 2, 3, 4, 5, 6, 8, 9, 10, 25, 50, 75, 100}, and a random target number between 100 and 999. The aim is to use the six given numbers and the four common arithmetic operations (addition, subtraction, multiplication, division; all over the rational numbers) to generate the target - or as close as possible either side. Each number may only be used once at most, while each arithmetic operator may be used any number of times (including zero.) Note that it does not matter how many numbers are used.
Write a function that takes the target number and set of 6 numbers (can be represented as list/collection/array/sequence) and returns the solution in any standard numerical notation (e.g. infix, prefix, postfix). The function must always return the closest-possible result to the target, and must run in at most 1 minute on a standard PC. Note that in the case where more than one solution exists, any single solution is sufficient.
Examples:
{50, 100, 4, 2, 2, 4}, target 203
e.g. 100 * 2 + 2 + (4 / 4) (exact)
e.g. (100 + 50) * 4 * 2 / (4 + 2) (exact){25, 4, 9, 2, 3, 10}, target 465
e.g. (25 + 10 - 4) * (9 * 2 - 3) (exact){9, 8, 10, 5, 9, 7}, target 241
e.g. ((10 + 9) * 9 * 7) + 8) / 5 (exact){3, 7, 6, 2, 1, 7}, target 824
e.g. ((7 * 3) - 1) * 6 - 2) * 7 (= 826; off by 2)
Rules
Other than mentioned in the problem statement, there are no further restrictions. You may write the function in any standard language (standard I/O is not necessary). The aim as always is to solve the task with the smallest number of characters of code.
Saying that, I may not simply accept the answer with the shortest code. I'll also be looking at elegance of the code and time complexity of the algorithm!
My Solution
I'm attempting an F# solution when I find the free time - will post it here when I have something!
Format
Please post all answers in the following format for the purpose of easy comparison:
Language
Number of characters: ???
Fully obfuscated function:
(code here)
Clear (ideally commented) function:
(code here)
Any notes on the algorithm/clever shortcuts it takes.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
Python
字符数:
548482425421416413408您可以这样称呼它:
在老式 PC 上完成给定示例大约需要半分钟。
这是评论版本:
它通过详尽枚举所有可能性来工作。它有点聪明,因为如果有两个具有相同值的表达式使用相同的输入数字,它会丢弃其中一个。它在如何考虑新组合方面也很聪明,使用 M 中的索引来快速修剪所有共享输入数字的潜在组合。
Python
Number of characters:
548482425421416413408you can call it like this:
Takes about half a minute on the given examples on an oldish PC.
Here's the commented version:
It works through exhaustive enumeration of all possibilities. It is a bit smart in that if there are two expressions with the same value that use the same input numbers, it discards one of them. It is also smart in how it considers new combinations, using the index into M to prune quickly all the potential combinations that share input numbers.
Haskell
字符数:
361350338322完全混淆的函数:
清除函数:
关于算法的任何注释/它采用了巧妙的快捷方式:
z
在列表 monad 中返回,而不是像ops
那样返回Maybe
。reduce
多次生成一些答案,以便轻松包含术语较少的解决方案。y
部分根据其自身定义。Rational
值计算的。如果使用Double
计算,高尔夫代码将缩短 17 个字符,并且速度更快。onRemainder
如何分解出pick
和pick2
之间的结构相似性。高尔夫版本的一号木:
运行,计时(每个结果仍低于一分钟):
Haskell
Number of characters:
361350338322Fully obfuscated function:
Clear function:
Any notes on the algorithm/clever shortcuts it takes:
z
returns in the list monad, rather thanMaybe
asops
does.reduce
generates some answers multiple times, in order to easily include solutions with fewer terms.y
is defined partially in terms of itself.Rational
values. Golf'd code would be 17 characters shorter, and faster if computed withDouble
.onRemainder
factors out the structural similarity betweenpick
andpick2
.Driver for golf'd version:
Run, with timing (still under one minute per result):
Ruby 1.9.2
字符数:404
我暂时放弃,只要有确切的答案就可以了。如果不存在,则需要很长时间才能枚举所有可能性。
完全混淆的
解码
测试脚本
输出
详细信息
用于生成括号对 (
b
) 的函数基于以下函数:查找格式正确的括号的所有组合Ruby 1.9.2
Number of characters: 404
I give up for now, it works as long as there is an exact answer. If there isn't it takes way too long to enumerate all possibilities.
Fully Obfuscated
Decoded
Test script
Output
Details
The function used for generating the bracket pairs (
b
) is based off this one: Finding all combinations of well-formed bracketsRuby 1.9.2 第二次尝试
字符数:
492440(426)不准确的答案再次出现问题。这次很容易足够快,但由于某种原因,最接近 824 的是 819 而不是 826。
我决定将其放入新答案中,因为它使用了与我上次尝试非常不同的方法。
删除输出总数(因为规范不要求)为 -14 个字符。
完全混淆的
解码
测试脚本
输出
详细信息
这构建了代表 5 个运算符的所有可能组合的三元树集。然后它会遍历输入数字的所有排列并将其插入到这些树的叶子中。最后,它只是迭代这些可能的方程,将它们存储到哈希中,并将结果作为索引。然后很容易从哈希中选择最接近所需答案的值并显示它。
Ruby 1.9.2 second attempt
Number of characters:
492440(426)Again there is a problem with the non-exact answer. This time this is easily fast enough but for some reason the closest it gets to 824 is 819 instead of 826.
I decided to put this in a new answer since it is using a very different method to my last attempt.
Removing the total of the output (as its not required by spec) is -14 characters.
Fully Obfuscated
Decoded
Test script
Output
Details
This constructs the set of ternary trees representing all possible combinations of 5 operators. It then goes through and inserts all permutations of the input numbers into the leaves of these trees. Finally it simply iterates through these possible equations storing them into a hash with the result as index. Then it's easy enough to pick the closest value to the required answer from the hash and display it.