代码高尔夫:钢琴

88

挑战

以字符数量最少的代码输出一个从给定音符开始的钢琴键盘部分,该部分长度由输入确定。

输入包括一个音符([ACDFG]#|[A-G]),表示从哪个键开始打印键盘,以及一个正数,表示要打印的键数,包括第一个音符在内。

第一个键应该完整地打印出来 - 如果它有左边的升号键,则将其切断,同样,当起始键为升调时,左侧键也将被切断。

只计算白键,黑键不计入长度。

测试用例

Input
    C 14
Output
    |   ###  ###   |   ###  ###  ###   |   ###  ###   |   ###  ###  ###   |
    |   ###  ###   |   ###  ###  ###   |   ###  ###   |   ###  ###  ###   |
    |   ###  ###   |   ###  ###  ###   |   ###  ###   |   ###  ###  ###   |
    |   ###  ###   |   ###  ###  ###   |   ###  ###   |   ###  ###  ###   |
    |   ###  ###   |   ###  ###  ###   |   ###  ###   |   ###  ###  ###   |
    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |
    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |
    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |
    |____|____|____|____|____|____|____|____|____|____|____|____|____|____|

Input
    D# 1
Output
    ###   |
    ###   |
    ###   |
    ###   |
    ###   |
     |    |
     |    |
     |    |
    _|____|

Input
    A 7
Output
    ##  ###   |   ###  ###   |   ###  ##
    ##  ###   |   ###  ###   |   ###  ##
    ##  ###   |   ###  ###   |   ###  ##
    ##  ###   |   ###  ###   |   ###  ##
    ##  ###   |   ###  ###   |   ###  ##
    |    |    |    |    |    |    |    |
    |    |    |    |    |    |    |    |
    |    |    |    |    |    |    |    |
    |____|____|____|____|____|____|____|

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


5
这句话的意思是:[A-G]#*是否意味着我们需要将,比如说,B#####处理成E - Anon.
5
请为“key”的计数定义“key”。为什么例子“C 14”打印出24个键? - Guffa
53
好的,既然我们已经有了 C 和 C# 的解决方案,现在我们需要 B、D 和 F#。 - LiraNuna
7
下一个代码高尔夫:为这些钢琴实现一个MIDI接口。 - Mehrdad Afshari
10
亲爱的闭合者们,我向你们致敬,因为你们在三天后成功关闭了这个挑战。我们让它在5分钟内重新开放。这就足以说明一些事情 - 不管你喜不喜欢,社区都喜欢和接受这种问题。但如果你不喜欢,请将“code-golf”标签添加到您忽略的标签列表中。 - LiraNuna
显示剩余13条评论
22个回答

112

Perl, 133 (129)字符

Perl,167 160 156 147 142 133 噢!147 144 137 134 133个字符

    $_ = shift;
    die grep {
        5 > $n ? y/*/#/ : y/#*/| /;
        $n++ - 8 || y/ /_/
    } @Q=(substr(("*#  #" . ("*#  #*#   |   #") x 2) x 9,
    4 * /#/ + (7 <=> 0) * 5, 1 + /#/ + 5 * pop).$/) x 9

这是一个129个字符的解决方案,从molf的Ruby解决方案借鉴了几个想法:

    ($_,$c)=@ARGV;$j=($k=/#/)+ord;
    for$n(0..8){print$/,substr+(join'',map{8-$n?5>$n&&$_%7%4?"###  "
    :" |   ":"_|___"}$j..$j+$c),!$k,-3}

并借助于Acme::AsciiArtinator的帮助:

                sub init_piano{$S=$";$H='#';
                (                            $
               T                              ,$P,$U)=qw(
              T                                          |
             _                                            |
            /                                              )
           ;                                                $
          d             =$T.$H.$S.$S;$t                     =
         $             d               .                   $H
        .              $               d                  . $
       S               .$P.$S.$S.$S.$H;$                t=  $
      d.$H.$t.$t;};$_=shift;-/-/;&init_piano();$Z=/#/;-/|   |
      |                                                 |   |
      |                    YAMAHA                       |  /
      ;die grep{4>$n++?y/T/#/:y/#T/ |/;$n-8||y/ /_/;}@q=(m{
     // // /// // /// // /// // /// // /// // /// // /// /   
    // // /// // /// // /// // /// // /// // /// // /// /
   }                                                   .
   substr(${t}x(9),4*${Z}+(7&ord)*5,1+$Z+5*pop).$/)x(8)
          ;   '                            \   /
           | |                              | |
           /_\                              /';

7
哈哈哈,太棒了。那是斯坦威、雅马哈还是扬琴? - Steve Tjoa
2
我要收藏这个,以便向不懂“猴子”笑话的人展示。 - Mehrdad Afshari
3
@Steve - 让我们选择雅马哈。 - mob
6
@mobrule,你讨厌grep吗?为什么你想让它死去?:( - LiraNuna
Golfscript * 1.3 将会是 105 :) - John La Rooy

34

Ruby - 125个字符

146 144 140 137 134 126 125个字符

a,n=$*;h=a[1]?0:1;s=a[0]-h+1
9.times{|t|puts (s..s+n.to_i).map{|i|i%7%4<1||t>4?" |   ":"###  "
}.join[h..-4].tr t>7?" ":n,"_"}

第二个换行符不是必需的,只是为了避免在 SO 上出现滚动条。如果需要,分号可以被换行符替换。

Ruby 1.9 版本与此不同,但长度相等(将 a[0] 替换为 a.ord,将 "_" 替换为 ?_):

a,n=$*;h=a[1]?0:1;s=a.ord-h+1
9.times{|t|puts (s..s+n.to_i).map{|i|i%7%4<1||t>4?" |   ":"###  "
}.join[h..-4].tr t>7?" ":n,?_}

与...通话

$ ruby piano.rb C 14

1
你甚至可以用"$*"替换"gets.split",并在命令行上输入输入,-8个字符。 - hurikhan77
你可以通过将“_”替换为“?_”,并在调用tr的末尾删除括号(将第一个括号替换为空格)来节省2个额外的字符。 - JRL
@hurikhan77:太棒了! @mobrule:不幸的是(在这种情况下),在Ruby中0是真值,所以那样行不通。 @JRL:在Ruby 1.8中,?_是一个Fixnum(字符代码),而不是字符串,但在1.9中确实可以工作!谢谢! - molf
1
我们已经找到了最短的解决方案,是吗?Ruby万岁!:-D - hurikhan77
我的 Ruby 答案已经发布了,如果你们想看看我有没有漏掉什么,请访问以下链接:https://dev59.com/ZXE95IYBdhLWcg3wrP-w#2220265 - John La Rooy
显示剩余3条评论

29

LilyPond,285 288 291 310 315 330 333 340 350 个字符

为了与音乐主题保持一致,这里提供了一个用于排版音乐谱的语言LilyPond的解决方案:

x=#ly:string-substitute
u=#(x"*""###  ""|   *** |   ** ")t=#(x"###"" | "u)q=#read-char
z=#(q)v=#(if(eq?(q)#\#)1 0)y=#(iota(+(*(read)5)1 v))#(format #t"~{~{~a~}
~}"(map(lambda(s)(map(lambda(i)(string-ref s(modulo(+(*(char->integer z)5)i(* v
4))35)))y))(list u u u u u t t t(x" ""_"t))))

