¿Puede mi caja de música de 4 notas tocar esa canción?

51

Tengo una caja de música con manivela que puede tocar una serie de cuatro notas. Cuando giro la manivela, arranca una de las cuatro cuerdas, dependiendo de la posición de la manivela y la dirección de la vuelta. Cuando la manivela se gira hacia el norte, la caja (con sus cadenas numeradas del 1 al 4) se ve así:

1  |  2
   |
   O   

4     3

A partir de ahí, puedo girar la manivela en el sentido de las agujas del reloj para arrancar la cadena # 2 y apuntar la manivela hacia el este:

1     2

   O---   

4     3

Alternativamente, también podría haber girado la manivela en sentido antihorario desde el norte para tocar la cuerda # 1 y terminar con una manivela apuntando hacia el oeste:

1     2

---O   

4     3

En cualquier momento, la caja puede tocar una de dos notas: la siguiente nota disponible en el sentido de las agujas del reloj o la siguiente nota en el sentido contrario.

Desafío

Su desafío es escribir un programa o función que acepte una cadena no vacía de valores de nota (es decir, números a 1través 4) y determinar si es posible reproducir esa secuencia de notas en la caja de música. Produzca un resultado verdadero o falso para indicar la jugabilidad o no jugabilidad de la entrada.

Algunas notas:

  • La entrada no hace suposiciones sobre la posición inicial de inicio. Las entradas 214(comenzando en el este y moviéndose estrictamente en sentido antihorario) y 234(comenzando en el norte y moviéndose estrictamente en sentido horario) y ambas son válidas.

  • La manivela puede moverse libremente en cualquier dirección después de cada nota. Es posible una serie de la misma nota (por ejemplo, 33333) moviéndose hacia adelante y hacia atrás a través de una cadena. La serie 1221441es perfectamente jugable (comenzando hacia el oeste, moviéndose dos pasos en sentido horario, luego tres pasos en sentido antihorario, luego dos pasos en sentido horario).

Muestras

Algunos truecasos:

1
1234
1221
3333
143332
22234
2234
22214
1221441
41233

Algunos 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  
apsillers
fuente
¿Puede la entrada ser la cadena que incluye comillas?
Luis Mendo
@LuisMendo Claro, lo permitiré: estoy interesado en su algoritmo, no en hacer que salte a través de los aros para obtener la entrada. De todos modos, existe un consenso no oficial de la comunidad de que generalmente está bien: ¿ Entrada de cadena con o sin ""?
apsillers
1
No lo sabia. Gracias por el enlace!
Luis Mendo
1
@AJMansfield No, las soluciones deberían permitir arbitrariamente muchos ciclos. Por supuesto, si alguna entrada hace que su código exceda un límite en el intérprete de su idioma o en la memoria de su computadora, está bien (ya que está limitado simplemente por la cantidad de memoria que tenga físicamente o su intérprete lo permita), pero su solución no debería imponer limitaciones adicionales sobre qué tan lejos o cuántas veces se mueve la manivela.
apsillers
1
Este desafío ha ganado la categoría No tan simple como parece en Best of PPCG 2016. Desafortunadamente, no podemos dar recompensas por los desafíos, pero Zgarb ha escrito un desafío en su honor . ¡Felicidades!
Martin Ender

Respuestas:

9

Pyth, 30 27 bytes

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

Aquí está la idea:

 1.5  1  0.5

  2       0

 2.5  3  3.5

La manivela siempre está en una posición de medio entero c. En cada paso, lo reflejamos sobre una nota de posición entera nestableciendo c = 2*n-c. Si nes válido, ccambia en ± 1 mod 8. Si nno es válido, ccambia en ± 3 mod 8. Reducimos acumulativamente la entrada para recopilar todos los valores de c, y luego vemos si todas las notas fueron válidas. Hacemos esto para cada valor inicial de c, porque es más corto que marcar solo los adyacentes a la primera nota.

Formateado:

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

Banco de pruebas .

lirtosiast
fuente
18

CJam, 34 31 bytes

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

Hice esto en mi teléfono, así que tendré que dar una explicación más tarde. La salida no es vacía si es verdad.

Pruébalo en línea | Banco de pruebas

Explicación

El nuevo código cambia un poco el diseño:

2    3    4

1    .    5

0/8  7    6

Los números pares corresponden a posiciones de cuerda y los números impares corresponden a posiciones de manivela.

