Ngắn hơn một giây phân chia!


16

Thử thách

Nhiệm vụ của bạn cho câu hỏi này là phân chia một mảng số nguyên đầu vào trên lần xuất hiện thứ hai của mỗi số nguyên trong mảng đó.

Không đủ rõ ràng? Đây là một ví dụ để giúp đỡ

Mảng đầu vào:

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

Đầu ra:

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

Giải trình:

Đây là mảng chỉ có phần tử thứ hai được tô đậm:

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

Bây giờ chúng ta đặt các khối mảng phân tách xung quanh các lần xuất hiện thứ hai táo bạo này:

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

và bọc các mảng bị tách ra trong một mảng để có được kết quả cuối cùng

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

Lưu ý rằng khi xảy ra lần thứ hai liền kề, sẽ có các mảng trống.

Quy tắc

Như thường lệ, bạn phải viết một chương trình đầy đủ hoặc một hàm lấy mảng đầu vào thông qua STDIN, ARGV hoặc đối số hàm.

Đầu vào

Đầu vào bao gồm bất kỳ định dạng số nguyên (hoặc dạng mảng) thuận tiện nào.

Chẳng hạn, bất kỳ điều nào sau đây sẽ được chấp nhận:

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

Đầu ra

Khi xuất ra STDOUT, mảng của bạn cũng có thể được in ở bất kỳ định dạng mảng (lồng nhau) thuận tiện nào, ví dụ như một trong

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

(Đây thường sẽ là biểu diễn chuỗi gốc của các mảng trong ngôn ngữ của bạn.)

Cũng lưu ý rằng các mảng trống theo dõi nên được in như là một phần của mảng.

Chấm điểm

Đây là để mã ngắn nhất trong byte giành chiến thắng!


@PeterTaylor nhiều câu hỏi cho phép các định dạng khác nhau của mảng trong cả đầu ra và đầu vào.
Tối ưu hóa

5
Điểm cho phép ""là mảng trống là gì? Điều này có mùi của favourism đối với một ngôn ngữ golf cụ ​​thể.
John Dvorak

@JanDvorak Sau khi thảo luận trong trò chuyện, ý định thực sự là bao quát hơn và thường cho phép các ngôn ngữ sử dụng biểu diễn gốc của chúng. Tôi đã chỉnh sửa từ ngữ bây giờ để làm cho rõ ràng hơn.
Martin Ender

1
Tôi chỉ có thể đầu ra 2 1, 1 4 5 6?
jimmy23013

@ user23013 tùy thuộc vào ngôn ngữ bạn đã chọn.
Tối ưu hóa

Câu trả lời:


6

APL 25

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

Thí dụ:

]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│ │
│ └~──┘ └~┘ └~────────────┘ └~┘ └~┘ └~┘ │
└∊──────────────────────────────────────┘

Người già:

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

Đây là một câu hỏi hay cho toán tử khóa () đã được giới thiệu với Dyalog APL v14. Nó nhận hàm đối số bên trái ({1 ↑ 1}) và cung cấp cho từng đối số duy nhất, các chỉ số trong vectơ cho đối số đó. Ở đây tôi đang lấy chỉ số thứ hai, sau đó tôi kiểm tra chỉ số nào có trong danh sách này ((⍳⍴⍵) ∊) và sử dụng boolean kết quả để tách vectơ gốc.

Có thể dùng thử trực tuyến tại đây:

http://tryapl.org


Chỉ trích. Vẫn không dưới 24?
Tối ưu hóa

@Optimizer: 25 ... Tôi đang cố gắng ;-)
Moris Zucca

Chấp nhận điều này thay vì giải pháp của riêng tôi :)
Trình tối ưu hóa

Chỉ 24 và một chức năng phù hợp:1↓¨{1,∨⌿<\2=+\∘.=⍨⍵}⊂1∘,
Adám

không may hoạt động ... omega trong dfn không giống như "a"
Moris Zucca

9

APL (Dyalog 14) (31)

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

Đây là một hàm lấy một mảng và trả về một mảng lồng nhau.

Kiểm tra:

      +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 : ()

