英文:
i have a 2D list of any size of all "0" and want to randomly replace 10 of these with a "1"
问题
I have translated the code-related portion for you:
我正在制作扫雷游戏,有一个二维列表表示始终为用户输入大小的正方形棋盘。它开始时填满了零,我想用一些“1”来代表地雷的位置。
我需要确保它始终生成10个地雷,不重复在同一个位置,使用随机库来实现。
我不介意计算时间,但我希望它能更优雅,我以前的项目总是计算机翻译的思维混乱。
我认为我有一个大致的伪代码解决方案,如下所示:
mines10
while mines 大于 1
选择随机行
选择随机列
尝试更改它
如果成功更改,地雷数量减少1
但这很笨拙,我想要一个更优雅的解决方案,也许是内置的随机函数,我不确定,这就是我在问的原因。
英文:
I am making mine sweeper and have a 2D list representing a board that is always a square of user inputted size. It begins filled with zeroes and I want to replace x number of these with ones to represent a mines location.
I need it to always make 10 mines never duplicate the same place and this is using the random library.
I don't mind computational time is will be almost meaningless but i do want it to be elegant, all my past projects have been a jumbled mess of computer translated thoughts.
I think i have an aproximate solution in sudo code allong the lines of:
mines10
while mines is more than 1
chose a random row
chose random column
try change it
if it change one less mine left to place
but this is very clunky i want a more elegant solution maby an inbuilt random function IDK that's why I'm asking
答案1
得分: 3
以下是翻译好的部分:
一个简单的一行代码方法是使用 `itertools.product` 生成所有位置的序列,并使用 `random.sample` 从该序列中选择 10 个唯一元素。
假设棋盘是 5x5 的,你想要 10 个项目,代码看起来会是这样的:
>>> import itertools
>>> import random
>>> random.sample(list(itertools.product(range(5), repeat=2)), k=10)
[(4, 1), (4, 3), (4, 2), (2, 1), (1, 2), (0, 4), (2, 4), (2, 0), (4, 0), (2, 3)]
请注意,如果你有一个非常大的棋盘,构建所有位置的列表可能不是最优的方法(尽管如果你有一个非常大的棋盘,设置地雷的起始位置可能是你最不担心的问题之一)。 最优的方法(即不需要构建所有这些元组的列表只是为了选择其中的一个子集)是将每个位置表示为`range`中的单个值,然后在调用 `sample` 后将这些值转换为元组:
>>> [(n % 5, n // 5) for n in random.sample(range(5 * 5), 10)]
[(0, 3), (0, 1), (1, 4), (3, 0), (3, 1), (3, 2), (0, 4), (1, 2), (4, 0), (1, 0)]
英文:
An simple one-liner approach would be to use itertools.product
to generate a sequence of all the locations and random.sample
to pick 10 unique elements from that sequence.
Assuming the board is 5x5 and you want 10 items, that'd look like:
>>> import itertools
>>> import random
>>> random.sample(list(itertools.product(range(5), repeat=2)), k=10)
[(4, 1), (4, 3), (4, 2), (2, 1), (1, 2), (0, 4), (2, 4), (2, 0), (4, 0), (2, 3)]
Note that building a list of all the locations may not be optimal if you have a ridiculously large board (although if you have a ridiculously large board, setting up the starting locations for the mines is likely to be the least of your worries). The optimal approach (i.e. not requiring you to build a list of all those tuples just to pick a subset of them) would be to represent each location as a single value in a range
and then convert the values to tuples after calling sample
:
>>> [(n % 5, n // 5) for n in random.sample(range(5 * 5), 10)]
[(0, 3), (0, 1), (1, 4), (3, 0), (3, 1), (3, 2), (0, 4), (1, 2), (4, 0), (1, 0)]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论