Tìm binarray!


24

Chúng tôi định nghĩa một binarray là một mảng thỏa mãn các thuộc tính sau:

  • nó không trống
  • giá trị đầu tiên là một 1
  • giá trị cuối cùng là một 1
  • tất cả các giá trị khác là 0hoặc1

Ví dụ, mảng [ 1, 1, 0, 1 ]là một binarray hợp lệ .

Nhiệm vụ

Cho một mảng không trống A gồm các số nguyên không âm và số nguyên dương N , công việc của bạn là tìm một binarray B có độ dài N cho phép tạo A bằng cách tính tổng số lượng bản sao B không giới hạn, được dịch chuyển bởi số lượng không giới hạn vị trí.

Thí dụ

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

Đối với đầu vào này, binarray B = [ 1, 1, 0, 1 ] sẽ là một câu trả lời hợp lệ vì chúng ta có thể làm:

  [ 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 ]

Quy tắc

  • Đầu vào có thể được thực hiện trong bất kỳ định dạng hợp lý.
  • Đầu ra có thể là một mảng riêng (ví dụ [1, 1, 0, 1]) hoặc một chuỗi nhị phân có hoặc không có dấu phân cách (ví dụ "1,1,0,1"hoặc "1101")
  • Bạn chỉ được yêu cầu in hoặc trả lại một binarray hợp lệ . Ngoài ra, bạn có thể chọn in hoặc trả lại tất cả chúng khi có một số giải pháp.
  • Bạn không cần phải hỗ trợ các đầu vào không dẫn đến bất kỳ giải pháp nào.
  • Tổng thể bao gồm số không tiềm ẩn mà không trùng với bất kỳ bản sao của B . Số 0 thứ hai trong tổng số trên là số 0 ẩn như vậy.
  • Bạn có thể cho rằng kích thước tối đa của A là 100 và kích thước tối đa của B là 30.
  • Đây là môn đánh gôn, vì vậy câu trả lời ngắn nhất bằng byte sẽ thắng. Sơ hở tiêu chuẩn bị cấm.

Các trường hợp thử nghiệm

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 ]

Giá trị lớn nhất của Nđiều đó nên được hỗ trợ một cách hợp lý là gì?
Neil

@Neil Tôi đã thêm giới hạn kích thước cho cả A và B.
Arnauld

1
@ fəˈnɛtɪk Có thể, nhưng đối với N=4, A = [ 1, 1, 2, 4, 1, 2, 2, 2, 1, 2, 2, 1, 2, 0, 1 ], bạn nhận được 30459 chia hết cho cả 11 và 13 nhưng chỉ có một [ 1, 1, 0, 1 ][ 1, 0, 1, 1 ]là một câu trả lời hợp lệ.
Neil

1
@ fəˈnɛtɪk Những số này không được viết trong cơ sở 2 nên quy tắc số học không được áp dụng. Chẳng hạn, bạn rõ ràng không thể mang theo khi thêm.
BallpointBen

2
Vui lòng thêm các trường hợp kiểm tra này, dường như phá vỡ gần như tất cả các câu trả lời được đăng: N = 3, A = [1, 0, 2, 0, 2, 0, 1], output = [1, 0, 1]; N = 3, A = [1, 1, 1, 0, 0, 0, 1, 1, 1], đầu ra = [1, 1, 1].
Anders Kaseorg

Câu trả lời:


8

PHP, 105 92 90 86 byte

Giải pháp Jörg bàos cố định và đánh gôn:

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

lấy Ntừ đối số dòng lệnh đầu tiên, các giá trị sau đó; chạy với -rhoặc kiểm tra nó trực tuyến .
in số nhị phân (định dạng 10001); in giải pháp không hợp lệ hoặc chạy chết nếu không có giải pháp hợp lệ.

phiên bản đầu tiên (hiện là 97 byte) không in gì cho đầu vào không hợp lệ: kiểm tra trực tuyến

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

phá vỡ

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

Nice bạn có thể không đạt được số byte dưới 100?
Jörg Hülsermann 30/03/2017

1
@ JörgHülsermann Tôi có thể.
Tít

Suy nghĩ nặng nề. Tôi biết trước điều này rằng bạn tốt hơn. Tôi hy vọng bạn có thể giữ số byte thấp nhất
Jörg Hülsermann

1
Trên N = 3, A = [1, 0, 2, 0, 2, 0, 1], điều này trả về không chính xác111 trong đó kết quả đúng duy nhất là [1, 0, 1].
Anders Kaseorg

8

PHP , 219 byte

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

Hãy thử trực tuyến!

-4 byte sử dụng [$g,$z]=$_GETPHP 7.1 thay vìlist($g,$z)=$_GET


Có vẻ như nó xuất ra cả [1,0,1,0,1,0,1,0,1]câu trả lời hợp lệ ( ) và câu trả lời không hợp lệ ( [1,0,0,0,1,0,1,1,1]) cho trường hợp kiểm tra cuối cùng.
Arnauld

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

@Arnauld Có, tôi chỉ nên cung cấp với giá trị binarray cao nhất để giải pháp này hợp lệ
Jörg Hülsermann

2
@ fəˈnɛtɪk Tôi đồng ý với toán học của bạn, nhưng thách thức là tìm ra một mô hình có thể được tóm tắt chính xác đến A, không phải là một sự sắp xếp tương đương. Ở đây, chúng tôi sẽ nhận được [ 1,0,1,1,1,0,2,2,2,2,2,1 ].
Arnauld

