Minha caixa de música de 4 notas toca essa música?


51

Eu tenho uma caixa de música com manivela que pode tocar uma série de quatro notas. Quando eu giro a manivela, ela puxa uma das quatro cordas, dependendo da posição da manivela e da direção da curva. Quando a manivela é virada para o norte, a caixa (com suas cordas numeradas de 1 a 4) fica assim:

1  |  2
   |
   O   

4     3

A partir daí, eu posso girar a manivela no sentido horário para puxar a corda # 2 e apontar a manivela para o leste:

1     2

   O---   

4     3

Como alternativa, eu também poderia ter girado a manivela no sentido anti-horário do norte para tocar a corda nº 1 e terminar com uma manivela apontando para oeste:

1     2

---O   

4     3

A qualquer momento, a caixa pode tocar uma das duas notas: a próxima nota disponível no sentido horário ou a próxima nota no sentido anti-horário.

Desafio

Seu desafio é escrever um programa ou função que aceite uma seqüência de valores de notas não vazia (ou seja, números 1até 4) e determinar se é possível reproduzir essa sequência de notas na caixa de música. Produza um resultado verdadeiro ou falso para indicar a capacidade de reprodução ou não da entrada.

Algumas notas:

  • A entrada não faz suposições sobre a posição inicial inicial. As entradas 214(começando no leste e movendo-se estritamente no sentido anti-horário) e 234(começando no norte e movendo-se estritamente no sentido horário) e ambas válidas.

  • A manivela pode se mover livremente em qualquer direção após cada nota. Uma série da mesma nota é possível (por exemplo, 33333) movendo-se para frente e para trás através de uma corda. A série 1221441é perfeitamente reproduzível (começando no oeste, movendo-se duas etapas no sentido horário, depois três etapas no sentido anti-horário e depois duas etapas no sentido horário).

Amostras

Alguns truecasos:

1
1234
1221
3333
143332
22234
2234
22214
1221441
41233

Alguns falsecasos:

13     (note 3 is never available after note 1)
1224   (after `122`, the crank must be north, so 4 is not playable)
121    (after `12` the crank is east; 1 is not playable)
12221  (as above, after `1222` the crank is east)
43221  

A entrada pode ser a sequência incluindo aspas?
Luis Mendo 26/01

@LuisMendo Claro, vou permitir - estou interessado no seu algoritmo, não fazendo você pular os bastidores para obter a entrada. De qualquer forma, existe um consenso não oficial da comunidade de que geralmente está tudo bem: entrada de string com ou sem ""?
Apsillers

11
Eu não sabia disso. Obrigado pelo link!
Luis Mendo

11
@AJMansfield Não, as soluções devem permitir arbitrariamente muitos ciclos. Obviamente, se alguma entrada faz com que seu código exceda um limite no intérprete do seu idioma ou na memória do seu computador, tudo bem (já que é meramente limitado pela quantidade de memória que você possui fisicamente ou o seu intérprete permite), mas sua solução não deve impor limitações extras em quão longe ou quantas vezes a manivela se move.
Apsillers

11
Esse desafio ganhou a categoria Não é tão simples quanto parece no Best of PPCG 2016. Infelizmente, não podemos dar prêmios a desafios, mas o Zgarb escreveu um desafio em sua homenagem . Parabéns!
Martin Ender

Respostas:


9

Pitão, 30 27 bytes

f!-aVJ.u%-ysYN8zTtJ,1 7cR2T

Aqui está a ideia:

 1.5  1  0.5

  2       0

 2.5  3  3.5

A manivela está sempre em uma posição meio inteiro c. Em cada etapa, refletimos sobre uma nota de posição inteira n, definindo c = 2*n-c. Se nfor válido, caltera em ± 1 mod 8. Se nfor inválido, caltera em ± 3 mod 8. Reduzimos cumulativamente a entrada para coletar todos os valores de ce depois verificamos se todas as notas eram válidas. Fazemos isso para todos os valores iniciais de c, porque é mais curto do que verificar apenas os adjacentes à primeira nota.

