Бинарные Заборы


16

Входные данные:

  • Целое число nв диапазоне2 <= n <= 10
  • Список целых положительных чисел

Выход:

Преобразуйте целые числа в их двоичное представление (без начальных нулей) и соедините их все вместе.
Затем определите все двоичные подстроки, которые образуют «бинарный забор», используя nколичество столбов забора. Пространства (нули) между каждым забором не имеют значения (не менее 1), но сами столбы должны быть одинаковой ширины.
Здесь регулярные выражения двоичные подстроки должны соответствовать для каждого n:

n   Regex to match to be a 'binary fence'   Some examples

2   ^(1+)0+\1$                              101; 1100011; 1110111;
3   ^(1+)0+\10+\1$                          10101; 1000101; 110011011;
4   ^(1+)0+\10+\10+\1$                      1010101; 110110011011; 11110111100001111001111;
etc. etc. You get the point

Глядя на n=4примеры:

1010101
^ ^ ^ ^    All fence posts have a width of one 1
 ^ ^ ^     with one or more 0s in between them

110110011011
^^ ^^  ^^ ^^    All fence posts have a width of two 1s
  ^  ^^  ^      with one or more 0s in between them

11110111100001111001111
^^^^ ^^^^    ^^^^  ^^^^    All fence posts have a width of four 1s
    ^    ^^^^    ^^        with one or more 0s in between them

Затем мы выводим числа, которые используют двоичные цифры совпадений «двоичные заборы».

Пример:

Входные данные : n=4,L=[85,77,71]

Двоичное представление этих целых чисел, объединенных вместе:
1010101 1001101 1000111(ПРИМЕЧАНИЕ. Пробелы добавляются только в качестве пояснения для примера).

Так как n=4мы ищем подстроки, соответствующие регулярному выражению (1+)0+\10+\10+\1, в этом случае мы можем найти две:
1010101(в позиции (1010101) 1001101 1000111); и 11001101100011(в положении 101010(1 1001101 100011)1)

Первый двоичный забор использует только двоичные цифры из 85, а второй двоичный забор использует двоичные цифры из всех трех целых чисел. Таким образом, вывод в этом случае будет:
[[85],[85,77,71]]

Правила вызова:

  • Хотя это также упоминается в приведенном выше примере, последнее предложение является важным: мы выводим числа, для которых используются двоичные цифры, в подстроке «двоичный забор».
  • Ввод / вывод является гибким. Входные данные могут быть списком / массивом / потоком целых чисел, строкой, разделенной запятой / запятой / символом новой строки, и т. Д. Выходными данными могут быть двумерный список целых чисел, одиночная строка с разделителями, список строк, новая строка, напечатанная в STDOUT, и т. Д. Все зависит от вас, но, пожалуйста, укажите, что вы использовали в своем ответе.
  • Порядок вывода самого списка не имеет значения, но вывод каждого внутреннего списка, конечно, в том же порядке, что и список ввода. Таким образом, в приведенном выше примере [[85,77,71],[85]]это также допустимый вывод, но [[85],[77,85,71]]это не так.
  • Как вы, возможно, уже заметили из примера (the 85), двоичные цифры могут использоваться несколько раз.
  • Регулярные выражения должны полностью соответствовать подстроке. Так 110101или 010101нет, когда-либо действительные «двоичные заборы» ( 10101однако, если и так n=3).
  • Элементы в выходном списке не являются уникальными, только двоичные позиции «двоичных ограждений» являются уникальными. Если несколько «двоичных ограждений» могут быть созданы с одним и тем же целым числом, мы добавляем их несколько раз в список вывода.
    Например: n=2, L=[109, 45](двоичный 1101101 101101) может формировать эти подстроки «двоичного забора»: 11011(в положении (11011)01 101101); 101(в положении 1(101)101 101101); 11011(в положении 110(1101 1)01101); 101(в положении 1101(101) 101101); 11011(в положении 110110(1 1011)01); 101(в положении 1101101 (101)101); 101(в положении 1101101 101(101)), поэтому вывод будет [[109],[109],[109,45],[109],[109,45],[45],[45]].
    Другой пример: n=2, L=[8127](двоичный 1111110111111) может формировать эти подстроки «двоичного забора»: 1111110111111(в положении (1111110111111));11111011111(в положении 1(11111011111)1); 111101111(в положении 11(111101111)11); 1110111(в положении 111(1110111)111); 11011(в положении 1111(11011)1111); 101(в положении 11111(101)11111), поэтому вывод будет [[8127],[8127],[8127],[8127],[8127],[8127]].
  • Если действительная выход не возможно, вы можете вернуть пустой список или какой - либо другой вид продукции falsey ( null, false, выдает сообщение об ошибке и т.д. Опять же , ваш вызов).

