Uwaga: Jest to numer 2 w serii wyzwań dotyczących manipulacji tablicami . Aby zobaczyć poprzednie wyzwanie, kliknij tutaj .
Rozdzielanie list zagnieżdżonych
Aby oddzielić wartości na liście zagnieżdżonej, spłaszcz ją, a następnie zawiń każdą wartość, aby znajdowała się na tej samej głębokości zagnieżdżenia, co poprzednio.
To znaczy, ta lista:
[1, [2, 3], [4, 4, [5, 2], 1]]
Stanie się:
[1, [2], [3], [4], [4], [[5]], [[2]], [1]]
Wyzwanie
Twoim zadaniem jest napisanie programu, który pobierze dowolną zagnieżdżoną listę liczb całkowitych dodatnich (w granicach twojego języka) i wykona tę operację separacji.
Możesz przesłać funkcję, która przyjmuje listę jako argument, lub pełny program wykonujący operacje we / wy.
Ponieważ jest to kod-golf , wygrywa najkrótsza przesyłka (w bajtach)! *
* Standardowe luki w grze w golfa są zakazane. Znasz zasady.
Przypadki testowe
Listy wejściowe zawsze będą zawierać liczby całkowite w standardowym rozmiarze całkowitym twojego języka. Aby uniknąć ograniczeń języków uniemożliwiających im konkurowanie, wartości nie będą zagnieżdżane na głębokościach większych niż 10.
Możesz założyć, że dane wejściowe nie będą miały pustych list podrzędnych: na przykład - [[5, []]]
nie zostaną podane. Jednak główna lista może być pusta.
[] -> []
[[1, 2]] -> [[1], [2]]
[3, [4, 5]] -> [3, [4], [5]]
[3, [3, [3]]] -> [3, [3], [[3]]]
[[6, [[7]]]] -> [[6], [[[7]]]]
[[5, 10], 11] -> [[5], [10], 11]
Nie wahaj się zostawić komentarza, jeśli przegapiłem skrzynkę.
Przykład
Rzuciłem razem szybki (ungolfed) Pythonie 3 rozwiązanie jako przykład - można go przetestować na repl.it .
źródło
Odpowiedzi:
Brachylog , 16 bajtów
Wypróbuj online!
Wyjaśnienie
źródło
Z
argument na TIO? Bez tego wydaje się, że jest wyprowadzane z wartością prawda / fałsz, co sprawia, że wydaje się, żeZ
jest to konieczne w liczbie bajtów.Z
informuje Brachylog, że argument wyjściowy jest zmienną. Ta zmienna zostaje ujednolicona z wynikowym wynikiem. Po usunięciu informuje Brachylog, że wyjście jest zmienną anonimową, i zamiast tego wypisuje, czy główny predykat się powiedzie, czy nie. Jest to to samo, co w Prologu, gdzie wynik jest „wstawiany” do zmiennej.Mathematica,
2421 bajtówlub jeden z tych:
Wyjaśnienie
Jest to tak krótkie, że jest to w zasadzie rekurencja, która nie wymaga jednoznacznego przypadku podstawowego.
Jest tu dużo cukru syntaktycznego, więc zacznijmy od odkrycia tego.
&
oznacza pozostawioną po niej nienazwaną funkcję, której argument zapisano jako#
. Wewnątrz tej funkcji#0
odnosi się do samej funkcji, która umożliwia pisanie nienazwanych funkcji rekurencyjnych. Ale zacznijmy od nadania funkcji wewnętrznej nazwy i wyciągnięcia jej:Innym ważnym cukrem syntaktycznym
f/@x
jest skrót,Map[f, x]
który wywołujef
każdy elementx
. Powodem, dla któregof[x_] := ... f /@ x
nie prowadzi do nieskończonej rekurencji jest to, że mapowanie czegoś na atomie pozostawia atom bez zmian bez faktycznego wywoływania funkcji. Dlatego nie musimy jawnie sprawdzać przypadku podstawowego (bieżącym elementem jest liczba całkowita).Więc funkcja
f
najpierw powraca do najgłębszej listy w środkux
, w którym to momencief/@
staje się brakiem operacji . Następnie nazywamy użycie##& @@ List /@
w tym celu. MapowanieList
listy po prostu otacza każdy element osobną listą, więc{1, 2, 3}
staje się{{1}, {2}, {3}}
. Następnie stosujemy się##&
do niego, co oznacza, że głowa (tj. Zewnętrzna lista) zostaje zastąpiona przez##&
, więc zmienia się w##&[{1}, {2}, {3}]
. Ale##&
po prostu zwraca argumenty jakoSequence
(które można traktować jako niepakowaną listę lub rodzaj operatora „splat” w innych językach).Tak więc
##& @@ List /@
zamienia listę{1, 2, 3}
w{1}, {2}, {3}
(coś w rodzaju, że ostatnia rzecz jest rzeczywiście owinięta w głowęSequence
, ale znika, gdy tylko użyjemy tej wartości w dowolnym miejscu).To pozostawia pytanie, dlaczego
f
samo to nie jest rozwiązaniem tego wyzwania. Problem polega na tym, że najbardziej zewnętrzna lista powinna być traktowana inaczej. Jeśli mamy wkład{{1, 2}, {3, 4}}
, chcemy,{{1}, {2}, {3}, {4}}
a nie chcemy{{1}}, {{2}}, {{3}}, {{4}}
. Moje oryginalne rozwiązanie naprawiło to, przekazując końcowy wynik jako listę argumentów,Join
które przywróciłyby zewnętrzny poziom list, ale ten po prostu pomija zewnętrzny poziom, używającf
siebie w mapie na wyjściu. Dlategof
jest stosowany tylko do poszczególnych elementów listy najbardziej oddalonych i nigdy nie dotyka tej listy.Jeśli chodzi o pozostałe trzy rozwiązania, pierwsze z nich po prostu stosuje rekurencję, poza
f
którą równie dobrze działa. Pozostałe dwa rozwiązania pozwalają uniknąć powtarzanejMap
operacji, najpierw łącząc dwie funkcje, a następnie odwzorowując wynik tylko raz.źródło
J ,
1918 bajtówJest to anonimowy czasownik, który przyjmuje i zwraca tablice w ramkach, które są (raczej nieporęczną) wersją zagnieżdżonych tablic. Zobacz, jak przejdzie wszystkie testy.
Wyjaśnienie
Wykorzystuje to nieco egzotyczne operacje
{::
( mapa ) iS:
( rozkładanie ), które działają na tablicach pudełkowych.{::
zastępuje każdy liść ścieżką pudełkową do tego liścia.S:
stosuje dany czasownik na danej głębokości zagnieżdżenia, a następnie dzieli wyniki na tablicę.źródło
R, 199 bajtów
To pytanie było trudne. Listy R są trochę dziwne i absolutnie nie jest łatwo zapętlić wszystkie elementy list podrzędnych. Nie jest również łatwe określenie głębokości tej listy. Następnie wyzwaniem staje się odtworzenie listy z oddzielonymi wszystkimi elementami, dlatego potrzebujemy również sposobu na adaptacyjne utworzenie listy o określonej głębokości.
Rozwiązanie składa się z dwóch dużych części. Funkcja rekurencyjna, która zapętla wszystkie listy i rejestruje głębokość:
Gdy mamy
unlist(l)
zapisane głębokości każdego wpisu wektora ,d
domyślnie tworzymy listę poprzezlapply
i wypełniamy ją następującą funkcją:W tym wywołaniu Apply tworzymy obiekt
q
o wartości wpisu na liście, sprawdzamy jego głębokość i sprawdzamy, czy jest on niezerowy. Jeśli wynosi zero, możemy po prostu zostawić to jako wartość liczbową. Jeśli jest niezerowa, musimy zagnieździć ją na takiej liczbie list. Więc wywołujemyd
czasy pętli for i wielokrotnie dzwonimyq=list(q)
.lapply
następnie umieszcza wszystkie te wartościq
na liście, tworząc pożądany wynik.Kompletny program z odpowiednimi odstępami i takimi:
źródło
is.list(y)
zamiastclass(y)=='list'
? nie mogę zweryfikować, czy to faktycznie zadziała.Retina , 34 bajty
Wypróbuj online!
źródło
(?<-2>)
działaC (gcc), 147 bajtów
Przykładowe dane wejściowe:
Przykładowe dane wyjściowe:
źródło
ułożone w stos , niekonkurencyjne, 25 bajtów
Jest to funkcja polegająca na modyfikacji górnego elementu stosu. Jeśli chcesz skorzystać z funkcji bonafide, po prostu dodaj
[
i]
na początku i na końcu.Wypróbuj tutaj!Oto czytelna wersja:
Przypadek testowy:
Wyjście bez nowych linii:
źródło
*
jak argument do bloku kodu?d-1
czasy argumentów .$func
jest funkcją, którą można manipulować.PHP,
10194 bajtówzapisano 1 bajt dzięki @Christoph, zapisano kolejne 6 zainspirowanych tym.
funkcja rekurencyjna, całkiem prosta
awaria
źródło
$r
pobiera elementy w pętli, albo funkcja zwraca pustą tablicę. Może dawać powiadomienia, ale nie są drukowane przy domyślnej konfiguracji.!cos()
.cos()
zwracanull
dla każdej tablicy i liczby zmiennoprzecinkowej! = 0 dla każdej dodatniej liczby całkowitej. Mam na myśli ... kogo obchodzą ostrzeżenia?is_int
: Cofnięcie warunku niczego nie zapisuje; Potrzebuję odstępu międzyelse
iforeach
. ALE:$b[0]
dla liczby całkowitej jestNULL
.Python 2,
122106 bajtówCałkiem okropny wynik, po prostu prosta implementacja.
Dzięki @Zachary T za pomoc w oszczędzaniu 16 bajtów!
Zadzwoń
x
z jednym argumentem, aby uruchomić. Z jakiegoś powodu można go uruchomić tylko raz.źródło
a+=[n(l,d)]
naa+=n(l,d),
(zwróć uwagę na przecinek)t
?n
do funkcji i usunąć pierwszy argument, ponieważ zawsze będziel
.JavaScript (Firefox 30-57), 53 bajty
Najlepsza dotychczasowa odpowiedź na ES6 to 76 bajtów:
źródło
f=
.Pyth - 29 bajtów
Pakiet testowy .
źródło
Perl 6 ,
6047 bajtów( Wypróbuj online. )
Wyjaśnienie:
[... for |$^a]
: Iteruj po tablicy wejściowej i stwórz z niej nową tablicę.$_ ~~ List ?? ... !! ...
: Dla każdego elementu sprawdź, czy sam jest tablicą.|([$_] for .&f)
: Jeśli element jest tablicą, zastosuj do niego rekurencyjnie funkcję, iteruj po elementach nowej tablicy zwróconej z tego wywołania rekurencyjnego, zawiń każdy element we własną tablicę i wsuń je na zewnętrzną listę.$_
: Jeśli element nie jest tablicą, przekaż go takim, jaki jest.źródło
Haskell, 71 bajtów
Znów muszę zdefiniować własny typ listy, ponieważ list tubylców Haskella nie można dowolnie zagnieżdżać. Ten nowy typ
L
może zostać zwrócony z funkcji, ale nie może być domyślnie drukowany, więc aby zobaczyć wynik, definiujęshow
instancję dlaL
:Teraz możemy wykonać test w REPL:
Jak to działa: prosta rekurencja, która przechodzi poziom zagnieżdżenia jako funkcja
C
konstruktorów. Zaczynamy od funkcji tożsamościid
i ilekroć jest lista (-> dopasowanie do wzorcad#C l=
), dodajemy kolejną warstwęC
(->C .pure.d
) do rekurencyjnego wywołania#
wszystkich elementów listy. Jeśli napotkamy liczbę, po prostu zastosujemy do niej funkcję poziomu zagnieżdżeniad
.źródło
APL (Dyalog) , 44 bajty *
Anonimowa ukryta funkcja prefiksu. Pobiera zagnieżdżoną listę APL jako argument i zwraca zagnieżdżoną tablicę APL.
Wypróbuj online!
{
…}
Zastosuj następującą jawną funkcję, w której argument jest reprezentowany przez⍵
:⎕JSON⍵
przekonwertować argument na JSONj←
przechowywaćj
'[]'∘.=
tabela, w którejj
równa się nawiasy otwierające (górny rząd) i zamykające (dolny rząd)-⌿
górny rząd minus dolny rząd (zmniejszenie różnicy pionowej)+\
suma skumulowana (daje to poziom zagnieżdżenia dla każdej postaci)(
…)⊆
Partycja, rozpoczynanie nowej partycji za każdym razem, gdy 1 nie jest poprzedzony 1 w…j∊⎕D
gdzie każda postaćj
jest członkiem zbioru D. igits⊃¨
wybierz pierwszy z nich (daje to poziom zagnieżdżenia na liczbę wielocyfrową)∊{
…}¨
Zastosuj następującą funkcję do każdego poziomu zagnieżdżenia (⍵
), używając odpowiedniego elementu z ϵ nlistowanego (spłaszczonego) argumentu jako lewego argumentu (⍺
):,⍺
ravel (listify) liczbę (ponieważ skalary nie mogą być zamknięte)⊂⍣⍵
ująć⍵
czasy⊃
ujawnij (ponieważ sama najbardziej wewnętrzna lista jest załącznikiem)* Korzystanie Dyalog Classic z
⎕ML←3
(domyślnie w wielu systemach), zastępując⊂
na⊆
i↑
na⊃
. Tio!źródło