Formatado:

f
  ! -
      aV J .u
              % -
                  y s Y
                  N
                8
              z
              T
         t J
      ,
        1 
        7
  cR2 T

Conjunto de teste .


18

CJam, 34 31 bytes

8,q{~2*f{_@-_zF8b&,@@+8,=*}0-}/

Fiz isso no meu telefone, então terei que apresentar uma explicação mais tarde. A saída não é vazia, se for verdade.

Experimente online | Suíte de teste

Explicação

O novo código muda um pouco o layout:

2    3    4

1    .    5

0/8  7    6

Os números pares correspondem às posições das cordas e os números ímpares correspondem às posições da manivela.

Aqui está o que acontece:

8,           Create the range [0 1 .. 7] of possible starting positions
             We can leave the string positions [0 2 4 6] in since it doesn't matter
q{ ... }/    For each character in the input...
  ~2*          Evaluate as integer and double, mapping "1234" -> [2 4 6 8]
  f{ ... }     Map over our possible current crank positions with the string
               position as an extra parameter
    _@-          Calculate (string - crank), giving some number in [-7 ... 7]
    _z           Duplicate and absolute value
    F8b          Push 15 base 8, or [1 7]
    &,           Setwise intersection and get length. If (string - crank) was in
                 [-7 -1 1 7] then the move was valid and this evaluates to 1, otherwise 0
    @@+          Calculate ((string - crank) + string)
    8,=          Take modulo 8, giving the new crank position. x%y in Java matches the
                 sign of x, so we need to do ,= (range + index) to get a number in [0 .. 7]
    *            Multiply the new crank position by our previous 0 or 1
  0-           Remove all 0s, which correspond to invalid positions

A pilha é impressa automaticamente no final. Quaisquer possíveis posições que terminam será na saída, por exemplo, para a entrada 1, a saída é 31, o que significa que a manivela pode extremidade virada quer para a esquerda ou para cima.

Se apenas CJam tivesse filtro com parâmetro extra ...


Edit: Reverter temporariamente enquanto eu me convencer de que este byte de 29 bytes funciona:

8,q{~2*f{_@-_7b1#@@+8,=|}W-}/

37
Toda vez que alguém responde com alguma linguagem difícil como cjam e diz que "fiz isso no meu telefone" eu morro um pouco dentro
Dennis van Gils

2
Ele provavelmente quis dizer que o texto foi produzido usando um telefone, mas foi feito em sua cabeça.
Nelson Nelson

7

Haskell, 93 88 87 bytes

any(all(\(a,b:c)->1>mod(a!!1-b)4).(zip=<<tail)).mapM((\a->[[a,a+1],[a+1,a]]).read.pure)

Isso avalia uma função anônima que pega uma string e retorna um booleano. Conjunto de teste aqui.

Explicação

A idéia é que o lambda à direita mapeie um número apara [[a,a+1],[a+1,a]], os dois possíveis "movimentos" que acionam a manivela sobre esse número, de acordo com o seguinte diagrama:

  1 (2) 2

(1/5)  (3)

  4 (4) 3

Na principal função anônima, primeiro fazemos mapM((...).read.pure), que converte cada caractere em um número inteiro, aplica o lambda acima a ele e escolhe um dos dois movimentos, retornando a lista de todas as seqüências de movimentos resultantes. Em seguida, verificamos se alguma dessas seqüências tem a propriedade de que o segundo número de cada movimento seja igual ao primeiro número do próximo módulo 4, o que significa que é uma sequência fisicamente possível. Para fazer isso, zipcada um de nós move a sequência com ela tail, verifica a condição alldos pares e verifica se a anysequência é avaliada como True.



6

Retina , 127 109 bytes

^((1|2)|(2|3)|(3|4)|(4|1))((?<2-5>1)|(?<5-2>1)|(?<3-2>2)|(?<2-3>2)|(?<4-3>3)|(?<3-4>3)|(?<5-4>4)|(?<4-5>4))*$

Isso imprime 0ou 1, consequentemente.

Experimente online! (Esta é uma versão ligeiramente modificada que marca todas as correspondências na entrada em vez de imprimir 0ou 1.)

Eu tentei criar um algoritmo elegante, mas minhas primeiras tentativas não foram capazes de contornar o retorno e a implementação do retorno é irritante ... então usei uma linguagem que faz o retorno para mim, onde eu só preciso codificar um solução válida. Infelizmente, a codificação é bastante detalhada e redundante ... Tenho certeza que isso pode ser reduzido.

Enquanto tento descobrir algo mais limpo, se alguém quiser entender como isso funciona, aqui está uma versão um pouco mais legível:

^
(
    (?<a>1|2)
  | (?<b>2|3)
  | (?<c>3|4)
  | (?<d>4|1)
)
(
    (?<a-d>1) | (?<d-a>1)
  | (?<b-a>2) | (?<a-b>2)
  | (?<c-b>3) | (?<b-c>3)
  | (?<d-c>4) | (?<c-d>4)
)*
$

E aqui está uma dica:

1  a  2

d  O  b

4  c  3

6

MATL , 57 55 bytes

1t_hjnZ^!t1tL3$)2_/wvG1)UGnl2$Ov+Ys.5tv3X53$Y+4X\G!U=Aa

