ค้นหา binarray!


24

เรากำหนดbinarrayเป็นอาร์เรย์ที่ตอบสนองคุณสมบัติดังต่อไปนี้:

  • มันไม่ว่างเปล่า
  • ค่าแรกคือ 1
  • ค่าสุดท้ายคือ 1
  • ค่าอื่น ๆ ทั้งหมดเป็นอย่างใดอย่างหนึ่ง0หรือ1

ตัวอย่างเช่นอาร์เรย์[ 1, 1, 0, 1 ]เป็นbinarray ที่ถูกต้อง binarray

งาน

ด้วยอาร์เรย์ที่ไม่ว่างAของจำนวนเต็มไม่เป็นลบและเลขจำนวนเต็มบวกNงานของคุณคือค้นหาbinarray B ที่มีความยาวNซึ่งอนุญาตให้สร้างAโดยการรวมจำนวนสำเนาBที่ไม่ จำกัด ซึ่งถูกย้ายโดยจำนวนที่ไม่ จำกัด ตำแหน่ง

ตัวอย่าง

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

สำหรับอินพุตนี้binarray B = [ 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, 0, 1 ]
  -----------------------------------------------
= [ 1, 1, 2, 4, 1, 2, 2, 1, 0, 1, 0, 1, 1, 0, 1 ]

กฎระเบียบ

  • สามารถป้อนข้อมูลในรูปแบบที่เหมาะสม
  • เอาต์พุตอาจเป็นอาร์เรย์ดั้งเดิม (เช่น[1, 1, 0, 1]) หรือสตริงไบนารีที่มีหรือไม่มีตัวคั่น (เช่น"1,1,0,1"หรือ"1101" )
  • คุณจะต้องพิมพ์หรือส่งคืนbinarray ที่ถูกต้องเพียงหนึ่งใบเท่านั้น หรือคุณอาจเลือกพิมพ์หรือส่งคืนทั้งหมดเมื่อมีวิธีแก้ไขปัญหาหลายประการ
  • คุณไม่จำเป็นต้องสนับสนุนอินพุตที่ไม่นำไปสู่โซลูชันใด ๆ
  • ผลรวมอาจรวมถึงศูนย์นัยที่ไม่ทับซ้อนกับสำเนาใด ๆB ศูนย์ที่สองในผลรวมข้างต้นนั้นเป็นศูนย์โดยปริยาย
  • คุณสามารถสันนิษฐานได้ว่าขนาดสูงสุดของAคือ 100 และขนาดสูงสุดของBคือ 30
  • นี่คือรหัสกอล์ฟดังนั้นคำตอบที่สั้นที่สุดในหน่วยไบต์ชนะ ช่องโหว่มาตรฐานเป็นสิ่งต้องห้าม

กรณีทดสอบ

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 ]

มูลค่าสูงสุดNที่ควรได้รับการสนับสนุนอย่างสมเหตุสมผลคืออะไร
Neil

@Neil ฉันได้เพิ่มการ จำกัด ขนาดทั้ง A และ B
Arnauld

1
@ fəˈnɛtɪk บางที แต่สำหรับN=4, A = [ 1, 1, 2, 4, 1, 2, 2, 2, 1, 2, 2, 1, 2, 0, 1 ]คุณจะได้รับ 30459 ซึ่งหารด้วย 11 และ 13 ได้เพียงหนึ่งเดียวเท่านั้น[ 1, 1, 0, 1 ]และ[ 1, 0, 1, 1 ]เป็นคำตอบที่ถูกต้อง
Neil

1
@ fəˈnɛtɪk ตัวเลขเหล่านี้ไม่ได้เขียนในฐาน 2 ดังนั้นกฎของการคำนวณจึงไม่สามารถใช้ได้ ตัวอย่างเช่นคุณไม่สามารถดำเนินการได้อย่างชัดเจนเมื่อเพิ่ม
BallpointBen

2
โปรดเพิ่มกรณีทดสอบเหล่านี้ซึ่งดูเหมือนจะทำลายคำตอบที่โพสต์เกือบทั้งหมด: N = 3, A = [1, 0, 2, 0, 2, 0, 1], เอาท์พุท = [1, 0, 1]; N = 3, A = [1, 1, 1, 0, 0, 0, 1, 1, 1], เอาต์พุต = [1, 1, 1]
Anders Kaseorg

คำตอบ:


8

PHP, 105 92 90 86 ไบต์

โซลูชันของ Jörg´ ได้รับการแก้ไขและgolfed :

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

