เก็บค่าที่ไม่ใช่ศูนย์และเพื่อนบ้าน


26

นำมาจากคำถามนี้ที่ Stack Overflow ขอขอบคุณ @miles และ @Dada สำหรับการแนะนำอินพุตทดสอบที่กล่าวถึงบางกรณี

ความท้าทาย

รับอาร์เรย์ของค่าจำนวนเต็มลบศูนย์ทั้งหมดที่ไม่ได้ขนาบข้างด้วยค่าที่ไม่ใช่ศูนย์

รายการควรถูกเก็บไว้อย่างใดอย่างหนึ่งหากเป็นค่าที่ไม่ใช่ศูนย์หรือหากเป็นศูนย์ที่อยู่ใกล้กับค่าที่ไม่ใช่ศูนย์ทันที

รายการที่เก็บไว้ควรเก็บไว้ในเอาท์พุทตามลำดับที่มีในอินพุต

ตัวอย่าง

ป.ร. ให้ไว้

[2 0 4 -3 0 0 0 3 0 0 2 0 0]

ค่าที่ควรลบจะถูกทำเครื่องหมายด้วยx:

[2 0 4 -3 0 x 0 3 0 0 2 0 x]

และผลลัพธ์ควรเป็น

[2 0 4 -3 0 0 3 0 0 2 0]

กฎระเบียบ

อาเรย์อินพุตอาจว่างเปล่า (และจากนั้นเอาต์พุตควรเป็นค่าว่างด้วย)

รูปแบบอินพุตและเอาต์พุตมีความยืดหยุ่นตามปกติ: อาร์เรย์รายการสตริงหรืออะไรก็ได้ที่สมเหตุสมผล

รหัสกอล์ฟที่ดีที่สุดน้อยที่สุด

กรณีทดสอบ

[2 0 4 -3 0 0 0 3 0 0 2 0 0] -> [2 0 4 -3 0 0 3 0 0 2 0]
[] -> []
[1] -> [1]
[4 3 8 5 -6] -> [4 3 8 5 -6]
[4 3 8 0 5 -6] -> [4 3 8 0 5 -6]
[0] -> []
[0 0] -> []
[0 0 0 0] -> []
[0 0 0 8 0 1 0 0] -> [0 8 0 1 0]
[-5 0 5] -> [-5 0 5]
[50 0] -> [50 0]

ฉันสามารถใช้_2แทนได้-2หรือไม่ บางภาษาใช้รูปแบบดังกล่าว
Leun Nun

เราจะมี-0ไหม
Leun Nun

@LeakyNun 1 ใช่ 2 ไม่ใช่
Luis Mendo

ตัวเลขจะมีเลขศูนย์นำหน้าหรือไม่ ชอบ[010 0 0 01 1]ไหม
FryAmTheEggman

@FryAmTheEggman Nope
Luis Mendo

คำตอบ:


16

JavaScript (ES6), 35 ไบต์

a=>a.filter((e,i)=>e|a[i-1]|a[i+1])

ทำงานบนลอยเช่นกันสำหรับสองไบต์พิเศษ


10

Python ขนาด 50 ไบต์

f=lambda l,*p:l and l[:any(l[:2]+p)]+f(l[1:],l[0])

ฟังก์ชั่นวนซ้ำที่รับ tuple รวมองค์ประกอบแรกถ้ามีค่าที่ไม่ใช่ศูนย์ในทั้งสององค์ประกอบแรกหรือค่าก่อนหน้านี้ที่เก็บไว้จากครั้งที่แล้ว จากนั้นลบองค์ประกอบแรกและทำซ้ำ องค์ประกอบก่อนหน้านี้ถูกเก็บไว้ในรายการเดี่ยวpซึ่งจะแพ็คโดยอัตโนมัติในรายการและเริ่มว่างเปล่า (ขอบคุณเดนนิสสำหรับ 3 ไบต์ด้วยสิ่งนี้)


55 ไบต์:

lambda l:[t[1]for t in zip([0]+l,l,l[1:]+[0])if any(t)]

สร้างชิ้นส่วนความยาว -3 ทั้งหมดของรายการวางศูนย์เป็นจุดเริ่มต้นและจุดสิ้นสุดก่อนแล้วจึงนำองค์ประกอบของตัว middles ที่ไม่เป็นศูนย์ทั้งหมด