Isso usa a versão atual (10.2.1) , que é anterior a esse desafio.

EDIT (17 de janeiro de 2017): devido a alterações no idioma,v precisa ser substituído por &ve tL3$)por Y)(além disso, algumas outras melhorias podem ser feitas). O link a seguir inclui essas duas modificações

Experimente online!

Explicação

Isso se baseia em duas das minhas ferramentas favoritas para o código de golfe: força bruta e convolução .

O código define o caminho seguido pela manivela em termos de coordenadas 0.5, 1.5etc. Cada número indica a posição da manivela entre as notas. O código primeiro cria uma matriz de caminhos com todos os caminhos possíveis que começam com a primeira nota da sequência de entrada. Cada caminho é uma coluna nessa matriz. Este é o componente de força bruta .

A partir dessa matriz de caminho, é obtida uma matriz de notas , onde cada coluna é uma sequência realizável de notas tocadas. Por exemplo, o movimento da posição 0.5para 1.5produz uma nota 1. Isso consiste em tomar a média entre as posições e depois aplicar uma operação do módulo 4. A média de execução ao longo de cada coluna é feita com uma convolução 2D .

Finalmente, o programa verifica se alguma coluna da matriz de notas coincide com a entrada.

1t_h        % row array [1, -1]
j           % input string
nZ^!        % Cartesian power of [1, -1] raised to N, where "N" is length of string
t           % duplicate
1tL3$)      % extract first row
2_/         % divide by -2
wv          % attach that modified row to the top of Cartesian power array
G1)U        % first character of input string converted to number, "x"
Gnl2$O      % column array of N-1 zeros, where N is length of input
v           % concat vertically into column array [x;0;0...;0]
+           % add with singleton expansion
Ys          % cumulative sum along each column. Each column if this array is a path
.5tv        % column array [.5;.5]
3X5         % predefined string 'same' (for convolution)
3$Y+        % 2D convolution of path array with [.5;.5]
4X\         % modified modulo operation. This gives note array with values 1,2,3,4
G!U         % column array of input string characters converted to numbers
=Aa         % true if any column of the note array equals this

5

Pyth, 43

Km-R2sMdc`M%R4-VJjQTtJ`0|Fm!s-VKdCm_B^_1dlK

Suíte de teste

Provavelmente isso é muito jogável, e também não é o algoritmo ideal para o golfe (espero que enumerar todos os caminhos seja mais curto?) ... De qualquer forma, se você encontrar algum erro no algoritmo, informe-me, acho que deve funcionar, mas já estive errado antes!

Vou explicar meu algoritmo usando a entrada de exemplo de 1221. Este primeiro programa mapeia os dígitos contra os seus sucessores, assim: [[1,2],[2,2],[2,1]]. Em seguida, ele recebe suas diferenças mod 4(Pyth obtém o resultado que coincide com o sinal do argumento direito de %, então isso é sempre positivo): [3,0,1]. Em seguida, os resultados estão divididos sobre 0e ter 2subtraído de cada um deles: [[1],[-1]].

