지형 문자열


23

다음은 입력 예입니다. 문제가 무엇인지 설명 할 수 있습니다.

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

이 텍스트 줄을 일부 산의 지형도라고 생각하십시오. 각 괄호 세트는 하나의 고도 단위를 나타냅니다.

우리가 이것을 측면에서 "보면"산을 세로로 볼 수 있습니다.

          4 5                cherries    woohoo  
  1 2  3       moo       lik          e
                      i

이러한 지형도 중 하나가 주어지면 위의 출력과 같이지도를 수직 스케일로 출력하십시오. 다음 항목의 문자 수를 사용하여 맵에서 다른 항목을 분리하십시오. 예를 들어, 사이의 출력에 공백이 4 mooi. 마찬가지로 moo와 사이에 입력에 4 개의 문자가 i있습니다.

최소한의 문자 로이 작업을 수행하는 코드가 승리합니다.


높이가 항상 양수라고 가정하는 것이 안전합니까? 예를 들어 ((1 2))))))))))3음수 높이가 금지 된 경우 입력 이 유효하지 않아야합니다.
Cristian Lupascu

@ 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이 적용됩니다에 h, he, hel, hell,와 hello. 그것은되는 포크 열린 괄호의 수를 계산 ('('&([:+/=)한 다음 닫기 괄호의 수를 뺍니다 ')'&([:+/=). 이것은 나에게 목록을 제공 문자열에 대한 indeces와 해당 인덱스의 문자가 출력에 있어야하는 레벨 간단한 입력에서 다음을 제공합니다.

   (('('&([:+/=)-')'&([:+/=))\,.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 네, 우리 둘 다 :)
Cristian Lupascu

작동 방식에 대한 설명을 추가 하시겠습니까?
Timwi

@Timwi 나는 설명을 포함하도록 내 답변을 편집했습니다
Cristian Lupascu

5

APL (59)

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

'베이스'도 사용할 수 있어야한다고 가정했습니다. (즉 (a(b))c(d)유효하다). 이것이 필요하지 않으면 두 문자를 저장할 수 있습니다.

설명:

  • T←⍞: 입력 줄을 T에 저장
  • '()'∘=¨T: T의 각 문자에 대해 여는 괄호인지 닫는 괄호인지 확인하십시오. 부울 목록이 제공됩니다.
  • 1 ¯1∘ר: 각 목록의 두 번째 요소에 -1을 곱하십시오 (따라서 여는 괄호는 1이고 닫는 것은 -1이고 다른 문자는 0입니다).
  • +/¨: 각 내부 목록의 합계를 가져옵니다. 이제 각 문자에 대해 ∆y 값이 있습니다.
  • P←: P.에 저장
  • R←1++\P: 각 캐릭터의 키를 제공하여 누계 P를 취합니다. 괄호 밖의 문자가 첫 번째 행에 있도록 각 문자에 하나씩 추가하십시오.
  • (⍴T)∘⍴¨⍳⌈/R: 가능한 각 y- 값에 대해 해당 값만으로 구성된 T만큼 목록을 만드십시오. (예 : 1111 ..., 2222 .... 등)
  • R∘=¨:이 목록의 각 요소에 대해 R과 같은지 확인하십시오. 이제 각 수준에 대해 문자가 해당 수준에 표시되어야하는지 여부에 해당하는 0과 1의 목록이 있습니다.
  • ⍵×P=0: 이러한 각 목록에 대해 P가 해당 지점에서 0이 아닌 경우 0으로 설정하십시오. 이것은 0이 아닌 델타 -y로 문자를 제거하므로 괄호를 제거합니다.
  • ⊃,/T\¨⍨: 각 깊이에 대해 T에서 표시 할 문자를 선택하십시오.
  • ⊖↑: 행렬을 만들고 오른쪽을 위로합니다.

어떤 APL 구현을 사용하고 있습니까? 이거 공짜인가요?
FUZxxl

@FUZxxl Dyalog APL을 사용하고 있으며 Windows 버전을 무료로 다운로드 할 수 있습니다.
marinus

5

Tcl, 50

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

부정 행위의 종류, 그러나 ..

나는 ascii escape sequence를 사용하여 줄 차이를 얻 ^[[A습니다 ^[[B.


5

APL, 41 자 / 바이트 *

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

로모그래퍼, Dyalog에서 테스트 ⎕IO←1⎕ML←3환경. 필요한 입력을 받아 출력을 반환하는 함수입니다. 질문의 말을 감안할 때, 나는 그것이 받아 들일 만하다고 믿는다. 그렇지 않은 경우 stdin에서 읽고 stdout에 쓰는 버전이 4 문자 이상입니다.

⍞←⊖⍉⊃(↑∘''¨-⌿+/¨'()'∘.=,\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 기호를 상위 128 바이트에 매핑하는 다양한 레거시 단일 바이트 문자 집합에 APL을 저장할 수 있습니다. 따라서 골프를 목적으로 ASCII 문자와 APL 기호 만 사용하는 프로그램은 chars = bytes로 점수를 매길 수 있습니다.


여기 에서 APL 문자 세트를 검색하고 있는데 기호를 찾을 수 없습니다 . ¨~문자 의 조합처럼 보이는가 ?
Gareth

@Gareth 아니요, IBM APL2에 없었습니다. 당신은에서 찾을 수 있습니다 Dyalog (상업,하지만 자신의 웹 사이트에 묻혀 내그웨어 버전이있다, 그것은 골프에 대한 좋은 충분, 이럴 사용할 수있는 최고의 APL 오늘), Nars2000 (최고의 오픈 소스 APL), GNU APLNGN의 APL 중 다른 사람.
Tobia

@Gareth 그래픽 적으로 ~와 의 조합 ¨이지만 둘 다와 는 다른 문자입니다. Commute 라는 연산자 입니다. dyadic 형식으로 적용되는 dyadic 함수의 인수를 뒤집습니다 (5-2)=(2-⍨5). 모나 딕 연산자로서 이항 함수를 모나 딕으로 바꾸어 올바른 인수를 복제합니다 (2*2)=(*⍨2). 주로 큰 식을 괄호로 묶고 눈을 뛰지 않고 오른쪽에서 왼쪽으로 중단없는 함수 스트림을 작성하는 데 주로 사용됩니다. 골프에서 그것은 3*⍨1-2한 문자보다 적기 때문에 유용합니다 (1-2)*3:-)
Tobia

2
~J 와 동일 합니다.
Gareth

3

J, 56 자

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

또 다른 56 자 J 솔루션 ... 나는 (⁻1, )1 및 다른 모든 문자를 0으로 변환 한 다음 누적 합계를 취하여 깊이를 계산 [: +/\ 1 _1 0 {~ '()'&i.합니다. 나머지는 @Gareth의 솔루션과 거의 비슷합니다.


2

파이썬, 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

파이썬, 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
좋은! 루비 형광펜에서 버그를 발견했습니다 :)
Cristian Lupascu

테스트를 마쳤으며 SQL 강조 표시가 프로그램에 더 적합합니다.
Cristian Lupascu

@ w0lf ha, 당신이 맞아요. 나는 변경 //''있는 문자가 같은 계산 유지하고 하이 라이터의 버그를 방지 할 수 있습니다.
Paul Prestidge

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

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

인용 된 arg로 실행, egaout "((1 2) (3 (4 5) moo)) (i (lik (cherries) e (woohoo)))"



0

C #, 229 바이트

선행 수직 공간에 제한이없는 경우이를 사용하여 명확성을 위해 들여 쓰기 할 수 있습니다. (인쇄하기 전에 찾은 모든 줄마다 커서를 한 줄 아래로 초기화 한 다음 대괄호를 읽을 때 커서를 위 아래로 이동합니다.

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

PowerShell을 , 120 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.