Vereinfachen Sie ein Array


22

Eingang

Ein Array, das Arrays oder positive, aufeinanderfolgende, aufsteigende Ganzzahlen enthalten kann. Die Arrays können eine beliebige Anzahl von Arrays enthalten, usw. Es sind keine Arrays leer.

Ausgabe

Dieses Array vereinfacht

So vereinfachen Sie ein Array

Wir werden das Array [1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9]]als unser Beispiel verwenden.

Zuerst prüfen wir, wie tief die Werte verschachtelt sind. Hier sind die Tiefen und die Zahlen in diesen Tiefen:

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

Wir konstruieren das Ausgabearray, indem wir die Zahlen im ursprünglichen Array nehmen, sie nach der Tiefe ihrer Verschachtelung gruppieren und dann die Gruppen in der Tiefe der ursprünglichen Tiefe ihrer Elemente verschachteln. Ordne die Zahlen in aufsteigender Reihenfolge und aufsteigender Tiefe an.

Unsere Ausgabe ist also [1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[[8]]]]]]

Beispiele

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

Ist die Ausgabe flexibel? Wie Zahlen in verschiedenen Zeilen, wobei jede Zeile eine Ebene hat; oder andere Array-Trennzeichen / Trennzeichen
Luis Mendo


@ LuisMendo, ja, es ist flexibel
Daniel

In der 8Zeile fehlt ein Klammerpaar So, our output is...... Sie haben es jedoch im Beispiel-Snippet behoben.
Bis

2
Einige Antworten geben eine leere Zeile für Verschachtelungsebenen ohne Elemente aus. Ist es in solchen Fällen in Ordnung, ein leeres Array zurückzugeben, z. B. Sie erstes Beispiel als [1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[]]]], [[[[[8]]]]]]?
Nimi

Antworten:


1

Gelee , 8 Bytes

fFṄḟ@;/ß

Die Ausgabe erfolgt auf einer Ebene pro Zeile mit leeren Zeilen für Ebenen ohne Elemente. Probieren Sie es online!

Wie es funktioniert

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 Bytes

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

Erläuterung anhand der Beispieleingabe: vist eine Hilfsmethode, die die Arrays (mit Parameter 1) oder Werte (ohne Parameter) zurückgibt . Wir beginnen mit a = [1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9]], was nicht leer ist. Wir filtern die Arrays heraus und geben[1] . Wir bezeichnen uns dann rekursiv als die Arrays, die zusammen verkettet sind, was [2, 3, [4], [[5, 6], 7, [[[8]]]], 9]zur Folge hat [2, 3, 9, [4, 7], [[5, 6]], [[[[8]]]]]. Wir filtern die Arrays erneut heraus, wodurch wir den zweiten Term unserer Ausgabe erhalten. [2, 3, 9]Wir müssen jedoch darauf achten, hier kein leeres Array einzufügen. Es bleibt ihnen überlassen, die Arrays [4, 7], [[5, 6]], [[[[8]]]]in Arrays zu verpacken und sie an die Ausgabe anzuhängen [1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[[8]]]]]].


Könnte in der Lage sein, ein paar Bytes zu speichern, indem ein Alias ​​für erstellt wird filter. Beginnen Sie vielleicht mitF=(x,y)=>x.filter(y)
Cyoce

@Cyoce hat sich am Ende als 30 herausgestellt!
Neil

Sie haben definitiv noch ein bisschen Golf zu spielen. Ich glaube , Sie sicher ersetzen können [].concat(...v(1))mit v(1)zu speichern 14 Bytes. Es gibt wahrscheinlich auch ein paar andere Dinge, aber ich habe es schwer, die geschachtelten Klammern in meinem Kopf im Auge zu behalten.
Patrick Roberts

1
@PatrickRoberts [].concat(...v(1))ist ein ganz anderes Biest v(1), sonst würde ich es nicht tun! Als einfaches Beispiel betrachten wir a = [2, [3], [[4]]]dann v(1) = [[3], [[4]]]doch [].concat(...v(1)) = [3, [4]].
Neil

@Neil oh, wow, ich hätte wirklich meinen Vorschlag testen sollen, bevor ich meinen Mund aufmache. Ich denke, es sollte eine kürzere Möglichkeit geben, dies zu tun.
Patrick Roberts

2

05AB1E , 27 26 25 21 Bytes

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

Probieren Sie es online! (leicht modifiziert, da .gnoch nicht auf TIO)

Erläuterung

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

Die Hauptstrategie besteht darin, jede mögliche Ebene des verschachtelten Arrays zu durchlaufen und alle Ziffern in einer Zeile zu drucken, während die Nicht-Ziffern (Listen) in einer Liste eine Ebene weniger verschachtelt bleiben.