Agora que a configuração está concluída, criamos uma lista [-1,1,-1...]e sua negação [1,-1,...], ambas do mesmo tamanho que a matriz resultante de antes. Em seguida, para cada uma dessas listas, execute a subtração definida entre os elementos da lista e a lista gerada na etapa anterior. Então, se um dos resultados contiver apenas listas vazias, produziremos true.


O que você quer dizer com "os resultados são divididos em 0"? Em particular, o que você obteria 1221221e 1221441?
Neil

11
@ Neil 1221221é falso e 1221441dá verdade geral, mas se eu entendo que você quer o resultado após essa etapa no algoritmo? Se for esse o caso, ele fornece: de [3, 0, 1, 3, 0, 1]para [[3], [1, 3], [1]]e [3, 0, 1, 1, 0, 3]para [[3], [1, 1], [3]]. Deixe-me saber se você quer algo mais explicou :)
FryAmTheEggman

Acho que estou mais confuso do que antes, então você poderia terminar esses dois exemplos para explicar como os resultados (corretos) são alcançados?
Neil

11
@ Neil Claro, não há problema :) A partir daí, fazemos a subtração para obter: [[1], [-1, 1], [-1]]e a [[1], [-1, -1], [1]]partir daqui, você pode ver que o primeiro não tem listas que alternam entre -1e 1enquanto a outra lista, dando o resultado final. O algoritmo é um pouco obtuso, mas basicamente é o mapeamento das mudanças de direção para 0e direção de +/-1, em seguida, verificando se nenhum salto é feito e as direções fazem sentido.
FryAmTheEggman

Ah, então o que estava faltando era que cada lista dividida deve consistir no mesmo valor e esses valores devem ser alternados. Obrigado!
Neil

4

Matlab, 279 180 bytes

o=eye(4);a=input('')-'0';M=[o,o(:,[4,1:3]);o(:,[2:4,1:4,1])];x=2;for p=[a(1),mod(a(1),4)+1];for k=a;i=find(M*[o(:,k);o(:,p)]>1);if i;p=mod(i-1,4)+1;else;x=x-1;break;end;end;end;x>0

Uma solução bastante preguiçosa, mas a mais curta que consegui encontrar. Criei uma matriz especial: quando você codifica o estado do arrancador e a última string a ser arrancada, ele retorna um vetor, que codifica a nova posição do arrancador e se a arrancada anterior era possível. Agora, passamos por todas as notas das duas possíveis posições iniciais e vemos se uma delas resulta em uma melodia tocável. Provavelmente pode ser jogado muito mais.

Fonte expandida e explicada:

o=eye(4);
a=input('')-'0';

% encoding of plucker/notes
%      1
%   1     2
%4           2
%   4     3
%      3
%

M=[...
%12 3 4 1 2 3 4 <
1,0,0,0,0,1,0,0; %1  k = current note
0,1,0,0,0,0,1,0; %2  
0,0,1,0,0,0,0,1; %3  
0,0,0,1,1,0,0,0; %4  
0,0,0,1,0,0,0,1; %1  p = current position of plucker
1,0,0,0,1,0,0,0; %2
0,1,0,0,0,1,0,0; %3
0,0,1,0,0,0,1,0];%4
% the vector we multiply with this matrix has following structure,
% the k-th and the p+4 th entries are 1, the rest 0
% when we multiply this vecotr with this matrix, we get a vector with an
% entry of value 2 IF this is a valid move ( mod(positionOfThe2 -1,4)+1 is
% the position of the plucker now)
% or only entries less than 2 it is impossible
x=2;  %number of "chances" to get it right
for p=[a(1),mod(a(1),4)+1] %check both starting values;
    for k=a;                %loop throu the notes
        size(M);

        c = M * [o(:,k);o(:,p)];
        i=find(c>1);               %did we find a 2?
        if i;
           p=mod(i-1,4)+1;         %if yes, valid move
        else;
            x=x-1;                 %if no, invalid, 
            break;
        end 
    end
