地形文字列


23

以下に入力例を示します。そのため、問題が何であるかを説明できます。

((1 2)(3 (4 5) moo)) (i (lik(cherries)e (woohoo)))

このテキスト行は、いくつかの山の地形図と考えてください。括弧の各セットは、高度の1単位を示しています。

これを側面から「見る」と、山が垂直に見えるようになります。

          4 5                cherries    woohoo  
  1 2  3       moo       lik          e
                      i

これらの地形図のいずれかを指定して、地図を出力しますが、上記の出力のように垂直スケールで出力します。次のアイテムまでの文字数でマップ内のさまざまなアイテムを分離します。たとえば、mooとの間の出力には4つのスペースがありますi。同様に、mooとの間の入力には4文字がありますi

最小限の文字数でこれを行うコードが勝ちです。


高さが常に正であると仮定するのは安全ですか?たとえば、((1 2))))))))))3負の高さが禁止されている場合、入力は無効である必要があります。
クリスチャンルパスク

@ w0lf:はい、括弧は常に一致します。
beary605

回答:


10

J、87 79 72 70 67 57 56文字

'( ) 'charsub|.|:(+/\@('('&=-')'&=)(],~' '$~[)"0])1!:1[1

キーボードから入力を受け取ります。例:

   '( ) 'charsub|.|:(+/\@('('&=-')'&=)(],~' '$~[)"0])1!:1[1
((1 2)(3 (4 5) moo)) (i (lik(cherries)e (woohoo)))
          4 5                cherries    woohoo
  1 2  3       moo       lik          e
                      i

説明:

この説明は、私のプログラムの最初のバージョンに基づいています。

|.|:('( ) 'charsub x)((' '$~{.@]),[{~{:@])"1(('('&([:+/=)-')'&([:+/=))\,.i.@#)x=.1!:1[1

x=.1!:1[1キーボードから入力を取りx、後で使用するために入力します

(('('&([:+/=)-')'&([:+/=))\,.i.@#)文字列(i.@#)にすべてのインデックスのリストを作成し,.(('('&([:+/=)-')'&([:+/=))\動詞の結果と結び付けます()。

(('('&([:+/=)-')'&([:+/=))\この動詞は、その入力に(文字列のすべてのプレフィックスに適用されhello、それはに適用されるhhehelhell、とhello。それはあるフォークオープン括弧の数をカウントし、('('&([:+/=)[閉じる括弧の数を差し引く')'&([:+/=)。これは私のリストを与えます文字列とそのインデックスの文字が出力にあるべきレベルのインデックスの単純な入力では、これは私に次を与えます:

   (('('&([:+/=)-')'&([:+/=))\,.i.@#)x=.1!:1[1
(one(two(three)))
1  0
1  1
1  2
1  3
2  4
2  5
2  6
2  7
3  8
3  9
3 10
3 11
3 12
3 13
2 14
1 15
0 16

((' '$~{.@]),[{~{:@])"1これは、生成したばかりのリストと('( ) 'charsub x)(すべてのブラケットをでスペースで置き換える文字列置換を行う)出力を受け取る動詞xです。リストの各項目の末尾{:@]を取得し、文字列のインデックスとして使用して文字を取得します[{~{:@]。次に,、リスト内の各項目のヘッドで示されるように、スペースの数をプレフィックスとして追加します(' '$~{.@])。前の例では、これは私に与えます:

   ('( ) 'charsub x)((' '$~{.@]),[{~{:@])"1(('('&([:+/=)-')'&([:+/=))\,.i.@#)x=.1!:1[1
(one(two(three)))

 o
 n
 e

  t
  w
  o

   t
   h
   r
   e
   e

次に、配列|:を転置し、逆に|.して目的の出力を取得します。


6

GolfScript 69

0:§;{.'()'?))3%(.§+:§' ':s*\@s\if\n}%n/.{,}%$)\;:μ;{.,μ\-s*\+}%zip n*

オンラインデモはこちら

説明:

0:§;                # declare the variable §, representing the 
                    # current vertical level and initialize it at 0

{                   # iterate for each char in the string:

    .'()'?))3% (    # add on the stack the amount by which
                    # the current vertical level should be 
                    # adjusted:
                    #   * +1 if the character is '('
                    #   * -1 if the character is ')'
                    #   * 0 otherwise

    .§+:§           # adjust the value of §

    ' ':s*          # add as many spaces as § tells us
                    # and save the space in variable s

    \@s\if\         # return current char, if it's printable,
                    # or a space if it's '(' or ')'

    n               # add a newline char

}%

n/                  # split by newline char; now we have 
                    # an array of strings on the stack.
                    # Each string is a vertical line of the
                    # final output.

.{,}%$)\;:μ;        # Iterate through the strings and find the
                    # maximum length

{
    .,μ\-s*\+       # Add spaces at the end to make all the strings 
                    # the same length
}%

zip                 # Transpose the strings

n*                  # Join the transposed strings by newline characters

@Garethはい、私たちは両方:)
クリスチャンルパスク

それがどのように機能するかの説明を追加する気ですか?
ティムウィ14

@Timwi私は説明を含めるように私の答えを編集した
クリスティアンLupascuに

5

APL(59)

⊖↑{⊃,/T\¨⍨⍵×P=0}¨R∘=¨(⍴T)∘⍴¨⍳⌈/R←1++\P←+/¨1 ¯1∘ר'()'∘=¨T←⍞

「ベース」も使用可能である必要があると想定しました。(つまり(a(b))c(d)有効です)。これが必要でない場合は、2文字を保存できます。

説明:

  • T←⍞:入力行をTに保存します
  • '()'∘=¨T:Tの各文字について、それが開き括弧か閉じ括弧かを確認します。これはブール値のリストのリストを提供します。
  • 1 ¯1∘ר:これらの各リストの2番目の要素に-1を掛けます(したがって、開き括弧は1、閉じ括弧は-1、その他の文字は0です)。
  • +/¨:各内部リストの合計を取得します。これで、各文字の∆y値が得られました。
  • P←:Pに保存
  • R←1++\P:合計Pを取り、各キャラクターの高さを指定します。括弧の外側の文字が最初の行にあるように、各文字に1を追加します。
  • (⍴T)∘⍴¨⍳⌈/R:可能なy値ごとに、その値のみで構成されるTのリストを作成します。(つまり、1111 ...、2222 ....など)
  • R∘=¨:このリスト内の各要素について、Rと等しいかどうかを確認します(各レベルについて、文字がそのレベルに表示されるかどうかに対応するゼロと1のリストがあります)。
  • ⍵×P=0:これらのリストのそれぞれについて、Pがそのスポットでゼロでない場合、ゼロに設定します。これにより、ゼロ以外のデルタyを持つ文字が削除されるため、括弧が削除されます。
  • ⊃,/T\¨⍨:深さごとに、表示される文字をTから選択します。
  • ⊖↑:マトリックスを作成し、右側を上にして置きます。

どのAPL実装を使用していますか?無料なの?
-FUZxxl

@FUZxxl Dyalog APLを使用していますが、Windowsバージョンは無料でダウンロードできます。
マリナス

5

Tcl、50

puts \33\[9A[string map {( \33\[A ) \33\[B} $argv]

不正行為の一種ですが、まあ..

asciiエスケープシーケンスを使用して行の違いを取得します。^[[Aつまり、カーソルを1行上に^[[B移動し、カーソルを1行下に移動します。


5

APL、41文字/バイト*

{⊖⍉⊃(↑∘''¨-⌿+/¨p∘.=,\⍵),¨⍵/⍨1-2×⍵∊p←'()'}

⎕IO←1および⎕ML←3環境で、Dyalogでテスト済み。これは、必要な入力を受け取り、出力を返す関数です。質問の文言を考えると、私はそれが受け入れられると信じています。そうでない場合は、4文字以上で、stdinから読み取り、stdoutに書き込むバージョンを次に示します。

⍞←⊖⍉⊃(↑∘''¨-⌿+/¨'()'∘.=,\a),¨a/⍨1-2×'()'∊⍨a←⍞

説明

{                                 p←'()'}  p is the string made of two parentheses
                                ⍵∊ ______  check which characters from ⍵ are parens
                            1-2× ________  -1 for every par., 1 for every other char
                         ⍵/⍨ ____________  replace () with spaces in the orig. string
    (                 ),¨ _______________  append every char to the following items
                   ,\⍵ _____________________  for every prefix of the original string
               p∘.= ________________________  check which chars are '(' and which ')'
            +/¨ ____________________________  sum: compute the number of '(' and ')'
          -⌿ _______________________________  subtract the no. of ')' from that of '('
     ↑∘''¨ _________________________________  generate as many spaces as that number
 ⊖⍉⊃ ____________________________________  make it into a table, transpose and flip

例:

topo '((1 2)(3 (4 5) moo)) (i (lik(cherries)e (woohoo)))'
          4 5                cherries    woohoo   
  1 2  3       moo       lik          e           
                      i                           

 

topo 'a  (  b ( c(d)e ) f  )  g'
            d            
          c   e          
      b           f      
a                       g

*:APLは、APLシンボルを上位128バイトにマッピングするさまざまなレガシーシングルバイト文字セットに保存できます。したがって、ゴルフの目的のために、ASCII文字とAPLシンボルのみを使用するプログラムは、chars =バイトとして記録できます。


ここで APL文字セットを検索していますが、シンボルが見つかりません。¨~文字の組み合わせのように見えますか?
ガレス14

こんにちは@Garethいいえ、IBM APL2にはありませんでした。Dyalog(商用ですが、ウェブサイトにナグウェアバージョンが埋められており、ゴルフには十分です; IMHOは現在入手可能な最高のAPL)、Nars2000(最高のオープンソースAPL)、GNU APLおよびngnのAPLで見つけることができますその他。
トビア14

@Garethグラフィック的には、との組み合わせですが~¨両方とは異なります。これはCommuteという演算子です。二項形式では、適用される二項関数の引数を反転します(5-2)=(2-⍨5)。モナド演算子として、ダイアディック関数をモナドに変換し、正しい引数を複製します(2*2)=(*⍨2)。これは、大規模な式を括弧で囲んだり、目をジャンプしたりすることなく、右から左へ関数の中断のないストリームを記述するために主に使用されます。ゴルフでは、便利なためだ3*⍨1-21文字未満です(1-2)*3:-)
トビア

2
したがって~、Jの場合と同等です。
ガレス14

3

J、56文字

'( ) 'charsub|.|:((,~#&' ')"0[:+/\1 _1 0{~'()'&i.)1!:1]1

別の56文字のJソリューション... (depth1に変換し、)1に変換し、他のすべての文字を0に変換して、深さをカウントします[: +/\ 1 _1 0 {~ '()'&i.。残りは@Garethのソリューションとほぼ同じです。


2

Python、161文字

S=raw_input()
R=range(len(S))
H=[S[:i].count('(')-S[:i].count(')')for i in R]+[0]
for h in range(max(H),0,-1):print''.join((' '+S[i])[H[i]==H[i+1]==h]for i in R)

2

Python、130

a=[""]*9
l=8
i=0
for c in raw_input():o=l;l+=c==')';l-=c=='(';a[l]=a[l].ljust(i)+c*(o==l);i+=1
print"\n".join(filter(str.strip,a))

2

ルビー1.9(129)

stdinから読み取ります。

l=0
$><<gets.split('').map{|c|x=[?(]*99;x[l+=c==?(?-1:c==?)?1:0]=c;x}.transpose.map(&:join).*(?\n).tr('()',' ').gsub(/^\s+\n/,'')

3
いいね!Rubyハイライトでバグを発見しました:)
Cristian Lupascu

私はテストしましたが、SQLの強調表示はあなたのプログラムによりよく機能します。
クリスチャンルパスク

@ w0lf ha、あなたは正しい。文字カウントを同じに保ち、蛍光ペンのバグを回避する//ように変更しまし''た。
ポール・プレスティッジ

2

C、132文字

char*p,b[999];n;
main(m){for(p=gets(memset(b,32,999));*p;++p)*p-41?*p-40?p[n*99]=*p:++n>m?m=n:0:--n;
for(;m;puts(b+m--*99))p[m*99]=0;}

説明では、提出を受け入れるために提出する必要のある入力の量を指定できなかったため、ゴルフのニーズと最も一致する制限に決めました(入力例を1つ与えたままで作業中)。この機会を利用して、チャレンジの説明に最小の最大値を指定することをお勧めします。

コードには2つのメインループがあります。最初のループはすべての非括弧文字を適切な出力行に出力し、2番目のループは各行を出力します。


1

C、149文字

#define S for(i=0;c=v[1][i++];)h+=a=c-'('?c-')'?0:-1:1,
c,i,h=0,m=0;main(int a,char**v){S m=h>m?h:m;for(;m;m--){S putchar(a||h-m?32:c);putchar(10);}}

引用引数付きで実行、egaout "((1 2)(3(4 5)moo))(i(lik(cherries)e(woohoo)))"



0

C#、229バイト

先行する垂直方向のスペースに制限がない場合は、これを使用できます(わかりやすくするためにインデントされています)。(印刷前に見つかったすべての行に対してカーソルを1行下に初期化し、括弧が読み取られるときにカーソルを上下に移動します。

using C=System.Console;
class P{
    static void Main(string[]a){
        int l=a[0].Length,i=l;
        while(i>0)
            if(a[0][--i]=='(')C.CursorTop++;
        while(++i<l){
            char c=a[0][i];
            if(c=='('){
                c=' ';
                C.CursorTop--;
            }
            if(c==')'){
                c=' ';
                C.CursorTop++;
            }
            C.Write(c);
        }
    }
}

0

PowerShell120 119バイト

(($h=($c=$args|% t*y)|%{($l+=(1,-1)[$_-40])})|sort)[-1]..0|%{$x=0;$y=$_
-join($c|%{"$_ "[$h[$x++]-ne$y-or$_-in40,41]})}

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

副作用:文字数&'として、高さが変化(して)ますが、表示されます。結果の比較:

&$f "((1 2)(3 (4 5) moo)) (i (lik(cherries)e (woohoo)))"
&$f "&&1 2'&3 &4 5' moo'' &i &lik&cherries'e &woohoo'''"

少ないゴルフ:

$chars=$args|% toCharArray

$heights=$chars|%{
    $level+=(1,-1)[$_-40]       # 40 is ASCII for '(', 41 is ASCII for ')'
    $level
}

$maxHeight=($heights|sort)[-1]

$maxHeight..0|%{
    $x=0;$y=$_
    $line=$chars|%{
        "$_ "[$heights[$x++]-ne$y -or $_-in40,41]
    }
    -join($line)
}

-1

VB.net(S&Gの場合)

最もきれいなコードではありません。

Module Q
 Sub Main(a As String())
  Dim t = a(0)
  Dim h = 0
  For Each m In (From G In (t.Select(Function(c)
                                     h += If(c = "(", 1, If(c = ")", -1, 0))
                                     Return h
                                   End Function).Select(Function(y, i) New With {.y = y, .i = i}))
             Group By G.y Into Group
             Order By   y Descending
            Select Group.ToDictionary(Function(x) x.i)
               ).Select(Function(d) New String(
                          t.Select(Function(c,i)If(d.ContainsKey(i),If(c="("c Or c=")"c," "c,c)," "c)).ToArray))
   Console.WriteLine(m)
  Next
 End Sub
End Module
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.