วิธีการวนซ้ำเกิดขึ้นอีก (58 ไบต์)

a=0;b,*l=input()
for x in l+[0]:a|b|x and print(b);a,b=b,x

สิ่งนี้ไม่ได้ผลเพราะb,*lต้องการ Python 3 แต่ Python 3 inputให้สตริง การเริ่มต้นยังน่าเกลียด บางทีวิธีแบบเรียกซ้ำคล้ายกันอาจใช้งานได้

น่าเสียดายที่วิธีการจัดทำดัชนีของ

lambda l:[x for i,x in enumerate(l)if any(l[i-1:i+2])]

ไม่ทำงานเพราะl[-1:2]ล่าม-1เป็นจุดสิ้นสุดของรายการไม่ใช่จุดก่อนที่จะเริ่ม


10

Haskell, 55 48 ไบต์

h x=[b|a:b:c:_<-scanr(:)[0]$0:x,any(/=0)[a,b,c]]

ตัวอย่างการใช้งาน: ->h [0,0,0,8,0,1,0,0][0,8,0,1,0]

scanrสร้างรายการอินพุตใหม่xอีกครั้ง0เมื่อเริ่มต้นและสิ้นสุด ในแต่ละขั้นตอนเราจัดรูปแบบจับคู่ 3 องค์ประกอบและเก็บกึ่งกลางหากมีองค์ประกอบที่ไม่เป็นศูนย์อย่างน้อยหนึ่งรายการ

ขอบคุณ @xnor 7 ไบต์โดยเปลี่ยนจากการzip3scanr


มันเป็นการดีที่จะทำh x=[snd t|t<-zip3(0:x)x$tail x++[0],(0,0,0)/=t]แต่ฉันคิดว่าไม่มีทางลัดที่จะได้องค์ประกอบที่สองของ 3-tuple
xnor

ปรากฎสั้นจะได้รับอเนกประสงค์ออกจากscanกว่า:zip3 h x=[b|a:b:c:_<-scanr(:)[0]$0:x,any(/=0)[a,b,c]]
xnor

8

Matlab, 29 27 ไบต์

อินพุตต้องประกอบด้วย1*nเมทริกซ์ (หากn=0เป็นไปได้) (มันจะโยนข้อผิดพลาดสำหรับ0*0เมทริกซ์)

@(a)a(conv(a.*a,1:3,'s')>0) 

Convolution คือกุญแจสู่ความสำเร็จ


's'แทน'same'<- :-D
Luis Mendo

เคล็ดลับนั้นใช้งานได้หลายครั้งกับ builtins =)
ข้อผิดพลาด

ฉันเคยเห็นกลอุบายนั้นแม้ว่าจะเป็นคำถามที่ไม่ใช่การเล่นกอล์ฟด้วยธง'UniformOutpout'(เข้าใจได้) แต่ฉันไม่รู้เกี่ยวกับอันนี้
หลุยส์เมนโด

1
คุณสามารถใช้~~aแทนa.*a?
feersum

2
@feersum Matlab น่าเสียดายที่ปฏิเสธที่จะโน้มน้าวlogicalอาร์เรย์ นี่เป็นปัญหาสำหรับบิวด์อินที่ไม่ได้เขียนใน Matlab เอง มิฉะนั้นอาร์เรย์แบบลอจิคัลจะมีพฤติกรรมคล้ายกับตัวเลข มันอาจใช้งานได้ในความคิดของ Octave แต่ฉันไม่ได้ติดตั้งในตอนนี้
ข้อบกพร่อง

6

J, 17 14 ไบต์

#~0<3+/\0,~0,|

บันทึก 3 ไบต์ด้วยความช่วยเหลือจาก @ Zgarb

การใช้

   f =: #~0<3+/\0,~0,|
   f 2 0 4 _3 0 0 0 3 0 0 2 0 0
2 0 4 _3 0 0 3 0 0 2 0
   f ''

   f 0 0 0 8 0 1 0 0
0 8 0 1 0

คำอธิบาย

#~0<3+/\0,~0,|  Input: array A
             |  Get the absolute value of each in A
           0,   Prepend a 0
        0,~     Append a 0
    3  \        For each subarray of size 3, left to right
     +/           Reduce it using addition to find the sum
  0<            Test if each sum is greater than one
                (Converts positive values to one with zero remaining zero)
