Lebih Pendek dari Sepersekian Detik!


16

Tantangan

Anda tugas untuk pertanyaan ini adalah untuk membagi input array integer pada kemunculan kedua setiap integer dalam array itu.

Tidak cukup jelas? Ini adalah contoh untuk membantu

Array input:

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

Keluaran:

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

Penjelasan:

Berikut ini array dengan elemen kedua yang disorot dalam huruf tebal:

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

Sekarang kita menempatkan blok array pemisah di sekitar kejadian kedua yang tebal ini:

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

dan bungkus array yang terpecah ini dalam array untuk mendapatkan final

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

Perhatikan bahwa ketika kejadian kedua yang berdekatan terjadi, akan ada array kosong.

Aturan

Seperti biasa, Anda harus menulis program lengkap atau fungsi yang mengambil array input melalui STDIN, ARGV atau argumen fungsi.

Memasukkan

Input terdiri atas format bilangan bulat array yang nyaman (atau mirip array).

Misalnya, salah satu dari yang berikut ini dapat diterima:

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

Keluaran

Saat mengeluarkan ke STDOUT, array Anda juga dapat dicetak dalam format array yang nyaman (bersarang), mis. Salah satunya

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

(Ini biasanya akan menjadi representasi string asli dari array dalam bahasa Anda.)

Perhatikan juga bahwa trailing array kosong harus dicetak sebagai bagian dari array.

Mencetak gol

Ini adalah sehingga kode terpendek dalam byte menang!


@PeterTaylor banyak pertanyaan memungkinkan untuk berbagai format array di kedua output dan inputl.
Pengoptimal

5
Apa gunanya membiarkan ""sebagai array kosong? Ini berbau favorit menuju bahasa golf tertentu.
John Dvorak

@JanDvorak Setelah diskusi dalam obrolan, maksudnya sebenarnya untuk menjadi lebih inklusif dan umumnya memungkinkan bahasa untuk menggunakan representasi asli mereka. Saya telah mengedit kata-katanya sekarang untuk membuatnya lebih jelas.
Martin Ender

1
Bisakah saya output saja 2 1, 1 4 5 6?
jimmy23013

@ user23013 tergantung pada bahasa yang Anda pilih.
Pengoptimal

Jawaban:


6

APL 25

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

Contoh:

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

Yang lama:

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

Ini adalah pertanyaan yang bagus untuk operator utama (⌸) yang diperkenalkan dengan Dyalog APL v14. Dibutuhkan fungsi argumen kiri ({1 ↑ 1 ↓ ⍵}) dan memberikannya untuk setiap argumen unik, indeks dalam vektor untuk argumen itu. Di sini saya mengambil indeks kedua, lalu saya memeriksa indeks mana yang ada dalam daftar ini ((⍳⍴⍵) ∊) dan menggunakan boolean yang dihasilkan untuk memisahkan vektor asli.

Dapat dicoba online di sini:

http://tryapl.org


Sial. Masih tidak kurang dari 24?
Pengoptimal

@Optimizer: 25 ... Saya mencoba ;-)
Moris Zucca

Menerima ini alih-alih solusi saya sendiri :)
Pengoptimal

Hanya 24, dan fungsi yang tepat:1↓¨{1,∨⌿<\2=+\∘.=⍨⍵}⊂1∘,
Ad

sayangnya tidak berfungsi ... omega di dfn tidak sama dengan "a"
Moris Zucca

9

APL (Dyalog 14) (31)

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

Ini adalah fungsi yang mengambil array dan mengembalikan array bersarang.

Uji:

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

Penjelasan:

  • 0,⍵: Tambahkan 0ke depan , untuk pemrosesan lebih mudah. (Itu tidak dihitung sebagai kejadian.)
  • (... )⊂: Bagi array sesuai dengan bitmask yang diberikan. Grup baru dimulai di 1bitmask masing-masing .
    • +\∘.=⍨⍵: untuk setiap nilai dalam (asli) , temukan semua kemunculan di . Kemudian buat jumlah yang berjalan untuk setiap nilai, dengan memberikan matriks kuadrat yang menunjukkan untuk setiap posisi dalam berapa banyak dari masing-masing nilai yang telah terjadi.
    • : Pisahkan matriks dengan barisnya, berikan untuk setiap nilai sebuah array yang menunjukkan berapa kali itu terjadi pada setiap posisi.
    • 2⍳⍨¨: Di setiap array ini, cari indeks yang pertama 2.
    • (⍳⍴⍵)∊: Untuk setiap kemungkinan indeks , lihat apakah indeks tersebut terdapat dalam daftar indeks kejadian kedua. (Ini memulai setiap grup, kecuali yang pertama.)
    • 1,: Tambahkan 1ke depan, menandai awal dari grup pertama.
  • 1↓¨: Hapus elemen pertama dari setiap grup. (Ini adalah nilai tambah 0, dan kemunculan kedua dari setiap nilai.)

