ネストされた配列を視覚化する


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はい、強制しない限り、人々はI / Oをひねり始めます。私を信じて、私はそれを試しました。
マシュー盧

網膜がこれに勝つ気がします。
魔法のタコUr

1
文字列に表示できる文字に制限はありますか?
マーティンエンダー

追加の関連質問12
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:1を追加し、ネストされた各配列に関数を適用します

5
待って、それはそのアスキーアート形式で入力を取りますか?
Rɪᴋᴇʀ

4
@Riker:いいえ、通常のネストされた配列を使用しますが、これはDyalog APLがネストされた配列を表示する方法です。例えばを書くことで構築でき('Atom' ('Proton' ('Up Quark' 'Up Quark' 'Down Quark') 'Neutron' ('Up Quark' 'Down Quark' 'Down Quark') 'Electron'))ます。
マリナス

9
うん、いいよ。それはそれをクリアします。やや....のに今がっかり
Rɪᴋᴇʀ


7

Mathematica、58 57 56バイト

1バイトを節約してくれたGreg Martinに感謝します。

1バイトを節約してくれたngenisisに感謝します。

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

47
PPCGへようこそ!説明がほとんどまたはまったくない回答は、システムによって自動的にフラグが付けられ、最終的に低品質レビューキューに入れられることを知っておく必要があります。回答が削除される可能性があります。複数の回答が削除されている場合、一時的に停止される可能性があることに注意してください。ちょっと頭を上げて!
スティービーグリフィン

20
@StewieGriffin暖かい歓迎をありがとう、私はそれを心に留めておきます!
マーティンエンダー

6
@StewieGriffinあなたはサイトモッドを歓迎していますか?ここで何が起こっていますか?これは内部の冗談ですか?#confusedあなたが北にいる場合、皆さんにとって良い春です。
マインドウィン

4
@Mindwin:Stack Exchangeには、役に立たないと思われる回答をキャッチするように設計されたフィルターがあります。この種の投稿(タイトル+短いコードサンプル、コメントなし)は、コンピューターへの労力の少ない投稿のように見えるため、誤検知を引き起こす可能性が非常に高い(およびStewie Griffinのコメントには、誤検知が実際に発生したこと、それは状況をからかっています)。これがフィルターに巻き込まれた別の投稿の例です。

8
@Titus 1つ追加したいのですが、Stewieのコメントを無効にしたくありません。:(
マーティンエンダー

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

@ Barteks2xのおかげで-39バイト

説明:

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+="-");。また、次の行が何を行うには、代わりにオブジェクトのジェネリック引数を使用して、[]の 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の代わりの0を渡す場合とにも1つの文字少ないです引数は大丈夫です。
barteks2x

ジェネリック引数から[]を削除することでさらに短くする方法を見つけました。追加の2文字を保存します(ただし、5分を超えるとコメントを編集できません)
barteks2x

@ Barteks2xありがとう!-12バイトありがとう。:)ところで、[]追加の1バイトを保存するためにパラメータからを削除すると、エラーが発生します。実行後のデバッグでエラーを参照してください。
ケビン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;}これは動作します。また、あなたはadditionaバイトを保存するために、文字列と同様の一般的なトリックを行うことができますが、どちらか、それを印刷する前に、変数に結果を格納する、または明示的なキャスト(不明瞭メソッド呼び出し)が必要です: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
引数の代わりに、ゼロ(「>」が引数として許可されている場合は1文字以下とすることができる)として空の文字列で、これは許さ考えられている場合、私はわからないんだけど、114は、ここでバイトを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バイト

@manatworkのおかげで4バイト節約できました。

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では。
マナトワーク

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番目のルールである2 ^ 32-1レベルを達成するために long型を使用します。ほとんどのスクリプト言語では、再帰の深さが制限されているか、スタックオーバーフローで単純にクラッシュします。

私はCでゴルフをするのに慣れていません。どんな助けもありがたいです:)

bolovのヒントをありがとう!特に、Cでさえも良いゴルフラウンドを常に楽しんでいるTitusに感謝します!

最後に一致したら終了でき]、null文字に一致する必要はないという事実によって、さらに2バイト節約されます。

Wandboxでテストできます。



