Visualizar matriz aninhada


15

Você receberá uma matriz aninhada. Seu programa tem que visualizar a matriz.


Mas como?

Por exemplo, vamos assumir que temos uma matriz aninhada, como [["1","2"],[["1","2"],"3"],"4",[[[["5"]]]],"6"].

Essa matriz aninhada pode ser visualizada como:

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

Exemplos

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

Regras

  • Você pode usar string (ou outros tipos que funcionam como uma matriz aninhada) como entrada.
  • O nível máximo de "camadas" é 2 ^ 32-1.

Ele precisa ter essa visualização exata?
#

@mnbvc Sim, a menos que eu force a fazê-lo, as pessoas começam a torcer muito a E / S. Acredite, eu tentei.
Matthew Roh 21/03

Eu sinto que a retina vai ganhar isso.
Magic Octopus Urn

1
Existem restrições sobre quais caracteres podem aparecer nas strings?
Martin Ender

Questões relacionadas adicionais 1 , 2
AdmBorkBork 21/03

Respostas:


12

APL, 32 bytes

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

Teste:

      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

Explicação:

  • {... }∘0: execute a seguinte função com 0vinculado a :
    • 1=≡⍺:: se a entrada tiver profundidade 1 (ou seja, uma matriz que não contenha outras matrizes):
      • ⍵/'->': crie uma string contendo -s e >s,
      • 1↓: solte o primeiro elemento,
      • ⍵↑: e pegue os primeiros elementos. Isso resulta em uma sequência contendo ⍵-1traços e um >.
      • ⍺,⍨: acrescente a entrada,
      • ⎕←: e enviar isso para a tela
    • : de outra forma,
      • ⍺∇¨⍵+1: adicione 1 e aplique a função a cada matriz aninhada

5
Espere, é necessário inserir essa forma ascii-art?
Rɪᴋᴇʀ

4
@Riker: Não, é preciso uma matriz aninhada normal, no entanto, é assim que o Dyalog APL exibe uma matriz aninhada e (pensei) torna óbvio o que está acontecendo. Você pode construí-lo escrevendo, por exemplo ('Atom' ('Proton' ('Up Quark' 'Up Quark' 'Down Quark') 'Neutron' ('Up Quark' 'Down Quark' 'Down Quark') 'Electron')).
marinus

9
Ah ok. Isso esclarece tudo. Um pouco desapontado agora ...
#


7

Mathematica, 58 57 56 bytes

Agradecemos a Greg Martin por economizar 1 byte.

Obrigado a ngenisis por economizar 1 byte.

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

47
Bem-vindo ao PPCG! Você deve saber que as respostas que fornecem pouca ou nenhuma explicação são sinalizadas automaticamente pelo sistema e acabam na Fila de revisão de baixa qualidade . Isso pode ter sua resposta excluída. Observe que, se você tiver várias respostas excluídas, poderá receber uma suspensão temporária. Apenas um pouco de atenção!
Stewie Griffin

20
@ StewieGriffin Obrigado pela recepção calorosa, vou manter isso em mente!
Martin Ender

6
@StewieGriffin você está dando boas-vindas a um sitemod? O que está acontecendo aqui? Isso é uma piada interna? #confused E boa primavera para vocês, se estão no norte.
Mindwin

4
@ Mindwin: O Stack Exchange possui um filtro projetado para capturar respostas que dificilmente serão úteis. É provável que esse tipo de postagem (título + amostra de código curto, sem comentários) cause falsos positivos, porque parece muito com uma publicação de baixo esforço em um computador (e o comentário de Stewie Griffin contém um link para uma captura de tela que indica que um falso positivo realmente aconteceu; está tirando sarro da situação). Aqui está um exemplo de outra postagem que foi capturada no filtro.

8
@ Titus Eu adoraria adicionar um, mas não quero invalidar o comentário de Stewie. :(
Martin Ender

6

Java 7, 153 141 114 bytes

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 bytes graças a @ Barteks2x

Explicação:

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

Código do teste:

Experimente aqui.

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

Resultado:

->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
Você pode diminuí-lo um pouco (143 ou mesmo 142) usando o operador ternário for(int j=i;j-->0;r+="-");para também fazer o que a próxima linha faz e usando o argumento genérico em vez de Objeto []: 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 até 1 caractere a menos se passar 1 em vez de 0 como o primeiro argumento está ok.
barteks2x

Eu encontrei uma maneira de torná-lo ainda mais curto, removendo o [] de argumento genérico, ele economiza mais 2 personagens (mas não pode editar o comentário após> 5 minutos)
barteks2x

@ Barteks2x Obrigado! -12 bytes graças a você. :) Aliás, remover o []parâmetro para salvar 1 byte adicional gera um erro. Veja o erro aqui em > Debug após a execução.
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;}isso funciona. Além disso, você pode fazer truque genérico semelhante com corda para salvar additiona byte mas requer ou armazenando o resultado na variável antes de imprimi-lo, ou um (chamada de método ambíguo) conversão explícita: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
Não tenho certeza se isso é considerado permitido, mas 114 bytes aqui, com string vazia como argumento, em vez de zero (pode ser 1 caractere a menos se ">" for permitido como argumento) 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 o requisito para a conversão de string no tipo de retorno ao chamar já se foi.
barteks2x

