Я делаю игру в вяза и пытаюсь случайно разместить N злых роботов на сетке с ячейками ROWS x COLS.Elm - список случайных чисел без дубликатов
Что я хотел бы, это пары (Int, Int), которые определяют, где разместить N роботов.
я могу сделать список координатных пар с
makeGrid : Seed -> List (Int, Int)
makeGrid seed =
let gen = list n <| pair (int 0 rows) (int 0 cols)
in
fst (generate gen seed)
Это нормально. Но если я хочу сгенерировать список уникальных пар?
Должен ли я сделать императивное решение, где я держу набор своих вещей и цикл, добавляя до тех пор, пока у меня не будет достаточно?
Может быть что-то вроде этого (вероятно, неправильно, не проверить это в РЕПЛ):
makeN : Int -> Seed -> (List (Int, Int), Seed)
makeN n seed =
let gen = list n <| pair (int 0 rows) (int 0 cols)
in
generate gen seed
makeGrid : List(Int, Int) -> Seed -> Int -> List (Int, Int)
makeGrid partial seed n =
case of List.length partial
n -> partial
current ->
let (new_elems, new_seed) = makeN (n - current) seed
makeGrid Set.toList (Set.fromList <| append partial new_elems) new_seed n
Это чувствует себя прочь. Я думал, что из 3-х вариантов:
сделать мою сетку список РЯДОВ * COLS пара координат со списком типа (Int, Int), затем перетасовать ее и взять первые N пар в списке место мои роботы. Это кажется очень кратким и чистым, но неэффективным/плохим, если количество уникальных точек, которые мне нужны, намного меньше, чем моя сетка, и если моя сетка большая (поскольку Fisher-Yates - O (n log (n)), я думаю).
Используйте что-то наподобие this package для образца из моей сетки без замены, но мне нужно сменить сетку на массив, и похоже, что он много расщепляет и сращивает массивные операции, которые выглядят дорого.
Используйте JS FFI для реализации этого в четырехстрочном цикле JS.
Ни одно из этих решений не чувствует себя хорошо, есть ли что-то, что мне не хватает? Я, вероятно, собираюсь просто изменить механику игры, чтобы каждая клетка имела вероятность P иметь на ней робота, так что ее проще реализовать.
Сразу после публикации этого сообщения мне кажется, что я должен использовать для этого специальный генератор. Я смотрю Random.Extra, генератор Set и некоторые из приведенных методов семейства generateUntil. –
Это звучит как правильный подход. Обязательно добавьте ответ на свой вопрос, если вы это выясните. – Apanatshka