2行目を短くできませんfor(int d=1 ...か?longは4文字intですが、3 文字しかありません2^32 - 1。送信を有効にするために1文字以上節約する必要はありません。
Restioson

@Restioson intは署名されているため、まで有効2^31-1です。
クリストフ

@Christoph課題は、あなたがいなかったと述べていそれよりもさらに行くために。
-Restioson

@Restiosonチャレンジはルールとして述べていThe maximum level of "layers" is 2^32-1.ます。2^31-1は、よりもはるかに少ないです2^32-1。or に収まって2^32-1いるint間は収まりません(もちろん、ほとんどのシステム/コンパイラにあります)。したがって、正しい答えを出せません(ここでのほとんどの答えが失敗するように)。unsignedlongint
クリストフ

4

JavaScript(ES6)、58 51バイト

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

編集:@Arnauldが2つのアプローチを組み合わせることができると指摘したときに7バイトを節約しました。


4

PHP、129123112109 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 "-"
;

数字が引用符で囲まれていることを嬉しく思います。したがって、一度に必要なアクションは1つだけです。

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を]1に追加して1を[削除し]ます。


またいいね!
クリストフ

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バイトですが、コードのゴルフ規則に違反しているかどうかはわかりません。
カレル

これは、1つのバイトを保存します。f=lambda o,d=0:o<''and'\n'.join(f(e,d+1)for e in o)or'-'*d+'>'+o
ベン・フランケル

@Carelあなたは「輸入PとしてPPRINT」または多分(ないように注意してください。この作品であれば)「Pとして輸入pprint.pprint」(私は自分の携帯電話のキーボードのバックティックを見つけることができないよう良)で行うことはできません
コール

@Cole Hmm .. import sys, pprint.pprint as p; p(sys.argv)はまだ43 ですが、それでもなお良い提案import sys.argv as vです。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がパラメーターを処理する方法はゴルフ機能には最適ではありません。オプションのパラメーターがないため、最初の関数を呼び出す2番目の関数(匿名)を実行する必要があります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は文字列を解析できます(つまり、"文字列を -enclosed charシーケンス)ので、ここで少し助けてください。

使用例:

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

オンラインでお試しください!

使い方:

この関数#は、文字ごとに文字列を調べ、ネストレベル(最初のパラメーターl)を-finalの文字列として保持します>。リストの先頭が文字列として解析できる場合は、文字列を取得lし、その後に文字列を削除して再帰呼び出しを行います。最初の文字がスペースの場合、スキップします。aの場合,、改行を取得して続行します。それがの場合]、ネストレベルを下げて続行し、そうでない場合([左のみ)ネストレベルを上げて続行します。再帰は、空の入力文字列で終了します。main関数(">"#)は、ネストレベルをに設定し">"、呼び出します#


2

SWI-Prolog、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バイト

Martin Enderのおかげで2バイト節約

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

-"
>
T`]"

オンラインでお試しください!

説明

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

まず、引用符で囲まれた各文字列を、その前にあるすべての文字列と、それ自体に加えて改行で置き換えることにより、配列が分割されます。このように分割することで、各文字列の前に一致しない開き括弧を見つけることができます。

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

この音訳は、に置き換え[られ-]変更されずに残り、1文字おきに削除されます( -~すべて印刷可能なASCIIです)。ただし、各行の最終文字列の前に表示される文字のみを置き換えます。

-]

次に、すべてのインスタンス-]が削除されます。これらは一致するブラケットペアに対応し、一致しないブラケットのみが必要です。これらが削除された後、各行には、その-前に一致していない開始括弧がいくつあるかに等しい数のsがあります。

-"
>

-aの前の最後"がに置き換えられ>、矢印が形成されます。

T`]"

最後に、残り]のsおよび"sがすべて削除されます。


これは、文字列内に(エスケープされた)引用符がないことを前提としているように見えます。それが合法かどうかはわかりませんが、説明を求めました。
マーティンエンダー

@MartinEnder良いキャッチ、私はそれを監視します
ビジネス猫


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バイトしかカウントしていないため)の周りにスペースは必要ありません=。また、3つの後にすべてのスペースをドロップできると思われますが)、Pythonでのゴルフにはあまり慣れていません。
マーティンエンダー

0

Groovy、92バイト

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


0

Gema、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 characters

(67 64 characters code + 3 characters command line option)

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

Sample run:

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

On-line test

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.