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 1
travé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) y234
(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 serie1221441
es 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 true
casos:
1
1234
1221
3333
143332
22234
2234
22214
1221441
41233
Algunos false
casos:
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
fuente
Respuestas:
Pyth,
3027 bytesAquí está la idea:
La manivela siempre está en una posición de medio entero
c
. En cada paso, lo reflejamos sobre una nota de posición enteran
estableciendoc = 2*n-c
. Sin
es válido,c
cambia en ± 1 mod 8. Sin
no es válido,c
cambia en ± 3 mod 8. Reducimos acumulativamente la entrada para recopilar todos los valores dec
, y luego vemos si todas las notas fueron válidas. Hacemos esto para cada valor inicial dec
, porque es más corto que marcar solo los adyacentes a la primera nota.Formateado:
Banco de pruebas .
fuente
CJam,
3431 bytesHice 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:
Los números pares corresponden a posiciones de cuerda y los números impares corresponden a posiciones de manivela.
Esto es lo que pasa:
La pila se imprime automáticamente al final. Cualquier posición final posible estará en la salida, por ejemplo, para la entrada
1
la salida es31
, 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:
fuente
Haskell,
93 8887 bytesEsto 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
a
a[[a,a+1],[a+1,a]]
los dos "movimientos" posibles que llevan la manivela a ese número, de acuerdo con el siguiente diagrama: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,zip
cada uno mueve la secuencia con sutail
, verificamos la condición deall
los pares y vemos si laany
secuencia se evalúaTrue
.fuente
Retina, 50 bytes
Creo que esto funciona?
Pruébalo aquí.
fuente
Retina ,
127109bytesEsto imprime
0
o1
, 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
0
o1
).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:
Y aquí hay una pista:
fuente
MATL ,
5755 bytesUtiliza 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
, ytL3$)
porY)
(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.5
etc. 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.5
hasta1.5
produce una nota1
. 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.
fuente
Pyth, 43
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 mod4
(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 en0
y han2
restado 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.fuente
1221221
e1221441
?1221221
es falso y1221441
da 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 :)[[1], [-1, 1], [-1]]
y[[1], [-1, -1], [1]]
desde aquí, puede ver que el primero no tiene listas que alternan entre sí-1
y1
mientras que la otra lista tiene, dando el resultado final. El algoritmo es un poco obtuso, pero básicamente es un mapeo de cambios de0
dirección y dirección como+/-1
, luego verifica que no se realicen saltos y que las direcciones tengan sentido.Matlab,
279180 bytesUna 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:
fuente
ES6,
104100 bytesEditar: 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}1
como3221
y3441
son ilegales4xx2
,1xx3
y2xx4
dondex
está cualquiera de los dígitos faltantes(.).\1
como cosas como121
son ilegales (111
se ha reducido a1
antes)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}3
usando una afirmación negativa anticipada, pero resultó ser más largo de esa manera.fuente
f("1122") => true
@DigitalTraumaf("1221221")
la respuesta es incorrecta, así que tendré que repensar.[24][24]
a(2|4)\1
pero no había probado adecuadamente. Lo siento por eso.[24][24]
a[24]{2}
?JavaScript (ES6), 80 bytes
Explicación
i%4
es la posición actual de la manivela:Sangrado y comentado
Prueba
fuente
|
funciona en este caso?(x.map(...),v)
. Funciona porque la matriz que losmap
rendimientos arroja a0
y0|v == v
.Lua ,
146 142 108 162 162 159 149 144 135 132 118113 bytesDevuelve 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) then
devuelve verdadero si int no es cero.Así:
cambios a:
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:
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:
Cuando se compara con su alternativa usando string: sub, puede ver el valor para golf (o uso general):
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:
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:
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:
A:
fuente
121
debería dar como resultado falso.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.
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 :
O,
diff
en 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
Para el patrón de diferencia (ignorando la
1-4
transición por ahora), esto significa queImplementé 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-3
igualación+1
y el2
rechazo 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.fuente
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 ser3M
porque entonces recibo la entrada de no)
, no:
sino deq
(omitirw
ya que no es una función normal )?w
se omite porque no es una función normal. Las funciones normales que no aceptan entradas también se omitiríanPython (3,5)
160151150 bytesUna solución recursiva
Sin golfista sin lambda
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.Casos de prueba
fuente
3"[i:]) for
.Python 2 , 65 bytes
Pruébalo en línea!
fuente
JavaScript (ES2015),
1109515 bytes guardados por Neil! Versión original sin golf:
Pruebas: https://jsbin.com/cuqicajuko/1/edit?js,console
fuente
(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)))
Código de máquina de Turing, 395 bytes
Pruébalo en línea!
Esto es básicamente un enfoque basado en el estado:
a
,b
,c
, Yd
son "estados indecisos" que sólo se producen al comienzoN
,E
,S
, YW
son los "estados" decidido, obviamente, de pie paraN
Orth,E
ast,S
l sur, yW
est.fuente
Jue, 203 bytes
No puedo pensar en cómo jugar golf más lejos.
Si la secuencia de notas es posible, dará salida a la dirección final, de lo contrario la salida estará vacía.
fuente
Prólogo (SWI) , 117 bytes
Define un predicado
p
que 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
a
define una relación de adyacencia entre la notaN
y la posición del cigüeñalP
. Definimos la posición p entre las notas p y p + 1 . Por lo tanto, una posición es adyacente a la notaN
iffN
(P=N
); oN=1,P=4
); o!
) y la posición es igual aN-1
(P is N-1
).m
toma una lista de notas e intenta generar una lista de posiciones que reproducirán esas notas.A
es la nota que se acaba de tocar,B
es la nota que se va a tocar;X
es la posición actual del cigüeñal,Y
es la siguiente posición del cigüeñal. Un movimiento es válido sia(A,X)
);a(B,X)
);a(B,Y)
); yX\=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
p
llamarm
y descartar la lista generada de posiciones de arranque.Vea una versión sin golf y verifique todos los casos de prueba aquí .
fuente