#~              Select the values from A using the previous as a mask and return

ลองที่นี่


จะ0<ทำงานในสถานที่ของ0~:?
Zgarb

@Zgarb ขนาดของ 3 ขนาดสามารถบวกหรือลบหลังจากการประมวลผล
ไมล์

อาฉันลืมเกี่ยวกับค่าลบ
Zgarb

6

MATL , 8 ไบต์

tg3:Z+g)

เอาท์พุทเป็นสตริงที่มีตัวเลขคั่นด้วยช่องว่าง อาร์เรย์ว่างที่เอาต์พุตจะแสดงเป็นไม่มีอะไร (ไม่ใช่แม้แต่บรรทัดใหม่)

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

คำอธิบาย

รหัสแปลงอินพุตเป็นชนิดโลจิคัลเช่นรายการที่ไม่ใช่ศูนย์กลายเป็นtrue(หรือ1) และรายการศูนย์กลายเป็นfalse(หรือ0) นี้จะ convolved [1 2 3]แล้วกับเคอร์เนล ค่าที่ไม่ใช่ศูนย์ทำให้เกิดผลลัพธ์ที่ไม่ใช่ศูนย์ที่ตำแหน่งนั้นและที่ตำแหน่งใกล้เคียง การแปลงเป็นโลจิคัลจะให้trueค่าที่ควรเก็บไว้ดังนั้นการจัดทำดัชนีอินพุตที่สร้างเอาต์พุตที่ต้องการ

t    % Input array implicitly. Duplicate
g    % Convert to logical: nonzero becomes true, zero becomes false
3:   % Push array [1 2 3]
Z+   % Convolution, keeping size of first input
g    % Convert to logical
)    % Index into original array. Implicitly display

5

Jolf, 14 ไบต์

ตอนนี้ฉันคิดว่ามัน Jolf เป็น Java ของภาษากอล์ฟ ถอนหายใจ ลองที่นี่

ψxd||H.nwS.nhS

คำอธิบาย

ψxd||H.nwS.nhS
ψxd             filter input over this function
   ||           or with three args
     H           the element
      .nwS       the previous element
          .nhS   or the next element

5

Python 3, 55 ไบต์

lambda s:[t[1]for t in zip([0]+s,s,s[1:]+[0])if any(t)]

1
ว้าว. ฉันไม่ทราบว่าคุณเห็น @xnor ตอบก่อนหน้านี้หรือไม่ แต่คุณมีรหัสเดียวกันโดยมีความแตกต่างเพียงอย่างเดียวคือชื่อของแลมบ์ดา ถ้าคุณใช้รหัสของเขาให้เครดิตเขาถ้าไม่ใช่นั่นเป็นเรื่องบังเอิญที่ยอดเยี่ยมมาก!
Theo

ไม่ได้ดูรหัสของใคร
RootTwo

3
@ T.Lukin มันไม่ใช่เรื่องแปลกที่จะเกิดขึ้นกับรหัสเดียวกัน คุณสามารถดูนี้เกิดขึ้นในความโกลาหลกอล์ฟที่รหัสถูกซ่อนไว้จนกว่าเส้นตายและคนหลายคนมาบรรจบกันในการแก้ปัญหาเช่นเดียวกับคนนี้
xnor

4

เยลลี่ขนาด 9 ไบต์

0,0jo3\Tị

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

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

0,0jo3\Tị  Main link. Argument: A (array)

0,0        Yield [0, 0].
   j       Join, separating with A. This prepends and appends a 0 to A.
    o3\    Reduce each group of three adjacent integers by logical OR.
       T   Truth; get the indices of all truthy results.
        ị  At-index; retrieve the elements of A at those indices.

4

Perl, 34 + 1 ( -pตั้งค่าสถานะ) = 35 bytes

s/([^1-9]0 |^)\K0 ?(?=0|$)//&&redo

ต้องการแฟล็ก -p เพื่อรัน ใช้รายการของตัวเลขเป็น imput ตัวอย่างเช่น

perl -pe 's/([^1-9]0 |^)\K0 ?(?=0|$)//&&redo' <<< "0 0 0 8 0 1 0 0
0 0 0
-5 0 5"

ฉันจะได้รับถ้าฉันป้อนข้อมูล5 50 0
feersum

