Итак, я думаю, что самая сложная часть - это создание списка элементов.Мы можем сделать это рекурсивно.
Базовый случай прост.Для матрицы 1x1 у вас есть 1 элемент, который может иметь только две комбинации: [|[|0|]; [|1|]|]
.
Для элементов 2x2 у нас есть 2 ^ 2 = 4 элемента.Каждый из них может быть либо 1, либо 0, поэтому возможны 2 ^ 4 = 16 комбинаций.Чтобы получить все возможные комбинации для этого массива 2x2, мы можем думать о нем как о массиве длины 4.
Но сначала давайте подумаем о массиве длины 2. Затем мы должны найти все комбинации между[|[|0|]; [|1|]|]
и [|[|0|]; [|1|]|]
.Это было бы [|[|0; 0|]; [|0;1|]; [|1;0|]; [|1; 1|]|]
.К счастью, есть функция с именем Array.allPairs
, которая сгенерирует массив всех возможных комбинаций между двумя массивами, который уже делает это для нас!
Итак, мы можем применить Array.allPairs
к каждому элементу нашего массивадлина 4 последовательно, чтобы получить все возможные комбинации для всей матрицы, используя Array.reduce
.Я создаю функцию с именем pairsToArray
, которая в основном выравнивает структуру данных.
let pairsToArray x = Array.concat [|fst x; snd x|]
let rec binary N =
match N with
| 0 -> [||]
| 1 -> [|[|0|]; [|1|]|]
| n -> let elements = n*n
let combinations = Array.init elements (fun i -> binary 1)
let result = Array.reduce (fun acc i -> Array.allPairs acc i |> Array.map pairsToArray) combinations
result
Теперь все, что остается, - это преобразовать это в Array2D
.Нечто подобное должно сделать трюк
let c = binary 2
c |> Array.map (fun i -> Array2D.init 2 2 (fun j k -> i.[j+k*2]))
для случая 2x2