Giải trình:

  • 0,⍵: Thêm một 0 vào phía trước của , để xử lý dễ dàng hơn. (Nó không được tính là một sự xuất hiện.)
  • (...)⊂ : Tách mảng theo bitmask đã cho. Một nhóm mới bắt đầu ở mỗi1 bitmask.
    • +\∘.=⍨⍵: cho mỗi giá trị trong (bản gốc) , tìm tất cả các lần xuất hiện trong . Sau đó tạo tổng chạy cho từng giá trị, đưa ra ma trận vuông hiển thị cho từng vị trí trong số lượng từng giá trị đã xảy ra.
    • : Tách ma trận theo các hàng của nó, đưa ra cho mỗi giá trị một mảng hiển thị số lần xảy ra của từng vị trí.
    • 2⍳⍨¨: Trong mỗi mảng này, tìm chỉ mục của đầu tiên 2 .
    • (⍳⍴⍵)∊: Đối với mỗi chỉ mục có thể vào , hãy xem nếu nó được chứa trong danh sách các chỉ số của lần xuất hiện thứ hai. (Những cái này bắt đầu mỗi nhóm, ngoại trừ cái đầu tiên.)
    • 1,: Thêm một 1vào phía trước, đánh dấu sự bắt đầu của nhóm đầu tiên.
  • 1↓¨: Xóa phần tử đầu tiên khỏi mỗi nhóm. (Đây là những bổ sung 0và lần xuất hiện thứ hai của mỗi giá trị.)

8

J, 28 24 char

Đặc biệt cảm ơn ngẫu nhiên .

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

