L'autre jour, notre équipe s'est rendue dans une salle d'évasion. L'un des casse-tête impliquait une carte de six interrupteurs mécaniques où vous deviez trouver la bonne combinaison d'activation et de désactivation afin de déverrouiller une boîte, un peu comme ceci:
-v-v-v-
-v-v-v-
En tant que développeurs, nous avons décidé qu'il serait plus efficace d'essayer chacune des combinaisons 2 ^ 6 = 64 que de résoudre le puzzle. Nous avons donc assigné un pauvre gars pour faire un comptage binaire:
-v-v-v-
-v-v-v-
-v-v-v-
-v-v-^-
-v-v-v-
-v-^-v-
-v-v-v-
-v-^-^-
etc.
Le défi
Écrivez un programme qui, étant donné que les commutateurs sont tous en position d'arrêt sous forme de chaîne formatée comme ci-dessus, génère toutes les combinaisons d'activation et de désactivation dans n'importe quel ordre.
Vous pouvez écrire soit un programme complet soit une fonction. Ainsi, votre programme peut soit prendre en entrée via stdin, un fichier, soit en tant qu'argument de chaîne unique, et retourner ou imprimer la sortie. S'il est retourné, la sortie peut être dans une liste / tableau / etc. plutôt qu'une seule chaîne. Si la sortie est une seule chaîne, les tableaux doivent être séparés par des retours à la ligne (les retours à la ligne sont autorisés.)
Les chaînes d'entrée correspondront à l'expression régulière r'((-v)+-)(\n(-v)+-)*'
et représenteront une carte avec tous les commutateurs désactivés. Cela signifie qu'il n'y a pas de cas zéro et que les commutateurs sont alignés à gauche. Chaque ligne peut ne pas avoir le même nombre de commutateurs.
Chaque carte de sortie doit avoir exactement le même format que l'entrée, sauf que les v peuvent être remplacés par des ^ si nécessaire. Les cartes de sortie peuvent être séparées par un nombre quelconque de sauts de ligne.
Étant donné que l'exécution est naturellement O (2 ^ n) dans le nombre de commutateurs, votre code ne sera pas testé sur plus de 10 commutateurs dans n'importe quel arrangement.
C'est le code-golf, donc le code le plus court en nombre d'octets gagne.
Exemples d'entrées et de sorties
Contribution:
-v-
Sortie possible:
-v-
-^-
Contribution:
-v-
-v-
Sortie possible:
-^-
-^-
-^-
-v-
-v-
-^-
-v-
-v-
Puisqu'il est extrêmement fastidieux de vérifier votre réponse pour un plus grand nombre de commutateurs, voici un script Python en tant qu'outil de vérification d'intégrité. (J'ai inclus un extrait actuellement commenté pour générer la sortie attendue à partir d'un fichier d'entrée donné au cas où vous voudriez plus de cas de test.) C'est un peu moins flexible en termes d'entrée et de sortie que la spécification, malheureusement; placez la chaîne d'entrée dans un fichier nommé 'input' et la sortie séparée par la nouvelle ligne (désolé, pas de formatage de liste) dans un fichier nommé 'output' dans le même répertoire et exécutez python3 sanitycheck.py
.
la source
Réponses:
Haskell ,
25242317 octetsEssayez-le en ligne!
-1 octet grâce à @ H.PWiz
-1 octet grâce à @nimi
Renvoie une liste de chaînes. Le TIO a 2 octets supplémentaires pour la déclaration de fonction - j'ai vu d'autres personnes le laisser de côté quand ils écrivent la fonction sans point donc je fais la même chose sauf indication contraire.
Réponse précédente (25 octets)
Les explications sont toutes pour la réponse précédente, qui fonctionne à peu près de la même manière, sauf que j'ai souligné la définition de
g
. La façon dontg
fonctionne est maintenant en utilisant la comparaison lexical de remplacer^v
pourv
et garder tout le reste le même.Fait intéressant, cela fonctionne pour les standards arbitraires:
Explication (courte)
Explication (longue)
mapM
est une fonction assez effrayante pour ceux qui ne connaissent pas Haskell. Mais ce n'est pas difficile à comprendre dans ce contexte. En le faisant agir sur lesString
s (qui dans Haskell sont des listes de caractères), je l'ai spécialisé dans sa définition des listes. Donc, dans ce contexte, sa signature de type estIl est en fait encore plus spécialisé dans mon utilisation -
a
etb
les deuxChar
- afin que nous puissions voir la signature de type commeVoyons rapidement ce qui se
g
passe avant d'expliquer comment celamapM
fonctionne.g
utilise la correspondance de motifs pour convertir leChar 'v'
en chaîne"v^"
; tout le reste est converti en une chaîne singleton (rappelez-vous, les chaînes ne sont que des listes deChar
s, nous pouvons donc mettrex
une liste singleton). En testant sur le REPL, on trouve que c'est le casNotez que
g
a le bon type pour être un argumentmapM
(sans surprise!).Nous allons explorer comment cela
mapM
fonctionne en lui donnantg
et l'argumentcomme entrée.
mapM
mappe d'abordg
sur leString
, et parce queg
convertitChar
s enStrings
, cela nous donne une liste deStrings
Bien qu'il s'agisse du type de sortie correct, il en
mapM
fait un peu plus. Vous pouvez le considérer comme formant tous lesString
s que vous pourriez créer à partir de cette liste si vous deviez choisir un seul caractère de chaqueString
(dans l'ordre).Donc, pour le premier élément, vous n'avez pas d'autre choix que de choisir le
Char '-'
. Pour le deuxième élément, vous pouvez choisir entre'v'
et'^'
, ainsi de suite et ainsi de suite.Il est à peu près équivalent à ce code python:
Sauf que depuis Haskell sépare entre
Char
s etString
s, quand il met leChar
s dans une liste, il n'en a pas besoinjoin
.Donc, la sortie finale est
comme voulu.
la source
mapM
fonctionné pour ce défi, au début, je l'avais formulé comme,sequence . map g
mais cela peut être exprimé de manière compactemapM id . map g
, puis j'ai vu que je pouvaismapM g
=='v'
pour>'-'
Perl 6 , 32 octets
Essayez-le en ligne!
.comb
divise la chaîne en caractères.».&{...}
mappe les caractères selon la fonction entre les accolades.$_, ('^' if /v/)
produit une liste de suppléants pour chaque caractère. N'av
qu'un remplaçant:^
.[X~]
réduit cette liste avec l'opérateur de produit croisé de concaténation de chaînesX~
.la source
Gelée , 7 octets
Essayez-le en ligne!
La sortie est une liste de chaînes Jelly.
Explication:
la source
Perl 5 , 29 octets
Essayez-le en ligne!
Ma première soumission!
Normalement, les golfeurs de Perl 5 soumettent des programmes au lieu de fonctions pour éviter d'avoir à inclure
sub{}
au minimum. Mais ils doivent ajoutersay
,say␠
,say for
ousay for␠
en échange.En allant sous l'approche, je pourrais raccourcir
à
L'explication est assez simple. Perl 5 a un
glob
opérateur intégré qui accepte un modèle glob de type shell qui peut être utilisé pour générer des listes de noms de fichiers (par exemplefoo*.txt
) ou une liste de chaînes (par exemple{a,b,c}
). Le hic, c'est que la nouvelle ligne doit être échappée, ce que j'ai fait en utilisantquotemeta
(as\Q
).la source
K (ngn / k) ,
2725 octetsEssayez-le en ligne!
"^"/"v"\
remplacer"v"
par"^"
x,'
zip avec les caractères d'origine(,/,/:\:)/
produit cartésien terminé?
uniqla source
APL (Dyalog Classic) ,
21 1715 octetsEssayez-le en ligne!
semblable à ma solution k
renvoie un tableau de chaînes à n dimensions (n = nombre de commutateurs)
sous une forme plus facile à expliquer:
⊃(∘.,⌿ ⊢ ∪¨ 'v'⎕r'^')
'v'⎕r'^'
remplacerv
s par^
s⊢ ∪¨
... des unions avec chacun des personnages originaux. c'est un vecteur de chaînes de longueur 1 ou 2∘.,⌿
réduction du produit cartésien⊃
divulguerpour arriver à la version entièrement golfée, nous suivons le modèle
f⌿ A g¨ B
->A f.g B
:∘.,⌿ ⊢ ∪¨ 'v'⎕r'^'
->⊢ ∘.,.∪ 'v'⎕r'^'
comme effet secondaire les parenthèses ne sont plus nécessaires
la source
J , 42 octets
Essayez-le en ligne!
explication
Laisse prendre
comme notre exemple d'entrée.
('v^' {~ 2 #:@i.@^ 1 #. e.&'v')
crée tous les combos possibles uniquement des commutateurs, en ignorant le format d'entrée. pour notre exemple, il produit:1 #. e.&'v'
compte le nombre dev
s dans l'entrée.2 #:@i.@^
élève 2 à cette puissance, produit les entiers de 0 à ce nombrei.
et les convertit en binaire#:
'v^' {~
modifications apportées aux chiffres binairesv
et^
]`('v' I.@e.~ [)`[}"1
modifie l'entrée d'origine, en produisant une copie pour chaque ligne du résultat décrit à l'étape précédente (c'est-à-dire tous les combosv
/ possibles^
). Dans chaque copie, l'v
entrée d'origine est remplacée par une séquence possible dev
/^
.la source
Java,
202197189191 octetsOui, c'est un langage relativement verbeux, mais c'est ce que je considère comme du golf classique:
Je pensais qu'une façon "simple" de traiter les sauts de ligne nécessaires pour obtenir une mise en page correcte était de réutiliser le tableau de caractères d'entrée d'origine et de le remplir uniquement avec
'v'
s et'^'
s aux positions appropriées.Mises à jour:
Il s’est avéré que le fait de ne pas stocker les positions permet d’abandonner les
int
déclarations des variables et du tableau (au prix de vérifier si chaque position du tableau contient unv
ou^
à la volée), économisant 5 octets.8 octets supplémentaires enregistrés en calculant la limite supérieure
(1<<numberOfSwitches)
supérieure de manière plus compacte.Selon la règle mentionnée dans le commentaire, la déclaration de fonction doit être comptée, alors maintenant c'est un lambda ...
la source
String generate(String s) {...}
) dans votre nombre d'octets. Voici une version fixe / lambda pour 191 octets . J'ai fait du golf mineur pour raser 3 octets{ function body }
devrait être pertinent, car peu importe que vous le mettiez dans une fonction qui eststatic
ou non, et bien sûr, si la déclaration compte pour le score, on peut le convertir en une expression lambda. Mais c'est ce qui se fait maintenant, merci de l'avoir signalé.d=94
). 2. Initialisezi
lorsque vous le déclarez. 3. Utilisezi++<m
au lieu d'un incrément séparé (besoin de modifier le contenu de la boucle en un seul endroit, mais cela n'ajoute aucun coût). 4. Pouvez-vous vous en sortir(i&1<<j++)>0
? 5. Je ne pense pas que vous ayez besoin{}
de lafor
boucle intérieure . 6. Vous pouvez remplacera[k]==d||a[k]==u
para[k]>45
, je pense. 7. Allez-yj=k=0
. Tout cela devrait supprimer 19 octets.{}
sont nécessaires, mais je peux avoir un autre regard. Lea[k]>45
peut - être une astuce, cependant. Certes, je n'ai écrit cela que pour perdre du temps à attendre le début d'une réunion (d'où le nom de la classe - c'était intentionnel ;-)) mais peut-être que j'aurai un autre regard - merci en tout cas!J ,
41 4024 octetsEssayez-le en ligne!
la source
{
. bien que je pense que ce[:>@,@{<@(,'^'$~'v'=])"0
serait un peu plus juste car "chaque carte de sortie devrait être du même format que l'entrée" et l'entrée n'est pas encadrée.Python 2 , 87 octets
Essayez-le en ligne!
Une approche non regex.
la source
C (gcc) ,
75 7470 octets-5 octets grâce à @ceilingcat
Essayez-le en ligne!
nécessite que les
s
points de mémoire soient accessibles en écriturela source
Python 3.8 (pré-version) ,
129117116110octets-10 octets grâce à @Chas Brown
Essayez-le en ligne!
la source
C (gcc) , 102 octets
Essayez-le en ligne!
la source
K4 , 44 octets
Solution:
Exemples:
Explication:
Remplacement sur place de
"^"
. Déterminer le nombre de combinaisons de commutateurs (par exemple 2 ^ n), compter en binaire, remplacer les commutateurs ...la source
R , 116 octets
Essayez-le en ligne!
Fonction renvoyant un vecteur de planches séparées par une nouvelle ligne
la source
"[<-"
!JavaScript, 88 octets
Essayez-le en ligne!
la source
n>>=1
->n/=2
Retina 0.8.2 , 29 octets
Essayez-le en ligne! Explication:
Changez les sauts de ligne en
;
s et lesv
s en#
marqueurs.Remplacez le
#
s un à la fois de gauche à droite.Changez chaque ligne en deux lignes, une
#
remplacée par unv
, une remplacée par un^
.Remplacez les
;
s par de nouvelles lignes et séparez les résultats.la source
Perl 5
-0
, 51 octetsEssayez-le en ligne!
la source
-n
aurait évité le besoin de$_=<>;
JavaScript (Node.js) ,
80 7368 octetsEssayez-le en ligne!
la source
Python 3 - construction, 203 octets
Essayez-le en ligne!
Essayez d'abord, pas très petit mais ça marche. Il n'y a pas de remplacement de chaîne élégant en Python ...
La première boucle construit un mappage de lignes en index de bits, c'est-à-dire que pour chaque ligne, l'index du premier bit d'un compteur de bits est stocké. Ceci est utilisé pour indexer le compteur de bits dans la boucle suivante.
La deuxième boucle exécute un compteur binaire, extrait les bits pour chaque ligne et itération et les joint. Après avoir tout réuni, il est retransformé au format de carte de commutateur, en utilisant le remplacement de chaîne.
Je suppose qu'il existe un moyen plus élégant de réutiliser la chaîne d'entrée au lieu de la reconstruire encore et encore.
Edit: inspiré par la réponse Python 3.8 , voici une version de remplacement beaucoup plus courte
Python 3 - remplacer, 123 octets
Essayez-le en ligne!
la source
Rubis , 64 octets
Renvoie un tableau. Obtient des nombres de1 à 2v (où v est le nombre de "v" dans l'entrée) et bascule les commutateurs en fonction de la v bits les moins significatifs. Cela nous permet d'économiser un octet sur l'itération de0 à 2v- 1 , parce que le v bits les moins significatifs 2v sont tous nuls.
Dans Ruby,
i[j]
retourne lej
e biti
à partir du bit le moins significatif, c'est-à-dire qu'il est équivalent à(i>>j)&1
.Essayez-le en ligne!
la source
Fusain , 28 octets
Essayez-le en ligne! Le lien est vers la version verbeuse du code. Explication:
la source
PHP , 93 octets
Essayez-le en ligne!
Programme autonome, entrée via la ligne de commande.
Boucle le nombre de permutations possibles de la chaîne d'entrée en fonction du nombre de
v
. Pendant le décompte en binaire, remplacez chaque binaire1
par un^
et chaque binaire0
par unv
dans la chaîne d'entrée.la source