The Note of Destiny - วางโน้ตไว้บนพนักงาน


19

การเปิดเผยของซอมบี้ได้มาแล้วและโลกก็จะสิ้นสุดลง ทันใดนั้นมีคนค้นพบสูตรที่ใช้เวลาชั่วโมงนาทีและวันปัจจุบันและแยกโน้ตที่สมบูรณ์แบบเพื่อเล่นบนเปียโนที่จะฆ่าซอมบี้ทุกตัวที่ได้ยินทันที น่าเสียดายที่มีผู้เล่นเปียโนเพียงคนเดียวที่เหลืออยู่ในโลกนี้และเขาลืมวิธีการอ่านโน้ต แต่เขาก็ยังรู้วิธีอ่านแผ่นโน้ตเพลง แน่นอนว่านี่เป็นสิ่งที่ไวต่อเวลามากดังนั้นจึงเป็นเรื่องธรรมดาที่คอมพิวเตอร์จะใช้คอมพิวเตอร์ 1

ความท้าทายของคุณคือการจดบันทึกเช่นGและส่งออกบันทึกย่อที่วางไว้บนเจ้าหน้าที่ (ในเสียงแหลมโน๊ต) เช่นนี้:

-----

-----
   |
---|-
   |
--O--

-----

รายละเอียด:

  • คุณต้องส่งออกพนักงานของสายการสลับของ-----(5 ขีดกลาง) และบรรทัดว่าง จะมี-----ทั้งหมด5 s หมายเหตุจะต้องซ้อนทับทับบนพนักงานนี้
  • อินพุตจะระบุตำแหน่งของบันทึกย่อ อินพุตจะเป็น:
    • ตัวเลือกHหรือLระบุ "สูง" หรือ "ต่ำ"
    • จดหมายจากAถึงGโดยระบุระดับเสียง
    • ตัวเลือก#หรือbระบุคมหรือแบน
  • "note" ถูกกำหนดเป็น:
    • หนึ่งO(เมืองหลวง O) จัดอยู่ตรงกลางของพนักงานซึ่งอยู่ในสถานที่ของบันทึก (บรรทัดบนสุดคือHF(สูง F) และบรรทัดล่างคือE(ปกติ E))
    • สาม|s (แถบแนวตั้ง), ก้านซึ่งจะเป็น:
      • หนึ่งช่องว่างทางด้านซ้ายของบันทึกย่อและไปด้านล่าง (เริ่มต้นหนึ่งช่องว่างด้านล่างของบันทึกย่อ) หากบันทึกย่ออยู่ในบรรทัดกลาง ( B) หรือสูงกว่าหรือ
      • หนึ่งช่องทางด้านขวาของบันทึกย่อและขึ้นไปข้างบน (เริ่มต้นหนึ่งช่องว่างเหนือบันทึก) หากโน้ตอยู่ต่ำกว่าเส้นกลาง
    • A #หรือbหนึ่งช่องว่างทางด้านซ้ายของบันทึกย่อหากระบุไว้ในอินพุต
  • ต้องเพิ่มบรรทัดบัญชีแยกประเภทหากบันทึกย่อสูงหรือต่ำเกินไป บรรทัดเหล่านี้จะ---(กว้าง 3 ขีดเท่านั้นเมื่อเทียบกับ 5) และจะปรากฏเฉพาะเมื่อโน้ตอยู่บนหรือสูงกว่า / ต่ำกว่า (สำหรับบรรทัดบัญชีแยกประเภทด้านบน / ล่างตามลำดับ) บรรทัดบัญชีแยกประเภท
  • ช่องว่างภายนอกอาจถูกวางไว้ทุกที่ที่คุณต้องการ ตัวอย่างเช่นคุณสามารถทำให้บรรทัดว่างมีช่องว่างหรือมีช่องว่างหลังบรรทัดบัญชีแยกประเภทถ้ามันช่วยให้คุณบันทึกอักขระใด ๆ

นี่คือการสร้างภาพเพื่อทำความเข้าใจข้อมูลจำเพาะได้ง่ายขึ้นด้วยชื่อโน้ตทั้งหมดที่อยู่ถัดจากบรรทัด

      HB
 ---  HA
      HG
----- HF
      HE
----- HD
      HC
----- B
      A
----- G
      F
----- E
      D
 ---  C
      LB
 ---  LA
      LG
 ---  LF
