As cercas binárias


16

Entrada:

  • Um número inteiro nno intervalo2 <= n <= 10
  • Uma lista de números inteiros positivos

Resultado:

Converta os números inteiros em suas representações binárias (sem zeros à esquerda) e junte todos eles.
Em seguida, determine todas as substrings binárias que formam uma 'cerca binária' usando a nquantidade de postes da cerca. Os espaços (zeros) entre cada pilar são irrelevantes (pelo menos 1), mas os pilares devem ter largura igual.
Aqui, as expressões regulares que as substrings binárias devem corresponder para cada uma 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

Olhando para os n=4exemplos:

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

Em seguida, produzimos os números que usam dígitos binários das correspondências 'cercas binárias'.

Exemplo:

Entrada: n=4,L=[85,77,71]

A representação binária desses números inteiros unidos é:
1010101 1001101 1000111(NOTA: Os espaços são adicionados apenas como esclarecimento para o exemplo).

Desde então n=4, procuramos substrings que correspondam ao regex (1+)0+\10+\10+\1; nesse caso, podemos encontrar dois:
1010101(na posição (1010101) 1001101 1000111); e 11001101100011(na posição 101010(1 1001101 100011)1)

A primeira cerca binária usa apenas dígitos binários de 85e a segunda cerca binária usa dígitos binários de todos os três números inteiros. Portanto, a saída neste caso seria:
[[85],[85,77,71]]

Regras do desafio:

  • Embora também seja mencionado no exemplo acima, a última frase é importante: Nós produzimos os números para os quais os dígitos binários são usados ​​na substring 'cerca binária'.
  • A E / S é flexível. A entrada pode ser uma lista / matriz / fluxo de números inteiros, sequência delimitada por espaço / vírgula / nova linha, etc. A saída pode ser uma lista inteira 2D, uma única sequência delimitada, uma lista de sequências, uma nova linha impressa em STDOUT, etc. Tudo depende de você, mas indique o que você usou em sua resposta.
  • A ordem de saída da lista em si é irrelevante, mas a saída de cada lista interna é obviamente da mesma ordem que a lista de entrada. Portanto, com o exemplo acima, também [[85,77,71],[85]]é uma saída válida, mas [[85],[77,85,71]]não é.
  • Como você já deve ter notado no exemplo (the 85), dígitos binários podem ser usados ​​várias vezes.
  • As expressões regulares devem corresponder inteiramente à substring. Portanto, 110101ou 010101nunca existem 'cercas binárias' válidas ( 10101é, no entanto, iff n=3).
  • Os itens na lista de saída não são únicos, apenas as posições binárias das 'cercas binárias' são únicas. Se várias 'cercas binárias' podem ser criadas com o mesmo número inteiro, as adicionamos várias vezes à lista de saída.
    Por exemplo: n=2, L=[109, 45](binário 1101101 101101) pode formar estas subsequências 'cerca binário': 11011(em posição (11011)01 101101); 101(na posição 1(101)101 101101); 11011(na posição 110(1101 1)01101); 101(na posição 1101(101) 101101); 11011(na posição 110110(1 1011)01); 101(na posição 1101101 (101)101); 101(na posição 1101101 101(101)), então a saída seria [[109],[109],[109,45],[109],[109,45],[45],[45]].
    Um outro exemplo: n=2, L=[8127](binário 1111110111111) pode formar estas subsequências 'cerca binário': 1111110111111(em posição (1111110111111));11111011111(na posição 1(11111011111)1); 111101111(na posição 11(111101111)11); 1110111(na posição 111(1110111)111); 11011(na posição 1111(11011)1111); 101(na posição 11111(101)11111), então a saída seria [[8127],[8127],[8127],[8127],[8127],[8127]].
  • Se nenhuma saída válido é possível, você pode retornar uma lista vazia ou algum outro tipo de saída Falsey ( null, false, gera um erro, etc. Mais uma vez, a sua chamada).

Regras gerais:

  • Isso é , então a resposta mais curta em bytes vence.
    Não permita que idiomas com código de golfe o desencorajem a postar respostas com idiomas que não sejam codegolf. Tente encontrar uma resposta o mais curta possível para 'qualquer' linguagem de programação.
  • As regras padrão se aplicam à sua resposta, para que você possa usar STDIN / STDOUT, funções / método com os parâmetros adequados e programas completos do tipo retorno. Sua chamada.
  • As brechas padrão são proibidas.
  • Se possível, adicione um link com um teste para o seu código (ou seja, TIO ).
  • Além disso, é altamente recomendável adicionar uma explicação para sua resposta.