1
-1 byte với for($g=$_GET[0];$g;).
Tít

3

Python, 166 byte

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

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

Coi A và B là các chữ số của các số cơ sở k số uv . Ví dụ: chúng tôi sẽ sử dụng k = 1000 để minh họa):

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

Như nhiều người trả lời khác nhận thấy, nếu B là câu trả lời hợp lệ, thì u chia hết cho v . Trong trường hợp này,

u = 1 002 001 002 v

Thương số này, được dịch trở lại mảng [1, 2, 1, 2], cho chúng ta biết chính xác có bao nhiêu bản sao B chúng ta cần chuyển sang từng vị trí.

  [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]

(Tại sao? Bởi vì đó chính xác là thời gian nhân hoạt động trong cơ sở k .)

Điều mà những người trả lời khác không nhận thấy là điều kiện trên là không đủ . Ví dụ:

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

Về mặt toán học, chúng ta vẫn có thể dịch thương số đó trở lại mảng [1, 1, 1, 2], hoạt động tốt nếu chúng ta được phép sử dụng các bản sao âm của B:

  [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]

nhưng tất nhiên thách thức không cho phép các bản sao tiêu cực. Vì vậy, chúng tôi cần kiểm tra bổ sung.

Để đạt được điều đó, chúng tôi chọn một cơ sở k = 10 e trong đó k > 10 ⋅ tổng (A) và kiểm tra xem không có chữ số k cơ sở nào tràn vào chữ số k cơ sở tiếp theo khi chúng tôi nhân thương số với mười. Đó là, mỗi e thứ cơ sở mười chữ số, bắt đầu từ lúc kết thúc, trong các đại diện mười cơ sở của thời đại thương mười, phải bằng 0. Điều này đảm bảo rằng các thương chuyển trở lại một mảng với các yếu tố âm.


1
Tôi thích thủ thuật của bạn là sử dụng công suất lớn 10 làm cơ sở để chuyển đổi cơ sở dễ dàng hơn.
Neil

2

PHP, 213 byte

Cùng một cách chơi golf

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

Hãy thử trực tuyến!

PHP, 344 byte đầu tiên làm việc

Sau câu trả lời đầu tiên của tôi, tôi đã quyết định thực hiện một thử nghiệm dài hơn mà trả lại tất cả các giải pháp hợp lệ.

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

Phiên bản trực tuyến

Phá vỡ

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

Điều này dường như hoạt động với N 2, nhưng thất bại trong các trường hợp N = 1, chẳng hạn như trường hợp thử nghiệm đầu tiên trong thử thách.
Anders Kaseorg

@AndersKaseorg Bây giờ, nó hỗ trợ N = 1 Case chỉ cần đặt một =vòng lặp đầu tiên cho phiên bản ngắn hơn Trong phiên bản lớn hơn, nó cần xóa bốn Byte
Jörg Hülsermann

1

Python, 205 byte

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

Trả về một chuỗi nhị phân không có dấu phân cách. Như @AndersKaseorg chỉ ra, có những đầu vào mà giải pháp của @ fəˈnɛtɪk không hoạt động vì phép chia đại diện cho một hệ số âm không được phép. Để giải quyết vấn đề này, tôi sử dụng một cơ sở rất lớn và kiểm tra rằng không có khoản vay nào trong bộ phận.


Được rồi, tôi nghĩ rằng đây là một ví dụ thực tế: f([1, 1, 1, 0, 0, 0, 1, 1, 1], 3)trả về không chính xác 101.
Anders Kaseorg

@AndersKaseorg Hmm, việc đảo ngược thứ tự trợ giúp của vòng lặp, hay thuật toán vẫn bị phá vỡ cơ bản?
Neil

Tôi nghĩ rằng về cơ bản nó đã bị hỏng mà không cần kiểm tra thêm. Biến thể ngược không thành công f([1, 0, 2, 0, 2, 0, 1], 3)và cả biến thể tiến và lùi đều thất bại f([1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0], 5).
Anders Kaseorg

Và ngay cả khi bạn kiểm tra đó ilà số lẻ, cả hai biến thể tiến và lùi đều thất bại f([1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0]*10, 5).
Anders Kaseorg

1
@AndersKaseorg À đúng rồi, khi gcd (k, n) = 1, (x^kn-1)/(x^k-1)luôn có (x^n-1)/(x-1)một yếu tố, đó là giải pháp của fools @ fəˈnɛtɪk trong bất kỳ cơ sở nào.
Neil

1

Bình thường, 32 byte

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

Dùng thử trực tuyến

Làm thế nào nó hoạt động

                           ^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

Chiến lược này tương tự như câu trả lời Python của tôi , ngoại trừ vì Pyth đã tích hợp sẵn để chuyển đổi cơ sở, chúng tôi có thể sử dụng cơ sở hiệu quả hơn k = 2 ⋅ sum (A) và kiểm tra trực tiếp rằng mọi chữ số của thương số có nhiều nhất không (A ).


1

Pari / GP , 77 74 96 80 byte

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

Trả về tất cả các giải pháp.

Đầu tiên chuyển đổi mảng athành đa thức b. Sau đó chọn từ các ước bcủa các đa thức dsao cho các hệ số của dtất cả 10, và các hệ số củab / d tất cả đều không âm, và d(0) = 1, và deg(d) = n + 1. Cuối cùng, chuyển đổi chúng trở lại mảng.

Hãy thử trực tuyến!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.