41

挑战

按字符计数的最短代码从输入字符串生成波形。

通过提升(第 1 行)较高的字符和降低(第+1 行)较低的字符来生成波浪。相同的字符保持在同一行(不进行提升或降级)。

输入仅由小写字符和数字组成,字母被认为高于数字。

测试用例:

Input:
    1234567890qwertyuiopasdfghjklzxcvbnm

Output:
                                 z
                                l x v n
                               k   c b m
                              j
                             h
                            g
                   y   p s f
                  t u o a d
               w r   i
            9 q e
           8 0
          7
         6
        5
       4
      3
     2
    1

Input:
    31415926535897932384626433832795028841971693993751058209749445923078164062862

Output:
                9 9   8 6 6
         9 6   8 7 3 3 4 2 4  8   9   88
    3 4 5 2 5 5     2       33 3 7 5 2  4 9   9 99 7
     1 1     3                  2   0    1 7 6 3  3 5   8              8 6
                                            1        1 5 2 9      9 3 7 1 4 6 8
                                                      0   0 7 9  5 2 0     0 2 6
                                                             4 44               2

代码计数包括输入/​​输出(即完整程序)。

4

33 回答 33

76

x86 机器码(37 字节)

十六进制转储:

6800B807BF8007BE8200B40EAC3C0D741338D8740A720481EF400181C7A000AB86C3EBE8C3

在带有 50 行控制台的 MS-DOS 中运行,输入来自命令行。

例如

wave.com 1234567890qwertyuiopasdfghjklzxcvbnm

在此处下载二进制文件

更新:感谢jrandomhacker ,减少了三个字节

于 2009-09-03T23:04:52.770 回答
40

Ĵ

54 个字符,如果您让解释器处理输入/输出。

e=:|:@((#&' '@],[)"0[:(-<./)0,[:+/\[:(}:(>-<)}.)a.i.])

65 显式地从标准输入读取并写入标准输出。

(|:((#&' '@],[)"0[:(-<./)0,[:+/\[:(}:(>-<)}.)a.&i.)~1!:1[3)1!:2[4
   e'1234567890qwertyuiopasdfghjklzxcvbnm'
                             z
                            lxvn
                           煤层气
                          j
                         H
                        G
               ypsf
              坨坨
           写
        9个
       8 0
      7
     6
    5
   4
  3
 2
1
   e'31415926535897932384626433832795028841971693993751058209749445923078164062862'
            9 9 8 6 6
     9 6 8 7 3 3 4 2 4 8 9 88
3 4 5 2 5 5 2 33 3 7 5 2 4 9 9 99 7
 1 1 3 2 0 1 7 6 3 3 5 8 8 6
                                        1 1 5 2 9 9 3 7 1 4 6 8
                                                  0 0 7 9 5 2 0 0 2 6
                                                         4 44 2


   注意。查找 ASCII 码
   ord =: ai ]
   ord 'p4ssw0rd'
112 52 115 115 119 48 114 100

   注意。往上走?
   向上=:}:<}。
   向上 ord 'p4ssw0rd'
0 1 0 1 0 1 0

   注意。下降?
   向下=:}:>}。
   向下排序“p4ssw0rd”
1 0 0 0 1 0 1

   注意。结合得到±1 
   updown =: }: (> - <) }。
   updown or 'p4ssw0rd'
1 _1 0 _1 1 _1 1

   注意。从 0 开始,然后是部分和
   sum =: 0 , +/\
   总结 ord 'p4ssw0rd'
0 1 0 0 _1 0 _1 0

   注意。减去最小值以得到碱基为 0 的序列
   fix =: - <./
   修复 sum updown ord 'p4ssw0rd'