แก้ไข @feersum แล้วขอบคุณ
Dada

4

Haskell, 48 ไบต์

p%(h:t)=[h|any(/=0)$p:h:take 1t]++h%t
p%e=e
(0%)

ดูที่องค์ประกอบก่อนหน้านี้p, องค์ประกอบแรกhและองค์ประกอบหลัง (ถ้ามี) และถ้าผู้ใดมีเลข prepends hองค์ประกอบแรก

เงื่อนไขคือความยาวโดยเฉพาะอย่างยิ่งในany(/=0)$p:h:take 1t take 1tฉันจะหาวิธีที่จะย่อให้สั้นลงบางทีโดยการจับคู่รูปแบบ


4

เรติน่า , 42 35 33 ไบต์

7 ไบต์ขอบคุณ Martin Ender

(? <= ^ | \ b0) 0 (? = $ | 0)

 +

^ | $

บรรทัดสุดท้ายเป็นสิ่งที่จำเป็น

ตรวจสอบการทดสอบทั้งหมดในครั้งเดียว (แก้ไขเล็กน้อยเพื่อรันงานทดสอบทั้งหมดในครั้งเดียว)

ดูเหมือนว่าภาษาที่สมบูรณ์แบบในการทำเช่นนี้ใน ... ยังคงพ่ายแพ้โดยคำตอบส่วนใหญ่


ฉันจะทิ้งวงเล็บจากรูปแบบ I / O
Martin Ender


3

C, 96 ไบต์

โทรf()ด้วยตัวชี้ไปยังรายการจำนวนเต็มและตัวชี้ไปยังขนาดของรายการ รายการและขนาดจะถูกแก้ไขในสถานที่

i,t,e,m;f(int*p,int*n){int*s=p;for(i=m=e=0;i++<*n;s+=t=m+*s||i<*n&&p[1],e+=t,m=*p++)*s=*p;*n=e;}

ลองบน ideone


รูปแบบพารามิเตอร์ K&R มักจะสั้นกว่า แต่ไม่ใช่ที่นี่ - f(int*p,int*n)บันทึกเป็นไบต์ หรือกำหนดsเป็นพารามิเตอร์ตัวที่ 3 (ที่ไม่ผ่านมันเป็นชนิดของตกลง)
ugoren

3

Brachylog , 44 38 ไบต์

,0gL:?:Lc:1fzbh.
~c[A:.:B],[0:0:0]'.l3

ลองออนไลน์!

ภาษานี้ดีพอ ๆ กับการพิสูจน์สิ่งต่าง ๆ ซึ่งเป็นสิ่งที่เราจะใช้

กริยา 0 (เพรดิเคตหลัก)

,0gL:?:Lc:1fzbh.
 0gL               [0] = L    (assignment works both ways)
   L:?:Lc          [L:input:L] = temp
         :1f       find all solutions of predicate 1 with temp as input
            zbh.   then transpose and take the middle row and assign to output

ภาคที่ 1 (ภาคเสริม)

~c[A:.:B],[0:0:0]'.l3
~c[A:.:B]                 input is in the form of [A:output:B]
         ,                and
          [0:0:0]'.       output is not [0:0:0]
                  .l3     and length of output is 3

2

Matlab พร้อมกล่องเครื่องมือประมวลผลภาพขนาด 27 ไบต์

@(a)a(~imerode(~a,~~(1:3)))

นี่คือฟังก์ชั่นที่ไม่ระบุชื่อ

ตัวอย่างการใช้:

>> @(a)a(~imerode(~a,~~(1:3)))
ans = 
    @(a)a(~imerode(~a,~~(1:3)))
>> ans([0 0 0 8 0 1 0 0])
ans =
     0     8     0     1     0

1
ฉันคิดว่าimerodeมากเกินไป แต่รุ่นของฉันเก็บไว้เป็นเวลานานกว่าหนึ่งในปัจจุบันของฉันทำงานที่ดี =)
flawr

2

Bash + GNU utils, 25

grep -vC1 ^0|grep -v \\-$

ยอมรับอินพุตเป็นรายการที่คั่นด้วยบรรทัดใหม่

Ideone - ด้วยการเพิ่มรหัสไดรเวอร์ทดสอบเพื่อเรียกใช้การทดสอบทั้งหมดด้วยกันโดยการแปลงเป็น / จากช่องว่างแยกจากกันและขึ้นบรรทัดใหม่คั่น


