Đơn giản hóa một mảng


22

Đầu vào

Một mảng có thể chứa các mảng hoặc số nguyên dương, liên tiếp, tăng dần. Các mảng có thể có bất kỳ số lượng các mảng bên trong chúng, và cứ như vậy. Không có mảng sẽ trống.

Đầu ra

Mảng này đơn giản hóa

Cách đơn giản hóa một mảng

Chúng tôi sẽ sử dụng mảng, [1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9]]như ví dụ của chúng tôi.

Đầu tiên, chúng tôi kiểm tra độ sâu của các giá trị được lồng vào nhau. Dưới đây là độ sâu và số ở độ sâu đó:

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

Chúng tôi xây dựng mảng đầu ra bằng cách lấy các số trong mảng ban đầu, nhóm chúng theo độ sâu của chúng được lồng vào nhau, và sau đó lồng các nhóm ở độ sâu của độ sâu ban đầu của các phần tử của chúng. Sắp xếp các số theo thứ tự tăng dần và độ sâu tăng dần.

Vì vậy, đầu ra của chúng tôi là [1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[[8]]]]]]

Ví dụ

[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]]]]]

Đầu ra có linh hoạt không? Giống như các số trong các dòng khác nhau, trong đó mỗi dòng là một cấp; hoặc các dấu phân cách / phân cách mảng khác
Luis Mendo


@LuisMendo, vâng, nó linh hoạt
Daniel

Bạn đang thiếu một cặp khung xung quanh 8tại dòng So, our output is...... Tuy nhiên, bạn đã sửa nó trong đoạn ví dụ.
sbisit

2
Một số câu trả lời đưa ra một dòng trống cho các mức lồng nhau không có phần tử. Bạn có thể trả lại một mảng trống trong các trường hợp như vậy không, ví dụ như ví dụ đầu tiên của bạn là [1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[]]]], [[[[[8]]]]]]?
nimi

Câu trả lời:


1

Thạch , 8 byte

fFṄḟ@;/ß

Đầu ra là một cấp trên mỗi dòng, với các dòng trống cho các cấp không có phần tử. Hãy thử trực tuyến!

Làm thế nào nó hoạt động

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.

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])):[]

Giải thích bằng cách sử dụng đầu vào ví dụ: vlà một phương thức trợ giúp trả về các mảng (có tham số 1) hoặc các giá trị (không có tham số). Chúng tôi bắt đầu với a = [1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9]], đó là không trống rỗng. Chúng tôi lọc ra các mảng, đưa ra [1]. Sau đó, chúng tôi gọi đệ quy chính mình trên các mảng được nối với nhau, đó là [2, 3, [4], [[5, 6], 7, [[[8]]]], 9]kết quả [2, 3, 9, [4, 7], [[5, 6]], [[[[8]]]]]. Chúng tôi một lần nữa lọc ra các mảng, cung cấp cho chúng tôi thuật ngữ thứ hai của đầu ra [2, 3, 9], tuy nhiên chúng tôi phải cẩn thận không chèn một mảng trống ở đây. Chúng vẫn còn để bọc các mảng [4, 7], [[5, 6]], [[[[8]]]]bên trong mảng và nối chúng vào đầu ra, dẫn đến [1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[[8]]]]]].


Có thể có thể lưu một vài byte bằng cách đặt bí danh filter. Có thể bắt đầu vớiF=(x,y)=>x.filter(y)
Cyoce

@Cyoce Hóa ra là 30 cuối cùng!
Neil

Bạn chắc chắn có một số golf còn lại để làm điều này. Tôi nghĩ bạn có thể an toàn thay thế [].concat(...v(1))bằng v(1)để tiết kiệm 14 byte. Có lẽ có một vài điều khác nữa nhưng tôi đang gặp khó khăn trong việc theo dõi các dấu ngoặc đơn lồng trong đầu.
Patrick Roberts

1
@PatrickRoberts [].concat(...v(1))là một con quái vật rất khác v(1), nếu không tôi sẽ không làm điều đó! Cho một ví dụ đơn giản, xem xét a = [2, [3], [[4]]]sau đó v(1) = [[3], [[4]]]nhưng [].concat(...v(1)) = [3, [4]].
Neil

@Neil oh, wow tôi thực sự nên thử nghiệm đề nghị của tôi trước khi mở miệng. Tôi cảm thấy như nên có một cách ngắn hơn để làm điều này mặc dù ..
Patrick Roberts

2

05AB1E , 27 26 25 21 byte

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

Hãy thử trực tuyến! (sửa đổi một chút như .gchưa có trên TIO)

Giải trình

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

Chiến lược chính là lặp qua từng cấp độ có thể của mảng lồng nhau và in bất kỳ chữ số nào trên một hàng, trong khi giữ các chữ số (danh sách) trong một danh sách ít hơn một mức lồng nhau.