Основные правила:

  • Это , поэтому выигрывает самый короткий ответ в байтах.
    Не позволяйте языкам кода-гольфа отговаривать вас от публикации ответов на языках, не относящихся к кодексу. Попробуйте найти как можно более короткий ответ для «любого» языка программирования.
  • К вашему ответу применяются стандартные правила , поэтому вы можете использовать STDIN / STDOUT, функции / метод с правильными параметрами и типом возврата, полные программы. Ваш звонок.
  • По умолчанию лазейки запрещены.
  • Если возможно, добавьте ссылку с тестом для вашего кода (например, TIO ).
  • Кроме того, добавление объяснения для вашего ответа настоятельно рекомендуется.

Тестовые случаи:

Input:                       Output
                             (the binary below the output are added as clarification,
                             where the parenthesis indicate the substring matching the regex):

4, [85,77,71]                [[85],[85,77,71]]
                             (1010101) 1001101 1000111; 101010(1 1001101 100011)1

2, [109,45]                  [[109],[109],[109,45],[109],[109,45],[45],[45]]
                             (11011)01 101101; 1(101)101 101101; 110(1101 1)01101; 1101(101) 101101; 110110(1 1011)01; 1101101 (101)101; 1101101 101(101)

3, [990,1,3,3023,15,21]      [[990,1,3,3023],[990,1,3,3023],[1,3,3023],[21]]
                             (1111011110 1 11 1)01111001111 1111 10101; 11110(11110 1 11 101111)001111 1111 10101; 1111011110 (1 11 101111001111) 1111 10101; 1111011110 1 11 101111001111 1111 (10101)

2, [1,2,3,4,5,6,7,8,9,10]    [[1,2,3],[2,3],[4,5],[5],[5,6,7],[6,7],[6,7],[8,9],[9],[10]]
                             (1 10 11) 100 101 110 111 1000 1001 1010; 1 (10 1)1 100 101 110 111 1000 1001 1010; 1 10 11 (100 1)01 110 111 1000 1001 1010; 1 10 11 100 (101) 110 111 1000 1001 1010; 1 10 11 100 10(1 110 111) 1000 1001 1010; 1 10 11 100 101 (110 11)1 1000 1001 1010; 1 10 11 100 101 1(10 1)11 1000 1001 1010; 1 10 11 100 101 110 111 (1000 1)001 1010; 1 10 11 100 101 110 111 1000 (1001) 1010; 1 10 11 100 101 110 111 1000 1001 (101)0

3, [1,2,3,4,5,6,7,8,9,10]    [[4,5],[8,9]]
                             1 10 11 (100 101 )110 111 1000 1001 1010; 1 10 11 100 101 110 111 (1000 1001) 1010

10, [1,2,3,4,5,6,7,8,9,10]   []
                             No binary fences are possible for this input

6, [445873,2075]             [[445873,2075],[445873,2075],[445873,2075]]
                             (1101100110110110001 1)00000011011; 110(1100110110110001 100000011)011; 1101100(110110110001 100000011011)

2, [8127]                    [[8127],[8127],[8127],[8127],[8127],[8127]]
                             (1111110111111); 1(11111011111)1; 11(111101111)11; 111(1110111)111; 1111(11011)1111; 11111(101)11111

2, [10,10]                   [[10],[10,10],[10]]
                             (101)0 1010; 10(10 1)010; 1010 (101)0

4, [10,10,10]                [[10,10],[10,10,10],[10,10]]
                             (1010 101)0 1010; 10(10 1010 1)010; 1010 (1010 101)0

Ах, чёрт побери, вы отправили это, как только начался урок!
Quintec

Не [1,2,3]подходит для теста 4? Я вижу забор(1 10 11)
TFeld

1
Хорошо, я думаю, что понял это правильно. Я недостаточно внимательно прочитал последнее предложение примера. (Так как это очень важный вопрос, возможно, его не следует упоминать в примере.)
Арно

