【发布时间】:2014-07-29 08:50:37
【问题描述】:
作为学习 Lisp 的一部分,我目前正在尝试编写一个函数来帮助我填写我的彩票。我希望该函数返回
- 列表
- 六个数字,
- 其中每个数字都在 1 到 49 之间,
- 没有重复的数字,
- 并且是按升序排列的列表。
到目前为止,我已经完成了五个要求中的四个。这是我当前的代码:
(defun lottery ()
(sort (loop repeat 6 collect (1+ (random 49))) #'<))
当我运行这个函数时,我会得到如下信息:
(lottery)
;; => (3 10 23 29 41 43)
基本上,一切都很好 - 除了有时我在列表中有两次相同的数字。在这里它开始变得令人费解。我的问题是我不太确定如何以 Lisp 方式解决这个问题。我能想到多种选择:
- 在结果上运行
remove-duplicates,然后使用length检查列表是否少于六个元素,如果是,第二次运行lottery,append它到第一个结果,使用@ 987654327@只获取前六个元素,然后重复。这行得通,但不是很优雅,尤其是当它涉及排序和合作时。多次。 - 从一个空列表开始,使用
(1+ (random 49))创建一个随机数,然后调用pushnew。现在用列表递归调用lottery,直到length返回6。我更喜欢这种方法,但我仍然不太相信,因为这样我需要两个函数:一个外部函数lottery和一个内部函数,它被递归调用并将列表作为参数处理。 - 从哈希表开始,使用从 1 到 49 的数字作为键,并将键的值设置为
nil。然后,在一个循环中,获取一个 1 到 49 之间的随机数,并将相应键的值更改为t。一旦哈希表的六个元素具有t作为值,则返回。恕我直言,这是迄今为止最糟糕的方法,因为它非常浪费内存并且不能很好地扩展。
您如何看待这些选项,还有其他实现方式吗?高级 Lisp 开发人员将如何解决这个问题?
有什么提示吗?
【问题讨论】:
标签: lisp common-lisp