İkili Çitler


16

Giriş:

  • nAralıktaki bir tam sayı2 <= n <= 10
  • Pozitif tamsayıların listesi

Çıktı:

Tam sayıları ikili gösterimlere (baştaki sıfır olmadan) dönüştürün ve hepsini birleştirin.
Ardından n, çit direkleri miktarını kullanarak 'ikili çit' oluşturan tüm ikili alt dizeleri belirleyin . Her bir çit direği arasındaki boşlukların (sıfırlar) ilgisiz (en az 1), ancak çit direklerinin kendileri eşit genişlikte olmalıdır.
Burada ikili alt dizelerin her biri için eşleşmesi gereken normal ifadeler 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

n=4Örneklere bakıldığında :

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

Daha sonra "ikili çitler" eşleşmelerinin ikili rakamlarını kullanan sayıları çıkarırız.

Misal:

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

Birleştirilen bu tamsayının ikili temsili şöyledir:
1010101 1001101 1000111(NOT: Boşluklar yalnızca örnek için açıklama olarak eklenmiştir).

Çünkü n=4regex ile eşleşen alt dizeleri ararız (1+)0+\10+\10+\1, bu durumda iki tane bulabiliriz:
1010101(konumda (1010101) 1001101 1000111); ve 11001101100011(konumda 101010(1 1001101 100011)1)

İlk ikili çit, yalnızca gelen ikili basamakları kullanır 85ve ikinci ikili çit, üç tamsayıdan gelen ikili basamakları kullanır. Yani bu durumda çıktı:
[[85],[85,77,71]]

Zorluk kuralları:

  • Yukarıdaki örnekte de belirtilmiş olmasına rağmen, son cümle önemlidir: İkili basamakların kullanıldığı sayıları 'ikili çit' alt dizesinde çıkarırız.
  • G / Ç esnektir. Giriş bir liste / dizi / tamsayı akışı, boşluk / virgül / satırsonu ayrılmış dize, vb olabilir. Çıktı bir 2B tam sayı listesi, tek bir sınırlandırılmış dize, bir dize listesi, STDOUT'a yazdırılan yeni satır, vb. Olabilir. Tamamen size kalmış, ancak lütfen yanıtınızda ne kullandığınızı belirtin.
  • Listenin kendisinin çıktı sırası ilgisizdir, ancak her bir iç listenin çıktısı elbette giriş listesiyle aynı sıradadır. Yani yukarıdaki örnekle, [[85,77,71],[85]]geçerli bir çıktıdır, ancak [[85],[77,85,71]]değildir.
  • Örnek (the 85) ' den daha önce fark etmiş olabileceğiniz gibi , ikili rakamlar birden çok kez kullanılabilir.
  • Normal ifadeler, alt dize ile tamamen eşleşmelidir. Öyleyse 110101ya 010101da hiç geçerli bir 'ikili çit' değildir ( 10101ancak, iff n=3).
  • Çıktı listesindeki öğeler benzersiz değil, sadece 'ikili çitlerin' ikili konumları benzersizdir. Aynı tamsayılarla birden fazla 'ikili çit' oluşturulabilirse, bunları çıkış listesine birçok kez ekleriz.
    Örneğin: n=2, L=[109, 45](ikili 1101101 101101), bu iki terimli çit 'altdizgelerin oluşturabilir: 11011(pozisyonda (11011)01 101101); 101(konumda 1(101)101 101101); 11011(konumda 110(1101 1)01101); 101(konumda 1101(101) 101101); 11011(konumda 110110(1 1011)01); 101(konumda 1101101 (101)101); 101(pozisyonda 1101101 101(101)), böylece çıkış olur [[109],[109],[109,45],[109],[109,45],[45],[45]].
    Başka bir örnek: n=2, L=[8127](ikili 1111110111111), bu iki terimli çit 'altdizgelerin oluşturabilir: 1111110111111(pozisyonda (1111110111111));11111011111(konumda 1(11111011111)1); 111101111(konumda 11(111101111)11); 1110111(konumda 111(1110111)111); 11011(konumda 1111(11011)1111); 101(pozisyonda 11111(101)11111), böylece çıkış olur [[8127],[8127],[8127],[8127],[8127],[8127]].
  • Geçerli bir çıkış mümkün değilse, boş bir liste veya başka tür bir falsey çıkışı döndürebilirsiniz ( null,, falsebir hata atar, vb. Yine çağrınız).

Genel kurallar:

  • Bu , bayt en kısa cevap kazanır.
    Kod golf dillerinin, kod yazmayan dillerle yanıt göndermenizi engellemesine izin vermeyin. 'Herhangi bir' programlama dili için olabildiğince kısa bir cevap bulmaya çalışın.
  • Cevabınız için standart kurallar geçerlidir , bu nedenle STDIN / STDOUT, fonksiyonlar / yöntem uygun parametreler ve dönüş tipi, tam programlar ile kullanılabilir. Çağrınız.
  • Varsayılan Loopholes yasaktır.
  • Mümkünse, lütfen kodunuz için bir test içeren bir bağlantı ekleyin (örn. TIO ).
  • Ayrıca, cevabınız için bir açıklama eklemeniz önemle tavsiye edilir.

