Binarray'i bulun!


24

Bir binarray'ı aşağıdaki özellikleri sağlayan bir dizi olarak tanımlarız :

  • boş değil
  • ilk değer bir 1
  • son değer bir 1
  • diğer tüm değerler 0ya1

Örneğin, dizi [ 1, 1, 0, 1 ]geçerli bir binarray .

Görev

Boş olmayan dizi Verilen bir negatif olmayan tamsayılar ve tamsayı pozitif N , işiniz bulmaktır binarray B uzunluğunun N oluşturmasına olanak sağlar A kopyalarının sınırsız sayıda toplayarak B , sınırsız sayıda kaydırılacaktır pozisyonlar.

Örnek

A = [ 1, 1, 2, 4, 1, 2, 2, 1, 0, 1, 0, 1, 1, 0, 1 ]
N = 4

Bu girdi için binarray B = [ 1, 1, 0, 1 ] geçerli bir cevap olacaktır, çünkü şunları yapabiliriz:

  [ 1, 1, 0, 1 ]
+       [ 1, 1, 0, 1 ]
+       [ 1, 1, 0, 1 ]
+          [ 1, 1, 0, 1 ]
+                   [ 1, 1, 0, 1 ]
+                                  [ 1, 1, 0, 1 ]
  -----------------------------------------------
= [ 1, 1, 2, 4, 1, 2, 2, 1, 0, 1, 0, 1, 1, 0, 1 ]

kurallar

  • Giriş, herhangi bir makul formatta alınabilir.
  • Çıktı yerel bir dizi (örn. [1, 1, 0, 1]) Veya ayırıcı olan veya olmayan bir ikili dize olabilir (örneğin "1,1,0,1"veya "1101")
  • Yalnızca bir geçerli binarray yazdırmanız veya iade etmeniz gerekir . Alternatif olarak, birkaç çözüm olduğunda hepsini yazdırabilir veya iade edebilirsiniz .
  • Herhangi bir çözüme yol açmayan girişleri desteklemeniz gerekmez.
  • Toplam, B'nin herhangi bir kopyasıyla örtüşmeyen örtük sıfırları içerebilir . Yukarıdaki toplamdaki ikinci sıfır, böyle açık bir sıfırdır.
  • A maksimum boyutunun 100, B maksimum boyutunun 30 olduğunu varsayabilirsiniz .
  • Bu kod golf, yani bayt cinsinden en kısa cevap kazanır. Standart boşluklar yasaktır.

Test durumları

Input : N = 1 / A = [ 1, 2, 3, 4, 5 ]
Output: [ 1 ]

Input : N = 2 / A = [ 1, 2, 100, 99 ]
Output: [ 1, 1 ]

Input : N = 3 / A = [ 1, 1, 1 ]
Output: [ 1, 1, 1 ]

Input : N = 3 / A = [ 1, 1, 3, 2, 2 ]
Output: [ 1, 1, 1 ]

Input : N = 3 / A = [ 1, 0, 2, 1, 1, 1, 0, 0, 1, 0, 1 ]
Output: [ 1, 0, 1 ]

Input : N = 4 / A = [ 1, 2, 2, 2, 1 ]
Output: [ 1, 1, 1, 1 ]

Input : N = 4 / A = [ 1, 1, 2, 4, 1, 2, 2, 1, 0, 1, 0, 1, 1, 0, 1 ]
Output: [ 1, 1, 0, 1 ]

Input : N = 4 / A = [ 1, 1, 0, 2, 1, 0, 1 ]
Output: [ 1, 0, 0, 1 ] or [ 1, 1, 0, 1 ]

Input : N = 5 / A = [ 1, 3, 6, 9, 8, 6, 3, 4 ]
Output: [ 1, 1, 1, 0, 1 ]

Input : N = 8 / A = [ 2, 1, 0, 2, 3, 3, 1, 2, 1 ]
Output: [ 1, 0, 0, 1, 1, 1, 0, 1 ]

Input : N = 10 / A = [ 1, 2, 1, 2, 2, 1, 3, 3, 3, 2, 3, 0, 2, 1, 1, 0, 1 ]
Output: [ 1, 1, 0, 1, 0, 1, 1, 1, 0, 1 ]

Input : N = 13 / A = [ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 ]
Output: [ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ]

Input : N = 5 / A = [ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 ]
Output: [ 1, 1, 1, 1, 1 ]

Input : N = 6 / A = [ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 ]
Output: [ 1, 0, 0, 0, 0, 1 ]

Input : N = 7 / A = [ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 ]
Output: [ 1, 1, 0, 0, 0, 1, 1 ]

