Визуализировать вложенный массив


15

Вам будет предоставлен вложенный массив. Ваша программа должна визуализировать массив.


Но как?

Например, давайте предположим, что у нас есть вложенный массив, например [["1","2"],[["1","2"],"3"],"4",[[[["5"]]]],"6"].

Этот вложенный массив может быть визуализирован как:

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

Примеры

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

правила

  • Вы можете использовать строку (или другие типы, которые работают как вложенный массив) в качестве входных данных.
  • Максимальный уровень «слоев» составляет 2 ^ 32-1.

Должна ли она иметь эту точную визуализацию?
— пенальоса

@mnbvc Да, если я не заставлю это делать, люди начнут сильно искажать ввод-вывод. Поверьте мне, я попробовал это.
— Мэтью Ро

Я чувствую, что сетчатка победит это.
— Волшебный осьминог Урна

1
Есть ли какие-либо ограничения на то, какие символы могут появляться в строках?
— Мартин Эндер

Дополнительные связанные вопросы 1 , 2
— AdmBorkBork

Ответы:


12

APL, 32 байта

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

Тестовое задание:

      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

Объяснение:

  • {... }∘0: запустить следующую функцию с 0привязкой к ⍵:
    • 1=≡⍺:: если вход имеет глубину 1 (т.е. массив, который не содержит других массивов):
      • ⍵/'->': создать строку, содержащую ⍵ -s и ⍵ >s,
      • 1↓: отбросить первый элемент,
      • ⍵↑: и возьмите первые ⍵элементы. В результате получается строка, содержащая ⍵-1тире и единицу >.
      • ⍺,⍨: добавить вход к нему,
      • ⎕←: и вывести это на экран
    • ⋄: в противном случае,
      • ⍺∇¨⍵+1: добавить 1 ⍵и применить функцию к каждому вложенному массиву

5
Подождите, это принимает вклад в этой форме ascii-art?
— Rɪᴋᴇʀ

4
@Riker: Нет, для этого требуется обычный вложенный массив, однако именно так Dyalog APL отображает вложенный массив, и (как мне показалось) это делает очевидным, что происходит. Вы можете построить это, написав, например ('Atom' ('Proton' ('Up Quark' 'Up Quark' 'Down Quark') 'Neutron' ('Up Quark' 'Down Quark' 'Down Quark') 'Electron')).
— Мэринус

9
Ах хорошо. Это проясняет это. Хотя сейчас
— немного


7

Mathematica, 58 57 56 байт

Спасибо Грегу Мартину за сохранение 1 байта.

Спасибо ngenisis за сохранение 1 байта.

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

47
Добро пожаловать в PPCG! Вы должны знать, что ответы, которые дают мало объяснений или не дают их, автоматически помечаются системой и попадают в очередь проверки низкого качества . Это может удалить ваш ответ. Обратите внимание, что если у вас есть несколько удаленных ответов, вы можете получить временную приостановку. Просто немного на голову!
— Стьюи Гриффин

20
@ StewieGriffin Спасибо за теплый прием, я буду иметь это в виду!
— Мартин Эндер

6
@StewieGriffin вы приветствуете sitemod? Что здесь происходит? Это внутренняя шутка? #confused И хорошая весна для вас, ребята, если вы находитесь на севере.
— Mindwin

4
@Mindwin: в Stack Exchange есть фильтр, предназначенный для сбора ответов, которые вряд ли будут полезны. Этот вид поста (заголовок + пример короткого кода, без комментариев), скорее всего, вызовет на нем ложные срабатывания, поскольку он очень похож на пост с небольшим усилием на компьютере (и комментарий Стьюи Гриффина содержит ссылку на скриншот, который указывает что ложный позитив действительно случился, это высмеивает ситуацию). Вот пример другого поста, который попал в фильтр.

8
@Titus Я хотел бы добавить один, но я не хочу лишать законной силы комментарий Стьюи. :(
— Мартин Эндер

6

Java 7, 153 141 114 байт

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 байт благодаря @ Barteks2x

Объяснение:

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

Тестовый код:

Попробуй это здесь.

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"}));
  }
}

Выход:

->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
Вы можете получить его немного короче (143 или даже 142), используя тернарный оператор, for(int j=i;j-->0;r+="-");чтобы также делать то, что делает следующая строка, и используя универсальный аргумент вместо 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;} и даже на 1 символ меньше, если передать 1 вместо 0 в качестве первого аргумент в порядке.
— barteks2x

Я нашел способ сделать его еще короче, удалив [] из общего аргумента, он сохраняет дополнительные 2 символа (но не может редактировать комментарий через> 5 минут)
— barteks2x

