W tym wyzwaniu Twoim zadaniem jest stworzenie programu, który przyjmuje zagnieżdżoną tablicę i zwraca jednowymiarową spłaszczoną tablicę. Na przykład [10,20,[30,[40]],50]
powinien wyjść [10,20,30,40,50]
.
Wkład
Dane wejściowe będą tablicą zagnieżdżoną (np. [10,20,[[[10]]]]
). Będzie zawierać tylko liczby całkowite (zarówno ujemne, jak i dodatnie), łańcuchy i tablice. Możesz wziąć dane wejściowe jako argument funkcji, STDIN lub cokolwiek, co pasuje do twojego języka. Możesz założyć, że tablica wejściowa nie będzie pusta.
Wydajność
Dane wyjściowe będą płaską jednowymiarową tablicą z tymi samymi elementami tego samego typu, co w tablicy zagnieżdżonej i w takiej samej kolejności.
Przypadki testowe
[10,20,30] -> [10,20,30]
[[10]] -> [10]
[["Hi"],[[10]]] -> ["Hi",10]
[[[20],["Hi"],"Hi",20]] -> [20,"Hi","Hi",20]
[[["[]"],"[]"]] -> ["[]","[]"]
Poproś o wyjaśnienia za pomocą komentarzy. To jest golf golfowy , więc wygrywa najkrótszy kod w bajtach!
Uwaga: jeśli Twój język zawiera wbudowane narzędzie, NIE możesz go używać.
Edytować
Podaj także link do strony internetowej, na której można wykonać kod.
unflatten
pytanie, ale nie maflatten
pytania o PPCG.["[",[["[",],'[',"['['"]]
Jako przypadek testowy.'
i"
jako ograniczników. (Ale zgadzam się, że to przypadek testowy udziałem[
,]
,"
a\
wewnątrz łańcucha byłby przydatny.)Odpowiedzi:
K, 3 bajty
To dość powszechny idiom. „Połącz przez konwergencję”.
spróbuj tutaj z ok .
Jak to działa:
Join (
,
) łączy ze sobą atomy lub listy, aby utworzyć listę. Over (/
) pobiera czasownik (w tym przypadku łączyć) i stosuje go między każdym elementem listy, od lewej do prawej. W ten sposób związek,/
spłaszczy wszystkie elementy najwyższego poziomu listy. Symbol/
faktycznie ma różne znaczenia w zależności od wartościowości (liczby argumentów) czasownika, z którym jest złożony. Gdy podajemy,/
jako czasownik, ostateczne/
działa jako „zbieżne” - wielokrotnie stosuje,/
się do danych wejściowych, dopóki nie przestanie się zmieniać. Niektóre inne języki nazywają taką funkcję „kombinatorem stałych punktów”. Przez wielokrotne łączenie list najniższych poziomów ostatecznie dojdziesz do pojedynczej płaskiej listy i żadna z operacji nie zaburzy kolejności elementów. To wydaje się rozwiązać problem.źródło
JavaScript (ES6), 35 bajtów
Zainspirowany odpowiedzią @ user81655 :
źródło
Matematyka,
1614 bajtówNienazwana funkcja, która pobiera i zwraca listę, np .:
Wyjaśnienie
Impreza z syntaktycznym cukrem!
Aby zrozumieć, jak to działa, uwaga, że każdy wyraz w Mathematica jest albo atom (np liczby, ciągi znaków, symboli) lub wyrażenie związek z postaci
f[a, b, c, ...]
, gdzief
,a
,b
,c
same są dowolnymi wyrażeniami. Tutajf
nazywa się głową wyrażenia. Cała reszta to tylko cukier syntaktyczny. Np.{a, b, c}
Jest po prostuList[a, b, c]
.Zaczynamy od tego,
//@
która mapuje funkcje na wszystkich poziomach listy. Na przykład:Pamiętaj, że to mapy
f
atomy, a także wyrażenia złożone. To, czego teraz szukamy, to sposób na pozbycie się głów listy i zachowanie wszystkiego innego.Apply
Funkcja jest zwykle używany do zasilania elementów listy jako oddzielne argumentów do funkcji, ale jej rzeczywista definicja jest bardziej ogólny i po prostu zastępuje głowę wyrażenia. Np.Apply[g, f[a, b]]
Dajeg[a, b]
. .Teraz pojawia się specjalna „głowa”,
Sequence
która po prostu znika. Np. Po{a, Sequence[b, c], d}
prostu ocenia{a, b, c, d}
. Ideą spłaszczenia listy jest zastąpienieSequence
nagłówków wszystkich wewnętrznych list tak, aby zostały rozpryskiwane na otaczającą je listę. Więc to, co chcemy to doApply
głowySequence
na listach. Dogodnie, jeśli myApply
coś do atomu, po prostu pozostawia atom bez zmian, więc nie musimy w ogóle rozróżniać typów wyrażeń.Wreszcie, jest jeden mały problem:
f
jest on również stosowany do najbardziej zewnętrznego poziomu, dzięki czemu usuwa również skrajneList
, czego nie chcemy. Najkrótszym sposobem na skontrowanie jest po prostu ponowne zawinięcie wyniku w listę, tak aby otoczenieSequence
mogło bezpiecznie zniknąć.Zauważ, że nie ma
Apply
aniSequence
kodu.@@
jest formą operatoraApply
i##&
jest standardową sztuczką golfową, która skraca długą wbudowaną nazwęSequence
. Więc trochę golfa wszystko, otrzymujemy coś takiego:Aby uzyskać więcej informacji na temat tego, jak i dlaczego
##&
działa, zobacz sekcję „Sekwencje argumentów” w mojej odpowiedzi na wskazówki Mathematica .źródło
//@
. Bardzo przydatne informacje!//@
przechwytuje schludny wzór. Przypomina mi trochę rekurencyjnych kombinatorów w Joy. Czy masz link do dobrego odniesienia do jakichkolwiek powiązanych funkcji w Mathematica? Jestem bardzo zainteresowany sposobami uwzględnienia jawnej rekurencji w programach.Map
,MapAt
,Apply
, jakReplace
i związanych z nimi funkcji. Ogólnie jednak istnieje wiele funkcji, które przyjmują opcjonalny parametr levelspec (patrz moje oryginalne 16-bajtowe rozwiązanie), co pozwala na zastosowanie funkcji na wielu / wszystkich poziomach jednocześnie.Python 2, 43 bajty
Na liście powtarza się na elementach i łączy wyniki. W ciągu lub cyfrze jest umieszczany na liście singletonów.
Niestety, zamawianie w Pythonie 2 typów
int < list < string
kanapeklist
między innymi, wymaga sprawdzenia dwóch nierówności. Zamiast tegol*0
jest sprawdzany na pustej liście[]
, w przeciwnym razie daje0
lub""
.źródło
Rubinowy,
434234 bajtówRozwiązanie rekurencyjne. Teraz z obsługą wyjątków! (równie dobrze może pochwalić @akostadinov za inspirację zmiany)
Link IDEOne
źródło
rescue
taktry
bloku, więcbegin
zamiast tego używasz do rozróżnienia części, które chcesz złapać i części, których nie chcesz. Więc ponieważ łapiesz całą resztę bloku przed nią, technicznie nie potrzebujesz tego? Reszta jest właśnie przycięta spacją, ponieważ Ruby interpretuje tę linię jako...inject(:+) rescue [a]
a = raise("haha") rescue 1
przypisałby1
doa
. It 'rescue
, like there's an inlineif
andwhile
.JavaScript (ES6), 41 bytes
źródło
Perl 6, 24 bytes
Explanation:
Test:
źródło
Haskell, 43 bytes
Haskell has neither nested lists with different depths of the sublists nor mixed types for the list elements. For nesting I define a custom data type
D
which is either a leafL
that holds some element or a nodeN
which is a list ofD
s. For the mixed elements I use the predefined data typeEither
which combines two types into one, hereEither String Integer
. The new typeD
and the flatten functionf
are fully polymorphic in the type of the leaf elements, so I don't have to take extra care of anything regardingEither
.Usage example:
f (N[N[L(Right 20)], N[L(Left "Hi")], L(Left "Hi") , L(Right 20)])
->[Right 20,Left "Hi",Left "Hi",Right 20]
.źródło
Pyth,
765 bytesTry it online: Demonstration or Test Suite
But of course, there is also a build-in function, that handles the task in just 2 bytes:
.n
(Test Suite)źródło
G
implicitly, if I don't write it.JavaScript (Firefox 30-57), 43 bytes
Just because I could even avoid using
concat
.źródło
[for(of)]
is only available in Firefox 30+. It was proposed for ES7 but later dropped.for(__ in __)
Perl,
3429 bytesFunctions.
If needs to flatten to list like
my @a = f(@a)
, 29 bytes:Test it on Ideone
If needs to flatten to array ref like
my $a = f($a)
, 34 bytes:Test it on Ideone.
Perl 5.22.0+, 27 bytes
Thanks to hobbs.
If needs to flatten to list like
my @a = f(@a)
, 27 bytes:Test it on JDoodle
If needs to flatten to array ref like
my $a = f($a)
, 32 bytes:Test it on JDoodle.
źródło
?@{f@$_}:
should work instead of?@{f(@$_)}:
, saving two bytes.f
is a function becausef
not yet declared.sub f{}sub f{... f@$_ ...}
working.ref
doesn't need the parens to work, saving 2 bytes. 2. As far as I can see,sub f{map{ref?f(@$_):$_}@_}
is within the rules and saves another 5.f
takes an array (nonref) as a list, so it can return the same.ref
then the compiler assumes that?
is starting?PATTERN?
operation likeref(?PATTERN?)
. So the compiler searches second?
and throws error.?PATTERN?
was removed in 5.22.0 (m?PATTERN?
still works) and I'm testing on a recent version. So you can gain those two bytes by specifying 5.22+.Julia, 29 bytes
This is recursive splatting into a concatenate function until a reaching a fix point. Example
źródło
Retina, 30 bytes
Try it online! (The first line is only used to run multiple test cases at once.)
Retina has no concept of arrays, string literals or numbers, so I decided to go with a "common" input format of
[...,...]
style arrays and"
-delimited strings, where\
can be used inside the strings to escape any character (in particular"
and\
itself).The program itself simply matches either a full string or a square bracket, and replaces them with
$1
which keeps strings and removes square brackets. The limit1>
skips the first match so that we don't remove the leading[
. However, this does remove the trailing]
, so we add it back in in a separate stage.źródło
Pyke, 11 bytes
Try it here!
Explanation:
Or 7 bytes after a bugfix
Try it here!
Explanation:
Or even 2 bytes if printing to stdout is allowed (This might come under built-ins)
Try it here!
This deeply applies the
print_newline
function to every non-sequence item in the input and recurses for sequence items.źródło
Java (v8)
390276 bytesJust for completeness and all that. :) Can't say Java's code-efficient.
źródło
oaf
too
, and changeflatten
tof
.final
s, the whole thing can be a lambda, you don't needpublic static
...false
with1>2
, and additional 2 bytes you could get if you declare n but not define (compiler automatically define it as 0)Python, 57 bytes
Try it online: Python 2, Python 3
Thanks to Kevin Lau for the
list==type(x)
trick.źródło
type(x)==list
is shorter thanisinstance(x,list)
.[`x`>'['and...
? (That works in Python 2 only.)Ruby
there is builtin
flatten
method.You can run here: http://www.tutorialspoint.com/execute_ruby_online.php
One 43 bytes, but thought to share:
One 45 bytes that is more efficient than the previous and the other ruby answer:
here's benchmark:
result:
źródło
Note: If your language contains a built-in for this, then you must NOT use it
.rescue
rescue
looks to be rather slow btw, liketry/catch
in javaPerl,
3934 + 1 (-p
flag) 35 bytesOneliner. Inspired by Martin Büttner.
Test it on Ideone.
źródło
Clojure, 68 bytes
mapcat
first applies function to each element and then concats results. So every time it concats one 'nesting level' is lost. Concat does not work on not sequences so elements have to be wrapped into vector if they're not vector.You can try it here: http://www.tryclj.com
źródło
ANSI C, 193 bytes
:-/, any suggestions? Btw, I did try to find an online source to compile this but the WL is strict for this code to compile. It will work for VS and gcc otherwise.
źródło
JavaScript 20 bytes
The array + array is equal to array.toString
źródło
a
is an argument of the function. I will try to edit out the function now.a=>
to the beginning of your code.C#, 48 bytes
Thought I'd post it also since nobody has given a C# solution yet. Suggestions welcome!
źródło
i
initialized? and are you sure it works on the[["[]"],"[]"]
example?i=>$"{i.Replace("[","").Replace("]","")}"
?Racket, 63 bytes
źródło
Java 8 165 chars
Ungolfed into a class:
This answer is based on Jeremy Harton's approach. I used it changed it in some places and created a more golf-like version.
źródło
JavaScript, 17 Bytes
Finally, JavaScript's type conversions can be put to some good use! Please note that this will actually output an array, but string conversion (putting it into HTML) causes it to become a comma separated list.
If comma separated lists are acceptable output, then the following is valid:
7 Bytes
NOTE: Snippet is broken for some reason
źródło
["["]
... I tried running(a=>eval(
[${a}]))(["["])
and got aSyntaxError
oninput
event with abutton
click.PHP, 73 Bytes
źródło
Attache, 14 bytes
Try it online!
Fortunately, Attache has a "vectorization" operator, which applies a function at the atoms of a list. In this case, all we need to do is to set up a reaper with
Reap
andSow
all atoms of the input_
with@>
. I think it's quite elegant.Alternatives
15 bytes:
Fixpoint{`'^^_}
16 bytes:
Fixpoint!&Concat
17 bytes:
{q:=[]q&Push@>_q}
17 bytes:
Fixpoint[&Concat]
źródło
Elixir, 74 bytes
First Elixir answer, so can probably be golfed a bit.
Try it online.
Explanation:
Of course, if builtins were allowed, this could have been 25 bytes instead:
Try it online.
źródło
Jelly, 4 bytes
Try it online!
Explanation
Built-in
F
would be one byte if allowed.źródło
Wolfram Language (Mathematica), 13 bytes
Try it online!
Un-golfed:
F[x_] := Level[x, {-1}]
picks out the elements of the structure at the last level of its tree form. I'm not sure this counts as "avoiding the builtin" (which would be
Flatten
).źródło