8

J, 28 24 char

Terima kasih khusus kepada randomra .

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

Ini berfungsi seperti ini. Atas semua awalan ( \) dari larik input, kami melihat berapa banyak ( +/@) elemen awalan yang sama dengan elemen terakhir ( ={:) dari awalan itu. Ketika angka ini adalah 2, kita tahu ini adalah kejadian kedua dari item tersebut di dalam array, jadi kita membagi array di sana menggunakan <;._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

Hal lama menggunakan trik semacam: (1&,<;._1~1,1=i.~(]-{)/:@/:).


(1&,<;._1~1,2=+/@(={:)\)lebih pendek 4 byte dan jauh lebih sederhana. ( /:@/:Ini trik yang bagus.)
randomra

7

Mathematica, 58 51 49 byte

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

Ini adalah fungsi yang tidak disebutkan namanya yang mengambil daftar seperti

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

dan mengembalikan daftar bersarang seperti

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

Bagaimana itu bekerja

Ini menggunakan beberapa sihir yang cukup tidak jelas SplitBy.

Saya melacak kemunculan setiap angka dalam suatu fungsi f. Dalam Mathematica, Anda dapat menentukan nilai fungsi untuk setiap input secara terpisah, dan Anda tidak perlu menentukan nilai untuk semua input yang mungkin (ini lebih mirip tabel hash tentang steroid).

Jadi saya mulai dengan menginisialisasi fke 0 untuk nilai-nilai yang ada di input dengan (f@#=0;#)&/@.

Sekarang SplitBymengambil daftar dan fungsi dan "membagi daftar menjadi sublists yang terdiri dari menjalankan elemen berturut-turut yang memberikan nilai yang sama ketika fditerapkan" (catatan yang SplitBytidak menghapus elemen apa pun). Tapi tangkapan (tidak terdokumentasi) adalah, yang fdisebut dua kali pada setiap elemen - ketika membandingkannya dengan pendahulunya dan penggantinya. Jadi jika kita lakukan

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

kami tidak hanya mendapatkan setiap angka satu kali, tetapi malah mencetak ini

 1
 2
 2
 3
 3
 4

yaitu 6 panggilan untuk 3 perbandingan.

Kita dapat membagi daftar sebelum setiap kemunculan kedua, jika kita menulis fungsi yang selalu mengembalikan Falsetetapi kembali Trueketika kemunculan kedua dibandingkan dengan elemen sebelumnya. Itu adalah pemeriksaan ketiga pada elemen itu (dua pemeriksaan pada kejadian pertama, ditambah cek pertama pada kejadian kedua). Karenanya, kami menggunakan ++f[#]==3&. Yang menyenangkan adalah bahwa ini sudah kembali Falselagi pada pemeriksaan kedua dari kejadian kedua, sehingga saya bisa kembali Trueuntuk kejadian kedua berturut-turut, tetapi masih terbagi di antara mereka . Demikian juga, ini tidak akan terpecah setelah kejadian kedua, karena fungsi sudah kembali Falselagi pada pemeriksaan kedua.

Sekarang, pertanyaannya ingin kita juga menghapus kejadian kedua itu, jadi kita lepaskan elemen pertama dari setiap daftar Rest/@. Tapi tentu saja, kami tidak ingin menghapus elemen pertama dalam input, jadi kami benar-benar memulai, dengan menambahkan elemen ake awal daftar {a}~Join~#. aadalah variabel yang tidak terdefinisi, yang Mathematica hanya memperlakukan sebagai tidak diketahui, sehingga tidak akan memengaruhi nilai lain dari f. Ini juga memastikan bahwa elemen aktual pertama dalam input mendapatkan dua pemeriksaannya seperti setiap elemen lainnya.


Itu cukup pintar. Anda juga sebenarnya tidak perluBoole di sana.
desir

@berharap Ah, terima kasih sudah mengingatkan saya ... Saya perhatikan itu di ponsel, tetapi ingin mengujinya sebelum mengubahnya.
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)]

Solusi yang cukup menghebohkan. Pasti ada cara yang lebih baik ...

Panggil dengan s([2, 1, 1, 1, 4, 5, 6]).

Versi tidak disatukan

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
Apa itu apa ... Bisakah Anda mengedit dalam versi tidak golf? XD 148 karakter adalah garis yang sangat panjang;)
Sean Allred

1
@SeanAllred Saya tidak ingin memposting penjelasan karena saya yakin saya bisa melakukan yang lebih baik, tetapi karena saya mengalami masalah, saya telah memposting versi yang tidak diklik: 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

ini menyimpan jumlah setiap elemen yang muncul sejauh fungsi dari elemen ke jumlah masing-masing, yang merupakan trik yang menarik.

ini berfungsi menggunakan %, fungsi yang diberi fungsi f dan argumen xmengembalikan fungsi baru yang mengembalikanf diterapkan ke argumen itu jika berbeda dari x, dan 1 + f xsebaliknya.

misalnya, 3 % const 0adalah fungsi yang mengembalikan 0 untuk setiap argumen kecuali 3, yang mengembalikan 1. pembaruan: menyatu foldluntuk mendapatkan program yang jauh lebih kecil.


Ini terlihat menarik. Bisakah Anda memberikan versi tanpa ungolfed?
radomaj

4

Demo Ruby 66

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

Ruby lambda yang stabil, yang menggunakan array sebagai parameter dan mengembalikan array.


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

Solusi mudah. Saya mengulangi daftar, menghitung berapa kali karakter muncul sebelumnya, dan menambahkan bagian sejak cek terakhir ke daftar output.


3

Ruby, 66

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

Penjelasan

  • e adalah hasrat jumlah kejadian untuk setiap elemen, r adalah Array di mana hasilnya disimpan.
  • Loop melalui input, menambah jumlah kejadian untuk setiap elemen dengan 1 .
    • Jika jumlah kejadiannya adalah 2, kita perlu membagi. Tambahkan yang kosong Arrayke hasilnya.
    • Kalau tidak, tambahkan saja elemen ke hasil terakhir Array.

2
Topi yang bagus!! Oh tunggu.
Pengoptimal

4
Suatu kebetulan yang luar biasa! The jawaban saya diposting detik sebelum Anda hampir identik. :)
Cristian Lupascu