@ Barteks2x Спасибо! -12 байт благодаря вам. :) Кстати, удаление []из параметра для сохранения 1 дополнительного байта дает ошибку. Смотрите ошибку здесь > Отладка после запуска.
— Кевин Круйссен

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;}это работает. Также вы можете сделать аналогичный общий трюк со строкой, чтобы сохранить дополнительный байт, но требует либо сохранения результата в переменной перед его печатью, либо явного приведения (неоднозначный вызов метода):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
Я не уверен, что это считается разрешенным, но здесь 114 байтов, с пустой строкой в ​​качестве аргумента вместо нуля (может быть на 1 символ меньше, если «>» разрешено в качестве аргумента) 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;}И требование для приведения строки к типу возврата при вызове это прошло.
— barteks2x

6

PHP, 77 74 73 байта

4 байта сохранены благодаря @manatwork.

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

рекурсивная функция, требует PHP 7.1 или новее для отрицательного индекса строки.
"$e"это Arrayдля массивов; так "$e"!=$eже, как is_array($e).

  • начать с префикса >
  • добавить -префикс к каждому уровню
  • префикс печати + элемент + перевод строки для атомов

1
75 байтов:function f($a,$p=""){foreach($a as$e)echo$p,is_array($e)?f($e,"-"):">$e\n";}
— Исмаэль Мигель

1
если это не требуется для требуемого форматирования, print_r ($ array) будет еще меньше :)
— ivanivan

1
Сделал только быстрый тест, но, кажется, is_array($e)его можно заменить на $e[-1]!=="".
— Манатворк

1
@manatwork Это PHP <7.1 ... в PHP 7.1, это можно сделать с помощью $e[-]==""... и с обратным условием $e[-1]>"". Хорошая находка!
— Тит

1
Может быть , мне не хватает некоторых угловых случаев, но сейчас похоже , $e[-1]>""может быть заменен "$e"==$e. По крайней мере, в древнем PHP 5.6 я использую.
— manatwork

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("");}}

Расширенная форма:

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("");
        }
}

Это берет строку в правильном формате и завершается при поиске последнего соответствия ].

Он не использует рекурсию и использует длинные типы для достижения второго правила: 2 ^ 32-1 уровней . Большинство языков сценариев имеют ограниченную глубину рекурсии или просто аварийно завершают работу при переполнении стека.

Я не привык к гольфу в C, любая помощь приветствуется :)

Спасибо Болову за его советы! Особенно благодаря Титу, который всегда готов к хорошей игре в гольф (даже в C)!

Еще два байта сохраняются благодаря тому факту, что мы можем закончить, как только мы сопоставим последний ]и нам не нужно совпадать с нулевым символом.

Это можно проверить в Wandbox .



