Binarne ogrodzenia

16

Wejście:

  • Liczba całkowita nw zakresie2 <= n <= 10
  • Lista liczb całkowitych dodatnich

Wynik:

Konwertuj liczby całkowite na ich reprezentację binarną (bez zer wiodących) i łącz je wszystkie razem.
Następnie określ wszystkie binarne podciągi, które tworzą „binarne ogrodzenie”, używając nilości słupków ogrodzeniowych. Odstępy (zera) między każdym słupkiem ogrodzeniowym są nieistotne (co najmniej 1), ale same słupki ogrodzeniowe powinny mieć jednakową szerokość.
Tutaj wyrażenia regularne binarne podciągi powinny pasować do każdego 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

Patrząc na n=4przykłady:

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

Następnie wyprowadzamy liczby wykorzystujące binarne cyfry dopasowań „binarnych ogrodzeń”.

Przykład:

Wejście: n=4,L=[85,77,71]

Binarna reprezentacja połączonych ze sobą liczb całkowitych jest następująca:
1010101 1001101 1000111(UWAGA: spacje zostały dodane jedynie jako objaśnienie dla przykładu).

Ponieważ n=4szukamy podciągów pasujących do wyrażenia regularnego (1+)0+\10+\10+\1, w którym to przypadku możemy znaleźć dwa:
1010101(w pozycji (1010101) 1001101 1000111); i 11001101100011(w pozycji 101010(1 1001101 100011)1)

Pierwszy płot binarny używa tylko cyfr binarnych z 85, a drugi płot binarny używa cyfr binarnych ze wszystkich trzech liczb całkowitych. W takim przypadku wynikiem byłoby:
[[85],[85,77,71]]

Zasady konkursu:

  • Chociaż jest to również wspomniane w powyższym przykładzie, ostatnie zdanie jest ważne: podajemy liczby, dla których cyfry binarne są używane w podciągu „ogrodzenia binarnego”.
  • I / O jest elastyczny. Dane wejściowe mogą być listą / tablicą / strumieniem liczb całkowitych, spacją / przecinkiem / znakiem nowej linii itp. Dane wyjściowe mogą być listą całkowitą 2D, pojedynczym ciągiem rozdzielanym, listą ciągów, nową linią drukowaną do STDOUT itp. Wszystko zależy od ciebie, ale proszę podać, co użyłeś w swojej odpowiedzi.
  • Kolejność wyjściowa samej listy nie ma znaczenia, ale dane wyjściowe każdej wewnętrznej listy są oczywiście w tej samej kolejności co lista wejściowa. Tak więc w powyższym przykładzie [[85,77,71],[85]]jest również poprawnym wyjściem, ale [[85],[77,85,71]]nie jest.
  • Jak już zauważyłeś na przykładzie ( 85), cyfry binarne mogą być używane wiele razy.
  • Wyrazy regularne powinny całkowicie pasować do podłańcucha. Tak 110101lub 010101nie są nigdy ważnej „płoty” (binarnych 10101jest jednak, MFF n=3).
  • Elementy na liście wyników nie są unikalne, tylko pozycje binarne „ogrodzeń binarnych” są unikalne. Jeśli można utworzyć wiele „ogrodzeń binarnych” z tą samą liczbą (liczbami całkowitymi), dodajemy je wiele razy do listy wyników.
    Na przykład n=2, L=[109, 45](binarne 1101101 101101) mogą tworzyć te podciągi „ogrodzenia binarne” 11011(pozycja (11011)01 101101); 101(w pozycji 1(101)101 101101); 11011(w pozycji 110(1101 1)01101); 101(w pozycji 1101(101) 101101); 11011(w pozycji 110110(1 1011)01); 101(w pozycji 1101101 (101)101); 101(w pozycji 1101101 101(101)), więc wynik będzie [[109],[109],[109,45],[109],[109,45],[45],[45]].
    Innym przykładem n=2, L=[8127](binarne 1111110111111) mogą tworzyć te podciągi „ogrodzenia binarne” 1111110111111(pozycja (1111110111111));11111011111(w pozycji 1(11111011111)1); 111101111(w pozycji 11(111101111)11); 1110111(w pozycji 111(1110111)111); 11011(w pozycji 1111(11011)1111); 101(w pozycji 11111(101)11111), więc wynik będzie [[8127],[8127],[8127],[8127],[8127],[8127]].
  • Jeśli nie ważne wyjście jest możliwe, można powrócić pustą listę lub innego rodzaju wyjścia falsey ( null, false, zgłasza błąd, itp Znowu, połączenie).

Główne zasady:

  • To jest , więc wygrywa najkrótsza odpowiedź w bajtach.
    Nie pozwól, aby języki kod-golfowe zniechęcały Cię do publikowania odpowiedzi w językach niekodujących golfa. Spróbuj znaleźć możliwie najkrótszą odpowiedź na „dowolny” język programowania.
  • Do odpowiedzi mają zastosowanie standardowe reguły , więc możesz używać STDIN / STDOUT, funkcji / metody z odpowiednimi parametrami i zwracanymi typami, pełnych programów. Twoja decyzja.
  • Domyślne luki są zabronione.
  • Jeśli to możliwe, dodaj link z testem kodu (tj. TIO ).
  • Zalecane jest również dodanie wyjaśnienia do odpowiedzi.

