Le recinzioni binarie


16

Ingresso:

  • Un numero intero nnell'intervallo2 <= n <= 10
  • Un elenco di numeri interi positivi

Produzione:

Converti gli interi nella loro rappresentazione binaria (senza zero iniziali) e uniscili tutti insieme.
Quindi determinare tutte le sottostringhe binarie che formano una 'recinzione binaria' utilizzando la nquantità di pali della recinzione. Gli spazi (zeri) tra ogni paletto sono irrilevanti (almeno 1), ma i paletti stessi devono essere tutti della stessa larghezza.
Qui le regex che le sottostringhe binarie devono corrispondere per ciascuna 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

Guardando gli n=4esempi:

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

Trasmettiamo quindi i numeri che usano cifre binarie delle "recinzioni binarie" corrispondenti.

Esempio:

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

La rappresentazione binaria di questi numeri interi uniti insieme è:
1010101 1001101 1000111(NOTA: gli spazi vengono aggiunti solo come chiarimento per l'esempio).

Poiché n=4, cerchiamo sottostringhe corrispondenti al regex (1+)0+\10+\10+\1, nel qual caso possiamo trovarne due:
1010101(nella posizione (1010101) 1001101 1000111); e 11001101100011(in posizione 101010(1 1001101 100011)1)

Il primo recinto binario utilizza solo cifre binarie da 85e il secondo recinto binario utilizza cifre binarie da tutti e tre i numeri interi. Quindi l'output in questo caso sarebbe:
[[85],[85,77,71]]

Regole della sfida:

  • Anche se è anche menzionato nell'esempio sopra, l'ultima frase è importante: vengono visualizzati i numeri per i quali vengono utilizzate le cifre binarie nella sottostringa "binary fence".
  • L'I / O è flessibile. L'input può essere un elenco / array / flusso di numeri interi, spazio / virgola / stringa delimitata da nuova riga, ecc. L'output può essere un elenco intero 2D, una singola stringa delimitata, un elenco di stringhe, una nuova riga stampata su STDOUT, ecc. Tutto a te, ma per favore, indica cosa hai usato nella tua risposta.
  • L'ordine di output dell'elenco stesso è irrilevante, ma l'output di ciascun elenco interno è ovviamente nello stesso ordine dell'elenco di input. Quindi, con l'esempio sopra, [[85,77,71],[85]]è anche un output valido, ma [[85],[77,85,71]]non lo è.
  • Come avrai già notato dall'esempio (il 85), le cifre binarie possono essere utilizzate più volte.
  • Le regex dovrebbero corrispondere interamente alla sottostringa. Quindi 110101o 010101non sono mai valide 'recinzioni binarie' ( 10101è comunque iff n=3).
  • Gli elementi nella lista di output non sono univoci, solo le posizioni binarie delle "recinzioni binarie" sono uniche. Se è possibile creare più 'recinzioni binarie' con gli stessi numeri interi, li aggiungiamo più volte all'elenco di output.
    Ad esempio n=2, L=[109, 45](binario 1101101 101101) può formare questi sottostringhe 'recinzione binario': 11011(in posizione (11011)01 101101); 101(in posizione 1(101)101 101101); 11011(in posizione 110(1101 1)01101); 101(in posizione 1101(101) 101101); 11011(in posizione 110110(1 1011)01); 101(in posizione 1101101 (101)101); 101(in posizione 1101101 101(101)), quindi l'uscita sarebbe [[109],[109],[109,45],[109],[109,45],[45],[45]].
    Un altro esempio: n=2, L=[8127](binario 1111110111111) può formare questi sottostringhe 'recinzione binario': 1111110111111(in posizione (1111110111111));11111011111(in posizione 1(11111011111)1); 111101111(in posizione 11(111101111)11); 1110111(in posizione 111(1110111)111); 11011(in posizione 1111(11011)1111); 101(in posizione 11111(101)11111), quindi l'uscita sarebbe [[8127],[8127],[8127],[8127],[8127],[8127]].
  • Se nessuna uscita valida è possibile, si può restituire un elenco vuoto o qualche altro tipo di output Falsey ( null, false, getta un errore, ecc Anche in questo caso, la chiamata).

Regole generali:

  • Questo è , quindi vince la risposta più breve in byte.
    Non lasciare che le lingue di code-golf ti scoraggino dal pubblicare risposte con lingue non codegolfing. Prova a trovare una risposta il più breve possibile per "qualsiasi" linguaggio di programmazione.
  • Per la tua risposta valgono regole standard , quindi puoi usare STDIN / STDOUT, funzioni / metodo con i parametri corretti e tipo di ritorno, programmi completi. La tua chiamata.
  • Sono vietate le scappatoie predefinite .
  • Se possibile, aggiungi un link con un test per il tuo codice (ad es. TIO ).
  • Inoltre, si consiglia vivamente di aggiungere una spiegazione per la risposta.

Casi test:

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, schifo, l'hai pubblicato proprio come è iniziata la lezione!
Quintec,

Non è [1,2,3]valido per testcase 4? Vedo la recinzione(1 10 11)
TFeld

1
Ok, penso di aver capito bene questa volta. Non ho letto abbastanza attentamente l'ultima frase dell'esempio. (Poiché è molto importante, forse non dovrebbe essere menzionato nell'esempio.)
Arnauld

1
@Arnauld Ho aggiunto l'ultima frase dell'esempio come prima regola ora. Spero che questo lo renda più evidente.
Kevin Cruijssen,

3
Suggerirei di aggiungere un caso di test in cui lo stesso numero intero appare più volte nell'elenco, ad esempio, 2, [10, 10]che dovrebbe risultare [[10],[10,10],[10]]se capisco la sfida correctl.y
nwellnhof

Risposte:


5

Buccia , 33 byte

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

Provalo online!

Supera tutti i casi di test. Questa è stata una sfida difficile e la mia soluzione sembra in qualche modo contorta.

Spiegazione

Il programma scorre ciclicamente le sezioni dell'input e si ripete ciascuna quante volte contiene una corrispondenza del regex. Vogliamo contare solo quelle corrispondenze che si sovrappongono all'espansione binaria di ogni numero nella sezione. Sembra difficile, ma è più facile contare quelle partite che non usano il primo numero: basta rimuovere quel numero e contare tutte le partite. Per ottenere le buone partite, contiamo quindi tutte le partite, quindi sottraggiamo il numero di partite che non usano il primo numero e quelle che non usano l'ultimo numero. Le partite che non utilizzano nessuno dei due vengono conteggiate due volte, quindi è necessario aggiungerle nuovamente per ottenere il risultato corretto.

Contare il numero di corrispondenze in una sezione è una questione di concatenazione delle espansioni binarie e il ciclo sulle sezioni del risultato. Poiché Husk non ha supporto per le regex, usiamo la manipolazione dell'elenco per riconoscere una corrispondenza. La funzione gdivide una sezione in gruppi di elementi adiacenti uguali. Quindi dobbiamo verificare quanto segue:

  1. Il primo gruppo è un gruppo.
  2. Il numero di gruppi è dispari.
  3. Il numero di 1 gruppi è uguale al primo input n.
  4. I 1 gruppi hanno uguale lunghezza.

Per prima cosa tagliamo i gruppi in coppie. Se 1 e 2 sono validi, il primo gruppo di ogni coppia è un gruppo 1 e l'ultima coppia è un singleton. Quindi riduciamo questo elenco di coppie comprimendole con un'aggiunta componente. Ciò significa che i gruppi 1 e 0 vengono aggiunti separatamente. L'aggiunta conserva elementi traboccanti, quindi aggiungendo [1,1,1]e [1,1]dando [2,2,1]. Lo zipping no, quindi se l'ultima coppia è un singleton, la somma per componente dei gruppi 0 scompare dal risultato. Infine, controlliamo che tutti i numeri nel risultato siano uguali 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 byte

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

Provalo online!

Spiegazione

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

Accetta input come (n)(list). Restituisce una matrice di matrici.

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

Provalo online!

Come?

SBS

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

Esempio:

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

Usiamo il seguente modello per generare un'espressione regolare corrispondente ai recinti binari:

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

Sp

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

p=0

mSioBmS

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 byte

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

Provalo online!


1

Python 2 , 182 byte

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

Provalo online!


Questo sembra dare un errore per qualsiasi ninput maggiore di 2. Inoltre, anche con n=2esso fornisce un risultato errato per il test case n=2, L=[10,10]. Gli altri casi di test con n=2lavoro, però.
Kevin Cruijssen,

Oh, vedo perché fallisce [10,10]; fammi vedere quanto è costoso aggiustarlo ...
Lynn,

1
@KevinCruijssen Ho risolto entrambi i problemi (al costo di 22 byte, vabbè!)
Lynn,

0

05AB1E , 38 36 byte

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

Ispirato dalla risposta Husk di @Zgarb .

Emette gli elenchi delimitati da nuova riga.

Provalo online o verifica tutti i casi di test .

Spiegazione:

Π           # 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.