2

Perl, 52 byte

Chỉ là một chương trình con đệ quy. (không bình thường cho câu trả lời của Perl, tôi biết ..)

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

Gọi nó như thế:

$ 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

Mỗi dòng của đầu ra tương ứng với một mức độ sâu của mảng (do đó dòng trống trong ví dụ trên).

Nó có thể được biến thành một chương trình đầy đủ chỉ thêm một vài byte: thêm -ncờ và một eval(bên trong @{ }để chuyển đổi đầu vào thành một mảng chứ không phải là một mảng) để chuyển đổi đầu vào thành một mảng Perl:

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

Cách tiếp cận trước đây của tôi dài hơn một chút (65 byte), nhưng vẫn thú vị, vì vậy tôi sẽ để nó ở đây:

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

2

JavaScript (ES6) 121 144 152

Chỉnh sửa Đã sửa rất nhiều, 1 byte đã lưu thx Patrick Roberts và 21 lần nữa chỉ cần xem lại mã

Hàm đệ quy làm việc trên các mảng trong đầu vào và đầu ra. Tôi không thích yêu cầu có các phần tử ở độ sâu 1 dưới dạng các phần tử đơn trong mảng đầu ra (trong khi các mức lớn hơn được nhóm thành một phần tử) : [l1,l1, [l2...], [[l3...]] ]. Trong khi điều này sẽ trực tiếp hơn:[ [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,[])

Dòng mới được thêm vào để dễ đọc.

Một số lưu ý: dòng 2 được đánh giá lặp đi lặp lại ở mỗi cuộc gọi đệ quy, nhưng chỉ lần lặp cuối cùng ở cuối đệ quy là hữu ích.
Việc xử lý đặc biệt khi d==0ở dòng 2 chăm sóc sự bất thường cho các yếu tố cấp 1.
Hàm nđệ quy xử lý mảng lồng trong đầu ra

Kiểm tra

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>


1
Cho rằng chỉ có các mảng lồng nhau và các số nguyên dương và được chỉ định rằng không có mảng nào trong đầu vào trống, một thử nghiệm dễ dàng hơn cho toán tử ternary của bạn sẽ được v[0]thay thế v.map. Tiết kiệm 1 byte.
Patrick Roberts

@PatrickRoberts cảm ơn tuyệt vời
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``+']')

Bản giới thiệu


1

PHP, 145 byte

<?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]));

Phá vỡ

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

1

Pyth, 19 16 byte

W=Qsf!&sITp+TdQk

Hãy thử trực tuyến. Bộ thử nghiệm.

Lưu ý không gian hàng đầu. Đầu ra mức trên các hàng như câu trả lời Perl.

Giải trình

  • Đầu vào ngầm định trong Q.
  • fmục ilter Tcủa Qtrên:
    • Kiểm tra nếu sum là Inha khoa trên T.
    • Nếu đó là (đó là một số), print Tcộng với một không gian +... d.
    • Nếu không (đó là một mảng), hãy giữ nó.
  • sum các mặt hàng. Điều này loại bỏ một lớp mảng từ mỗi mục. Nếu không còn lại, sản lượng 0.
  • Gán =kết quả cho Q.
  • WHile kết quả là không trống, in chuỗi trống kvà một dòng mới.

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

Vì Haskell không hỗ trợ danh sách hỗn hợp (số nguyên và danh sách số nguyên) theo mặc định, tôi xác định loại danh sách tùy chỉnh L. Ví dụ sử dụng:

*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]]]]]]

Lưu ý: phải mất một thời gian để chạy, bởi vì nó lặp qua tất cả các Ints dương (32 hoặc 64 bit) để tìm kiếm một cấp độ tổ sâu. Ngoài ra: loại danh sách tùy chỉnh không thể được in theo mặc định, vì vậy nếu bạn muốn xem kết quả như trong ví dụ trên, bạn cần thêm deriving Showvào datakhai báo (-> data L=I Int|R[L] deriving Show). Bởi vì không cần thiết để trả về danh sách L từ một hàm, tôi không đếm các byte.

Làm thế nào nó hoạt động:

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

Sửa @BlackCap lưu một byte bằng cách chuyển từ >>=để doký hiệu. Cảm ơn!


Ký hiệu lưu một byteh l=R$do d<-[1..];[i|(e,i)<-0#l,d==e]!d
BlackCap

0

JavaScript (ES6), 127 137 134 byte

Lấy một mảng làm đầu vào và trả về một chuỗi.

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``}]`

Các trường hợp thử nghiệm


@Shebang Cảm ơn bạn đã chú ý. Điều này cần được sửa chữa.
Arnauld

Tôi tin rằng có vẻ tốt bây giờ! :)
Kade
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.