Visualizza array nidificato


15

Ti verrà dato un array nidificato. Il tuo programma deve visualizzare l'array.


Ma come?

Ad esempio, supponiamo di avere un array nidificato, come [["1","2"],[["1","2"],"3"],"4",[[[["5"]]]],"6"].

Questo array nidificato può essere visualizzato come:

->1
->2
-->1
-->2
->3
>4
---->5
>6

Esempi

Input 1:
["Atom",["Proton",["Up Quark", "Up Quark", "Down Quark"], "Neutron", ["Up Quark", "Down Quark", "Down Quark"], "Electron"]]
Output 1:
>Atom
->Proton
-->Up Quark
-->Up Quark
-->Down Quark
->Neutron
-->Up Quark
-->Down Quark
-->Down Quark
->Electron

Input 2:
[["1","2"],["3","4"]]
Output 2:
->1
->2
->3
->4

Regole

  • È possibile utilizzare una stringa (o altri tipi che funzionano come una matrice nidificata) come input.
  • Il livello massimo di "livelli" è 2 ^ 32-1.

Deve avere questa visualizzazione esatta?
penalosa,

@mnbvc Sì, a meno che non mi costringa a farlo, le persone iniziano a distorcere molto l'I / O. Credetemi, l'ho provato.
Matthew Roh,

Sento che la retina vincerà questo.
Magic Octopus Urn

1
Ci sono restrizioni su quali caratteri possono apparire nelle stringhe?
Martin Ender,

Altre domande correlate 1 , 2
AdmBorkBork

Risposte:


12

APL, 32 byte

{1=≡⍺:⎕←⍺,⍨⍵↑1↓⍵/'->'⋄⍺∇¨⍵+1}∘0

Test:

      r
┌────┬─────────────────────────────────────────────────────────────────────────────────────────┐
│Atom│┌──────┬──────────────────────────────┬───────┬────────────────────────────────┬────────┐│
│    ││Proton│┌────────┬────────┬──────────┐│Neutron│┌────────┬──────────┬──────────┐│Electron││
│    ││      ││Up Quark│Up Quark│Down Quark││       ││Up Quark│Down Quark│Down Quark││        ││
│    ││      │└────────┴────────┴──────────┘│       │└────────┴──────────┴──────────┘│        ││
│    │└──────┴──────────────────────────────┴───────┴────────────────────────────────┴────────┘│
└────┴─────────────────────────────────────────────────────────────────────────────────────────┘
      {1=≡⍺:⎕←⍺,⍨⍵↑1↓⍵/'->'⋄⍺∇¨⍵+1}∘0 ⊢ r 
>Atom
->Proton
-->Up Quark
-->Up Quark
-->Down Quark
->Neutron
-->Up Quark
-->Down Quark
-->Down Quark
->Electron

Spiegazione:

  • {... }∘0: esegui la seguente funzione 0associata a :
    • 1=≡⍺:: se l'ingresso ha profondità 1 (ovvero un array che non contiene altri array):
      • ⍵/'->': crea una stringa contenente -s e >s,
      • 1↓: rilascia il primo elemento,
      • ⍵↑: e prendi i primi elementi. Ciò si traduce in una stringa contenente ⍵-1trattini e uno >.
      • ⍺,⍨: aggiungi l'input ad esso,
      • ⎕←: e l'output sullo schermo
    • : altrimenti,
      • ⍺∇¨⍵+1: aggiungi 1 a e applica la funzione a ciascun array nidificato

5
Aspetta, ci vuole input in quella forma ascii-art?
Rɪᴋᴇʀ

4
@Riker: No, ci vuole un normale array nidificato, tuttavia questo è il modo in cui Dyalog APL mostra un array nidificato e (pensavo) rende ovvio cosa sta succedendo. Potresti costruirlo scrivendo ad es ('Atom' ('Proton' ('Up Quark' 'Up Quark' 'Down Quark') 'Neutron' ('Up Quark' 'Down Quark' 'Down Quark') 'Electron')).
Marin

9
Ah ok. Questo chiarisce. Ora un po 'deluso ...
Rɪᴋᴇʀ


7

Mathematica, 58 57 56 byte

Grazie a Greg Martin per aver salvato 1 byte.

Grazie a ngenisis per il salvataggio di 1 byte.

