สั้นกว่าเสี้ยววินาที!


16

ท้าทาย

งานของคุณสำหรับคำถามนี้คือการแบ่งอาร์เรย์อินพุตของจำนวนเต็มในการเกิดขึ้นครั้งที่สองของทุกจำนวนเต็มในอาร์เรย์นั้น

ไม่ชัดเจนเพียงพอหรือไม่ นี่คือตัวอย่างที่จะช่วย

อาร์เรย์อินพุต:

[2 1 1 2 3 2 2 4 5 6 7 3 7 0 5]

เอาท์พุท:

[[2 1] [] [3 2 2 4 5 6 7] [] [0] []]

คำอธิบาย:

นี่คืออาร์เรย์ที่มีเพียงองค์ประกอบที่สองที่เน้นเป็นตัวหนา:

[2 1 1 2 3 2 2 4 5 6 7 3 7 0 5 ]

ตอนนี้เราวางบล็อกอาเรย์แยกรอบเหตุการณ์ที่สองที่เป็นตัวหนาเหล่านี้:

[2 1] 1 [] 2 [3 2 2 4 5 6 7] 3 [] 7 [0] 5 []

และตัดอาร์เรย์ที่แยกออกเหล่านี้ในอาร์เรย์เพื่อให้ได้ค่าสุดท้าย

[[2 1] [] [3 2 2 4 5 6 7] [] [0] []]

โปรดทราบว่าเมื่อเกิดเหตุการณ์ที่สองติดกันเกิดขึ้นจะมีอาร์เรย์ว่างเปล่า

กฎระเบียบ

ตามปกติคุณต้องเขียนโปรแกรมเต็มรูปแบบหรือฟังก์ชั่นการใช้อาร์เรย์อินพุตผ่าน STDIN, ARGV หรือฟังก์ชั่นการโต้แย้ง

อินพุต

อินพุตประกอบด้วยรูปแบบจำนวนเต็มของอาร์เรย์จำนวนเต็ม

ตัวอย่างเช่นข้อใดข้อหนึ่งต่อไปนี้จะเป็นที่ยอมรับ:

2 1 1 1 4 5 6
[2 1 1 1 4 5 6]
[2, 1, 1, 1, 4, 5, 6]

เอาท์พุต

เมื่อส่งออกไปยัง STDOUT อาเรย์ของคุณยังสามารถพิมพ์ในรูปแบบอาเรย์ที่สะดวก (ซ้อนกัน) เช่นหนึ่งใน

[[2 1] [1 4 5 6]]
[[2, 1], [1, 4, 5, 6]]
{{2, 1}, {1, 4, 5, 6}}

(ซึ่งโดยปกติจะเป็นการแทนค่าสายอักขระดั้งเดิมของอาร์เรย์ในภาษาของคุณ)

นอกจากนี้โปรดทราบว่าควรพิมพ์อาร์เรย์ว่างเปล่าต่อท้ายเป็นส่วนหนึ่งของอาร์เรย์

เกณฑ์การให้คะแนน

นี่คือสั้นที่สุดในหน่วยไบต์!


@PeterTaylor มีคำถามมากมายที่ให้รูปแบบที่แตกต่างกันของอาร์เรย์ในทั้งเอาต์พุตและอินพุต
เครื่องมือเพิ่มประสิทธิภาพ

5
จุดประสงค์ของการอนุญาตให้""เป็นอาร์เรย์ว่างคืออะไร นี่คือกลิ่นของความนิยมไปสู่ภาษากอล์ฟที่เฉพาะเจาะจง
John Dvorak

@JanDvorak หลังจากการสนทนาในการแชทความตั้งใจจริง ๆ แล้วจะครอบคลุมมากขึ้นและโดยทั่วไปแล้วอนุญาตให้ภาษาต่างๆ ฉันได้แก้ไขข้อความตอนนี้เพื่อให้ชัดเจนขึ้น
Martin Ender

1
ฉันสามารถส่งออกได้2 1, 1 4 5 6หรือไม่
jimmy23013

@ user23013 ขึ้นอยู่กับภาษาที่คุณเลือก
เครื่องมือเพิ่มประสิทธิภาพ

คำตอบ:


6

APL 25

1↓¨(1,∨⌿<\2=+\∘.=⍨a)⊂1,a←

ตัวอย่าง:

]display 1↓¨(1,∨⌿<\2=+\∘.=⍨a)⊂1,a←2 1 1 2 3 2 2 4 5 6 7 3 7 0 5
┌→──────────────────────────────────────┐
│ ┌→──┐ ┌⊖┐ ┌→────────────┐ ┌⊖┐ ┌→┐ ┌⊖┐ │
│ │2 1│ │0│ │3 2 2 4 5 6 7│ │0│ │0│ │0│ │
│ └~──┘ └~┘ └~────────────┘ └~┘ └~┘ └~┘ │
└∊──────────────────────────────────────┘

อันเก่า:

{1↓¨(1,(⍳⍴⍵)∊,{1↑1↓⍵}⌸⍵)⊂1,⍵}

นี่เป็นคำถามที่ดีสำหรับผู้ให้บริการหลัก (⌸) ซึ่งได้รับการแนะนำให้รู้จักกับ Dyalog APL v14 มันใช้ฟังก์ชันอาร์กิวเมนต์ด้านซ้าย ({1 ↑ 1 ↓⍵}) และให้มันสำหรับแต่ละอาร์กิวเมนต์ที่ไม่ซ้ำกันดัชนีในเวกเตอร์สำหรับอาร์กิวเมนต์นั้น ที่นี่ฉันกำลังทำดัชนีที่สองจากนั้นฉันตรวจสอบว่าดัชนีใดที่มีอยู่ในรายการนี้ ((⍳⍴⍵) ∊) และใช้บูลีนที่ได้จากการแยกเวกเตอร์ดั้งเดิม