end
x=x>0 %if we failed more than once, it is not possible

4

ES6, 104 100 bytes

s=>!/13|24|31|42|3[24]{2}1|4[13]{2}2|1[24]{2}3|2[13]{2}4|(.).\1/.test(s.replace(/(.)(\1\1)+/g,"$1"))

Editar: salvou 4 bytes graças a @DigitalTrauma.

Esta é uma reescrita completa, pois minha abordagem anterior foi falha.

Começo reduzindo todas as execuções de dígitos para 1 ou 2, dependendo da existência de um número ímpar ou par na execução. Em seguida, procuro todas as combinações ilegais:

  • 13|24|31|42 (lados opostos)
  • 3[24]{2}1como 3221e 3441são ilegais
  • semelhante para 4xx2, 1xx3e 2xx4onde xé um dos dígitos ausentes
  • (.).\1como coisas 121ilegais ( 111foi reduzida para 1mais cedo)

Se não houver pares ou "triplos" ilegais, toda a cadeia é legal (a prova por indução é deixada como exercício, porque aqui é tarde da noite).

Tentei simplificar 3[24]{2}1|1[24]{2}3usando uma afirmação negativa, mas acabou sendo mais longa.


f("1122") => true@DigitalTrauma
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ Não vejo nada de errado nisso. Por outro lado, percebi que f("1221221")gera a resposta errada, então terei que repensar.
Neil

É sempre agradável para incluir um conjunto de testes, '43221' falha: jsbin.com/vafitotequ/1/edit?js,console
Pavlo

@Pavlo Whoops, eu golfed [24][24]para (2|4)\1mas eu não tinha testado adequadamente. Me desculpe por isso.
Neil

Pode você golf [24][24]para [24]{2}?
Digital Trauma

2

JavaScript (ES6), 80 bytes

s=>[r=0,1,2,3].map(i=>[...s].map(n=>n-1-i%4?n%4-i%4?v=0:i+=3:i++,v=1)|v?r=1:0)|r

Explicação

i%4 é a posição atual da manivela:

    1 (i%4 == 1) 2   

(i%4 == 0) (i%4 == 2)

    4 (i%4 == 3) 3   

Recuado e Comentado

s=>
  [r=0,1,2,3].map(i=> // i = crank position, test for i starting at 0 to 3, r = result
    [...s].map(n=>    // for each note n
      n-1-i%4?        // if n is not at the position after i
        n%4-i%4?      // if n is not at the position before i
          v=0         // set the result of this test to invalid
        :i+=3         // else i-- (+3 used because i%4 would break for negative values)
      :i++,           // else i++
      v=1             // v = result of test, initialise to 1 (valid)
    )
    |v?r=1:0          // if the test returned true, set the result to true
  )
  |r                  // return the result

Teste

var solution = s=>[r=0,1,2,3].map(i=>[...s].map(n=>n-1-i%4?n%4-i%4?v=0:i+=3:i++,v=1)|v?r=1:0)|r
<input type="text" value="1221441" oninput="result.textContent=solution(this.value)" />
<pre id="result"></pre>


Bem feito. Você explicaria como |funciona neste caso?
Pavlo 03/02

11
@pavlo Obrigado. É uma maneira mais curta de escrever (x.map(...),v). Funciona porque a matriz para a qual os mapretornos são convertidos 0e 0|v == v.
User81655

2

Lua , 146 142 108 162 159 149 144 135 132 118 113 bytes

z,q,s=0,0,io.read()for i in s:gmatch'.'do t=i-z if 2==math.abs(t)or t==q then return''end q=-t z=i end return 2>1

