Sederhanakan sebuah array

22

Memasukkan

Array yang dapat berisi array atau bilangan bulat positif, berurutan, naik. Array dapat memiliki sejumlah array di dalamnya, dan seterusnya dan seterusnya. Tidak ada array yang akan kosong.

Keluaran

Array ini disederhanakan

Cara menyederhanakan array

Kami akan menggunakan array, [1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9]]sebagai contoh kami.

Pertama, kami memeriksa seberapa dalam nested. Berikut adalah kedalaman dan angka pada kedalaman tersebut:

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

Kami membangun array output dengan mengambil angka-angka dalam array asli, mengelompokkannya dengan seberapa dalam mereka bersarang, dan kemudian bersarang grup pada kedalaman kedalaman asli elemen mereka. Atur angka dalam urutan menaik dan kedalaman naik.

Jadi, output kami adalah [1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[[8]]]]]]

Contohnya

[1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9]] -> [1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[[8]]]]]]
[[[1]], [2, [3]], 4, [5, [6, [7, [8], [9, [[10]]]]]]] -> [4, [2, 5], [[1, 3, 6]], [[[7]]], [[[[8, 9]]]], [[[[[[10]]]]]]]
[1] -> [1]
[1, [2], [[3]], [[[4]]], [[[[5]]]]] -> [1, [2], [[3]], [[[4]]], [[[[5]]]]]
[1, [[[[2], 3]]] [[4]]] -> [1, [[4]], [[[3]]], [[[[2]]]]]
Daniel
sumber
Apakah output fleksibel? Seperti angka di garis yang berbeda, di mana setiap baris adalah satu tingkat; atau pembatas / pemisah array lainnya
Luis Mendo
Terkait
nimi
@LuisMendo, ya itu fleksibel
Daniel
Anda kehilangan satu pasangan braket 8di sekitar garis So, our output is...... Namun, Anda memperbaikinya dalam cuplikan contoh.
sbisit
2
Beberapa jawaban menghasilkan garis kosong untuk level bersarang tanpa elemen. Apakah boleh mengembalikan array kosong dalam kasus seperti itu, misalnya Anda contoh pertama [1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[]]]], [[[[[8]]]]]]?
nimi

Jawaban:

1

Jelly , 8 byte

fFṄḟ@;/ß

Output adalah satu level per baris, dengan baris kosong untuk level tanpa elemen. Cobalah online!

Bagaimana itu bekerja

fFṄḟ@;/ß  Main link. Argument: A (array)

 F        Flat; yield all integers (at any level) in A.
f         Filter; intersect A with the integers, yielding those at level 0.
  Ṅ       Print the filtered array and a linefeed. Yields the filtered array.
     ;/   Reduce by concatenation.
          This decreases the levels of all integers at positive levels by 1.
   ḟ@     Swapped filter-false; remove the integers at level 0 in A from the array
          with decreased levels.
       ß  Recursively call the main link on the result.
          The program stops once A is empty, since ;/ will result in an error.
Dennis
sumber
3

JavaScript (ES6), 139 109 byte

f=(a,v=b=>a.filter(a=>b^!a[0]))=>a[0]?v().concat((a=f([].concat(...v(1))),b=v())[0]?[b]:[],v(1).map(a=>[a])):[]

Penjelasan menggunakan contoh input: vadalah metode pembantu yang mengembalikan array (dengan parameter 1) atau nilai (tanpa parameter). Kita mulai dengan a = [1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9]], yang tidak kosong. Kami menyaring array, memberi [1]. Kami kemudian secara rekursif menyebut diri kami pada array yang disatukan, yang [2, 3, [4], [[5, 6], 7, [[[8]]]], 9]hasilnya adalah [2, 3, 9, [4, 7], [[5, 6]], [[[[8]]]]]. Kami sekali lagi menyaring array, yang memberi kami istilah kedua dari output kami [2, 3, 9], namun kami harus berhati-hati untuk tidak memasukkan array kosong di sini. Itu mereka tetap membungkus array [4, 7], [[5, 6]], [[[[8]]]]di dalam array dan menambahkannya ke output, menghasilkan [1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[[8]]]]]].