สามารถลองออนไลน์ได้ที่นี่:

http://tryapl.org


ประณาม. ยังไม่น้อยกว่า 24?
เครื่องมือเพิ่มประสิทธิภาพ

@Optimizer: 25 ... ฉันกำลังพยายาม ;-)
Moris Zucca

ยอมรับสิ่งนี้แทนโซลูชันของฉันเอง :)
เครื่องมือเพิ่มประสิทธิภาพ

เพียง 24 และฟังก์ชั่นที่เหมาะสม:1↓¨{1,∨⌿<\2=+\∘.=⍨⍵}⊂1∘,
อดัม

ไม่ทำงานโชคไม่ดี ... โอเมก้าใน dfn นั้นไม่เหมือนกับ "a"
Moris Zucca

9

APL (Dyalog 14) (31)

{1↓¨(1,(⍳⍴⍵)∊2⍳⍨¨↓+\∘.=⍨⍵)⊂0,⍵}

นี่คือฟังก์ชั่นที่รับอาเรย์และส่งกลับอาเรย์ที่ซ้อนกัน

ทดสอบ:

      +V← {1↓¨(1,(⍳⍴⍵)∊2⍳⍨¨↓+\∘.=⍨⍵)⊂0,⍵} 2 1 1 2 3 2 2 4 5 6 7 3 7 0 5
┌───┬┬─────────────┬┬─┬┐
│2 1││3 2 2 4 5 6 7││0││
└───┴┴─────────────┴┴─┴┘
      ⍝ this return value is a real nested array:
      ⎕←'Length: ',⍴V ⋄ (⍳⍴V){⎕←'Array #',⍺,': (', ⍵, ')'}¨V 
Length:  6
Array # 1 : ( 2 1 )
Array # 2 : ()
Array # 3 : ( 3 2 2 4 5 6 7 )
Array # 4 : ()
Array # 5 : ( 0 )
Array # 6 : ()

คำอธิบาย:

  • 0,⍵: เพิ่ม a 0ไว้ด้านหน้าเพื่อให้การประมวลผลง่ายขึ้น (ไม่นับเป็นการเกิดขึ้น)
  • (... )⊂: แบ่งอาร์เรย์ตาม bitmask ที่กำหนด กลุ่มใหม่เริ่มต้นที่แต่ละคน1ใน bitmask
    • +\∘.=⍨⍵: สำหรับค่าในแต่ละ (เดิม) หาที่เกิดขึ้นทั้งหมดใน จากนั้นสร้างผลรวมสะสมสำหรับแต่ละค่าโดยให้เมทริกซ์จตุรัสแสดงสำหรับแต่ละตำแหน่งในจำนวนที่เกิดขึ้นแล้ว
    • : แบ่งเมทริกซ์ออกเป็นแถวโดยให้แต่ละอาร์เรย์แสดงค่าตามจำนวนครั้งที่แต่ละตำแหน่งเกิดขึ้น
    • 2⍳⍨¨: 2ในแต่ละอาร์เรย์เหล่านี้พบว่าดัชนีของครั้งแรก
    • (⍳⍴⍵)∊: สำหรับแต่ละดัชนีที่เป็นไปได้ดูว่ามีอยู่ในรายการดัชนีที่เกิดขึ้นครั้งที่สองหรือไม่ (สิ่งเหล่านี้เริ่มแต่ละกลุ่มยกเว้นกลุ่มแรก)
    • 1,: เพิ่ม1ไปที่ด้านหน้าเพื่อทำเครื่องหมายจุดเริ่มต้นของกลุ่มแรก
  • 1↓¨: ลบองค์ประกอบแรกจากแต่ละกลุ่ม (นี่คือการเพิ่ม0และการเกิดขึ้นครั้งที่สองของแต่ละค่า)

8

J, 28 24 ถ่าน

ขอขอบคุณเป็นพิเศษrandomra

