ซ่อมแซมช่วง


30

กำหนดอินพุตของรายการจำนวนเต็มบวกที่แทนที่ด้วยบาง0เอาท์พุทรายการที่มีตัวเลขหายไปซึ่งเปลี่ยนเป็น0แทนที่

ลักษณะของรายการอินพุต:

  • รายการจะมีความยาวอย่างน้อย 2 เสมอ

  • ขอให้เรากำหนดรายการการป้อนข้อมูลเป็นaและรายการ "ต้นฉบับ" (นั่นคือรายการก่อนที่ตัวเลขที่ถูกแทนที่ด้วย0s) bเป็น สำหรับการใด ๆn, a[n]เป็นทั้งหรือb[n]0

  • สำหรับการใด ๆn, b[n]เป็นทั้งหรือb[n-1] + 1 b[n-1] - 1นั่นคือตัวเลขในbจะมีการเปลี่ยนแปลงโดย1ในแต่ละดัชนีจากก่อนหน้านี้ แน่นอนว่าองค์ประกอบแรกนั้นได้รับการยกเว้นจากกฎนี้

  • สำหรับทุกการทำงานของเลขศูนย์ในa(นั่นคือองค์ประกอบต่อเนื่องถูกแทนที่ด้วย 0) โดยxแสดงดัชนีของการเริ่มต้นของการรันและการy เป็นตัวแทนของจุดสิ้นสุดa[x-1]เพื่อที่a[y+1]จะเพิ่มหรือลดลง ดังนั้นจะมีเพียงวิธีเดียวที่เป็นไปได้ในการเติมในศูนย์

    • นี่ก็หมายความว่าทั้งองค์ประกอบแรกและสุดท้ายของอาร์เรย์ไม่สามารถเป็นศูนย์ได้

ในแง่ที่ง่ายกว่าในการเติมจำนวนศูนย์ให้แทนที่ด้วยช่วงจากจำนวนก่อนไปยังหมายเลขที่ตามมา ตัวอย่างเช่นอินพุตของ

1 2 0 0 0 6 7

จะต้องส่งออก

1 2 3 4 5 6 7

เนื่องจากนี่คือรหัสที่สั้นที่สุดเป็นไบต์จะเป็นผู้ชนะ

กรณีทดสอบ:

In                      Out
-----------------------------------------------------
1 0 0 0 5 6 0 4 0 0 1 | 1 2 3 4 5 6 5 4 3 2 1
7 6 0 0 3 0 0 0 7 0 5 | 7 6 5 4 3 4 5 6 7 6 5
1 0 3 0 5 0 3 0 5 0 7 | 1 2 3 4 5 4 3 4 5 6 7
14 0 0 0 0 0 0 0 0 23 | 14 15 16 17 18 19 20 21 22 23

แทนที่จะ0โปรแกรมของเราสามารถใช้ค่าอื่นเช่นnull?
Downgoat

@Downgoat 0ไม่มีตัวเลขที่หายไปจะต้องได้รับเป็น
Doorknob

คำตอบ:


15

JavaScript (ES6), 72 66 64 54 53 ไบต์

บันทึก 12 ไบต์ด้วย @Neil!

บันทึกแล้ว 1 ไบต์ขอบคุณ @IsmaelMiguel

a=>a.map((l,i)=>l?b=l:b+=a.find((q,r)=>r>i&&q)>b||-1)

ค่อนข้างดีสำหรับ JavaScript


ลองออนไลน์ (เบราว์เซอร์ทั้งหมดใช้งานได้)

คำอธิบาย

a=>  // Function with arg `a`
  a.map((l,i)=>  // Loop through input
    l?             // If nonzero
      b=l          // Set `b` to current number
    :a.find((q,r)=>r>i&q) // Otherwise look for the next nonzero number
     >b?           // If it's increased since nonzero last number   
       ++b:--b)    // Increasing? increase `b` (the previous nonzero number)
                   // otherwise decrease `b`

1
ฉันคิดว่าa.find((q,r)=>r>i&&q)>b?++b:--bเป็นเช่นเดียวกับb+=a.find((q,r)=>r>i&&q)>b||-1
Ismael Miguel

