36

チャレンジ

ユーザー入力に基づいて楽譜を出力する、文字数による最短コード。

入力は一連の文字と数字で構成されます。文字は音名を表し、数字は音の長さを表します。ノートは縦 4 列で構成されます。音符の頭は大文字Oの語幹になり、存在する場合は 3 行の高さになり、パイプ文字から作られ|、旗はバックスラッシュから作られ\ます。

有効な音符の長さは、なし、音符の 1/4、音符の 1/8、音符の 1/16、および音符の 1/32 です。

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

音符は、音名に従って譜表上の場所に配置されます。

  ----

D ----
C     
B ----
A     
G ----
F     
E ----

すべての入力は有効で、エラーがないと想定できます - 各メモは空白で区切られた 1 行に、少なくとも 1 つの有効なメモがあります。

テストケース

Input:
    B B/4 B/8 B/16 B/32 G/4 D/8 C/16 D B/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:
    C E/32 B/8 A/4 B F/32 B C/16
Output:

    ------------------------------|\
              |\                  |\
    ----------|---|---------------|-
     O        |   |              O   
    ---------O----|--O----|\-O------
          |\     O        |\        
    ------|\--------------|\--------
          |\             O           
    -----O--------------------------

コード カウントには、入力/出力 (つまり、完全なプログラム) が含まれます。

4

12 に答える 12

23

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}%
于 2009-10-18T05:05:19.867 に答える
22

Perl、126 文字 (スイッチを使用すると 115/122)

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

この Perl での 126 文字のソリューションは、私と 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 also proposes a solution to run with the perl -ap switch. With 111(!) characters in this solution plus 4 strokes for the extra command-line switch, this solution has a total score of 115.

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

The first newline in this solution is significant.

Or 122 characters embedding the switches in the shebang line:

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

(first two newlines are significant).

Half-notes can be supported with an additional 12 chars:

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

LilyPond - 244 バイト

技術的に言えば、これは出力仕様に準拠していません。なぜなら、出力は貧弱な ASCII テキストの代替ではなく、きれいに刻まれた PDF だからです。実際、「\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. 入力は、プログラムと同じディレクトリにある「M」という名前のファイルにある必要があります。
  2. 入力ファイルは改行で終わる必要があります。(または、末尾をスペースにすることで 9 バイト節約できます。)
  3. 出力は「thisfile.pdf」という名前の PDF です。ここで、「thisfile.ly」はプログラムの名前です。
  4. これを LilyPond 2.12.2 でテストしました。他のバージョンは動作しない可能性があります。

私は LilyPond で多くのことをしたことがないので、入力を LilyPond 形式に変換し、それを補助ファイルに書き込んでから読み込む必要があるため、これがこれを行うための最良の方法であるかどうかはわかりません。現在、私は組み込みの LilyPond パーサー/評価器を動作させることができません。:(

現在、ASCII出力ソリューションに取り組んでいます.... :)

于 2009-10-18T06:13:12.513 に答える
14

パイソン 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

パイソン 186 文字<<o>>

ここでは、Python は<<o>>邪眼演算子を使用して大きな効果を上げています。アイテムが見つからない場合、この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 バイト余分に 2 分音符付きのバージョンが得られます


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+y-t)>0]or B*2)
 print r
$ echo B B/2 B/4 B/8 B/16 B/32 G/4 D/8 C/16 D B/16| python notes.py 
                              |\            
------------------------------|---|\--------
      |   |   |\  |\  |\      |   |\      |\
------|---|---|---|\--|\-----@----|--O----|\
      |   |   |   |   |\  |      @        | 
-O---O---@---@---@---@----|--------------@--
                          |                 
-------------------------@------------------

--------------------------------------------
于 2009-10-15T23:45:55.607 に答える
14

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);}
于 2009-10-15T21:57:28.020 に答える
9

159ルビー文字

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}
于 2009-10-15T22:28:37.697 に答える
7

ルビー136

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}

ルビー139 (ツイート)

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}

ルビー143

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}

ルビー148

フラグを計算する別の方法を次に示し
ますm=ord(last character)#flags=1+m&3-(1&m/4)

#flags=141>>(m&7)&3もう1バイト節約する別の方法

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}

ルビー181

最初の試行は、私の Python ソリューションの音訳です

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}
于 2009-10-18T08:22:28.507 に答える
6

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())
于 2009-10-15T22:10:37.260 に答える
4

ルア、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
于 2009-10-15T23:35:48.663 に答える
4

C 196文字 <<o>>

ストレンジャーからいくつかのアイデアを借ります。興味深い機能には、n+++1「トリプル +」演算子と<<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);}
于 2009-10-16T05:39:42.413 に答える
4

Perl 5.10 で 168 文字

私の最初の解決策は 276 文字でしたが、何度も何度も微調整した結果、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

これを改善する小さな提案がある場合は、私のコードを編集してください。

于 2009-10-17T19:56:31.550 に答える
1

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);}
于 2009-10-15T22:27:18.417 に答える