Przypadki testowe:

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
źródło
Ach, kurwa, opublikowałeś to tak, jak zaczęła się klasa!
Quintec,
Nie jest [1,2,3]ważny dla przypadku testowego 4? Widzę ogrodzenie(1 10 11)
TFeld
1
Ok, myślę, że tym razem mam rację. Nie przeczytałem dokładnie ostatniego zdania przykładu. (Ponieważ jest to bardzo ważny, być może nie powinien być wymieniony w przykładzie).
Arnauld,
1
@Arnauld Dodałem teraz ostatnie zdanie przykładu jako pierwszą regułę. Mam nadzieję, że to czyni to bardziej widocznym.
Kevin Cruijssen
3
Proponuję dodać przypadek testowy, w którym ta sama liczba całkowita pojawia się wiele razy na liście, na przykład, 2, [10, 10]co powinno skutkować, [[10],[10,10],[10]]jeśli zrozumiem wyzwanie poprawne.y
nwellnhof

Odpowiedzi:

5

Łuska , 33 bajty

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

Wypróbuj online!

Przechodzi wszystkie przypadki testowe. Było to trudne wyzwanie, a moje rozwiązanie wydaje się nieco skomplikowane.

Wyjaśnienie

Program przechodzi przez wycinki danych wejściowych i powtarza je tyle razy, ile zawiera dopasowanie wyrażenia regularnego. Chcemy liczyć tylko te dopasowania, które nakładają się na rozwinięcie binarne każdej liczby w wycinku. Wydaje się to trudne, ale łatwiej policzyć te mecze, które nie używają pierwszej liczby: wystarczy usunąć tę liczbę i policzyć wszystkie mecze. Aby uzyskać dobre dopasowania, zliczamy więc wszystkie dopasowania, a następnie odejmujemy liczbę dopasowań, które nie używają pierwszej liczby, i te, które nie używają ostatniej liczby. Dopasowania, które nie używają żadnego, są liczone dwukrotnie, dlatego musimy je dodać z powrotem, aby uzyskać poprawny wynik.

Zliczanie liczby dopasowań w wycinku polega na powiązaniu rozszerzeń binarnych i zapętleniu wycinków wyniku. Ponieważ Husk nie obsługuje wyrażeń regularnych, używamy manipulacji listami, aby rozpoznać dopasowanie. Funkcja gdzieli plasterek na grupy równych sąsiadujących elementów. Następnie musimy zweryfikować następujące elementy:

  1. Pierwsza grupa to 1 grupa.
  2. Liczba grup jest nieparzysta.
  3. Liczba 1 grup jest równa pierwszej wartości wejściowej n.
  4. Grupy 1 mają równe długości.

Najpierw podzielimy grupy na pary. Jeśli 1 i 2 utrzymają się, pierwsza grupa każdej pary to 1 grupa, a ostatnia para to singleton. Następnie zmniejszamy tę listę par, kompresując je za pomocą dodawania komponentowego. Oznacza to, że grupy 1 i grupy 0 są dodawane osobno. Dodanie chroni przepełnione elementy, więc dodawanie [1,1,1]i [1,1]dawanie [2,2,1]. Zipping nie działa, więc jeśli ostatnia para jest singletonem, suma składowa grup 0 znika z wyniku. Na koniec sprawdzamy, czy wszystkie liczby w wyniku są równe 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
źródło
7

Perl 6 , 114 112 110 107 106 104 bajtów

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

Wypróbuj online!

Wyjaśnienie

->\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
źródło
4

JavaScript (ES6), 187 184 177 173 bajtów

Pobiera dane wejściowe jako (n)(list). Zwraca tablicę tablic.

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

Wypróbuj online!

W jaki sposób?

sbs

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

Przykład:

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

Używamy następującego szablonu, aby wygenerować ogrodzenia binarne pasujące do wyrażeń regularnych:

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

sp

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

p=0

Ilekroć mecz msjabms

a.filter((_, i) => -~b[i - 1] < p + m[0].length & b[i] >= p, p -= ~m.index)
Arnauld
źródło
3

Python 2 , 271 246 223 214 208 202 200 195 bajtów

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

Wypróbuj online!

TFeld
źródło
1

Python 2 , 182 bajty

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

Wypróbuj online!

Lynn
źródło
Wydaje się, że powoduje to błąd dla dowolnego nwejścia większego niż 2. Także, nawet n=2jeśli daje niepoprawny wynik dla przypadku testowego n=2, L=[10,10]. Jednak inne przypadki testowe z n=2pracą.
Kevin Cruijssen
Och, rozumiem, dlaczego zawodzi [10,10]; pokażę, jak kosztowne jest naprawienie tego…
Lynn
1
@KevinCruijssen Naprawiłem oba problemy (kosztem 22 bajtów, no cóż!)
Lynn
0

05AB1E , 38 36 bajtów

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

Zainspirowany @Zgarb „s Husk odpowiedź .

Wypisuj listy rozdzielane znakami nowej linii.

Wypróbuj online lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie:

Œ            # 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
źródło