Bir diziyi basitleştirin


22

Giriş

Dizileri veya pozitif, ardışık, artan tam sayıları içerebilen bir dizi. Diziler, içinde herhangi bir sayıda diziye sahip olabilirler. Hiçbir dizi boş bırakılmaz.

Çıktı

Bu dizi basitleştirilmiş

Bir diziyi basitleştirme

Diziyi, [1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9]]örnek olarak kullanacağız .

İlk olarak, değerlerin ne kadar derin iç içe olduğunu kontrol ederiz. İşte derinlikler ve bu derinlikteki sayılar:

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

Çıktı dizisini, orijinal dizideki sayıları alarak, iç içe geçme derinliğine göre gruplayarak ve ardından grupları, öğelerinin orijinal derinliklerinin derinliklerine yerleştirerek oluştururuz. Rakamları artan sırada ve artan derinlikte düzenleyin.

Yani çıktımız [1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[[8]]]]]]

Örnekler

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

Çıktı esnek mi? Her satırın bir seviye olduğu farklı satırlardaki sayılar gibi; veya diğer dizi sınırlayıcılar / ayırıcılar
Luis Mendo,


@LuisMendo, evet esnek
Daniel

8Satırda bir dirsek çifti eksik So, our output is...... Ancak, örnekleri pasajında ​​düzelttiniz.
sbisit

2
Bazı cevaplar iç içe geçme seviyeleri için element içermeyen boş bir satır çıkarır. Bu gibi durumlarda boş bir dizi döndürmek uygun mudur, örneğin ilk örnek olarak [1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[]]]], [[[[[8]]]]]]?
nimi

Yanıtlar:


1

Jöle , 8 bayt

fFṄḟ@;/ß

Çıktı, satır başına bir seviyedir, elemansız seviyeler için boş satırlar. Çevrimiçi deneyin!

Nasıl çalışır

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 bayt

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

Örnek girişi kullanarak yapılan açıklama: vdizileri (parametresi olan 1) veya değerleri ( parametresiz ) döndüren yardımcı bir yöntemdir . Biz a = [1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9]]işe yaramaz olan ile başlıyoruz . Dizileri filtreleyerek veriyoruz [1]. Daha sonra tekrar tekrar kendimizi bir araya getirilen diziler üzerine çağırırız [2, 3, [4], [[5, 6], 7, [[[8]]]], 9], yani sonuç [2, 3, 9, [4, 7], [[5, 6]], [[[[8]]]]]. Bize çıktımızın ikinci terimini veren dizileri tekrar filtreliyoruz [2, 3, 9], ancak buraya boş bir dizi eklememeye özen göstermeliyiz. Dizileri dizilerin [4, 7], [[5, 6]], [[[[8]]]]içine sarmak ve çıktıya eklemek için kalırlar [1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[[8]]]]]];


Bir takma ad yaparak birkaç bayttan tasarruf edebilirsiniz filter. Belki deF=(x,y)=>x.filter(y)
Cyoce

@Cyoce Sonunda 30 olduğu ortaya çıktı!
Neil,

Bu konuda kesinlikle golf oynayacaksınız. Ben güvenle yerine düşünmek [].concat(...v(1))ile v(1)kaydet 14 bayt. Muhtemelen bir kaç şey daha var ama kafamdaki parantezleri takip etmekte zorlanıyorum.
Patrick Roberts

1
@PatrickRoberts [].concat(...v(1)), çok farklı bir canavar v(1), aksi halde yapmazdım! Basit bir örnek için, a = [2, [3], [[4]]]o zaman düşünün v(1) = [[3], [[4]]]ama [].concat(...v(1)) = [3, [4]].
Neil

@Neil oh, vay ağzı açmadan önce önerimi gerçekten test etmeliydim. Bunu yapmanın daha kısa bir yolu olması gerektiğini düşünüyorum ..
Patrick Roberts

2

05AB1E , 27 26 25 21 bayt

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