用法:$ lilypond thisfile.ly <input.in >output.out 2>/dev/null

4
这可能是我第一次也是唯一一次看到LilyPond用于代码高尔夫比赛。 - cobbal
3
@cobbal: 请参考以下链接:https://dev59.com/b3M_5IYBdhLWcg3wThR3#1584216, https://dev59.com/LnI_5IYBdhLWcg3wAd82#1584160, https://dev59.com/L3RC5IYBdhLWcg3wMd9S#1905327 (比其他任何解决方案都更短),以及 http://golf.shinh.org/p.rb?Counting+adventure。 - KirarinSnow

27

GolfScript - 80个字符

在#SO中一行即可显示,无需滚动条 :)

' ':s/~~5*\(7&5*\,.4*@+):k;+):c;9,{5<'#'9**' | '4*+3/4<.1>+c*s.+*k>c<n+}%)s/'_'*

GolfScript — 81个字符

' ': /((7&\,.4*@5*+:k;\~~5*+):c;9,{5<'#'9**' | '4*+3/4<.1>+c*  +*k)>c<n+}%) /'_'*

漂亮格式化的版本(27 x 3)

' ': /((7&\,.4*@5*+:k;\~~5*
+):c;9,{5<'#'9**' | '4*+3/4
<.1>+9*  +*k)>c<n+}%) /'_'*

GolfScript - 82字符

' '/((7&\,.4*@5*+:k;\~~5*+):c;9,{5<3*'###  '*' |   '4*+20<.5>+c*k)>c<n+}%)' '/'_'*

GolfScript - 85个字符

' '/((7&\,.4*@5*+:k;\~~5*+):c;9,{.5<3*'###  '*' _'1/@8=='|'1$3*++4*+20<.5>+c*k)>c<n}%

漂亮的格式化版本(17 x 5)

' '/((7&\,.4*@5*+
:k;\~~5*+):c;9,{.
5<3*'###  '*' _'1
/@8=='|'1$3*++4*+
20<.5>+c*k)>c<n}%

GolfScript - 94个字符

' ': /~~5*:c;(7&5*:^;,:&;['###  '3*' |   '+.5>+c*1>{^4&*+>&c+)<n}:f~]5*'   _'1/{'|'\4*+7*c*f}%