Test senaryoları:

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, kahkahalar, bunu tıpkı sınıf başlarken yayınladın!
Quintec

Is not [1,2,3]testcase 4 için geçerlidir? Çiti görüyorum(1 10 11)
TFeld

1
Tamam, sanırım bu sefer doğru anladım. Örneğin son cümlesini yeterince dikkatli okumadım. (Çok önemli olduğu için belki örnekte belirtilmemelidir.)
Arnauld

1
@ Şimdi ilk kural olarak örneğin son cümlesini ekledim. Umarım bu daha görünür olur.
Kevin Cruijssen

3
Aynı tamsayı örneğin listede birden çok görünen bir test durumu eklemek öneririm 2, [10, 10]yol açmalıdır [[10],[10,10],[10]]ben meydan correctl.y anlarsanız
nwellnhof

Yanıtlar:


5

Kabuk , 33 bayt

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

Çevrimiçi deneyin!

Tüm test senaryolarını geçer. Bu zor bir işti ve benim çözümüm biraz kıvrımlı geliyor.

açıklama

Program giriş dilimleri arasında dolaşır ve her biri normal ifadenin bir eşleşmesini içerdiği kadar tekrar eder. Yalnızca dilimdeki her sayının ikili genişlemesiyle çakışan eşleşmeleri saymak istiyoruz. Bu zor görünüyor, ancak ilk sayıyı kullanmayan eşleşmeleri saymak daha kolay: sadece bu sayıyı kaldırın ve tüm eşleşmeleri sayın. İyi eşleşmeleri elde etmek için tüm eşleşmeleri sayıyoruz, ardından ilk sayıyı kullanmayan ve son sayıyı kullanmayan maçların sayısını çıkarıyoruz. İkisini de kullanmayan eşleşmeler iki kez sayılır, bu nedenle doğru sonucu elde etmek için bunları eklemeliyiz.

Bir dilimdeki eşleşme sayısını saymak, ikili açılımları birleştirmek ve sonuç dilimleri üzerinde döngü yapmaktır. Husk'un normal ifadeler için desteği olmadığından, bir eşleşmeyi tanımak için liste manipülasyonunu kullanıyoruz. İşlev g, bir dilimi eşit bitişik eleman gruplarına böler. O zaman aşağıdakileri doğrulamalıyız:

  1. İlk grup 1 gruptur.
  2. Grup sayısı tuhaftır.
  3. 1 grup sayısı ilk girişe eşittir n.
  4. 1-grupların eşit uzunlukları vardır.

Önce grupları çiftler halinde kesiyoruz. 1 ve 2 tutarsa, her çiftin ilk grubu 1-grubudur ve son çift bir singletondur. Ardından, bu çift listesini bileşen olarak ekleyerek sıkıştırarak azaltıyoruz. Bu, 1-grupların ve 0-grupların ayrı ayrı eklendiği anlamına gelir. Ekleme taşan elemanları korur, böylece ekleme [1,1,1]ve [1,1]verir [2,2,1]. Sıkıştırma yapmaz, bu nedenle son çift bir tek tonsa, 0-grupların bileşensel toplamı sonuçtan kaybolur. Son olarak, sonuçtaki tüm sayıların eşit olduğunu kontrol ederiz 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 bayt

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

Çevrimiçi deneyin!

açıklama

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

Girişi alır (n)(list). Bir dizi dizi döndürür.

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

Çevrimiçi deneyin!

Nasıl?

sbs

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

Misal:

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

İkili çitlerle eşleşen normal bir ifade oluşturmak için aşağıdaki şablonu kullanırız:

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

sp

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

p=0

msibms

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 bayt

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

Çevrimiçi deneyin!


1

Python 2 , 182 bayt

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

Çevrimiçi deneyin!


Bu n, 2'den büyük herhangi bir giriş için bir hata veriyor gibi görünüyor . Ayrıca, n=2test senaryosu için yanlış bir sonuç verir n=2, L=[10,10]. Yine de n=2çalışma ile diğer test vakaları .
Kevin Cruijssen

Oh, neden başarısız olduğunu anlıyorum [10,10]; Bunu düzeltmenin ne kadar pahalı olduğunu göreyim…
Lynn

1
@KevinCruijssen Her iki sorunu da düzelttim (22 bayt pahasına, oh iyi!)
Lynn

0

05AB1E , 38 36 bayt

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

Esinlenerek @Zgarb 'ın Kabuk cevap .

Yeni satırla ayrılmış listelerin çıktısını alın.

Çevrimiçi deneyin veya tüm test senaryolarını doğrulayın .

Açıklama:

Œ            # 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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.