Çevrimiçi deneyin! ( .ghenüz TIO'da olmadığı için biraz değiştirilmiş )

açıklama

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

Asıl strateji, iç içe dizinin olası her seviyesinin üzerinde dolaşmak ve herhangi bir basamağı herhangi bir basamağı basarken, basamak olmayanları (listeler) bir seviyede daha az iç içe tutmaktır.


2

Perl, 52 bayt

Sadece özyinelemeli bir alt yordam. (bir Perl cevabı için alışılmadık, biliyorum ..)

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

Buna öyle diyorsun:

$ 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

Çıktının her satırı dizinin derinlik seviyesine karşılık gelir (bu nedenle yukarıdaki örnekte boş satır).

Sadece birkaç bayt için tam bir programa dönüştürülebilir: girdiyi bir Perl dizisine dönüştürmek için -nflag ve a eval( @{ }girişi bir diziye dönüştürmek için içeride) ekleyin.

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

Önceki yaklaşımım biraz daha uzundu (65 bayt), ama yine de ilginçti, bu yüzden burada olmasına izin vereceğim:

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

Düzenleme Çok fazla revize edildi, 1 byte kaydedildi thx Patrick Roberts ve 21 kod daha gözden geçirme

Girdi ve çıktıda diziler üzerinde çalışan özyinelemeli işlev. I çıkış dizisinde tek elemanlar olarak derinliği 1 de elemanlara sahip talebi gibi değil (daha fazla ilave seviyeleri tek bir eleman olarak gruplandırılmıştır) [l1,l1, [l2...], [[l3...]] ]. Bu daha doğrudan olsa da:[ [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,[])

Okunabilirlik için Newline eklendi.

Bazı notlar: 2. satır her tekrarlamalı aramada tekrar tekrar değerlendirilir, ancak tekrarlama sonunda yalnızca son yineleme yararlı olur. Satır 2’deki
özel kullanım, d==0seviye 1 elemanların anormalliğini sağlar.
nÖzyinelemeli işlevi çıktı iç içe dizi işleme

Ölçek

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
Yalnızca iç içe diziler ve pozitif tamsayılar olduğu ve girdideki hiçbir dizinin boş olmadığı ve üçlü operatörünüz için daha kolay bir test olacağı v[0]belirtildi v.map. 1 bayt kaydeder.
Patrick Roberts

@PatrickRoberts harika teşekkürler
edc65

1

JavaScript (ES6) 168 bayt

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``+']')

gösteri


1

PHP, 145 Bayt

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

Yıkmak

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 bayt

W=Qsf!&sITp+TdQk

Çevrimiçi deneyin. Test odası.

Baştaki boşluğa dikkat edin. Perl cevabı gibi satırlardaki seviyeleri çıkarır.

açıklama

  • Örtük giriş Q.
  • filter ürün Tarasında Qtarih:
    • sUm Idişliliğin açık olup olmadığını kontrol edin T.
    • Öyleyse ( psayıydı ), Tartı bir boşluk +d.
    • Eğer değilse (bir diziydi), sakla.
  • sum öğeler. Bu, her öğeden bir dizi katmanını kaldırır. Hiçbiri bırakılmazsa, verim0 .
  • Ata =sonucu Q.
  • WSonuç boş değilse, boş dizgeyi kve yeni bir satır yazdırın .

1

Haskell, 124 123 bayt

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

Haskell varsayılan olarak karışık listeleri (tam sayılar ve tam sayılar listesi) desteklemediğinden, özel bir liste türü tanımlarım L. Kullanım örneği:

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

Not: Çalıştırması biraz zaman alır, çünkü derinlemesine bir yuva bulmak için tüm pozitif Int'ler (32 veya 64bit) arasında dolaşır. Ayrıca: özel liste türü varsayılan olarak yazdırılamaz, bu nedenle sonucu yukarıdaki örnekte olduğu gibi görmek istiyorsanız deriving Show, databildirime eklemeniz gerekir (->data L=I Int|R[L] deriving Show ). Bir L-listesinin bir fonksiyondan döndürülmesi için gerekli olmadığından, baytları saymam.

Nasıl çalışır:

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

@BlackCap Düzenle >>=, donotasyona geçiş yaparak bir bayt kaydetti . Teşekkürler!


Gösterim, bir bayt kazandırır mıh l=R$do d<-[1..];[i|(e,i)<-0#l,d==e]!d
BlackCap

0

JavaScript (ES6), 127 137 134 bayt

Bir diziyi girdi olarak alır ve bir dize döndürür.

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

Test durumları


@Shebang Fark ettiğiniz için teşekkürler. Bu düzeltilmeli.
Arnauld,

Bunun şimdi iyi göründüğüne inanıyorum! :)
Kade
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.