Krótszy niż ułamek sekundy!

16

Wyzwanie

Twoim zadaniem jest podzielenie wejściowej tablicy liczb całkowitych przy drugim wystąpieniu każdej liczby całkowitej w tej tablicy.

Nie dość jasne? Oto przykład, aby pomóc

Tablica wejściowa:

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

Wynik:

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

Wyjaśnienie:

Oto tablica z drugim elementem wyróżnionym pogrubioną czcionką:

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

Teraz umieszczamy bloki tablicy rozdzielającej wokół tych odważnych drugich wystąpień:

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

i zawiń te podzielone tablice do tablicy, aby uzyskać finał

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

Zauważ, że gdy wystąpią sąsiednie drugie wystąpienia, pojawią się puste tablice.

Zasady

Jak zwykle, musisz napisać pełny program lub funkcję, biorąc tablicę wejściową przez STDIN, ARGV lub argument funkcji.

Wejście

Dane wejściowe składają się z dowolnego wygodnego formatu liczb całkowitych (lub podobnego do tablicy).

Na przykład akceptowalny byłby jeden z poniższych:

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

Wynik

Podczas wysyłania do STDOUT, twoja tablica może być również wydrukowana w dowolnym wygodnym (zagnieżdżonym) formacie macierzy, np. Jednym z

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

(Zwykle będzie to natywna reprezentacja ciągu tablic w Twoim języku).

Zwróć także uwagę, że końcowe tablice powinny być drukowane jako część tablicy.

Punktacja

To jest więc wygrywa najkrótszy kod w bajtach!

Optymalizator
źródło
@PeterTaylor wiele pytań dopuszcza różne formaty tablic zarówno wyjściowych, jak i wejściowych.
Optymalizator
5
Po co zezwalać ""na pustą tablicę? To pachnie faworyzowaniem określonego języka golfowego.
John Dvorak,
@JanDvorak Po dyskusji na czacie, intencją było bycie bardziej włączającym i ogólnie pozwalać językom na używanie ich natywnej reprezentacji. Zredagowałem teraz sformułowanie, aby było jaśniejsze.
Martin Ender,
1
Czy mogę po prostu wysyłać 2 1, 1 4 5 6?
jimmy23013,
@ user23013 zależy od wybranego języka.
Optymalizator

Odpowiedzi:

6

APL 25

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

Przykład:

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

Stary:

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

To miłe pytanie dla głównego operatora (⌸), które zostało wprowadzone wraz z Dyalog APL v14. Pobiera funkcję lewego argumentu ({1 ↑ 1 ↓ ⍵}) i podaje jej dla każdego unikalnego argumentu indeksy w wektorze dla tego argumentu. Tutaj biorę drugi indeks, następnie sprawdzam, który z indeksów jest obecny na tej liście ((⍳⍴⍵) ∊) i używam wynikowej wartości logicznej do dzielenia oryginalnego wektora.

Można wypróbować online tutaj:

http://tryapl.org

Moris Zucca
źródło
Cholera. Nadal nie mniej niż 24?
Optymalizator
@Optimizer: 25 ... Próbuję ;-)
Moris Zucca,
Zaakceptowanie tego zamiast własnego rozwiązania :)
Optimizer
Tylko 24 i właściwa funkcja:1↓¨{1,∨⌿<\2=+\∘.=⍨⍵}⊂1∘,
Adám
nie działa niestety ... omega w dfn to nie to samo co „a”
Moris Zucca
9

APL (Dyalog 14) (31)

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

Jest to funkcja, która pobiera tablicę i zwraca tablicę zagnieżdżoną.

Test:

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

