Visualizar el código de Parsons


22

Introducción

El código Parsons es solo una manera simple de describir las variaciones de tono en una pieza musical, ya sea que una nota sea más alta o más baja que la anterior.

Incluso si apestas al recordar melodías, aún puedes recordar si una nota sube o baja, por lo que el código Parsons puede ayudarte a identificar una música usando un motor de búsqueda.


Descripción

Cada variación está representada por un solo carácter, que es uno de los siguientes:

  • Rsi la nota es la misma que la anterior (significa " R epeat" )
  • Usi la nota es más alta que la anterior (significa " U p" )
  • Dsi la nota es más baja que la anterior (significa " D propio" )

La nota inicial se escribe como *.


Ejemplo

Aquí hay un ejemplo de código Parsons (comienzo de "Oda a la Alegría" ):

*RUURDDDDRUURDR

Realmente puedes visualizarlo , así:

      *-*                    
     /   \                   
    *     *                  
   /       \                 
*-*         *         *-*    
             \       /   \   
              *     *     *-*
               \   /         
                *-*          

A partir de ahora lo llamaremos contorno .

Las reglas para dibujar dichos contornos se consideran explicadas por el ejemplo anterior.



Reto

Ahora viene el verdadero desafío.

Escriba un programa que, dado un contorno como entrada, emite su código Parsons correspondiente.

No se le pide que dibuje el contorno, sino todo lo contrario.
Desde el contorno, encuentre el código original de Parsons.


Reglas

  • Se aplican las reglas habituales para el golf de código.
  • El programa más corto en número de bytes gana
  • La entrada es un contorno y la salida debe ser un código Parsons válido.
  • Los detalles sobre espacios en blanco adicionales para la entrada son irrelevantes, haga lo que sea mejor para usted
  • No está permitido codificar, de una forma u otra, partes de la salida y / o el programa utilizando espacios en blanco adicionales debido a la regla anterior

Notas

  • Esto puede ser útil para probar
  • El código de Parsons correspondiente para *es*
  • Una cadena vacía no es un contorno válido
  • Un código de Parsons siempre comienza con*


¿Entonces debe comenzar con *quien no hace nada?
nicael

¿Qué quieres decir? cuando la entrada es justa *? No Debería imprimir *, supongo. Agregaré este caso de la esquina.
Helge von Koch

1
@nicael Sí, debe comenzar con *. Siempre.
Helge von Koch

Respuestas:



24

CJam, 21 bytes

