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 golf golfowy, więc wygrywa najkrótszy kod w bajtach!
źródło
""
na pustą tablicę? To pachnie faworyzowaniem określonego języka golfowego.2 1, 1 4 5 6
?Odpowiedzi:
APL 25
Przykład:
Stary:
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
źródło
1↓¨{1,∨⌿<\2=+\∘.=⍨⍵}⊂1∘,
APL (Dyalog 14) (31)
Jest to funkcja, która pobiera tablicę i zwraca tablicę zagnieżdżoną.
Test:
Wyjaśnienie:
0,⍵
: Dodaj a0
z przodu⍵
, aby ułatwić przetwarzanie. (Nie liczy się jako zdarzenie).(
...)⊂
: Podziel tablicę zgodnie z podaną maską bitową. Nowa grupa zaczyna się na każdej1
w 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 pierwszej2
.(⍳⍴⍵)∊
: 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 an1
z przodu, oznaczając początek pierwszej grupy.1↓¨
: Usuń pierwszy element z każdej grupy. (Są to dodane0
i drugie wystąpienie każdej wartości.)źródło
J,
2824 charSpecjalne podziękowania dla randomra .
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
.Stara sprawa używając sztuczek sortowania:
(1&,<;._1~1,1=i.~(]-{)/:@/:)
.źródło
(1&,<;._1~1,2=+/@(={:)\)
jest 4 bajty krótszy i dużo prostszy. (/:@/:
to niezła sztuczka.)Mathematica,
585149 bajtówJest to nienazwana funkcja, która przyjmuje taką listę
i zwraca zagnieżdżoną listę jak
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
f
na 0 dla wartości, które są obecne na wejściu za pomocą(f@#=0;#)&/@
.Teraz
SplitBy
pobiera 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, żeSplitBy
nie usuwa żadnych elementów). Ale (nieudokumentowany) haczyk polega na tym, żef
wywoływany jest dwukrotnie na każdym elemencie - w porównaniu z jego poprzednikiem i jego następcą. Więc jeśli to zrobimynie tylko otrzymujemy każdy numer raz, ale zamiast tego drukuje się
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,
False
ale zwraca,True
gdy 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ż powracaFalse
przy drugim sprawdzeniu drugiego wystąpienia, tak że mogę powrócićTrue
do 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 elementua
na początku listy za pomocą{a}~Join~#
.a
jest niezdefiniowaną zmienną, którą Mathematica po prostu traktuje jako nieznaną, więc nie wpłynie na żadne inne wartościf
. Zapewnia to również, że pierwszy rzeczywisty element na wejściu otrzyma dwa sprawdzenia, jak każdy inny element.źródło
Boole
.Python, 148 bajtów
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
źródło
Haskell,
11511310688przechowuje 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 argumentx
zwraca nową funkcję, która zwracaf
zastosowaną do niej argument, jeśli jest inny niżx
i1 + f x
inaczej.na przykład,
3 % const 0
jest funkcją, która zwraca 0 dla każdego argumentu oprócz 3, dla którego zwraca 1. aktualizację: połączyłafoldl
aby uzyskać znacznie mniejszy program.źródło
Demo Ruby 66
Ruby stabby lambda, która przyjmuje tablicę jako parametr i zwraca tablicę tablic.
źródło
Python: 100 bajtów
Proste rozwiązanie. Iteruję listę, liczę, ile razy znak pojawiał się wcześniej, i dołączam część od ostatniego sprawdzenia do listy wyników.
źródło
Ruby, 66
Wyjaśnienie
e
jest skrótem wystąpienia dla każdego elementu,r
jest tablicą, w której zapisywany jest wynik.1
.2
, musimy podzielić. Dodaj pustyArray
do wyniku.Array
wyniku.źródło
CJam,
2524 bajtówPobiera dane wejściowe ze STDIN jak
i wyniki jak
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 :
Wypróbuj online tutaj
1 bajt zapisany od porady Martina na czacie
źródło
Rubinowy, 64 bajty
źródło
Perl 5: 36
Nie jestem pewien, czy jest to do przyjęcia, ponieważ w tym przypadku nie dochodzi do rzeczywistego podziału.
Przykład:
źródło
-pa
jako dwa dodatkowe bajty (ponieważ „kosztuje” tylko dwa bajty, ponieważ można je zapisać jako-pae
zamiast-e
). To by było 38, a nie 36.CJam, 28 bajtów
Pobiera dane wejściowe na STDIN jak
i wypisuje dane wyjściowe do STDOUT jak
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]
stajeNastępnie wybieram co drugi element od końca, który jest oryginalną tablicą, ale z drugimi wystąpieniami zastąpionymi spacjami, tj
Na koniec po prostu podzieliłem tablicę na spacje. Oto podział kodu:
źródło
""
jest wyraźnie dozwolone w pierwszej wersji pytania. Obecna wersja stanowi „dowolny dogodny format ... zwykle natywna reprezentacja ciągu tablic”.Narzędzia uniksowe, 100 bajtów
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 :)źródło
11
? czy zostanie przekonwertowany na1][
?APL, 42 znaki
Przykład:
Wynik:
Testowane tutaj.
Jeśli muszę wyprowadzić ciąg, który jest interpretowany dokładnie jako odpowiednia struktura w APL ... 49 znaków
źródło
1↓1
wydawało się rozwiązać problem, ale wygląda to zbyt dziwnie.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ść.
Większość pracy wykonywana jest w wyrażeniu regularnym, które pokazano poniżej w postaci surowej:
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
a*
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
do
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.
Ponieważ mój wzór już się zaczyna
.*
, nie muszę dodawać kolejnego.*
z przodu.źródło
Perl 108
W akcji:
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.źródło
R 76
Dane wyjściowe dla przykładu: lista pięciu elementów, w tym trzy puste wektory. (
numeric(0)
).Nawiasem mówiąc: kod generuje komunikat ostrzegawczy, który można zignorować.
źródło
awk 29
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:
Wynik:
źródło
Pyth 30
32To jest mój pierwszy eksperyment z Pyth. To takie samo rozwiązanie jak w moim rozwiązaniu Python.
Możesz spróbować online: Pyth Compiler / Executor
Np. Dane wejściowe
wydrukuje
Wyjaśnienie:
źródło
=Y+Y...
?~Y...
Python 2, 84
Lista
l
jest 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 wp
. O dziwo, rekonstrukcja listy wydaje się krótsza niż dzielenie danych wejściowych.źródło
Pure Bash
1119481 tylko w przypadku podziału:
Drugi wiersz
declare -p c
po prostu zrzuca zmiennąPróba:
Uwaga: linia
local b c d i
jest wymagana tylko do kilkukrotnego uruchomienia funkcji.Do najseksowniejszej prezentacji (+26)
Wyrenderuje coś takiego:
źródło
Scala,
122111Weź kolekcję postaci, wydrukuj w formie
[21][][3224567][][0][]
,122111:... lub weź kolekcję znaków i zwróć listy zagnieżdżone,
135129:Jestem pewien, że mogę uzyskać pewne oszczędności, nie szukałem zbyt mocno.
źródło
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!
źródło
=
, zmianaxlist
iresult
do 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.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.
źródło
Integer.MAX_VALUE
na2147483647
? Jest to ta sama wartość z mniejszą liczbą bajtów. Ponadto,IndexOutOfBoundsException
może być skrócony doException