Wyjaśnienie:

  • 0,⍵: Dodaj a 0z przodu , aby ułatwić przetwarzanie. (Nie liczy się jako zdarzenie).
  • (... )⊂: Podziel tablicę zgodnie z podaną maską bitową. Nowa grupa zaczyna się na każdej 1w masce bitowej.
    • +\∘.=⍨⍵: dla każdej wartości w (oryginale) znajdź wszystkie wystąpienia w . Następnie wykonaj sumę bieżącą dla każdej wartości, podając kwadratową macierz pokazującą dla każdej pozycji, ile z każdej wartości już wystąpiło.
    • : Podziel macierz według jej rzędów, dając każdej wartości tablicę pokazującą liczbę przypadków, w których wystąpiła dla każdej pozycji.
    • 2⍳⍨¨: W każdej z tych tablic znajdź indeks pierwszej 2.
    • (⍳⍴⍵)∊: Dla każdego możliwego indeksu do sprawdź, czy jest zawarty na liście indeksów drugich wystąpień. (Rozpoczynają każdą grupę, z wyjątkiem pierwszej.)
    • 1,: Dodaj an 1z przodu, oznaczając początek pierwszej grupy.
  • 1↓¨: Usuń pierwszy element z każdej grupy. (Są to dodane 0i drugie wystąpienie każdej wartości.)
marinus
źródło
8

J, 28 24 char

Specjalne podziękowania dla randomra .

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

