Pagar Biner

16

Memasukkan:

  • Bilangan bulat ndalam kisaran2 <= n <= 10
  • Daftar bilangan bulat positif

Keluaran:

Konversikan bilangan bulat ke representasi biner mereka (tanpa angka nol di depan), dan gabungkan semuanya.
Kemudian tentukan semua substring biner yang membentuk 'pagar biner' menggunakan njumlah tiang pagar. Ruang (nol) di antara setiap tiang pagar tidak relevan (setidaknya 1), tetapi tiang pagar itu sendiri harus memiliki lebar yang sama.
Di sini regex substring biner harus cocok untuk masing-masing 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

Lihat n=4contoh - contohnya:

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

Kami kemudian menampilkan angka yang menggunakan digit biner dari 'pagar biner' yang cocok.

Contoh:

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

Representasi biner dari bilangan bulat ini yang digabungkan adalah:
1010101 1001101 1000111(CATATAN: Spasi hanya ditambahkan sebagai klarifikasi untuk contoh).

Karena n=4, kami mencari substring yang cocok dengan regex (1+)0+\10+\10+\1, dalam hal ini kami dapat menemukan dua:
1010101(pada posisi (1010101) 1001101 1000111); dan 11001101100011(pada posisi 101010(1 1001101 100011)1)

Pagar biner pertama hanya menggunakan digit biner 85, dan pagar biner kedua menggunakan digit biner dari ketiga bilangan bulat. Jadi output dalam hal ini adalah:
[[85],[85,77,71]]

Aturan tantangan:

  • Meskipun itu juga disebutkan dalam contoh di atas, kalimat terakhir adalah yang penting: Kami mengeluarkan angka yang menggunakan angka biner dalam substring 'pagar biner'.
  • I / O fleksibel. Input dapat berupa daftar / larik / aliran bilangan bulat, spasi / koma / string yang dibatasi baris, dll. Output dapat berupa bilangan bulat 2D, string tunggal yang dibatasi, daftar string, baris baru yang dicetak ke STDOUT, dll. Semuanya terserah Anda, tetapi sebutkan apa yang Anda gunakan dalam jawaban Anda.
  • Urutan output dari daftar itu sendiri tidak relevan, tetapi output dari masing-masing daftar dalam tentu saja dalam urutan yang sama dengan daftar input. Jadi dengan contoh di atas, [[85,77,71],[85]]adalah output yang valid juga, tetapi [[85],[77,85,71]]tidak.
  • Seperti yang mungkin telah Anda perhatikan dari contoh (the 85), digit biner dapat digunakan beberapa kali.
  • Regex harus sepenuhnya cocok dengan substring. Jadi 110101atau 010101tidak pernah menjadi 'pagar biner' yang valid ( 10101bagaimanapun, iff n=3).
  • Item dalam daftar output tidak unik, hanya posisi biner dari 'pagar biner' yang unik. Jika beberapa 'pagar biner' dapat dibuat dengan integer yang sama, kami menambahkannya beberapa kali ke daftar keluaran.
    Sebagai contoh: n=2,L=[109, 45] (biner 1101101 101101) dapat membentuk ini 'biner pagar' substring: 11011(pada posisi (11011)01 101101); 101(pada posisi 1(101)101 101101); 11011(pada posisi 110(1101 1)01101); 101(pada posisi 1101(101) 101101); 11011(pada posisi 110110(1 1011)01); 101(pada posisi 1101101 (101)101); 101(pada posisi 1101101 101(101)), jadi hasilnya akan [[109],[109],[109,45],[109],[109,45],[45],[45]].
    Contoh lain: n=2, L=[8127](biner 1111110111111) dapat membentuk ini 'biner pagar' substring: 1111110111111(pada posisi (1111110111111));11111011111(pada posisi 1(11111011111)1); 111101111(pada posisi 11(111101111)11); 1110111(pada posisi 111(1110111)111); 11011(pada posisi 1111(11011)1111); 101(pada posisi 11111(101)11111), jadi hasilnya akan [[8127],[8127],[8127],[8127],[8127],[8127]].
  • Jika tidak ada output yang valid yang mungkin, Anda dapat mengembalikan daftar kosong atau beberapa jenis output falsey lainnya ( null,, falsemenimbulkan kesalahan, dll. Sekali lagi, panggilan Anda).

Aturan umum:

  • Ini adalah , jadi jawaban tersingkat dalam byte menang.
    Jangan biarkan bahasa kode-golf mencegah Anda memposting jawaban dengan bahasa non-codegolf. Cobalah untuk memberikan jawaban sesingkat mungkin untuk bahasa pemrograman 'apa saja'.
  • Aturan standar berlaku untuk jawaban Anda, jadi Anda diperbolehkan menggunakan STDIN / STDOUT, fungsi / metode dengan parameter yang tepat dan tipe pengembalian, program lengkap. Panggilanmu.
  • Celah default tidak diperbolehkan.
  • Jika memungkinkan, silakan tambahkan tautan dengan tes untuk kode Anda (yaitu TIO ).
  • Juga, menambahkan penjelasan untuk jawaban Anda sangat dianjurkan.

