Les clôtures binaires

16

Contribution:

  • Un entier ndans la plage2 <= n <= 10
  • Une liste d'entiers positifs

Production:

Convertissez les entiers en leur représentation binaire (sans zéros non significatifs) et joignez-les tous ensemble.
Déterminez ensuite toutes les sous-chaînes binaires qui forment une «clôture binaire» en utilisant une nquantité de poteaux de clôture. Les espaces (zéros) entre chaque poteau de clôture ne sont pas pertinents (au moins 1), mais les poteaux de clôture eux-mêmes doivent tous être de largeur égale.
Ici, les expressions rationnelles les sous-chaînes binaires doivent correspondre pour chacun 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

En regardant les n=4exemples:

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

Nous sortons ensuite les nombres qui utilisent les chiffres binaires des correspondances «clôtures binaires».

Exemple:

Entrée: n=4,L=[85,77,71]

La représentation binaire de ces nombres entiers réunis est:
1010101 1001101 1000111(REMARQUE: les espaces ne sont ajoutés qu'à titre de clarification pour l'exemple).

Depuis n=4, nous recherchons des sous-chaînes correspondant à l'expression régulière (1+)0+\10+\10+\1, auquel cas nous pouvons en trouver deux:
1010101(à la position (1010101) 1001101 1000111); et 11001101100011(en position101010(1 1001101 100011)1 )

La première clôture binaire utilise uniquement des chiffres binaires de 85et la deuxième clôture binaire utilise des chiffres binaires des trois entiers. Ainsi, la sortie dans ce cas serait:
[[85],[85,77,71]]

Règles du défi:

  • Bien qu'elle soit également mentionnée dans l'exemple ci-dessus, la dernière phrase est importante: nous affichons les numéros pour lesquels des chiffres binaires sont utilisés dans la sous-chaîne «clôture binaire».
  • Les E / S sont flexibles. L'entrée peut être une liste / tableau / flux d'entiers, une chaîne délimitée par un espace / virgule / nouvelle ligne, etc. La sortie peut être une liste entière 2D, une seule chaîne délimitée, une liste de chaînes, une nouvelle ligne imprimée sur STDOUT, etc. Tout dépend de vous, mais veuillez indiquer ce que vous avez utilisé dans votre réponse.
  • L'ordre de sortie de la liste elle-même n'est pas pertinent, mais la sortie de chaque liste interne est bien sûr dans le même ordre que la liste d'entrée. Donc, avec l'exemple ci-dessus, [[85,77,71],[85]]est également une sortie valide, mais [[85],[77,85,71]]ne l'est pas.
  • Comme vous l'avez peut-être déjà remarqué dans l'exemple (le 85), les chiffres binaires peuvent être utilisés plusieurs fois.
  • Les expressions régulières doivent correspondre entièrement à la sous-chaîne. Donc 110101ou 010101ne sont jamais des «clôtures binaires» valides ( 10101est cependant ssi n=3).
  • Les éléments de la liste de sortie ne sont pas uniques, seules les positions binaires des «clôtures binaires» sont uniques. Si plusieurs «clôtures binaires» peuvent être créées avec le ou les mêmes nombres entiers, nous les ajoutons plusieurs fois à la liste de sortie.
    Par exemple: n=2, L=[109, 45](binaire 1101101 101101) peut former ces sous - chaînes « de clôture binaire »: 11011(en position (11011)01 101101); 101(en position 1(101)101 101101); 11011(en position 110(1101 1)01101); 101(en position 1101(101) 101101); 11011(en position 110110(1 1011)01); 101(en position 1101101 (101)101); 101(à la position 1101101 101(101)), donc la sortie serait [[109],[109],[109,45],[109],[109,45],[45],[45]].
    Un autre exemple: n=2, L=[8127](binaire 1111110111111) peut former ces sous - chaînes « de clôture binaire »: 1111110111111(en position(1111110111111) );11111011111(en position 1(11111011111)1); 111101111(en position 11(111101111)11); 1110111(en position 111(1110111)111); 11011(en position 1111(11011)1111); 101(à la position 11111(101)11111), donc la sortie serait [[8127],[8127],[8127],[8127],[8127],[8127]].
  • Si aucune sortie valide est possible, vous pouvez retourner une liste vide ou un autre type de sortie Falsey ( null, false, jette une erreur, etc. Encore une fois, votre appel).

Règles générales:

  • C'est le , donc la réponse la plus courte en octets l'emporte.
    Ne laissez pas les langues de golf de code vous décourager de publier des réponses avec des langues autres que le golf de code. Essayez de trouver une réponse aussi courte que possible pour «n'importe quel» langage de programmation.
  • Des règles standard s'appliquent à votre réponse, vous êtes donc autorisé à utiliser STDIN / STDOUT, fonctions / méthode avec les paramètres appropriés et des programmes complets de type retour. Ton appel.
  • Les failles par défaut sont interdites.
  • Si possible, veuillez ajouter un lien avec un test pour votre code (par exemple TIO ).
  • De plus, l'ajout d'une explication à votre réponse est fortement recommandé.