@ IsmaelMiguel มันฉลาดต้องขอบคุณ!
Downgoat

ไม่เป็นไร ฉันดีใจที่มันได้ผลสำหรับคุณ
Ismael Miguel

ฉันคิดว่าคุณสามารถแทนที่ && ด้วย & & เพียง (สังเกตว่าคุณมีหนึ่ง & ในคำอธิบายและสองในคำตอบ)
Charlie Wynn

7

MATL , 11 12ไบต์

fGXzGn:3$Yn

ทำงานร่วมกับรีลีสปัจจุบัน (13.0.0)ของภาษา / คอมไพเลอร์

ลองออนไลน์!

f        % implicitly input array. Indices of nonzero elements (*)
GXz      % push input and get its nonzero elements (**)
Gn:      % vector [1,2,...,n], where n is input length (***)
3$Yn     % interpolate at positions (***) from data (**) defined at positions (*)

7

Haskell, 68 61 58 ไบต์

g(a:b:r)=[a..b-1]++[a,a-1..b+1]++g(b:r)
g x=x
g.filter(>0)

ตัวอย่างการใช้งาน: ->g.filter(>0) $ [7,6,0,0,3,0,0,0,7,0,5][7,6,5,4,3,4,5,6,7,6,5]

วิธีการทำงาน: gศูนย์ลบจากการป้อนข้อมูลโทรแล้ว อนุญาตaเป็นองค์ประกอบแรกและตัวbที่สองของรายการที่เหลือ เชื่อมต่อรายการจากaขึ้นไปb-1และจากaลงสู่b+1(หนึ่งในนั้นจะว่างเปล่า) และการโทรซ้ำด้วยการaลดลง

แก้ไข: @Zgarb บันทึก 3 ไบต์ ขอบคุณ!


6

Mathematica, 59 ไบต์

#//.{a___,x_,0..,y_,b___}:>{a,##&@@Range[x,y,Sign[y-x]],b}&

กรณีทดสอบ

%[{1,0,3,0,5,0,3,0,5,0,7}]
(* {1,2,3,4,5,4,3,4,5,6,7} *)

4

Perl, 47 45 44 39 37 ไบต์

รวม +1 สำหรับ -p

s%\S+%$p+=/\G(0 )+/?$'<=>$p:$&-$p%eg

คาดหวังรายการ stdin ตัวอย่าง: echo 1 0 3 0 1 | perl -p file.pl


ฉันเห็นสำเนาวางที่นี่ .. ;-) btw ทำได้ดีมาก
Kenney

3

เยลลี่12 11 ไบต์

ḢWW;ḟ0Ṫr¥\F

ลองออนไลน์!

รุ่นทางเลือก 8 ไบต์ (ไม่ใช่การแข่งขัน)

น่าเสียดายที่ Jelly's popไม่ได้ทิ้งตำแหน่งไว้ในเวอร์ชั่นล่าสุดที่ท้าทายความสามารถนี้ สิ่งนี้ได้รับการแก้ไขแล้วและงานต่อไปนี้ในเวอร์ชันปัจจุบัน

ḟ0Ṫr¥\FḊ

ลองออนไลน์!

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

ḢWW;ḟ0Ṫr¥\F  Main link. Input: A (list)

Ḣ            Pop the first element of A. Let's call it a.
 WW          Yield [[a]].
   ;         Concatenate with the popped A.
             This wraps the first element of A in an array.
    ḟ0       Filter; remove all zeroes.
        ¥    Create a dyadic chain:
      Ṫ        Pop the last element of the left argument.
       r       Call range on the popped element and the right argument.
         \   Reduce the modified A by this chain.
          F  Flatten the resulting list of ranges.

ในเวอร์ชั่นอื่นḢWW;จะไม่จำเป็น อย่างไรก็ตามเนื่องจากองค์ประกอบแรกถูกส่งไปยัง iterable ก่อนที่จะ popping จึงไม่ได้ทำการแก้ไขจริง ขั้นสุดท้ายจะลบสิ่งที่ซ้ำกันขององค์ประกอบแรก