qN/:.e>(o2%:i"DRXU"f=

Dobla las líneas ( :) vectorizando ( .) una operación máxima de carácter e>. Como solo hay un carácter sin espacio en cada columna, este será el resultado, ya que el espacio tiene un código ASCII más pequeño que todos los caracteres sin espacio imprimibles.

Desmarque e imprima el primer asterisco (o, luego asigne cada otro ( 2%) carácter restante para UDRusar la indexación modular.

Solución anterior (29 bytes)

'*qN/z2%'*f#0+2ew);::-"RDU"f=

qN/obtiene líneas de entrada. ztranspone esta matriz de caracteres. 2%cae cada fila impar. '*f#encuentra el índice del asterisco en cada fila. 0+2ew);obtiene todos los pares de índices sucesivos. ::-calcula sus diferencias, y "RDU"f=los asigna a las letras (a través de la indexación modular: 0 → R, 2 → U, -2 ≡ 1 → D). El encabezado '*antepone el asterisco.

EDITAR : cambié 2ewa 0+2ew);trabajar para evitar que CJam maneje ew(cortes sucesivos) en listas que son demasiado cortas. Esto hace que el código funcione para la cadena de entrada *.

Pruébalo aquí o míralo en acción:

              

77
Esto es realmente asombroso de ver.
Jeel Shah

2
¡Estoy de acuerdo! +1 para el código, ojalá pudiera +10 para el GIF.
ETHproductions

Por cierto, me gusta la carita sonriente en la longitud del código 17:-p
ETHproductions

1
Estoy de acuerdo, esto es increíble de ver. Sin embargo, no funciona *como entrada. Me da un buen RuntimeExceptionlugar.
Helge von Koch

Ugh, considero que un error de CJam: [X]2ewdebería volver en []lugar de fallar. Sin embargo, agregaré una solución alternativa.
Lynn

4

Python 3, 129 108 98 86 bytes

Probablemente hay varias formas de jugar al golf, pero me gusta bastante que lo tengo todo en una sola línea.

Editar: ahora usando''.translate()

Editar: Muchas gracias a wnnmaw .

Editar: cambié el formato de entrada a una matriz de cadenas en lugar de una cadena separada por una nueva línea para guardar bytes. Además, en la última edición, me confundí Uy Rlo arreglé.

lambda a:'*'+"".join(('UR'[j<'/']+'D')[j>'/']for l in zip(*a)for j in l if j in'-/\\')

La entrada debe ser una matriz de cadenas. Para el ejemplo anterior, esto se parece a:

["      *-*                    ","     /   \                   ","    *     *                  ","   /       \                 ","*-*         *         *-*    ","             \       /   \   ","              *     *     *-*","               \   /         ","                *-*          "]

Sin golf:

def f(a):
    s = ''
    for c in zip(*a):           # transpose
        for d in c:             # for each letter in column c
            if e in "-/\\":     # if that letter is either -,/,\
                if e < '/':     # if < '/' (same as if == '-')
                    s += "R"
                elif e > '/':   # if > '/' (same as if == '\')
                    s += "D"
                else:           # if == '/'
                    s += "U"
        return "*" + s          # in the code we ''.join() it all together
                                # in this ungolfing, we add to an empty string

No quiero dar una nueva respuesta porque tomé prestado mucho del tuyo, pero lambda s:'*'+"".join((('D','R')[j=='-'],'U')[j=='/']for l in zip(*s.split('\n'))for j in l if j in'\\/-')registra 105 bytes. La principal diferencia es utilizar una tupla condicional en lugar de traducir
wnnmaw

Gracias @wnnmaw! ¡Creo que puedo jugar golf aún más!
Sherlock9

Buen golf en el condicional en el frente, ¡eso es súper inteligente!
wnnmaw

Ah shucks. Gracias por el consejo @wnnmaw
Sherlock9

3

Rubí, 87 bytes

Requiere espacios finales en la entrada para que todas las líneas tengan la misma longitud.

$><<?*+$<.readlines.map(&:chars).transpose.join.gsub(/./,{?-=>:R,?/=>:U,?\\=>:D}).strip

44
Seguramente este es un código malicioso, ya que contiene >:D.
Alex A.

3

Japt, 38 bytes 40 41 45 46 48

Guardado 2 bytes gracias a @ETHproductions

'*+U·y £Yu ?"RUD"g1+(XrS c -47 g):P} q

Si hubiera un comando de recorte, esto sería solo 38 bytes; -; agregaré una explicación cuando termine de jugar al golf. El :Pprograma no intenta ser divertido, en realidad es el programa que ignora los personajes que no son importantes.

Pruébalo en línea


Cuando vi que había un desafío que prácticamente requería una transposición de matriz, y que Doᴡɴɢᴏᴀᴛ lo había respondido, supe que tenía que ser Japt.
ETHproductions

Por cierto, agregaré una función de recorte en xy transponer y rotar funciones en yy z(dividir en líneas nuevas, usar la función de matriz, unir con líneas nuevas)
ETHproductions

Podría guardar dos bytes como este:Yu ?"RUD"g1+(XrS c -47 g):P
ETHproductions

@ETHproductions gracias, ¡hasta menos de 40 bytes!
Downgoat

3

Haskell, 89 bytes

import Data.List
m '/'="U"
m '-'="R"
m '\\'="D"
m _=""
('*':).(>>=(>>=m)).transpose.lines

Ejemplo de uso:

*Main> ('*':).(>>=(>>=m)).transpose.lines $ "      *-*                    \n     /   \\                   \n    *     *                  \n   /       \\                 \n*-*         *         *-*    \n             \\       /   \\   \n              *     *     *-*\n               \\   /         \n                *-*          "
"*RUURDDDDRUURDR"

*Main> ('*':).(>>=(>>=m)).transpose.lines $ "*"
"*"

Transponga la entrada y reemplace los caracteres // -/ \con cadenas simples "U"/ "R"/ "D". Todos los demás caracteres se reemplazan por cadenas vacías "", que luego desaparecen al concatenar todo. Finalmente, anteponga el asterisco *.


2

Mathematica, 103 bytes

"*"<>(Differences@Position[Thread@Characters@StringSplit[#,"
"],"*"][[;;,2]]/.{-2->"U",0->"R",2->"D"})&

En resumen, considerando que este es un desafío de procesamiento de cadenas.


2

JavaScript (ES6) 90

Una función anónima. Escanea la cadena de entrada char por char, teniendo en cuenta la posición en la línea actual. Al hacer esto, se construye una matriz de salida subsituting U D Rpara / \ -en el lugar correcto

c=>[...c].map(c=>c>'*'?t[i++]=c>'/'?'D':c<'/'?'R':'U':c<' '?i=0:++i,t=['*'],i=0)&&t.join``

2

Matlab, 62 bytes

r=@(s)[85-(s<14)*3-(s>59)*17,''];@(p)r(sum(p(:,2:2:end)-32))

Esto requiere que la entrada sea rectangular (el mismo número de caracteres en cada fila). P.ej

    ['      *-*                    ';    '     /   \                   ';    '    *     *                  ';    '   /       \                 ';    '*-*         *         *-*    ';    '             \       /   \   ';    '              *     *     *-*';    '               \   /         ';    '                *-*          '];

Explicación

sum(p(:,2:2:end)-32)        % exctract every second column, substract 32 (spaces->zeros) 
                            % and sum column wise (results in a vector of 3 different values)
[85-(s<14)*3-(s>59)*17,'']  % map each of the values to the corresponding value of the letter and convert back to characters
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.