Nó hoạt động như thế này. Trên tất cả các tiền tố ( \) của mảng đầu vào, chúng tôi xem xét có bao nhiêu +/@phần tử ( ) của tiền tố bằng với phần tử cuối cùng ( ={:) của tiền tố đó. Khi số này là 2, chúng tôi biết đây là lần xuất hiện thứ hai của mục đó trong mảng, vì vậy chúng tôi chia mảng ở đó bằng cách sử dụng <;._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

Điều cũ bằng cách sử dụng thủ thuật sắp xếp : (1&,<;._1~1,1=i.~(]-{)/:@/:).


(1&,<;._1~1,2=+/@(={:)\)ngắn hơn 4 byte và đơn giản hơn rất nhiều. ( /:@/:là một mẹo hay mặc dù vậy.)
Randomra

7

Toán học, 58 51 49 byte

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

Đây là một chức năng chưa được đặt tên có một danh sách như

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

và trả về một danh sách lồng nhau như

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

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

Điều này sử dụng một số phép thuật khá tối nghĩa với SplitBy .

Tôi đang theo dõi sự xuất hiện của mỗi số trong một hàm f . Trong Mathematica, bạn có thể xác định giá trị của hàm cho từng đầu vào một cách riêng biệt và bạn không cần chỉ định giá trị cho tất cả các đầu vào có thể (giống như bảng băm trên steroid).

Vì vậy, tôi bắt đầu bằng cách khởi tạo fvề 0 cho các giá trị có trong đầu vào với(f@#=0;#)&/@ .

Bây giờ SplitBylấy một danh sách và một hàm và "chia danh sách thành các danh sách con bao gồm các phần tử liên tiếp có cùng giá trị khi fđược áp dụng" (lưu ý SplitBykhông loại bỏ bất kỳ phần tử nào). Nhưng sản phẩm khai thác (không có giấy tờ) là, fđược gọi hai lần cho mỗi yếu tố - khi so sánh nó với người tiền nhiệm và người kế nhiệm của nó. Vì vậy, nếu chúng ta làm

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

chúng tôi không chỉ nhận được mỗi số một lần, mà thay vào đó là bản in này

 1
 2
 2
 3
 3
 4

đó là 6 cuộc gọi cho 3 so sánh.

Chúng ta có thể phân chia danh sách trước mỗi lần xuất hiện thứ hai, nếu chúng ta viết một hàm luôn trả về Falsenhưng trả về Truekhi lần xuất hiện thứ hai được so sánh với phần tử trước nó. Đó là kiểm tra thứ ba về yếu tố đó (hai kiểm tra về lần xuất hiện đầu tiên, cộng với kiểm tra đầu tiên về lần xuất hiện thứ hai). Do đó, chúng tôi sử dụng ++f[#]==3&. Điều tuyệt vời là điều này đã trở Falselại một lần nữa trong lần kiểm tra thứ hai về lần xuất hiện thứ hai, để tôi có thể quay lại Truelần thứ hai liên tiếp, nhưng vẫn bị tách ra giữa chúng . Tương tự, điều này sẽ không phân tách sau lần xuất hiện thứ hai, bởi vì chức năng đã trở Falselại lần nữa trong lần kiểm tra thứ hai.

Bây giờ, câu hỏi muốn chúng tôi cũng loại bỏ những lần xuất hiện thứ hai đó, vì vậy chúng tôi bỏ phần tử đầu tiên khỏi mỗi danh sách, với Rest/@. Nhưng tất nhiên, chúng tôi không muốn loại bỏ phần tử đầu tiên trong đầu vào, vì vậy chúng tôi thực sự bắt đầu, bằng cách thêm một phần tử avào đầu danh sách {a}~Join~#. alà một biến không xác định, mà Mathicala chỉ coi là một ẩn số, vì vậy nó sẽ không ảnh hưởng đến bất kỳ giá trị nào khác của f. Điều này cũng đảm bảo rằng phần tử thực tế đầu tiên trong đầu vào có hai kiểm tra giống như mọi phần tử khác.


Điều đó khá thông minh. Bạn cũng thực sự không cần Booleở đó.
swish

@swish Ah, cảm ơn vì đã nhắc nhở tôi ... Tôi nhận thấy rằng khi ở trên di động, nhưng muốn kiểm tra nó trước khi thay đổi nó.
Martin Ender

5

Python, 148 byte

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

Giải pháp khá khủng khiếp. Có một cách tốt hơn ...

Gọi với s([2, 1, 1, 1, 4, 5, 6]) .

Phiên bản ung dung

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
Những gì bạn có thể chỉnh sửa trong một phiên bản không chơi gôn? XD 148 ký tự là một dòng rất dài;)
Sean Allred

1
@SeanAllred Tôi không muốn đăng một lời giải thích vì tôi chắc chắn rằng tôi có thể làm tốt hơn, nhưng vì tôi gặp rắc rối nên tôi đã đăng phiên bản không có bản quyền: 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

điều này lưu trữ số lượng mà mọi phần tử xuất hiện cho đến khi một hàm từ các phần tử đến số lượng tương ứng của chúng, đây là một mẹo thú vị.

cái này hoạt động bằng cách sử dụng %, một hàm cung cấp hàm f và một đối số xtrả về một hàm mới trả về fđược áp dụng cho đối số của nó nếu nó khác x1 + f x ngược lại.

ví dụ, 3 % const 0là một hàm trả về 0 cho mọi đối số ngoại trừ 3, nó trả về 1. update: hợp nhất foldlđể có được một chương trình nhỏ hơn nhiều.


Điều này có vẻ thú vị. Bạn có thể cung cấp một phiên bản không linh hoạt?
radomaj


4

Python: 100 byte

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

Giải pháp đơn giản. Tôi lặp lại danh sách, đếm số lần một nhân vật xuất hiện trước đó và nối phần đó kể từ lần kiểm tra cuối cùng vào danh sách đầu ra.


3

Ruby, 66

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

Giải trình

  • elà một Hash của số lần xuất hiện cho mỗi phần tử, rlà một mảng trong đó kết quả được lưu trữ.
  • Lặp lại máng đầu vào, tăng số lần xuất hiện cho mỗi phần tử theo 1.
    • Nếu số lần xuất hiện là 2, chúng ta cần chia. Thêm một khoảng trống Arrayvào kết quả.
    • Nếu không, chỉ cần thêm phần tử vào cuối cùng Arraytrong kết quả.

2
Cái mũ đẹp!! Đợi đã.
Tối ưu hóa

4
Thật là một sự trùng hợp đáng kinh ngạc! Câu trả lời tôi đã đăng vài giây trước khi bạn gần như giống hệt nhau. :)
Cristian Lupascu

Ôi trời, nó thậm chí còn ngắn hơn 1 ký tự!
Anh

Đó là một tiết kiệm bạn có thể dễ dàng áp dụng cho bạn. Tôi nghĩ thật tuyệt vời khi chúng tôi có cùng một ý tưởng cùng một lúc. : D
Cristian Lupascu

3

CJam, 25 24 byte

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

Lấy đầu vào từ STDIN như

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

và đầu ra như

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

Về cơ bản, tôi đang lặp lại tất cả các phần tử của mảng, từng phần một đưa chúng vào một mảng khác. Sau đó, tôi nhận được số phần tử hiện tại trong mảng khác. Nếu là 2, tôi bắt đầu một mảng khác từ vị trí đó. Loại bắt đầu mảng ngẫu nhiên này chỉ có thể đạt được trong một ngôn ngữ dựa trên ngăn xếp.

Mở rộng mã :

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";

Dùng thử trực tuyến tại đây

1 byte được lưu từ mẹo của Martin khi trò chuyện


3

Ruby, 64 byte

s=->a{x=[];b=[[]];a.map{|e|x<<e;x.count(e)==2?b<<[]:b[-1]<<e};b}

3

Perl 5: 36

Không chắc chắn nếu điều này được chấp nhận vì không có sự chia tách thực tế xảy ra ở đây.

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

Thí dụ:

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

Hoàn toàn chấp nhận được.
Tối ưu hóa

Câu trả lời tốt đẹp. Nhưng thực tế tiêu chuẩn, tôi nghĩ, là tính -pahai byte bổ sung (vì nó "chỉ tốn" hai byte, vì bạn có thể viết nó -paethay vì -e). Vậy là 38 chứ không phải 36.
msh210

2

CJam, 28 byte

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

Đưa đầu vào vào STDIN như

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

và in kết quả ra STDOUT như

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

Lưu ý rằng chuỗi rỗng và mảng trống là điều tương tự trong CJam và được hiển thị ""theo mặc định (đây biểu diễn gốc của các mảng trống).

(Tôi đã bắt đầu làm việc này một chút trước khi thử thách được đăng, bởi vì chúng tôi đã thảo luận về việc thử thách sẽ khó khăn như thế nào.)

Giải trình

Về cơ bản, tôi đang sao chép từng phần tử trong mảng, trừ khi đó là lần xuất hiện thứ hai, trong trường hợp đó tôi thay thế bản sao đầu tiên bằng một khoảng trắng. Vì lý do chơi gôn, mảng sửa đổi này được xây dựng ngược lại. Vì vậy, [2 1 1 2 3 2 3]trở thành

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

Sau đó, tôi chọn ra mọi phần tử thứ hai từ cuối, đó là mảng ban đầu, nhưng với lần xuất hiện thứ hai được thay thế bằng khoảng trắng, nghĩa là

[2 1 S S 3 2 S]

Cuối cùng, tôi chỉ đơn giản là phân chia mảng trên không gian. Đây là một sự cố của mã:

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.";

Vì đây là thử thách của riêng tôi, tôi sẽ đưa ra một cơ hội đầu tiên: P. Tôi có một giải pháp Cjam 25 byte với tôi.
Tối ưu hóa

Không hiển thị mảng trống chính xác - rõ ràng không hợp lệ!
frageum

1
@feersum hiển thị các mảng trống như ""được cho phép rõ ràng trong lần sửa đổi đầu tiên của câu hỏi. Bản sửa đổi hiện tại nêu rõ "bất kỳ định dạng thuận tiện nào ... thường là sự phục hồi chuỗi gốc của mảng".
John Dvorak

2

Công cụ Unix, 100 byte

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

Chấp nhận đầu vào thông qua stdin. Nó về cơ bản chỉ thay thế mỗi lần xuất hiện thứ hai với "] [". Không hoạt động với các chuỗi rỗng, []sẽ cung cấp một chuỗi trống, mà tôi nghĩ là một đại diện thuận tiện của một mảng trống :)


Vâng, sau đó câu trả lời là không đáp ứng thông số kỹ thuật, phải không? (về số nguyên âm). Còn nữa thì 11sao? nó sẽ được chuyển đổi thành 1][?
Tối ưu hóa

Nó hoạt động tốt cho 11, nhưng bạn đã đúng về các số âm, đã sửa nó và giờ đây nó cũng chấp nhận các mảng đơn.
pgy

2

APL, 42 ký tự

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

Thí dụ:

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

Đầu ra:

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

Đã thử nghiệm ở đây.

Nếu tôi phải xuất một chuỗi được hiểu chính xác là cấu trúc đúng trong APL ... 49 ký tự

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

Làm thế nào là một danh sách lồng nhau thực sự được đại diện trong APL? Có thể bạn không cần phải thực hiện thao tác chuỗi
Trình tối ưu hóa

@Optimizer Chuỗi đầu ra là một danh sách hợp lệ trong chương trình APL. Tuy nhiên, nó sẽ không được lồng nếu chỉ có một danh sách trong đó. Chuẩn bị một cái 1↓1dường như để khắc phục vấn đề, nhưng điều đó có vẻ quá kỳ lạ.
jimmy23013

2

Java, 223

Điều này chỉ hoạt động trên Oracle hoặc OpenJDK JRE, vì tôi sử dụng cách giải quyết vấn đề này trong việc thực hiện định lượng và kiểm tra độ dài của chúng để xem phía sau để thực hiện nhìn phía sau có độ dài thay đổi.

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).*) *","] [")+"]");}}