Casos de teste:

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

Ah, droga, você postou isso assim que a aula começou!
Quintec 8/08

Não é [1,2,3]válido para o testcase 4? Eu vejo a cerca(1 10 11)
TFeld 8/08

1
Ok, acho que desta vez acertou. Não li a última frase do exemplo com bastante atenção. (Como é muito importante, talvez não deva ser mencionado dentro do exemplo.) #
311 Arnauld

1
@ Arnauld Adicionei a última frase do exemplo como primeira regra agora. Espero que isso torne mais aparente.
18764 Kevin Crijssen

3
Eu sugiro para adicionar um caso de teste, onde o mesmo número inteiro aparece várias vezes na lista, por exemplo, 2, [10, 10]que deve resultar em [[10],[10,10],[10]]se eu entender o correctl.y desafio
nwellnhof

Respostas:


5

Casca , 33 bytes

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

Experimente online!

Passa em todos os casos de teste. Esse foi um desafio difícil e minha solução parece um pouco complicada.

Explicação

O programa percorre as fatias da entrada e repete cada uma das vezes que contém uma correspondência da regex. Queremos contar apenas as correspondências que se sobrepõem à expansão binária de cada número na fatia. Isso parece difícil, mas é mais fácil contar as correspondências que não usam o primeiro número: basta remover esse número e contar todas as correspondências. Para obter as boas correspondências, contamos todas as correspondências e subtraímos o número de correspondências que não usam o primeiro número e aquelas que não usam o último número. As correspondências que não usam nem são contadas duas vezes, portanto, devemos adicioná-las novamente para obter o resultado correto.

Contar o número de correspondências em uma fatia é uma questão de concatenar as expansões binárias e fazer um loop sobre as fatias do resultado. Como o Husk não tem suporte para expressões regulares, usamos a manipulação de lista para reconhecer uma correspondência. A função gdivide uma fatia em grupos de elementos adjacentes iguais. Em seguida, devemos verificar o seguinte:

  1. O primeiro grupo é um grupo.
  2. O número de grupos é ímpar.
  3. O número de 1 grupos é igual à primeira entrada n.
  4. Os grupos 1 têm comprimentos iguais.

Primeiro, cortamos os grupos em pares. Se 1 e 2 são válidos, o primeiro grupo de cada par é um grupo 1 e o último par é um singleton. Em seguida, reduzimos essa lista de pares compactando-os com a adição de componentes. Isso significa que os grupos 1 e 0 são adicionados separadamente. A adição preserva elementos transbordantes, adicionando [1,1,1]e [1,1]fornecendo [2,2,1]. O zíper não é necessário; portanto, se o último par for um singleton, a soma dos componentes 0 dos grupos 0 desaparecerá do resultado. Finalmente, verificamos que todos os números no resultado são iguais a 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 bytes

->\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}>/]}

Experimente online!

Explicação

->\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 bytes

Toma entrada como (n)(list). Retorna uma matriz de matrizes.

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))

Experimente online!

Quão?

sbs

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

Exemplo:

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

Usamos o seguinte modelo para gerar uma expressão regular correspondente a cercas binárias:

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

sp

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

p=0 0

msEubms

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

3

Python 2 , 271 246 223 214 208 202 200 195 bytes

lambda n,l,R=range,L=len:sum([next(([l[i:j+1]]for j in R(i,L(l))if re.match('(1+)'+r'(0+\1)'*~-n,('{:b}'*(1+j-i)).format(*l[i:])[o:])),[])for i in R(L(l))for o in R(L(bin(l[i]))-2)],[])
import re

Experimente online!


1

Python 2 , 182 bytes

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

Experimente online!


Isso parece dar um erro para qualquer nentrada maior que 2. Além disso, mesmo com n=2isso, fornece um resultado incorreto para o caso de teste n=2, L=[10,10]. Os outros casos de teste com n=2trabalho, no entanto.
Kevin Cruijssen 9/10

Oh, vejo por que falha [10,10]; deixe-me ver como é caro consertar isso ...
Lynn

1
@KevinCruijssen I fixa ambas as questões (com o custo de 22 bytes, oh bem!)
Lynn

0

05AB1E , 38 36 bytes

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

Inspirado na resposta de @Zgarb Husk .

Saída das listas delimitadas por nova linha.

Experimente online ou verifique todos os casos de teste .

Explicação:

Π           # 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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.