Генерация двоичных матриц, которые различаются вплоть до отражений

14

Вот все двоичные матрицы 2x2

#0  #1  #2  #3  #4  #5  #6  #7  #8  #9  #10 #11 #12 #13 #14 #15
--  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  
00  00  00  00  01  01  01  01  10  10  10  10  11  11  11  11  
00  01  10  11  00  01  10  11  00  01  10  11  00  01  10  11  

Две бинарные квадратные матрицы эквивалентны по отношению, ~если одну можно отобразить на другую с помощью любого количества отражений на горизонтальной или вертикальной осях .

#1 ~ #2под отражением на вертикальной оси, поэтому нам нужно оставить только один из них (не важно, какой). Точно так же #3 ~ #12, #6 ~ #9и так далее.

Цель состоит в том, чтобы создать программу, которая принимает один вход Nи печатает столько N x Nдвоичных матриц, сколько существует, так что все матрицы в выходных данных различаются в соответствии с вышеуказанным соотношением.

В ручном волновом псевдокоде допустимым решением будет

define M[i] = N by N matrix with bit pattern equal to i

for i = 0 to (2^(N^2)) - 1
    valid = true
    for j = i+1 to (2^(N^2)) - 1
        if (equivalent(M[i], M[j]))
            valid = false
            break
    if (valid)
        print (M[i])

Для ввода N=2один действительный вывод будет

00  00  00  01  10  01  11
00  01  11  01  01  11  11

Но, выбирая разные матрицы из одного и того же класса эквивалентности, можно получить другой действительный результат.

00  10  11  11  11  10  01
00  00  00  10  11  10  10

Порядок матриц не имеет значения, конкретный выбор из эквивалентных матриц не имеет значения, и пробелы не имеют значения, выводят матрицы, как вам угодно, если они удобочитаемы.

Вывод должен быть исчерпывающим.

Самый короткий код выигрывает.

РЕДАКТИРОВАТЬ: это мой первый пост в гольф, и я передумал на критерии победы.

Самый короткий код на языке, специально не предназначенном для лаконичности / победы в гольфе .

Я надеюсь, что поменять этот критерий не сложно, но я думаю, что делать это на «нормальном» языке - гораздо более интересное предложение.

spraff
источник
5
Добро пожаловать в PPCG! Это хорошая первая задача, но я бы рекомендовал людям выводить результат в гибком формате (например, каждая матрица в виде списка списков). Таким образом, люди могут сосредоточиться на очень интересном ядре задачи (от поиска уникальных матриц до симметрий) вместо того, чтобы беспокоиться о форматировании выходных данных (которые могут легко занять столько же байтов и сделать гольф основной задачи менее сложным). важный).
Мартин Эндер
Спасибо за отзыв, вы оба отредактировали вопрос соответственно.
Spraff
2
Я был склонен включить вращения как эквивалентность. Мне также хотелось включить инвертирование каждого бита в качестве эквивалентности. Я также был склонен включить перестановки строк / столбцов в качестве эквивалентности. В итоге я принял произвольное решение, чтобы требования были достаточно простыми. Не стесняйтесь размещать изменения.
spraff
1
Мы обсуждали это в прошлом , и вынесли решение против исключения или наказаний определенных языков в соревнованиях кода для гольфа, а это означает , что вызов, сделать это следует рассматривать не по теме. Кроме того, принятый ответ является ответом, который выигрывает испытание , что означает самый короткий код для вопросов о коде в гольф. Подводя итог: Если вы не хотите принимать какой - либо ответ на все , то нет. Однако, если вы принимаете ответ, он должен быть самым коротким.
Деннис
1
Наконец, язык J - это не язык игры в гольф, а высокоуровневый высокопроизводительный язык программирования общего назначения, который существует уже 25 лет. Даже с вашими текущими правилами вы все равно приняли неправильный ответ.
Деннис

Ответы:

1

J 66 56 53 байта

