代码高尔夫:音符
挑战
字符数最短的代码,将根据用户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
笔记:
- input必须在与程序相同的目录中名为“M”的文件中。
- input文件必须以换行符结束。 (或者通过以空格结束保存9个字节)
- 输出是一个名为“thisfile.pdf”的PDF,其中“thisfile.ly”是程序的名称。
- 我用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);}