Retorna verdadeiro ou falso, considerando uma sequência de números entre 1 e 4. (Não processa dados ou números fora do intervalo.

Simplesmente rastreia qual foi o último movimento e verifica se esse movimento é uma reversão do último movimento (IE, 121 ou 12221) ou se a distância em movimento é maior do que possível.

EDIT 1 :

Salvo 6 bytes. Esqueci que if (int) thenretorna true se int for diferente de zero.

Portanto:

if t~=0 then

muda para:

if t then

Também salvou alguns bytes reestruturando.

EDIT 2 :

Estou lentamente descobrindo isso. Estive lendo a documentação aqui: http://www.lua.org/pil/ E uma das páginas mais úteis para o golfe é http://www.lua.org/pil/3.3.html

Em particular, isso é muito útil:

Como estruturas de controle, todos os operadores lógicos consideram falso e nulo como falso e qualquer outra coisa como verdadeiro.

O que isso significa para mim é que posso prosseguir e remover minha declaração para q ( que foi inicialmente definida como 0 ), pois ela será considerada "falsa" até ser definida. Então, guardo mais alguns bytes com isso.

Outra coisa que vale a pena mencionar, embora eu não a use, é que se você deseja trocar valores em Lua, você pode simplesmente fazer isso a,b=b,a sem a necessidade de uma variável temporária.

EDIT 3

Então, através de alguma reconstrução inteligente e de uma nova função, eu tenho a contagem de bytes em mais 9.

Melhor modo para receber entrada

Se você precisar ler uma lista de números e executar operações neles, um de cada vez, poderá usar:

for x in string:gmatch('.') do
    print(x) --This is our number
end

Quando comparado à sua alternativa usando string: sub, você pode ver o valor do golfe (ou uso geral):

for x=1,string:len() do
    print(string:sub(x,x)) --This is our number
end

Reestruturar funções ou seqüências de caracteres

Segunda coisa, se você possui várias declarações em uma linha e um dos valores é uma função ou se possui uma condição na qual você compara um número ao resultado de uma função como esta:

x,y,z=io.read(),0,0 print('test')

if math.abs(x)==2 then

reestruturando-o para que os parênteses de fechamento sejam o último caractere na condição ou declaração, você pode cortar um caractere assim:

y,z,x=0,0,io.read()print('test') --Notice no space

if 2==math.abs(x)then --If we put the '2' first in the conditional statement, we can now remove a space character

Retornar condições que são iguais a Verdadeiro ou Falso em vez de 'Verdadeiro' ou 'Falso'

Encontrei uma maneira meio divertida de reduzir ainda mais minha contagem de bytes. Se você precisar retornar verdadeiro ou falso, poderá retornar uma declaração que seja igual a verdadeiro ou falso que tenha menos caracteres que "verdadeiro" ou "falso".

Por exemplo, compare:

return true
return false

Para:

return 2>1
return 1>2

121deve gerar false.
precisa saber é o seguinte

Ah deixa pra lá. Eu vejo. Será corrigido em breve
Skyl3r 26/01

Você pode estar interessado em adicionar algumas dessas dicas de Lua às Dicas de golfe em Lua, se ainda não as encontrar listadas.
Apsillers

2

MATL, 49 bytes (não concorrentes 1 )

1. A resposta (ab) usa a indexação menos rigorosa das versões mais recentes do MATL e não teria funcionado no momento em que esse desafio foi lançado.

dt~aX`tt~f1)q:)w3MQJh)_ht~a]tT-3hX|n2=wT_3hX|n2=+

Experimente online! .

Eu vi esse desafio no Best of PPCG 2016 e percebi que isso poderia usar meu operador favorito :

d

Ou, diffno MATLAB / Octave (usarei livremente a terminologia MATLAB / Octave na minha explicação, pois é mais fácil ler para humanos). Este comando calcula a diferença entre elementos em um vetor ou, nesse caso, em uma matriz de caracteres.

Para esse problema, as diferenças exibem um padrão interessante. Observe que

Uma mudança de direção deve significar que uma nota é tocada duas vezes .

Para o padrão de diferença (ignorando a 1-4transição por enquanto), isso significa que

Uma alteração na entrada diff(input)deve ter um número ímpar de zeros no meio. Por outro lado, o sinal não pode mudar após um número par de zeros.


Eu implementei isso, para cada matriz, encontrando o primeiro zero. Eu aparei o zero e multipliquei todos os elementos depois dele -1. Para o resultado final, isso significa que todos os elementos devem ter o mesmo sinal. Obviamente, há a pequena questão da -3igualdade +1e 2não é permitida em geral. Resolvi isso tomando a união do conjunto com o resultado [1 -3]e verificando se o tamanho é 2 (ou seja, nenhum elemento não permitido 'entrou' no conjunto por meio da união). Repita para [-1 3]e verifique se um (ou ambos, no caso de uma entrada de 1 comprimento) é verdadeiro.

d                                % Difference of input
 t~a                             % Check if any element equals 0
    X`                     t~a]  % Start while loop, ending in the same check
       t~                           % Get a new vector, logical negated to find zeroes.
          f1)                       % Find the position of the first zero. 
      t         q:)                 % Decrement by 1, to index all elements before that zero.
                   w3MQJh)          % Push the result of 'find', but increment to get all elements after.
                         _h         % Multiply the second half by -1, and concatenate horizontally.

  T-3hX|n2=                      % Check if set union with [1 -3] is size 2
 t        wT_3hX|n2=             % Check if set union with [-1 3] is size 2
                    +            % Logical OR. 

