地形字符串


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 2012年

@ w0lf:是的,括号总是匹配的。
beary605

Answers:


10

Ĵ,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。这是一个,其计算开放括号的数量('('&([:+/=),然后减去密切括号的数量')'&([:+/=),这给了我清单在字符串中将inIndex定义为字符串,并且该索引处的字符应位于输出中的水平上。

   (('('&([:+/=)-')'&([:+/=))\,.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

高尔夫脚本 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 2012年

想要补充说明它是如何工作的?
Timwi 2014年

@Timwi我已经编辑了答案,添加了解释
Cristian Lupascu 2014年

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。(对于每个级别,我们现在都有一个零和一的列表,这些列表分别对应于该字符是否应出现在该级别上)。
  • ⍵×P=0:对于这些列表中的每一个,如果该点的P不为零,请将其设置为零。这将消除具有非零delta-y的字符,从而消除括号。
  • ⊃,/T\¨⍨:对于每个深度,从T中选择应该出现的字符。
  • ⊖↑:创建一个矩阵,并使其正面朝上。

您正在使用哪个APL实现?免费吗?
FUZxxl 2012年

@FUZxxl我一直在使用Dyalog APL,可以免费下载Windows版本。
marinus

5

Tcl,50

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

有点作弊,但是很好。

我使用ascii转义序列来获取行差,^[[A即向上^[[B移动光标1行,向下移动光标1行。


5

APL,41个字符/字节*

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

⎕IO←1⎕ML←3环境下在Dyalog上进行了测试。该函数接受所需的输入并返回输出。考虑到问题的措辞,我认为这是可以接受的。如果不是这样的话,这是一个从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可以保存在各种传统的单字节字符集中,这些字符集将APL符号映射到高128个字节。因此,出于打高尔夫球的目的,仅使用ASCII字符和APL符号的程序可以记为chars = bytes。


我在这里搜索APL字符集,但找不到该符号。看起来像¨~字符的组合?
Gareth 2014年

嗨,@ Gareth,不,它不在IBM APL2中。您可以在Dyalog中找到它(商业的,但是在他们的网站中有一个nagware版本,对于高尔夫来说已经足够了;恕我直言,是当今最好的APL),Nars2000(最好的开源APL),GNU APLngn的APL,其他。
Tobia 2014年

@Gareth在图形上是~和的组合¨,尽管这是两者的不同字符。这是一个称为Commute的运算符。它以二进形式翻转适用于的二进功能的参数(5-2)=(2-⍨5)。作为monadic运算符,它将二元函数转换为monadic,从而复制了正确的参数:(2*2)=(*⍨2)。它通常用于从右到左编写不间断的函数流,而不必在大表达式周围加上括号并使您的视线不停。在打高尔夫球中很有用,因为它3*⍨1-2(1-2)*3:-) 少一个字符
Tobia

2
因此,这等效~于J。
Gareth 2014年

3

J,56个字符

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

另一个56个字符的J解决方案...我通过将(trans1 )转换为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 2012年

我已经测试过,SQL高亮显示对您的程序效果更好。
克里斯蒂安·卢帕斯库

@ 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

八度,128

非常类似于我的最后一个答案...

p=1;x=[0];y=input(0);for j=1:numel(y);p-=(y(j)==")");x(p,j)=y(j);p+=(y(j)=="(");end;x(x==40)=x(x==41)=x(x==0)=32;char(flipud(x))

测试

输入: "((1 2)(3 (4 5) moo)) (i (lik(cherries)e (woohoo)))"

输出:

          4 5樱桃woohoo   
  1 2 3 moo lik e           
                      一世                           

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.