GolfScript - 98个字符

' ': /~~5*:c;(7&5*:^;,:&;['###  '3*' |   '+.5>+c*^4&*+:^)>&c+):&<n]5*[   '_']{['|'\4*+7*c*^>&<n]}%

GolfScript - 101个字符

' ': /~~5*:c;(7&5*:^;,:&;['###  '3*' |   '+.5>+c*^4&*+)>&c+)<n]5*[   '_']{['|'\4*+7*c*^4&*+>&c+)<n]}%

GolfScript - 109个字符

' ': /~~5*:c;(7&5*:^;,:&;['##''  ###'.'   | '++.'  #'+++c*^4&*+>&c+)<n]5*[   '_']{['|'\4*+7*c*^4&*+>&c+)<n]}%

GolfScript - 120 Characters

' '/~~5*:c;(7&5*:^;,:&;['##''  ###'.'   | '++.'  #'+++c*^4&*+>&c+)<n]5*['|    '7*c*^4&*+>&c+)<n]3*'|____'7*c*^4&*+>&c+)<

GolfScript - 127个字符

' '/~~5*:c;(7&5*:^;,:&;['##  ###  ###   |   ###  ###   |   #'c*^4&*+>&c+)<n]5*['|    '7*c*^4&*+>&c+)<n]3*'|____'7*c*^4&*+>&c+)<

$ echo -n C 14 | ruby golfscript.rb piano.gs 
|   ###  ###   |   ###  ###  ###   |   ###  ###   |   ###  ###  ###   |
|   ###  ###   |   ###  ###  ###   |   ###  ###   |   ###  ###  ###   |
|   ###  ###   |   ###  ###  ###   |   ###  ###   |   ###  ###  ###   |
|   ###  ###   |   ###  ###  ###   |   ###  ###   |   ###  ###  ###   |
|   ###  ###   |   ###  ###  ###   |   ###  ###   |   ###  ###  ###   |
|    |    |    |    |    |    |    |    |    |    |    |    |    |    |
|    |    |    |    |    |    |    |    |    |    |    |    |    |    |
|    |    |    |    |    |    |    |    |    |    |    |    |    |    |
|____|____|____|____|____|____|____|____|____|____|____|____|____|____|
$ echo -n D# 1| ruby golfscript.rb piano.gs 
###   |
###   |
###   |
###   |
###   |
 |    |
 |    |
 |    |
_|____|
$ echo -n A 7| ruby golfscript.rb piano.gs 
##  ###   |   ###  ###   |   ###  ##
##  ###   |   ###  ###   |   ###  ##
##  ###   |   ###  ###   |   ###  ##
##  ###   |   ###  ###   |   ###  ##
##  ###   |   ###  ###   |   ###  ##
|    |    |    |    |    |    |    |
|    |    |    |    |    |    |    |
|    |    |    |    |    |    |    |
|____|____|____|____|____|____|____|

我正准备为另一个挑战提交我的第一个GolfScript条目(http://stackoverflow.com/questions/2104556/code-golf-0-to-1-and-1-to-0-closed),但它被关闭了 :-( - mob
2
我希望学校教授 GolfScript 。我要退款。 - Steve Tjoa
6
好的,我会稍后用PianoScript发布我的解决方案。它只有6个字符。 :-) - molf

26

RetroGolf - Applesoft BASIC:236 239 245 249 257 245 267 285

为了易读性,此处显示为多行,但应为单行:

1K$="##   |   ###  #":K$="##  #"+K$+K$:
 FORI=1TO21:F$=F$+"|____":L$=L$+"|    ":NEXT:
 INPUTN$:S=MID$(N$,2,1)="#":O=(ASC(N$)-65)*5+1+S*4:L=VAL(RIGHT$(N$,2))*5+1+S:
 FORI=1TO5:?MID$(K$+K$+K$,O,L):NEXT:FORI=1TO3:?MID$(L$,O,L):NEXT:?MID$(F$,O,L)

可以使用这个Applesoft BASIC 解释器在Javascript中进行测试,或者模拟器


根据规范,是否可以在同一行上读取两个参数? - KirarinSnow

18

C# - 315

虽然C#不是一种非常精简的语言,但我仍然坚持在其中进行高尔夫练习...

using C=System.Console;class P{static void L(int o,int c,string s){while(c-->0)C.Write(s[(420>>o++%5*2&3)+(91>>(o+2)/5%7&1)*3]);C.WriteLine();}static void Main(string[]a){int i=0,s=a[0].Length-1,c=int.Parse(a[1])*5+1+s,o=(a[0][0]-65+s)*5-s;while(i++<5)L(o,c,"|  ## ");while(i++<8)L(o,c,"|  |  ");L(o,c,"|__|__");}}

