The Note of Destiny - coloca una nota en un pentagrama

19

El apocalipsis zombie ha llegado y el mundo está llegando a su fin. De repente, alguien descubre una fórmula que toma la hora, los minutos y el día actuales, y escupe la nota perfecta para tocar en un piano que mata instantáneamente a cada zombi que lo escucha. Desafortunadamente, solo queda un pianista en el mundo, y se ha olvidado de cómo leer notas, pero aún sabe leer partituras. Por supuesto, esto es algo muy sensible al tiempo, por lo que parece natural que una computadora lo haga. 1

Su desafío es tomar una nota, como Gy enviar la nota colocada en un pentagrama (en clave de sol), de esta manera:

-----

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

-----

Especificación:

  • Debe generar un pentagrama de líneas alternas de -----(5 guiones) y una línea en blanco. Habrá 5 -----s en total. La nota debe superponerse sobre este personal.
  • La entrada especificará dónde se encuentra la nota. La entrada será:
    • un opcional Ho L, especificando "alto" o "bajo"
    • una carta de Aa G, especificando el tono
    • un opcional #o b, especificando agudo o plano.
  • La "nota" se define como:
    • Uno O(O mayúscula) alineado al centro del pentagrama, que está en el lugar de la nota. (La línea superior es HF(F alta) y la línea inferior es E(una E normal).
    • Tres |s (barras verticales), el tallo, que será:
      • un espacio a la izquierda de la nota y hacia abajo (comenzando un espacio debajo de la nota) si la nota está en la línea media ( B) o arriba, o
      • un espacio a la derecha de la nota y hacia arriba (comenzando un espacio por encima de la nota) si la nota está debajo de la línea media.
    • Un #o bun espacio directamente a la izquierda de la nota si se especifica en la entrada.
  • Deben agregarse líneas contables si la nota es demasiado alta o baja. Estas líneas serán ---(solo 3 guiones de ancho, en lugar de 5) y solo aparecerán si la nota está en o arriba / abajo (para las líneas de contabilidad superior / inferior respectivamente) las líneas de contabilidad.
  • Se pueden colocar espacios extraños en cualquier lugar que desee; por ejemplo, podría hacer que las líneas en blanco tengan espacios o después de las líneas del libro mayor si le ayuda a guardar los caracteres.

Aquí hay una visualización, para comprender la especificación más fácilmente, con todos los nombres de las notas al lado de las líneas:

      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)

Aquí hay algunos ejemplos más que puede usar para probar su programa:

Entrada: HG#

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

-----

-----

-----

Entrada: LAb

-----

-----

-----

-----

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

Entrada: HB

  O
 |--
 |
-|---

-----

-----

-----

-----

Entrada: C

-----

-----

-----

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

Este es el , por lo que el código más corto en bytes ganará.

1: exposición más realista evar! :-PAG

Pomo de la puerta
fuente
2
Parece muy extraño tener #o ba la derecha de la nota en lugar de a la izquierda; ¿Es realmente lo que se requiere?
Thomas Baruchel
2
¿Qué pasa con B # y similares? 1. trazar como está; 2. rechazar; 3. ¿convertir silenciosamente a C?
Trauma digital
2
Puede ser mejor decir explícitamente que debe estar en clave de sol.
user12205
3
¿Alguien puede intentar esto en Fugue ?
AJMansfield
3
@AJM Sí, tiene que ser el arte ASCII.
Pomo de la puerta

Respuestas:

1

Golfscript, 211 210 209 197 195 192 caracteres

Al ganar (a partir de esta publicación), una versión de GolfScript de mi última versión de 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}/

Pruébelo aquí (las primeras 2 líneas son introducidas por el usuario, normalmente proviene de stdin).

Versión 'legible':