Działa to w ten sposób. Nad wszystkimi prefiksami ( \) tablicy wejściowej patrzymy, ile +/@elementów ( ) prefiksu jest równych ostatnim elementowi ( ={:) tego prefiksu. Gdy liczba ta wynosi 2, wiemy, że jest to drugie wystąpienie tego elementu w tablicy, więc podzieliliśmy tablicę za pomocą <;._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

Stara sprawa używając sztuczek sortowania: (1&,<;._1~1,1=i.~(]-{)/:@/:).

algorytmshark
źródło
(1&,<;._1~1,2=+/@(={:)\)jest 4 bajty krótszy i dużo prostszy. ( /:@/:to niezła sztuczka.)
randomra
7

Mathematica, 58 51 49 bajtów

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

Jest to nienazwana funkcja, która przyjmuje taką listę

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

i zwraca zagnieżdżoną listę jak

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

Jak to działa

Używa to dość niejasnej magii SplitBy.

Śledzę występowanie każdej liczby w funkcji f. W Mathematica możesz zdefiniować wartość funkcji dla każdego wejścia osobno i nie musisz określać wartości dla wszystkich możliwych danych wejściowych (jest to bardziej jak tablica skrótów na sterydach).

Zaczynam od inicjalizacji fna 0 dla wartości, które są obecne na wejściu za pomocą (f@#=0;#)&/@.

Teraz SplitBypobiera listę i funkcję i „dzieli listę na listy podrzędne składające się z serii kolejnych elementów, które po zastosowaniu mają tę samą wartość f” (uwaga, że SplitBynie usuwa żadnych elementów). Ale (nieudokumentowany) haczyk polega na tym, że fwywoływany jest dwukrotnie na każdym elemencie - w porównaniu z jego poprzednikiem i jego następcą. Więc jeśli to zrobimy

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

nie tylko otrzymujemy każdy numer raz, ale zamiast tego drukuje się

 1
 2
 2
 3
 3
 4

czyli 6 wzywa do 3 porównań.

Możemy podzielić listę przed każdym drugim wystąpieniem, jeśli napiszemy funkcję, która zawsze zwraca, Falseale zwraca, Truegdy drugie wystąpienie jest porównywane z elementem przed nim. Jest to trzecia kontrola tego elementu (dwie kontrole pierwszego wystąpienia plus pierwsza kontrola drugiego wystąpienia). Dlatego używamy ++f[#]==3&. Fajną rzeczą jest to, że to już powraca Falseprzy drugim sprawdzeniu drugiego wystąpienia, tak że mogę powrócić Truedo kolejnych drugich wystąpień, ale nadal dzieli się między nimi . Podobnie, to nie podzieli się po drugim wystąpieniu, ponieważ funkcja już powracaFalse przy drugim sprawdzeniu.

Teraz pytanie chce, abyśmy również usunęli te drugie wystąpienia, więc usuwamy pierwszy element z każdej listy za pomocą Rest/@. Ale oczywiście nie chcemy usuwać pierwszego elementu z danych wejściowych, więc zaczynamy od dodania elementu ana początku listy za pomocą {a}~Join~#. ajest niezdefiniowaną zmienną, którą Mathematica po prostu traktuje jako nieznaną, więc nie wpłynie na żadne inne wartości f. Zapewnia to również, że pierwszy rzeczywisty element na wejściu otrzyma dwa sprawdzenia, jak każdy inny element.

Martin Ender
źródło
To całkiem sprytne. Ty też tak naprawdę nie potrzebujesz Boole.
świst
@ Swish Ach, dziękuję za przypomnienie ... Zauważyłem to na telefonie komórkowym, ale chciałem to przetestować przed zmianą.
Martin Ender
5

Python, 148 bajtów

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

Całkiem przerażające rozwiązanie. Musi być lepszy sposób ...

Zadzwoń z s([2, 1, 1, 1, 4, 5, 6]).

Wersja bez golfa

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)]
Sp3000
źródło
1
Co, co… Czy mógłbyś edytować w wersji bez gry w golfa? XD 148 znaków to bardzo długa linia;)
Sean Allred,
1
@SeanAllred Nie chciałem zamieszczać wyjaśnień, ponieważ byłem pewien, że mogę zrobić lepiej, ale ponieważ mam problemy, opublikowałem wersję bez golfa: 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

przechowuje to ilość każdego elementu, który pojawił się do tej pory w funkcji od elementów do ich odpowiedniej ilości, co jest interesującą sztuczką.

działa to za %pomocą funkcji, która dała funkcję f, a argument xzwraca nową funkcję, która zwracaf zastosowaną do niej argument, jeśli jest inny niż xi 1 + f xinaczej.

na przykład, 3 % const 0jest funkcją, która zwraca 0 dla każdego argumentu oprócz 3, dla którego zwraca 1. aktualizację: połączyła foldlaby uzyskać znacznie mniejszy program.

dumny haskeller
źródło
To wygląda interesująco. Czy możesz podać wersję bez golfa?
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 stabby lambda, która przyjmuje tablicę jako parametr i zwraca tablicę tablic.

Cristian Lupascu
źródło
4

Python: 100 bajtów

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

Proste rozwiązanie. Iteruję listę, liczę, ile razy znak pojawiał się wcześniej, i dołączam część od ostatniego sprawdzenia do listy wyników.

Jakube
źródło
3

Ruby, 66

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

Wyjaśnienie

  • e jest skrótem wystąpienia dla każdego elementu, r jest tablicą, w której zapisywany jest wynik.
  • Pętla przez wejście, zwiększaj liczbę wystąpień dla każdego elementu o 1 .
    • Jeśli liczba wystąpień jest 2, musimy podzielić. Dodaj pustyArray do wyniku.
    • W przeciwnym razie po prostu dodaj element do ostatniego Arraywyniku.
Britishtea
źródło
2
Niezły kapelusz!! Zaczekaj.
Optymalizator
4
Cóż za niesamowity zbieg okoliczności! Odpowiedź Zamieściłem sekund przed twój jest niemal identyczny. :)
Cristian Lupascu,
O rany, jest nawet o 1 postać krótszy!
britishtea,
To oszczędność, którą możesz łatwo zastosować do swojej. Myślę, że to niesamowite, że mieliśmy ten sam pomysł w tym samym czasie. : D
Cristian Lupascu,
3

CJam, 25 24 bajtów

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

Pobiera dane wejściowe ze STDIN jak

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

i wyniki jak

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

W zasadzie powtarzam wszystkie elementy tablicy, jeden po drugim umieszczając je w innej tablicy. Następnie uzyskuję liczbę bieżącego elementu w drugiej tablicy. Jeśli jest 2, uruchamiam kolejną tablicę z tej lokalizacji. Tego rodzaju losowe uruchamianie tablic można osiągnąć tylko w języku stosowym.

