代码高尔夫:音符

挑战

字符数最短的代码,将根据用户input输出乐谱。

input将由一系列字母和数字组成 – 字母将代表笔记的名称,数字将代表笔记的长度。 笔记由4个垂直列组成。 笔记的头将是一个大写的O ,干,如果存在将是三行高,由pipe字符 ,而国旗将由反斜线\

有效的音符长度是无,音符的1/4,音符的1/8,音符的1/16和音符的1/32。

  | |\ |\ |\ | | |\ |\ | | | |\ OOOOO 1 1/4 1/8 1/16 1/32 

根据他们的笔记名字,笔记是工作人员的地方:

  ---- D ---- CB ---- AG ---- FE ---- 

所有的input可以被认为是有效的和没有错误的 – 每一个音符在一行上用一个空格分隔,至less有一个有效的音符。

testing用例

 Input: BB/4 B/8 B/16 B/32 G/4 D/8 C/16 DB/16 Output: |\ --------------------------|---|\-------- | |\ |\ |\ | |\ |\ ------|---|---|\--|\-----O----|--O----|\ | | | |\ | O | -O---O---O---O---O----|--------------O-- | ---------------------O------------------ ---------------------------------------- 

 Input: E/4 F/8 G/16 A/32 E/4 F/8 G/16 A/32 Output: -------------------------------- --------------|\--------------|\ |\ |\ |\ |\ ------|\--|\--|\------|\--|\--|\ | | | O | | | O --|---|--O--------|---|--O------ | O | O -O---------------O-------------- 

 Input: CE/32 B/8 A/4 BF/32 BC/16 Output: ------------------------------|\ |\ |\ ----------|---|---------------|- O | | O ---------O----|--O----|\-O------ |\ O |\ ------|\--------------|\-------- |\ O -----O-------------------------- 

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

Golfscript(112个字符)

 ' '%:A;10,{):y;A{2/.0~|1=~:r;0=0=5\- 7% 4y@--:q' '' O'if-4q&!q*r*{16q/r<'|\\' '| 'if}' 'if+{.32=y~&{;45}*}%}%n}% 

Perl,126个字符(带开关的115/122)

Perl中239 226 218 216 183 180 178 172 157 142 136 133 129 128 126字符

Perl中的这个126个字符的解决scheme是我和A. Rex之间冗长协作的结果。

 @o=($/)x10;$/=$";map{m[/];$p=4+(5-ord)%7; $_.=--$p?!($p&~3)*$'?16<$p*$'?" |\\":" | ":$/x4:" O ", $|--&&y@ @-@for@o}<>;print@o 

A. Rex还提出了一个使用perl -ap开关运行的解决scheme。 在这个解决scheme中有111(!)个字符,另加4个笔划作为额外的命令行开关,这个解决scheme的总分为115。

 $\="$: "x5;$p=4+(5-ord)%7,s#..##,$\=~s#(.)\K$#--$p? $_*!($p&~3)?"$1|".(16<$p*$_?"\\":$1).$1:$1x4:O.$1x3#gemfor@F 

这个解决scheme的第一个换行符非常重要。

或者将这些开关embedded到shebang行中的122个字符:

 #!perl -ap $\="$: "x5;$p=4+(5-ord)%7,s#..##,$\=~s#(.)\K$#--$p?$_*!($p&~3)?"$1|".(16<$p*$_? "\\":$1).$1:$1x4:O.$1x3#gemfor@F 

(前两个换行很重要)。

可以使用额外的12个字符来支持半笔记:

 @o=($/)x10;$/=$";map{m[/];$p=4+(5-ord)%7; $_.=--$p?!($p&~3)*$'?16<$p*$'?" |\\":" | ":$/x4:$'>2?" @ ":" O ", $|--&&y@ @-@for@o}<>;print@o 

LilyPond – 244字节

从技术上讲,这不符合输出规范,因为输出是一个很好的雕刻PDF,而不是一个可怜的ASCII文本替代品,但我认为这个问题只是在呼救LilyPond解决scheme。 事实上,你可以删除“\ autoBeamOff \ cadenzaOn \ stemUp”,使它看起来更好的格式。 您还可以在“\ layout {}”之后添加“\ midi {}”以获取要收听的MIDI文件。

 o=#(open-file"o""w")p=#ly:string-substitute #(format o"~(~a"(p"2'1""2"(p"4'1""4"(p"6'1""6"(p"8'1""8"(p"/""'"(p"C""c'"(p"D""d'"(p" ""/1"(p" "" "(ly:gulp-file"M")))))))))))#(close-port o)\score{{\autoBeamOff\cadenzaOn\stemUp\include"o"}\layout{}} 

用法: lilypond thisfile.ly

笔记:

  1. input必须在与程序相同的目录中名为“M”的文件中。
  2. input文件必须以换行符结束。 (或者通过以空格结束保存9个字节)
  3. 输出是一个名为“thisfile.pdf”的PDF,其中“thisfile.ly”是程序的名称。
  4. 我用LilyPond 2.12.2testing了这个; 其他版本可能不起作用。