2

Perl, 52 Bytes

Nur eine rekursive Subroutine. (ungewöhnlich für eine Perl-Antwort, ich weiß ..)

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

Nenne es so:

$ 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

Jede Zeile der Ausgabe entspricht einer Tiefenebene des Arrays (daher die leere Zeile im obigen Beispiel).

Es kann in ein vollständiges Programm für ein paar weitere Bytes umgewandelt werden: add -nflag und an eval(inside, @{ }um die Eingabe in ein Array und nicht in ein Arrayref umzuwandeln), um die Eingabe in ein Perl-Array umzuwandeln:

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

Mein früherer Ansatz war etwas länger (65 Bytes), aber immer noch interessant, also lasse ich es hier:

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

Bearbeiten Viel überarbeitet, 1 Byte gespeichert, Patrick Roberts und 21 weitere, die nur den Code überprüfen

Rekursive Funktion, die an Arrays in Eingabe und Ausgabe arbeitet. Ich weiß nicht , wie die Anfrage von Elementen in der Tiefe 1 als Einzelelemente in Ausgangsarray (während höhere Niveaus als ein Element gruppieren) [l1,l1, [l2...], [[l3...]] ]. Dies wäre zwar direkter:[ [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,[])

Neue Zeile zur besseren Lesbarkeit hinzugefügt.

Einige Hinweise: Die Zeile 2 wird bei jedem rekursiven Aufruf immer wieder ausgewertet, aber nur die letzte Iteration am Ende der Rekursion ist sinnvoll.
Durch die spezielle Behandlung d==0in Zeile 2 wird die Anomalie für Elemente der Ebene 1 behoben.
Die nrekursive Funktion behandelt die Verschachtelung des Arrays in der Ausgabe

Prüfung

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
Da es nur verschachtelte Arrays und positive Ganzzahlen gibt und angegeben ist, dass keines der Arrays in der Eingabe leer ist, wäre ein einfacherer Test für Ihren ternären Operator v[0]anstelle von v.map. Spart 1 Byte.
Patrick Roberts

@
Patrick

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


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

Nervenzusammenbruch

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 Bytes

W=Qsf!&sITp+TdQk

Probieren Sie es online aus. Testsuite.

Beachten Sie das führende Leerzeichen. Gibt Ebenen in Zeilen wie die Perl-Antwort aus.

Erläuterung

  • Implizite Eingabe in Q.
  • fWeitere Artikel Tvon Qam:
    • Überprüfen Sie, ob sum IDentity ist T.
    • Wenn es war (es war eine Zahl), print Tplus ein Leerzeichen +...d .
    • Wenn es nicht war (es war ein Array), behalte es.
  • sum die Gegenstände. Dadurch wird eine Ebene mit Arrays von jedem Element entfernt. Wenn keine mehr übrig sind, ergibt sich 0.
  • Ordnen Sie =das Ergebnis zu Q.
  • WWenn das Ergebnis nicht leer ist, drucken Sie die leere Zeichenfolge kund eine neue Zeile.

1

Haskell, 124 123 Bytes

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

Da Haskell standardmäßig keine gemischten Listen (Ganzzahlen und Liste von Ganzzahlen) unterstützt, definiere ich einen benutzerdefinierten Listentyp L. Anwendungsbeispiel:

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

Hinweis: Die Ausführung dauert einige Zeit, da alle positiven Ints (32 oder 64 Bit) durchlaufen werden, um nach einem so tiefen Nestlevel zu suchen. Außerdem: Der benutzerdefinierte Listentyp kann standardmäßig nicht gedruckt werden. Wenn Sie also das Ergebnis wie im obigen Beispiel anzeigen möchten, müssen Sie deriving Showder dataDeklaration (->) hinzufügendata L=I Int|R[L] deriving Show ). Da es nicht benötigt wird, um eine L-Liste von einer Funktion zurückzugeben, zähle ich die Bytes nicht.

Wie es funktioniert:

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

Bearbeiten @BlackCap hat ein Byte gespeichert, indem von >>=zur doNotation gewechselt wurde . Vielen Dank!


Notation speichert ein Byteh l=R$do d<-[1..];[i|(e,i)<-0#l,d==e]!d
BlackCap

0

JavaScript (ES6), 127 137 134 Bytes

Nimmt ein Array als Eingabe und gibt eine Zeichenfolge zurück.

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

Testfälle


@Shebang Danke, dass du es bemerkt hast. Dies sollte behoben werden.
Arnauld

Ich glaube das sieht jetzt gut aus! :)
Kade
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.