Rozszerzenie kodu :

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

Wypróbuj online tutaj

1 bajt zapisany od porady Martina na czacie

Optymalizator
źródło
3

Rubinowy, 64 bajty

s=->a{x=[];b=[[]];a.map{|e|x<<e;x.count(e)==2?b<<[]:b[-1]<<e};b}
AlexRath
źródło
3

Perl 5: 36

Nie jestem pewien, czy jest to do przyjęcia, ponieważ w tym przypadku nie dochodzi do rzeczywistego podziału.

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

Przykład:

$ 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 ][]]
nutki
źródło
Całkowicie do zaakceptowania.
Optymalizator
Niezła odpowiedź. Myślę jednak, że standardową praktyką jest liczenie -pajako dwa dodatkowe bajty (ponieważ „kosztuje” tylko dwa bajty, ponieważ można je zapisać jako -paezamiast -e). To by było 38, a nie 36.
msh210
2

CJam, 28 bajtów

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

Pobiera dane wejściowe na STDIN jak

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

i wypisuje dane wyjściowe do STDOUT jak

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

Zauważ, że puste ciągi i puste tablice są tym samym w CJam i są wyświetlane jako "" domyślnie (to jest to natywna reprezentacja pustych tablic).

(Zacząłem nad tym pracować trochę przed opublikowaniem wyzwania, ponieważ dyskutowaliśmy o tym, jak trudne będzie wyzwanie).

Wyjaśnienie

Zasadniczo duplikuję każdy element w tablicy, chyba że jest to drugie wystąpienie, w którym to przypadku zastępuję pierwszą kopię spacją. Z powodów golfowych ta zmodyfikowana tablica jest zbudowana w odwrotnej kolejności. Tak się [2 1 1 2 3 2 3]staje

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

Następnie wybieram co drugi element od końca, który jest oryginalną tablicą, ale z drugimi wystąpieniami zastąpionymi spacjami, tj

[2 1 S S 3 2 S]

Na koniec po prostu podzieliłem tablicę na spacje. Oto podział kodu:

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.";
Martin Ender
źródło
Ponieważ jest to moje własne wyzwanie, najpierw daję szansę: P. Mam ze sobą 25-bajtowe rozwiązanie Cjam.
Optymalizator
Nie wyświetla poprawnie pustych tablic - oczywiście nieprawidłowy!
feersum,
1
@feersum wyświetla puste tablice, co ""jest wyraźnie dozwolone w pierwszej wersji pytania. Obecna wersja stanowi „dowolny dogodny format ... zwykle natywna reprezentacja ciągu tablic”.
John Dvorak,
2

Narzędzia uniksowe, 100 bajtów

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

Z wyjątkiem wprowadzania przez stdin. Zasadniczo po prostu zastępuje co drugie wystąpienie "] [". Nie działa z pustymi łańcuchami, []da pusty łańcuch, który moim zdaniem jest wygodną reprezentacją pustej tablicy :)