6

PHP, 77 74 73 bytes

4 bytes salvos graças a @manatwork.

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

função recursiva, requer PHP 7.1 ou mais recente para o índice de string negativo.
"$e"é Arraypara matrizes; assim "$e"!=$eé o mesmo que is_array($e).

  • comece com prefixo >
  • preceda -a ao prefixo de cada nível
  • prefixo de impressão + elemento + nova linha para átomos

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

1
Se ele werent para a formatação exigida, print_r ($ array) seria ainda menor :)
ivanivan

1
Fiz apenas um teste rápido, mas parece que is_array($e)poderia ser substituído por $e[-1]!=="".
manatwork

1
@manatwork Isso é PHP <7.1 ... no PHP 7.1, isso pode ser feito com $e[-]==""... e com a condição revertida $e[-1]>"". Bom achado!
Titus

1
Talvez eu perca alguns casos de canto, mas por enquanto parece que $e[-1]>""pode ser substituído por "$e"==$e. Pelo menos no antigo PHP 5.6 eu uso.
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("");}}

forma expandida:

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

Isso pega uma string no formato correto e termina ao encontrar a última correspondência ].

Ele não usa recursão e usa tipos longos para realmente atingir a segunda regra: 2 ^ 32-1 níveis . A maioria das linguagens de script tem uma profundidade de recursão limitada ou simplesmente trava no estouro da pilha.

Eu não estou acostumado a jogar golfe em C, qualquer ajuda é apreciada :)

Obrigado no bolov por suas dicas! Especialmente obrigado a Titus, que está sempre pronto para uma boa partida de golfe (mesmo em C)!

Outros dois bytes salvos pelo fato de podermos terminar quando correspondermos ao último ]e não precisarmos corresponder a um caracter nulo.

Pode ser testado no Wandbox .