ใช้เวลาNจากอาร์กิวเมนต์บรรทัดคำสั่งแรกค่าหลังจากนั้น ทำงานด้วย-rหรือทดสอบออนไลน์
พิมพ์เลขฐานสอง (รูปแบบ10001); พิมพ์โซลูชันที่ไม่ถูกต้องหรือทำงานไม่ติดหากไม่มีวิธีการแก้ไขที่ถูกต้อง

รุ่นแรก (ตอนนี้ 97 ไบต์) ที่พิมพ์อะไรก็ได้สำหรับการป้อนข้อมูลที่ไม่ถูกต้อง: ทดสอบออนไลน์

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

ทำให้พังถล่ม

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 คุณไม่สามารถนับจำนวนไบต์ที่ต่ำกว่า 100 ได้หรือไม่
JörgHülsermann

1
@ JörgHülsermannฉันทำได้
ติตัส

คิดหนัก ฉันรู้ก่อนหน้านี้ว่าคุณดีกว่า ฉันหวังว่าคุณจะสามารถนับจำนวนไบต์ที่ต่ำที่สุดได้
JörgHülsermann

1
บน N = 3, A = [1, 0, 2, 0, 2, 0, 1] สิ่งนี้จะส่งกลับอย่างไม่ถูกต้อง111โดยที่ผลลัพธ์ที่ถูกต้องเพียงอย่างเดียวคือ [1, 0, 1]
Anders Kaseorg

8

PHP , 219 ไบต์

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

ลองออนไลน์!

-4 ไบต์โดยใช้[$g,$z]=$_GETPHP 7.1 แทนlist($g,$z)=$_GET


ดูเหมือนว่าจะส่งออกทั้งที่ถูกต้อง ( [1,0,1,0,1,0,1,0,1]) และคำตอบที่ไม่ถูกต้อง ( [1,0,0,0,1,0,1,1,1]) สำหรับกรณีทดสอบล่าสุด
Arnauld

-8 while($_GET[0])$s+=2**$i++*array_pop($_GET[0]);ไบต์: -5 range(1|.5*$m=2**$_GET[1],$m,2)ไบต์:
ติตัส

@Arnauld ใช่ฉันควรให้ผลลัพธ์เป็น binarray ที่สูงที่สุดเท่านั้นเช่นกันทำให้โซลูชันนี้ใช้งานได้
JörgHülsermann

2
@ fəˈnɛtɪk ฉันเห็นด้วยกับคณิตศาสตร์ของคุณ แต่ความท้าทายคือการหารูปแบบที่สามารถสรุปได้อย่างแน่นอนกับ A ไม่ใช่การจัดการที่เท่าเทียมกัน [ 1,0,1,1,1,0,2,2,2,2,2,1 ]ที่นี่เราจะได้รับ
Arnauld

1
-1 for($g=$_GET[0];$g;)ไบต์ด้วย
ติตัส

3

Python ขนาด 166 ไบต์

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

ลองออนไลน์!

มันทำงานอย่างไร

พิจารณา A และ B เป็นตัวเลขของฐานkหมายเลขUและV ตัวอย่าง (เราจะใช้k = 1,000 สำหรับภาพประกอบ):

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

เป็นจำนวนมากของ answerers อื่น ๆ สังเกตเห็นถ้า B เป็นคำตอบที่ถูกต้องแล้วมึงคือหารด้วยวี ในกรณีนี้,

คุณ = 1 002 001 002 ⋅ v

ความฉลาดทางนี้แปลกลับไปยังอาเรย์ [1, 2, 1, 2] บอกเราว่าเราต้องเปลี่ยนสำเนา B จำนวนเท่าไรในแต่ละตำแหน่ง

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

(เพราะเหตุใดเพราะนั่นคือการคูณการทำงานที่ยาวนานในฐานk )

สิ่งที่ answerers อื่น ๆ ล้มเหลวที่จะแจ้งให้ทราบว่าเงื่อนไขดังกล่าวข้างต้นไม่เพียงพอ ตัวอย่างเช่น:

A = [1, 2, 1, 3, 2, 1, 2]
B = [1, 1, 1, 1]
u = 1 002 001 003 002 002 001 002
v = 1 001 001 001
u = 1 000 999 002 ⋅ โวลต์

การพูดทางคณิตศาสตร์เรายังสามารถแปลผลหารกลับไปเป็นอาร์เรย์ [1, 1, −1, 2] ซึ่งใช้งานได้ดีถ้าเราอนุญาตให้ใช้สำเนาเชิงลบของ 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]

แต่แน่นอนว่าความท้าทายไม่อนุญาตให้มีการคัดลอก ดังนั้นเราจึงต้องการการตรวจสอบเพิ่มเติม