Ya ampun, ini bahkan 1 karakter lebih pendek!
britishtea

Ini adalah penghematan yang dapat Anda terapkan dengan mudah ke milik Anda. Saya pikir itu luar biasa bahwa kami memiliki ide yang sama pada saat yang bersamaan. : D
Cristian Lupascu

3

CJam, 25 24 byte

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

Mengambil input dari STDIN seperti

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

dan output seperti

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

Saya pada dasarnya mengulangi semua elemen array, satu per satu menempatkan mereka ke array lain. Lalu saya mendapatkan hitungan elemen saat ini di array lain. Jika 2, saya mulai array lain dari lokasi itu. Jenis awal array acak ini hanya dapat dicapai dalam bahasa berbasis stack.

Perluasan kode :

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

Cobalah online di sini

1 byte disimpan dari tip Martin saat mengobrol


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

Tidak yakin apakah ini dapat diterima karena tidak ada pemisahan yang sebenarnya terjadi di sini.

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

Contoh:

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

Benar-benar dapat diterima.
Pengoptimal

Jawaban bagus. Tetapi praktik standar, saya pikir, adalah untuk menghitung -pasebagai dua byte tambahan (karena "biaya" hanya dua byte, karena Anda dapat menuliskannya sebagai -paeganti -e). Jadi itu 38, bukan 36.
msh210

2

CJam, 28 byte

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

Mengambil input dari STDIN seperti

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

dan mencetak output ke STDOUT suka

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

Perhatikan bahwa string kosong dan array kosong adalah hal yang sama di CJam, dan ditampilkan sebagai ""default (ini adalah representasi asli dari array kosong).

(Saya mulai mengerjakan ini sedikit sebelum tantangan dipasang, karena kami sedang mendiskusikan betapa sulitnya tantangan itu.)

Penjelasan

Pada dasarnya, saya menduplikasi setiap elemen dalam array, kecuali itu kejadian kedua, dalam hal ini saya mengganti salinan pertama dengan spasi. Untuk alasan bermain golf, array yang dimodifikasi ini dibuat secara terbalik. Jadi [2 1 1 2 3 2 3]menjadi

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

Lalu saya memilih setiap elemen kedua dari ujung, yang merupakan array asli, tetapi dengan kejadian kedua digantikan oleh spasi, yaitu

[2 1 S S 3 2 S]

