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*
Helge von Koch
fuente
¿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
2
Relacionado: codegolf.stackexchange.com/q/55593/42545
ETHproductions

Respuestas:

4

Pyth - 28 25 27 25 bytes

2 byes guardados gracias a @Jakube.

s+\*@L"RDU"-VFtBxR\*%2C.z

Pruébelo en línea aquí .

Maltysen
fuente
1
No funciona con *como entrada. La salida es *0mientras debería ser justa *. Apareció un cero salvaje malvado.
Helge von Koch
@HelgevonKoch solucionado
Maltysen
@Jakube gracias!
Maltysen
Has cambiado Uy Dpor cierto. De lo contrario, bien hecho.
Helge von Koch
@HelgevonKoch oops
Maltysen
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:

              
Lynn
fuente
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
Sherlock9
fuente
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
daniero
fuente
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

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

nimi
fuente
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.

LegionMammal978
fuente
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``
edc65
fuente
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
falla
fuente