You will be given a nested array. Your program has to visualize the array.


But.. How?

For example, let's assume we have a nested array, like [["1","2"],[["1","2"],"3"],"4",[[[["5"]]]],"6"].

This nested array can be visualised as:

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

Examples

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

Rules

  • You may use string (or other types which work like a nested array) as input.
  • The maximum level of "layers" is 2^32-1.
share|improve this question
    
Does it have to have this exact visualisation? – mnbvc 20 hours ago
    
@mnbvc Yes, unless I force to do it people start to twist the I/O a lot. Believe me, I tried it. – SIGSEGV 20 hours ago
    
I feel like retina will win this. – carusocomputing 16 hours ago
    
Are there any restrictions on what characters can appear in the strings? – Martin Ender 15 hours ago
    
Additional related questions 1, 2 – AdmBorkBork 14 hours ago

16 Answers 16

APL, 32 bytes

{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

Explanation:

  • {...}∘0: run the following function with 0 bound to :
    • 1=≡⍺:: if the input has depth 1 (i.e. an array that does not contain other arrays):
      • ⍵/'->': create a string containing -s and >s,
      • 1↓: drop the first element,
      • ⍵↑: and take the first elements. This results in a string containing ⍵-1 dashes and one >.
      • ⍺,⍨: append the input to it,
      • ⎕←: and output that to the screen
    • : otherwise,
      • ⍺∇¨⍵+1: add 1 to and apply the function to each nested array
share|improve this answer
2  
Wait, does it take input in that ascii-art form? – Riker 12 hours ago
    
@Riker: No, it takes a normal nested array, however this is how Dyalog APL displays a nested array, and (I thought) it makes it obvious what is going on. You could construct it by writing e.g. ('Atom' ('Proton' ('Up Quark' 'Up Quark' 'Down Quark') 'Neutron' ('Up Quark' 'Down Quark' 'Down Quark') 'Electron')). – marinus 11 hours ago
1  
Ah, okay. That clears it up. Somewhat dissapointed now though.... – Riker 11 hours ago

Mathematica, 58 57 56 bytes

Thanks to Greg Martin for saving 1 byte.

Thanks to ngenisis for saving 1 byte.

MapIndexed[Print[Table["-",Tr[1^#2]-1]<>">",#]&,#,{-1}]&
share|improve this answer
38  
Welcome to PPCG! You should know that answers that provide little or no explanation get automatically flagged by the system and end up in the Low Quality Review Queue. That might get your answer deleted. Note that if you have several deleted answers you might get a temporary suspension. Just a little heads up! – Stewie Griffin 20 hours ago
14  
@StewieGriffin Thanks for the warm welcome, I'll keep that in mind! – Martin Ender 20 hours ago
3  
@StewieGriffin are you welcoming a sitemod? What is going on here? Is this an inner joke? #confused And good spring for you guys if you are on the north. – Mindwin 13 hours ago
2  
@Mindwin: Stack Exchange has a filter designed to catch answers that are unlikely to be helpful. This sort of post (title + short code sample, no commentary) is highly likely to cause false positives on it, because it looks a lot like a low effort post to a computer (and Stewie Griffin's comment contains a link to a screenshot that indicates that a false positive did in fact happen; it's making fun of the situation). Here's an example of another post that got caught in the filter. – ais523 13 hours ago
4  
@Titus I'd love to add one but I don't want to invalidate Stewie's comment. :( – Martin Ender 10 hours ago

Java 7, 153 bytes

String r="";String c(int i,Object[]o){for(Object x:o)if(x instanceof Object[])c(i+1,(Object[])x);else{for(int j=i;j-->0;r+="-");r+=">"+x+"\n";}return r;}

Explanation:

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

Test code:

Try it here.

class M{
  String r="";String c(int i,Object[]o){for(Object x:o)if(x instanceof Object[])c(i+1,(Object[])x);else{for(int j=i;j-->0;r+="-");r+=">"+x+"\n";}return r;}

  public static void main(String[] a){
    M m = new M();
    System.out.println(m.c(0, 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(0, 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"}));
  }
}

Output:

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

>Atom
->Proton
-->Up Quark
-->Up Quark
-->Down Quark
->Neutron
-->Up Quark
-->Up Quark
-->Down Quark
>Electron
share|improve this answer

PHP, 77 bytes

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

or

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

recursive function

  • start with empty prefix
  • add a "-" to the prefix for recursion
  • print prefix+>+element+newline for atoms
share|improve this answer
1  
75 bytes: function f($a,$p=""){foreach($a as$e)echo$p,is_array($e)?f($e,"-"):">$e\n";} – Ismael Miguel 15 hours ago
    
@IsmaelMiguel Nice idea; but it fails if the sub-array has more than one element. – Titus 15 hours ago
    
@Titus PHP recursion anyway fails to meet the second rule of 2^32-1 levels :P – Christoph 15 hours ago
    
@Christoph not in PHP, if you don´t cripple your server. But ... possibly in the default config? Have to check! – Titus 15 hours ago
1  
if it werent for the required formatting, print_r($array) would be even smaller :) – ivanivan 13 hours ago

Perl 5, 55 bytes

53 bytes of code + -nl flags.

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

Try it online!

Not optimal for regex because of some edgy cases that could potentially occur (in particular, if an element of the array contains brackets inside).
A recursive anonymous function would be barely longer though (61 bytes):

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

Try it online!

But the way Perl deals with parameters isn't optimal for golfing functions: no optional parameters means I have to do a second function (anonymous) calling the first one, and I have to explicitly get the last parameter with that long my$v=pop.

share|improve this answer

JavaScript (ES6), 58 51 bytes

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

Edit: Saved 7 bytes when @Arnauld pointed out that I could combine my two approaches.

share|improve this answer

Python 2, 65 bytes

f=lambda o,s=">":o<""and"\n".join(f(e,"-"+s)for e in o)or s[1:]+o

Right now my answer consistently starts with no dashes, so ["foo", "bar"] is:

>foo
>bar
share|improve this answer

C (GCC), 201 187

f(char* a,unsigned b){unsigned d=-1,j;for(char* i=a;i<a+b;++i){*i=='['&&++d;*i==']'&&--d;if(*i=='"'){for(j=0;j++<d;)putchar('-');putchar('>');while(*++i!='"')putchar(*i);putchar('\n');}}}

expanded form:

f(char* a,unsigned b){
    unsigned d=-1,j;
    for(char* i=a;i<a+b;++i){
        *i=='['&&++d;
        *i==']'&&--d;
        if(*i=='"'){
            for(j=0;j++<d;)putchar('-');
            putchar('>');
            while(*++i!='"')putchar(*i);
            putchar('\n');
        }
    }
}

This takes a string a pair data + length (so basically C++ style).

It doesn't use recursion and uses unsigned types to actually achieve the second rule: 2^32-1 levels. Most scripting languages have a limited recursion depth or simply crash on stack overflow.

I'm not used to golf in C any help is appreciated :)

It can be tested on Melpon.

share|improve this answer

SWI-Prolog, 115 bytes

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).

Line breaks added for readability only, not included in byte count.

p predicate recursively traverses the arrays, adding a '-' to the prefix F when moving a level deeper. w is used to write the prefix array as well as the actual element to the output.

Example:

?- 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
share|improve this answer

Batch, 249 bytes

@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

Annoyingly Batch has trouble comparing commas. Sample run:

[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
share|improve this answer

Ruby, 49 45 46 bytes

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

Example:

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

Explanation:

Recursive function: if x==[*x] then x is an array, and we iterate over it. If not, indent it.

share|improve this answer
1  
I found a different way to fix it, I think you are right and an unflattened array is not a valid output. – G B 14 hours ago

PHP, 129 123 112 109 95 93 bytes

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

iterative solution takes string from STDIN: Run with echo '<input>' | php -nR '<code>'.

breakdown

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)-2)      // add "-" to or remove from prefix
;

Happy that the numbers are in quotes; so I only need one action at a time.

"["^i is "2", "]"^i is "4", subtract 2 and I get the correct offset.
($c^h)-3, 5-($c^n), 4-($c^o) and ($c^k)/3 give the same results
... $c^"2" does too, but yields warnings. And $c^"2"^" " is two bytes longer

share|improve this answer
    
Good job again! – Christoph 11 hours ago

Retina, 63 54 52 bytes

Saved 2 bytes thanks to Martin Ender

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

-"
>
T`]"

Try it online!

Explanation

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

First, the array is broken up by replacing each quoted string with everything that came before it, plus itself, plus a newline. By breaking it up like this, it's possible to find the unmatched opening brackets before each string.

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

This transliteration will replace [ with -, leave ] unchanged, and delete every other character ( -~ is all printable ASCII). However, it only replaces characters appearing before the final string on each line.

-]

Next all instances of -] are removed. These correspond to matching bracket pairs, and we only want unmatched brackets. After these are removed, each line has a number of -s equal to how many unmatched opening brackets came before it.

-"
>

The last - before a " is replaced with >, to form the arrows.

T`]"

Finally, all remaining ]s and "s are deleted.

share|improve this answer
    
This looks like it assumes that there won't be (escaped) quotes inside the strings. I'm not sure whether that's legitimate but I've asked for clarification. – Martin Ender 15 hours ago
    
@MartinEnder Good catch, I'll keep an eye on it – Basic Sunset 15 hours ago

Groovy, 92 bytes

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

Haskell, 104 bytes

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 doesn't have nested lists with different depths, so I have to parse the input string on my own. Luckily the library function reads can parse Strings (i.e. "-enclosed char sequence), so I have a little help here.

Usage example:

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

Try it online!.

How it works:

The function # goes through the string char by char and keeps the nesting level (the first parameter l) as a string of - with a final >. If the head of the list can be parsed as a String, take l and the String followed by recursive call with the String removed. If the first char is a Space, skip it. If it's a ,, take a newline and go on, if it's ], lower the nesting level and go on and else (only [ left) raise the nesting level and go on. Recursion ends with the empty input string. The main function (">"#) sets the nesting level to ">" and calls #.

share|improve this answer

Stacked, 27 bytes

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

Try it online!

Takes input from the top of the stack and leaves output on STDOUT. This is simple as doing a depth map, repeating - d times, concatenating with '>' and the element itself.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.