2

Cheddar , 78 ไบต์

a->([[]]+a.map((e,i)->e|(i?a[i-1]:0)|(i-a.len+1?a[i+1]:0)?[e]:[])).reduce((+))

ชุดทดสอบ

Cheddar ไม่มีตัวกรองดังนั้นการกรองจะทำโดยการห่อองค์ประกอบที่เราต้องการและเปลี่ยนองค์ประกอบที่เราไม่ต้องการให้เป็นอาร์เรย์ว่างเปล่าจากนั้นเชื่อมทุกอย่างเข้าด้วยกัน

ยกตัวอย่างเช่น[0,0,0,8,0,1,0,0]กลายเป็นแล้วตัดแบ่งอาร์เรย์จะเป็น[[],[],[0],[8],[0],[1],[0],[]][0,8,0,1,0]


.reduce((+))->.sum
Downgoat

@Downgoat คุณไม่แก้ไขเมื่อไหร่
Leun Nun

โอ้ขอโทษไม่เป็นไร ฉันคิดว่าคุณกำลังสรุปอาเรย์ ไม่เข้าร่วมอาร์เรย์
Downgoat

1

APL, 14 ไบต์

{⍵/⍨×3∨/0,⍵,0}

ทดสอบ:

      {⍵/⍨×3∨/0,⍵,0}2 0 4 ¯3 0 0 0 3 0 0 2 0 0
2 0 4 ¯3 0 0 3 0 0 2 0

คำอธิบาย:

  • 0,⍵,0: เพิ่มศูนย์ไปที่จุดเริ่มต้นและจุดสิ้นสุดของ⍵
  • ×3∨/: ค้นหาเครื่องหมายของ GCD ของทุกกลุ่มของตัวเลขสามตัวที่อยู่ติดกัน (นี่จะเป็น 0 ถ้าพวกมันทั้งหมดเป็นศูนย์และ 1 เป็นอย่างอื่น)
  • ⍵/⍨: เลือกรายการทั้งหมดจาก⍵ซึ่งผลลัพธ์เป็น 1

1

Ruby 2.x, 63 ไบต์

f=->(x){x.select.with_index{|y,i|x[i-1].to_i|y|x[i+1].to_i!=0}}

เครดิตที่ถึงกำหนดชำระนี่คือพอร์ตของคำตอบ ES6 ที่เหนือกว่าของ Neil

มันเป็นผลงานชิ้นแรกของฉันด้วย เย้.


1

Brain-Flak 142 ไบต์

ลองออนไลน์!

(<()>)(()){{}([]<([]){{}({}<>)<>({}<>)<>({}<>)<>(<>({}<>)<>({}<>)<>({})<>){{}((<()>))}{}{}([][()])}{}{}<>{}([]){{}({}<>)<>([])}{}<>>[[]])}{}{}

คำอธิบาย

(<()>)                    #Pad the top with an extra zero
(()){{}([]<...>[[]])}{}   #Until the stack height remains the same
 ([]){{}...([][()])}{}    #Until the stack height is one
  ({}<>)<>                #Move the top three to the other stack
  ({}<>)<>
  ({}<>)<>
  (...)                   #Push the sum of the top three
   <>({}<>)               #Move the second and third back
   <>({}<>)
   <>({})<>               #Leave the top of the stack
  {{}...}{}               #If the sum is not zero
   ((<()>))               #Add a buffer to the top of the stack
  {}                      #Pop the buffer/middle value
 {}                       #Remove extra zero
 <>                       #Switch to the off stack
 {}                       #Remove extra zero
 ([]){{}({}<>)<>([])}{}<> #Move the entire off stack back

ลิงค์ว่างเปล่า คุณสามารถวางรหัสและการป้อนข้อมูลกด "บันทึก" และใช้ลิงก์ผลลัพธ์
Luis Mendo

@LuisMendo น่าเสียดายที่ฉันไม่สามารถใช้ tryitonline ดังนั้นฉันเพิ่งเชื่อมโยงไปยัง URL
ตัวช่วยสร้างข้าวสาลี

ทำไมคุณไม่สามารถเข้าถึง tryitonline ได้?
DJMcMayhem

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