... (bottom cut off for brevity, you get the idea anyway)

นี่คือตัวอย่างเพิ่มเติมที่คุณสามารถใช้ทดสอบโปรแกรมของคุณ:

การป้อนข้อมูล: HG#

 #O
-|---
 |
-|---

-----

-----

-----

การป้อนข้อมูล: LAb

-----

-----

-----

-----

-----
   |
 --|
   |
 bO-

การป้อนข้อมูล: HB

  O
 |--
 |
-|---

-----

-----

-----

-----

การป้อนข้อมูล: C

-----

-----

-----

-----
   |
---|-
   |
 -O-

นี่คือดังนั้นโค้ดที่สั้นที่สุดเป็นไบต์จะเป็นผู้ชนะ!

1: การแสดงออกที่สมจริงที่สุด evar! :-P


2
มันดูแปลกมากที่มี#หรือbอยู่ทางด้านขวาของโน้ตแทนที่จะอยู่ทางซ้าย มันเป็นสิ่งที่จำเป็นจริง ๆ ?
โทมัสบารูเชล

2
สิ่งที่เกี่ยวกับ B # และชอบ? 1. พล็อตตาม - เป็น; 2. ปฏิเสธ 3. แปลงเป็น C เงียบ ๆ
บาดเจ็บทางดิจิทัล

2
มันอาจจะดีกว่าที่จะระบุอย่างชัดเจนว่ามันควรจะอยู่ในเสียงแหลม
user12205

3
ใครก็ตามที่พยายามทำสิ่งนี้ในFugue ?
AJMansfield

3
@AJM ใช่มันต้องเป็นศิลปะ ASCII
Doorknob

คำตอบ:


1

Golfscript, 211 210 209 197 195 192 ตัวอักษร

เข้ามาเพื่อลุ้นรับรางวัล (จากการโพสต์นี้) GolfScript รุ่นPython ล่าสุดของฉัน:

"J"\+[0]+.1=71>>3<{}/@7*2/246-@3+7%-:z;:c;21,{..3z<3z
if<\11z>11z
if>|{;}{...2>\12<&\2%.{'-'' 'if}:Q~:9;&Q\.z={c!9{[c]''+}if}{..z>\4z+<&8z>&'|'9if}if\.z='o'9if\..z
4-\<\z<&7z<&'|'9if\;3$n}if}/

ทดสอบที่นี่ (2 บรรทัดแรกคืออินพุตของผู้ใช้โดยปกติมาจาก stdin)

รุ่น 'อ่านได้':

;"HCb"

"J"\+[0]+       #process input
.1=71>>3<       #first char is HJL, second is letter, third is #b or space
{}/             #spill chars onto stack, now we working with ints
@7*2/246-@3+7%- #convert HC/JD/LE etc to a number from 0 to 20
:z;:c;
21,{            #for r in range(21):
  ..3z<3z if<           #either out-of-bounds or process the line
  \11z>11z if>|
  {;}{
    ...2>\12<&\2%.{'-'' 'if}:Q~:9;&Q\        #1st char
    .z={c!9{[c]''+}if}                       #2nd char accidental
       {..z>\4z+<&8z>&'|'9if}if\            #2nd char stem or row
    .z='o'9if\                              #3rd char
    ..z 4-\<\z<&7z<&'|'9if\                 #4th char stem or row
    ;3$                                      #5th char=1st char
    n
  }if
}/

เอาเป็นว่าแพ้ GolfScript อีกครั้ง :) ...
Martin Ender

@ m.buettner: ฮ่า ๆ มันไม่เคยจบ .. ใกล้เข้ามาอย่างน่าประหลาดใจ!
Claudiu

1
ดีกว่า! ตอนนี้ผมเพียงต้องการที่จะหา 6/9 ไบต์ที่จะจับขึ้น: D (แม้ว่าฉันไม่เห็นว่าฉันจะทำอย่างนั้น)
มาร์ตินเอนเดอร์

@ m.buettner: ลดลงอีก 2 ไบต์! แต่ละคนโหดเหี้ยมเหลือเกินแม้ว่า ... ข้าอาจจะต้องหยุดตอนนี้ โชคดี!
Claudiu

2
โอ้เลือดนองเลือด ... เมื่อฉันคิดว่าฉันถูกตี 209 ของคุณฉันคิดว่าฉันยอมแพ้ GolfScript เหนือกว่า ;)
Martin Ender