pgy
źródło
Cóż, więc odpowiedź nie jest zgodna ze specyfikacją, prawda? (o ujemnych liczbach całkowitych). A co powiesz na 11? czy zostanie przekonwertowany na 1][?
Optymalizator
Działa dobrze dla 11, ale masz rację co do liczb ujemnych, naprawiłeś to, a teraz akceptuje również tablice singleton.
pgy
2

APL, 42 znaki

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

Przykład:

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

Wynik:

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

Testowane tutaj.

Jeśli muszę wyprowadzić ciąg, który jest interpretowany dokładnie jako odpowiednia struktura w APL ... 49 znaków

{'1↓1(',',⍬)',⍨⍵[(2=+/¨(↑=↓)¨⌽¨,\⍵)/⍳⍴⍵]←⊂',⍬)('}
jimmy23013
źródło
W jaki sposób zagnieżdżona lista faktycznie jest reprezentowana w APL? Być może nie musisz wykonywać manipulacji na łańcuchach
Optimizer
@Optimizer Wyprowadzany ciąg jest prawidłową listą w programie APL. Jednak nie zagnieżdżałby się, gdyby była tylko jedna lista. Przygotowanie 1↓1wydawało się rozwiązać problem, ale wygląda to zbyt dziwnie.
jimmy23013,
2

Java, 223

Działa to tylko w Oracle lub OpenJDK JRE, ponieważ wykorzystuję to dziwactwo w ich implementacji kwantyfikatora i sprawdzania długości w przeszłości, aby zaimplementować wsteczną zmienną długość.

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

Większość pracy wykonywana jest w wyrażeniu regularnym, które pokazano poniżej w postaci surowej:

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

Zanim spojrzymy na wyrażenie regularne powyżej, przyjrzyjmy się równoważnemu wyrażeniu regularnemu .NET, które jest prostsze, ponieważ bezpośrednio obsługuje opóźnienie o zmiennej długości (opóźnienie .NET najprawdopodobniej odbywa się w trybie dopasowania od prawej do lewej) :

 *\b(\d+)\b(?<=(.*\b\1\b){2})(?<!(.*\b\1\b){3}) *
  •  *\b(\d+)\ba  *na końcu pasuje do liczby i otaczających spacji (jeśli istnieją). Ograniczenia kontrolne mają zapobiegać dopasowaniu liczby częściowej, ponieważ spacje po obu stronach są opcjonalne. Przechwytuje również liczbę, aby sprawdzić, czy jest to drugi wygląd w tablicy.

  • (?<=(.*\b\1\b){2}) sprawdza, czy można znaleźć 2 wystąpienia liczby przechwyconej powyżej. (?<!(.*\b\1\b){3})sprawdza, czy nie można znaleźć 3 wystąpień przechwyconej liczby. Oba połączone warunki potwierdzają, że do tej pory istnieją tylko 2 wystąpienia tej liczby. Dostępne kontrole mają na celu sprawdzenie, czy cała liczba jest testowana.

Powrót do wersji Java. Aby zaimplementować spojrzenie o zmiennej długości, przekształcamy

(?<=var-length-pattern)

do

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

Trochę macham ręką w związku z tym . wyklucza separatory linii, ale można to łatwo naprawić i nie chcę dalej komplikować składni.

Przyszłość ma zawsze wartość 0, a kontrola długości mija z powodu implementacji * kwantyfikatora.

The ^ jest konieczne, aby działało, ale ma to na celu sprawienie, aby awaria uległa awarii szybciej. Spojrzenie za siebie w implementacji Oracle / OpenJDK odbywa się poprzez cofnięcie minimalnej długości wzorca, następnie dopasowanie, następnie spłukanie i powtarzanie przez zwiększenie długości aż do znalezienia dopasowania lub, w najgorszym przypadku, do maksymalnej długości wzorca . Z^ upewniam się, że ciąg prefiksu jest dopasowywany tylko raz.

Jednak patrzenie w przyszłość za obserwatorem nie jest ograniczone prawą granicą patrzenia za plecami, więc może pasować do końca łańcucha. Aby potwierdzić granicę, przechwytuję resztę łańcucha do innej grupy przechwytywania w spojrzeniu w przyszłość i używam go do ograniczenia panowania wzoru o zmiennej długości.

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

Ponieważ mój wzór już się zaczyna .*, nie muszę dodawać kolejnego .*z przodu.

n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨d̷̰̀ĥ̷̳
źródło
1

Perl 108

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

W akcji:

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

Uwaga: Dwie pierwsze linie $Data::...służą tylko do ładniejszej prezentacji, a trzecia linia @a=@b=@e=();służy do pracy z wieloma liniami.

F. Hauri
źródło
1

R 76

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

Dane wyjściowe dla przykładu: lista pięciu elementów, w tym trzy puste wektory. ( 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)

Nawiasem mówiąc: kod generuje komunikat ostrzegawczy, który można zignorować.

Sven Hohenstein
źródło
1

awk 29

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

To wymaga trochę swobody w przypadku formatów wejściowych i wyjściowych. „Tablica” wejściowa jest pionowa, jedna liczba na linię. Dane wyjściowe są również pionowe, jedna liczba na linię, z myślnikami oddzielającymi tablice.

Wejście:

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

Wynik:

2
1
–
–
3
2
2
4
5
6
7
–
–
0
–
Kevin
źródło
1

Pyth 30 32

To jest mój pierwszy eksperyment z Pyth. To takie samo rozwiązanie jak w moim rozwiązaniu Python.

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

Możesz spróbować online: Pyth Compiler / Executor

Np. Dane wejściowe

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

wydrukuje

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

Wyjaśnienie:

                                 # 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:]]
Jakube
źródło
Czy istnieje lepsza alternatywa dla =Y+Y...?
Jakube,
to jest -~Y...
Optymalizator
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

Lista ljest jak dotąd danymi wyjściowymi. Iterujemy po elementach. Jeśli obecny jest drugi występ, rozpoczynamy nową pustą podlistę; w przeciwnym razie dodajemy go do najnowszej listy podrzędnej. Lista elementów widocznych do tej pory jest przechowywana w p. O dziwo, rekonstrukcja listy wydaje się krótsza niż dzielenie danych wejściowych.

xnor
źródło
1

Pure Bash 111 94

81 tylko w przypadku podziału:

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

Drugi wiersz declare -p cpo prostu zrzuca zmienną

Próba:

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
}

