Simplifier un tableau

22

Contribution

Un tableau qui peut contenir des tableaux ou des entiers positifs, consécutifs et ascendants. Les tableaux peuvent avoir n'importe quel nombre de tableaux à l'intérieur d'eux, et ainsi de suite. Aucun tableau ne sera vide.

Sortie

Ce tableau simplifié

Comment simplifier un tableau

Nous utiliserons le tableau, [1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9]]comme exemple.

Tout d'abord, nous vérifions la profondeur d'imbrication des valeurs. Voici les profondeurs et les nombres à ces profondeurs:

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

Nous construisons le tableau de sortie en prenant les nombres dans le tableau d'origine, en les regroupant en fonction de leur profondeur d'imbrication, puis en imbriquant les groupes à la profondeur de la profondeur d'origine de leurs éléments. Disposez les nombres par ordre croissant et par profondeur croissante.

Donc, notre sortie est [1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[[8]]]]]]

Exemples

[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
la source
La sortie est-elle flexible? Comme des nombres dans des lignes différentes, où chaque ligne est d'un niveau; ou autres séparateurs / séparateurs de tableaux
Luis Mendo
@LuisMendo, oui c'est flexible
Daniel
Il vous manque une paire de supports autour 8de la ligne So, our output is...... Cependant, vous l'avez corrigé dans l'extrait d'exemples.
sbisit
2
Certaines réponses génèrent une ligne vide pour les niveaux d'imbrication sans éléments. Est-il correct de retourner un tableau vide dans de tels cas, par exemple, votre premier exemple comme [1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[]]]], [[[[[8]]]]]]?
nimi

Réponses:

1

Gelée , 8 octets

fFṄḟ@;/ß

La sortie est d'un niveau par ligne, avec des lignes vides pour les niveaux sans éléments. Essayez-le en ligne!

Comment ça marche

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
la source
3

JavaScript (ES6), 139 109 octets

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

Explication à l'aide de l'exemple d'entrée: vest une méthode d'assistance qui renvoie les tableaux (avec paramètre 1) ou les valeurs (sans paramètre). Commençons par a = [1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9]]ce qui n'est pas vide. Nous filtrons les tableaux, donnant [1]. Nous nous appelons alors récursivement sur les tableaux concaténés ensemble, ce qui est [2, 3, [4], [[5, 6], 7, [[[8]]]], 9], le résultat étant [2, 3, 9, [4, 7], [[5, 6]], [[[[8]]]]]. Nous filtrons à nouveau les tableaux, ce qui nous donne le deuxième terme de notre sortie [2, 3, 9], mais nous devons faire attention à ne pas insérer de tableau vide ici. Il leur reste pour envelopper les tableaux à l' [4, 7], [[5, 6]], [[[[8]]]]intérieur des tableaux et les ajouter à la sortie, résultant en [1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[[8]]]]]].

Neil
la source
Pourrait être en mesure d'économiser quelques octets en créant un alias pour filter. Peut-être commencer parF=(x,y)=>x.filter(y)
Cyoce
@Cyoce s'est avéré être 30 à la fin!
Neil
Il vous reste certainement du golf à faire à ce sujet. Je pense que vous pouvez remplacer en toute sécurité [].concat(...v(1))avec v(1)pour économiser 14 octets. Il y a probablement quelques autres choses aussi, mais j'ai du mal à garder une trace des parenthèses imbriquées dans ma tête.
Patrick Roberts
1
@PatrickRoberts [].concat(...v(1))est une bête très différente v(1), sinon je ne le ferais pas! Pour un exemple simple, considérez a = [2, [3], [[4]]]alors v(1) = [[3], [[4]]]mais [].concat(...v(1)) = [3, [4]].
Neil
@Neil oh, wow j'aurais vraiment dû tester ma suggestion avant d'ouvrir la bouche. Je pense cependant qu'il devrait y avoir un moyen plus court de le faire ..
Patrick Roberts
2

05AB1E , 27 26 25 21 octets

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