Neil
sumber
Mungkin dapat menyimpan beberapa byte dengan membuat alias untuk filter. Mungkin mulai denganF=(x,y)=>x.filter(y)
Cyoce
@Cyoce Ternyata menjadi 30 pada akhirnya!
Neil
Anda pasti memiliki beberapa golf tersisa untuk dilakukan dalam hal ini. Saya pikir Anda dapat dengan aman mengganti [].concat(...v(1))dengan v(1)menyimpan 14 byte. Mungkin ada beberapa hal lain juga, tetapi aku kesulitan melacak kurung bersarang di kepalaku.
Patrick Roberts
1
@ PatrickRoberts [].concat(...v(1))adalah binatang yang sangat berbeda v(1), kalau tidak saya tidak akan melakukannya! Sebagai contoh sederhana, mempertimbangkan a = [2, [3], [[4]]]kemudian v(1) = [[3], [[4]]]tapi [].concat(...v(1)) = [3, [4]].
Neil
@Neil oh, wow saya benar-benar harus menguji saran saya sebelum membuka mulut. Saya merasa harus ada cara yang lebih singkat untuk melakukan hal ini ..
Patrick Roberts
2

05AB1E , 27 26 25 21 byte

D˜gFvyydi„ÿ ?}}¶?.gG«

Cobalah online! (sedikit dimodifikasi karena .gbelum pada TIO)

Penjelasan

D˜gF                    # flattened input length times do
    vy                  # for each y current level of list
      ydi„ÿ ?}          # if y is a digit, print with space
              }         # end v-loop
               ¶?       # print newline
                 .g     # calculate length of stack (this should be .g but I can't test)
                   G«   # length stack times, concatenate items on stack

Strategi utama adalah untuk mengulang setiap tingkat yang mungkin dari array bersarang dan mencetak angka pada satu baris, sambil menjaga non-digit (daftar) dalam daftar satu tingkat lebih sedikit bersarang.

Emigna
sumber
2

Perl, 52 byte

Hanya subrutin rekursif. (tidak biasa untuk jawaban Perl, saya tahu ..)

sub f{say"@{[grep!ref,@_]}";@_&&f(map/A/?@$_:(),@_)}

Sebut saja seperti itu:

$ perl -E 'sub f{say"@{[grep!ref,@_]}";@_&&f(map/A/?@$_:(),@_)}f(1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9])'
1
2 3 9
4 7
5 6

8

Setiap baris output sesuai dengan level kedalaman array (maka baris kosong pada contoh di atas).

Itu bisa diubah menjadi program penuh hanya dengan beberapa byte lagi: tambahkan -nflag dan eval(di dalam @{ }untuk mengubah input menjadi array dan bukan arrayref) untuk mengubah input menjadi array Perl:

perl -nE 'sub f{say"@{[grep!ref,@_]}";@_&&f(map/A/?@$_:(),@_)}f(@{+eval})' <<< "[1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9]]"

Pendekatan saya sebelumnya sedikit lebih lama (65 byte), tetapi masih menarik, jadi saya akan membiarkannya di sini:

perl -nE '/\d/?push@{$;[$d-1]},$_:/]/?$d--:$d++for/\[|]|\d+/g;say"@$_"for@' <<< "[1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9]]"
Dada
sumber
2

JavaScript (ES6) 121 144 152

Sunting Revisi banyak, 1 byte disimpan thx Patrick Roberts, dan 21 lainnya hanya meninjau kode

Fungsi rekursif bekerja pada array dalam input dan output. Aku tidak suka permintaan memiliki elemen pada kedalaman 1 sebagai elemen tunggal dalam output array (sementara tingkat yang lebih besar dikelompokkan sebagai salah satu unsur): [l1,l1, [l2...], [[l3...]] ]. Sementara ini akan lebih langsung:[ [l1...], [[l2...]], [[[l3...]]] ]