1
@Arnauld Я добавил последнее предложение примера в качестве первого правила. Я надеюсь, что это делает это более очевидным.
Кевин Круйссен

3
Я бы предложил добавить контрольный пример, в котором одно и то же целое число будет 2, [10, 10][[10],[10,10],[10]]
появляться

Ответы:


5

Шелуха , 33 байта

ṠṘmȯF-mȯ#öΛΛ=⁰Fzż+C2gQṁḋmëhohttIQ

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

Проходит все тестовые случаи. Это был сложный вызов, и мое решение кажется несколько запутанным.

объяснение

Программа перебирает фрагменты ввода и повторяет каждый раз столько раз, сколько содержит совпадение с регулярным выражением. Мы хотим считать только те совпадения, которые перекрывают двоичное расширение каждого числа в срезе. Это кажется трудным, но легче сосчитать те совпадения, которые не используют первое число: просто удалите это число и сосчитайте все совпадения. Чтобы получить хорошие совпадения, мы подсчитываем все совпадения, затем вычитаем количество совпадений, в которых не используется первое число, и совпадений, в которых не используется последнее число. Совпадения, которые не используют ни один, учитываются дважды, поэтому мы должны добавить их обратно, чтобы получить правильный результат.

Подсчет количества совпадений в срезе сводится к объединению двоичных расширений и циклическому срезу результата. Поскольку Husk не поддерживает регулярные выражения, мы используем манипуляции со списком для распознавания совпадений. Функция gразбивает срез на группы равных смежных элементов. Затем мы должны проверить следующее:

  1. Первая группа - это 1 группа.
  2. Количество групп нечетное.
  3. Количество 1-групп равно первому входу n.
  4. 1-группы имеют одинаковую длину.

Сначала мы разрезаем группы на пары. Если 1 и 2 выполнены, то первая группа каждой пары является 1-группой, а последняя пара - одиночной. Затем мы сокращаем этот список пар, упаковывая их с компонентным сложением. Это означает, что 1-группы и 0-группы добавляются отдельно. Добавление сохраняет переполнение элементов, поэтому добавление [1,1,1]и [1,1]дает [2,2,1]. Zipping не делает, поэтому, если последняя пара является синглтоном, компонентная сумма 0-групп исчезает из результата. Наконец, мы проверяем, что все числа в результате равны n.

ṠṘm(...)Q  First input is explicit, say 3, second is implicit.
        Q  List of slices.
  m(...)   Map this function (which counts good matches) over the slices
ṠṘ         and replicate each by the corresponding number.

F-m(...)mëhohttI  Count good matches. Argument is a slice, say [6,2,5].
         ë        Define a list of 4 functions:
          h        remove first element,
           oht     remove first and last element,
              t    remove last element,
               I   identity.
        m         Apply each: [[2,5],[2],[6,2],[6,2,5]]
  m(...)          Map function (which counts all matches): [0,0,1,2]
F-                Reduce by subtraction: 1
                  In Husk, - has reversed arguments, so this computes
                  M(x) - (M(tx) - (M(htx) - M(hx)))
                  where M means number of matches.

#(...)Qṁḋ  Count all matches. Argument is a slice.
       ṁ   Map and concatenate
        ḋ  binary expansions.
      Q    List of slices.
#(...)     Count number of truthy results of function (which recognizes a match).

ΛΛ=⁰Fzż+C2g  Recognize a match. Argument is list of bits, say [1,1,0,1,1,0,0,0,1,1].
          g  Group elements: [[1,1],[0],[1,1],[0,0,0],[1,1]]
        C2   Cut into pairs: [[[1,1],[0]],[[1,1],[0,0,0]],[[1,1]]]
    F        Reduce by
     z       zip (discarding extraneous elements) with
      ż      zip (preserving extraneous elements) with
       +     addition: [[3,3]]
Λ            For all lists
 Λ           all elements
  =⁰         are equal to first input.

7

Perl 6 , 114 112 110 107 106 104 байта

->\n,\L{L[map {[...] flat(^L Zxx(L>>.msb X+1))[.from,.to-1]},L.fmt('%b','')~~m:ov/(1+)<{"0+$0"x n-1}>/]}

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

объяснение