Hầu hết các công việc được thực hiện trong regex, được hiển thị dưới đây ở dạng thô:

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

Trước khi chúng ta xem xét regex ở trên, chúng ta hãy xem xét regex .NET tương đương, đơn giản hơn, vì nó trực tiếp hỗ trợ nhìn phía sau có độ dài thay đổi (nhìn từ phía sau rất có thể được thực hiện bởi chế độ khớp từ phải sang trái) :

 *\b(\d+)\b(?<=(.*\b\1\b){2})(?<!(.*\b\1\b){3}) *
  •  *\b(\d+)\b *ở cuối khớp với một số và các khoảng trống xung quanh (nếu có). Các kiểm tra ràng buộc là để ngăn chặn một phần số được khớp, vì khoảng trắng ở cả hai bên là tùy chọn. Nó cũng chụp số để kiểm tra xem nó có xuất hiện lần thứ 2 trong mảng không.

  • (?<=(.*\b\1\b){2})kiểm tra xem có thể tìm thấy 2 trường hợp của số được chụp ở trên không. (?<!(.*\b\1\b){3})kiểm tra rằng không có 3 trường hợp của số bị bắt có thể được tìm thấy. Cả hai điều kiện kết hợp đều khẳng định rằng chỉ có 2 trường hợp số. Các kiểm tra ràng buộc ở đó để đảm bảo toàn bộ số được kiểm tra.