f=(l,d=0,r=[])=>l.map(v=>v[0]?f(v,d+1,r):r[d]=[...r[d]||[],v])
r.reduce((r,v,d)=>d?[...r,(n=d=>d-->1?[n(d)]:v)(d)]:v,[])

Newline ditambahkan agar mudah dibaca.

Beberapa catatan: saluran 2 dievaluasi berulang kali pada setiap panggilan rekursif, tetapi hanya iterasi terakhir di akhir rekursi yang berguna.
Penanganan khusus ketika d==0di jalur 2 menangani anomali untuk elemen level 1.
Fungsi nrekursif menangani array yang bersarang dalam output

Uji

f=(l,d=0,r=[])=>l.map(v=>v[0]?f(v,d+1,r):r[d]=[...r[d]||[],v])
&&r.reduce((r,v,d)=>d?[...r,(n=d=>d-->1?[n(d)]:v)(d)]:v,[])

console.log=x=>O.textContent+=x+'\n'

test=[
 [ 
   [1, [2,3], 4], /* -> */ [1, 4, [2,3]]
 ]
,[
   [1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9]], 
   // ->
   [1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[[8]]]]]]
 ]
,[
  [[[1]], [2, [3]], 4, [5, [6, [7, [8], [9, [[10]]]]]]],
  // ->
  [4, [2, 5], [[1, 3, 6]], [[[7]]], [[[[8, 9]]]], [[[[[[10]]]]]]] 
 ]
,[  
  [1], /* -> */ [1]
 ]
,[  
  [1, [2], [[3]], [[[4]]], [[[[5]]]]],
  // ->
  [1, [2], [[3]], [[[4]]], [[[[5]]]]]
 ]
,[  
  [1, [[[[2], 3]]], [[4]]],
  [1, [[4]], [[[3]]], [[[[2]]]]]
]]

test.forEach(t=>{
  var i=t[0], k=t[1], r=f(i),
      si=JSON.stringify(i),
      sr=JSON.stringify(r),
      sk=JSON.stringify(k)
  
  console.log((sr==sk?'OK ':'KO ')+si + " => " + sr)
})
<pre id=O></pre>

edc65
sumber
1
Mengingat bahwa hanya ada array bersarang dan bilangan bulat positif, dan ditentukan bahwa tidak ada array dalam input yang kosong, maka tes yang lebih mudah untuk operator ternary Anda adalah v[0]sebagai gantinya v.map. Menghemat 1 byte.
Patrick Roberts
@ Patrickrickobert keren terima kasih
edc65
1

JavaScript (ES6) 168 byte

f=a=>(s=[],b=-1,k=0,a.replace(/\d+|\[|\]/g,a=>a=='['?b++:a==']'?b--:(s[b]=s[b]||[]).push(a)),'['+s.map((a,b)=>k=a&&(k?',':'')+'['.repeat(b)+a+']'.repeat(b)).join``+']')

Demo

sbisit
sumber
1

PHP, 145 Bytes

<?function c($r){$n=[];foreach($r as$k=>$v)if(is_array($v)){$n=array_merge($n,$v);unset($r[$k]);}if($n)$r[]=c($n);return$r;}print_r(c($_GET[a]));

Kerusakan

function c($r){
  #usort($r,function($x,$y){return is_array($x)<=>is_array($y)?:$x<=>$y;}); 
#no need to sort and a simple sort($r); do it sort array after scalar
  $n=[];
  foreach($r as$k=>$v)if(is_array($v)){$n=array_merge($n,$v);unset($r[$k]);} # put arrays on the same depth together
  if($n)$r[]=c($n); # recursive if an array exists
  return$r; #return changes
}
print_r(c($_GET[a])); #Output and Input
Jörg Hülsermann
sumber
1

Pyth, 19 16 byte

W=Qsf!&sITp+TdQk

Cobalah online. Suite uji.

Perhatikan ruang terdepan. Output level pada baris seperti jawaban Perl.