我在LilyPond中没有做太多的工作,所以我不确定这是做这件事的最好方法,因为它必须把input转换成LilyPond格式,写入一个辅助文件,然后读入。我目前无法使内置的LilyPondparsing器/评估器正常工作。 🙁

现在正在使用ASCII输出解决scheme…. 🙂

C89(186个字符)

 #define P,putchar( N[99];*n=N;y;e=45;main(q){for(;scanf(" %c/%d",n,n+1)>0;n +=2);for(;y<11;q=y-(75-*n++)%7 P+q-4?e:79)P*n&&q<4&q>0? 124:e)P*n++/4>>q&&q?92:e))*n||(e^=13,n=N,y++P+10))P+e);} 

半支持(+7个字符)

 #define P,putchar( N[99];*n=N;y;e=45;main(q){for(;scanf(" %c/%d",n,n+1)>0;n +=2);for(;y<11;q=y-(75-*n++)%7 P+q-4?e:v<4?79:64)P*n&&q<4&q>0? 124:e)P*n++/4>>q&&q?92:e))*n||(e^=13,n=N,y++P+10))P+e);} 

Python 178个字符

167是虚惊一场,我忘记了整个音符的茎干。

 R=raw_input().split() for y in range(10): r="" for x in R:o=y-(5-ord(x[0]))%7;b=" -"[y&1]+"O\|";r+=b[0]+b[o==3]+b[-(-1<o<3and''<x[1:])]+b[2*(-1<o<":862".find(x[-1]))] print r 

Python 167个字符(破碎)

这里没有邪恶的眼睛,虽然里面有2个填充字,所以我加了一个笑脸。 这种技巧利用了音符长度的最后一个字符的独特性,所以我很幸运没有1/2音符或1/64音符

 R=raw_input().split() for y in range(10): r="" for x in R:o=y-(5-ord(x[0]))%7;b=" -"[y&1]+"O\|";r+=b[0]+b[o==3]+b[-(-1<o<3)]+b[2*(-1<o<":862".find(x[-1]))] print r 

Python 186个字符<<o>>

Python在这里使用<<o>>邪眼操作符效果很好。 如果find()项目, find()方法返回-1,所以这就是为什么D不需要出现在注释中。

 R=raw_input().split() for y in range(10): r="" for x in R:o='CBAGFE'.find(x[0])+4;B=" -"[y%2];r+=B+(B,'O')[o==y]+(x[2:]and y+4>o>y and"|"+(B,'\\')[int(x[2:])<<o>>6+y>0]or B*2) print r 

11个额外的字节给出了一半的音符版本

 R=raw_input().split() for y in range(10): r="" for x in R:t='CBAGFE'.find(x[0])+4;l=x[2:];B=" -"[y%2];r+=B+(B,'@O'[l in'2'])[t==y]+(l and y+4>t>y and"|"+(B,'\\')[int(l)>>(6+yt)>0]or B*2) print r 
 $ echo BB/2 B/4 B/8 B/16 B/32 G/4 D/8 C/16 DB/16| python notes.py |\ ------------------------------|---|\-------- | | |\ |\ |\ | |\ |\ ------|---|---|---|\--|\-----@----|--O----|\ | | | | |\ | @ | -O---O---@---@---@---@----|--------------@-- | -------------------------@------------------ -------------------------------------------- 

159个Ruby字符

 n=gets.split;9.downto(0){|p|m='- '[p%2,1];n.each{|t|r=(t[0]-62)%7;g=t[2..-1] print m+(r==p ?'O'+m*2:p>=r&&g&&p<r+4?m+'|'+(g.to_i>1<<-p+r+5?'\\':m):m*3)} puts} 

ruby136

 n=gets;10.times{|y|puts (b=' -'[y&1,1])+n.split.map{|t|r=y-(5-t[0])%7 (r==3?'O':b)+(t[1]&&0<=r&&r<3?'|'<<(r<t[2,2].to_i/8?92:b):b+b)}*b} 

ruby139(鸣叫)

 n=gets;10.times{|y|puts (b=' -'[y&1,1])+n.split.map{|t|r=y-(5-t[0])%7 (r==3?'O':b)+(t[1]&&0<=r&&r<3?'|'<<(r<141>>(t[-1]&7)&3?92:b):b+b)}*b} 

ruby143

 n=gets.split;10.times{|y|puts (b=' -'[y&1,1])+n.map{|t|r=y-(5-t[0])%7;m=t[-1] (r==3?'O':b)+(m<65&&0<=r&&r<3?'|'<<(r<141>>(m&7)&3?92:b):b+b)}*b} 

ruby148

这是另一种计算标志的方法,
其中m=ord(last character)#flags=1+m&3-(1&m/4)

另一种方法是#flags=141>>(m&7)&3 ,这样可以节省多一个字节

 n=gets.split;10.times{|y|b=' -'[y&1,1];n.each{|t|r=y-(5-t[0])%7;m=t[-1] print b+(r==3?'O':b)+(m<65&&0<=r&&r<3?'|'<<(r<141>>(m&7)&3?92:b):b+b)} puts} 

ruby181

