Las vallas binarias

16

Entrada:

  • Un entero nen el rango2 <= n <= 10
  • Una lista de enteros positivos

Salida:

Convierta los enteros a su representación binaria (sin ceros a la izquierda), y únalos a todos juntos.
Luego determine todas las subcadenas binarias que forman una 'cerca binaria' usando la ncantidad de postes de cerca. Los espacios (ceros) entre cada poste de la cerca son irrelevantes (al menos 1), pero los postes de la cerca deben tener el mismo ancho.
Aquí las expresiones regulares que las subcadenas binarias deben coincidir para cadan :

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

Mirando los n=4ejemplos:

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

Luego sacamos los números que usan dígitos binarios de las coincidencias 'cercas binarias'.

Ejemplo:

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

La representación binaria de estos enteros unidos es:
1010101 1001101 1000111(NOTA: Los espacios solo se agregan como aclaración para el ejemplo).

Desde entonces n=4, buscamos subcadenas que coincidan con la expresión regular (1+)0+\10+\10+\1, en cuyo caso podemos encontrar dos:
1010101(en la posición (1010101) 1001101 1000111); y 11001101100011(en la posición 101010(1 1001101 100011)1)

La primera cerca binaria solo usa dígitos binarios de 85, y la segunda cerca binaria usa dígitos binarios de los tres enteros. Entonces la salida en este caso sería:
[[85],[85,77,71]]

Reglas de desafío:

  • Aunque también se menciona en el ejemplo anterior, la última oración es importante: sacamos los números para los que se utilizan dígitos binarios en la subcadena 'cerca binaria'.
  • I / O es flexible. La entrada puede ser una lista / matriz / secuencia de enteros, espacio / coma / cadena delimitada por nueva línea, etc. La salida puede ser una lista entera en 2D, una sola cadena delimitada, una lista de cadenas, una nueva línea impresa en STDOUT, etc. Todo depende de usted, pero indique lo que ha utilizado en su respuesta.
  • El orden de salida de la lista en sí es irrelevante, pero la salida de cada lista interna es, por supuesto, en el mismo orden que la lista de entrada. Entonces, con el ejemplo anterior, también [[85,77,71],[85]]es una salida válida, pero [[85],[77,85,71]]no lo es.
  • Como ya habrás notado en el ejemplo (the 85), los dígitos binarios se pueden usar varias veces.
  • Las expresiones regulares deben coincidir con la subcadena por completo. Por lo tanto, 110101o 010101no son nunca una 'cerca binaria' válida ( 10101es, sin embargo, iff n=3).
  • Los elementos en la lista de salida no son únicos, solo las posiciones binarias de las 'cercas binarias' son únicas. Si se pueden crear múltiples 'cercas binarias' con los mismos enteros, los agregamos varias veces a la lista de salida.
    Por ejemplo: n=2, L=[109, 45](binario 1101101 101101) puede formar estas subcadenas 'valla binario': 11011(en la posición (11011)01 101101); 101(en la posición 1(101)101 101101); 11011(en la posición 110(1101 1)01101); 101(en la posición 1101(101) 101101); 11011(en la posición 110110(1 1011)01); 101(en la posición 1101101 (101)101); 101(en la posición 1101101 101(101)), entonces la salida sería [[109],[109],[109,45],[109],[109,45],[45],[45]].
    Otro ejemplo: n=2, L=[8127](binario 1111110111111) puede formar estas subcadenas 'valla binario': 1111110111111(en la posición (1111110111111));11111011111(en la posición 1(11111011111)1);111101111(en la posición 11(111101111)11); 1110111(en la posición 111(1110111)111); 11011(en la posición 1111(11011)1111); 101(en la posición 11111(101)11111), entonces la salida sería [[8127],[8127],[8127],[8127],[8127],[8127]].
  • Si no hay salida válida es posible, puede devolver una lista vacía o algún otro tipo de salida Falsey- ( null, false, arroja un error, etc. Una vez más, su llamada).

Reglas generales:

  • Este es el , por lo que la respuesta más corta en bytes gana.
    No permita que los lenguajes de code-golf lo desanimen a publicar respuestas con lenguajes que no sean codegolfing. Trate de encontrar una respuesta lo más breve posible para 'cualquier' lenguaje de programación.
  • Aplican reglas estándar para su respuesta, por lo que puede usar STDIN / STDOUT, funciones / método con los parámetros adecuados y programas completos de tipo retorno. Tu llamada.
  • Las lagunas predeterminadas están prohibidas.
  • Si es posible, agregue un enlace con una prueba para su código (es decir, TIO ).
  • Además, se recomienda agregar una explicación para su respuesta.