Quay lại phiên bản Java. Để thực hiện nhìn chiều dài thay đổi phía sau, chúng tôi chuyển đổi

(?<=var-length-pattern)

đến

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

Tôi hơi vẫy tay về thực tế rằng . loại trừ các dấu phân cách dòng, nhưng nó có thể được sửa một cách dễ dàng và tôi không muốn làm phức tạp thêm cú pháp.

Nhìn về phía trước luôn có độ dài 0 và kiểm tra độ dài vượt qua do việc thực hiện * định lượng.

Điều ^này là không cần thiết để làm cho nó hoạt động, nhưng nó ở đó để làm cho trường hợp thất bại thất bại nhanh hơn. Nhìn lại phía sau trong triển khai Oracle / OpenJDK được thực hiện bằng cách lùi lại độ dài tối thiểu của mẫu, sau đó khớp, sau đó rửa và lặp lại bằng cách tăng độ dài cho đến khi tìm thấy kết quả khớp, hoặc trong trường hợp xấu nhất, đến độ dài tối đa của mẫu . Với^ , tôi chắc chắn rằng chuỗi tiền tố chỉ được khớp một lần.

Tuy nhiên, cái nhìn phía trước bên trong cái nhìn phía sau không bị giới hạn bởi ranh giới bên phải của cái nhìn phía sau, vì vậy nó có thể khớp tất cả các con đường đến cuối chuỗi. Để khẳng định ranh giới, tôi chụp phần còn lại của chuỗi vào một nhóm bắt khác trong một cái nhìn phía trước và sử dụng nó để giới hạn sự thống trị của mẫu có độ dài thay đổi.

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

Vì mô hình của tôi đã bắt đầu với .*, tôi không cần phải thêm một mẫu khác .*ở phía trước.


1

Perl 108

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

Trong hành động:

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

Lưu ý: Hai dòng đầu tiên $Data::...chỉ có để trình bày đẹp hơn và dòng thứ ba @a=@b=@e=();ở đó để làm cho công cụ hoạt động trên nhiều dòng.