6

Ruby - 271 267 252 249 234 229 220 214 ตัวอักษร

ฉันเพิ่งเรียนรูบี้เรื่องนี้ ดังนั้นจึงมีห้องสำหรับการปรับปรุงในการตีกอล์ฟ หรือทำอะไรจริงๆ แต่ฉันต้องการภาษาที่มีสตริงที่ไม่แน่นอน :)

def f(n)s=[0]*20
s.fill{|i|i%2>0?i<3||i>11?" ---":?-*5:" "*5}
s[l=(3-n[(p="H_L".index n[0])?1:0].ord)%7+7*(p||1)][1,2]=("#b"[n[-1]]||s[l][1])+?O
s[l+3-2*o=l>7?3:1,3].map{|t|t[o]=?|}
puts s[[3,l].min..[11,l].max]end

ค่อนข้างอวดดี:

def f(note)
  staff=[]
  0.step(20) {|i| staff[i] = " "*5}
  1.step(19,2) {|i| staff[i] = " ---"}
  3.step(11,2) {|i| staff[i] = "-"*5}
  level = 7
  if !(pos="HL".index note[i=0]).nil?
    level = 14*pos
    i += 1
  end
  level += (73-note[i].ord)%7
  staff[level][2] = "O"
  mark = note[-1]
  if !"#b".index(mark).nil?
    staff[level][1] = mark
  end
  offset = (level > 7) ? 3 : 1
  staff[level-2*offset+3,3].map {|line| line[offset] = "|"}
  first = [3,level].min
  last = [11,level].max
  puts s[first..last]
end

ฉันสามารถตัดมันได้อีก 2 ตัวอักษรลงไปที่212 ตัวอักษรหากบรรทัดว่างนำหน้าได้รับอนุญาต วิธีนี้ไม่ได้เติมบรรทัดที่ไม่ได้พิมพ์อยู่แล้ว:

def f(n)s=[]
[3,l=(3-n[(p="H_L".index n[0])?1:0].ord)%7+7*(p||1)].min.step(l>11?l:11){|i|s[i]=i%2>0?i<3||i>11?" ---":?-*5:" "*5}
s[l][1,2]=("#b"[n[-1]]||s[l][1])+?O
s[l+3-2*o=l>7?3:1,3].map{|t|t[o]=?|}
puts s
end

เป็นเกมที่ยุติธรรมของแลมด้าหรือไม่? จากนั้นฉันก็จะได้210 ตัวอักษรด้วยวิธีแรก

f=->n{s=[0]*20
s.fill{|i|i%2>0?i<3||i>11?" ---":?-*5:" "*5}
s[l=(3-n[(p="H_L".index n[0])?1:0].ord)%7+7*(p||1)][1,2]=("#b"[n[-1]]||s[l][1])+?O
s[l+3-2*o=l>7?3:1,3].map{|t|t[o]=?|}
puts s[[3,l].min..[11,l].max]}

หรือ207 ตัวอักษรที่มีบรรทัดว่างเพิ่มเติม:

f=->n{s=[]
[3,l=(3-n[(p="H_L".index n[0])?1:0].ord)%7+7*(p||1)].min.step(l>11?l:11){|i|s[i]=i%2>0?i<3||i>11?" ---":?-*5:" "*5}
s[l][1,2]=("#b"[n[-1]]||s[l][1])+?O
s[l+3-2*o=l>7?3:1,3].map{|t|t[o]=?|}
puts s}

f.call("HGb")แน่นอนว่าตอนนี้คุณจะต้องทำ


ฮ่า +1 สำหรับการเรียนรู้ภาษาใหม่ทั้งหมด! ;-) นี่คือเคล็ดลับ: เทียบเท่ากับ!x.nil? !xและสำหรับหนึ่ง IFS บรรทัดเทียบเท่ากับif x;y;end; y if xนอกจากนี้คุณสามารถใช้ตัวอักษรขึ้นบรรทัดใหม่ในสตริงนั้นได้
Doorknob

@ Doorknob ขอบคุณฉันจะพยายามทำงานในสิ่งเหล่านั้น!
Martin Ender