Kasus uji:

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
sumber
Ah, sial, kamu memposting ini tepat saat kelas dimulai!
Quintec
Tidak [1,2,3]berlaku untuk testcase 4? Saya melihat pagar(1 10 11)
TFeld
1
Ok, saya pikir saya sudah benar kali ini. Saya tidak membaca kalimat terakhir dari contoh itu dengan cukup hati-hati. (Karena itu yang sangat penting, mungkin itu tidak boleh disebutkan dalam contoh.)
Arnauld
1
@Arnauld Saya telah menambahkan kalimat terakhir dari contoh sebagai aturan pertama sekarang. Saya harap itu membuatnya lebih jelas.
Kevin Cruijssen
3
Saya akan menyarankan untuk menambahkan kasus uji di mana bilangan bulat yang sama muncul beberapa kali dalam daftar, misalnya 2, [10, 10]yang akan menghasilkan [[10],[10,10],[10]]jika saya memahami tantangan correctl.y
nwellnhof

Jawaban:

5

Sekam , 33 bytes

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

Cobalah online!

Lewati semua kasus uji. Ini adalah tantangan yang sulit dan solusi saya terasa agak berbelit-belit.

Penjelasan

Program loop melalui irisan input, dan mengulangi masing-masing sebanyak mengandung kecocokan dari regex. Kami hanya ingin menghitung kecocokan yang tumpang tindih dengan ekspansi biner dari setiap angka di slice. Ini tampaknya sulit, tetapi lebih mudah untuk menghitung kecocokan yang tidak menggunakan angka pertama: hapus saja angka itu dan hitung semua kecocokan. Untuk mendapatkan kecocokan yang baik, kami menghitung semua kecocokan, lalu kurangi jumlah kecocokan yang tidak menggunakan angka pertama, dan kecocokan yang tidak menggunakan angka terakhir. Pertandingan yang menggunakan keduanya tidak dihitung dua kali, jadi kami harus menambahkannya kembali untuk mendapatkan hasil yang benar.

Menghitung jumlah kecocokan dalam sebuah irisan adalah masalah menggabungkan ekspansi biner dan mengulangi irisan hasil. Karena Husk tidak memiliki dukungan untuk regex, kami menggunakan manipulasi daftar untuk mengenali kecocokan. Fungsi ini gmembagi irisan menjadi kelompok-kelompok elemen yang berdekatan yang sama. Maka kita harus memverifikasi yang berikut:

  1. Grup pertama adalah grup 1.
  2. Jumlah grupnya ganjil.
  3. Jumlah 1-grup sama dengan input pertama n.
  4. 1-grup memiliki panjang yang sama.

Pertama-tama kita memotong kelompok menjadi berpasangan. Jika 1 dan 2 bertahan, maka kelompok pertama dari setiap pasangan adalah 1-kelompok dan pasangan terakhir adalah singleton. Kemudian kami mengurangi daftar pasangan ini dengan meng-zipnya dengan penambahan komponen. Ini berarti 1-grup dan 0-grup ditambahkan secara terpisah. Penambahan ini mempertahankan elemen yang meluap, sehingga menambah [1,1,1]dan [1,1]memberi [2,2,1]. Zip tidak, jadi jika pasangan terakhir adalah singleton, jumlah komponen-0 dari kelompok-0 menghilang dari hasilnya. Akhirnya, kami memeriksa bahwa semua angka dalam hasilnya sama dengan 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
sumber
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}>/]}

Cobalah online!

Penjelasan

->\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
sumber
4

JavaScript (ES6), 187 184 177 173 byte

Mengambil input sebagai (n)(list). Mengembalikan array array.

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

Cobalah online!

Bagaimana?

sbs

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

Contoh:

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

Kami menggunakan templat berikut untuk menghasilkan pagar biner pencocokan ekspresi reguler:

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

shal

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

hal=0

mssayabms

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

Cobalah online!

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

Cobalah online!

Lynn
sumber
Ini tampaknya memberikan kesalahan untuk ninput yang lebih besar dari 2. Juga, bahkan dengan n=2itu memberikan hasil yang salah untuk test case n=2, L=[10,10]. Kasus uji lain dengan n=2pekerjaan, meskipun.
Kevin Cruijssen
Oh, aku mengerti mengapa itu gagal [10,10]; biarkan saya melihat betapa mahal untuk memperbaikinya ...
Lynn
1
@KevinCruijssen Saya memperbaiki kedua masalah (dengan biaya 22 byte, oh well!)
Lynn
0

05AB1E , 38 36 byte

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

Terinspirasi oleh jawaban Husk @Zgarb .

Keluarkan daftar-baris baru dibatasi.

Cobalah secara online atau verifikasi semua kasus uji .

Penjelasan:

Œ            # 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
sumber