@LuisMendo Thanks. Eu realmente preciso ler M, da última vez que tentei, funcionou de maneira diferente do esperado, então eu o ignorei por enquanto. É correto dizer que precisa ser 3Mporque, então, recebo a entrada de não ), não :mas de q(pulando wcomo não é uma função normal )?
Sanchises

Sim, exatamente. wé ignorado porque não é uma função normal. As funções normais que não aceitam entradas também seriam ignoradas
Luis Mendo

2

Python (3.5) 160 151 150 bytes

Uma solução recursiva

def f(s):g=lambda s,c:s==''or g(s[1:],(c[:4]*2)[(s[0]==c[0])*2+1:])if s==''or s[0]in c[:2]else 0;return any([g(s,"1234123"[i:])for i in range(4)])

Ungolfed sem lambda

def f(s):
    def g(s,c):
        if s=='' or s[0] in c[:2] :
            return s=='' or g(s[1:],(c[:4]*2)[(s[0]==c[0])*2+1:])
        else:
            return False
    return any([g(s,"1234123"[i:]) for i in range(4)])

Giro toda a caixa em vez da manivela. A posição da manivela está entre o primeiro e o segundo caracteres da cadeia c. Preciso testar todas as posições iniciais da manivela.

Truque usar para girar a corda

A maneira usual de rotacionar uma string em python ( s[i:]+s[:i]) também precisa repetir o índice e a string. Nesse caso, duplico a string e recorte os primeiros caracteres.

(c*2)                        # duplicate the string
     [(s[0]==c[0])*2+1       # test that return 1 if firsts characters match 3 instead 
                      :]     
                        [:4] # crop again to have a 4 characters string

Casos de teste

[f(i) for i in ["1", "1234", "1221", "3333", "143332", "22234", "2234", "22214", "1221441", "41233", "13", "1224", "121", "12221", "43221"]]
[True, True, True, True, True, True, True, True, True, True, False, False, False, False, False]

11
Você pode remover o espaço em 3"[i:]) for.
Erik the Outgolfer

@EriktheOutgolfer obrigado por removê-lo.
Erwan


1

JavaScript (ES2015), 110 95

p=(s,d)=>(h=s[0],t=s.slice(1),g=t[0],!g||(d?g==h?p(t,-d):g%4==(h-d)%4&&p(t,d):p(s,1)||p(s,-1)))

15 bytes salvos por Neil! Versão original não destruída:

p = (s, d) => {
  h = s[0]
  t = s.substr(1)

  if (!t[0]) return true
  if (!d) return p(s, 1) || p(s, -1)
  if (t[0] == h) return p(t, d*-1)
  if (t[0] == (h-d > 4 ? 1 : h-d || 4)) return p(t, d)

  return false
}