Akhirnya, saya cukup membagi array pada spasi. Berikut ini adalah rincian kode:

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

Karena ini adalah tantangan saya sendiri, saya memberikan kesempatan pertama: P. Saya memiliki solusi Cjam 25 byte dengan saya.
Pengoptimal

Tidak menampilkan array kosong dengan benar - jelas tidak valid!
feersum

1
@feersum menampilkan array kosong seperti ""yang secara eksplisit diizinkan dalam revisi pertama pertanyaan. Revisi saat ini menyatakan "format apa pun yang nyaman ... biasanya reparasi string asli array".
John Dvorak

2

Alat Unix, 100 byte

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

Kecuali input melalui stdin. Ini pada dasarnya hanya menggantikan setiap kejadian dengan "] [". Tidak bekerja dengan string kosong, []akan memberikan string kosong, yang menurut saya merupakan representasi nyaman dari array kosong :)


Nah, maka jawabannya tidak memenuhi spek, kan? (tentang bilangan bulat negatif). Juga, bagaimana 11? apakah akan dikonversi 1][?
Pengoptimal

Ini bekerja dengan baik untuk 11, tetapi Anda benar tentang angka negatif, memperbaikinya, dan sekarang juga menerima array tunggal.
pgy

2

APL, 42 karakter

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

Contoh:

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

Keluaran:

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

Diuji di sini.

Jika saya harus menampilkan string yang ditafsirkan persis sebagai struktur yang tepat di APL ... 49 karakter

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

Bagaimana daftar bersarang benar-benar terwakili dalam APL? Mungkin Anda mungkin tidak perlu melakukan manipulasi string
Pengoptimal

@Optimizer String yang dihasilkan adalah daftar yang valid dalam program APL. Namun itu tidak akan disarangkan jika hanya ada satu daftar di dalamnya. Prepending a 1↓1sepertinya memperbaiki masalah, tetapi itu terlihat terlalu aneh.
jimmy23013

2

Jawa, 223

Ini hanya bekerja pada Oracle atau OpenJDK JRE, karena saya menggunakan kekhasan ini dalam penerapan kuantifier dan panjang memeriksa dalam melihat-belakang untuk mengimplementasikan variabel-panjang melihat-belakang.

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

Sebagian besar pekerjaan dilakukan di regex, yang ditunjukkan di bawah ini dalam bentuk mentah:

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

Sebelum kita melihat regex di atas, mari kita lihat ekuivalen .NET regex, yang lebih sederhana, karena secara langsung mendukung variabel-panjang melihat-belakang (. NET melihat-balik kemungkinan besar dilakukan oleh mode pencocokan kanan-ke-kiri) :

 *\b(\d+)\b(?<=(.*\b\1\b){2})(?<!(.*\b\1\b){3}) *
  •  *\b(\d+)\b dan  * pada akhirnya cocok dengan angka dan ruang di sekitarnya (jika ada). Cek terikat adalah untuk mencegah pencocokan nomor parsial, karena spasi di kedua sisi adalah opsional. Ini juga menangkap nomor untuk memeriksa apakah ini adalah penampilan ke-2 dalam array.

  • (?<=(.*\b\1\b){2}) memeriksa 2 contoh nomor yang ditangkap di atas dapat ditemukan. (?<!(.*\b\1\b){3})memeriksa bahwa tidak ada 3 contoh nomor yang ditangkap dapat ditemukan. Kedua kondisi yang digabungkan menyatakan bahwa hanya ada 2 contoh dari jumlah sejauh ini. Cek terikat ada untuk memastikan seluruh nomor diuji.

Kembali ke versi Java. Untuk mengimplementasikan tampilan panjang variabel di belakang, kami mentransformasikannya

(?<=var-length-pattern)

untuk

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

Saya sedikit melambaikan tangan tentang fakta itu . mengecualikan pemisah garis, tetapi bisa diperbaiki dengan mudah dan saya tidak ingin memperumit sintaksis lebih lanjut.

Panjang melihat-depan selalu 0, dan cek panjang melewati karena implementasi * kuantifier.

Itu ^ tidak perlu untuk membuatnya bekerja, tetapi itu ada untuk membuat kasus gagal gagal lebih cepat. Lihat-belakang dalam implementasi Oracle / OpenJDK dilakukan dengan melangkah mundur dari panjang minimum pola, kemudian mencocokkan, kemudian membilas dan ulangi dengan menambah panjang sampai kecocokan ditemukan, atau dalam kasus terburuk, hingga panjang maksimum dari pola . Dengan^ , saya memastikan string awalan hanya cocok sekali.

Namun, melihat-depan di dalam melihat-belakang tidak dibatasi oleh batas-kanan melihat-belakang, sehingga dapat mencocokkan semua jalan sampai akhir string. Untuk menegaskan batas, saya menangkap sisa string ke grup menangkap lain di dalam melihat ke depan, dan menggunakannya untuk membatasi pemerintahan pola panjang variabel.

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

Karena pola saya sudah dimulai .*, saya tidak perlu menambahkan yang lain .*di depan.


1

Perl 108

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

Dalam aksi:

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

Catatan: Dua baris pertama $Data::...hanya ada untuk presentasi yang lebih bagus dan baris ketiga @a=@b=@e=();ada untuk membuat alat bekerja pada banyak baris.


1

R, 76

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

Output untuk contoh: Daftar lima elemen, termasuk tiga vektor kosong. ( 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)

Ngomong-ngomong: Kode menghasilkan pesan peringatan yang dapat diabaikan.


1

awk 29

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

Ini membutuhkan sedikit kebebasan dengan format input dan output. Input "array" adalah vertikal, satu angka per baris. Output juga vertikal, satu angka per baris, dengan tanda hubung memisahkan array.

Memasukkan:

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

Keluaran:

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

1

Pyth 30 32

Ini adalah pertama kalinya saya bereksperimen dengan Pyth. Ini solusi yang sama seperti pada solusi Python saya.

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

Anda dapat mencobanya secara online: Pyth Compiler / Executor

Misalnya input

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

akan dicetak

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

Penjelasan:

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

Apakah ada alternatif yang lebih baik =Y+Y...?
Jakube

ini adalah -~Y...
Pengoptimal

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

Daftar lini adalah output sejauh ini. Kami beralih pada elemen. Jika yang sekarang adalah penampilan kedua, kami memulai sublist kosong baru; jika tidak, kami menambahkannya ke sublist terbaru. Daftar elemen yang dilihat sejauh ini disimpan di p. Anehnya, merekonstruksi daftar tampaknya lebih pendek daripada memotong input.


1

Bash murni 111 94

81 hanya untuk pemisahan:

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

Baris kedua declare -p chanya membuang variabel

Sampel:

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
}

