Achatar a matriz!


34

Nesse desafio, sua tarefa é criar um programa que utilize uma matriz aninhada e retorne uma matriz achatada unidimensional. Por exemplo [10,20,[30,[40]],50]deve saída [10,20,30,40,50].


Entrada

A entrada será uma matriz aninhada (por exemplo [10,20,[[[10]]]]). Ele conterá apenas números inteiros (negativos e positivos), seqüências de caracteres e matrizes. Você pode usar a entrada como argumento de função, STDIN ou o que for mais adequado ao seu idioma. Você pode assumir que a matriz de entrada não terá uma matriz vazia.


Saída

A saída será uma matriz unidimensional plana com os mesmos elementos do mesmo tipo que na matriz aninhada e na mesma ordem.


Casos de teste

[10,20,30] -> [10,20,30]
[[10]] -> [10]
[["Hi"],[[10]]] -> ["Hi",10]
[[[20],["Hi"],"Hi",20]] -> [20,"Hi","Hi",20]
[[["[]"],"[]"]] -> ["[]","[]"]


Sinta-se à vontade para solicitar esclarecimentos usando comentários. Isso é , então o código mais curto em bytes vence!

Nota: Se o seu idioma contiver um built-in para isso, você NÃO deve usá-lo.


Editar

Inclua também um link para um site em que seu código possa ser executado.


7
Alguns idiomas tratam as strings como matrizes, é [["Oi"], [[10]]] -> ["H", "i", 10], ok?
Adám 18/05/19

4
@Mego Também fiquei surpreso ao descobrir que havia uma unflattenpergunta, mas nenhuma flattenpergunta sobre o PPCG.
Arjun

3
E se o seu idioma suportar apenas subarrays do mesmo tamanho? (Por exemplo, Java?) E se o tipo de cada elemento precisar ser o mesmo? (Por exemplo, Java, C ++ etc.?) Além disso, adicione, por exemplo, ["[",[["[",],'[',"['['"]]como um caso de teste.
Flawr 18/05/19

4
@flawr Esse caso de teste só faz sentido para idiomas que suportam bot 'e "como delimitadores. (Mas eu concordo que um caso de teste envolvendo [, ], "e \dentro de uma string seria útil.)
Martin Ender

4
Os casos de teste também excluem idiomas que não suportam esses tipos de matrizes com vários tipos ou com outra notação para literais da matriz.
Flawr 18/05/19

Respostas:


40

K, 3 bytes

,//

Este é um idioma bastante comum. "Juntar sobre convergir".

tente aqui com oK .

Como funciona:

Join ( ,) funde átomos ou listas para produzir uma lista. Over ( /) pega um verbo (neste caso, junte-se) e o aplica entre cada elemento de uma lista, da esquerda para a direita. Assim, o composto ,/achatará todos os elementos de nível superior da lista. O símbolo, /na verdade, tem significados diferentes, dependendo da valência (número de argumentos) do verbo com o qual é composto. Quando fornecemos ,/como verbo, o final /age como "convergir" - ele se aplica repetidamente ,/à entrada até que pare de mudar. Alguns outros idiomas chamam um recurso como este de "combinador de ponto fixo". Ao fundir repetidamente as listas de nível inferior, você chegará a uma única lista plana e nenhuma das operações perturbará a ordem dos elementos. Isso parece resolver o problema.


1
Tudo bem, obrigado pela explicação! Tenha o seu merecido +1.
Value Ink


1
Eu vim com o mesmo algoritmo (mas não nesta linguagem). +1 para escolher o idioma certo para implementá-lo!
Cyoce

@Cyoce Se seu idioma possui equivalentes aos três operadores usados ​​aqui, é uma solução extremamente natural. Por todos os meios, publique sua variação.
JohnE

1
@JohnE Longa história, estou derivando uma linguagem dos algoritmos que eu proponho, para que a linguagem ainda não esteja concluída (e, portanto, implementada).
Cyoce

38

JavaScript (ES6), 35 bytes

Inspirado na resposta de @ user81655 :

f=a=>a.map?[].concat(...a.map(f)):a