1 2 1 1 0 1 0 1

   注意。为方便起见,将此函数链命名为
   d =: [: fix [: sum [: updown ord
   注意。在字符
   push =: (#&' ' @ ] , [)"0 d
   推“p4ssw0rd”
 p
  4
 s
 s
w
 0
r
 d

   注意。把它
   翻过来 |: push 'p4ssw0rd'
    写
p ss 0 天
 4

   注意。组合成一个命名函数… 
   e =: |: @ push 
   NB。…并内联所有内容
   e =: |:@((#&' '@],[)"0[:(-<./)0,[:+/\[:(}:(>-<)}。 )ai])
于 2009-09-03T22:02:46.320 回答
35

按字符数计算的最短代码,用于从输入字符串中打印“wave”。

Console.WriteLine("输入字符串中的'wave'。");

于 2009-09-03T21:39:18.217 回答
14

Perl(94 个字符)

144 个字符由 barnaba 原创:

chop($_=<>);$l=length;push(@a," "x$l)for(1..$l*2);$l+=(ord $p<=>ord $_),substr($a[$l],$r++,1)=$p=$_ for(split //);/^\s+$/||print "$_\n" for(@a)

Chris Lutz 优化的 121 个字符:

$_=<>;chop;$a[@a]=" "x$l for 1..($l=length)*2;$l+=$p cmp$_,substr($a[$l],$r++,1)=$p=$_ for split//;/\S/&&print"$_\n"for@a

进一步优化的 94 个字符:

$_=<>;@a=($"x($l=y///c).$/)x(2*$l);s/./substr$a[$l+=$"cmp$&],"@-",1,$"=$&/ge;/\S/&&print for@a

请注意,在传统的 Perl 高尔夫中,通常会添加开关的数量和代码的长度(这在此处会有所帮助),但这里我们使用的是没有开关的独立程序。

于 2009-09-03T22:56:49.547 回答
12

VT100 终端上的 C(76 个字符)

这适用于我在 FreeSBIE 上的测试:

o;main(c){for(;(c=getchar())-10;o=c)printf("\33[1%c%c",c<o?66:c>o?65:71,c);}

但是为了清楚地看到输出,您必须使用以下内容运行它:

clear ; printf "\n\n\n\n\n" ; echo the quick brown fox jumps over the lazy dog | ./a.out ; printf "\n\n\n\n\n"

这算不算?

于 2009-09-04T20:47:20.943 回答
11

Python(161 个字符)

v,s="",raw_input()
m=n=len(s)
r=[' ']*n
q=[r[:]for i in range(2*n)]
for j,i in enumerate(s):
 m+=(i<v)-(i>v)
 q[m][j],v=i,i
for i in q:
 if i!=r:print''.join(i)

我还没有做太多压缩它。现在用宇宙飞船操作员把它移植到某个东西上。

于 2009-09-03T21:58:42.947 回答
10

红宝石:99 字节

r,a,q,i=[],"",99,0
gets.chars{|x|t=r[q+=a<=>x]||=""
a=x
r[q]+=" "*(i-t.size)+x
i+=1}
puts r.compact

未压缩:

r,a,q,i = [],"",99,0
gets.chars { |x|
  t = r[q+=a<=>x] ||= ""
  a = x
  r[q] += " "*(i-t.size)+x
  i += 1
}
puts r.compact
于 2009-09-04T01:09:57.530 回答
7

PHP(138 个字符)

<?for($lc=$i=$h=0;"\n"!=$c=fgetc(STDIN);$o[$h]=sprintf("%- {$i}s%s",@$o[$h],$lc=$c),$i++)$h+=$c<$lc?-1:$c>$lc;krsort($o);echo join($c,$o);

“可读”版本:

<?
for (
    $last_ch = $i = $level = 0;
    "\n" != $ch = fgetc(STDIN);
    $out[$level] = sprintf("%- {$i}s%s", @$out[$level], $last_ch = $ch), $i++
    )
    $level += $ch < $last_ch ? -1 : $ch > $last_ch;
krsort($out);
echo join($ch,$out);
于 2009-09-04T08:42:26.813 回答
6

Python 2.x,现在减少到 156 个字符:

s=raw_input()
R=range(len(s))
m=[0]
for i in R[1:]:m+=[m[-1]-cmp(s[i],s[i-1])]
for x in range(min(m),max(m)+1):print''.join(m[i]==x and s[i]or' 'for i in R)
于 2009-09-03T23:38:29.087 回答
5

C89(151 个字符)

l[999][999];p;v=500;r;main(c){for(;(c=getchar())>0;
)l[v+=c>p,v-=c<p][++r]=*l[v]=p=c;for(v=999;v--;)for
(c=0;c++<=r;)*l[v]&&putchar(c<=r?32|l[v][c]:10);}
于 2009-09-03T22:14:57.617 回答
5

Haskell,215 个字符。我发布这个是因为我根本不喜欢 Khoth 的版本。仅仅通过以合理的功能风格编写,我最终得到了一个更短且 IMO 更具可读性的程序。除了变量名和间距之外,我实际上并没有试图让它变短。破坏性地更新数组可能会使它比复制空间更短。

import Char    
import List    
main=getLine>>=(putStr.p)    
p s=unlines$transpose[z++(y:x)|(m,y)<-zip n s,let(x,z)=splitAt m$replicate(maximum n)' ']
    where o=map ord s
    n=scanl(+)0$map signum$zipWith(-)(tail o)o
于 2009-09-04T07:30:50.233 回答
4

C#:

using System;
static class A
{ 
    static void Main(string[] a)
    {
        var s=a[0];var r="";
        int i=1,h=0,d=0,c=0,n=s.Length;
        var m=new int[n];
        m[0]=0;
        for(;i<n;i++)
        {
            c+=Math.Sign(s[i]-s[i-1]);
            h=(c>h)?c:h;
            d=(c<d)?c:d;
            m[i]=c;
        }
        for(;h>=d;h--)
        {    
            for (c=0;c<n;c++)
                r+=(m[c]==h)?s[c]:' ';  
             r+="\n";
        }
       Console.Write(r);
    }
}

压缩后的重量为 287。

于 2009-09-03T22:01:35.293 回答
4

Perl,85 个字符带开关,96 个不带

-F// -an   使用开关调用  

$q=$"x($n=@F);$,=$/;for(@F){/
/&&print@O;substr($O[$n+=$*cmp$_]|=$q,$i++,1)=$_;$*=$_}

第二个和第三个斜杠字符之间有一个换行符。没有开关你可以做

$q=$"x($n=@C=split//,<>);$,=$/;for(@C){/
/&&print@O;substr($O[$n+=$*cmp$_]|=$q,$i++,1)=$_;$*=$_}
于 2009-09-27T07:02:45.770 回答
3

Haskell(285 个字符):

heightDiff x y | x == y = 0
           | x < y = -1
           | True = 1

heights h (x:y:z)= (x,h):(heights (h+(heightDiff x y) ) (y:z))
heights h [y] = [(y,h)]

makech ((x,h):xs) i = (if i==h then x else ' '):makech xs i
makech [] _ = []

printAll xs = mapM_ (putStrLn . (makech xs)) [(minimum $ map snd xs)..(maximum $ map snd xs)]

main = getLine >>= (printAll . heights 0)

一些压缩(260 个字符):

a x y|x==y=0
     |x<y= -1
     |True=1
c h (x:y:z)=(x,h):(c(h+(a x y))(y:z))
c h [y]=[(y,h)]
d ((x,h):xs)i=(if i==h then x else ' '):d xs i
d [] _=[]
p xs = mapM_ (putStrLn .(d xs)) [(minimum $ map snd xs)..(maximum $ map snd xs)]
main = getLine >>= (p . c 0)
于 2009-09-03T22:16:59.283 回答
3

Perl,88 个字符

现在,编辑为 88 个字符:

$_=<>;
s/.(?=(.))/($"x40).$&.$"x(39+($1cmp$&))/ge;
@_=/.{80}/g;
{say map{chop||die}@_;redo}

曾是:

$_=<>;
s/.(?=(.))/$&.$"x(79+($1cmp$&))/ge;
s/^.{40}|.{80}/$&\n/g;
print $& while /.$/gm || s/.$//gm * /\n/;

97 个字符(省略空格)。它不是那么短,但我想知道是否有更多 PERL 经验的人可以进一步缩短它。并发现任何错误。第二行使用空格在 80 宽的环绕屏幕上产生垂直而不是水平下降的波浪。第三行插入换行符。最后一行翻转 X/Y 轴。

我最初想知道最后两行是否可能类似于 interleave(s/.{80}/g) ,其中 interleave 交错一个字符串数组。但似乎没有我希望的那个功能。(或者图书馆里有吗?)

于 2009-09-24T12:35:12.347 回答
2

C# 中的第一声呐喊。输入必须作为第一个命令行参数提供。

using System;
using C = System.Console;

static class P
{
    static void Main(string[] a)
    {
        var b = a[0];
        var l = b.Length;

        int y = 0, z = 0;
        for (int i = 0; i < l - 1; i++)
        {
            y += Math.Sign(b[i] - b[i + 1]);
            z = Math.Min(y, z);
        }

        y = 0;
        for (int i = 0; i < l - 1; i++)
        {
            C.SetCursorPosition(i, y - z);
            C.Write(b[i]);

            y += Math.Sign(b[i] - b[i + 1]);
        }
    }
}

这会产生 280 字节的压缩数据。

using System;using C=System.Console;static class P{static void Main(string[]a){var b=a[0];var l=b.Length;int y=0,z=0;for(int i=0;i<l-1;i++){y+=Math.Sign(b[i]-b[i+1]);z=Math.Min(y,z);}y=0;for(int i=0;i<l-1;i++){C.SetCursorPosition(i,y-z);C.Write(b[i]);y+=Math.Sign(b[i]-b[i+1]);}}}

尝试第二个不同的方法。

using System;
using System.Collections.Generic;

static class P
{
    static void Main(string[] a)
    {
        var b = a[0] + "$";
        var l = new List<string>();    
        var y = -1;

        for (int i = 0; i < b.Length - 1; i++)
        {
            if ((y == -1) || (y == l.Count))
            {
                y = y < 0 ? 0 : y;
                l.Insert(y, b.Substring(i, 1).PadLeft(i + 1));
            }
            else
            {
                l[y] = l[y].PadRight(i) + b[i];
            }
            y += Math.Sign(b[i] - b[i + 1]);
        }

        foreach (var q in l) Console.WriteLine(q);
    }
}

可以进一步重写循环以使用 try/catch 块。

for (int i = 0; i < b.Length - 1; i++)
{
    try
    {
        l[y] = l[y].PadRight(i) + b[i];
    }
    catch
    {
        y = y < 0 ? 0 : y;
        l.Insert(y, b.Substring(i, 1).PadLeft(i + 1));
    }

    y += Math.Sign(b[i] - b[i + 1]);
}

这会产生稍微修改和压缩的 321 字节 - 比第一次尝试多一点,但更健壮。

using System;static class P{static void Main(string[]a){var b=a[0]+"$";var r=new System.Collections.Generic.List<string>();var y=-1;for(int i=0;i<b.Length-1;i++){try{r[y]=r[y].PadRight(i)+b[i];}catch{y=y<0?0:y;r.Insert(y,b[i].ToString().PadLeft(i+1));}y+=Math.Sign(b[i]-b[i+1]);}foreach(var l in r)Console.WriteLine(l);}}

于 2009-09-03T22:02:52.093 回答
2

电源外壳

我确信这可以用更少的代码来完成,如果有人想编辑那将是极好的。我让它可读。

$v = (Read-Host).ToCharArray()
$r = @(0)
for($i = 1; $i -lt $v.length; $i++) {
    $p = $i - 1
    $r += $r[$p] + [System.Math]::Sign($v[$i] - $v[$p])
    $t = [System.Math]::Max($t, $r[$i])
    $b = [System.Math]::Min($b, $r[$i])
}
for($i = $t; $i -ge $b; $i--) {
    for($x = 0; $x -lt $r.length; $x ++) {
        if($r[$x] -eq $i) {
            $o += $v[$x]
        }
        else {
            $o += " "
        }
    }
    $o += "`n"
}
$o
于 2009-09-04T05:28:46.970 回答
2

F#,242 个字符:

let F(s:string)=(fun L->let a=Array.init(L*3)(fun _->Array.create L ' ')in Seq.fold(fun(r,p,c)n->let r=r+sign(int p-int n)in a.[r].[c]<-n;r,n,c+1)(L,s.[0],0)s;for r in a do if Array.exists((<>)' ')r then printfn"%s"(new string(r)))s.Length

添加了空格以便于阅读,它是

let F(s:string) = 
   (fun L->
    let a = Array.init (L*3) (fun _ -> Array.create L ' ') in 
    Seq.fold (fun (r,p,c) n ->
            let r = r + sign(int p-int n) in 
            a.[r].[c]<-n;
            r, n, c+1)
        (L, s.[0], 0)
        s;
    for r in a do 
        if Array.exists ((<>) ' ') r then 
            printfn "%s" (new string(r))
   ) s.Length
于 2009-09-04T10:48:40.927 回答
2

C(157 个字符)

我暂时卡在那里。我认为C不会在这一点上击败J。不过,感谢 strager 帮助修剪 8 个字符。

char*p,a[999][80];w,x,y=500;main(c){for(gets(memset(p=*a,32,79920));*p;
a[y][x++]=c=*p++)y+=*p<c,y-=*p>c;for(;++w<998;strspn(p," ")-79&&puts(p))
79[p=a[w]]=0;}

格式化:

char *p,         /* pointer to current character (1st) or line (2nd) */
     a[999][80]; /* up to 998 lines of up to 79 characters */

w, x, y = 500;   /* three int variables. y initialized to middle of array */

main(c){
    for(gets(memset(p=*a, 32, 79920));
    /* 999 * 80 = 79920, so the entire array is filled with space characters.
     * memset() returns the value of its first parameter, so the above is
     * a shortcut for:
     *
     *     p = *a;
     *     memset(p, 32, 79920);
     *     gets(p);
     *
     * Incidentally, this is why I say "up to 998 lines", since the first
     * row in the array is used for the input string.
     *
     * **** WARNING: Input string must not be more than 79 characters! ****
     */

    *p;a[y][x++] = c = *p++)  /* read from input string until end;
                               * put this char in line buffer and in prev
                               */
        y += *p < c,          /* if this char < prev char, y++ */
        y -= *p > c;          /* the use of commas saves from using { } */

    for(;++w < 998;         /* will iterate from 1 to 998 */
    strspn(p, " ") - 79 &&
    /* strspn returns the index of the first char in its first parameter
     * that's NOT in its second parameter, so this gets the first non-
     * space character in the string.  If this is the NULL at the end of
     * the string (index 79), then we won't print this line (since it's blank).
     */
    puts(p))  /* write the line out to the screen (followed by '\n') */
        79[p = a[w]] = 0;    /* same as "(p = a[y])[79] = 0",
                              * or "p = a[y], p[79] = 0", but shorter.
                              * Puts terminating null at the end of each line
                              */
}

我没有费心支持超过 79 个字符的输入,因为这会在大多数终端上造成混乱的换行。

于 2009-09-04T20:02:28.117 回答
1

Java 解决方案,没有特别压缩(现在修改为从标准输入读取)。

public class W
{ 
 public static void main(String[] x)
 {
  String s = new java.util.Scanner(System.in).nextLine();
  int i,j;
  int t = s.length();
  char[] b = s.toCharArray();
  char[][] p = new char[2*t][t];
  int q = t;
  char v = b[0];
  for (i=0; i<2*t; i++)
  {
   for (j=0; j<t; j++)
   {
    p[i][j] = ' ';
   }
  }
  p[q][0] = v;
  String z = new String(p[0]);
  for (i=1; i<t; i++)
  {
   char c = b[i];
   int d = (c == v) ? 0 : (c > v ? -1 : 1);
   q += d;
   p[q][i] = c;
   v = c;
  }
  for (i=0; i<2*t; i++)
  {
   String n = new String(p[i]);
   if (!n.equals(z))
   {
    System.out.println(n);
   }
  }
 } 
}
于 2009-09-03T21:50:47.003 回答
1

C#(564 个字符的代码)

using System;
class Program {
    static void Main(string[] args) {
        var input = args[0];
        int min = 0, max = 0;
        var heights = new int[input.Length];

        for (var i = 1; i < input.Length; i++) {
            heights[i] = heights[i-1] + (input[i] > input[i-1] ? 1 : (input[i] < input[i-1] ? -1 : 0));
            min = Math.Min(min, heights[i]);
            max = Math.Max(max, heights[i]);
        }

        for (var row = max; row >= min; row--, Console.WriteLine())
            for (var col = 0; col < input.Length; col++)
                Console.Write(heights[col] == row ? input[col] : ' ');
    }
}

压缩:(324 个字符的代码)

using System;class A{static void Main(string[] args){var I=args[0];int M=0,X=0;var H=new int[I.Length];for(var i=1;i<I.Length;i++){H[i]=H[i-1]+(I[i]>I[i-1]?1:(I[i]<I[i-1]?-1:0));M=Math.Min(M,H[i]);X=Math.Max(X,H[i]);}for(var r=X;r>=M;r--,Console.WriteLine())for(var c=0;c<I.Length;c++)Console.Write(H[c]==r?I[c]:' ');}}

使用评论中的技巧(283 个字符):

using System;class A{static void Main(string[] a){var I=a[0];int M=0,X=0,i=1,r,h,c=0,l=I.Length;var H=new int[l];for(;i<l;i++){h=H[i-1]+(I[i]>I[i-1]?1:(I[i]<I[i-1]?-1:0));H[i]=h;M=M<h?M:h;X=x>h?X:h;}for(r=X;r>=M;r--,Console.Write('\n'))for(;c<l;c++)Console.Write(H[c]==r?I[c]:' ');}}
于 2009-09-03T22:08:44.717 回答
1

Perl 5.10

159 个字符,最“用户友好”的版本:

perl -nE'chop;@l=split//;$l{$_}=$l{$_-1}+($l[$_]cmp$l[$_-1])for 0..$#l;%e=();for$x(sort{$b<=>$a}grep{!$e{$_}++}values%l){say map{$l{$_}==$x?$l[$_]:" "}0..$#l}'

以下版本为153 个字符,但您只能输入一行。要输入多个,您必须重新启动程序。规则不清楚是否允许这样做,但我认为最好还是发布两个版本:

perl -nE'chop;@l=split//;$l{$_}=$l{$_-1}+($l[$_]cmp$l[$_-1])for 0..$#l;for$x(sort{$b<=>$a}grep{!$e{$_}++}values%l){say map{$l{$_}==$x?$l[$_]:" "}0..$#l}'

这是一个149个字符的版本 - 这是一个脚本而不是 shell 单行,也只适用于一行输入,但在第一行之后不会继续接受输入,这可能是件好事:

$_=<>;chop;@l=split//;$l{$_}=$l{$_-1}+($l[$_]cmp$l[$_-1])for 0..$#l;for$x(sort{$b<=>$a}grep{!$e{$_}++}values%l){say map{$l{$_}==$x?$l[$_]:" "}0..$#l}

这些都没有已经发布的 Perl 解决方案那么短,但它们似乎确实胜过 Python 和 Ruby。此外,还有不止一种方法可以做到这一点。

于 2009-09-04T01:23:51.990 回答
1

F#,235 个字符

与我的其他解决方案相比,完全不同的策略节省了一些字符。

let F(s:string)=(fun L->let _,_,h=Seq.fold(fun(p,h,l)n->let r=h-sign(int n-int p)in n,r,r::l)(s.[0],0,[0])s in for r in Seq.min h..Seq.max h do printfn"%s"(new string(Array.init L (fun c->if r=h.[L-1-c]then s.[c]else ' '))))s.Length

带空格:

let F(s:string) = 
   (fun L->
    let _,_,h = Seq.fold (fun (p,h,l) n ->
        let r = h - sign(int n-int p) in 
        n,r,r::l) (s.[0],0,[0]) s in 
    for r in Seq.min h..Seq.max h do 
        printfn "%s" (new string(Array.init L (fun c -> 
            if r=h.[L-1-c] then s.[c] else ' ')))
   ) s.Length   
于 2009-09-04T12:17:37.503 回答
1

C# 545 字节未压缩

using System;
using System.Linq;
class Program{
    static void Main(string[] b){
        var s = b[0];
        var t = new System.Collections.Generic.Dictionary<int, string>();
        int y=0, p=0;
        for (int i = 0; i < s.Length; i++){
            y += Math.Sign(s[i] - p);
            p = s[i];        
            if (!t.ContainsKey(y))
                t.Add(y, "");
            t[y] = t[y].PadRight(i) + s[i];
        }
        foreach (var v in t.OrderBy(a => -a.Key))
            Console.WriteLine(v.Value);
    }
}
于 2009-09-04T12:44:01.270 回答
1

Ruby:109 字节,计算换行符!!

s=gets
r,a,q,i=[],s[0,1],99,0
s.chars{|x|q+=a<=>x
a=x
t=r[q]||=""
r[q]+=" "*(i-t.size)+x
i+=1}
puts r.compact

未压缩:

s = gets
r,a,q,i = [],s[0,1],99,0
s.chars { |x|
  q += a<=>x
  a  = x
  t = r[q] ||= ""
  r[q]  += " "*(i-t.size)+x
  i += 1
}
puts r.compact
于 2009-09-07T12:47:23.200 回答
1

Groovy(195 个字符)

测试

s="1234567890qwertyuiopasdfghjklzxcvbnm"

短的

=(s=~/./).collect{(char)it}
e=' ';x=0;l=[];u=[]
w.eachWithIndex({it,n->
if(l.size()>x){l[x]+=e*(n-u[x]-1)+it;u[x]=n}else{l+=e*n+it;u+=n}
if(w[n+1]>it)x++else x--;})
l.reverse().each({println it})
于 2009-10-24T21:26:06.433 回答
1

PHP:108 个字符

<?while(-1<$a=fgetc(STDIN)){$d+=$a<$b^-($a>$b);$r[$d].=' ';$r[$d][$k++]=$b=$a;}ksort($r);echo join("\n",$r);

可读版本:

<?
while(-1<$a=fgetc(STDIN)){
  $d+=$a<$b^-($a>$b);
  $r[$d].=' ';
  $r[$d][$k++]=$b=$a;
}
ksort($r);
echo join("\n",$r);
于 2009-10-26T17:59:10.953 回答
1

Golfscript - 65 个字符

' ': :c;1/:a,.+,{:N;a,a{:@c<+c@:c<-.N=[ c]\=}%.[n+'']\$-1= ==\;}%

逐行生成波形

{:N;a,a{:@c<+c@:c<-.N=[ c]\=}%

过滤掉空行

.[n+'']\$-1= ==\
于 2009-11-03T05:57:49.073 回答
1

翔升:73

args1[,;{ch},1_]@1]o o>:><-0 0a:/+,/&-;{()@:'{" "`}}@;{};;{(){`}#`}" ":|P

我刚刚将 J 解决方案翻译成 ASL。

于 2011-02-05T16:00:50.953 回答
0

XQuery

(257 字节)

declare variable$i external;let$c:=string-to-codepoints($i),$h:= for$x at$p in$c
return sum(for$x in 1 to$p let$d:=$c[$x]-$c[$x -1]return(-1[$d>0],1[$d<0]))return
codepoints-to-string(for$p in min($h)to max($h),$x at$q
in($c,10)return(32[$h[$q]!=$p],$x)[1])

由于 XQuery 纯粹是声明性的,因此我不得不将输入伪装成在外部变量中传递。这是使用 XQSharp 运行它的命令行:

xquery wave.xq !method=text i='1234567890qwertyuiopasdfghjklzxcvbnm'

如果字符串作为上下文项传入,则可以进一步减少,但是所有 XQuery 实现都不支持将上下文项设置为非节点值(XQSharp 命令行工具也不支持):

let$c:=string-to-codepoints(.),$h:= for$x at$p in$c return sum(for$x in 1 to$p
let$d:=$c[$x]-$c[$x -1]return(-1[$d>0],1[$d<0]))return codepoints-to-string(for$p
in min($h)to max($h),$x at$q in($c,10)return(32[$h[$q]!=$p],$x)[1])

只有 228 个字节。

于 2009-09-03T23:45:47.383 回答
0

Clojure 版本:


(def a "1234567890qwertyuiopasdfghjklzxcvbnm")
(defn sign [x] (cond (pos? x) 1, (neg? x) -1, :else 0))
(def cmp (cons 0 (map (comp sign compare) a (rest a))))
(def depths (loop [depth 0, remaining cmp, built []]
              (if (first remaining)
                (recur (+ depth (first remaining)) (rest remaining) (conj built depth))
                built)))
(let [top (apply min depths), bottom (apply max depths)]
  (doseq [line (range top (inc bottom)), col (range 0 (count a))]
    (if (= line (depths col))
      (print (get a col))
      (print \space))
    (if (= col (dec (count a)))
      (print \newline))))
于 2009-09-08T06:48:45.033 回答
0

Scala(2.8 之前):275 个字符,当内联并删除空格时。

object W {
  def main(r:Array[String]){
    var(a,l,i,c,b)=(r(0),r(0).size,0,0,99999)
    val h=a.drop(1)./:(List(0)){(x,y)=>c=if(a(i)<y)c-1 else if(a(i)>y)c+1 else c;b=b min c;i+=1;c::x}.reverse
    val z=((" "*l+"\n")*l).toArray
    a./:(0){(x,y)=>z((h(x)-b)*(l+1)+x)=y;x+1}
    print(z.mkString)
  }
}
于 2009-09-09T21:22:58.320 回答
0

哈斯克尔,170

main=getLine>>=putStr.p
p s=unlines[[if m==i then c else ' '|(m,c)<-zip n s]|i<-[minimum n..maximum n]]
 where o=map fromEnum s;n=scanl(+)0$map signum$zipWith(-)o$tail o

168 如果你加入最后两行。基于 Greg M 的解决方案。

于 2012-05-11T18:55:46.973 回答