Testes: https://jsbin.com/cuqicajuko/1/edit?js,console


11
Você economizou 17 bytes:(s,d)=>(h=s[0],t=s.slice(1),g=t[0],!g||(d?g==h?p(t,-d):g%4==(h-d)%4&&p(t,d):p(s,1)||p(s,-1)))
Neil

Ainda não é tão curto quanto a resposta do @ user81655.
Neil

1

Código de máquina de Turing, 395 bytes

0 1 _ r a
0 2 _ r b
0 3 _ r c
0 4 _ r d
a 1 _ r a
a 2 _ r E
a 3 _ r h
a 4 _ r S
b 1 _ r W
b 2 _ r b
b 3 _ r S
b 4 _ r h
c 1 _ r h
c 2 _ r N
c 3 _ r c
c 4 _ r W
d 1 _ r N
d 2 _ r h
d 3 _ r E
d 4 _ r d
N 1 _ r W
N 2 _ r E
N _ _ r r
N * _ r h
E 2 _ r N
E 3 _ r S
E _ _ r r
E * _ r h
S 3 _ r E
S 4 _ r W
S _ _ r r
S * _ r h
W 4 _ r S
W 1 _ r N
W _ _ r r
W * _ r h
h _ 0 r halt
h * _ r h
r _ 1 r halt

Experimente online!

Esta é basicamente uma abordagem baseada em estado:

  • O estado inicial é 0.
  • a, b, c, E dsão "estados indecisos" que ocorrem apenas no início
  • N, E, S, E Wsão os "estados decidiram", obviamente, de pé para NOrth, East, South, e West.

1

Terça, 203 bytes

Não consigo pensar em como jogar golfe tão longe.

0::=:::
>11::=>1
>22::=>2
>33::=>3
>44::=>4
>12::=b
>21::=d
>14::=c
>41::=a
>23::=c
>32::=a
>34::=d
>43::=b
a1::=d
a2::=b
b2::=a
b3::=c
c3::=b
c4::=d
d4::=c
d1::=a
a<::=~n
b<::=~e
c<::=~s
d<::=~w
::=
>0<

Se a sequência de notas for possível, a saída será finalizada; caso contrário, a saída estará vazia.


1

Prolog (SWI) , 117 bytes

a(N,P):-P=N;N=1,P=4,!;P is N-1.
m([A,B|C],[X,Y|Z]):-a(A,X),a(B,X),a(B,Y),X\=Y,m([B|C],[Y|Z]).
m([_],_).
p(N):-m(N,_).

Define um predicado pque obtém êxito nas entradas reproduzíveis (fornecidas como uma lista de números inteiros) e falha nas que não são reproduzíveis. Experimente online!

Explicação

adefine uma relação de adjacência entre a nota Ne a posição da manivela P. Nós definimos posição p para ser entre notas p e p + 1 . Assim, uma posição é adjacente à nota Nse

  • é igual a N( P=N); ou
  • a nota é 1 e a posição é 4 ( N=1,P=4); ou
  • o caso acima não é verdadeiro ( !) e a posição é igual a N-1( P is N-1).

mpega uma lista de notas e tenta gerar uma lista de posições que tocarão essas notas. Aé a nota que acabou de ser tocada, Bé a nota a ser tocada; Xé a posição atual da manivela, Yé a próxima posição da manivela. Um movimento é válido se

  • a nota tocada é adjacente à posição atual da manivela ( a(A,X));
  • a nota a ser tocada também é adjacente à posição atual da manivela ( a(B,X));
  • a nota a ser tocada é adjacente à próxima posição da manivela ( a(B,Y)); e
  • as duas posições da manivela não são iguais ( X\=Y).

Se tudo isso acontecer, recorra. Se conseguirmos chegar a qualquer nota ( m([_],_)), a sequência de notas é reproduzível.

Para esta pergunta, apenas nos importamos se existe uma sequência de movimentos, por isso, definimos pchamar me descartar a lista gerada de posições de manivela.

Veja uma versão não destruída e verifique todos os casos de teste aqui .

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.