3

Retina, 39 34 31 ไบต์

บันทึก 3 ไบต์ด้วย @Martin

+`1(1*) (?= +((1)\1)?)
$0$1$3$3

รับอินพุตและให้เอาต์พุตใน unary

รหัสซ้ำเติมทุกสถานที่ว่างเปล่า (0) previous_number - 1 + 2 * if_next_nonzero_number_biggerด้วย previous_number - 1เป็น$1และเป็นif_next_nonzero_number_bigger$3

ด้วย I / O ทศนิยมรหัสคือ 51 ไบต์ที่คุณสามารถเห็นในล่ามออนไลน์กับกรณีทดสอบทั้งหมด


คุณสามารถบันทึกไบต์อื่นได้โดยไม่ต้องใส่ตัวแรก1ใน lookahead
Martin Ender

@ MartinBüttnerถูกต้องแก้ไข
randomra

2

GNU Sed (พร้อมexecส่วนขยายโดยใช้ bash), 61

คะแนนรวม +1 สำหรับ-rตัวเลือกในการระงับ

:
s/( 0)+ /../
s/\w+..\w+/{&}/
s/.*/bash -c 'echo &'/e
/ 0/b
  • ค้นหา run of 0s และแทนที่..
  • ใส่เครื่องหมายวงเล็บรอบ ๆ หมายเลขปลายทางเพื่อสร้างการขยาย bash brace เช่นเดียว{1..4}กับจุดปลายในเครื่อง ความสวยงามของการขยายปีกกาที่นี่คือลำดับที่สร้างขึ้นจะวิ่งไปในทิศทางที่ถูกต้องเสมอไม่ว่าจุดเริ่มต้นหรือจุดสิ้นสุดนั้นใหญ่กว่าก็ตาม
  • ใช้eตัวเลือกไปยังsคำสั่งเพื่อโทรออกเพื่อทุบตีเพื่อประเมินการขยายรั้ง
  • หากพบสิ่งใดเพิ่มเติม0ให้ข้ามกลับไปที่จุดเริ่มต้น

Ideone


2

Python 2, 195 111 bytes (ขอบคุณอเล็กซ์ !)

t=input()
z=0
for i,e in enumerate(t):
 if e:
  while z:t[i-z]=e+z if l>e else e-z;z-=1
  l=e
 else:z+=1
print t

อินพุต: ต้องเป็น[list]ของ ints
เอาต์พุต: [list]ของ ints


ขอโทษสำหรับเรื่องนั้น! คงที่ ขอบคุณสำหรับหัวขึ้น.
vageli

ไม่ต้องห่วง. ทางออกที่ดี :) คุณสามารถลดขนาดได้ถึง 112 ไบต์โดยใช้วิธีนี้ซึ่งเป็นวิธีการเดียวกับคุณ นอกจากนี้เรายังมีการเก็บรวบรวมเคล็ดลับสำหรับการเล่นกอล์ฟในหลามที่นี่
Alex A.

1

Perl, 85 82 ไบต์

รวม +1 สำหรับ -p

s/(\d+)(( 0)+) (\d+)/$s=$1;$e=$4;$_=$2;$c=$s;s!0!$c+=$e<=>$s!eg;"$s$_ $e"/e&&redo

คาดหวังรายการ stdin ตัวอย่าง: echo 1 0 3 0 1 | perl -p file.pl.

สิ่งนี้ใช้ regexp ซ้อนกัน ค่อนข้างอ่านได้:

s/(\d+)(( 0)+) (\d+)                  # match number, sequence of 0, number
 /
    $s=$1;                            # start number
    $e=$4;                            # end number
    $_=$2;                            # sequence of ' 0'
    $c=$s;                            # initialize counter with start number
    s!0! $c += $s <=> $e !eg          # replace all 0 with (in|de)cremented counter
    "$s$_ $e"                         # return replacement
 /e
&& redo                               # repeat until no more changes.

1

Python 2, 92 88 ไบต์

(ลบตัวแปรกลาง)

t=filter(bool,input())
print sum([range(o,p,cmp(p,o))for o,p in zip(t,t[1:])],[])+t[-1:]

1

Pyth, 17 ไบต์

u+G+treGHHfTtQ[hQ

วิธีการทำงาน:

u                 reduce
              [hQ     seed: the first element of input, in a list
                      iterable:
          tQ              all except the first element of input
        fT                remove if 0
                      lambda: G is the list to be returned, H is the current item
 +G                       append to return list
    reGH                  a range from the last element of the return list and the current item
   +                      concatenated with
        H                 the last item (this step forms a bidirectional inclusive list)

กล่าวอีกนัยหนึ่ง: ศูนย์ทั้งหมดจะถูกลบออกจากอินพุตจากนั้นช่วงพิเศษจะถูกแทรกระหว่างทุกองค์ประกอบ ช่วงนี้มีความยาวเป็นศูนย์ในองค์ประกอบแยกกันเพียงหนึ่ง


1

05AB1E , 3 ไบต์ (ไม่แข่งขัน)

นี่เป็นคุณสมบัติที่เพิ่มเข้ามาหลังจากการท้าทาย รหัส:

0KŸ

คำอธิบาย:

0K   # Remove all zeroes from the input list
  Ÿ  # Rangify, [1, 4, 1] would result into [1, 2, 3, 4, 3, 2, 1]

ลองออนไลน์! หรือตรวจสอบกรณีทดสอบทั้งหมด!


1

เป็นกลุ่ม: 231 คำสั่งหลัก

โปรดทราบว่า ^ นำหน้าอักขระใด ๆ หมายความว่าคุณควรควบคุมในขณะที่พิมพ์อักขระนั้น

mbomayiwo^V^R"^V^V^V^X ^V^["sy0dd`a@f ^["bc0yiwo^V^V^V^X^V^R"^V^[0l@sa^V^V^V^A-^V^[0f-"ayhdd`a@i ^["dc0mbyiwo^V^R"Exe@b^V^[0fel"ty2ldd`b@t ^["ec0wmbyiwo@f @d^V^[@z ^["fc0"xyiwwmbyiwocw^V^V^V^Rx^V^V^V^[@a@i @e^V^[@z ^["ic0IB0 B^V^R" ^V^OWB0 ^V^OA B0^V^[0*w"tyiWdd`b@t ^["zd0dd`bAe^[0@e 

ขั้นตอนเพื่อให้คุณสามารถเรียกใช้สิ่งนี้ได้เช่นกัน!

  1. คัดลอกบรรทัดลงในกลุ่ม
  2. พิมพ์:s/\^V/<Ctrl-V><Ctrl-V>/gและกด Enter (ทั้งสองควรให้สีฟ้า ^ V)
  3. พิมพ์:s/\^R/<Ctrl-V><Ctrl-R>/gและกด Enter (คุณควรเห็นสีน้ำเงิน ^ Rs ตอนนี้)
  4. พิมพ์:s/\^X/<Ctrl-V><Ctrl-X>/gและกด Enter (คุณควรเห็นสีน้ำเงิน ^ Xs ทันที)
  5. พิมพ์:s/\^O/<Ctrl-V><Ctrl-O>/gและกด Enter
  6. พิมพ์:s/\^A/<Ctrl-V><Ctrl-A>/gและกด Enter
  7. พิมพ์:s/\^\[/<Ctrl-V><Ctrl-[>/gและกด Enter (คำสั่งนี้จะแตกต่างกันเล็กน้อยเพราะฉันต้องการที่จะหลบหนี [)
  8. ประเภท0"yy$. คำสั่งจะถูกเก็บไว้ใน y register
  9. ตั้งค่าอินพุตบนบรรทัดแล้วรันด้วย @y

หากมีคนรู้วิธีที่ดีกว่าในการแบ่งปันคำสั่งโปรดแจ้งให้เราทราบ ฉันรู้ว่ามันยาว แต่มันดีที่สุดที่ฉันจะนึกได้

Input / Output

สตริงอินพุตควรอยู่ตามลำพังบนบรรทัดใด ๆ ในไฟล์ 1 0 0 4 3 0 0 0 7

เอาต์พุตจะเขียนทับสตริงอินพุต 1 2 3 4 3 4 5 6 7

คำอธิบาย

ขั้นตอนวิธี

  1. เริ่มต้นด้วยตัวเลขที่ไม่ใช่ศูนย์ตรวจสอบให้แน่ใจว่าไม่ใช่ตัวเลขสุดท้าย
  2. ค้นหาหมายเลขที่ไม่ใช่ศูนย์ถัดไป
  3. รับความแตกต่าง หากคำตอบนั้นเป็นค่าลบคุณควรจะลดช่วงซ่อมมิฉะนั้นจะเพิ่มขึ้นเพื่อซ่อมแซมช่วง
  4. กลับไปที่ตัวอักษรตัวแรกและแทนที่แต่ละศูนย์ด้วยการเพิ่ม / ลดจำนวนก่อนหน้า
  5. ทำซ้ำจนกว่าจะถึงตัวละครตัวสุดท้าย

มาโครที่ใช้แล้ว

@e - ตรวจสอบเพื่อสิ้นสุด หมายเลขสุดท้ายจะมี e ต่อท้าย หากหมายเลขใต้เคอร์เซอร์มี e อยู่ท้ายให้ลบ e และหยุดการเรียกใช้งาน มิฉะนั้นให้เริ่มรอบการแก้ไขด้วย @b

mbyiwo^R"Exe@b^[0fel"ty2ldd`b@t

@b - เริ่มรอบการแก้ไข บันทึกหมายเลขใต้เคอร์เซอร์เพื่อทำการลบ (@s) จากนั้นค้นหาคำที่ไม่เป็นศูนย์ถัดไป (@f)

mayiwo^R"^V^X ^["sy0dd`a@f

@s - เก็บคำสั่งการลบเพื่อใช้ใน @d มันเป็นเพียง(val)^Xที่(val)เป็นจำนวนที่เริ่มต้นของขั้นตอนการแก้ไขที่ นี้ถูกกำหนดโดยคำสั่ง @b

@f - ค้นหาคำที่ไม่เป็นศูนย์ถัดไป เขียนค่าปัจจุบันไปยังการลงทะเบียนที่ไม่มีชื่อจากนั้นเขียน@f @dบนบรรทัดถัดไปแล้วเรียกใช้ @z คำสั่งนี้จะทำซ้ำคำสั่งนี้หากตัวเลขเป็นศูนย์และดำเนินการ @d หากไม่มี

wmbyiwo@f @d^[@z

@z - เงื่อนไขการดำเนินการในกรณีที่ไม่มีชื่อลงทะเบียนเป็น 0 command1 command2คำสั่งนี้คาดว่าทั้งสองคำสั่งในบรรทัดใหม่ในรูปแบบ หากการลงทะเบียนที่ไม่มีชื่อคือ 0 command1จะถูกดำเนินการมิฉะนั้นcommand2จะถูกดำเนินการ โปรดทราบว่าคำสั่งทั้งสองสามารถมีช่องว่างใด ๆ ในนั้น

 IB0 B^R" ^OWB0 ^OA B0^[0*w"tyiWdd`b@t`

@t - การลงทะเบียนคำสั่งชั่วคราว เก็บคำสั่งต่าง ๆ ในช่วงเวลาสั้น ๆ ก่อนดำเนินการ ใช้เป็นหลักใน if statement

@d - กำหนดทิศทางการแก้ไข ลบหมายเลขแรกในลำดับจากตัวเลขใต้เคอร์เซอร์ (ใช้ @s) หากผลลัพธ์เป็นลบการแก้ไขต้องลดลงดังนั้น ^ X จะถูกบันทึกเป็น @a มิฉะนั้นเราควรเพิ่มขึ้นเพื่อให้ ^ A ถูกบันทึกลงใน @a เมื่อสิ่งนี้ถูกบันทึกแล้วให้ย้ายกลับไปที่จุดเริ่มต้นของวัฏจักรการสอดแทรกนี้และรัน @i เพื่อแทรกสอดจริง

yiwo^V^X^R"^[0l@sa^V^A-^[0f-"ayhdd`a@i

@a - เก็บอย่างใดอย่างหนึ่ง^Aหรือ^Xเพื่อเพิ่มหรือลดในระหว่างขั้นตอนการแก้ไข นี้ถูกกำหนดโดยคำสั่ง @d

@i - แก้ไข คัดลอกหมายเลขที่ตำแหน่งปัจจุบันไปที่ @x และย้ายไปยังหมายเลขถัดไป หากหมายเลขนั้นเป็นศูนย์ให้แทนที่ด้วย @x และเรียกใช้ @a เพื่อแก้ไขขึ้นหรือลงอย่างถูกต้องจากนั้นทำซ้ำคำสั่งนี้ หากตัวเลขไม่ใช่ศูนย์เราได้สิ้นสุดรอบการแก้ไขนี้แล้ว ใหม่ควรเริ่มต้นด้วยหมายเลขนี้เป็นจุดเริ่มต้นดังนั้นรัน @ e เพื่อตรวจสอบการสิ้นสุดและเรียกใช้อีกครั้ง

"xyiwwmbyiwocw^V^Rx^V^[@a@i @e^[@z

@x - ลงทะเบียนที่เก็บข้อมูลชั่วคราว ใช้ในคำสั่ง interpolate (@i)

ทำลายการกดแป้น

mbo :Set b mark to current position and open a new line below to write macros
mayiwo^V^R"^V^V^V^X ^V^["sy0dd`a@f ^["bc0 :Write to @b and reset line

yiwo^V^V^V^X^V^R"^V^[0l@sa^V^V^V^A-^V^[0f-"ayhdd`a@i ^["dc0 :Write to @d and reset line

mbyiwo^V^R"Exe@b^V^[0fel"ty2ldd`b@t ^["ec0 :Write to @e and reset line

wmbyiwo@f @d^V^[@z ^["fc0 :Write to @f and reset line

"xyiwwmbyiwocw^V^V^V^Rx^V^V^V^[@a@i @e^V^[@z ^["ic0 :Write to @i and reset line

IB0 B^V^R" ^V^OWB0 ^V^OA B0^V^[0*w"tyiWdd`b@t ^["zd0 :Write to @z and reset line

dd`b :Delete this line and move cursor back to original line

Ae^[ :Append an e to the last number

0@e  :Move to the beginning of the line and run

0

Python 3.5, 159 ไบต์

โซลูชันแบบเรียกซ้ำ

def f(s):
 h=s[0]
 g=lambda s,h,v:h*(h[-1]==s[0])if len(s)==1else(g(s[1:],h+[h[-1]-v],-v)+g(s[1:],h+[h[-1]+v],+v))*(s[0]==0 or h[-1]==s[0])
 return g(s,[h],1)

Ungolfed

def f(s):
    h=s[0]
    def g(s,h,v):
        if len(s)==1:
            if h[-1]!=s[0]:
                r=[]
            else:
                r=h
        else:
            if s[0]==0:
                r=g(s[1:],h+[h[-1]+v],v)
            elif h[-1]!=s[0]:
                r=[]
            else:
                r=g(s[1:],h+[h[-1]-v],-v)+g(s[1:],h+[h[-1]+v],+v)
        return r
return g(s,[h],1)

ในโซลูชัน golfed ฉันแทนที่เงื่อนไขโดยใช้ข้อเท็จจริงที่h*True=hและh*False=[]

ผล

>>> f([7, 6, 0, 0, 3, 0, 0, 0, 7, 0, 5])
[7, 6, 5, 4, 3, 4, 5, 6, 7, 6, 5]


0

MATLAB, 39 38 37 ไบต์

@(a)interp1(find(a),a(a>0),find(a/0))

aฟังก์ชั่นที่ไม่ระบุชื่อที่สอดแทรกเป็นเส้นตรงระหว่างจุดใน find(a)คืออาร์เรย์ของดัชนีขององค์ประกอบที่ไม่เป็นศูนย์ในaและa(a>0)เป็นค่าบวก ที่บันทึกไว้ 1 ขอบคุณไบต์ข้อเสนอแนะของเพื่อนของมากกว่า>~=

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