3
Muito esperto! +1 por [ab] usando a maneira estranha de JS de lidar com as chaves ausentes!
Cyoce

Eu posso vencer isso.
Bald Bantha

@BaldBantha: Estamos ansiosos pela sua resposta :-)
Bergi

2
Porcaria NVM Minha solução de 33 bytes falha em um dos casos de teste. NOOOO
Bald Bantha

2
@BaldBantha, a junção-divisão falhará nas vírgulas dentro das strings.
Qwertiy

19

Mathematica, 16 14 bytes

{##&@@#&//@#}&

Uma função sem nome que pega e retorna uma lista, por exemplo:

{##&@@#&//@#}& @ {{{20}, {"Hi"}, "Hi", 20}}
(* {20, "Hi", "Hi", 20} *)

Explicação

Festa sintática do açúcar!

Para entender como isto funciona, nota que cada expressão em Mathematica é ou um átomo (por exemplo, números, símbolos, cordas) ou um composto de expressão a forma f[a, b, c, ...], onde f, a, b, csão eles próprios expressões arbitrárias. Aqui, fé chamado a cabeça da expressão. Tudo o resto é apenas açúcar sintático. Por exemplo, {a, b, c}é justo List[a, b, c].

Começamos com o //@qual mapeia uma função em todos os níveis de uma lista. Por exemplo:

f //@ {{{20}, {"Hi"}, "Hi", 20}}
(* f[{f[{f[{f[20]}], f[{f["Hi"]}], f["Hi"], f[20]}]}] *)

Observe que este mapas f átomos e expressões compostas. O que estamos procurando agora é uma maneira de se livrar das listas e manter todo o resto.

A Applyfunção é normalmente usada para alimentar os elementos de uma lista como argumentos separados para uma função, mas sua definição real é mais geral e simplesmente substitui a cabeça de uma expressão. Por exemplo, Apply[g, f[a, b]]g[a, b] .

Agora há uma "cabeça" especial chamada Sequenceque simplesmente desaparece. Por exemplo, {a, Sequence[b, c], d}apenas avalia como {a, b, c, d}. A idéia de achatar a lista é substituir os cabeçalhos de todas as listas internas por, Sequencepara que eles sejam divididos em sua lista circundante. Então, o que queremos é Applychegar Sequenceàs listas. Convenientemente seApply algo com um átomo, ele apenas o deixará inalterado, para que não tenhamos que distinguir os tipos de expressões.

Finalmente, há um pequeno problema: ftambém é aplicado ao nível mais externo, para que também remova o mais externo List, o que não queremos. A maneira mais curta de combater isso é simplesmente agrupar o resultado em uma lista novamente, de modo que os arredoresSequence possa desaparecer com segurança.

Observe que não há nem Applynem Sequenceno código. @@é uma forma de operador Applye ##&é um truque de golfe padrão para encurtar o longo nome interno Sequence. Então, desenredando tudo um pouco, temos algo como:

flatten[list_] := { MapAll[Apply[Sequence], list] }

Para mais detalhes sobre como e por que ##&funciona, consulte a seção "Sequências de argumentos" na minha resposta para obter as dicas do Mathematica .


Primeira vez que vi //@. Muito útil para conhecer!
DavidC

//@captura um padrão elegante. Me lembra um pouco de alguns dos combinadores recursivos no Joy. Você tem um link para uma boa referência a funções relacionadas no Mathematica? Estou muito interessado em maneiras de levar em consideração a recursão explícita dos programas.
18716 JohnE

1
@ JohnE Bem, aqui estão os documentos . Você também pode olhar para as coisas como Map, MapAt, Apply, bem como Replacee funções relacionadas. Em geral, embora haja muitas funções que usam um parâmetro levelspec opcional (consulte minha solução original de 16 bytes), que permite aplicar a função em vários / todos os níveis ao mesmo tempo.
Martin Ender

12

Python 2, 43 bytes

f=lambda l:[l]*(l*0!=[])or sum(map(f,l),[])

Em uma lista, repete-se nos elementos e concatena os resultados. Em uma sequência ou número, é envolto em uma lista de singleton.

Infelizmente, o Python 2 está solicitando tipos de int < list < stringsanduíches listentre os outros, exigindo duas desigualdades para verificar. Então, em vez disso, l*0é verificado na lista vazia [], caso contrário, fornece 0ou "".


10

Ruby, 43 42 34 bytes

Solução recursiva. Agora com manipulação de exceção! (pode muito bem acreditar no @akostadinov por inspirar a mudança)

f=->a{a.map(&f).inject:+rescue[a]}

Link IDEOne


elogios para falta, impressionante
akostadinov

Eu não sabia que você poderia usar rescueassim
Cyoce

1
@Cyoce Eu acho que é porque Ruby tecnicamente não tem um trybloco, então você usa beginpara diferenciar as partes que deseja pegar e as que não tem. Então, como você está procurando o resto do quarteirão antes dele, tecnicamente não precisa? O resto é apenas um espaço em branco aparado, pois Ruby interpreta a linha como...inject(:+) rescue [a]
Value Ink

1
@ KevinLau-notKenny, não, o resgate na mesma linha é diferente, apenas resgatar essa linha. por exemplo a = raise("haha") rescue 1, atribuiria 1a a. É '
akostadinov

@ KevinLau-notKenny Há um inline rescue, como há um inline ife while.
Fund Monica's Lawsuit

8

JavaScript (ES6), 41 bytes

f=a=>[].concat(...a.map(v=>v.pop?f(v):v))
<textarea id="input" rows="6" cols="40">[[[20],["Hi"],"Hi",20]]</textarea><br /><button onclick="result.textContent=JSON.stringify(f(eval(input.value)))">Go</button><pre id="result"></pre>


8

Perl 6 , 24 bytes

{gather {$_».&{.take}}}

Explicação:

{ # has $_ as an implicit parameter

  gather {

    $_\ # the parameter from the outer block
    »\  # for each single value in the structure
    .&( # call the following block as if it was a method
      { # this block has its own $_ for a parameter
        .take # call the .take method implicitly on $_
      }
    )
  }
}

Teste:

#! /usr/bin/env perl6

use v6.c;
use Test;

my &flatten = {gather {$_».&{.take}}}

my @tests = (
  [10,20,30], [10,20,30],
  [[10,],], [10,],
  [["Hi",],[[10,],],], ["Hi",10],
  [[["[]",],"[]"],], ["[]","[]"],
);

plan @tests / 2;

for @tests -> $input, $expected {
  # is-deeply cares about the exact type of its inputs
  # so we have to coerce the Seq into an Array
  is-deeply flatten($input).Array, $expected, $input.perl;
}
1..4
ok 1 - $[10, 20, 30]
ok 2 - $[[10],]
ok 3 - $[["Hi"], [[10],]]
ok 4 - $[[["[]"], "[]"],]

7

Haskell, 43 bytes

data D a=L a|N[D a]
f(L x)=[x]
f(N l)=f=<<l

Haskell não possui listas aninhadas com diferentes profundidades das sublistas nem tipos mistos para os elementos da lista. Para aninhamento, defino um tipo de dados personalizado Dque é uma folha Lque contém algum elemento ou um nó Nque é uma lista de Ds. Para os elementos mistos, uso o tipo de dados predefinido Eitherque combina dois tipos em um, aqui Either String Integer. O novo tipo De a função achatar fsão totalmente polimórficos no tipo de elementos da folha, portanto, não preciso tomar muito cuidado com nada Either.

Exemplo de uso: f (N[N[L(Right 20)], N[L(Left "Hi")], L(Left "Hi") , L(Right 20)])-> [Right 20,Left "Hi",Left "Hi",Right 20].



6

JavaScript (Firefox 30-57), 43 bytes

f=a=>a.map?[for(b of a)for(c of f(b))c]:[a]

Só porque eu poderia mesmo evitar o uso concat.


O ECMAScript 6 não é o Firefox 30+ ?
Solomon Ucko

1
@SolomonUcko Não, [for(of)]está disponível apenas no Firefox 30+. Foi proposto para o ES7, mas depois caiu.
194 Neil

1
obrigado por explicar! Principalmente, eu apenas pensei que erafor(__ in __)
Solomon Ucko

@SolomonUcko [for (in)] era uma sintaxe experimental alternativa que forneceu as chaves do objeto.
194 Neil

5

Perl, 34 29 bytes

Funções.

Se precisar achatar para listar como my @a = f(@a), 29 bytes:

sub f{map{ref()?f(@$_):$_}@_}

Teste no Ideone

Se precisar achatar para ref da matriz my $a = f($a), 34 bytes:

sub f{[map{ref()?@{f(@$_)}:$_}@_]}

Teste em Ideone .

Perl 5.22.0+, 27 bytes

Graças a hobbs .

Se precisar achatar para listar como my @a = f(@a), 27 bytes:

sub f{map{ref?f(@$_):$_}@_}

Teste no JDoodle

Se precisar achatar para ref da matriz my $a = f($a), 32 bytes:

sub f{[map{ref?@{f(@$_)}:$_}@_]}

Teste no JDoodle .


Não testei, mas acho que ?@{f@$_}:deveria funcionar em vez de ?@{f(@$_)}:, economizando dois bytes.
Msh210

1
@ msh210 Não, não está funcionando. O compilador não mostra como essa fé uma função porque fainda não foi declarada. sub f{}sub f{... f@$_ ...}trabalhando.
Denis Ibaev 19/05

1. refnão precisa do parens para trabalhar, economizando 2 bytes. 2. Tanto quanto posso ver, sub f{map{ref?f(@$_):$_}@_}está dentro das regras e salva outras 5. fpega uma matriz (sem ref) como uma lista, para que possa retornar o mesmo.
Hobbs 20/05

@hobbs 1. Se não houver parênteses ref, o compilador assume que ?está iniciando a ?PATTERN?operação como ref(?PATTERN?). Portanto, o compilador procura o segundo ?e gera erro.
Denis Ibaev 20/05

@DenisIbaev ah. ?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+.
hobbs

4

Julia, 29 bytes

f(x,y=vcat(x...))=x==y?x:f(y)

This is recursive splatting into a concatenate function until a reaching a fix point. Example

julia> f([1,[2,[3,[4,[5,[6]]]]]])
6-element Array{Int64,1}:
 1
 2
 3
 4
 5
 6

3

Retina, 30 bytes

1>`("(\\.|[^"])+")|[][]
$1
$
]

Try it online! (The first line is only used to run multiple test cases at once.)

O Retina não tem conceito de matrizes, literais ou números de strings, então eu decidi usar um formato de entrada "comum" de [...,...]matrizes de estilo e "strings -delimited, onde \pode ser usado dentro das strings para escapar de qualquer caractere (em particular" and \ itself).

O programa em si simplesmente corresponde a uma sequência completa ou a um colchete e os substitui pelo $1que mantém as strings e remove os colchetes. O limite 1>ignora a primeira correspondência para que não removamos a liderança [. No entanto, isso remove a trilha ], então a adicionamos novamente em um estágio separado.


3

Pyke, 11 bytes

.F~]+=])K~]

Experimente aqui!

Explicação:

.F~]+=])    - Deep for loop
  ~]        -    contents of `]` ([] by default)
    +       -  ^+i
     =]     - `]` = ^
        K~] - Output value
        K   - Remove the output from the for loop
         ~] - Return the contents of `]`

Ou 7 bytes após uma correção de bug

M?+]K~]

Experimente aqui!

Explicação:

M?+]    - Deep map
 ?+]    -  `]` = `]`+i
    K~] - Output value
    K   - Remove the output from the for loop
     ~] - Return the contents of `]`

Ou até 2 bytes se a impressão em stdout for permitida (isso pode estar incluído nos recursos internos)

M
<newline required>

Experimente aqui!

This deeply applies the print_newline function to every non-sequence item in the input and recurses for sequence items.


Just 4 away from K! +1
Arjun

3

Java (v8) 390 276 bytes

public static Object[] f(final Object[]a) {
    List<Object>r=new ArrayList<>();boolean t=false;int n=0;
    for(final Object p:a)
        if(t=p instanceof Object[]){for(final Object q:(Object[])p) r.add(q);}
        else r.add(p);
    return(t)?f(r.toArray()):r.toArray();
}  

Just for completeness and all that. :) Can't say Java's code-efficient.


3
Hello, and welcome to PPCG! This question is code-golf, so please try to minimize your code. Thanks!
NoOneIsHere

3
Remove all the unnecessary spaces, tabs, and newlines. Change oaf to o, and change flatten to f.
NoOneIsHere

2
You don't need the finals, the whole thing can be a lambda, you don't need public static...
David Conrad

1
you could save couple characters if you use generics instead object
user902383

1
you could also save 2 bytes if you replace false with 1>2, and additional 2 bytes you could get if you declare n but not define (compiler automatically define it as 0)
user902383

2

Python, 57 bytes

f=lambda a:sum([list==type(x)and f(x)or[x]for x in a],[])

Try it online: Python 2, Python 3

Thanks to Kevin Lau for the list==type(x) trick.


2
type(x)==list is shorter than isinstance(x,list).
Value Ink

1
“It will contain only Integers (both negative and positive), Strings and Arrays.” How about [`x`>'['and...? (That works in Python 2 only.)
Lynn

2

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:

f=->a{a.inject([]){|r,e|r+(f[e]rescue[e])}}

One 45 bytes that is more efficient than the previous and the other ruby answer:

f=->a{a.map{|e|Array===e ?f[e]:[e]}.inject:+}

here's benchmark:

require 'benchmark'
n=10^9
arr=[[[20],[[[[[[[[123]]]]]]]],"ads",[[[[[[[4]]]]]]],5,[[[[[[[[[[6]]]]]]]]]],7,8,[[[[[[[[[[9]]]]]]]]]],[[[[[[[[[[0]]]]]]]]]],[[[[[[[[[[[["Hi"]]]]]]]]]]]],[[[[[["Hi"]]]]]],[[[[[20]]]]]]]
Benchmark.bm do |x|
  x.report { f=->a{a.map(&f).inject:+rescue[a]}; f[arr] }
  x.report { f=->a{a.map{|e|e!=[*e]?[e]:f[e]}.inject:+}; f[arr] }
  x.report { f=->a{a.inject([]){|r,e|r+(f[e]rescue[e])}}; f[arr] }
  x.report { f=->a{a.map{|e|Array===e ?f[e]:[e]}.inject:+}; f[arr] }
end

result:

       user     system      total        real
   0.010000   0.000000   0.010000 (  0.000432)
   0.000000   0.000000   0.000000 (  0.000303)
   0.000000   0.000000   0.000000 (  0.000486)
   0.000000   0.000000   0.000000 (  0.000228)

1
Hello, and welcome to PPCG! Unfortunately, your answer is not valid, because of this rule: Note: If your language contains a built-in for this, then you must NOT use it.
NoOneIsHere

@NoOneIsHere, thanks, didn't know that
akostadinov

1
How does my new update stack against time-wise against yours? Also, just like my new answer, you can remove the spaces around rescue
Value Ink

@KevinLau-notKenny updated, thanks! rescue looks to be rather slow btw, like try/catch in java
akostadinov

1
Update your bytecount, too
Value Ink


2

Clojure, 68 bytes

(def f #(if(some vector? %)(f(mapcat(fn[z](if(vector? z)z[z]))%))%))

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

(f [[[20],["Hi"],"Hi",20]])
(f [[["[]"],"[]"]])

Nice first code-golf. +1 :)
Arjun

2

ANSI C, 193 bytes

#define b break;
#define c case
#define p putch(_);
char f;main(_){switch(_){c 1:putch(91);b c 34:f^=1;p b c 91:f&&p b c 93:f&&p b c 10:c 13:putch(93);return;default:p}_=getch();main(_);}

:-/, 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.


2
Welcome to PPCG!
Martin Ender

1
Welcome to PPCG! Nice first golf. Good luck ahead!
Arjun

Thanks! It was an attempt to up my points so that I can get commenting privileges elsewhere. It appears things don't work like that the accounts are for different portals. :D I will see if some nifty features from c++ can be used.
amritanshu

2

JavaScript 20 bytes

a=>(a+[]).split(',')

The array + array is equal to array.toString


@WheatWizard thanks for the welcome and I am new to the site. actually a is an argument of the function. I will try to edit out the function now.
i--

I think now it's ok @WheatWizard. Please let me know if there is a problem with this
i--

1
Actually looking at the javaScript docs an anonymous function would definitely be shorter, you would only have to add a=> to the beginning of your code.
Wheat Wizard

@WheatWizard I updated with the arrow function as you mentioned. But I have to remove the snippet because arrow function doesn't support direct invoke. It is only for callbacks
i--

1
This doesn't handle strings with commas in them correctly
Jo King

2

C#, 48 bytes

()=>{$"[{i.Replace("[","").Replace("]","")}]";};

Thought I'd post it also since nobody has given a C# solution yet. Suggestions welcome!


Welcome to the site. I haven't programmed in C# in a while but it looks to me that you might have a couple of issues. For one how is i initialized? and are you sure it works on the [["[]"],"[]"] example?
Wheat Wizard

Sorry, i is the input passed in as a string. An empty array would just translate to an empty string.
PmanAce

How about the last testcase? Also, I presume you meant to do i=>$"{i.Replace("[","").Replace("]","")}"?
Embodiment of Ignorance

Sadly doesn't work in the last case, it will get rid of empty array. :(
PmanAce

This answer doesn't pass the final test case. Since it has not been fixed for a few months, I'm voting to delete it.
mbomb007

1

Racket, 63 bytes

(define(f l)(apply append(map(λ(x)(if(list? x)(f x)`(,x)))l)))