[:~.,~{.@/:~@(2:_&(][:,(;|.;|."1)&>)<)@$"#.2#:@i.@^*:

Грубый поиск.

использование

   f =: [:~.,~{.@/:~@(2:_&(][:,(;|.;|."1)&>)<)@$"#.2#:@i.@^*:
   f 2
┌───┬───┬───┬───┬───┬───┬───┐
│0 0│0 0│0 0│0 1│0 1│0 1│1 1│
│0 0│0 1│1 1│0 1│1 0│1 1│1 1│
└───┴───┴───┴───┴───┴───┴───┘
   # f 3
168
   # f 4
16576

объяснение

[:~.,~{.@/:~@(2:_&(][:,(;|.;|."1)&>)<)@$"#.2#:@i.@^*:  Input: integer n
                                                   *:  Square n
                                           2      ^    Compute m = 2 ^ (n ^ 2)
                                               i.@     Make a range [0, m)
                                            #:@        Convert each to binary digits
    ,~                                                    Pair, make [n, n]
                                       $"#.            Reshape each binary list
                                                          to a matrix with size [n, n]
             (                       )@                Operate on each
                                    <                    Box it, call x
              2:                                         The constant 2
                _&(                )                     Repeat that many times on x
                       (        )&>                        For each box
                            |."1                             Reverse by column
                         |.                                  Reverse by row
                           ;                                 Join them
                        ;                                    Join with initial
                    [:,                                    Flatten
                   ]                                       Return that as the new x
         /:~@                                          Sort each
      {.@                                              Take the head of each
[:~.                                                   Unique and return
миль
источник
4

Желе , 19 байт

Ṛ€;U;
2ḶṗṗµWdz¡Ṃµ€Q

Попробуйте онлайн!

Как это устроено

2ḶṗṗµWdz¡Ṃµ€Q  Main link. Argument: n (integer)

2Ḷ             Unlength 2; yield [0, 1].
  ṗ            Cartesian product; construct all vectors of {0, 1}^n.
   ṗ           Cartesian product; construct all vectors of ({0, 1}^n)^n.
               This yields A, the array of all binary n×n matrices.
    µ     µ€   Begin a new, monadic chain and apply it to all matrices M in A.
     W           Wrap; yield [M].
      dz¡        Call the helper link n times, initially with argument [M], then
                 on the previous return value.
         Ṃ       Take the minimum of the results.
               This replaces all matrices with the lexicographical minimum of their
               equivalence classes, mapping equivalent matrices to the same matrix.
            Q  Unique; deduplicate the resulting array of matrices.

Ṛ€;U;          Helper link. Argument: L (array of matrices)

Ṛ€             Reverse the order of the rows of each M in L.
   U           Reverse the order of the columns of each M in L.
  ;            Concatenate the resulting matrix arrays.
    ;          Concatenate the result with L.
Деннис
источник
2

Pyth - 24 23 21 байт

Хочу найти лучший способ получить все отражения.

Спасибо @Pietu1998 за то, что я получил в гольф 2 байта!

hM.gS+K_Bk_MMKcRQ^`T*

Попробуйте это онлайн здесь .

Я собираюсь дождаться игры в гольф, прежде чем приступить к полному объяснению, но, по сути, он создает все возможные двоичные матрицы, затем .gгруппирует их по отсортированному списку всех возможных отражений, а затем берет только одно из каждой группы.

Maltysen
источник
Если я запускаю это с аргументом, 3вывод начинается с [['000', '000', '00'],отметки отсутствующего нуля в конце.
Spraff
@ spraff упс, я сделал ^2Qвместо Q^2. Фикс спасает меня тоже байт: D
Maltysen
@ Спраф исправил это.
Maltysen
Я уверен, что вы можете сделать _MMвместо mC_Cd.
PurkkaKoodari
@ Pietu1998 о, да, спасибо!
Maltysen
1

Haskell, 100 байт

import Data.List
r=reverse
e#n=mapM id$e<$[1..n]
f n=nubBy(\a b->elem a[r b,r<$>b,r$r<$>b])$"01"#n#n

Пример использования: f 2-> [["00","00"],["00","01"],["00","11"],["01","01"],["01","10"],["01","11"],["11","11"]].

Как это устроено:

e#n=mapM id$e<$[1..n]        -- helper function: creates a list of all combinations
                             -- of the elements of e of length n
                             -- "01" # 2 -> ["00","01","10","11"]

                   "01"#n#n  -- creates all binary n x n matrices
nubBy                        -- remove duplicates according to the equivalence
                             -- relation
   \a b ->                   -- a equals b if
       a elem                -- a is an element of
         [r b,r<$>b,r$r<$>b] -- the list of reflections of b 
Ними
источник
1

JavaScript (ES6), 195 байт

n=>[...Array(p=1<<n*n)].map(_=>(p++).toString(2).slice(1)).filter((s,i,a)=>![1,0,1].some(c=>a.indexOf((c?b.reverse():b=b.map(s=>[...s].reverse().join``)).join``)<i,b=s.match(eval(`/.{${n}}/g`))))

Возвращает строки, представляющие все объединенные элементы матрицы, например, 111101111представляет матрицу 3 × 3 1s с символом a 0в середине. Объяснение:

n=>[...Array(p=1<<n*n)].map(            Enumerate all binary matrices
 _=>(p++).toString(2).slice(1)          Convert to padded binary
).filter((s,i,a)=>![1,0,1].some(        Check reflections of each matrix
 c=>a.indexOf((c?b.reverse():           Reverse the order of lines
  b=b.map(s=>[...s].reverse().join``    Or reverse each line
  )).join``)<i,                         Has this been seen before?
 b=s.match(eval(`/.{${n}}/g`))))        Reshape string into a square
Нил
источник
Рекурсивная функция .map(f=(x=p++)=>x>1?f(x>>1)+x%2:"")
преобразования
1

Mathematica, 94 байта

DeleteDuplicatesBy[{0,1}~Tuples~{#,#},Sort@Join[Join@@Outer[Reverse,{#},{1,2,{1,2}},1],{#}]&]&
Юнг Хван Мин
источник
1
Привет, ДХМ! Спасибо за ответ. Я не очень хорошо понимаю Mathematica, поэтому не могли бы вы немного объяснить, что происходит? (Я опубликовал то же самое в вашем другом недавнем ответе. Давать какое-то объяснение - сильное ожидание ответов на этом сайте)
isaacg
0

JavaScript (ES6), 184

Это оказалось очень похоже на Нила, но в целом мешок трюков в JavaScript не так разнообразен.

n=>eval("r=x=>[...x].reverse();for(l='',i=m=1<<n*n;i<m+m;i++)a=i.toString(2).slice(1).match(eval(`/.{${n}}/g`)),[b=a.map(x=>r(x).join``),r(a),r(b)].some(x=>~l.search(x))?0:l+=a+`\n`")

Меньше гольфа

n=>{
  r = x =>[...x].reverse();
  for(l = '', i = m = 1<<n*n; i < m+m; i++)
    a = i.toString(2).slice(1).match(eval(`/.{${n}}/g`)), // base matrix as an array of strings
    b = a.map(x => r(x).join``), // horizontal reflection
    c = r(a), // vertical reflection
    d = r(b), // both reflections
    // check if already found 
    [b, c, d].some(x => ~l.search(x)) // using search, arrays are converted to comma separated strings 
      ? 0 
      : l += a+`\n` // add new found to list (again as a comma separated string)
  return l
}

Тест Остерегайтесь, даже для входа 4 время работы слишком велико

f=n=>eval("r=x=>[...x].reverse();for(l='',i=m=1<<n*n;i<m+m;i++)a=i.toString(2).slice(1).match(eval(`/.{${n}}/g`)),[b=a.map(x=>r(x).join``),r(a),r(b)].some(x=>~l.search(x))?0:l+=a+`\n`")

function update() {
  var i=+I.value;
  
  result = f(i)
  count = result.split('\n').length
  O.textContent = count+'\n'+result
}

update()
Input <select id=I onchange="update()"><option>2<option>3<option>4<option>5</select>
<pre id=O></pre>

edc65
источник