ในช่วงท้ายว่าเราเลือกฐานk = 10 Eที่k > 10 ⋅ผลรวม (A) และตรวจสอบไม่มีฐานที่kตัวเลขล้นเข้าไปในฐานต่อไปkบาทเมื่อเราคูณหารโดยสิบ นั่นคือทุกอี TH ฐานสิบบาทเริ่มต้นที่ท้ายที่สุดแล้วในการเป็นตัวแทนฐานสิบสิบครั้งเชาวน์ต้อง 0. การค้ำประกันนี้ว่าเชาวน์แปลกลับไปยังอาร์เรย์ที่มีองค์ประกอบไม่ติดลบ


1
ฉันชอบกลอุบายของคุณในการใช้พลังขนาดใหญ่เป็นฐานในการแปลงฐานให้ง่ายขึ้น
Neil

2

PHP, 213 ไบต์

วิธีเดียวกันเล่นกอล์ฟนิดหน่อย

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

ลองออนไลน์!

PHP, 344 Bytes ใช้งานได้ครั้งแรก

หลังจากคำตอบแรกของฉันฉันได้ตัดสินใจที่จะลองอีกต่อไปที่ให้ผลตอบแทนที่ถูกต้องทั้งหมด

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

เวอร์ชั่นออนไลน์

ทำให้พังถล่ม

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

ดูเหมือนว่าจะใช้ได้กับ N ≥ 2 แต่ล้มเหลวใน N = 1 รายเช่นกรณีทดสอบครั้งแรกในการท้าทาย
Anders Kaseorg

@AndersKaseorg ตอนนี้รองรับ N = 1 เคสที่จำเป็นสำหรับการตั้งค่า=ในลูปแรกสำหรับรุ่นที่สั้นกว่าในรุ่นที่ใหญ่กว่านั้นจำเป็นต้องลบสี่ไบต์
JörgHülsermann

1

Python ขนาด 205 ไบต์

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

ส่งคืนสตริงไบนารีที่ไม่มีตัวคั่น ตามที่ @AndersKaseorg ชี้ให้เห็นมีอินพุตที่โซลูชันของ @ fəˈnɛtɪk ไม่ทำงานเพราะการหารหมายถึงสัมประสิทธิ์เชิงลบซึ่งไม่ได้รับอนุญาต เพื่อหลีกเลี่ยงปัญหานี้ฉันใช้ฐานขนาดใหญ่มากและทดสอบว่าไม่มีการยืมในแผนก


เอาล่ะผมคิดว่านี่เป็น counterexample จริง: ไม่ถูกต้องผลตอบแทนf([1, 1, 1, 0, 0, 0, 1, 1, 1], 3) 101
Anders Kaseorg

@AndersKaseorg อืมกลับคำสั่งของการวนซ้ำช่วยหรืออัลกอริทึมยังคงแตกหัก?
Neil

ฉันคิดว่ามันขาดพื้นฐานโดยไม่มีการตรวจสอบเพิ่มเติม ตัวแปรกลับล้มเหลวบนและทั้งสองสายพันธุ์ไปข้างหน้าและย้อนกลับล้มเหลวในf([1, 0, 2, 0, 2, 0, 1], 3) f([1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0], 5)
Anders Kaseorg

และแม้ว่าคุณจะตรวจสอบว่าเป็นเลขคี่ทั้งสองสายพันธุ์ไปข้างหน้าและย้อนกลับล้มเหลวในi f([1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0]*10, 5)
Anders Kaseorg

1
@AndersKaseorg อ่าใช่เมื่อ gcd (k, n) = 1 (x^kn-1)/(x^k-1)จะมี(x^n-1)/(x-1)ปัจจัยเสมอซึ่ง fools @ fəˈnɛtɪk แก้ปัญหาของฐานใด ๆ
Neil

1

Pyth, 32 ไบต์

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

ลองออนไลน์

มันทำงานอย่างไร

                           ^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

กลยุทธ์คล้ายกับคำตอบของPythonของฉันยกเว้นว่า Pyth มี builtins สำหรับการแปลงฐานเราสามารถใช้ฐานที่มีประสิทธิภาพมากขึ้นk = 2 ⋅ sum (A) และตรวจสอบโดยตรงว่าทุกหลักของผลหารเป็นผลรวมสูงสุด (A )


1

Pari / GP , 77 74 96 80 ไบต์

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

ส่งคืนโซลูชันทั้งหมด

แรกแปลงอาร์เรย์จะพหุนามa bจากนั้นจึงเลือกbพหุนามหารด้วยตัวหารdที่สัมประสิทธิ์ของdทั้งหมด1และ0และสัมประสิทธิ์ของb / dทุกคนไม่ติดลบและและd(0) = 1 deg(d) = n + 1ในที่สุดแปลงให้กลับไปเป็นอาร์เรย์

ลองออนไลน์!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.