Uwaga: linia local b c d ijest wymagana tylko do kilkukrotnego uruchomienia funkcji.

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

Do najseksowniejszej prezentacji (+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>"

Wyrenderuje coś takiego:

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


}
F. Hauri
źródło
0

Scala, 122 111

Weź kolekcję postaci, wydrukuj w formie [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+"]")

... lub weź kolekcję znaków i zwróć listy zagnieżdżone, 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

Jestem pewien, że mogę uzyskać pewne oszczędności, nie szukałem zbyt mocno.

Chad Retz
źródło
0

Python 220 bajtów

Poniżej jest 220 bajtów, co nie jest świetne w porównaniu do wielu innych, ale działa wystarczająco szybko z większymi liczbami całkowitymi!

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)
S rick
źródło
Cześć, witamy w PPCG! Jednak twój kod nie jest wystarczająco krótki. Widzę miejsca, w których można to zdecydowanie skrócić. Proszę kontynuować grę w golfa.
Rɪᴋᴇʀ
Cześć! Jeśli potrzebujesz pomocy w golfa, można usunąć spacje wokół =, zmiana xlisti resultdo krótszych nazwach i usuń spacje wokół ==, ;i :. Jeśli potrzebujesz dodatkowej pomocy, po prostu wpisz @NoOneIsHere(lub dowolną nazwę użytkownika), a ja / użytkownik spróbuje ci pomóc.
NoOneIsHere
-1

Java: 563 bajty

zauważ, że używa to Java 8, wcześniejsza wersja JDK8 byłaby o kilka bajtów dłuższa z powodu 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
źródło
gdzie jeszcze mogę użyć lambda? zapętlanie aż do długości tablicy jest niepoprawne, ponieważ lista powiększa się w miarę dodawania kolejnych „]” i „[”.
PoweredByRice
zwiększanie długości za każdym razem jest tak samo długie jak wyłapanie wyjątku, również nie sądzę, aby w Javie można było zmienić ustawienie CEILING w (dla i = 0; i <CEILING; i ++).
PoweredByRice
Naprawdę ?
Optymalizator
hmm nie wiedziałem tego, dziękuję za zwrócenie uwagi.
PoweredByRice
Co z konwersją Integer.MAX_VALUEna 2147483647? Jest to ta sama wartość z mniejszą liczbą bajtów. Ponadto, IndexOutOfBoundsExceptionmoże być skrócony doException
Charlie