MapIndexed[Print[Table["-",Tr[1^#2]-1]<>">",#]&,#,{-1}]&

47
Benvenuti in PPCG! Dovresti sapere che le risposte che forniscono poche o nessuna spiegazione vengono automaticamente segnalate dal sistema e finiscono nella coda di revisione di bassa qualità . Questo potrebbe far cancellare la tua risposta. Tieni presente che se hai diverse risposte eliminate potresti ottenere una sospensione temporanea. Solo un piccolo avvertimento!
Stewie Griffin,

20
@StewieGriffin Grazie per il caloroso benvenuto, lo terrò a mente!
Martin Ender,

6
@StewieGriffin stai dando il benvenuto a un sitemod? Cosa sta succedendo qui? È uno scherzo interiore? #confuso E buona primavera per voi ragazzi se venite al nord.
Mindwin

4
@Mindwin: Stack Exchange ha un filtro progettato per catturare risposte che difficilmente possono essere utili. Questo tipo di post (titolo + esempio di codice breve, nessun commento) è molto probabile che causi falsi positivi su di esso, perché assomiglia molto a un post a basso sforzo su un computer (e il commento di Stewie Griffin contiene un collegamento a uno screenshot che indica che in realtà è accaduto un falso positivo; sta prendendo in giro la situazione). Ecco un esempio di un altro post che è stato bloccato nel filtro.

8
@Titus Mi piacerebbe aggiungerne uno ma non voglio invalidare il commento di Stewie. :(
Martin Ender,

6

Java 7, 153 141 114 byte

String r="";<T,S>S c(S s,T o){for(T x:(T[])o)if(x instanceof Object[])c("-"+s,x);else r+=s+">"+x+"\n";return(S)r;}

-39 byte grazie a @ Barteks2x

Spiegazione:

String r="";                         // Result String outside the method / on class-level
<T,S> S c(S s, T o){                 // Recursive Method with generic String and Object parameters and String return-type
  for(T x : (T[])o)                  //  Loop over the input-array
    if(x instanceof Object[])        //   If the current item is an array itself:
      c("-"+s, x);                   //    Recursive method-call with this array
    else                             //   Else:
      r += s+">"+x+"\n";             //    Append return-String with stripes String-input, ">", current item, and a new-line
                                     //  End of loop (implicit / single-line body)
  return (S)r;                       //  Return the result-String
}                                    // End of method

Codice di prova:

Provalo qui.

class M{
  String r="";<T,S>S c(S s,T o){for(T x:(T[])o)if(x instanceof Object[])c("-"+s,x);else r+=s+">"+x+"\n";return(S)r;}

  public static void main(String[] a){
    M m = new M();
    System.out.println(m.c("", new Object[]{new Object[]{1,2},new Object[]{new Object[]{1,2},3},4,new Object[]{new Object[]{new Object[]{new Object[]{5}}}},6}));
    m.r = "";
    System.out.println(m.c("", new Object[]{"Atom",new Object[]{"Proton",new Object[]{"Up Quark","Up Quark","Down Quark"}},new Object[]{"Neutron",new Object[]{"Up Quark","Up Quark","Down Quark"}},"Electron"}));
  }
}

Produzione:

->1
->2
-->1
-->2
->3
>4
---->5
>6

>Atom
->Proton
-->Up Quark
-->Up Quark
-->Down Quark
->Neutron
-->Up Quark
-->Up Quark
-->Down Quark
>Electron

1
Puoi ottenerlo leggermente più breve (143 o addirittura 142) usando l'operatore ternario for(int j=i;j-->0;r+="-");per fare anche quello che fa la riga successiva, e usando l'argomento generico invece di Object []: String r="";<T>String c(int i,T[] o){for(T x:o)if(x instanceof Object[])c(i+1,(T[])x);else for(int j=i;j-->=0;r+=j<0?">"+x+"\n":"-");return r;} E anche 1 carattere in meno se si passa 1 invece di 0 come primo l'argomento è ok.
barteks2x

Ho trovato un modo per renderlo ancora più breve rimuovendo [] dall'argomento generico, salva altri 2 caratteri (ma non riesco a modificare il commento dopo> 5 minuti)
barteks2x

@ Barteks2x Grazie! -12 byte grazie a te. :) A proposito, la rimozione di []dal parametro per salvare 1 byte aggiuntivo dà un errore. Vedi l'errore qui su > Debug dopo l'esecuzione.
Kevin Cruijssen,

String r="";<T>String c(int i,T a){for(T x:(T[])a)if(x instanceof Object[])c(i+1,x);else for(int j=i;j-->0;r+=j<1?">"+x+"\n":"-");return r;}questo funziona. Inoltre puoi fare un trucco generico simile con una stringa per salvare il byte addizionale, ma richiede sia la memorizzazione del risultato in variabile prima di stamparlo, sia un cast esplicito (chiamata al metodo ambiguo):String r="";<T,S>S c(int i,T a){for(T x:(T[])a)if(x instanceof Object[])c(i+1,x);else for(int j=i;j-->0;r+=j<1?">"+x+"\n":"-");return(S)r;}
barteks2x

1
Non sono sicuro che questo sia considerato consentito, ma 114 byte qui, con stringa vuota come argomento anziché zero (può essere 1 carattere in meno se ">" è consentito come argomento) String r="";<T,S>S c(S p,T a){for(T x:(T[])a)if(x instanceof Object[])c("-"+p,x);else r+=p+">"+x+"\n";return(S)r;}E il requisito per il cast della stringa sul tipo restituito quando si chiama è andato.
barteks2x

6

PHP, 77 74 73 byte

4 byte salvati grazie a @manatwork.

function f($a,$p=">"){foreach($a as$e)"$e"!=$e?f($e,"-$p"):print"$p$e
";}

funzione ricorsiva, richiede PHP 7.1 o versione successiva per l'indice di stringa negativo.
"$e"è Arrayper array; così "$e"!=$eè lo stesso di is_array($e).

  • inizia con il prefisso >
  • anteponi -a al prefisso per ogni livello
  • stampa prefisso + elemento + newline per gli atomi

1
75 byte:function f($a,$p=""){foreach($a as$e)echo$p,is_array($e)?f($e,"-"):">$e\n";}
Ismael Miguel,

1
se fosse richiesto per la formattazione richiesta, print_r ($ array) sarebbe ancora più piccolo :)
ivanivan

1
Ha fatto solo un test rapido, ma sembra che is_array($e)potrebbe essere sostituito con $e[-1]!=="".
arte

1
@manatwork Questo è PHP <7.1 ... in PHP 7.1, può essere fatto con $e[-]==""... e con la condizione invertita $e[-1]>"". Bella scoperta!
Tito

1
Forse mi mancano alcuni casi angolari, ma per ora sembra che $e[-1]>""possano essere sostituiti "$e"==$e. Almeno nell'antico PHP 5.6 che uso.
arte

5

C99 (GCC), 201 187 140 112 109

f(char*a){for(long d=1,j;j=d+=*++a>90?92-*a:0;)if(*a<35){for(;j||*++a^34;)putchar(j?"->"[!--j]:*a);puts("");}}

forma estesa:

f(char*a){
    for(long d=1,j;j=d+=*++a>90?92-*a:0;)
        if(*a<35){
            for(;j||*++a^34;)putchar(j?--j?45:62:*a);
            puts("");
        }
}

Questo prende una stringa nel formato corretto e termina quando trova l'ultima corrispondenza ].

Non utilizza la ricorsione e utilizza tipi lunghi per ottenere effettivamente la seconda regola: livelli 2 ^ 32-1 . La maggior parte dei linguaggi di scripting ha una profondità di ricorsione limitata o semplicemente si blocca in caso di overflow dello stack.

Non sono abituato a giocare a golf in C qualsiasi aiuto è apprezzato :)

Grazie a Bolov per i suoi consigli! Soprattutto grazie a Titus che è sempre pronto per una buona partita di golf (anche in C)!

Altri due byte salvati dal fatto che possiamo terminare una volta abbinato l'ultimo ]e non è necessario che corrisponda a un carattere nullo.

Può essere testato su Wandbox .



Non potresti accorciare la seconda riga for(int d=1 ...? longha 4 caratteri mentre intne ha solo 3, e non vi è alcun motivo per cui è necessario che vada al di sopra di quello necessario 2^32 - 1affinché l'invio sia valido, salvandovi un singolo byte.
Restioson,

@Restioson int è firmato e quindi funziona solo fino al 2^31-1.
Christoph,

@Christoph la sfida dichiarato che non è stato necessario andare oltre a quello.
Restioson,

@Restioson La sfida afferma come regola The maximum level of "layers" is 2^32-1.. 2^31-1è molto meno di 2^32-1. 2^32-1non va bene per un intpo 'si adatta a un unsignedo long(che è sulla maggior parte dei sistemi / compilatori ovviamente). Pertanto intnon darebbe una risposta corretta (come la maggior parte delle risposte qui non riescono a essere).
Christoph

4

JavaScript (ES6), 58 51 byte

f=(a,s='>')=>a.map(e=>e.map?f(e,'-'+s):s+e).join`
`

Modifica: salvato 7 byte quando @Arnauld ha sottolineato che potrei combinare i miei due approcci.


4

PHP, 129 123 112 109 95 93 91 byte

for(;a&$c=$argn[++$i];)$c<A?$c<"-"?a&$s?$s=!print"$p>$s
":0:$s.=$c:$p=substr("---$p",$c^i);

soluzione iterativa prende stringa da STDIN:
Eseguire con echo '<input>' | php -nR '<code>'o prova online .

abbattersi

for(;a&$c=$argn[++$i];)     // loop $c through input characters
    $c<A                        // not brackets?
        ?$c<"-"                     // comma or quote?
            ?a&$s?$s=!print"$p>$s\n":0  // if $s not empty, print and clear $s
            :$s.=$c                     // digit: append to $s
        :$p=substr("---$p",$c^i)    // prefix plus or minus one "-"
;

Felice che i numeri siano tra virgolette; quindi ho bisogno solo di un'azione alla volta.

ASCII giocherellare

char    ascii   binary/comment
 "       34
 ,       44
 [       91     0101 1011
 ]       93     0101 1101

 A       65     $c<A    true for comma, quote and digits
 -       45     $c<"-"  true for comma and quote

                =0011 1010 -> 50 -> "2"
i^"["   105^91  ^0101 1011
 i      105      0110 1001
i^"]"   105^93  ^0101 1101
                =0011 0100 -> 52 -> "4"

Aggiungendo 3 trattini a $pe rimuovendo 2 per [, 4 per ]aggiunge uno per [e rimuove uno per ].


Ottimo lavoro di nuovo!
Christoph

4

Python 2, 65 64 byte

f=lambda o,d=0:o<''and'\n'.join(f(e,d+1)for e in o)or'-'*d+'>'+o

In questo momento la mia risposta inizia costantemente senza trattini, quindi ["foo", "bar"]è:

>foo
>bar

import sys, pprint; pprint.pprint(sys.argv)è di 43 byte ma non so se infrange le regole del codice golf.
Carel,

Ciò consente di risparmiare un byte:f=lambda o,d=0:o<''and'\n'.join(f(e,d+1)for e in o)or'-'*d+'>'+o
Ben Frankel,

@Carel non riesci a fare 'import pprint as p' o forse (non sono sicuro che funzioni) 'import pprint.pprint as p' (bontà non riesco a trovare il segno di spunta posteriore sulla tastiera del mio telefono)
cole

@Cole Hmm .. import sys, pprint.pprint as p; p(sys.argv)è ancora 43 ma un buon suggerimento comunque; D Provando in import sys.argv as vrealtà lo allunga in qualche modo ~ 48 byte. Se si potesse eliminare sys.argv, si risparmierebbe molto, ma il programma diventa abbastanza inutile. Un approccio ricorsivo è piuttosto lungo def p(L,d=0): [p(i,d+1) if isinstance(i,list) else print(">"*d + i) for i in L], ~ 80 byte.
Carel,

3

Perl 5 , 55 byte

53 byte di codice + -nlflag.

/"/?print"-"x~-$v.">$_":/]/?$v--:$v++for/]|\[|".*?"/g

Provalo online!

Non ottimale per regex a causa di alcuni casi spigolosi che potrebbero potenzialmente verificarsi (in particolare, se un elemento dell'array contiene parentesi all'interno).
Una funzione anonima ricorsiva sarebbe a malapena più lunga (61 byte):

sub f{my$v=pop;map{ref?f(@$_,$v+1):"-"x$v.">$_"}@_}sub{f@_,0}

Provalo online!

Ma il modo in cui Perl gestisce i parametri non è ottimale per le funzioni del golf: nessun parametro facoltativo significa che devo fare una seconda funzione (anonima) che chiama la prima, e devo ottenere esplicitamente l'ultimo parametro con quel tempo my$v=pop.


3

Rubino, 49 45 46 byte

f=->c,p=?>{c.map{|x|x==[*x]?f[x,?-+p]:p+x}*$/}

Esempio:

puts f[["Atom",["Proton",["Up Quark", "Up Quark", "Down Quark"], "Neutron", ["Up Quark", "Down Quark", "Down Quark"], "Electron"]]]

>Atom
->Proton
-->Up Quark
-->Up Quark
-->Down Quark
->Neutron
-->Up Quark
-->Down Quark
-->Down Quark
->Electron

Spiegazione:

Funzione ricorsiva: se x==[*x]allora x è un array, e lo ripetiamo. Altrimenti, rientralo.


3

Haskell, 104 byte

l@(x:y)#(a:m)|[(h,t)]<-reads$a:m=y++h++l#t|a<'#'=l#m|a<'-'='\n':l#m|a>'['=y#m|q<-'-':l=q#m
l#_=""
(">"#)

Haskell non ha elenchi nidificati con profondità diverse, quindi devo analizzare la stringa di input da sola. Fortunatamente la funzione di libreria readspuò analizzare le stringhe (es" sequenza di caratteri chiusa), quindi ho un piccolo aiuto qui.

Esempio di utilizzo:

*Main> putStrLn $ (">"#) "[[\"1\",\"2\"],[\"3\",\"4\"]]" 
->1
->2
->3
->4

Provalo online!.

Come funziona:

La funzione #passa attraverso il carattere stringa per carattere e mantiene il livello di annidamento (il primo parametro l) come una stringa di -con un finale >. Se la testa dell'elenco può essere analizzata come una stringa, prendere le la stringa seguita da una chiamata ricorsiva con la stringa rimossa. Se il primo carattere è uno spazio, saltalo. Se è un ,, prendi una nuova riga e vai avanti, se lo è ], abbassa il livello di nidificazione e vai avanti, altrimenti (solo a [sinistra) aumenta il livello di nidificazione e continua. La ricorsione termina con la stringa di input vuota. La funzione principale (">"#)imposta il livello di annidamento su ">"e chiama #.


2

SWI-Prolog, 115 byte

p(L):-p(L,[>]).
p([],_):-!.
p([H|T],F):-p(H,[-|F]),p(T,F),!.
p(E,[_|F]):-w(F),w([E]),nl.
w([]).
w([H|T]):-write(H),w(T).

Le interruzioni di riga sono state aggiunte solo per la leggibilità, non incluse nel conteggio dei byte.

pIl predicato attraversa ricorsivamente gli array, aggiungendo un "-" al prefisso Fquando si sposta un livello più in profondità. wviene utilizzato per scrivere l'array prefisso e l'elemento reale nell'output.

Esempio:

?- p(["Atom",["Proton",["Up Quark", "Up Quark", "Down Quark"], "Neutron", ["Up Quark", "Down Quark", "Down Quark"], "Electron"]]).
>Atom
->Proton
-->Up Quark
-->Up Quark
-->Down Quark
->Neutron
-->Up Quark
-->Down Quark
-->Down Quark
->Electron

2

Lotto, 249 byte

@echo off
set/ps=
set i=
:t
set t=
:l
set c=%s:~,1%
set s=%s:~1%
if "%c%"=="[" set i=-%i%&goto l
if not "%c%"=="]" if not "%c%"=="," set t=%t%%c%&goto l
if not "%t%"=="" echo %i:~1%^>%t%
if "%c%"=="]" set i=%i:~1%
if not "%s%"=="" goto t

Batch ha fastidiosi problemi nel confrontare le virgole. Esecuzione di esempio:

[Atom,[Proton,[Up Quark,Up Quark,Down Quark],Neutron,[Up Quark,Down Quark,Down Quark],Electron]]
>Atom
->Proton
-->Up Quark
-->Up Quark
-->Down Quark
->Neutron
-->Up Quark
-->Down Quark
-->Down Quark
->Electron

2

Retina , 63 54 52 byte

Salvato 2 byte grazie a Martin Ender

.*?".*?"
$`$&¶
T`[] -~`-]_`.(?=.*".*")
-]

-"
>
T`]"

Provalo online!

Spiegazione

.*?".*?"
$`$&¶

Innanzitutto, l'array viene suddiviso sostituendo ogni stringa tra virgolette con tutto ciò che lo precede, più se stesso e una nuova riga. Spezzandolo in questo modo, è possibile trovare le parentesi di apertura senza pari prima di ogni stringa.

T`[] -~`-]_`.(?=.*".*")

Questo traslitterazione sostituirà [con -, lasciare ]invariato, ed eliminare tutti gli altri personaggi (  -~è tutto ASCII stampabile). Tuttavia, sostituisce solo i caratteri che appaiono prima della stringa finale su ogni riga.

-]

Successivamente -]vengono rimosse tutte le istanze di . Questi corrispondono a coppie di parentesi corrispondenti e desideriamo solo parentesi senza pari. Dopo che questi sono stati rimossi, ogni riga ha un numero di -s pari a quante parentesi di apertura non corrispondenti sono state precedute.

-"
>

L'ultimo -prima di a "viene sostituito da >, per formare le frecce.

T`]"

Infine, tutti i restanti ]s e "s vengono cancellati.


Sembra che supponga che non ci siano virgolette (con escape) all'interno delle stringhe. Non sono sicuro che sia legittimo, ma ho chiesto chiarimenti.
Martin Ender,

@MartinEnder Buona cattura, lo terrò d'occhio
Business Cat

1

Röda , 54 byte

f d=""{{|n|{n|f d=`$d-`}if[n is list]else[`$d>$n
`]}_}

Provalo online!

È una funzione che legge l'array di input dal flusso. Per ogni articolo, si chiama ricorsivamente o stampa l'elemento.


1

Python 3, 80 byte

Sembra che l'agnello di Python sostenga la ricorsione, chi lo sapeva?

p=lambda l,d=1:[p(i,d+1)if isinstance(i,list)else print("-"*d+">"+i)for i in l]

Questo è un contatore / complimento per la risposta di orlp .


Benvenuti in PPCG! Sembra che tu abbia contato un avanzamento riga finale o qualcosa del genere (perché conto solo 80 byte) e non hai bisogno degli spazi attorno al =. Ho anche il sospetto che tu possa lasciare tutti gli spazi dopo i tre ), ma non ho molta familiarità con il golf in Python.
Martin Ender,

0

Groovy, 92 byte

x={a,b->if(a instanceof List){a.each{x(it,b+1)}}else{y(a,b)}};y={a,b->println("-"*b+">$a")};

0

Impilato , 27 byte

[@.1-'-'*\'>'\,,out]deepmap

Provalo online!

Prende input dalla parte superiore dello stack e lascia l'output su STDOUT. Questo è semplice come fare una mappa di profondità, ripetere i - dtempi, concatenarsi con '>' e l'elemento stesso.


0

Gema, 63 caratteri

\A=@set{i;-1}
[=@incr{i}
]=@decr{i}
"*"=@repeat{$i;-}>*\n
,<s>=

Come le altre soluzioni di analisi, presuppone che non ci siano doppie virgolette di escape nelle stringhe.

Esecuzione di esempio:

bash-4.3$ gema '\A=@set{i;-1};[=@incr{i};]=@decr{i};"*"=@repeat{$i;-}>*\n;,<s>=' <<< '[["1","2"],[["1","2"],"3"],"4",[[[["5"]]]],"6"]'
->1
->2
-->1
-->2
->3
>4
---->5
>6

0

jq, 70 67 caratteri

( 67 codice 64 caratteri + opzione riga comandi 3 caratteri)

def f(i):if type=="array"then.[]|f("-"+i)else i+. end;.[]|f(">")

Esecuzione di esempio:

bash-4.3$ jq -r 'def f(i):if type=="array"then.[]|f("-"+i)else i+. end;.[]|f(">")' <<< '[["1","2"],[["1","2"],"3"],"4",[[[["5"]]]],"6"]'
->1
->2
-->1
-->2
->3
>4
---->5
>6

Test online

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.