1

Java 8 165 chars

import java.util.*;<T>T[]f(T[]a){List<T>l=new ArrayList<>();for(T e:a)if(e instanceof Object[])Collections.addAll(l,f((T[])e));else l.add(e);return(T[])l.toArray();}

Ungolfed into a class:

public class Q80096 {

    public static <T> T[] flatten(T[] array) {
        List<T> flattenedList = new ArrayList<>();
        for (T element : array)
            if (element instanceof Object[])
                 Collections.addAll(flattenedList, flatten((T[]) element));
            else
                flattenedList.add(element);
        return (T[]) flattenedList.toArray();
    }
}

This answer is based on Jeremy Harton's approach. I used it changed it in some places and created a more golf-like version.


would it be not better when using Arrays.asList() on "array" and then go the foreach with lambda and end this with a Collector?
Serverfrog

1

JavaScript, 17 Bytes

a=>eval(`[${a}]`)

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

a=>""+a

NOTE: Snippet is broken for some reason

var subject = 
  a=>eval(`[${a}]`)
<input oninput="try {output.innerHTML = subject(this.value)} catch(e) {output.innerHTML='Invaild Input'}" />
<div id="output"></div>


3
This doesn't seem to work when run in the console for input ["["]... I tried running (a=>eval([${a}]))(["["]) and got a SyntaxError
jrich

@jrich. You just get this error when you type character by character. If you copy and paste any valid array, it will work as expected. By the way, nice answer SpeedNinja, I would only change oninput event with a button click.
Washington Guedes

This doesn't work for strings with commas in them
Jo King


1

Attache, 14 bytes

{Reap[Sow@>_]}

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 and Sow 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]


1

Elixir, 74 bytes

def d(l)do l|>Stream.flat_map(fn x->if is_list(x)do d(x)else[x]end end)end

First Elixir answer, so can probably be golfed a bit.

Try it online.

Explanation:

def d(l)do l|>            # Recursive method taking a list as input:
  Stream.flat_map(fn x->  #  Map over each item `x` of the input-list:
    if is_list(x)do       #   If `x` is a list itself:
      d(x)                #    Do a recursive call with `x`
    else                  #   Else:
      [x]                 #    Simply leave `x` unchanged
    end                   #   End of the if-else statements
  end)                    #  End of the map
end                       # End of the recursive method

Of course, if builtins were allowed, this could have been 25 bytes instead:

fn(l)->List.flatten(l)end

Try it online.



Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.