Você não pode encurtar a segunda linha para for(int d=1 ...? longpossui 4 caracteres, enquanto intapenas 3, e não há motivo para você exceder o limite 2^32 - 1para que seu envio seja válido, economizando um único byte.
Restioson 22/03/19

@Restioson int é assinado e, portanto, só funciona até 2^31-1.
Christoph

@Christoph, o desafio declarou que você não precisava ir além.
Restioson

@Restioson O desafio declara como regra The maximum level of "layers" is 2^32-1.. 2^31-1é muito menos que 2^32-1. 2^32-1não se encaixa um intpouco enquanto se encaixa em um unsignedou long(que está na maioria dos sistemas / compiladores, é claro). Portanto int, não daria uma resposta correta (como a maioria das respostas aqui deixa de ser).
Christoph

4

JavaScript (ES6), 58 51 bytes

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

Edit: Salvo 7 bytes quando @Arnauld apontou que eu poderia combinar minhas duas abordagens.


4

PHP, 129 123 112 109 95 93 91 bytes

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

A solução iterativa utiliza a cadeia STDIN:
execute echo '<input>' | php -nR '<code>'ou teste on-line .

demolir

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

Feliz que os números estão entre aspas; então eu só preciso de uma ação por vez.

Mexendo em 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"

Adicionar 3 traços $pe remover 2 para [, 4 para ]adiciona um para [e remove um para ].


Bom trabalho de novo!
Christoph

4

Python 2, 65 64 bytes

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

No momento, minha resposta começa consistentemente sem traços, assim ["foo", "bar"]é:

>foo
>bar

import sys, pprint; pprint.pprint(sys.argv)tem 43 bytes, mas não sei se ele quebra as regras de código de golfe.
Carel

Isso economiza um byte:f=lambda o,d=0:o<''and'\n'.join(f(e,d+1)for e in o)or'-'*d+'>'+o
Ben Frankel 22/03

@Carel você não pode 'importar pprint como p' ou talvez (não tenho certeza se isso funciona) 'importar pprint.pprint como p' (Deus não consigo encontrar o sinal de volta no teclado do telefone)
cole

@ Holeole .. import sys, pprint.pprint as p; p(sys.argv)ainda é 43, mas uma boa sugestão, no entanto, D Tentando import sys.argv as vrealmente aumenta um pouco ~ 48 bytes. Se alguém pudesse eliminar o sys.argv, eles economizariam muito, mas o programa se tornaria inútil. Uma abordagem recursiva é bastante longa def p(L,d=0): [p(i,d+1) if isinstance(i,list) else print(">"*d + i) for i in L], ~ 80 bytes.
Carel 23/03

3

Perl 5 , 55 bytes

53 bytes de código + -nlsinalizadores.

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

Experimente online!

Não é ideal para regex devido a alguns casos nervosos que podem potencialmente ocorrer (em particular, se um elemento da matriz contiver colchetes dentro).
Uma função anônima recursiva demoraria um pouco mais (61 bytes):

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

Experimente online!

Mas a maneira como o Perl lida com os parâmetros não é ideal para as funções de golfe: nenhum parâmetro opcional significa que eu tenho que fazer uma segunda função (anônima) chamando a primeira, e eu tenho que obter explicitamente o último parâmetro por tanto tempo my$v=pop.


3

Ruby, 49 45 46 bytes

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

Exemplo:

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

Explicação:

Função recursiva: se x==[*x]então x é uma matriz, e iteramos sobre ela. Caso contrário, recue-o.


3

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 não tem listas aninhadas com diferentes profundidades, então eu tenho que analisar a sequência de entrada por conta própria. Felizmente, a função de biblioteca readspode analisar Strings (ou seja," sequência de caracteres incluída), então eu tenho uma pequena ajuda aqui.

Exemplo de uso:

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

Experimente online!.

Como funciona:

A função #passa pela string char por char e mantém o nível de aninhamento (o primeiro parâmetro l) como uma string -com um final >. Se o cabeçalho da lista puder ser analisado como uma String, pegue le a String seguida de uma chamada recursiva com a String removida. Se o primeiro caractere for um espaço, pule-o. Se for um ,, pegue uma nova linha e continue, se for ], abaixe o nível de aninhamento e continue e mais (apenas à [esquerda) aumente o nível de aninhamento e continue. A recursão termina com a sequência de entrada vazia. A função principal (">"#)define o nível de aninhamento para ">"e chama #.


2

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

Quebras de linha adicionadas apenas para legibilidade, não incluídas na contagem de bytes.

pO predicado percorre recursivamente as matrizes, adicionando um '-' ao prefixo Fao mover um nível mais fundo. wé usado para escrever a matriz do prefixo, bem como o elemento real na saída.

Exemplo:

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

Lote, 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

Irritantemente, o lote tem problemas para comparar vírgulas. Exemplo de execução:

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

Economizou 2 bytes graças a Martin Ender

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

-"
>
T`]"

Experimente online!

Explicação

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

Primeiro, a matriz é dividida substituindo cada sequência de caracteres citada por tudo o que veio antes dela, mais ela própria, mais uma nova linha. Ao dividir dessa maneira, é possível encontrar os colchetes de abertura incomparáveis ​​antes de cada sequência.

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

Essa transliteração será substituída [por -, deixará ]inalterada e excluirá qualquer outro caractere (  -~é tudo ASCII imprimível). No entanto, ele substitui apenas os caracteres que aparecem antes da sequência final em cada linha.

-]

Em seguida, todas as instâncias de -]são removidas. Eles correspondem a pares de colchetes correspondentes, e queremos apenas colchetes incomparáveis. Após a remoção, cada linha tem um número de -s igual a quantos colchetes de abertura incomparáveis ​​vieram antes dela.

-"
>

O último -antes de a "ser substituído por >, para formar as setas.

T`]"

Por fim, todos os ]segundos restantes "são excluídos.


Parece que assume que não haverá aspas (escapadas) dentro das strings. Não tenho certeza se isso é legítimo, mas pedi esclarecimentos.
Martin Ender

@MartinEnder Boa captura, vou ficar de olho nele #
Business Cat

1

Röda , 54 bytes

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

Experimente online!

É uma função que lê a matriz de entrada do fluxo. Para cada item, ele se chama recursivamente ou imprime o item.


1

Python 3, 80 bytes

Os lambdas de Python apóiam a recursão, quem sabe?

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

Este é um contador / elogio à resposta do orlp .


Bem-vindo ao PPCG! Parece que você contou um avanço de linha à direita ou algo assim (porque eu só conto 80 bytes) e você não precisa dos espaços ao redor do =. Eu também suspeito que você pode eliminar todos os espaços após os três ), mas não estou muito familiarizado com o golfe em Python.
Martin Ender

0

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

0

Empilhados , 27 bytes

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

Experimente online!

Pega a entrada da parte superior da pilha e deixa a saída em STDOUT. Isso é simples como fazer um mapa de profundidade, repetir - dtempos, concatenar com '>' e o próprio elemento.


0

Gema, 63 caracteres

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

Como as outras soluções de análise, assume que não haverá aspas duplas escapadas nas cadeias.

Exemplo de execução:

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 caracteres

( 67 64 de código de caracteres + 3 caracteres de comando opção de linha)

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

Exemplo de execução:

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

Teste on-line

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.