Visualizando Código Parsons


22

Introdução

O código de Parsons é apenas uma maneira simples de descrever variações de tom em uma peça musical, seja uma nota maior ou menor que a anterior.

Mesmo se você se lembrar de músicas, ainda é possível lembrar se uma nota sobe ou desce, portanto, o código Parsons pode ajudá-lo a identificar uma música usando um mecanismo de pesquisa.


Descrição

Cada variação é representada por um único caractere, que é um dos seguintes:

  • Rse a nota for a mesma que a anterior (significa " R epeat" )
  • Use a nota for maior que a anterior (significa " U p" )
  • Dse a nota for menor que a anterior (significa " D own" )

A nota inicial é escrita como *.


Exemplo

Aqui está um exemplo de código de Parsons (início de "Ode to Joy" ):

*RUURDDDDRUURDR

Você pode visualizá- lo assim:

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

Vamos chamar isso de um contorno a partir de agora.

As regras para desenhar esses contornos são consideradas auto-explicadas pelo exemplo acima.



Desafio

Agora vem o verdadeiro desafio.

Escreva um programa que, dado um contorno como entrada, produz seu código Parsons correspondente.

Você não é solicitado a desenhar o contorno, mas o oposto, na verdade.
No contorno, encontre o código Parsons original.


Regras

  • Aplicam-se as regras usuais para o golfe com código
  • O programa mais curto em número de bytes vence
  • A entrada é um contorno e a saída deve ser um código Parsons válido
  • Detalhes sobre espaço em branco extra para a entrada são irrelevantes, faça o que for melhor para você
  • Você não tem permissão para codificar, de uma maneira ou de outra, partes da saída e / ou do programa usando espaço em branco extra devido à regra anterior

Notas

  • Isso pode ser útil para testar
  • O código Parsons correspondente para *é*
  • Uma sequência vazia não é um contorno válido
  • Um código Parsons sempre começa com*


Então deve começar com o *que não faz nada?
Nicael 28/12/2015

O que você quer dizer? quando a entrada é justa *? Não. Deveria imprimir *, suponho. Vou adicionar esta caixa de canto.
Helge von Koch

1
@nicael Sim, deve começar com *. Sempre.
Helge von Koch

Respostas:



24

CJam, 21 bytes

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

Dobre as linhas ( :) vetorizando ( .) uma operação máxima em caracteres e>. Como existe apenas um caractere não espacial em cada coluna, este será o resultado, pois o espaço possui um código ASCII menor que todos os caracteres não espaciais imprimíveis.

Desative a mudança e imprima o primeiro asterisco e (o, em seguida, mapeie todos os outros ( 2%) caracteres restantes para UDRusar a indexação modular.

Solução antiga (29 bytes)

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

qN/obtém linhas de entrada. ztranspõe essa matriz de caracteres. 2%cai todas as linhas ímpares. '*f#localiza o índice do asterisco em cada linha. 0+2ew);obtém todos os pares sucessivos de índices. ::-calcula suas diferenças, e "RDU"f=os mapeia para letras (via indexação modular: 0 → R, 2 → U, -2 ≡ 1 → D). O líder '*precede o asterisco.

Edição : Eu mudei 2ewpara 0+2ew);para contornar o CJam não manipular ew(fatias sucessivas) em listas que são muito curtas. Isso faz o código funcionar para a sequência de entrada *.

Experimente aqui ou assista em ação:

              

7
Isso é realmente incrível de assistir.
Jeel Shah

2
Concordo! +1 para o código, gostaria de poder +10 para o GIF.
ETHproductions

BTW, eu gosto do smiley no comprimento do código 17:-p
ETHproductions

1
Eu concordo, isso é incrível de assistir. *Porém, ele não funciona como entrada. Eu recebo um bom RuntimeExceptionlugar.
Helge von Koch

Ugh, considero que um bug do CJam: [X]2ewdeve retornar em []vez de errar. Vou adicionar uma solução alternativa, no entanto.
Lynn

4

Python 3, 129 108 98 86 bytes

Provavelmente, existem várias maneiras de jogar isso, mas eu gosto que tenha tudo em uma linha.

Editar: agora usando''.translate()

Edit: Com muitos agradecimentos a wnnmaw .

Editar: alterei o formato de entrada para uma matriz de seqüências de caracteres em vez de uma sequência separada por nova linha para salvar bytes. Além disso, na última edição, eu me misturei Ue R, então, corrigi isso.

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

A entrada deve ser uma matriz de seqüências de caracteres. Para o exemplo acima, isso se parece com:

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

Ungolfed:

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

Não quero dar uma nova resposta porque peguei muito emprestado da sua, mas tenho lambda s:'*'+"".join((('D','R')[j=='-'],'U')[j=='/']for l in zip(*s.split('\n'))for j in l if j in'\\/-')105 bytes. Principal diferença está usando uma tupla condicional em vez de traduzir
wnnmaw

Obrigado @wnnmaw! Eu acho que posso jogar isso ainda mais!
Sherlock9

Bom golfe no condicional na frente, que é super inteligente!
wnnmaw

Ah shucks. Obrigado pela dica @wnnmaw #
Sherlock9

3

Ruby, 87 bytes

Requer espaços à direita na entrada para que todas as linhas tenham o mesmo comprimento.

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

4
Certamente este é um código malicioso, pois contém >:D.
Alex A.

3

Japt, 38 bytes 40 41 45 46 48

Economizou 2 bytes graças a @ETHproductions

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

Se houvesse um comando trim, isso seria apenas 38 bytes; -; adicionará explicações quando eu terminar de jogar golfe. Não :Pé o programa que tenta ser engraçado, na verdade é o programa que ignora os caracteres que não são importantes.

Experimente online


Quando vi que havia um desafio praticamente exigindo uma transposição de matriz e que Doᴡɴɢᴏᴀᴛ havia respondido, eu sabia que tinha que ser japt.
ETHproductions

BTW, vou adicionar uma função de aparar em xe transpor e rotacionar funções em ye z(dividir em novas linhas, use a função de matriz, junte-se a novas linhas) #
214 ETHproductions

Você pode salvar dois bytes como este:Yu ?"RUD"g1+(XrS c -47 g):P
ETHproductions

@ETHproductions obrigado, menos de 40 bytes!
Downgoat

3

Haskell, 89 bytes

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

Exemplo de uso:

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

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

Transponha a entrada e substitua os caracteres // -/ \por strings singleton "U"/ "R"/ "D". Todos os outros caracteres são substituídos por cadeias vazias "", que desaparecem mais tarde concatenando tudo. Por fim, anexe o asterisco *.


2

Mathematica, 103 bytes

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

Muito curto, considerando que este é um desafio para o processamento de strings.


2

JavaScript (ES6) 90

Uma função anônima. Ele varre a string de entrada char por char, levando em conta a posição na linha atual. Fazendo isso, ele cria uma matriz de saída subsituting U D Rpara / \ -no lugar certo

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

Isso requer que a entrada seja retangular (o mesmo número de caracteres em cada linha). Por exemplo

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

Explicação

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.