Essayez-le en ligne! (légèrement modifié car il .gn'est pas encore sur TIO)

Explication

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

La stratégie principale consiste à parcourir chaque niveau possible du tableau imbriqué et à imprimer tous les chiffres sur une ligne, tout en conservant les non-chiffres (listes) dans une liste un niveau de moins imbriqué.

Emigna
la source
2

Perl, 52 octets

Juste un sous-programme récursif. (inhabituel pour une réponse Perl, je sais ..)

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

Appelez ça comme ça:

$ 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

Chaque ligne de la sortie correspond à un niveau de profondeur du tableau (d'où la ligne vide dans l'exemple ci-dessus).

Il peut être transformé en un programme complet pour quelques octets de plus: ajoutez un -nindicateur et un eval(à l'intérieur @{ }pour transformer l'entrée en tableau et non un tableauref) pour transformer l'entrée en tableau Perl:

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

Mon approche précédente était légèrement plus longue (65 octets), mais toujours intéressante, alors je vais la laisser ici:

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

JavaScript (ES6) 121 144 152

modifier beaucoup révisé, 1 octet enregistré thx Patrick Roberts, et 21 autres en examinant simplement le code

Fonction récursive travaillant sur les tableaux en entrée et en sortie. Je ne suis pas comme la demande d'avoir des éléments en profondeur 1 comme éléments individuels dans le réseau de sortie (tandis que des niveaux plus élevés sont regroupés en un élément) [l1,l1, [l2...], [[l3...]] ]. Bien que ce soit plus direct:[ [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,[])

Ajout d'une nouvelle ligne pour plus de lisibilité.

Quelques remarques: la ligne 2 est évaluée encore et encore à chaque appel récursif, mais seule la dernière itération en fin de récursivité est utile.
Le traitement spécial d==0en ligne 2 s'occupe de l'anomalie pour les éléments de niveau 1.
La nfonction récursive gère l'imbrication du tableau en sortie

Tester

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
la source
1
Étant donné qu'il n'y a que des tableaux imbriqués et des entiers positifs, et qu'il est spécifié qu'aucun des tableaux dans l'entrée n'est vide, un test plus facile pour votre opérateur ternaire serait à la v[0]place de v.map. Enregistre 1 octet.
Patrick Roberts
@PatrickRoberts cool thanks
edc65
1

JavaScript (ES6) 168 octets

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

Démo

sbisit
la source
1

PHP, 145 octets

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

Panne

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
la source
1

Pyth, 19 16 octets

W=Qsf!&sITp+TdQk

Essayez-le en ligne. Suite de tests.

Notez l'espace de tête. Affiche les niveaux sur des lignes comme la réponse Perl.

Explication

  • Entrée implicite dans Q.
  • filter les articles Tde Q:
    • Vérifiez si sum est Isur la dentité T.
    • Si c'était (c'était un nombre), print Tplus un espace +d.
    • Si ce n'était pas (c'était un tableau), gardez-le.
  • seuh les articles. Cela supprime une couche de tableaux de chaque élément. S'il n'en reste plus, les rendements0 .
  • Attribuez =le résultat à Q.
  • While le résultat n'est pas vide, imprimez la chaîne vide ket une nouvelle ligne.
PurkkaKoodari
la source
1

Haskell, 124 123 octets

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

Comme Haskell ne prend pas en charge les listes mixtes (entiers et liste d'entiers) par défaut, je définis un type de liste personnalisé L. Exemple d'utilisation:

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

Remarque: l'exécution prend un certain temps, car elle parcourt tous les Ints positifs (32 ou 64 bits) pour rechercher un niveau d'imbrication aussi profond. Aussi: le type de liste personnalisé ne peut pas être imprimé par défaut, donc si vous voulez voir le résultat comme dans l'exemple ci-dessus, vous devez ajouterderiving Show à la datadéclaration (-> data L=I Int|R[L] deriving Show). Parce qu'il n'est pas nécessaire pour renvoyer une liste L à partir d'une fonction, je ne compte pas les octets.

Comment ça marche:

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

Modifier @BlackCap enregistré un octet en passant d' >>=à la donotation. Merci!

nimi
la source
La notation Do enregistre un octeth l=R$do d<-[1..];[i|(e,i)<-0#l,d==e]!d
BlackCap
0

JavaScript (ES6), 127 137 134 octets

Prend un tableau en entrée et renvoie une chaîne.

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

Cas de test

Arnauld
la source
@Shebang Merci d'avoir remarqué. Cela devrait être corrigé.
Arnauld
Je crois que ça a l'air bien maintenant! :)
Kade