Не могли бы вы сократить вторую строку до for(int d=1 ...? longимеет 4 символа, в то время как intимеет только 3, и нет никаких причин, по которым вам нужно сделать так, чтобы оно превышало значение, 2^32 - 1чтобы отправка была действительной, сохраняя вам один байт.
— Restioson

@Restioson int подписан и поэтому работает только до 2^31-1.
— Кристоф

@ Кристоф, заявив, что вам не нужно идти дальше.
— Restioson

@Restioson Задача утверждается как правило The maximum level of "layers" is 2^32-1.. 2^31-1намного меньше, чем 2^32-1. 2^32-1не подходит, в intто время как он соответствует unsignedили или long(это, конечно, на большинстве систем / компиляторов). Поэтому intне смог бы дать правильный ответ (как большинство ответов здесь не может быть).
— Кристоф

4

JavaScript (ES6), 58 51 байт

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

Редактировать: Сохранено 7 байт, когда @Arnauld указал, что я могу объединить два моих подхода.


4

PHP, 129 123 112 109 95 93 91 байт

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

Итеративное решение берет строку из STDIN:
Запустите ее echo '<input>' | php -nR '<code>'или протестируйте онлайн .

сломать

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 "-"
;

Рад, что цифры в кавычках; поэтому мне нужно только одно действие за раз.

ASCII возиться

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"

Добавление 3 штрихов $pи удаление 2 для [, 4 для ]добавляет один для [и удаляет один для ].


Хорошая работа снова!
— Кристоф

4

Python 2, 65 64 байта

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

Прямо сейчас мой ответ последовательно начинается без черточек, поэтому ["foo", "bar"]:

>foo
>bar

import sys, pprint; pprint.pprint(sys.argv)43 байта, но я не знаю, нарушает ли он правила игры в гольф.
— Карел

Это сохраняет один байт:f=lambda o,d=0:o<''and'\n'.join(f(e,d+1)for e in o)or'-'*d+'>'+o
— Бен Франкель

@Carel вы не можете «импортировать pprint как p» или, может быть (не уверен, работает ли это) «import pprint.pprint как p» (боже, мне кажется, я не могу найти обратный тик на клавиатуре телефона)
— Коул

@Cole Хмм .. import sys, pprint.pprint as p; p(sys.argv)все еще 43, но хорошее предложение тем не менее; D Попытка import sys.argv as vфактически удлиняет это приблизительно ~ 48 байтов. Если бы можно было устранить sys.argv, они бы сэкономили много, но тогда программа становится совершенно бесполезной. Рекурсивный подход довольно длинный def p(L,d=0): [p(i,d+1) if isinstance(i,list) else print(">"*d + i) for i in L], ~ 80 байт.
— Карел

3

Perl 5 , 55 байт

53 байта кода + -nlфлаги.

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

Попробуйте онлайн!

Не оптимально для регулярных выражений из-за некоторых острых случаев, которые могут произойти (в частности, если элемент массива содержит скобки внутри).
Хотя рекурсивная анонимная функция была бы чуть длиннее (61 байт):

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

Попробуйте онлайн!

Но то, как Perl обрабатывает параметры, не является оптимальным для функций игры в гольф: отсутствие дополнительных параметров означает, что мне нужно сделать вторую (анонимную) функцию, вызывающую первую, и я должен явно получить последний параметр с этой длинной my$v=pop.


3

Рубин, 49 45 46 байт

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

Пример:

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

Объяснение:

Рекурсивная функция: если x==[*x]тогда x является массивом, и мы перебираем его. Если нет, сделайте отступ.


3

Haskell, 104 байта

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 нет вложенных списков с разной глубиной, поэтому мне приходится разбирать входную строку самостоятельно. К счастью, библиотечная функция readsможет анализировать строки (т. "Е. -Замкнутая последовательность символов), поэтому здесь я немного помог.

Пример использования:

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

Попробуйте онлайн! ,

Как это устроено:

Функция #проходит строку char с помощью char и сохраняет уровень вложенности (первый параметр l) в виде строки -с финалом >. Если заголовок списка можно проанализировать как строку, возьмите lстроку и строку, а затем рекурсивный вызов со удаленной строкой. Если первый символ - пробел, пропустите его. Если это ,, возьмите новую строку и продолжайте, если это так ], снизьте уровень вложенности и продолжайте, а в противном случае (только [слева) поднимите уровень вложенности и продолжайте. Рекурсия заканчивается пустой строкой ввода. Основная функция (">"#)устанавливает уровень вложенности ">"и вызывает #.


2

SWI-Пролог, 115 байт

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

Разрывы строк добавлены только для удобства чтения, не включены в число байтов.

pПредикат рекурсивно обходит массивы, добавляя «-» к префиксу Fпри перемещении уровня глубже. wиспользуется для записи массива префиксов, а также фактического элемента в вывод.

Пример:

?- 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

Пакетный, 249 байт

@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

Досадно, что Пакет не может сравнивать запятые. Образец прогона:

[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

Сетчатка , 63 54 52 байта

Сохранено 2 байта благодаря Мартину Эндеру

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

-"
>
T`]"

Попробуйте онлайн!

объяснение

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

Во-первых, массив разбивается путем замены каждой строки в кавычках на все, что было до нее, а также на себя и на новую строку. Разбивая его так, можно найти непревзойденные открывающие скобки перед каждой строкой.

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

Эта транслитерации заменит [с -, оставить ]без изменений, а также удалить любой другой символ (  -~все печати ASCII). Однако он заменяет только символы, появляющиеся перед последней строкой в ​​каждой строке.

-]

Далее все экземпляры -]удаляются. Они соответствуют совпадающим парам скобок, и нам нужны только несопоставимые скобки. После их удаления каждая строка имеет число -s, равное количеству непревзойденных открывающих скобок перед ней.

-"
>

Последний -перед a "заменяется на >, чтобы сформировать стрелки.

T`]"

Наконец, все остальные ]s и "s удаляются.


Это выглядит так, как будто предполагается, что внутри строк не будет (экранированных) кавычек. Я не уверен, что это законно, но я попросил разъяснений.
— Мартин Эндер

@MartinEnder Хороший улов, я буду следить за ним
— Business Cat

1

Röda , 54 байта

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

Попробуйте онлайн!

Это функция, которая читает входной массив из потока. Для каждого элемента он либо вызывает себя рекурсивно, либо печатает элемент.


1

Python 3, 80 байт

Кажется, кто-то знал рекурсию поддержки лямбд Python.

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

Это счетчик / комплимент к ответу orlp .


Добро пожаловать в PPCG! Кажется, вы посчитали конечный перевод строки или что-то в этом роде (потому что я считаю только 80 байтов), и вам не нужны пробелы вокруг =. Я также подозреваю, что вы можете отбросить все пробелы после трех ), но я не очень знаком с игрой в гольф на Python.
— Мартин Эндер



0

Гема, 63 персонажа

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

Как и другие решения синтаксического анализа, предполагается, что в строках не будет экранированных двойных кавычек.

Образец прогона:

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 символов

( 67 64 символов кода + 3 символа командной строки)

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

Образец прогона:

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

Он-лайн тест

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.