1

R, 76

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

Đầu ra cho ví dụ: Một danh sách gồm năm phần tử, bao gồm ba vectơ trống. ( 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)

Nhân tiện: Mã tạo ra một thông điệp cảnh báo có thể bỏ qua.


1

ôi 29

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

Điều này có một chút tự do với các định dạng đầu vào và đầu ra. "Mảng" đầu vào là dọc, một số trên mỗi dòng. Đầu ra cũng là dọc, một số trên mỗi dòng, với các dấu gạch ngang ngăn cách.

Đầu vào:

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

Đầu ra:

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

1

Pyth 30 32

Đây là lần đầu tiên tôi thử nghiệm với Pyth. Đó là giải pháp tương tự như trong giải pháp Python của tôi.

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

Bạn có thể dùng thử trực tuyến: Trình biên dịch / thực thi Pyth

Ví dụ: Đầu vào

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

sẽ in

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

Giải trình:

                                 # 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:]]

Có một sự thay thế tốt hơn cho =Y+Y...?
Jakube

đây là -~Y...
Trình tối ưu hóa

1

Con trăn 2, 84

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

Danh sách lnày là đầu ra cho đến nay. Chúng tôi lặp đi lặp lại các yếu tố. Nếu cái hiện tại là sự xuất hiện thứ hai, chúng ta bắt đầu một danh sách con trống mới; mặt khác, chúng tôi thêm nó vào danh sách con mới nhất. Danh sách các yếu tố nhìn thấy cho đến nay được lưu trữ trong p. Kỳ lạ thay, việc xây dựng lại danh sách dường như ngắn hơn cắt lát đầu vào.


1

Bash tinh khiết 111 94

81 chỉ chia tách:

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

Dòng thứ hai declare -p cchỉ bán biến

Mẫu vật:

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
}

Lưu ý: dòng local b c d ichỉ được yêu cầu để chạy chức năng nhiều lần.

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")'

Để trình bày gợi cảm nhất (+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>"

Sẽ hiển thị một cái gì đó như:

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

Scala, 122 111

Lấy bộ sưu tập nhân vật, in dưới dạng [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+"]")

... hoặc lấy một bộ sưu tập nhân vật và trả về các danh sách lồng nhau, 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

Tôi chắc chắn có một số tiền tiết kiệm tôi có thể nhận được, tôi đã không nhìn quá khó khăn.


0

Python 220 byte

Dưới đây là 220 byte không tuyệt vời so với nhiều loại khác nhưng chạy đủ nhanh với số nguyên lớn hơn!

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)

Xin chào, và chào mừng đến với PPCG! Tuy nhiên, mã của bạn không thực sự đủ ngắn. Tôi thấy một số nơi mà bạn chắc chắn có thể rút ngắn nó. Hãy tiếp tục chơi golf.
Rɪᴋᴇʀ

Xin chào! Nếu bạn cần sự giúp đỡ chơi golf, bạn có thể loại bỏ các khoảng trống xung quanh =, thay đổi xlistresultđể tên ngắn hơn, và loại bỏ không gian xung quanh ==, ;:. Nếu bạn cần thêm trợ giúp, chỉ cần nhập @NoOneIsHere(hoặc bất kỳ tên người dùng nào) và tôi / người dùng sẽ cố gắng giúp đỡ.
NoOneIsHãy

-1

Java: 563 byte

lưu ý điều này sử dụng Java 8, tiền JDK8 sẽ dài hơn một vài byte do 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));}}

Tôi có thể sử dụng lambda ở đâu nữa? lặp cho đến khi độ dài của mảng không chính xác vì danh sách tiếp tục mở rộng khi bạn thêm nhiều "]" và "[".
PoweredByRice

tăng độ dài mỗi lần cũng dài như bắt ngoại lệ, tôi cũng không nghĩ rằng Java có thể thay đổi CEILING trong (đối với i = 0; i <CEILING; i ++).
PoweredByRice


hmm không biết điều đó, cảm ơn vì đã chỉ ra
PoweredByRice

Còn việc chuyển đổi Integer.MAX_VALUEthành 2147483647gì? Đó là cùng một giá trị với ít byte hơn. Ngoài ra, IndexOutOfBoundsExceptioncó thể rút ngắn thànhException
Charlie
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.