(1&,<;._1~1,2=+/@(={:)\)

มันใช้งานได้เช่นนี้ เหนือคำนำหน้า ( \) ทั้งหมดของอาร์เรย์อินพุตเราจะดูว่า+/@องค์ประกอบ( ) จำนวนใดของคำนำหน้าเท่ากับองค์ประกอบสุดท้าย ( ={:) ของคำนำหน้านั้น เมื่อตัวเลขนี้เป็นที่ 2 <;._1เรารู้ว่านี่เป็นปรากฏการณ์ที่เกิดขึ้นที่สองของรายการที่ในอาร์เรย์เพื่อให้เราแยกอาร์เรย์มีการใช้

   a=.2 1 1 2 3 2 2 4 5 6 7 3 7 0 5
   (={:)\ a
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
1 0 0 1 0 1 0 0 0 0 0 0 0 0 0
1 0 0 1 0 1 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 1 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 1 0 0 0 0 0 1
   +/@(={:)\ a
1 1 2 2 1 3 4 1 1 1 1 2 2 1 2

สิ่งเก่าโดยใช้เทคนิคการเรียงลำดับ: (1&,<;._1~1,1=i.~(]-{)/:@/:).


(1&,<;._1~1,2=+/@(={:)\)สั้นลง 4 ไบต์และง่ายกว่ามาก ( /:@/:เป็นกลอุบายที่ดี)
Randomra

7

Mathematica, 58 51 49 ไบต์

Rest/@SplitBy[(f@#=0;#)&/@{a}~Join~#,++f[#]==3&]&

นี่คือฟังก์ชั่นที่ไม่มีชื่อซึ่งใช้รายการเช่น

Rest/@SplitBy[(f@#=0;#)&/@{a}~Join~#,++f[#]==3&]&[{2,1,1,2,3,2,2,4,5,6,7,3,7,0,5}]

และส่งคืนรายการที่ซ้อนกันเช่น

{{2, 1}, {}, {3, 2, 2, 4, 5, 6, 7}, {}, {0}, {}}

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

SplitByนี้ใช้บางมายากลปิดบังสวยด้วย

fผมติดตามความเคลื่อนไหวของการเกิดขึ้นของแต่ละหมายเลขในฟังก์ชั่น ใน Mathematica คุณสามารถกำหนดค่าของฟังก์ชั่นสำหรับแต่ละอินพุตแยกกันและคุณไม่จำเป็นต้องระบุค่าสำหรับอินพุตที่เป็นไปได้ทั้งหมด (มันเหมือนกับตารางแฮชบนเตียรอยด์)

ดังนั้นผมจึงเริ่มต้นด้วยการ initialising f0 (f@#=0;#)&/@สำหรับค่าที่มีอยู่ในการป้อนข้อมูลด้วย

ตอนนี้SplitByรับรายการและฟังก์ชั่นและ "แยกรายการออกเป็นรายการย่อยซึ่งประกอบด้วยองค์ประกอบที่ต่อเนื่องซึ่งให้ค่าเดียวกันเมื่อfใช้" (หมายเหตุที่SplitByไม่ได้ลบองค์ประกอบใด ๆ ) แต่จับ (ไม่มีเอกสาร) คือที่fถูกเรียกสองครั้งในแต่ละองค์ประกอบ - เมื่อเปรียบเทียบกับรุ่นก่อนและตัวตายตัวแทนของมัน ดังนั้นหากเราทำ

 SplitBy[{1,2,3,4},Print]

เราไม่ได้รับแต่ละหมายเลขเพียงครั้งเดียว แต่พิมพ์ออกมาแทน

 1
 2
 2
 3
 3
 4

ซึ่งคือ 6 สายสำหรับการเปรียบเทียบ 3 ครั้ง

เราสามารถแยกรายการก่อนเกิดเหตุการณ์ที่สองแต่ละครั้งถ้าเราเขียนฟังก์ชั่นที่มักจะส่งกลับFalseแต่ผลตอบแทนTrueเมื่อเกิดเหตุการณ์ที่สองจะถูกเปรียบเทียบกับองค์ประกอบก่อน นั่นคือการตรวจสอบครั้งที่สามในองค์ประกอบนั้น (การตรวจสอบสองครั้งสำหรับการเกิดครั้งแรกรวมทั้งการตรวจสอบครั้งแรกในการเกิดครั้งที่สอง) ++f[#]==3&ดังนั้นเราจะใช้ สิ่งที่ดีคือสิ่งนี้กลับมาFalseอีกครั้งในการตรวจสอบครั้งที่สองของการเกิดขึ้นครั้งที่สองเช่นฉันสามารถกลับมาTrueเป็นครั้งที่สองติดต่อกัน แต่ก็ยังแยกกันอยู่ ในทำนองเดียวกันสิ่งนี้จะไม่แยกหลังจากที่เกิดขึ้นครั้งที่สองเพราะฟังก์ชั่นกลับมาFalseอีกครั้งในการตรวจสอบครั้งที่สอง

Rest/@ตอนนี้คำถามต้องการให้เรายังเอาเหตุการณ์ที่สองเหล่านั้นเพื่อให้เราวางองค์ประกอบแรกจากแต่ละรายการด้วย แต่แน่นอนเราไม่ต้องการที่จะลบองค์ประกอบแรกมากในการป้อนข้อมูลเพื่อให้เราจริงเริ่มต้นโดยการเพิ่มองค์ประกอบที่จุดเริ่มต้นของรายการที่มีa เป็นตัวแปรที่ไม่ได้กำหนดซึ่ง Mathematica เพียงถือว่าเป็นที่ไม่รู้จักดังนั้นมันจะไม่ส่งผลกระทบต่อค่าอื่น ๆ ของ สิ่งนี้ยังช่วยให้มั่นใจได้ว่าองค์ประกอบที่แท้จริงแรกในอินพุตได้รับการตรวจสอบสองครั้งเหมือนกับองค์ประกอบอื่น ๆ{a}~Join~#af


มันค่อนข้างฉลาด จริงๆแล้วคุณไม่จำเป็นต้องBooleมี
swish

@swish อ่าขอบคุณที่เตือนฉัน ... ฉันสังเกตว่าขณะอยู่บนมือถือ แต่ต้องการทดสอบก่อนที่จะเปลี่ยน
Martin Ender

5

Python ขนาด 148 ไบต์

def s(a):z=len(a);x=[-1]+sorted({[i for i in range(z)if a[i]==n][1]for n in a if a.count(n)>1})+[z];return[a[x[i]+1:x[i+1]]for i in range(len(x)-1)]

ทางออกที่น่ากลัวสวย จะต้องมีวิธีที่ดีกว่า ...

s([2, 1, 1, 1, 4, 5, 6])โทรหา

เวอร์ชันที่ไม่ดี

def split(array):
  indices = [-1]
  second_occurrences = set()

  for n in array:
      if array.count(n) > 1:
          occurrences = [i for i in range(len(array)) if array[i] == n]
          second_occurrences.add(occurrences[1])

  indices += sorted(second_occurrences)
  indices += [len(array)]

  return [array[indices[i]+1:indices[i+1]] for i in range(len(indices)-1)]

1
คุณสามารถแก้ไขอะไรในเวอร์ชันที่ไม่ได้ตีกอล์ฟ? XD 148 ตัวอักษรเป็นเส้นที่ยาวมาก ;)
Sean Allred

1
@ SeanAllred ฉันไม่ต้องการโพสต์คำอธิบายเนื่องจากฉันแน่ใจว่าฉันสามารถทำได้ดีกว่า แต่เนื่องจากฉันมีปัญหาฉันได้โพสต์เวอร์ชันที่ไม่ได้รับการยกย่อง: P
Sp3000

5

Haskell, 115 113 106 88

f?(x:s)|1<-f x=[]:x%f?s|a:b<-x%f?s=(x:a):b
f?x=[x]
(x%f)h=sum$f h:[1|x==h]
r s=(\_->0)?s

สิ่งนี้จะเก็บจำนวนเงินที่ทุกองค์ประกอบปรากฏเท่าที่ฟังก์ชั่นจากองค์ประกอบไปยังจำนวนนั้น ๆ ซึ่งเป็นเคล็ดลับที่น่าสนใจ

งานนี้โดยใช้%ฟังก์ชั่นที่ได้รับฟังก์ชัน f และข้อโต้แย้งxผลตอบแทนที่ได้ฟังก์ชั่นใหม่ที่ให้ผลตอบแทนfนำไปใช้เป็นของอาร์กิวเมนต์ถ้ามันเป็นความแตกต่างxและ1 + f xเป็นอย่างอื่น

ตัวอย่างเช่น3 % const 0เป็นฟังก์ชันที่ส่งกลับค่า 0 สำหรับทุกอาร์กิวเมนต์ยกเว้น 3 ซึ่งจะส่งกลับค่า 1 update: fused the foldlเพื่อรับโปรแกรมที่มีขนาดเล็กกว่ามาก


มันดูน่าสนใจ คุณช่วยจัดเตรียมเวอร์ชั่นที่ไม่น่ารังเกียจได้ไหม?
radomaj


4

Python: 100 ไบต์

def g(l):
 i=j=0;o=[]
 for e in l:
  if l[:i].count(e)==1:o+=[l[j:i]];j=i+1
  i+=1
 return o+[l[j:]]

ทางออกที่ตรงไปตรงมา ฉันวนซ้ำในรายการนับจำนวนอักขระที่ปรากฏก่อนหน้านี้และต่อท้ายส่วนตั้งแต่การตรวจสอบครั้งสุดท้ายไปยังรายการผลลัพธ์


3

ทับทิม, 66

f=->a{s=Hash.new 0
r=[[]]
a.map{|e|(s[e]+=1)==2?r<<[]:r[-1]<<e}
r}

คำอธิบาย

  • eคือแฮชของจำนวนครั้งที่เกิดขึ้นสำหรับแต่ละองค์ประกอบrเป็นอาร์เรย์ที่เก็บผลลัพธ์ไว้
  • วน1ซ้ำ อินพุตเพิ่มจำนวนการเกิดขึ้นสำหรับแต่ละองค์ประกอบโดย
    • หากการนับเหตุการณ์เกิดขึ้น2เราจำเป็นต้องแยก เพิ่มค่าว่างArrayลงในผลลัพธ์
    • มิฉะนั้นเพียงเพิ่มองค์ประกอบไปยังArrayผลลัพธ์สุดท้าย

2
หมวกสวย!! โอ้เดี๋ยวก่อน
เครื่องมือเพิ่มประสิทธิภาพ

4
ช่างเป็นเรื่องบังเอิญจริง ๆ ! คำตอบที่ผมโพสต์วินาทีก่อนที่คุณเป็นเหมือนกันเกือบ :)
Cristian Lupascu

โอ้ฉันมันสั้นกว่า 1 ตัวอักษร!
britishtea

เป็นการประหยัดที่คุณสามารถนำไปใช้กับคุณได้อย่างง่ายดาย ฉันคิดว่ามันยอดเยี่ยมที่เรามีความคิดเดียวกันในเวลาเดียวกัน : D
Cristian Lupascu

3

CJam, 25 24 ไบต์

q~{_L+:L1$a/,3=S@?}%Sa/p

ใช้อินพุตจาก STDIN เช่นกัน

[ 2 1 2 1 0 2 2 1 1 3 4 3]

และผลลัพธ์เช่น

[[2 1] "" [0 2 2 1 1 3 4] ""]

โดยทั่วไปฉันจะวนองค์ประกอบทั้งหมดของอาร์เรย์อีกทีละหนึ่งใส่เข้าไปในอีกอาร์เรย์หนึ่ง จากนั้นฉันจะได้รับการนับองค์ประกอบปัจจุบันในอาร์เรย์อื่น ๆ หากเป็น 2 ฉันจะเริ่มต้นอาร์เรย์อื่นจากตำแหน่งนั้น การสุ่มเริ่มต้นของอาเรย์ชนิดนี้สามารถทำได้ในภาษาที่ใช้สแต็กเท่านั้น

การขยายรหัส :

q~{_L+:L1$a/,3=S@?}%Sa/p
q~{               }%             "Evaluate the input array and map it on this block";
   _                             "Copy the current element in iteration";
    L+:L                         "Add the copy to an initially blank array L and update L";
        1$a/                     "Make another copy of the element and split L on it";
            ,3=                  "This checks if the splitted array is of length 3";
                                 "which indirectly means that L contains the element twice";
               S@?               "If the above is true, replace the element by space";
                    Sa/          "Split the final array on space. This final array contains";
                                 "second occurrence of every integer replaced by a space";
                       p         "Print the stringified version of the final nested array";

ลองออนไลน์ได้ที่นี่

บันทึก 1 ไบต์จากเคล็ดลับของ Martin ในการแชท



3

Perl 5: 36

ไม่แน่ใจว่าสิ่งนี้ยอมรับได้หรือไม่เนื่องจากไม่มีการแยกเกิดขึ้นจริงที่นี่

#!perl -pa
$x{$_}++-1or$_=']['for@F;$_="[[@F]]"

ตัวอย่าง:

$ perl spl.pl <<<"2 1 1 2 3 2 2 4 5 6 7 3 7 0 5"
[[2 1 ][ ][ 3 2 2 4 5 6 7 ][ ][ 0 ][]]

ยอมรับโดยสิ้นเชิง
เครื่องมือเพิ่มประสิทธิภาพ

คำตอบที่ดี แต่ฉันคิดว่าการฝึกฝนมาตรฐานคือการนับ-paเป็นสองไบต์พิเศษ (เพราะ "ราคา" เพียงสองไบต์เนื่องจากคุณสามารถเขียนเป็น-paeแทน-e) นั่นก็คือ 38 ไม่ใช่ 36
msh210

2

CJam, 28 ไบต์

Lq~{1$1$a/,3=S2$?@++}/-2%S/`

ใช้อินพุตเหมือน STDIN

[2 1 1 2 3 2 2 4 5 6 7 3 7 0 5]

และพิมพ์ผลลัพธ์ไปที่ STDOUT เช่น

[[2 1] "" [3 2 2 4 5 6 7] "" [0] ""]

โปรดทราบว่าสตริงว่างและอาร์เรย์ว่างเปล่าเป็นสิ่งเดียวกันใน CJam และแสดงเป็น""ค่าเริ่มต้น (นี่คือการแทนค่าดั้งเดิมของอาร์เรย์ว่าง)

(ฉันเริ่มทำงานกับเรื่องนี้เล็กน้อยก่อนที่ความท้าทายจะโพสต์เพราะเรากำลังคุยกันถึงความท้าทายที่จะเกิดขึ้น)

คำอธิบาย

โดยพื้นฐานแล้วฉันจะทำซ้ำองค์ประกอบแต่ละอย่างในอาร์เรย์เว้นแต่จะเป็นเหตุการณ์ที่สองซึ่งในกรณีนี้ฉันแทนที่สำเนาแรกด้วยช่องว่าง สำหรับเหตุผลในการตีกอล์ฟอาเรย์ที่ดัดแปลงนี้ถูกสร้างขึ้นในสิ่งที่ตรงกันข้าม ดังนั้น[2 1 1 2 3 2 3]กลายเป็น

[3 S 2 2 3 3 2 S 1 S 1 1 2 2]

จากนั้นฉันก็เลือกทุกองค์ประกอบที่สองจากจุดสิ้นสุดซึ่งเป็นอาร์เรย์ดั้งเดิม แต่มีสิ่งที่สองเกิดขึ้นแทนที่ด้วยช่องว่างคือ

[2 1 S S 3 2 S]

ในที่สุดฉันก็แบ่งอาร์เรย์กับช่องว่าง นี่คือรายละเอียดของรหัส:

L                            "Push empty array.";
 q~                          "Read STDIN an evaluate.";
   {                }/       "For each element of the input.";
    1$1$                     "Copy the array and the element.";
        a/                   "Split the array by that element.";
          ,3=                "Check that it's split into 3 parts.";
             S2$?            "If so, push a space, else, copy the current number.";
                 @++         "Pull up the array from the bottom and add both to the beginning.";
                      -2%    "Pick every second element from the end.";
                         S/  "Split on spaces.";
                           ` "Get the string representation.";

เนื่องจากนี่เป็นความท้าทายของฉันเองฉันจึงให้โอกาสก่อน: พี ฉันมีโซลูชัน Cjam 25 ไบต์กับฉัน
เครื่องมือเพิ่มประสิทธิภาพ

ไม่แสดงอาร์เรย์ว่างอย่างถูกต้อง - เห็นได้ชัดว่าไม่ถูกต้อง!
feersum

1
@feersum แสดงอาร์เรย์ว่างตามที่""ได้รับอนุญาตอย่างชัดเจนในการแก้ไขครั้งแรกของคำถาม การแก้ไขปัจจุบันระบุว่า "รูปแบบใด ๆ ที่สะดวก ... โดยปกติแล้วการรีสตริงของ Native"
John Dvorak

2

เครื่องมือ Unix ขนาด 100 ไบต์

grep -o '[-0-9]*'|awk '{print(++A[$0]-2)?$0:"] ["}'|paste -sd' '|sed -e '/]/s/.*/[\0]/' -e's//[\0]/'

ยกเว้นอินพุตผ่าน stdin "] ["มันเป็นพื้นเพียงแทนที่เกิดขึ้นทุกครั้งที่สองกับ ไม่ทำงานกับสตริงที่ว่างเปล่า[]จะให้สตริงที่ว่างเปล่าซึ่งฉันคิดว่าเป็นตัวแทนที่สะดวกสบายของอาร์เรย์ที่ว่างเปล่า :)


ถ้าอย่างนั้นคำตอบก็ไม่ตรงตามสเป็คใช่มั้ย (เกี่ยวกับจำนวนเต็มลบ) แล้วยัง11ไงล่ะ มันจะถูกแปลงเป็น1][?
เครื่องมือเพิ่มประสิทธิภาพ

มันทำงานได้ดีสำหรับ 11 แต่คุณพูดถูกเกี่ยวกับจำนวนลบคงที่และตอนนี้ก็ยอมรับอาร์เรย์แบบซิงเกิล
pgy

2

APL, 42 ตัวอักษร

{'(',')',⍨⍵[(2=+/¨(↑=↓)¨⌽¨,\⍵)/⍳⍴⍵]←⊂')('}

ตัวอย่าง:

{'(',')',⍨⍵[(2=+/¨(↑=↓)¨⌽¨,\⍵)/⍳⍴⍵]←⊂')('}2 1 1 2 3 2 2 4 5 6 7 3 7 0 5

เอาท์พุท:

( 2 1  )(   )(  3 2 2 4 5 6 7  )(   )(  0  )(  )

ทดสอบที่นี่

ถ้าฉันต้องเอาท์พุทสตริงที่ถูกตีความเหมือนกับโครงสร้างที่ถูกต้องใน APL ... 49 ตัวอักษร

{'1↓1(',',⍬)',⍨⍵[(2=+/¨(↑=↓)¨⌽¨,\⍵)/⍳⍴⍵]←⊂',⍬)('}

วิธีนี้เป็นรายการที่ซ้อนกันจริงตัวแทนใน APL? บางทีคุณอาจไม่จำเป็นต้องทำการจัดการสตริง
เครื่องมือเพิ่มประสิทธิภาพ

@Optimizer สตริงที่ส่งออกเป็นรายการที่ถูกต้องในโปรแกรม APL อย่างไรก็ตามมันจะไม่ซ้อนกันถ้ามีเพียงหนึ่งในรายการ การเตรียม1↓1ดูเหมือนจะแก้ไขปัญหาได้ แต่มันดูแปลกเกินไป
jimmy23013

2

Java, 223

สิ่งนี้ใช้ได้กับ Oracle หรือ OpenJDK JRE เท่านั้นเนื่องจากฉันใช้ประโยชน์จากการเล่นโวหารนี้ในการใช้งานตัวตรวจสอบปริมาณและตรวจสอบความยาวเพื่อดูการใช้ความยาวแปรผัน

class W{public static void main(String a[]){System.out.print("["+new java.util.Scanner(System.in).nextLine().replaceAll(" *\\b(\\d+)\\b(?=(.*))(?<=^(?=(.*\\b\\1\\b){2}\\2).*)(?<!^(?=(.*\\b\\1\\b){3}\\2).*) *","] [")+"]");}}

งานส่วนใหญ่จะทำใน regex ซึ่งแสดงด้านล่างในรูปแบบดิบ:

 *\b(\d+)\b(?=(.*))(?<=^(?=(.*\b\1\b){2}\2).*)(?<!^(?=(.*\b\1\b){3}\2).*) *

ก่อนที่เราจะดูที่ regex ข้างต้นให้เราดู. NET regex ที่เทียบเท่ากันซึ่งง่ายกว่าเนื่องจากสนับสนุนการดูความยาวผันแปรโดยตรง (.NET look-behind เป็นไปได้มากที่สุดโดยโหมดจับคู่จากขวาไปซ้าย) :

 *\b(\d+)\b(?<=(.*\b\1\b){2})(?<!(.*\b\1\b){3}) *
  •  *\b(\d+)\bและ *ท้ายที่สุดจะจับคู่ตัวเลขและช่องว่างโดยรอบ (ถ้ามี) การตรวจสอบที่ถูกผูกไว้เป็นการป้องกันไม่ให้จับคู่หมายเลขบางส่วนเนื่องจากช่องว่างทั้งสองด้านเป็นทางเลือก นอกจากนี้ยังจับหมายเลขเพื่อตรวจสอบว่าเป็นลักษณะที่ 2 ในอาร์เรย์

  • (?<=(.*\b\1\b){2})ตรวจสอบว่ามี 2 อินสแตนซ์ของจำนวนที่จับด้านบนสามารถพบได้ (?<!(.*\b\1\b){3})ตรวจสอบว่าไม่พบ 3 หมายเลขที่จับได้ เงื่อนไขทั้งสองรวมกันยืนยันว่ามีเพียง 2 อินสแตนซ์ของจำนวนจนถึงขณะนี้ มีการตรวจสอบที่ถูกผูกไว้เพื่อให้แน่ใจว่าได้ทดสอบจำนวนทั้งหมดแล้ว

กลับไปเป็นเวอร์ชั่น Java ในการใช้ความยาวผันแปรของตัวแปรเราจะแปลง

(?<=var-length-pattern)

ถึง

(?<=^(?=.*var-length-pattern).*)

ฉันโบกมือเล็กน้อยเกี่ยวกับความจริงที่.ไม่รวมตัวแยกบรรทัด แต่สามารถแก้ไขได้อย่างง่ายดายและฉันไม่ต้องการทำให้ไวยากรณ์ซับซ้อนขึ้นอีก

การตรวจสอบล่วงหน้ามีความยาว 0 เสมอและการตรวจสอบความยาวผ่านไปเนื่องจากการใช้งาน *ปริมาณ

^ไม่จำเป็นที่จะทำให้การทำงาน แต่ก็จะมีการให้ความล้มเหลวในกรณีที่ล้มเหลวได้เร็วขึ้น การตรวจสอบใน Oracle / OpenJDK นั้นทำได้โดยการย้อนกลับไปที่ความยาวต่ำสุดของรูปแบบจากนั้นจับคู่แล้วล้างและทำซ้ำโดยการเพิ่มความยาวจนกว่าจะพบการแข่งขันหรือในกรณีที่เลวร้ายที่สุดจนถึงความยาวสูงสุดของรูปแบบ . กับ^ฉันทำให้แน่ใจว่าสตริงคำนำหน้าจะจับคู่เพียงครั้งเดียว

อย่างไรก็ตามการมองไปข้างหน้าภายใน Look-Behind นั้นไม่ได้ถูก จำกัด ด้วยขอบเขตด้านขวาของ Look-behind ดังนั้นมันสามารถจับคู่ไปจนสุดของสตริงได้ เพื่อยืนยันขอบเขตฉันจับส่วนที่เหลือของสตริงลงในกลุ่มการจับภาพอื่นภายในการมองไปข้างหน้าและใช้มันเพื่อ จำกัด การปกครองของรูปแบบความยาวผันแปร

(?=(.*))(?<=^(?=.*var-length-pattern\m).*)
   ^--^                              ^
   mth capturing group               m is the number of the capturing group marked

ตั้งแต่รูปแบบของฉันเริ่มต้นด้วย.*ฉันไม่จำเป็นต้องเพิ่มอีกแบบ.*ไว้ข้างหน้า


1

Perl 108

map{$e[$_]==1?do{push@a,[@b];@b=();}:push@b,$_;$e[$_]++}split" ";push@a,[@b];s/.*/Data::Dumper->Dump(\@a)/e;

ในการดำเนินการ:

perl -MData::Dumper -pe '
    $Data::Dumper::Terse = 1;
    $Data::Dumper::Indent = 0;
    @a=@b=@e=();
    map{$e[$_]==1?do{push@a,[@b];@b=();}:push@b,$_;$e[$_]++}split" ";
    push@a,[@b];
    s/.*/Data::Dumper->Dump(\@a)/e;
' <<<$'2 1 1 2 3 2 2 4 5 6 7 3 7 0 5\n2 1 1 1 4 5 6\n'"$(
    sed 's/./& /g;w/dev/stderr' <<< ${RANDOM}${RANDOM}${RANDOM}$'\n'${RANDOM}${RANDOM})"
2 4 4 7 7 2 9 8 8 4 6 0 1 8 
1 0 3 9 3 7 9 
[2,1][][3,2,2,4,5,6,7][][0][]
[2,1][1,4,5,6]
[2,4][7][][9,8][4,6,0,1,8]
[1,0,3,9][7][]

หมายเหตุ: สองบรรทัดแรก$Data::...มีเฉพาะสำหรับงานนำเสนอที่ดีกว่าและบรรทัดที่สาม@a=@b=@e=();มีไว้เพื่อให้เครื่องมือทำงานบนหลายบรรทัด


1

R, 76

y=scan();r=split(y,cumsum(ave(y,y,FUN=seq)==2));c(r[1],lapply(r[-1],"[",-1))

เอาท์พุทสำหรับตัวอย่าง: รายการของห้าองค์ประกอบรวมถึงสามเวกเตอร์ที่ว่างเปล่า ( numeric(0))

$`0`
[1] 2 1

$`1`
numeric(0)

$`2`
[1] 3 2 2 4 5 6 7

$`3`
numeric(0)

$`4`
[1] 0

$`5`
numeric(0)

โดยวิธีการ: รหัสสร้างข้อความเตือนที่สามารถละเว้นได้


1

awk 29

a[$1]++==1{print"-";next}1

สิ่งนี้ใช้เสรีภาพเล็กน้อยกับรูปแบบอินพุตและเอาต์พุต อินพุต "array" เป็นแนวตั้งหนึ่งหมายเลขต่อหนึ่งบรรทัด เอาต์พุตยังเป็นแนวตั้งหนึ่งหมายเลขต่อบรรทัดด้วยขีดกลางเพื่อแยกอาร์เรย์

การป้อนข้อมูล:

2
1
1
2
3
2
2
4
5
6
7
3
7
0
5

เอาท์พุท:

2
1
–
–
3
2
2
4
5
6
7
–
–
0
–

1

Pyth 30 32

นี่เป็นครั้งแรกที่ฉันได้ทดลองใช้ Pyth มันเป็นโซลูชันเดียวกับในโซลูชัน Python ของฉัน

VQIq/<QN@QN1~Y]:QZN=ZhN;+Y]>QZ

คุณสามารถลองออนไลน์ได้: Pyth Compiler / Executor

เช่นการป้อนข้อมูล

[2,1,1,2,3,2,2,4,5,6,7,3,7,0,5]

จะพิมพ์

[[2, 1], [], [3, 2, 2, 4, 5, 6, 7], [], [0], []]

คำอธิบาย:

                                 # Q = input(), Y = [], Z = 0
VQ                               # for loop: N iterates over the indices of Q
  I                              # if 
   q\<QN@QN1                     #    Q[N] appears exactly once in Q[:N]
            ~Y]:QZN              #         append the list [Q[Z:N]] to Y
                   =ZhN          #         and assign Z = N + 1
                       ;         # end if and for loop
                        +Y]>QZ   # print Y + [Q[Z:]]

มีทางเลือกที่ดีกว่าสำหรับ=Y+Y...หรือไม่
Jakube


1

Python 2, 84

l=[[]];p=[]
for x in input():p+=[x];b=p.count(x)==2;l+=[[]]*b;l[-1]+=[x][b:]
print l

รายการlคือผลลัพธ์จนถึงปัจจุบัน เราวนซ้ำองค์ประกอบต่างๆ หากรายการปัจจุบันเป็นลักษณะที่สองเราจะเริ่มรายการย่อยใหม่ที่ว่างเปล่า มิฉะนั้นเราจะเพิ่มเข้าไปในรายการย่อยล่าสุด pรายการขององค์ประกอบที่เห็นเพื่อให้ห่างไกลถูกเก็บไว้ใน น่าแปลกที่การสร้างรายการขึ้นใหม่นั้นสั้นกว่าการแบ่งอินพุต


1

ทุบตีบริสุทธิ์111 94

81สำหรับการแยกเท่านั้น:

for i;do [ "${b[i]}" == 7 ]&&c+=("${d# }") d=||d+=\ $i;b[i]+=7;done;c+=("${d# }")
declare -p c

บรรทัดที่สองdeclare -p cเพิ่งทิ้งตัวแปร

ตัวอย่าง:

splitIntFunc() {
    local b c d i
    for i;do
        [ "${b[i]}" == 7 ]&&c+=("${d# }") d=||d+=\ $i
        b[i]+=7
      done
    c+=("${d# }")
    declare -p c
}

หมายเหตุ: local b c d iจำเป็นต้องใช้บรรทัดเพื่อการใช้งานฟังก์ชั่นหลายครั้งเท่านั้น

splitIntFunc 2 1 1 2 3 2 2 4 5 6 7 3 7 0 5
declare -a c='([0]="2 1" [1]="" [2]="3 2 2 4 5 6 7" [3]="" [4]="0" [5]="")'

splitIntFunc 2 1 1 1 4 5 6
declare -a c='([0]="2 1" [1]="1 4 5 6")'

splitIntFunc $(sed 's/./& /g;w/dev/stderr' <<<${RANDOM}${RANDOM}${RANDOM})
1 6 5 3 2 2 4 3 9 4 2 9 7 7 4 
declare -a c='([0]="1 6 5 3 2" [1]="4" [2]="9" [3]="2" [4]="7" [5]="4")'

splitIntFunc $(sed 's/./& /g;w/dev/stderr' <<<${RANDOM}${RANDOM}${RANDOM})
2 4 5 2 9 1 1 4 8 7 8 1 0 3 
declare -a c='([0]="2 4 5" [1]="9 1" [2]="" [3]="8 7" [4]="1 0 3")'

สำหรับการนำเสนอที่เซ็กซี่ที่สุด (+26)

splitIntFunc() {
    local b c d i
    for i;do
        [ "${b[i]}" == 7 ]&&c+=("${d# }") d=||d+=\ $i
        b[i]+=7
      done
    c+=("${d# }")
    printf -v l "(%s) " "${c[@]}"
    echo "<$l>"

จะทำให้คล้าย:

splitIntFunc 2 1 1 2 3 2 2 4 5 6 7 3 7 0 5
<(2 1) () (3 2 2 4 5 6 7) () (0) () >

splitIntFunc $(sed 's/./& /g;w/dev/stderr' <<<${RANDOM}${RANDOM}${RANDOM})
4 3 8 1 4 5 7 9 2 7 8 4 0 
<(4 3 8 1) (5 7 9 2) () (4 0) >

splitIntFunc $(sed 's/./& /g;w/dev/stderr' <<<${RANDOM}${RANDOM}${RANDOM})
3 1 3 0 2 5 3 6 6 9 2 5 5 
<(3 1) (0 2 5 3 6) (9) () (5) >

splitIntFunc $(sed 's/./& /g;w/dev/stderr' <<<${RANDOM}${RANDOM}${RANDOM})
2 2 2 9 1 9 5 0 2 2 7 6 5 4 
<(2) (2 9 1) (5 0 2 2 7 6) (4) >


}

0

สกาลา, 122 111

คอลเลกชันใช้ตัวอักษรพิมพ์ในรูปแบบของ[21][][3224567][][0][], 122 111:

def s(a:Any*)=print((("[","")/:a){case((b,c),d)=>if(b.indexOf(d)==c.indexOf(d))(b+d,c)else(b+"][",c+d)}._1+"]")

... หรือรับชุดอักขระและส่งกลับรายการซ้อนกัน135 129:

def s(a:Char*)=(("",List(List[Any]()))/:a){case((b,c),d)=>b+d->(if(b.count(d==)==1)List()::c else(c.head:+d)::c.tail)}._2.reverse

ฉันแน่ใจว่ามีเงินออมบางส่วนที่ฉันจะได้รับฉันไม่ได้ดูหนักเกินไป


0

Python 220 ไบต์

ด้านล่างคือ 220 ไบต์ซึ่งไม่ดีมากเมื่อเทียบกับคนอื่น ๆ แต่วิ่งเร็วพอกับจำนวนเต็มขนาดใหญ่!

xlist = list(input()); result = []; x = 0
for i in range(len(xlist)):
    if xlist[0:i+1].count(xlist[i]) == 2: result.append(xlist[x:i]);x = i+1
    elif i == len(xlist)-1: result.append(xlist[x:])
print(result)

สวัสดีและยินดีต้อนรับสู่ PPCG! อย่างไรก็ตามรหัสของคุณยังไม่สั้นพอ ฉันเห็นสถานที่บางแห่งที่คุณสามารถย่อให้สั้นลงได้ โปรดเล่นกอล์ฟต่อไป
Rɪᴋᴇʀ

สวัสดี! หากคุณต้องการความช่วยเหลือในการเล่นกอล์ฟคุณสามารถลบช่องว่างรอบ=การเปลี่ยนแปลงxlistและresultชื่อที่สั้นกว่าและลบช่องว่างรอบ ๆ==, และ; :หากคุณต้องการความช่วยเหลือเพิ่มเติมเพียงพิมพ์@NoOneIsHere(หรือชื่อผู้ใช้) และฉัน / ผู้ใช้จะพยายามช่วย
NoOneIsHere ที่

-1

Java: 563 ไบต์

โปรดทราบว่านี่ใช้ Java 8 pre-JDK8 จะมีความยาวไม่กี่ไบต์เนื่องจาก foreach

import java.util.*;public class a{static String c(String[]b){List<String>d=new ArrayList<>(Arrays.asList(b));Set<String>e=new HashSet<>();Set<String>f=new HashSet<>();for(int i=0;i<Integer.MAX_VALUE;i++){String g;try{g=d.get(i);}catch(IndexOutOfBoundsException ex){break;}
if(e.contains(g)&&!f.contains(g)){d.remove(i);d.add(i,"]");d.add(i+1,"[");f.add(g);i++;}else{e.add(g);}}
d.add(0,"[[");d.add(d.size(),"]]");StringBuilder sb=new StringBuilder();d.forEach(sb::append);return sb.toString();}
public static void main(String[]args){System.out.println(c(args));}}

ฉันสามารถใช้แลมบ์ดาที่ไหน การวนซ้ำจนถึงความยาวของอาร์เรย์ไม่ถูกต้องเนื่องจากรายการจะขยายตัวตามที่คุณเพิ่ม "]" และ "[" เพิ่มเติม
PoweredByRice

การเพิ่มความยาวในแต่ละครั้งนั้นยาวพอ ๆ กับการจับข้อยกเว้นและฉันไม่คิดว่าเป็นไปได้ที่ Java จะเปลี่ยน CEILING ใน (สำหรับ i = 0; i <CEILING; i ++)
PoweredByRice


อืมไม่รู้เหมือนกันขอบคุณที่ชี้ให้เห็น
PoweredByRice

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