;"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
}/
Claudiu
fuente
Aaaaaa y otra vez golpeado por GolfScript. :) ...
Martin Ender
@ m.buettner: Jaja, nunca termina ... ¡sorprendentemente cerca!
Claudiu
1
¡Mejor! Ahora solo necesito encontrar 6/9 bytes para ponerme al día: D (aunque no veo cómo haría eso)
Martin Ender
@ m.buettner: ¡Tengo 2 bytes más abajo! Sin embargo, cada uno es tan brutal ... Podría tener que parar por ahora. ¡Buena suerte!
Claudiu
2
Oh, maldita sea ... justo cuando pensé que había vencido a tu 209. Creo que me estoy rindiendo. GolfScript prevalece. ;)
Martin Ender
6

Ruby - 271 267 252 249 234 229 220 214 caracteres

Literalmente aprendí a Ruby para esto. Por lo tanto, ciertamente hay margen de mejora en jugar golf. O haciendo algo realmente. Pero necesitaba un lenguaje con cadenas mutables. :)

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

Algo descabellado:

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

Puedo reducirlo en otros 2 caracteres a 212 caracteres si se permiten líneas en blanco iniciales. Esta solución no llena las líneas que no se imprimen de todos modos:

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

¿Son el juego justo de lambda? Entonces puedo obtener 210 caracteres con el primer enfoque

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]}

O 207 caracteres con líneas en blanco adicionales:

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}

Por supuesto, ahora deberías hacerlo f.call("HGb").

Martin Ender
fuente
¡Ja, +1 por aprender un idioma completamente nuevo! ;-) Aquí hay un consejo: !x.nil?es equivalente a !x. Y para una línea ifs, if x;y;end;es equivalente a y if x. También puede usar una nueva línea literal en esa cadena.
Pomo de la puerta
@Doorknob gracias, ¡intentaré trabajar en eso!
Martin Ender
@Doorknob hm, solo tengo ifque trabajar. Si uso ?\n(si eso es lo que quisiste decir) necesito agregar un espacio, así no gano nada. Y eliminar los .nil?s no funcionó en absoluto (siempre evaluado true).
Martin Ender
Me refería literalmente a agregar una nueva línea entre las dos citas. Y creo que se necesitan parens adicionales al eliminar .nil?, pero vale la pena en caracteres.
Pomo de la puerta
@Doorknob ah, no lo !x.nil?es !!x. :)
Martin Ender
2

Python, 329 309 295 286 280 277 caracteres

Golfé un poco más ahora. Todavía se puede mejorar, pero no estoy seguro si puedo vencer a las soluciones ruby ​​o golfscript con este enfoque.

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])

Inicialmente estaba imprimiendo línea por línea, pero resultó que tomaba demasiado, así que generé una cuadrícula de cadena y luego rellené lo que se debe completar. La entrada es desde la línea de comandos, por ejemplo:

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

-----

-----

-----
Claudiu
fuente
En la línea 5 puede eliminar el espacio antes de la segunda coma
usuario12205
@ace: Gracias, me perdí esa
Claudiu
2

GolfScript - 243 232 228 227 caracteres

Traduje mi respuesta CoffeeScript a GolfScript, que es mucho más adecuado para las manipulaciones de cadenas.

EDITAR: guardé seis caracteres usando correctamente el operador de incremento, tres haciendo un buen uso de la pila, seis más redefiniendo irresponsablemente los operadores que no estoy usando, y uno más al no imprimir el espacio final después de las líneas de gracia.

Completamente golfizado:

..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*

Con comentarios:

# 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*
couchand
fuente
Me hubiera sorprendido si pudiera superar una solución de GolfScript en un lenguaje en el que no tengo experiencia;)
Martin Ender
1
No soy un experto en GolfScript, pero creo que he eliminado casi todos los personajes que voy a sacar de esto, así que si puedes encontrar otros dos, ¡eres dorado!
Couchand
Intenta escribirlo Go. saldrá oo|||:)
Jamie
1

Python, 250 245 242 235 caracteres

¡Un enfoque muy diferente que terminó superando a mi otro! El código de procesamiento de entrada es similar, pero eso es todo.

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

Mapeé el valor de cada personaje en función de la fila y la columna y luego desarrollé la impresión:

#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]
Claudiu
fuente
+1, Última línea parece más magia negra de Perl que cosas
pitónicas
1

Java - 921 907 863 caracteres

Construyo cada cadena por separado, almacenando cada cadena en una matriz. Luego recorra la matriz e imprima cada línea.

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]);}}

Oh por favor no me odies, es mi primera vez. No puedo encontrar ninguna pregunta frecuente / introducción, así que espero que mi formato de publicación esté bien. No estoy seguro de cuán serias se pusieron las personas sobre el recuento de caracteres ... versión normal del código: adicional es linebreak / spaces (1313 caracteres):

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]);
  }
}
Will_61
fuente
Veo toneladas de espacios en blanco innecesarios (especialmente después de punto y coma y alrededor de operadores, paréntesis y paréntesis) y nombres largos de variables (como args).
Pomo de la puerta
En la presentación de recuento de caracteres: 921 caracteres, todo el espacio en blanco se ha ido: P
Will_61
El segundo envío con espacios en blanco en todas partes es dejar que las personas lean el código, como dije, es la primera vez, así que no estoy seguro de si debemos dejar 1 envío y 1 donde intentes reducir el límite de caracteres ... ¿o qué?
Will_61
No; Veo una enorme cantidad de espacios en blanco inútiles en esa versión. Por ejemplo, espacios después de punto y coma, espacios alrededor de operadores, espacios después [], espacios alrededor de paréntesis, etc.
Pomo de la puerta
Los eliminó a todos ahora (creo) Gracias :)
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

Versión sin golf:

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)
Rayo
fuente
0

CoffeeScript literario - 497 527 caracteres

Estoy seguro de que hay una mejor manera de construir la cuadrícula, pero no puedo entenderlo.

Un ayudante de golf.

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

AC mayor escala y personal.

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

Nuestra función de notación tomará la representación de cadena de una nota.

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

Primero determinaremos la octava.

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

Luego la nota y accidental. Tengo que amar la tarea de deconstruir.

  [n,a]=i

Convirtamos la nota y la octava en un índice y grafiquemos la nota.

  x=7*o+s.indexOf n

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

Ahora eliminaremos solo la cantidad de personal que necesitemos.

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

Y la nota de tallo.

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

Ahora produzcamos los resultados.

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

Finalmente, exportaremos la función para probar la consola. Estos personajes no cuentan para el total.

module.exports = f
couchand
fuente
Mirando más de cerca parece que me equivoqué al refactorizar el tallo de la nota, por lo que produce una salida ilegal en este momento.
Couchand
Lo arreglé, pero agregó 30 caracteres: - /
couchand
0

C, 325 304

¡Ahora 21 bytes más cortos gracias a @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));}

Salida:

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

-----

-----

-----

-----


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

-----

-----

-----

-----

 --| 
   | 
 --| 
 #O  
ossifrage aprensivo
fuente
Las variables globales se inicializan a cero de manera predeterminada, por lo que no necesita inicializar ny puede eliminarlas i=0en el primer forbucle.
user12205
Además, en la primera ifdeclaración, ((i%12)&11)==0se puede reemplazar con !((i%12)&11).
usuario12205
Finalmente, ?:tiene una precedencia muy inferior a ^y <, por lo que puede eliminar los corchetes de las condiciones anteriores a ?. Y puedes reemplazar printf("%s",con puts(.
user12205
0

JavaScript 390 388

Un pequeño desafío, debo admitirlo ... Estoy seguro de que hay formas de reducir esto aún más ... Estoy abierto a sugerencias ...

Primera iteración

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"))

Segunda iteración (usando en n.slice(-1)lugar de n[n.length-1]), afeita 2 bytes

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"))

Versión sin golf:

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"));
WallyWest
fuente
¿Podría agregar una versión no legible (legible), por favor?
Martin Ender
@ m.buettner Hecho ... Espero que te ayude a comprender mejor lo que he hecho :)
WallyWest