首先尝试一下我的Python解决scheme的音译

 n=gets.split;10.times{|y|r="";n.each{|x|o=y-(5-x[0])%7 r+=(b=" -"[y&1,1]+"O\\|")[0,1]+b[o==3?1:0,1]+b[-1<o&&o<3&&x[-1]<64?3:0,1]+b[-1<o&&o<(":862".index(x[-1]).to_i)?2:0,1]} puts r} 

F#,458个字符

合理短小,仍然大部分是可读的:

 let s=Array.init 10(fun _->new System.Text.StringBuilder()) System.Console.ReadLine().Split([|' '|]) |>Array.iter(fun n-> for i in 0..9 do s.[i].Append(if i%2=1 then"----"else" ") let l=s.[0].Length let i=68-int n.[0]+if n.[0]>'D'then 7 else 0 s.[i+3].[l-3]<-'O' if n.Length>1 then for j in i..i+2 do s.[j].[l-2]<-'|' for j in i..i-1+(match n.[2]with|'4'->0|'8'->1|'1'->2|_->3)do s.[j].[l-1]<-'\\') for x in s do printfn"%s"(x.ToString()) 

简短的评论:

 // create 10 stringbuilders that represent each line of output let s=Array.init 10(fun _->new System.Text.StringBuilder()) System.Console.ReadLine().Split([|' '|]) // for each note on the input line |>Array.iter(fun n-> // write the staff for i in 0..9 do s.[i].Append(if i%2=1 then"----"else" ") // write note (math so that 'i+3' is which stringbuilder should hold the 'O') let l=s.[0].Length let i=68-int n.[0]+if n.[0]>'D'then 7 else 0 s.[i+3].[l-3]<-'O' // if partial note if n.Length>1 then // write the bar for j in i..i+2 do s.[j].[l-2]<-'|' // write the tails if necessary for j in i..i-1+(match n.[2]with|'4'->0|'8'->1|'1'->2|_->3)do s.[j].[l-1]<-'\\') // print output for x in s do printfn"%s"(x.ToString()) 

C 196个字符<<o>>

借用一些想法。 有趣的function包括n+++1 “triple +”操作符和<<o>> “邪恶眼睛”操作符

 #define P,putchar N[99];*n=N;y;b;main(o){for(;scanf(" %c/%d",n,n+1)>0;n+=2);for(;y<11;) n=*n?n:(y++P(10),N)P(b=y&1?32:45)P((o=10-(*n+++1)%7-y)?b:79)P(0<o&o<4&&*n?'|':b) P(*n++<<o>>6&&0<o&o<4?92:b);} 

Perl 5.10中的168个字符

我原来的解决scheme是276个字符,但很多很多的调整减less了超过100个字符!

 $_=<>; y#481E-GA-D62 #0-9#d; s#.(/(.))?#$"x(7+$&).O.$"x($k=10).($1?"|":$")x3 .$"x(10-$2)."\\"x$2.$"x(9-$&)#ge; s#(..)*?\K (.)#-$2#g; print$/while--$k,s#.{$k}\K.#!print$&#ge 

如果你有一个小的build议,改善这一点,请随时编辑我的代码。

Lua,307个字符

 b,s,o="\\",io.read("*l"),io.write for i=1,10 do for n,l in s:gmatch("(%a)/?(%d*)")do x=n:byte() w=(x<69 and 72 or 79)-x l=tonumber(l)or 1 d=i%2>0 and" "or"-"o(d..(i==w and"O"or d)..(l>3 and i<w and i+4>w and"|"or d)..(l>7 and i==w-3 and b or l>15 and i==w-2 and b or l>31 and i==w-1 and b or d))end o"\n"end 

C – 293个字符

仍然需要更多的压缩,它需要在命令行上的参数,而不是阅读它们…

 i,j,k,l;main(c,v)char **v;{char*t;l=4*(c-1)+2;t=malloc(10*l)+1;for(i=0;i<10;i ++){t[i*l-1]='\n';for(j=0;j<l;j++)t[i*l+j]=i&1?'-':' ';}t[10*l-1]=0;i=1;while (--c){j='G'-**++v;if(j<3)j+=7;t[j*l+i++]='O';if(*++*v){t[--j*l+i]='|';t[--j*l +i]='|';t[--j*l+i]='|';if(*++*v!='4'){t[j++*l+i+1]='\\';if(**v!='8'){t[j++*l+ i+1]='\\';if(**v!='1'){t[j++*l+i+1]='\\';}}}}i+=3;}puts(t);} 

编辑:固定E

编辑:下降到293个字符,包括换行符…

 #define X t[--j*l+i]='|' #define Y t[j++*l+i+1]=92 i,j,k,l;main(c,v)char**v;{char*t;l=4*(c-1)+2;t=malloc(10*l)+1;for(i=10;i;)t[--i* l-1]=10,memset(t+i*l,i&1?45:32,l-1);t[10*l-1]=0;for(i=1;--c;i+=3)j=71-**++v,j<3? j+=7:0,t[j*l+i++]=79,*++*v?X,X,X,*++*v-52?Y,**v-56?Y,**v-49?Y:0:0:0:0;puts(t);}