Catatan: garis local b c d ihanya diperlukan untuk menjalankan fungsi beberapa kali.

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

Untuk presentasi terseksi (+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>"

Akan membuat sesuatu seperti:

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

Ambil koleksi karakter, cetak dalam bentuk [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+"]")

... atau ambil koleksi karakter dan kembalikan daftar yang bersarang, 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

Saya yakin ada beberapa penghematan yang bisa saya dapatkan, saya belum terlihat terlalu keras.


0

Python 220 byte

Di bawah ini adalah 220 byte yang tidak bagus dibandingkan dengan banyak yang lain tetapi berjalan cukup cepat dengan bilangan bulat yang lebih besar!

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)

Hai, dan selamat datang di PPCG! Namun, kode Anda tidak cukup pendek. Saya melihat beberapa tempat di mana Anda dapat mempersingkatnya. Silakan lanjutkan bermain golf.
R

Halo! Jika Anda membutuhkan bantuan golf, Anda dapat menghapus ruang di sekitar =, perubahan xlistdan resultnama-nama yang lebih pendek, dan menghapus spasi sekitar ==, ;dan :. Jika Anda memerlukan bantuan lebih lanjut, cukup ketik @NoOneIsHere(atau nama pengguna apa saja) dan saya / pengguna akan mencoba membantu.
NoOneIsHere

-1

Java: 563 byte

perhatikan ini menggunakan Java 8, pra-JDK8 akan menjadi beberapa byte lagi karena 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));}}

di mana lagi saya bisa menggunakan lambda? pengulangan hingga panjang array tidak benar karena daftar terus bertambah saat Anda menambahkan lebih banyak "]" dan "[".
PoweredByRice

menambah panjang setiap kali sama panjangnya dengan menangkap pengecualian, juga saya tidak berpikir itu mungkin di Jawa untuk mengubah CEILING di (untuk i = 0; i <CEILING; i ++).
PoweredByRice


hmm tidak tahu itu, terima kasih sudah menunjukkan.
PoweredByRice

Bagaimana dengan mengonversi Integer.MAX_VALUEke 2147483647? Ini nilai yang sama dengan byte lebih sedikit. Juga, IndexOutOfBoundsExceptiondapat disingkat menjadiException
Charlie
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.