Input : N = 9 / A = [ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 ]
Output: [ 1, 0, 1, 0, 1, 0, 1, 0, 1 ]

NMakul olarak desteklenmesi gereken en büyük değer nedir ?
Neil

@Neil A ve B'nin her ikisine de beden sınırlarını ekledim
Arnauld

1
@ fəˈnɛtɪk Belki, ama bunun için N=4, A = [ 1, 1, 2, 4, 1, 2, 2, 2, 1, 2, 2, 1, 2, 0, 1 ], hem 11 hem de 13 tarafından bölünebilen 30459'u alırsınız, ancak bunlardan sadece biri [ 1, 1, 0, 1 ]ve [ 1, 0, 1, 1 ]geçerli bir cevaptır.
Neil

1
@ fəˈnɛtɪk Bu sayılar 2. basamağa yazılmadığından, aritmetik kuralları uygulanmaz. Örneğin, eklerken açıkça taşıyamazsınız.
BallpointBen

2
Lütfen gönderilen cevapların neredeyse tamamını bozan görünen bu test durumlarını ekleyin: N = 3, A = [1, 0, 2, 0, 2, 0, 1], çıktı = [1, 0, 1]; N = 3, A = [1, 1, 1, 0, 0, 0, 1, 1, 1], çıkış = [1, 1, 1].
Anders Kaseorg

Yanıtlar:


8

PHP, 105 92 90 86 bayt

Jörg’ün çözümü sabitlendi ve golf oynadı

for($b=1+2**$argv[1];;)--$argc>1?$s+=$argv[$argc]*2**$i++:$s%($b-=2)||die(decbin($b));

Nilk komut satırı argümanından, ondan sonraki değerlerden alır ; çevrimiçi olarak çalıştırın -rveya test edin .
ikili sayıyı basar (format 10001); geçersiz bir çözüm yazdırır veya geçerli bir çözüm bulunmadığında çalışmaz.

geçersiz giriş için hiçbir şey yazdırmayan ilk sürüm (şimdi 97 bayt): çevrimiçi sınayın

for($b=1+$m=2**$argv[1];$m/2<=$b;)--$argc>1?$s+=$argv[$argc]*2**$i++:$s%($b-=2)||die(decbin($b));

Yıkmak

for($b=1+$m=2**$argv[1];$m/2<=$b;)  # second loop: loop $b from 2^N-1 by -2 to 2^(N-1)
--$argc>1                           # first loop: decrease $argc ...
    ?$s+=$argv[$argc]*2**$i++           # while $argc>1: binary sum from last to 2nd argument
    :$s%($b-=2)||die(decbin($b));       # later: if $b divides $s, print in binary and exit

100’ün altındaki bir bayt sayısına ulaşamaz mısın?
Jörg Hülsermann

1
@ JörgHülsermann Yapabilirim.
Titus,

Ağır Düşünme. Bundan önce senin daha iyi olduğunu biliyorum. İnşallah en düşük bayt sayısını tutabilirsin
Jörg Hülsermann

1
N = 3, A = [1, 0, 2, 0, 2, 0, 1] 'de, bu doğru111 tek sonucun [1, 0, 1] olduğu yerde yanlış döner .
Anders Kaseorg

8

PHP , 219 bayt

<?for(list($g,$z)=$_GET,$d=~-$l=2**$z;$d>=$l/2;max(array_diff_assoc($r,$g)?:[0])?:$o[]=$b,$d-=2)for($r=[],$b=decbin($d),$k=0;$k<count($g);$k++)for($u=$g[$k]-$r[$k],$i=0;$i<$z;$i++)$u<1?:$r[$k+$i]+=$u*$b[$i];print_r($o);

Çevrimiçi deneyin!

-4 Bayt [$g,$z]=$_GETyerine PHP 7.1 kullanaraklist($g,$z)=$_GET


Son sınama durumu için hem geçerli ( [1,0,1,0,1,0,1,0,1]) hem de geçersiz bir cevap ( [1,0,0,0,1,0,1,1,1]) çıktıyor gibi görünüyor .
Arnauld,

-8 bayt: while($_GET[0])$s+=2**$i++*array_pop($_GET[0]);. -5 bayt: range(1|.5*$m=2**$_GET[1],$m,2).
Titus

@Arnauld Evet Çıktı olarak vermelidir sadece en yüksek binarray de bu çözüm geçerli kılmak
Jörg Hülsermann

2
@ fəˈnɛtɪk Matematiğinizle aynı fikirdeyim, fakat asıl zorluk eşdeğer bir düzenleme değil, tam olarak A ile toplanabilecek bir model bulmakla ilgili. İşte alacağız [ 1,0,1,1,1,0,2,2,2,2,2,1 ].
Arnauld,