Cas de 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
Kevin Cruijssen
la source
Ah, shucks, vous avez posté ça juste au début du cours!
Quintec
N'est pas [1,2,3]valide pour le testcase 4? Je vois la clôture(1 10 11)
TFeld
1
Ok, je pense que j'ai bien compris cette fois. Je n'ai pas lu suffisamment la dernière phrase de l'exemple. (Puisqu'il est très important, il ne devrait peut-être pas être mentionné dans l'exemple.)
Arnauld
1
@Arnauld J'ai maintenant ajouté la dernière phrase de l'exemple comme première règle. J'espère que cela le rend plus apparent.
Kevin Cruijssen
3
Je suggère d'ajouter un cas de test où le même entier apparaît plusieurs fois dans la liste, par exemple, 2, [10, 10]ce qui devrait entraîner [[10],[10,10],[10]]si je comprends bien le défi correctl.y
nwellnhof

Réponses:

5

Husk , 33 octets

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

Essayez-le en ligne!

Réussit tous les cas de test. Ce fut un défi difficile et ma solution semble quelque peu compliquée.

Explication

Le programme parcourt les tranches de l'entrée et se répète autant de fois qu'il contient une correspondance de l'expression régulière. Nous voulons compter uniquement les correspondances qui chevauchent l'expansion binaire de chaque nombre dans la tranche. Cela semble difficile, mais il est plus facile de compter les correspondances qui n'utilisent pas le premier nombre: supprimez simplement ce nombre et comptez toutes les correspondances. Pour obtenir les bonnes correspondances, nous comptons donc toutes les correspondances, puis soustrayons le nombre de correspondances qui n'utilisent pas le premier numéro, et celles qui n'utilisent pas le dernier numéro. Les correspondances qui n'utilisent ni l'un ni l'autre sont comptées deux fois, nous devons donc les rajouter pour obtenir le résultat correct.

Compter le nombre de correspondances dans une tranche est une question de concaténation des extensions binaires et de bouclage sur les tranches du résultat. Étant donné que Husk ne prend pas en charge les expressions rationnelles, nous utilisons la manipulation de liste pour reconnaître une correspondance. La fonction gdivise une tranche en groupes d'éléments adjacents égaux. Ensuite, nous devons vérifier les points suivants:

  1. Le premier groupe est un groupe.
  2. Le nombre de groupes est impair.
  3. Le nombre de 1-groupes est égal à la première entrée n .
  4. Les groupes 1 ont des longueurs égales.

Nous avons d'abord découpé les groupes en paires. Si 1 et 2 tiennent, alors le premier groupe de chaque paire est un groupe 1 et la dernière paire est un singleton. Ensuite, nous réduisons cette liste de paires en les zippant avec une addition par composant. Cela signifie que les groupes 1 et les groupes 0 sont ajoutés séparément. L'addition préserve les éléments débordants, donc l'ajout [1,1,1]et [1,1]donne [2,2,1]. Le zippage ne fonctionne pas, donc si la dernière paire est un singleton, la somme des composants des groupes 0 disparaît du résultat. Enfin, nous vérifions que tous les nombres du résultat sont égaux à 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
la source
7

Perl 6 , 114 112 110 110 107 106 104 octets

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

Essayez-le en ligne!

Explication

->\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
la source
4

JavaScript (ES6), 187 184 177 173 octets

Prend l'entrée comme (n)(list). Renvoie un tableau de tableaux.

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

Essayez-le en ligne!

Comment?

sbs

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

Exemple:

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

Nous utilisons le modèle suivant pour générer une expression régulière correspondant aux clôtures binaires:

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

sp

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

p=0 et le jour à chaque itération en fonction de la position de la correspondance précédente.

msjeb ) chevauche l'intervalle fait des positions de début et de fin dem dans s.

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

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

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

Essayez-le en ligne!

TFeld
la source
1

Python 2 , 182 octets

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

Essayez-le en ligne!

Lynn
la source
Cela semble donner une erreur pour toute nentrée supérieure à 2. En outre, même avec n=2elle donne un résultat incorrect pour le cas de test n=2, L=[10,10]. Les autres cas de test avec le n=2travail, cependant.
Kevin Cruijssen
Oh, je vois pourquoi ça échoue [10,10]; laissez-moi voir combien il est coûteux de résoudre ce problème ...
Lynn
1
@KevinCruijssen J'ai corrigé les deux problèmes (au prix de 22 octets, eh bien!)
Lynn
0

05AB1E , 38 36 octets

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

Inspiré par la réponse Husk de @Zgarb .

Sortez les listes délimitées par des sauts de ligne.

Essayez-le en ligne ou vérifiez tous les cas de test .

Explication:

Œ            # 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
la source