Esto es lo que pasa:

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

La pila se imprime automáticamente al final. Cualquier posición final posible estará en la salida, por ejemplo, para la entrada 1la salida es 31, lo que significa que la manivela puede terminar mirando hacia la izquierda o hacia arriba.

Si solo CJam tuviera filtro con parámetro extra ...


Editar: retroceder temporalmente mientras me convenzo de que este 29 bytes funciona:

8,q{~2*f{_@-_7b1#@@+8,=|}W-}/
Sp3000
fuente
37
Cada vez que alguien responde con un lenguaje difícil como cjam y dice "hice esto en mi teléfono", me muero un poco por dentro
Dennis van Gils
2
Probablemente quiso decir que el texto se envió usando un teléfono, pero se hizo en su cabeza.
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)

Esto se evalúa como una función anónima que toma una cadena y devuelve un valor booleano. Prueba de suite aquí.

Explicación

La idea es que la lambda de la derecha asigna un número aa [[a,a+1],[a+1,a]]los dos "movimientos" posibles que llevan la manivela a ese número, de acuerdo con el siguiente diagrama:

  1 (2) 2

(1/5)  (3)

  4 (4) 3

En la función principal anónima, primero hacemos mapM((...).read.pure), que convierte cada carácter en un entero, le aplica la lambda anterior y elige uno de los dos movimientos, devolviendo la lista de todas las secuencias de movimientos resultantes. Luego, verificamos si alguna de estas secuencias tiene la propiedad de que el segundo número de cada movimiento es igual al primer número del próximo módulo 4, lo que significa que es una secuencia físicamente posible. Para hacer esto, zipcada uno mueve la secuencia con su tail, verificamos la condición de alllos pares y vemos si la anysecuencia se evalúa True.

Zgarb
fuente
7

Retina, 50 bytes

A`13|31|24|42|(.)(?!\1)(.)(\2\2)*(\1|\2(?!\1|\2).)

Creo que esto funciona?

Pruébalo aquí.

jimmy23013
fuente
6

Retina , 127109 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))*$

Esto imprime 0o 1, en consecuencia.

Pruébalo en línea! (Esta es una versión ligeramente modificada que marca todas las coincidencias en la entrada en lugar de imprimir 0o 1).

Traté de encontrar un algoritmo elegante, pero mis primeros intentos no pudieron evitar el retroceso ... e implementar el retroceso es molesto ... así que utilicé un lenguaje que hace el retroceso para mí donde solo necesito codificar un solución válida Desafortunadamente, la codificación es bastante detallada y bastante redundante ... Estoy seguro de que esto se puede acortar.

Si bien trato de descubrir algo más ordenado, si alguien quiere resolver cómo funciona esto, aquí hay una versión algo más legible:

^
(
    (?<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)
)*
$

Y aquí hay una pista:

1  a  2

d  O  b

4  c  3
Martin Ender
fuente
6

MATL , 57 55 bytes

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

Utiliza la versión actual (10.2.1) , que es anterior a este desafío.

EDITAR (17 de enero de 2017): debido a cambios en el idioma,v debe ser reemplazado por &v, y tL3$)por Y)(además, se podrían hacer algunas otras mejoras ). El siguiente enlace incluye esas dos modificaciones.

Pruébalo en línea!

Explicación

Esto se basa en dos de mis herramientas favoritas para el golf de código: fuerza bruta y convolución .

El código define la ruta seguida por la manivela en términos de coordenadas 0.5, 1.5etc. Cada número indica la posición de la manivela entre las notas. El código primero crea una matriz de ruta con todas las rutas posibles que comienzan con la primera nota de la cadena de entrada. Cada ruta es una columna en esta matriz. Este es el componente de fuerza bruta .

A partir de esta matriz de ruta, se obtiene una matriz de notas , donde cada columna es una secuencia realizable de notas tocadas. Por ejemplo, el movimiento desde la posición 0.5hasta 1.5produce una nota 1. Esto consiste en tomar el promedio entre posiciones y luego aplicar una operación de módulo 4. El promedio de ejecución a lo largo de cada columna se realiza con una convolución 2D .

Finalmente, el programa verifica si alguna columna de la matriz de notas coincide con la 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
Luis Mendo
fuente
5

Pyth, 43

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

Banco de pruebas

Esto probablemente sea muy fácil de jugar, y tampoco es el algoritmo óptimo para jugar al golf (¿espero que enumerar todas las rutas sea más corto?) ... De todos modos, si encuentra algún error con el algoritmo, hágamelo saber, creo que debería funcionar, pero yo te has equivocado antes!

Explicaré mi algoritmo usando la entrada de ejemplo de 1221. Este programa asigna primero los dígitos en contra de sus sucesores, así: [[1,2],[2,2],[2,1]]. Luego se pone sus diferencias mod 4(Pyth obtiene el resultado que coincide con el signo del argumento de la derecha %, por lo que esto es siempre positivo): [3,0,1]. A continuación, los resultados se dividen en 0y han 2restado de cada uno de ellos: [[1],[-1]].

Ahora que la configuración está hecha, creamos una lista [-1,1,-1...]y su negación [1,-1,...], ambas de la misma longitud que la matriz resultante de antes. Luego, para cada una de estas listas, realice una sustracción entre los elementos de la lista y la lista generada en el paso anterior. Luego, si alguno de los resultados contiene solo listas vacías, daremos como resultado verdadero.

FryAmTheEggman
fuente
¿Qué quiere decir con "los resultados se dividen en 0"? En particular, ¿qué te pasa por 1221221e 1221441?
Neil
1
@Neil 1221221es falso y 1221441da verdadero en general, pero si entiendo que quieres el resultado después de ese paso en el algoritmo? Si ese es el caso, da: de [3, 0, 1, 3, 0, 1]a [[3], [1, 3], [1]]y [3, 0, 1, 1, 0, 3]a [[3], [1, 1], [3]]. Avísame si quieres que te expliquen algo más :)
FryAmTheEggman
Creo que estoy más confundido que antes, entonces, ¿podría terminar esos dos ejemplos para explicar cómo se logran los resultados (correctos)?
Neil
1
@Neil Claro, no hay problema :) A partir de ahí, hacemos la resta para obtener: [[1], [-1, 1], [-1]]y [[1], [-1, -1], [1]]desde aquí, puede ver que el primero no tiene listas que alternan entre sí -1y 1mientras que la otra lista tiene, dando el resultado final. El algoritmo es un poco obtuso, pero básicamente es un mapeo de cambios de 0dirección y dirección como +/-1, luego verifica que no se realicen saltos y que las direcciones tengan sentido.
FryAmTheEggman
Ah, entonces lo que me faltaba era que cada lista dividida debe consistir en el mismo valor, y esos valores deben alternar. ¡Gracias!
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

Una solución bastante perezosa, pero la más corta que pude encontrar. Creé una matriz especial: cuando codifica el estado del arrancador y la última cadena que se va a arrancar, devuelve un vector, que codifica la nueva posición del arrancador, y si el arranque anterior fue posible. Ahora solo recorremos todas las notas de las dos posibles posiciones de inicio y vemos si una de ellas resulta en una melodía jugable. Probablemente se pueda jugar mucho más al golf.

Fuente ampliada y 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
falla
fuente
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: Guardado 4 bytes gracias a @DigitalTrauma.

Esta es una reescritura completa ya que mi enfoque anterior fue defectuoso.

Comienzo reduciendo todas las corridas de dígitos a 1 o 2 dependiendo de si hubo un número par o impar en la corrida. Luego busco todas las combinaciones ilegales:

  • 13|24|31|42 (lados opuestos)
  • 3[24]{2}1como 3221y 3441son ilegales
  • de manera similar para 4xx2, 1xx3y 2xx4donde xestá cualquiera de los dígitos faltantes
  • (.).\1como cosas como 121son ilegales ( 111se ha reducido a 1antes)

Si no hay pares o "triples" ilegales, entonces toda la cadena es legal (la prueba por inducción se deja como ejercicio porque aquí es de noche).

Traté de simplificar 3[24]{2}1|1[24]{2}3usando una afirmación negativa anticipada, pero resultó ser más largo de esa manera.

Neil
fuente
f("1122") => true@DigitalTrauma
Conor O'Brien
@ CᴏɴᴏʀO'Bʀɪᴇɴ No veo nada de malo en eso. Por otro lado, me he dado cuenta de que f("1221221")la respuesta es incorrecta, así que tendré que repensar.
Neil
Siempre es bueno incluir un conjunto de pruebas, '43221' falla: jsbin.com/vafitotequ/1/edit?js,console
Pavlo
@Pavlo Vaya, que había Jugamos al golf [24][24]a (2|4)\1pero no había probado adecuadamente. Lo siento por eso.
Neil
¿Puede usted campo [24][24]a [24]{2}?
Trauma digital
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

Explicación

i%4 es la posición actual de la manivela:

    1 (i%4 == 1) 2   

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

    4 (i%4 == 3) 3   

Sangrado y 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

Prueba

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>

usuario81655
fuente
Bien hecho. ¿Podría explicar cómo |funciona en este caso?
Pavlo
1
@pavlo Gracias. Es una forma más corta de escribir (x.map(...),v). Funciona porque la matriz que los maprendimientos arroja a 0y 0|v == v.
user81655
2

Lua , 146 142 108 162 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

Devuelve verdadero o falso dada una cadena de números entre 1 y 4. (No maneja datos o números fuera de rango.

Simplemente realiza un seguimiento de cuál fue el último movimiento y verifica si este movimiento es una inversión del último movimiento (IE, 121 o 12221) o si el movimiento de la distancia es más que posible.

EDITAR 1 :

Guardado 6 bytes. Olvidé que if (int) thendevuelve verdadero si int no es cero.

Así:

if t~=0 then

cambios a:

if t then

También se guardaron algunos bytes por reestructuración.

EDITAR 2 :

Poco a poco me estoy dando cuenta de esto. He estado leyendo la documentación aquí: http://www.lua.org/pil/ Y una de las páginas más útiles para jugar golf es http://www.lua.org/pil/3.3.html

En particular, esto es muy útil:

Al igual que las estructuras de control, todos los operadores lógicos consideran falso y nulo como falso y todo lo demás como verdadero.

Lo que esto significa para mí es que puedo continuar y eliminar mi declaración de q ( que inicialmente se estableció en 0 ), ya que se considerará "falsa" hasta que se establezca. Así que guardo algunos bytes más a través de esto.

Otra cosa que vale la pena mencionar, aunque no la uso, es que si desea intercambiar valores en Lua, simplemente puede hacerlo a,b=b,a sin la necesidad de una variable temporal.

EDITAR 3

Entonces, a través de una reconstrucción inteligente, así como una nueva función, tengo la cuenta regresiva de bytes por 9 más.

El mejor modo para recibir entradas

Si necesita leer una lista de números y realizar operaciones de uno en uno, puede usar:

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

Cuando se compara con su alternativa usando string: sub, puede ver el valor para golf (o uso general):

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

Reestructurar funciones o cadenas

En segundo lugar, si tiene varias declaraciones en una línea y uno de los valores es una función o tiene una condición en la que compara un número con el resultado de una función como esta:

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

if math.abs(x)==2 then

reestructurándolo para que el paréntesis de cierre sea el último carácter en la condición o declaración, puede cortar un carácter como este:

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

Condiciones de devolución que equivalen a verdadero o falso en lugar de 'verdadero' o 'falso'

Encontré una forma semi divertida de reducir mi cuenta de bytes aún más. Si necesita devolver verdadero o falso, puede devolver una declaración que equivale a verdadero o falso que tiene menos caracteres que "verdadero" o "falso".

Por ejemplo, compare:

return true
return false

A:

return 2>1
return 1>2
Skyl3r
fuente
121debería dar como resultado falso.
lirtosiast
Ah no importa. Veo. Se solucionará en breve
Skyl3r
Es posible que le interese agregar algunos de esos consejos de Lua a Consejos para jugar golf en Lua si aún no los ve allí.
apsillers
2

MAT, 49 bytes (no competitivos 1 )

1. La respuesta (ab) utiliza la indexación menos estricta de las versiones más recientes de MATL, y no habría funcionado en el momento en que se publicó este desafío.

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

Pruébalo en línea! .

Vi este desafío en el Best of PPCG 2016 , y pensé que esto podría usar mi operador favorito :

d

O, diffen MATLAB / Octave (utilizaré libremente la terminología de MATLAB / Octave en mi explicación, ya que es más fácil de leer para los humanos). Este comando calcula la diferencia entre elementos en un vector o, en este caso, en una matriz de caracteres.

Para este problema, las diferencias exhiben un patrón interesante. Tenga en cuenta que

Un cambio de dirección debe significar que una nota se toca dos veces .

Para el patrón de diferencia (ignorando la 1-4transición por ahora), esto significa que

Un cambio en el inicio de sesión diff(input)debe tener un número impar de ceros en el medio. Por el contrario, el signo no puede cambiar después de un número par de ceros.


Implementé esto, para cada matriz, encontrando el primer cero. Recorto el cero y multiplico todos los elementos después -1. Para el resultado final, esto significa que todos los elementos deben tener el mismo signo. Por supuesto, está el pequeño problema de la -3igualación +1y el 2rechazo en general. Resolví esto tomando la unión de conjunto del resultado con [1 -3], y verificando si esto es de tamaño 2 (es decir, ningún elemento no permitido 'ingresó' al conjunto a través de la unión). Repita para [-1 3]y compruebe si cualquiera (o ambos, en el caso de una entrada de 1 longitud) es verdadero.

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. 
Sanchises
fuente
@LuisMendo Gracias. Realmente necesito leer M, la última vez que lo probé, funcionó de manera diferente de lo esperado, así que por el momento lo ignoré. ¿Es correcto decir que debe ser 3Mporque entonces recibo la entrada de no ), no :sino de q(omitir wya que no es una función normal )?
Sanchises
Sí exactamente. wse omite porque no es una función normal. Las funciones normales que no aceptan entradas también se omitirían
Luis Mendo
2

Python (3,5) 160 151 150 bytes

Una solución 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)])

Sin golfista sin 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 la caja en lugar de la manivela. La posición del cigüeñal está entre el primer y el segundo carácter de la cadena c. Necesito probar todas las posiciones iniciales de la manivela.

Truco para rotar la cuerda

La forma habitual de rotar una cadena en python ( s[i:]+s[:i]) también necesita repetir tanto el índice como la cadena. En este caso, duplico la cadena y recorto los primeros 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 prueba

[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]
Erwan
fuente
1
Puede eliminar el espacio en 3"[i:]) for.
Erik the Outgolfer
@EriktheOutgolfer gracias, lo elimino.
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 guardados por Neil! Versión original sin golf:

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
}

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

Pavlo
fuente
1
Le ahorré 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
Sin embargo, aún no es tan corto como la respuesta de @ 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

Pruébalo en línea!

Esto es básicamente un enfoque basado en el estado:

  • El estado inicial es 0.
  • a, b, c, Y dson "estados indecisos" que sólo se producen al comienzo
  • N, E, S, Y Wson los "estados" decidido, obviamente, de pie para NOrth, East, Sl sur, y West.
Monja permeable
fuente
1

Jue, 203 bytes

No puedo pensar en cómo jugar golf más lejos.

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<

Si la secuencia de notas es posible, dará salida a la dirección final, de lo contrario la salida estará vacía.

MegaTom
fuente
1

Prólogo (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 un predicado pque tiene éxito en entradas jugables (dadas como una lista de enteros) y falla en las que no se pueden reproducir. Pruébalo en línea!

Explicación

adefine una relación de adyacencia entre la nota Ny la posición del cigüeñal P. Definimos la posición p entre las notas p y p + 1 . Por lo tanto, una posición es adyacente a la nota Niff

  • es igual a N( P=N); o
  • la nota es 1 y la posición es 4 ( N=1,P=4); o
  • el caso anterior no es verdadero ( !) y la posición es igual a N-1( P is N-1).

mtoma una lista de notas e intenta generar una lista de posiciones que reproducirán esas notas. Aes la nota que se acaba de tocar, Bes la nota que se va a tocar; Xes la posición actual del cigüeñal, Yes la siguiente posición del cigüeñal. Un movimiento es válido si

  • la nota que se acaba de tocar es adyacente a la posición actual de la manivela ( a(A,X));
  • la nota que se va a tocar también está adyacente a la posición actual de la manivela ( a(B,X));
  • la nota que se va a tocar es adyacente a la siguiente posición de arranque ( a(B,Y)); y
  • las dos posiciones de manivela no son iguales ( X\=Y).

Si todo esto se cumple, recurse. Si llegamos a una nota ( m([_],_)), la secuencia de notas se puede reproducir.

Para esta pregunta, solo nos importa si existe una secuencia de movimientos, por lo que definimos pllamar my descartar la lista generada de posiciones de arranque.

Vea una versión sin golf y verifique todos los casos de prueba aquí .

DLosc
fuente