1
-1 bayt ile for($g=$_GET[0];$g;).
Titus

3

Python, 166 bayt

def f(a,n):
 for i in range(1<<n-1,1<<n):
  b=bin(i)[2:];u,v=(int(('0{:0>%d}'%sum(a)*len(s)).format(*s))for s in[a,b])
  if u%v<1>int(str(u//v*10)[::~sum(a)]):yield b

Çevrimiçi deneyin!

Nasıl çalışır

Baz hane olarak A ve B düşünün k numaralar u ve v . Örneğin ( örnekleme için k = 1000 kullanacağız ):

A = [1, 2, 1, 3, 2, 1, 2]
B = [1, 0, 0, 1]
u = 1 002 001 003 002 001 002
v = 1 000 000 001

Diğer cevap verenlerin çoğunun farkına vardığı gibi, eğer B geçerli bir cevapsa, u tarafından bölünebilir v . Bu durumda,

u = 1 002 001 002 ⋅ v

[1, 2, 1, 2] dizisine geri çevrilen bu bölüm bize, her bir pozisyon için kaç tane B kopyasına ihtiyacımız olduğunu söylüyor.

  [1, 0, 0, 1]
+    [1, 0, 0, 1]
+    [1, 0, 0, 1]
+       [1, 0, 0, 1]
+          [1, 0, 0, 1]
+          [1, 0, 0, 1]
-----------------------
  [1, 2, 1, 3, 2, 1, 2]

(Neden? Çünkü bu tam olarak çarpma işleminin ne kadar sürdüğüdür. k .)

Diğer cevaplayıcıların farketmediği şey şudur: ise yukarıdaki koşulun yeterli olmamasıdır . Örneğin:

A = [1, 2, 1, 3, 2, 1, 2]
B = [1, 1, 1, 1]
u = 1 002 001 003 002 001 002
v = 1 001 001 001
u = 1 000 999 002 ⋅ v

Matematiksel olarak konuşursak, bu bölümü hala B'nin negatif kopyalarını kullanmamıza izin verilirse iyi sonuç veren [1, 1, −1, 2] dizisine çevirebiliriz:

  [1, 1, 1, 1]
+    [1, 1, 1, 1]
       [1, 1, 1, 1]
+          [1, 1, 1, 1]
+          [1, 1, 1, 1]
-----------------------
  [1, 2, 1, 3, 2, 1, 2]

Ancak, elbette bu sorun negatif kopyalara izin vermez. Bu yüzden ek bir çeke ihtiyacımız var.

Bu amaçla, k > 10 e olan bir üs seçeriz, burada k > 10 ⋅ toplam (A), ve kaideyi on ile çarptığımızda baz k rakamlarının hiçbirinin bir sonraki baz k rakamına taşmadığını kontrol ederiz. Her bir O e bölüm kez on baz on gösteriminde ucundan başlayarak inci baz on haneli,, bölüm negatif olmayan elemanları ile bir dizi geri çevirir 0 Bu garanti olmalıdır.


1
Taban dönüşümünü kolaylaştırmak için 10 üs olarak büyük bir güç kullanma şeklinizi seviyorum.
Neil

2

PHP, 213 Bayt

Aynı şekilde biraz golf oynadı

<?for($b=2**~-$l=$_GET[1];$b<2**$l;array_filter($t[$b++])?:$d[]=$o)for($g=count($t[$b]=$_GET[$i=0]);min($t[$b])>-1&$i<=$g-$l;$i++)for($e=$t[$b][$i],$k=0,$o=decbin($b);$k<$l;)$t[$b][$k+$i]-=$o[$k++]*$e;print_r($d);

Çevrimiçi deneyin!

PHP, 344 Bayt ilk çalışma

İlk cevabımdan sonra geçerli tüm çözümleri geri veren daha uzun bir denemeye karar verdim.

<?foreach(range(2**($l=$_GET[1])-1,2**($l-1))as$b){$t[$b]=($g=$_GET[0]);for($i=0;$t[$b]&&$i<=count($g)-$l;$i++){$e=reset($y=array_slice($t[$b],$i,$l));foreach(str_split(decbin($b))as$k=>$v)$t[$b][$k+$i]=$y[$k]-$e*$v;if(min($t[$b])<0)unset($t[$b]);}}foreach($t as$k=>$v)if(max($v)>0)unset($t[$k]);echo join(",",array_map(decbin,array_keys($t)));

Çevrimiçi sürüm

Yıkmak

foreach(
    range(2**($l=$_GET[1])-1
    ,2**($l-1)
    ) # make decimal range of a binarray with given length
    as$b){
$t[$b]=($g=$_GET[0]); # make a copy for each possible solution pattern
    for($i=0;$t[$b]&&$i<=count($g)-$l;$i++){ # Loop till solution is valid or reach last digit
        $e=reset($y=array_slice($t[$b],$i,$l)); # take first value of a sequence with the length
        foreach(str_split(decbin($b))as$k=>$v)
            $t[$b][$k+$i]=$y[$k]-$e*$v; # replace values in copy
        if(min($t[$b])<0)unset($t[$b]); # kill solution if a minimum <0 exists
    }
}
foreach($t as$k=>$v)if(max($v)>0)unset($t[$k]); # drop all solutions where the sum is not zero 


echo join(",",array_map(decbin,array_keys($t))); #Output all solutions

Bu, N ≥ 2 için çalışıyor gibi görünmektedir, ancak mücadeledeki ilk test durumu gibi N = 1 vakalarında başarısız olmaktadır.
Anders Kaseorg,

@AndersKaseorg Şimdi N = 1 Kılıflarını destekliyor =Kısa versiyon için sadece ilk döngüye
girmesi

1

Python, 205 bayt

def f(a,l):
 b=lambda s:b(s[:-1])*sum(a)*8+int(s[-1])if s else 0
 c=lambda n:n and(n/sum(a)/4%2 or c(n/sum(a)/8))
 for i in range(2**~-l,2**l):
  j=bin(i)[2:]
  if b(a)%b(j)<1 and not c(b(a)/b(j)):return j

Ayırıcı olmadan bir ikili dize döndürür. @AndersKaseorg'ın işaret ettiği gibi, @ fəˈnɛtɪk'ın çözümünün işe yaramadığı girdiler var, çünkü bölüm izin verilmeyen negatif bir katsayısı temsil ediyor. Bu soruna geçici bir çözüm bulmak için çok büyük bir taban kullanıyorum ve bölümde borçlanma olmadığını test ediyorum.


Tamam, bunun gerçek bir karşı örnek olduğunu düşünüyorum: f([1, 1, 1, 0, 0, 0, 1, 1, 1], 3)yanlış döner 101.
Anders Kaseorg

@AndersKaseorg Hmm, döngünün sırasını tersine çevirir mi, yoksa algoritma hala temelde bozuldu mu?
Neil,

Bence temel olarak ek kontroller olmadan bozuldu. Ters değişken başarısız olur f([1, 0, 2, 0, 2, 0, 1], 3)ve hem ileri hem de ters değişkenler etkin değil f([1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0], 5).
Anders Kaseorg

Ve ibunun garip olduğunu kontrol etseniz bile , hem ileri hem de geri değişkenler başarısız olur f([1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0]*10, 5).
Anders Kaseorg

1
@AndersKaseorg Ah evet, gcd (k, n) = 1 olduğunda, (x^kn-1)/(x^k-1)her zaman (x^n-1)/(x-1)@ f @nɛtɪk çözümünü herhangi bir temelde kandıran bir faktör vardır .
Neil

1

Pyth, 32 bayt

f!|%FKiRJysQ,QT>#sQj/FKJ+L1^U2tE

Çevrimiçi deneyin

Nasıl çalışır

                           ^U2tE   Cartesian power [0, 1]^(N - 1)
                        +L1        prepend 1 to every list
f                                  filter for lists T such that:
          sQ                         sum(A)
         y                           double
        J                            assign to J
      iR    ,QT                      convert [A, T] from base J
     K                               assign to K
   %F                                fold modulo
  |                                  logical OR with
                    /FK                fold integer division over K
                   j   J               convert to base J
               >#sQ                    filter for digits greater than sum(A)
 !                                   logical NOT

Strateji Python cevabına benzer , ancak Pyth temel dönüşüm için yerleşik yapılara sahip olduğundan, daha verimli bir taban k = 2 ⋅ toplam (A) kullanabiliriz ve doğrudan bölümün her basamağının en fazla toplamda olduğunu kontrol edebiliriz (A). ).


1

Pari / GP , 77 74 96 80 bayt

n->a->[v|d<-divisors(b=Pol(a)),(v=Vec(d))%2==v&&vecmin(Vec(b/d))>=0&&d%x&&#d==n]

Tüm çözümleri döndürür.

İlk olarak diziyi abir polinom'a dönüştürür b. Sonra bölenler gelen seçtiği bpolinomları dkatsayıları şekildedir dtüm 1ve 0ve katsayıları b / dher negatif olmayan, ve d(0) = 1, ve deg(d) = n + 1. Sonunda, onları dizilere geri dönüştürür.

Çevrimiçi deneyin!

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.