El otro día, nuestro equipo fue a una sala de escape. Uno de los acertijos involucraba una placa de seis interruptores mecánicos donde tenía que encontrar la combinación correcta de encendido y apagado para desbloquear una caja, algo así:
-v-v-v-
-v-v-v-
Como desarrolladores, decidimos que sería más eficiente probar cada una de las combinaciones 2 ^ 6 = 64 que resolver el rompecabezas. Entonces le asignamos a un pobre tipo que haga un recuento binario:
-v-v-v-
-v-v-v-
-v-v-v-
-v-v-^-
-v-v-v-
-v-^-v-
-v-v-v-
-v-^-^-
y así.
El desafío
Escriba un programa que, dado que todos los interruptores están en la posición de apagado como una cadena con el formato anterior, genera todas las combinaciones de encendido y apagado en cualquier orden.
Puede escribir un programa completo o una función. Por lo tanto, su programa puede recibir la entrada a través de stdin, un archivo o como un argumento de cadena única, y puede devolver o imprimir la salida. Si se devuelve, la salida puede estar en una lista / matriz / etc. en lugar de una sola cadena. Si la salida es una sola cadena, los tableros deben estar separados por nuevas líneas (se permiten nuevas líneas finales).
Las cadenas de entrada coincidirán con la expresión regular r'((-v)+-)(\n(-v)+-)*'
y representarán una placa con todos los interruptores apagados. Esto significa que no hay mayúsculas y cero, y los interruptores están alineados a la izquierda. Es posible que cada fila no tenga el mismo número de interruptores.
Cada placa de salida debe tener exactamente el mismo formato que la entrada, excepto que las v se pueden reemplazar por ^ 's según sea necesario. Las placas de salida se pueden separar por cualquier número de nuevas líneas.
Dado que el tiempo de ejecución es naturalmente O (2 ^ n) en la cantidad de interruptores, su código no se probará en más de 10 interruptores en ninguna disposición.
Este es el código de golf, por lo que gana el código más corto en número de bytes.
Muestra de entradas y salidas
Entrada:
-v-
Salida posible:
-v-
-^-
Entrada:
-v-
-v-
Salida posible:
-^-
-^-
-^-
-v-
-v-
-^-
-v-
-v-
Dado que es extremadamente tedioso verificar su respuesta para un mayor número de interruptores, aquí hay un script de Python como una herramienta de verificación de cordura. (He incluido un fragmento actualmente comentado para generar la salida esperada de un archivo de entrada dado en caso de que desee más casos de prueba). Desafortunadamente, es un poco menos flexible en términos de entrada y salida que la especificación; coloque la cadena de entrada en un archivo llamado 'input' y la salida separada por la nueva línea (lo siento, sin formato de lista) en un archivo llamado 'output' en el mismo directorio y ejecútelo python3 sanitycheck.py
.
fuente
Respuestas:
Haskell ,
25242317 bytesPruébalo en línea!
-1 byte gracias a @ H.PWiz
-1 byte gracias a @nimi
Devuelve una lista de cadenas. El TIO tiene 2 bytes adicionales para la declaración de función: he visto a otras personas dejarlo cuando escriben la función sin puntos, así que estoy haciendo lo mismo a menos que se indique lo contrario.
Respuesta anterior (25 bytes)
Las explicaciones son todas para la respuesta anterior, que funciona más o menos de la misma manera, excepto que subrayé la definición de
g
. La manerag
funciona ahora es mediante el uso de comparación léxica de sustituir^v
porv
y mantener todo lo demás igual.Curiosamente, esto funciona para cuadros de distribución arbitrarios:
Explicación (corta)
Explicación (larga)
mapM
es una función bastante aterradora para aquellos que no están familiarizados con Haskell. Pero no es difícil de entender en este contexto. Al hacerlo actuar enString
s (que en Haskell son listas de caracteres), lo he especializado en su definición de listas. Entonces, en este contexto, su firma de tipo esEn realidad, es aún más especializado en mi uso,
a
yb
son ambosChar
, por lo que podemos ver la firma de tipo comoVeamos rápidamente qué
g
hace antes de explicar cómomapM
funciona.g
utiliza la coincidencia de patrones para convertir elChar 'v'
en la cadena"v^"
; todo lo demás se convierte en una cadena singleton (recuerde, las cadenas son solo listas deChar
s, por lo que podemos ponerlasx
en una lista singleton). Al probar REPL, encontramos que este es el casoTenga en cuenta que
g
tiene el tipo correcto para ser un argumento demapM
(¡como era de esperar!).Exploraremos cómo
mapM
funciona dándoleg
y el argumentocomo entrada
mapM
primeros mapasg
sobreString
, y porqueg
convierteChar
s enStrings
, esto nos da una lista deStrings
Si bien este es el tipo de salida correcto,
mapM
hace un poco más. Puede pensar que forma todos los correosString
electrónicos que podría crear a partir de esta lista si tuviera que elegir un solo carácter de cada unoString
en ella (en orden).Entonces, para el primer elemento, no tiene otra opción que elegir el
Char '-'
. Para el segundo elemento, puede elegir entre'v'
y'^'
, y así sucesivamente.Es más o menos equivalente a este código de Python:
Excepto que, dado que Haskell se separa entre
Char
syString
s, cuando coloca lasChar
s en una lista, no las necesitajoin
.Entonces el resultado final es
como se desee.
fuente
mapM
funcionó para este desafío, al principio lo formulé comosequence . map g
pero eso se puede expresar de manera compactamapM id . map g
y luego vi que podía simplementemapM g
=='v'
por>'-'
Perl 6 , 32 bytes
Pruébalo en línea!
.comb
divide la cadena en caracteres.».&{...}
asigna los caracteres de acuerdo con la función entre llaves.$_, ('^' if /v/)
produce una lista de alternativas para cada personaje. Sólov
tiene una alternativa:^
.[X~]
reduce esa lista con el operador de productos cruzados de concatenación de cadenasX~
.fuente
Jalea , 7 bytes
Pruébalo en línea!
La salida es una lista de cadenas Jelly.
Explicación:
fuente
Perl 5 , 29 bytes
Pruébalo en línea!
Mi primera sumisión!
Normalmente, los golfistas de Perl 5 envían programas en lugar de funciones para evitar tener que incluir
sub{}
como mínimo. Pero tienen que añadirsay
,say␠
,say for
osay for␠
a cambio.Al ir al enfoque secundario, podría acortar
a
La explicación es bastante simple. Perl 5 tiene un
glob
operador incorporado que acepta un patrón de globo tipo shell que puede usarse para generar listas de nombres de archivo (por ejemplofoo*.txt
) o una lista de cadenas (por ejemplo{a,b,c}
). El problema es que la nueva línea necesita escapar, lo que he hecho usandoquotemeta
(como\Q
).fuente
K (ngn / k) ,
2725 bytesPruébalo en línea!
"^"/"v"\
reemplazar"v"
con"^"
x,'
zip con los caracteres originales(,/,/:\:)/
producto cartesiano sobre?
uniqfuente
APL (Dyalog Classic) ,
21 1715 bytesPruébalo en línea!
similar a mi solución k
devuelve una matriz n-dimensional de cadenas (n = número de conmutadores)
en forma más fácil de explicar:
⊃(∘.,⌿ ⊢ ∪¨ 'v'⎕r'^')
'v'⎕r'^'
reemplazarv
s con^
s⊢ ∪¨
... uniones con cada uno de los personajes originales. es un vector de cadenas de longitud 1 o 2∘.,⌿
reducción de productos cartesianos⊃
revelarpara llegar a la versión totalmente golfizada seguimos el patrón
f⌿ A g¨ B
->A f.g B
:∘.,⌿ ⊢ ∪¨ 'v'⎕r'^'
->⊢ ∘.,.∪ 'v'⎕r'^'
como efecto secundario los paréntesis ya no son necesarios
fuente
J , 42 bytes
Pruébalo en línea!
explicación
Dejar tomar
como nuestro ejemplo de entrada.
('v^' {~ 2 #:@i.@^ 1 #. e.&'v')
crea todos los combos posibles de solo los interruptores, ignorando el formato de entrada. para nuestro ejemplo produce:1 #. e.&'v'
cuenta los números dev
s en la entrada.2 #:@i.@^
eleva 2 a esa potencia, produce los enteros de 0 a ese númeroi.
y los convierte en binarios#:
'v^' {~
Los cambios en los dígitos binariosv
y^
]`('v' I.@e.~ [)`[}"1
modifica la entrada original, produciendo una copia para cada fila del resultado descrito en el paso anterior (es decir, todos los posiblesv
/^
combos). En cada copia, lav
entrada original se reemplaza con una posible secuencia dev
/^
.fuente
Java,
202197189191 bytesSí, es un lenguaje comparativamente detallado, pero eso es lo que considero como golf clásico:
Pensé que una manera "simple" de hacer frente a los saltos de línea que son necesarias para lograr que el diseño apropiado era que en realidad re-utilizar la matriz de caracteres de entrada original, y sólo llenarlo con
'v'
s y'^'
S a las posiciones adecuadas.Actualizaciones:
Resultó que no almacenar las posiciones permite deshacerse de las
int
declaraciones de variables de la matriz (a costa de verificar cada posición de la matriz si contiene unav
o^
sobre la marcha), ahorrando 5 bytes.Otros 8 bytes guardados al calcular el límite
(1<<numberOfSwitches)
superior de manera más compacta.De acuerdo con la regla mencionada en el comentario, la declaración de función debe contarse, por lo que ahora es una lambda ...
fuente
String generate(String s) {...}
) en su recuento de bytes. Aquí hay una versión fija / lambda para 191 bytes . Practiqué un poco de golf para reducir 3 bytes{ function body }
debería ser relevante, porque no importa si lo pones en una función que esstatic
o no, y por supuesto, si la declaración cuenta para el puntaje, uno puede convertirlo en una expresión lambda. Pero eso es lo que se hace ahora, gracias por señalar esto.d=94
). 2. Inicialicei
cuando lo declare. 3. Use eni++<m
lugar de un incremento separado (necesita modificar el contenido del bucle en un solo lugar, pero esto no tiene costo). 4. ¿Puedes salirte con la tuya(i&1<<j++)>0
? 5. No creo que necesites el{}
para elfor
bucle interno . 6. Puede reemplazara[k]==d||a[k]==u
cona[k]>45
, creo. 7. Ve conj=k=0
. Todo lo que debería eliminar 19bytes.{}
son necesarias, pero puedo echarle otro vistazo. Ela[k]>45
puede ser un buen truco, sin embargo. Es cierto que solo escribí esto para perder el tiempo esperando que comience una reunión (de ahí el nombre de la clase, esto fue intencional ;-)), pero tal vez voy a echar otro vistazo, ¡en cualquier caso, gracias!J ,
41 4024 bytesPruébalo en línea!
fuente
{
. aunque creo que[:>@,@{<@(,'^'$~'v'=])"0
sería un poco más justo ya que "Cada placa de salida debe tener exactamente el mismo formato que la entrada" y la entrada no está encuadrada.Python 2 , 87 bytes
Pruébalo en línea!
Un enfoque no regex.
fuente
C (gcc) ,
75 7470 bytes-5 bytes gracias a @ceilingcat
Pruébalo en línea!
requiere que los
s
puntos de memoria sean grabablesfuente
Python 3.8 (prelanzamiento) ,
129117116101bytes-10 bytes gracias a @Chas Brown
Pruébalo en línea!
fuente
C (gcc) , 102 bytes
Pruébalo en línea!
fuente
K4 , 44 bytes
Solución:
Ejemplos:
Explicación:
Reemplazo en el lugar de
"^"
. Determine el número de combinaciones de interruptores (por ejemplo, 2 ^ n), cuente en binario, reemplace los interruptores ...fuente
R , 116 bytes
Pruébalo en línea!
Función que devuelve un vector de tableros separados de nueva línea
fuente
"[<-"
!JavaScript, 88 bytes
Pruébalo en línea!
fuente
n>>=1
->n/=2
Retina 0.8.2 , 29 bytes
Pruébalo en línea! Explicación:
Cambie las nuevas líneas en
;
sy lasv
s en#
marcadores.Reemplace el
#
s uno a la vez de izquierda a derecha.Cambie cada línea en dos líneas, una con el
#
reemplazado por av
, otra con el reemplazado por a^
.;
Vuelva a cambiar la s a nuevas líneas y separe los resultados.fuente
Perl 5
-0
, 51 bytesPruébalo en línea!
fuente
-n
habría evitado la necesidad de$_=<>;
JavaScript (Node.js) ,
80 7368 bytesPruébalo en línea!
fuente
Python 3 - construcción, 203 bytes
Pruébalo en línea!
Primer intento, no muy pequeño pero funciona. No hay reemplazo de cuerda elegante en Python ...
El primer bucle crea una asignación de líneas a índices de bits, es decir, para cada línea, se almacena el índice del primer bit en un contador de bits. Esto se usa para indexar el contador de bits en el siguiente ciclo.
El segundo bucle ejecuta un contador binario, extrae los bits para cada línea e iteración y los une. Después de unir todo, se traduce nuevamente al formato de mapa de conmutación, utilizando el reemplazo de cadena.
Supongo que hay una manera más elegante reutilizando la cadena de entrada en lugar de reconstruirla una y otra vez.
Editar: inspirado en la respuesta de Python 3.8 , aquí hay una versión de reemplazo mucho más corta
Python 3 - reemplazar, 123 bytes
Pruébalo en línea!
fuente
Ruby , 64 bytes
En Ruby,
i[j]
devuelve elj
bit dei
inicio desde el bit menos significativo, es decir, es equivalente a(i>>j)&1
.Pruébalo en línea!
fuente
Carbón , 28 bytes
Pruébalo en línea! El enlace es a la versión detallada del código. Explicación:
fuente
PHP , 93 bytes
Pruébalo en línea!
Programa independiente, entrada por línea de comando.
Repita el número de posibles permutaciones de la cadena de entrada en función del número de
v
's. Mientras cuenta en binario, reemplace cada binario1
con a^
y cada binario0
con av
en la cadena de entrada.fuente