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 maneragfunciona ahora es mediante el uso de comparación léxica de sustituir^vporvy mantener todo lo demás igual.Curiosamente, esto funciona para cuadros de distribución arbitrarios:
Explicación (corta)
Explicación (larga)
mapMes 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 enStrings (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,
aybson ambosChar, por lo que podemos ver la firma de tipo comoVeamos rápidamente qué
ghace antes de explicar cómomapMfunciona.gutiliza 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 deChars, por lo que podemos ponerlasxen una lista singleton). Al probar REPL, encontramos que este es el casoTenga en cuenta que
gtiene el tipo correcto para ser un argumento demapM(¡como era de esperar!).Exploraremos cómo
mapMfunciona dándolegy el argumentocomo entrada
mapMprimeros mapasgsobreString, y porquegconvierteChars enStrings, esto nos da una lista deStringsSi bien este es el tipo de salida correcto,
mapMhace un poco más. Puede pensar que forma todos los correosStringelectrónicos que podría crear a partir de esta lista si tuviera que elegir un solo carácter de cada unoStringen 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
CharsyStrings, cuando coloca lasChars en una lista, no las necesitajoin.Entonces el resultado final es
como se desee.
fuente
mapMfuncionó para este desafío, al principio lo formulé comosequence . map gpero eso se puede expresar de manera compactamapM id . map gy luego vi que podía simplementemapM g=='v'por>'-'Perl 6 , 32 bytes
Pruébalo en línea!
.combdivide 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ólovtiene 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 forosay for␠a cambio.Al ir al enfoque secundario, podría acortar
a
La explicación es bastante simple. Perl 5 tiene un
globoperador 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'^'reemplazarvs 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 devs 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 binariosvy^]`('v' I.@e.~ [)`[}"1modifica 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, laventrada 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
intdeclaraciones de variables de la matriz (a costa de verificar cada posición de la matriz si contiene unavo^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 esstatico 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. Inicialiceicuando lo declare. 3. Use eni++<mlugar 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 elforbucle interno . 6. Puede reemplazara[k]==d||a[k]==ucona[k]>45, creo. 7. Ve conj=k=0. Todo lo que debería eliminar 19bytes.{}son necesarias, pero puedo echarle otro vistazo. Ela[k]>45puede 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'=])"0serí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
spuntos 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/=2Retina 0.8.2 , 29 bytes
Pruébalo en línea! Explicación:
Cambie las nuevas líneas en
;sy lasvs 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
-nhabrí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 eljbit deiinicio 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 binario1con a^y cada binario0con aven la cadena de entrada.fuente