Penjelasan

  • Masukan implisit dalam Q.
  • fitem Ilter Tdari Qpada:
    • Periksa apakah sum sudah Iaktif T.
    • Jika itu (angka), printisan Tditambah spasi +d.
    • Jika bukan (itu array), simpanlah.
  • sum item. Ini menghapus lapisan array dari setiap item. Jika tidak ada yang tersisa, hasilkan 0.
  • Tetapkan =hasilnya ke Q.
  • Wsebelum hasilnya kosong, cetak string kosong kdan baris baru.
PurkkaKoodari
sumber
1

Haskell, 124 123 byte

data L=I Int|R[L]
d#R l=((d+1)#)=<<l
d#i=[(d::Int,i)]
[]!_=[]
l!1=l
l!d=[R$l!(d-1)]
h l=R$do d<-[1..];[i|(e,i)<-0#l,d==e]!d

Karena Haskell tidak mendukung daftar campuran (bilangan bulat dan daftar bilangan bulat) secara default, saya mendefinisikan jenis daftar kustom L. Contoh penggunaan:

*Main> h (R[I 1, R[I 2, I 3], R[ R[I 4]], R[ R[ R[I 5, I 6], I 7, R[R[R[I 8]]]], I 9]])
R [I 1,R [I 2,I 3,I 9],R [R [I 4,I 7]],R [R [R [I 5,I 6]]],R [R [R [R [R [I 8]]]]]]

Catatan: butuh beberapa saat untuk berjalan, karena ia memutar semua Ints positif (32 atau 64bit) untuk mencari tingkat sarang yang dalam. Juga: tipe daftar khusus tidak dapat dicetak secara default, jadi jika Anda ingin melihat hasilnya seperti pada contoh di atas, Anda perlu menambahkan deriving Showke datadeklarasi (-> data L=I Int|R[L] deriving Show). Karena tidak diperlukan untuk mengembalikan daftar-L dari suatu fungsi, saya tidak menghitung byte.

Bagaimana itu bekerja:

data L=I Int|R[L]               -- custom list type L, which is either an Int
                                -- (-> I Int) or a list of some L (-> R [L]) 

d#R l=((d+1)#)=<<l              -- # makes a list of (depth, I-number) pairs from
d#i=[(d::Int,i)]                -- a given L-list, e.g.
                                -- 0 # (R[I 1,R[I 2,I 3],I 4]) -> [(1,I 4),(2,I 2),(2,I 3),(1,I 4)]
                                -- the type annotation ::Int makes sure that all
                                -- depths are bounded. Without it, Haskell
                                -- would use arbitrary large numbers of type
                                -- ::Integer and the program won't finish

[]!_=[]                         -- ! wraps a list of Is with (d-1) additional
l!1=l                           --  R constructors
l!d=[R$l!(d-1)]

h l=                            -- main function, takes a L-list
      do d<-[1..]               -- for each nest level d make
        [i|(e,i)<-0#l,d==e]     -- a list of all I where the depth is d
                           !!d  -- and wrap it again with d-1 Rs         
     R$                         -- wrap with a final R

Mengedit @BlackCap disimpan byte dengan beralih dari >>=ke donotasi. Terima kasih!

nimi
sumber
Jangan notasi menyimpan byteh l=R$do d<-[1..];[i|(e,i)<-0#l,d==e]!d
BlackCap
0

JavaScript (ES6), 127 137 134 byte

Mengambil array sebagai input dan mengembalikan sebuah string.

f=(a,l=[],d=0,o='')=>`[${a.map(x=>x[0]?f(x,l,d+1,o+'['):l[d]=(l[d]?l[d]+',':o)+x),l.map((s,d)=>x+s+']'.repeat(d,x=','),x='').join``}]`

Uji kasus

Arnauld
sumber
@ Shebang Terima kasih telah memperhatikan. Ini harus diperbaiki.
Arnauld
Saya percaya itu terlihat bagus sekarang! :)
Kade