@ Doorknob อืมฉันเพิ่งได้ifทำงาน ถ้าฉันใช้?\n(ถ้านั่นคือสิ่งที่คุณหมายถึง) ฉันต้องเพิ่มช่องว่างดังนั้นฉันจึงไม่ได้อะไรเลย และการลบ.nil?s ไม่ทำงานเลย (ประเมินเสมอtrue)
Martin Ender

ฉันหมายถึงการเพิ่มบรรทัดใหม่ระหว่างคำพูดสองคำ และฉันคิดว่าคุณจำเป็นต้องมีการเพิ่ม parens เมื่อถอดออก.nil?แต่มันก็คุ้มค่าในตัวละคร
Doorknob

@Doorknob ah, ไม่เป็น!x.nil? !!x:)
Martin Ender

2

Python, 329 309 295 286 280 277 ตัวอักษร

Golfed อีกเล็กน้อยในขณะนี้ ยังคงสามารถปรับปรุงได้ แต่ไม่แน่ใจว่าฉันสามารถเอาชนะโซลูชัน rubs หรือ golfscript ด้วยวิธีนี้ได้หรือไม่

R=range
N='J'+raw_input()+' '
X=N[1]>'G'
a,b,c=N[X:3+X]
z=266-ord(a)/2*7+(ord(b)-4)%7
Z=[list((' '*5,(' ---','-'*5)[8<r<18])[r%2])for r in R(21)]
Z[z][2]='o'
if' '<c:Z[z][1]=c
Q=(z<13)*2
for i in(1,2,3):Z[z+i*Q-i][Q+1]='|'
for r in R(max(17,z),min(z-1,8),-1):print''.join(Z[r])

ตอนแรกฉันกำลังพิมพ์บรรทัดต่อบรรทัด แต่มันกลับกลายเป็นมากเกินไปดังนั้นฉันจึงสร้างสตริงกริดและเติมสิ่งที่จำเป็นต้องกรอกข้อมูลอินพุตมาจากบรรทัดคำสั่งเช่น:

>echo HG# | python note2_golf.py
 #o
-|---
 |
-|---

-----

-----

-----

ในบรรทัดที่ 5 คุณสามารถลบช่องว่างก่อนเครื่องหมายจุลภาคที่สอง
user12205

@ace: ขอบคุณที่พลาดหนึ่ง
Claudiu

2

GolfScript - 243 232 228 227 ตัวอักษร

ฉันแปลคำตอบ CoffeeScript ของฉันเป็น GolfScript ซึ่งเหมาะกับการปรับเปลี่ยนสตริงมากขึ้น

แก้ไข:บันทึกหกตัวอักษรโดยใช้ตัวดำเนินการเพิ่มอย่างเหมาะสมสามตัวโดยใช้ประโยชน์จากสแต็กอย่างเหมาะสมอีกหกตัวโดยการกำหนดตัวดำเนินการที่ฉันไม่ได้ใช้โดยไม่รับผิดชอบ

ทั้งหมด golfed:

..0="HL"?2+3%:o)2%.@="CDEFGAB"?7o*+:`2%45 32if:r;
).2$,<{=}{;;r}if:&;
[" "5*:|" ---":g]4*[|"-"5*]5*+[|g|]+.
[`<~]\[`>([0=:^&79r^]''+\~]
+17`<`)18if<9`>`9if:j>:t 13`>.2*):x;
4,1>{`j-\2${+}{-}if}%\;
{.@<\t>(:v[x<'|'+x)v>+]\++:t}
/-1%n*

ด้วยความคิดเห็น:

# extract octave
..0="HL"?2+3%:o

# extract note
2%1\-.@="CDEFGAB"?7o*+:k

# line spacer
2%45 32if:r;

# extract accidental
1+.2$,<{=}{;;r}if:a;

# staff
[" "5*:|" --- ":g]4*[|"-"5*]5*+[|g|]+.

# lines below
[k<~]\

# note line and above
[k>([0=:w a 79r w]''+\~]+

# cut off just what we need
17k<1k+18if<
9k>k 9if:j>:t;

# and the note stem
13k>.2*1+:x;4,1>{k j-\2${+}{-}if}%\;

{
  .t<\
  t>(:v[x<'|'+1x+v>+]\++:t;
}/

# now output the note
t-1%n*

ฉันคงจะประหลาดใจถ้าฉันสามารถเอาชนะ GolfScript solution ในภาษาที่ฉันไม่เคยมีประสบการณ์มาก่อน)
Martin Ender

1
ฉันไม่ใช่ผู้เชี่ยวชาญ GolfScript แต่ฉันคิดว่าฉันได้ออกตัวละครทุกตัวที่ฉันจะออกไปจากเรื่องนี้ดังนั้นถ้าคุณสามารถหาอีกสองตัวคุณเป็นทอง!
couchand

พยายามที่จะพิมพ์Goในนั้น มันจะออกoo|||:)
เจมี่

1

งูหลาม, 250 245 242 235 ตัวอักษร

แนวทางที่แตกต่างซึ่งจบลงด้วยการตีหนึ่งของฉัน! รหัสการประมวลผลอินพุตคล้ายกัน แต่เกี่ยวกับมัน

M=' -'
N=raw_input()+M
a,b,c=('J'+N)[N>'G':][:3]
z=ord(a)*7/2-246-(ord(b)+3)%7
for r in range(21):
 L=M[r%2];F=M[2<r<12and r%2]
 if min(3,z)<=r<=max(11,z):print F+((L,'|')[8>z<r<z+4],(L,c)[M<c])[r==z]+(L,'o')[r==z]+(L,'|')[z-4<r<z>7]+F

ฉันทำแผนที่ค่าของตัวละครแต่ละตัวตามแถวและคอลัมน์จากนั้นทำการตีพิมพ์:

#given row r, with note on row n, how to print each char?
#rows are:
#       HB : 0
#  ---  HA : 1
#       HG : 2
# ----- HF : 3
#       HE : 4
# ----- HD : 5
#       HC : 6
# ----- B  : 7
#       A  : 8
# ----- G  : 9
#       F  : 10
# ----- E  : 11
#       D  : 12
#  ---  C  : 13
#       LB : 14
#  ---  LA : 15
#       LG : 16
#  ---  LF : 17
#       LE : 18
#  ---  LD : 19
#       LC : 20
#chars are:
# 0 | 1 | 2 | 3 | 4
#
# 0,4:
#    if r%2:
#      if 2<r<12: '-'
#      else ' '
#    else: ' '
# 1: ' -b#|'
#    if r==n:
#      if A: c
#      else: ' -'[r%2]
#    elif n<8 and n<r<n+4: '|'
#    else: ' -'[r%2]
# 2: ' -o'
#    if r==n: 'o'
#    else: ' -'[r%2]
# 3: ' -|'
#    if n>7 and n-4<r<n: '|'
#    else: ' -'[r%2]

+1, บรรทัดสุดท้ายดูเหมือนจะเป็นมนต์ดำของ Perl มากกว่า Pythonic
Antonio Ragagnin

1

Java - 921 907 863 ตัวอักษร

ฉันสร้างแต่ละสตริงแยกกันโดยเก็บแต่ละสตริงในอาร์เรย์ จากนั้นวนรอบอาร์เรย์และพิมพ์แต่ละบรรทัด

public class D{public static void main(String[]a){char[]z=a[0].toCharArray();char[]y=new char[3];y[0]=('H'==z[0]||'L'==z[0])?z[0]:'N';int o=(y[0]=='N')?0:1;y[1]=z[o++];y[2]=z.length>o?z[o]:'!';int n=y[1]<'C'?((int)(y[1]-'A'))+6:((int)(y[1]-'C'))+1;n=(y[0]=='N')?n+7:(y[0]=='H'?n+14:n);String s="     ";String b=" --- ";String[]u=new String[22];for(int i=1;i<=21;i+=2){u[i]=s;}for(int i=10;i<=18;i+=2){u[i]="-----";}u[20]=n>19?b:s;u[2]=n<3?b:s;u[4]=n<5?b:s;u[6]=n<7?b:s;u[8]=n<9?b:s;char c=u[n].charAt(0);char e=u[n].charAt(1);char[]h=new char[]{c,y[2]=='!'?e:y[2],'O',e,c};u[n]=new String(h);for(int i=0;i<22;i++){if(n<14&&i-n<4&&i>n)u[i]=u[i]!=null?u[i].substring(0,3)+"|"+u[i].charAt(4):s;else if(n>13&&n-i<4&&n>i)u[i]=u[i]!=null?u[i].substring(0,3)+"|"+u[i].charAt(4):s;}for(int i=21;i>=0;i--)if(!(i>n&&i>18||i<n&&i<10))System.u.println((u[i]==null)?s:u[i]);}}

โอ้โปรดอย่าเกลียดฉันมันเป็นครั้งแรกของฉัน ฉันไม่พบคำถาม / คำแนะนำใด ๆ เลยฉันหวังว่ารูปแบบการโพสต์ของฉันจะใช้ได้ ไม่แน่ใจว่าผู้คนมีความร้ายแรงเกี่ยวกับการนับตัวอักษรอย่างไร .... รหัสปกติเวอร์ชัน - พิเศษคือ linebreak / ช่องว่าง (1313 ตัวอักษร):

public class DisplayNote
{
  public static void main(String[] args)
  {
    char[] z=args[0].toCharArray();
    char[] y=new char[3];
    y[0]=('H'==z[0]||'L'==z[0])?z[0]:'N';
    int o=(y[0]=='N')?0:1;
    y[1]=z[o++];
    y[2]=z.length>o?z[o]:'!';

    int noteValue=y[1]<'C'?((int) (y[1] - 'A')) + 6:((int) (y[1] - 'C')) + 1;
    noteValue=(y[0]=='N')?noteValue+7:(y[0]=='H'?noteValue+14:noteValue);
    String s="     ";
    String b=" --- ";
    String[] out=new String[22];
    for (int i=1;i<=21;i+=2){out[i]=s;}
    for (int i=10;i<=18;i+=2){out[i]="-----";}
    out[20]=noteValue>19?b:s;
    out[2]=noteValue<3?b:s;
    out[4]=noteValue<5?b:s;
    out[6]=noteValue<7?b:s;
    out[8]=noteValue<9?b:s;

    char c=out[noteValue].charAt(0);
    char e=out[noteValue].charAt(1);
    char[] h=new char[]{c,y[2]=='!'?e:y[2],'O',e,c};
    out[noteValue]=new String(h);
    for (int i=0;i<22;i++)
    {
      if (noteValue<14&&i-noteValue<4&&i>noteValue)
        out[i]=out[i]!=null?out[i].substring(0,3)+"|"+out[i].charAt(4):s;
      else if (noteValue>13&&noteValue-i<4&&noteValue>i)
        out[i]=out[i]!=null?out[i].substring(0,3)+"|"+out[i].charAt(4):s;        
    }

    for (int i=21;i>=0;i--)
      if (!(i>noteValue&&i>18||i<noteValue&&i<10))
        System.out.println((out[i]==null)?s:out[i]);
  }
}

ฉันเห็นตันของช่องว่างที่ไม่จำเป็น (โดยเฉพาะอย่างยิ่งหลังจากที่อัฒภาคและรอบ ๆ ผู้ประกอบการและวงเล็บและ parens) และชื่อตัวแปรยาว (ชอบargs)
Doorknob

ในการส่งการนับตัวอักษร: 921 ตัวอักษรช่องว่างทั้งหมดหายไป: P
Will_61

การส่งครั้งที่สองพร้อมช่องว่างทุกที่คือเพื่อให้ผู้คนอ่านรหัสดังที่ฉันบอกว่ามันเป็นครั้งแรกของฉันดังนั้นไม่แน่ใจว่าถ้าเราตั้งใจจะออกจากการส่ง 1 ครั้งและ 1 ที่คุณพยายามลดจำนวนอักขระ ...
Will_61

ไม่มี ฉันเห็นช่องว่างที่ไร้ประโยชน์จำนวนมหาศาลในรุ่นนั้น ตัวอย่างเช่นช่องว่างหลังเครื่องหมายอัฒภาคช่องว่างรอบตัวดำเนินการช่องว่างหลัง[]ช่องว่างรอบวงเล็บ ฯลฯ
Doorknob

ลบออกทั้งหมดตอนนี้ (ฉันคิดว่า) ขอบคุณ :)
Will_61

1

Haskell 377C

import Data.Char
(<.)=elem
n(c:r)|elem c"HL"=let(s,a)=n r in(s+case c of 'H'->7;_-> -7,a)|1<2=(mod(ord c-67)7-2,case r of[]->' ';[x]->x)
r(s,a)y x=c where d|s>4= -1|1<2=1;c|x<.[0,4]&&(y<0||y>8)=' '|x==2&&y==s='o'|y==s&&x==1&&' '/=a=a|x==2+d&&y<.[s+k*d|k<-[1..3]]='|'|1<2="- "!!mod y 2
g p@(s,a)=unlines$[map(r p y)[0..4]|y<-reverse[min 0 s..max 8 s]]
main=getLine>>=putStr.g.n

เวอร์ชันที่ไม่ถูกปรับแต่ง:

import Data.Char

fromName ('H':s) = let (step, alter) = fromName s in ((step + 7), alter)
fromName ('L':s) = let (step, alter) = fromName s in ((step - 7), alter)
fromName (x:s) = (mod (ord x - 67) 7 - 2, if null s then ' ' else head s)

renderChar :: (Int, Char) -> Int -> Int -> Char
renderChar (step, alter) y x = let
    dir = if step >  4 then -1 else 1
    normal = "- "!!mod y 2
    stemYs = [step + k * dir | k <- [1..3]]
    c | elem x [0,4] && not(elem y [0,2,4,6,8]) = ' '
      | x == 2 && y == step = 'o'
      | y == step && x == 1 && alter /= ' ' = alter
      | elem y stemYs && x == 2 + dir = '|'
      | otherwise = normal
  in c

render :: (Int, Char)-> String
render (step, alter) = unlines [map (renderChar (step, alter) y) [0..4] | y <- ys] 
  where
    ys = reverse [min 0 step .. max 8 step]

main = getLine >>= (putStr.render.fromName)

0

Literate CoffeeScript - 497 527 ตัวอักษร

ฉันแน่ใจว่ามีวิธีที่ดีกว่าในการสร้างตาราง แต่ฉันไม่สามารถเข้าใจได้

ผู้ช่วยกอล์ฟคนหนึ่ง

_=(q)->->q.split ""

แอร์ขนาดใหญ่และพนักงาน

s=_("CDEFGAB")()
l=_ "-----"
e=_ "     "
g=_ " --- "
t=->
  o=[e(),l(),e(),l(),e(),l(),e(),l(),e(),l(),e(),g(),e()]
  o.unshift e(),g() for [0..3]
  o

ฟังก์ชันสัญกรณ์ของเราจะใช้การแทนสตริงของบันทึกย่อ

f=(i)->
  o=1
  m=t()

ก่อนอื่นเราจะกำหนดอ็อกเทฟ

  if /L|H/.test i[0]
    if i[0]=="L" then o=0 else o=2
    i=i[1..]

จากนั้นให้จดและเกิดอุบัติเหตุ ต้องรักการแยกชิ้นส่วนมอบหมาย

  [n,a]=i

ลองแปลงโน้ตและอ็อกเทฟเป็นดัชนีและพล็อตโน้ต

  x=7*o+s.indexOf n

  m[x][1]=a if a
  m[x][2]='O'

ตอนนี้เราจะตัดเฉพาะพนักงานมากเท่าที่เราต้องการ

  j=9
  k=17
  if x>17
    k=x
  else if x<9
    j=x
  u=x-j
  m=m[j..k]

และต้นกำเนิดโน้ต

  if x<13
    m[x][3]='|' for x in [u+3...u]
  else
    m[x][1]='|' for x in [u-3...u]

ทีนี้มาผลลัพธ์กันดีกว่า

  m.map((p)->p.join '').reverse().join '\n'

สุดท้ายเราจะส่งออกฟังก์ชั่นสำหรับการทดสอบคอนโซล อักขระเหล่านี้ไม่นับรวม

module.exports = f

ดูใกล้ ๆ ขึ้นดูเหมือนว่าฉันจะเมาเมื่อทำการอัดก้านโน้ตใหม่อีกครั้งดังนั้นมันจึงสร้างเอาท์พุทที่ผิดกฎหมายในขณะนี้
couchand

ฉันแก้ไขแล้ว แต่ก็เพิ่ม 30 ตัวอักษร: - /
couchand

0

C, 325 304

ตอนนี้ 21 ไบต์สั้นลงด้วย@ace !

i;j;c;n;main(t){char
x[133];for(i;i<132;i++){x[i]="-----\n     \n"[i%12];if((i<18||i>77)&&!((i%12)&11))x[i]=32;}for(;!n;){c=getchar();if(c>71)t=c^72?2:0;else
n=7*t+7-(c-4)%7;}x[i=n*6+2]=79;if((c=getchar())>32)x[i-1]=c;for(t=0,j=n<9?i+5:i-17;t<3;t++,j+=6)x[j]='|';x[n<13?77:n*6+5]=0;puts(x+(n>4?24:n*6));}

เอาท์พุท:

./a.out
HBb
 bO  
 |-- 
 |   
-|---

-----

-----

-----

-----


./a.out
LG#
-----

-----

-----

-----

-----

 --| 
   | 
 --| 
 #O  

ตัวแปรโกลบอลจะถูกกำหนดค่าเริ่มต้นเป็นศูนย์โดยค่าเริ่มต้นดังนั้นคุณไม่จำเป็นต้องเริ่มต้นnและคุณสามารถลบi=0ในforวงแรก
user12205

นอกจากนี้ในครั้งแรกที่ifคำสั่งจะถูกแทนที่ด้วย((i%12)&11)==0 !((i%12)&11)
user12205

สุดท้าย?:มีความสำคัญต่ำกว่ามาก^และเพื่อให้คุณสามารถลบวงเล็บเงื่อนไขก่อน< ?และคุณสามารถแทนที่ด้วยprintf("%s", puts(
user12205

0

JavaScript 390 388

ความท้าทายเล็กน้อยฉันจะต้องยอมรับ ... ฉันแน่ใจว่ามีวิธีลดความมันต่อไป ... ฉันเปิดรับข้อเสนอแนะ ...

การย้ำครั้งแรก

C=(a,x,o,c)=>{a[x]=a[x].substr(0,o)+c+a[x].substr(o+1)};l=7;s=[];for(i=21;i--;)s[i]="    ";for(j=1;19>j;j+=2)s[j]=" ---";for(k=3;12>k;k+=2)s[k]="-----";~(p="HL".indexOf((n=prompt())[i=0]))&&(l=14*p,i++);l+=(73-n.charCodeAt(i))%7;C(s,l,2,"O");m=n[n.length-1];"#"!=m&   "b"!=m||C(s,l,1,m);o=7<l?3:1;for(z=0;3>z;C(s,t=l-2*o+3+z++,o,"|"));S=s.splice(3<=l?3:l,11>=l?11:l);console.log(S.join("\n"))

การวนซ้ำครั้งที่สอง (ใช้n.slice(-1)แทนn[n.length-1]) จะโกนได้ 2 ไบต์

C=(a,x,o,c)=>{a[x]=a[x].substr(0,o)+c+a[x].substr(o+1)};l=7;s=[];for(i=21;i--;)s[i]="    ";for(j=1;19>j;j+=2)s[j]=" ---";for(k=3;12>k;k+=2)s[k]="-----";~(p="HL".indexOf((n=prompt())[i=0]))&&(l=14*p,i++);l+=(73-n.charCodeAt(i))%7;C(s,l,2,"O");m=n.slice(-1);"#"!=m& "b"!=m||C(s,l,1,m);o=7<l?3:1;for(z=0;3>z;C(s,t=l-2*o+3+z++,o,"|"));S=s.splice(3<=l?3:l,11>=l?11:l);console.log(S.join("\n"))

เวอร์ชันที่ไม่ถูกปรับแต่ง:

function C(a,x,o,c){
    a[x]=a[x].substr(0,o)+c+a[x].substr(o+1);
}
l=7;s=[];
for(i=21;i--;){
    s[i]="    ";
}
for(j=1;19>j;j+=2){
    s[j]=" ---";
}
for(k=3;12>k;k+=2){
    s[k]="-----";
}
i=0;n=prompt();
p="HL".indexOf(n[i]);
if(p>=0){
    l=14*p;i++;
}
l+=(73-n.charCodeAt(i))%7;
C(s,l,2,"O");
m=n.slice(-1);
if((m=="#")||m=="b"){
    C(s,l,1,m);
}
o=7<l?3:1;
for(z=0;3>z;z++){
    C(s,t=l-2*o+3+z,o,"|");
}
F=Math.min(3,l);
L=Math.max(11,l);
S=s.splice(F,L);
console.log(S.join("\n"));

คุณช่วยเพิ่มเวอร์ชั่นที่อ่านง่ายได้ไหม?
Martin Ender

@ m.buettner เสร็จสิ้น ... ฉันหวังว่ามันจะช่วยให้คุณเข้าใจในสิ่งที่ผมเคยทำ :)
WallyWest
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.