->\n,\L{  # Anonymous block taking arguments n and L
 L[       # Return elements of L
   map {  # Map matches to ranges
    [...] # Create range from start/end pair
          # Map indices into binary string to indices into L
          flat(     # Flatten
               ^L   # indices into L
               Zxx  # repeated times
               (L>>.msb X+1)  # length of each binary representation
          )
          # Lookup start/end pair in map above
          [.from,.to-1]
   },
   L.fmt('%b','')  # Join binary representations
   ~~              # Regex match
   m:ov/(1+)<{"0+$0"x n-1}>/  # Find overlapping matches
 ]
}

4

JavaScript (ES6), 187 184 177 173 байта

Принимает вход как (n)(list). Возвращает массив массивов.

n=>a=>(g=p=>(m=s.slice(p).match(`(1+)(0+\\1){${n-1}}`))?[a.filter((_,i)=>-~b[i-1]<p+m[0].length&b[i]>=p,p-=~m.index),...g(p)]:[])(s=[],b=a.map(n=>(s+=n.toString(2)).length))

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

Как?

Сначала мы вычисляем двоичную строку s и список б который описывает границы каждого числа в s,

s = [], b = a.map(n => (s += n.toString(2)).length)

Пример:

                      (0)     7     13
                       v      v     v
a = [109, 45] --> s = "1101101101101" --> b = [7, 13]
                       \_____/\____/
                         109    45

Мы используем следующий шаблон для генерации регулярного выражения, соответствующего двоичным изгородям:

`(1+)(0+\\1){${n-1}}`

Это регулярное выражение применяется к sначиная с позиции п,

m = s.slice(p).match(`(1+)(0+\\1){${n-1}}`)

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

Всякий раз, когда матч м находится в s: для каждого я-го числа во входном массиве мы проверяем, составляет ли интервал его границы (сохраняется в б) перекрывает интервал, состоящий из начальной и конечной позиции м в s,

a.filter((_, i) => -~b[i - 1] < p + m[0].length & b[i] >= p, p -= ~m.index)


1

Python 2 , 182 байта

lambda n,L,b='{:b}'.format:[zip(*set([t
for t in enumerate(L)for _ in b(t[1])][slice(*m.span(1))]))[1]for
m in re.finditer('(?=((1+)'+r'[0]+\2'*~-n+'))',''.join(map(b,L)))]
import re

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


Похоже, что это дает ошибку для любого nвхода больше 2. Кроме того, даже при n=2этом дает неверный результат для теста n=2, L=[10,10]. Другие тестовые случаи с n=2работой, хотя.
Кевин Круйссен

О, я понимаю, почему это не удается [10,10]; позвольте мне увидеть, как дорого это исправить ...
Линн

1
@KevinCruijssen Я исправил обе проблемы (по цене 22 байта, да ладно!)
Линн

0

05AB1E , 38 36 байт

Œvyy¨D¦y¦)bJεŒεγ0KDËsgIQyнyθP}}OÆFy,

Вдохновленный ответом @Zgarb 's Husk .

Выведите списки с новой строкой.

Попробуйте онлайн или проверьте все тесты .

Объяснение:

Œ            # Get the sublists of the (implicit) input-list
 v           # Loop `y` over each sublist:
  y          #  Push `y`
  y¨         #  Push `y` with the last item removed
  D¦         #  Push `y` with the first and last items removed
  y¦         #  Push `y` with the first item removed
  )          #  Wrap all four into a list
   b         #  Get the binary-string of each integer
    J        #  Join each inner list together
     ε       #  Map each converted binary-string to:
      Œ      #   Get all substrings of the binary-string
      ε      #   Map each binary substring to:
       γ     #    Split it into chunks of equal adjacent digits
       0K    #    Remove all chunks consisting of 0s
       DË    #    Check if all chunks consisting of 1s are the same
       sgIQ  #    Check if the amount of chunks of 1s is equal to the second input-integer
       yн    #    Check if the substring starts with a 1
       yθ    #    Check if the substring end with a 1
       P     #    Check if all four checks above are truthy for this substring
             #    (1 if truthy; 0 if falsey)
     }}      #  Close both maps
       O     #  Take the sum of each inner list
        Æ    #  Reduce the list of sums by subtraction
         F   #  Loop that many times:
          y, #   And print the current sublist `y` with a trailing newline
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.