Casos de prueba:

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
Kevin Cruijssen
fuente
Ah, carajo, ¡publicaste esto justo cuando comenzó la clase!
Quintec
¿No es [1,2,3]válido para el caso de prueba 4? Veo la cerca(1 10 11)
TFeld
1
Ok, creo que lo hice bien esta vez. No leí la última oración del ejemplo con suficiente atención. (Dado que es muy importante, tal vez no debería mencionarse en el ejemplo).
Arnauld
1
@Arnauld He agregado la última oración del ejemplo como primera regla ahora. Espero que eso lo haga más evidente.
Kevin Cruijssen
3
Yo sugeriría añadir un caso de prueba en el mismo entero aparece varias veces en la lista, por ejemplo, 2, [10, 10]que debería traducirse en [[10],[10,10],[10]]si entiendo el desafío correctl.y
nwellnhof

Respuestas:

5

Casco , 33 bytes

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

Pruébalo en línea!

Pasa todos los casos de prueba. Este fue un desafío difícil y mi solución se siente algo complicada.

Explicación

El programa recorre los segmentos de la entrada y los repite tantas veces como contiene una coincidencia de la expresión regular. Queremos contar solo aquellas coincidencias que se superponen a la expansión binaria de cada número en el segmento. Esto parece difícil, pero es más fácil contar esas coincidencias que no usan el primer número: simplemente elimine ese número y cuente todas las coincidencias. Para obtener las buenas coincidencias, contamos todas las coincidencias, luego restamos el número de coincidencias que no usan el primer número y las que no usan el último número. Las coincidencias que no usan ninguno se cuentan dos veces, por lo que debemos agregarlas nuevamente para obtener el resultado correcto.

Contar el número de coincidencias en un segmento es cuestión de concatenar las expansiones binarias y recorrer los segmentos del resultado. Como Husk no tiene soporte para expresiones regulares, usamos la manipulación de listas para reconocer una coincidencia. La función gdivide una división en grupos de elementos adyacentes iguales. Luego debemos verificar lo siguiente:

  1. El primer grupo es un grupo 1.
  2. El número de grupos es impar.
  3. El número de 1 grupos es igual a la primera entrada n.
  4. Los grupos 1 tienen longitudes iguales.

Primero cortamos los grupos en pares. Si 1 y 2 se mantienen, entonces el primer grupo de cada par es un grupo 1 y el último par es un singleton. Luego reducimos esta lista de pares comprimiéndolos con la suma de componentes. Esto significa que los grupos 1 y 0 se agregan por separado. La adición conserva elementos que se desbordan, por lo que agrega [1,1,1]y [1,1]da [2,2,1]. La compresión no lo hace, así que si el último par es un singleton, la suma componente de los grupos 0 desaparece del resultado. Finalmente, verificamos que todos los números en el resultado sean iguales 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.
Zgarb
fuente
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}>/]}

Pruébalo en línea!

Explicación

->\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
 ]
}
nwellnhof
fuente
4

JavaScript (ES6), 187 184 177 173 bytes

Toma entrada como (n)(list). Devuelve una matriz de matrices.

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

Pruébalo en línea!

¿Cómo?

Primero calculamos la cadena binaria s y una lista si que describe los límites de cada número en s.

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

Ejemplo:

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

Utilizamos la siguiente plantilla para generar una expresión regular que coincida con vallas binarias:

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

Esta expresión regular se aplica a s, comenzando desde una posición pag.

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

Empezamos con pag=0 0 y actualícelo en cada iteración de acuerdo con la posición de la coincidencia anterior.

Cada vez que un partido metro se encuentra en s: para cada yo-th número en la matriz de entrada, probamos si el intervalo está hecho de sus límites (almacenado en si) se superpone al intervalo realizado de las posiciones inicial y final de metro en s.

a.filter((_, i) => -~b[i - 1] < p + m[0].length & b[i] >= p, p -= ~m.index)
Arnauld
fuente
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

Pruébalo en línea!

TFeld
fuente
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

Pruébalo en línea!

Lynn
fuente
Esto parece dar un error para cualquier nentrada mayor que 2. Además, incluso con n=2eso da un resultado incorrecto para el caso de prueba n=2, L=[10,10]. Sin n=2embargo, los otros casos de prueba con trabajo.
Kevin Cruijssen
Oh, veo por qué falla [10,10]; déjame ver lo costoso que es arreglar eso ...
Lynn
1
@KevinCruijssen Solucioné ambos problemas (a un costo de 22 bytes, ¡bueno!)
Lynn
0

05AB1E , 38 36 bytes

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

Inspirado por la respuesta Husk de @Zgarb .

Salida de las listas delimitadas por nueva línea.

Pruébelo en línea o verifique todos los casos de prueba .

Explicación:

Œ            # 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
Kevin Cruijssen
fuente