23
现在我们来看一下用 F# 完成旋律的解决方案。 - LiraNuna
13
幽默加1分,俗套幽默减1分,C#和F#兼容得分再加1分。 - Steve Tjoa
当我尝试运行它时,出现了System.IndexOutOfRangeException异常。 - Fitzchak Yitzchaki
@Mendy:在运行时必须提供命令行参数。如果你是从Visual Studio运行的,打开项目属性,进入调试选项卡,在启动选项下可以输入命令行参数。如果你已经将代码编译成exe文件,只需在控制台窗口中以程序名称后面跟着参数的方式运行即可。 - Guffa
+1,我讨厌你。你的C#版本比我的F#版本短! - Benjol
1
非常好的使用了 --> 运算符。 - Kevin

16

Python - 164

k,n=raw_input().split()
m=k[1:]>""
n=int(n)*5+1
o=(ord(k[0])-65)*5+4*m
for x in["##  ###   |   ### "]*5+[n*"|    "]*3+[n*"|____"]:print((x+x[::-1][:-1])*n)[o:o+n+m]

你能否通过删除“t”和“u”的重复部分并乘以7来节省一些字符? - Matthew Crumley
@Matthew Crumley,可以放心地借鉴我的解决方案 :) - John La Rooy
@gnibbler,我不是一个真正的Python程序员(虽然我有点尝试过它,但并不是非常深入),所以我怀疑我将无法做太多事情。直到我看到您的原始解决方案,我甚至都不知道Python可以像那样乘字符串。 - Matthew Crumley
@gnibbler - 不错的解决方案,很想运行它,但是出现了SyntaxError... C 14 Traceback(最近的调用最后):文件“piano.py”,第1行,在? k,n = input() .split(),文件“<string>”,第1行 C 14。 - AJ.
@AJ,看起来这个错误是来自Python3的解决方案。不确定为什么你会遇到这个问题。 - John La Rooy
@gnibbler - 因为我太蠢了,复制了你的p3k解决方案并在2.6中运行:p - AJ.

15

Octave,153 154 155 158 159 162 172 180 186 185 188 197 199 200 206 207 209 212 214 215 219 240 244 268 字符

为什么只使用C、C#、F#(或B或D)时,你可以用完整的Octave编程呢?

(每60个字符换行以便阅读)

x=5*scanf("%2c%d");for k=-8:0disp((s={[t="|   ###  ###  ","#
##   ",t" "]"|    ","|____"}{(k>-4)+!k+1})(1+mod(5*(y=x(2)>1
60)+(-y:x(3))+x(1),rows(s'))))end

是的,这个解决方案确实可以计算出一个字符串的共轭转置。

用法:$ octave -q thisfile.m <input.in >output.out


13

C - 仅限197个字符

#define S"#   |   ###  ###  ##"
main(i,j,l,h,t){char*X[]={"____|","    |",S S,S S},s[i=11];for(scanf("%s%n%d",s,&h,&l);--i>1;puts(""))for(j=t=*s%7*5+h*4;j<t+l*5+h;putchar(X[i/3][j++%(i>5?35:5)]));}

这个等价的194个字符的版本假设缓冲区溢出是可以接受的。

#define S"#   |   ###  ###  ##"
i=11;main(j,l,h,t){char*X[]={"____|","    |",S S,S S},s;for(scanf("%s%n%d",&s,&h,&l);--i>1;puts(""))for(j=t=s%7*5+h*4;j<t+l*5+h;putchar(X[i/3][j++%(i>5?35:5)]));}

1
for(j=0; j<=l*5+h; j++) - Nicolás

12

后置脚本:239 245 293 312 (常规); 219 224 225 231 (ASCII85)

/r{(%stdin)(r)file token pop}def[(]){mul add}/z r(:-)cvs dup length 1
sub/v exch/p r/s(|   ###  ###  ###   |   ###  ###   )([){0 1 v p 5]{s
exch z 0 get 5]v 4]s length mod 1 getinterval print}for/
=}>>begin[[[[[/s(|    )def[[[/s(|____)def[

二进制版本通过ASCII85编码扩展为一个只使用ASCII可打印字符的219字符程序:

/(|____)/(|    )[/r/(|   ###  ###  ###   |   ###  ###   )<~Ou%G5-$+0=Bl5@JE[d/;P,jagI?HCK@<*JGP,4<rOuSV60p8LhG*5%O8oc=a.=3b)!HsVu23Md=!IHJ_A<K->@5*j;23Md=!HoSBP&-9^09Tk/@ZkI\P"_$^I?I,S+?b-:5*?@Z>?b<9Ou$<H>EUc~>cvx
exec[

用法: $ gs -q -dNOPROMPT -dNODISPLAY -dBATCH thisfile.ps <input.in >output.out


10
很高兴看到这些比赛中出现了不太传统的语言。 - mob

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接