Puis-je enchaîner tous mes cordons et adaptateurs ensemble?

30

Supposons qu'un jour vous fouilliez dans votre grande boîte de cordons et d'adaptateurs informatiques inutilisés (USB vers USB mini, VGA vers DVI, etc.). Il y a partout des cordons emmêlés qui font tout un gâchis, et vous vous demandez si vous pourriez simplifier les choses en attachant tous les cordons ensemble dans un long brin, puis en les enroulant simplement.

La question est, est-il possible de connecter tous vos cordons et adaptateurs sur une longue ligne comme celle-ci? Ce n'est évidemment pas toujours possible, par exemple si vous n'aviez que deux cordons avec des fiches complètement différentes, ils ne pourraient pas être connectés ensemble. Mais si vous aviez un troisième cordon qui peut se connecter aux deux, vous pouvez alors lier tous vos cordons ensemble.

Vous ne vous souciez pas du type de fiches aux extrémités du brin tout cordon. Ils n'ont pas besoin de se connecter les uns aux autres pour former une boucle. Vous voulez seulement savoir si la fabrication du toron tout cordon est possible, et si c'est le cas, comment le faire.

Défi

Écrivez un programme ou une fonction qui prend une chaîne multiligne où chaque ligne représente l'un des cordons que vous possédez. Un cordon est composé d'un ou plusieurs tirets ( -), avec une fiche à chaque extrémité. Une prise est toujours l'un des 8 caractères ()[]{}<>.

Voici donc quelques cordons valides:

>->
(--[
}-{
<-----]
(---)

Mais ce ne sont pas:

-->
(--
)--
[{
---

Lors de la connexion des cordons, seules les fiches ayant exactement le même type de support peuvent être connectées ensemble.

Voici donc quelques connexions de cordon valides:

...---((---...
...---))---...
...---]]---...
...---{{---...
...---<<---...

Et ceux-ci ne sont pas valides:

...---()---...
...---)(---...
...---{]---...
...---{[---...
...---><---...
...--->)---...

Si tous les cordons de l'entrée peuvent être réarrangés et attachés ensemble dans un long brin, alors sortez ce brin vers la sortie standard sur une ligne (avec un retour à la ligne de fin facultatif). Lorsqu'il existe plusieurs solutions, vous pouvez choisir l'une d'entre elles pour la sortie. S'il n'est pas possible de créer un seul brin, alors ne rien produire (ou sortir une chaîne vide avec un retour à la ligne facultatif).


Par exemple, si l'entrée est

[-->
{---]
>----{

la sortie pourrait être

[-->>----{{---]

où tous les cordons sont attachés ensemble.

Cependant, si l'entrée était

[-->
{---]

les cordons ne peuvent pas être connectés, il n'y aurait donc pas de sortie.


Notez que les cordons peuvent être retournés autant de fois que nécessaire pour effectuer les connexions. par exemple [-->et <--]sont effectivement le même cordon car ils peuvent faire le même type de connexions. Certaines sorties peuvent dépendre du retournement des cordons d'entrée.


Par exemple

(-[
}--]

pourrait avoir une sortie

(-[[--{

où le deuxième cordon est retourné, ou

}--]]-)

où le premier cordon est retourné.

(Notez qu'en général, le retournement de la sortie entière est valide car c'est la même chose que le retournement initial de chaque cordon individuellement.)


Les longueurs des cordons dans la sortie doivent bien sûr correspondre aux longueurs des cordons d'entrée correspondants. Mais les cordons peuvent être réorganisés et retournés autant que vous le souhaitez pour faire le brin tout cordon. L'entrée contiendra toujours au moins un cordon.

Le code le plus court en octets gagne.

Cas de test

Cas avec sortie:

[-->
{---]
>----{
gives
[-->>----{{---]
or
[---}}----<<--]

(-[
}--]
gives
(-[[--{
or
}--]]-)

(-)
gives
(-)

[--{
gives
[--{
or
}--]

[-]
]-[
gives
[-]]-[
or
]-[[-]

[----->
)------------[
{--<
}---)
could give
[----->>--}}---))------------[
or
>--}}---))------------[[----->
or
}---))------------[[----->>--}
or
{--<<-----]]------------((---{
etc.

>-->
>->
>--->
could give
>-->>->>--->
or
>--->>-->>->
or
>->>-->>--->
or
<--<<---<<-<
etc.

(-]
]->
>-}
}-)
)-[
[-<
<-{
{-(
could give
(-]]->>-}}-))-[[-<<-{{-(
or
{-((-]]->>-}}-))-[[-<<-{
or
<-{{-((-]]->>-}}-))-[[->
etc.

Cas sans sortie:

[-->
{---]

[-]
[-]

(-]
]->
}-)

>->
>-->
]---]

[-------------------]
]-------------------[
[-----------------]
[-----------------]

{--[
]--}
Loisirs de Calvin
la source
6
grande boîte de cordons et d'adaptateurs d'ordinateur inutilisés Cela me fait me sentir mieux - je ne suis pas le seul. En fait, j'ai plusieurs de ces boîtes.
Digital Trauma
mais que se passe-t-il si vous branchez un cordon sur lui-même?
anOKsquirrel
Les cordons sont-ils garantis valables pour tous?
R. Kap
@ R.Kap Oui, ils le sont
Calvin's Hobbies

Réponses:

10

Illisible , 3924 octets

C'est la première fois que j'implémente une structure semblable à une pile d'appels dans Unreadable.

(La première version de celui-ci était plus de 5300 octets, juste pour donner une idée de combien j'ai joué au golf.)

'"" "" "'" "'" "" "" "" "" "" ""' "" "'" "'" "'" "'" "'" "' '" "'" "" " "" "'" ""' "" "" "" '""' "" "'" "" "" "" "" "'" "" "'" "" "'" "" "'" " "" "" '""' "" '""' "" '""' "" '"" "" "" "'" "" '"" "" "'" "" "" "" """ '"" "" "" ""' "" "" "" "" '"" "" "" "" "" "" "" "" "'" "" "" "" "" "" " "" "" "" '"" "" "" ""' "" "" "" "" '"" "" "" ""' "" "" "" "" '"" "" "" " "'" "" "" "" "'" "" "" "" "'" "" "" "" "" "" "" "" ""' "" "" "" "" "'"" "" "" ""' "" "" "" "" '"" "" "" ""' "" "" "" "" '"" "" "" "" "'" "" " "" "" '"" "" "" ""' "" "" "" "" '"" "" "" ""' "" "" "" "" '"" "" "" ""' ' "" "" "" "" '"" "" "" ""' "" "" "" "" '"" "" "" ""' "" "" "" "" '"""" "" "" "'" "" "" "" "" "" "" "" ""' "" "" "" "" '"" "" "" "" "" "" "" " "" '"" "" "" ""' "" "" "" "" '"" "" "" "" "" "" "" "" "'" "" "" "" "" "" " "" "" "" '"" "" "" ""' "" "" "" '""' "" '"" "" "" "'" "" '"" "" """ "" "'" "" "" "" "'" "" '"" "'" "" "'" "" "" "'" "'" "'" "" "" '"" "" '"" "" "" "'" "'" "'" "" "" "" '"" "'" "" "" "'" "'" "" "" "" "'" ""' "" "'" "" "" ""' "" '"" "" "" "'" "" '"" "" "'" "" "" "'" "'" "" "" """" "" '"" "" "" "'" "" '"" ""' "" "" "" '""' "" '""' "" "" "" "" '"" "' "" "" "" "" "'" "" "" "" ""' "" "'" "" "" "" "'" "" "" "" "'" "" "" "" " '"" "" "" ""' "" "" "" "" '"" "" "" ""' "" "" "" "" '"" "" "" ""' '""" "" "" "'" "" "" "" "" "" "" "" ""' "" "" "" "" '"" "" "" "" "" "" "" " "" '"" "" "" ""' "" "" "" "" '"" "" "" "" "" "" "" "" "'" "" "" "" "" "" " "" "" "" '"" "" "" ""' "" "" "" "" '"" "" "" ""' "" "" "" "" '"" """ "" "'" "" "" "" "'" "" "" "" "'" "" "" "" "'" "" "" "" "'" "" "" "" " '"" "" "" ""' "" "" "" "" '"" "" "" ""' "" "" "" "" '"" "" "" "" "'" "" " "" "" '"" "" "" ""' "" "" "" "" '"" "" "" ""' "" "" "" "" '"" "" """ '""' "" "'" "" "" "" ""' "" "" "" '""' "" "'" "" "" "" "'" "" "" "" '""' "" "'" "" "" "" ""' "" "" "" '""' "" "'" "" "" "" "'" "" "" "" "'' "" "" "" "" '"" "" "" ""' "" "" "" "" '"" "" "" ""' "" "" "" "" '"" """ "" "" '"" "" "" ""' "" "" "" "" '"" "" "" ""' "" "" "" "" '"" "" "" " "'" "" "" "" "'" "" "" "" "'" "" "" "" "'" "" "" "" "'" "" "" "" ""' "" " "" "" "'" "" "" ""' "" '"" "'" "" "" "" "" '"" "" ""' "" '"" "'" """ "" "" "'" "" "" "" "" "" "" "" ""' "" "" "" "" '"" "" "" "" "" "" "" " "" '"" "" "" ""' "" "" "" "" '"" "" "" "" "" "" "" "" "'" "" "" "" "" "" " "" "" "" '"" "" "" ""' "" "" "" "" '"" "" "" ""' "" "" "" "" '"" """ "" "'" "" "" "" "'" "" "" "" "'" "" "" "" "'" "" "" "" "'" "" "" "" " '"" "" "" ""' "" "" "" "" '"" "" "" ""' "" "" "" "" '"" "" "" "" "'" "" " "" "" '"" "" "" ""' "" "" "" "" '"" "" "" ""' "" "" "" "'" "'" ""'"" "" "" "" "'" "" "" "" "'" "" "" "" "'" "" "" "" "'" "" "" "" ""' "" " "" "" "'" "" "" "" "'" "" "" "" "'" "" "" "" "'" "" "" "" "'" "" "" "" " '"" "" "" ""' "" "" "" "" '"" "" "" ""' "" "" "" "" '"" "" "" ""' '"" "" "" "" '"" "" "" ""' "" "" "" "" '"" "" "" ""' "" "" "" "" "" "" "" " "" "'" "" "" "" "'" "" "" "" "'" "" "" "" "'" "" "" "" "" "" "" "" "" '"" "" "" "" "'" "" "" "" "'" "" "" "" "'" "" "" "" "'" "" "" "" "'" """ "" "" '"" "" "" "'" "'" ""' "" "" "" "" '"" "" "" "" "" "" "" ""' "" "" "" "'" ""' "" '""' "" "" "" "'" "" "" ""' "" "'" "'" "'" "" "" ""' ' "" "" "" "'" ""' "" '""' "" "" "" "'" "" "" ""' "" "'" "" "" "" ""'"" "" "" "'" "" "" ""' "" "'" "'" "" "" "" '"" "" "" "'" "" '"" "" ""' "" "'" "'" "'" "" "" ""' "" "'" "" "" "" ""' "" '""' "" "" "" "" '"" "' "" "" "" "'" "" "" "" "'" "" "" "" '"" "'" "" "" "" "" "'" "" "" "' '"" "" "" "'" ""' "" "" "" "" '"" "" ""' "" '""' "" '"" "'" "" "" "" "" " "" "" '""' "" "'" "'" "" "" "" '"" "'" "" '"" "" "'" "" "" "" "'" "'" " '""' "" "'" "" "'" "" "'" "" "" "'" "'" "'" "" '"" "" ""' "" "'" """'" "" ""' "" "" "" "'" "" "" "'" "" '""' "" '""' "" '""' "" "" "" "'' "" "'" "" "" "" ""' "" "" "" "'" "'" "'" "'" "'" "" "" ""' "" "'" ""' ' "" "" "" '""' "" '"" "'" "" "" "" "'" ""' "" "" "" "" "'" "" "" ""' '"" '""' "" "'" "" "" "" ""' "" '""' "" "'" "" "" "" "'" "" '"" ""' "" "" '"" "" ""' "" "'" "" "" ""' "" "" "" "'" "'" "" '"" "" "' '" "" "" "" '"" "" ""' "" "'" "'" "'" "'" "'" "'" "" "" "" '"" "'" "" "" "" "" "'"" "" "" "'" "'" "'" "'" "'" "" "" "" '' "" '"" "'" "" "" "" "" "'" "" "" "" "" '"" "" "" "'" "" "" "" "'" "" "" ""' "" '"" "'" "" "" '"" ""' " "" "" "'" "" "" "" "'" "" '"" "" "" "'" "'" "'" "" "" "" '"" "" """" '"" "" "" "'" "'" ""' "" "" "" '""' "" '"" "'" "'" "" "" "" "'" "" " "" "'" ""' "" "" "" "" "'" "" ""' "" "" "" "" "'" "'" "" '"" "" "" ""' ' "" "" "" "'" "'" "'" ""' "" "" "" '"" "" "" ""' "" "'" "" "" "" ""'"" "" "" "'" "" "" "" "" "" "'" "" "" "" "" "" "'" ""' "" "'" "" "" "" "" "" '"" "" "" ""' "" "" "" '""' "" '"" "'" "" "" "'" "" "" "" "" "'" "" '"" "" "" "'" "" '"" "'" "" "" "" "" '"" "" "" "'" "'" "'" "" '"" """ "" '"" "" ""' "" '"" "'" "'" "" "" "" "" "'" "" '"" "" "" "'" "" "" " "'" ""' "" "" "" '"" "" "" "" "'" "" "" "" "" "" "" "" "" "" "" "" "" "" " "'" "'" "'" "'" "'" "'" "" "" "" '"" "'" "" "" "" "'" "" "" "" ""'"" "" "" "" '"" "" "" ""' "" "" "" "" '"" "" "" "'" "" '"" "'" "" "" "" "" '"" "" ""' "" "'" "" "" ""' "" "" "" '""' "" "'" "" "" "" ""' "" "" " "" '""' "" "'" "" "" "" ""' "" '""' "" '"" "" "" "'" "" '"" "" "" "'"" "" "" "" "'" "" "" "" '""' "" '""' "" "" "" "'" "" "" "'" "'" "'" " "'" "'" "'" "'" "'" "'" "" "" "" '"" "'" "" "" "" "'" "" "" "" "'" "" ' "" "" "" "" '"" "'" "" "" "'" "'" "'" "'" "" '"" "" "" ""' "" "'" """" "" "" "'" "" "" "" "" ""' "" "" "'" "" "" "" "'" "" "" "" '"" "" ""' ' "" "'" "'" "" "" "" '"" "'" "" "'" "" "'" '"" "" "" "'" "" "" "" "" "" " "" "" '"" "'" "" "" '""' "" "" "" '""' "" "" "" "'" "" "" ""' "" "'"" "" "" ""' "" "" "" "'" "'" "" "" "" '' "" "" "" '"" "'" '"" "" "" " '""' "" '""' "" '"" "'" '"" "" "" "'" "'" "'" "" "" "" '"" "" "" "" "" "" '"" "'"" "" "" "'" "'" "'" "'" "'" "" '"'" "" "" "" '""' "" '"" "" "" ""' " "" "" "" '"" "'" ""'"" "" "" "'" "'" "'" "'" "'" "" '"'" "" "" "" '""' "" '"" "" "" ""' " "" "" "" '"" "'" ""

Explication

Considérez cet exemple d'entrée:

>--{
[---}

Pendant la majeure partie de l'exécution, la bande se présente comme suit:

  • Les cellules 0 à 5 sont des emplacements pour diverses variables.

  • La cellule 6 à partir de maintenant contient toutes les informations sur le jeu de câbles dans votre boîte:

    exemple de disposition de bande

  • Les cellules restantes après le «zéro terminateur» contiennent la pile. Chaque «stackframe» est une cellule unique qui pointe vers la première cellule d'un câble (la cellule «start plug»). Dans l'exemple ci-dessus, lorsque le programme décide qu'il a trouvé une solution, la pile contiendra 6 (se référant au >--{premier câble) et 21 (se référant au {---]miroir du deuxième câble).

Le programme se déroule en trois étapes principales:

  1. Lisez l'intégralité de l'entrée et générez la structure ci-dessus, y compris tous les câbles en miroir.
  2. Essayez toutes les combinaisons (mais arrêtez si une solution est trouvée).
  3. Si une solution a été trouvée, sortez-la.

La première étape (lire l'entrée et générer la structure des câbles) utilise uniquement les cellules # 1 (que j'appellerai p) et # 2 (que j'appellerai ch) et fonctionne dans une boucle while comme suit:

  • En condition: incrémentez pde 6, lisez le caractère suivant (start plug) dans la cellule *pet vérifiez qu'il ne l'est pas -1(EOF).

  • Lisez les caractères suivants *(p+2)et comptez-les *(p+1)jusqu'à ce que nous rencontrions autre chose que -(trait d'union). À ce stade, *(p+1)contiendra le nombre de tirets (longueur du câble) et *(p+2)le dernier caractère non-trait d'union (le bouchon d'extrémité). (Nous copions également les traits d'union dans la cellule # 5 afin que nous puissions accéder à ce code ASCII plus tard dans l'étape de sortie.)

  • Dans une boucle while, trouvez la prise miroir et stockez-la à *(p+3), puis incrémentez pde 2 jusqu'à ce que *psoit zéro. La boucle ressemble à ceci en pseudocode:

    while (ch = *p) {
        *(p+3) = (ch -= 40) ? (ch -= 1) ? (ch -= 19) ? (ch -= 31) ? ch-32 ? *p-2 : *p+2 : *p+2 : *p+2 : *p-1 : *p+1
        p += 2
    }
    
  • Cette boucle effectuera toujours deux itérations (la fiche de démarrage et la fiche de fin) et stockera les résultats dans les quatrième et sixième cellules de ce câble. Maintenant, si vous avez fait attention, vous vous rendez compte que la sixième cellule est en effet l'emplacement correct pour la fiche d'extrémité en miroir, mais la fiche de démarrage en miroir se trouve dans la cellule intitulée "booléen indiquant le câble d'origine". C'est OK car nous avons seulement besoin que cette cellule soit une valeur non nulle.

  • Puisqu'il pvient d'être incrémenté d'un total de 4, il pointe maintenant vers la cellule intitulée «le câble booléen indiquant que le câble est en cours d'utilisation». Définissez *(p+3)la valeur de *(p-1). Cela place la prise de démarrage en miroir au bon endroit.

  • Lisez (et jetez) un caractère de plus (qui devrait être une nouvelle ligne, mais le programme ne vérifie pas cela).

pcommence initialement à 0 mais est incrémenté de 6 à l'intérieur de la condition while, ainsi les données du câble commencent à la cellule # 6. pest incrémenté de 4 à l'intérieur du corps de la boucle, et donc un total de 10 pour chaque câble, ce qui est exactement ce dont nous avons besoin.

Au cours de la deuxième étape, les cellules # 0-4 sont occupés par des variables que je vais appeler a, p, q, met notdone. (La cellule n ° 5 se souvient toujours du code ASCII du trait d'union.)

Pour se préparer à l'étape 2, nous devons *premettre à 0 (la cellule intitulée «terminaison zéro») afin qu'elle puisse agir comme terminateur pour la liste des câbles; nous définissons également q(qui est notre pointeur de pile) la p+1(c'est- à -dire la cellule après le «zéro terminateur»; c'est là que la pile commence); *qà 1 (le premier objet de la pile; pourquoi 1 deviendra apparent plus tard); et notdoneà 1. Tout cela se fait en une seule déclaration:

*p = (notdone = *(q = p+1) = 1)-1

La deuxième étape est également une boucle while. Son état est simplement notdone. À chaque itération de cette boucle while, l'une des quatre choses suivantes peut se produire:

  1. Nous constatons que tous les câbles sont marqués «en cours d'utilisation». Cela signifie que nous avons trouvé une solution (qui est représentée par le contenu actuel de la pile).
  2. Nous pouvons passer *qà un autre câble éligible (que nous marquons rapidement comme «en cours d'utilisation» avec son jumeau), puis recurse (c'est-à-dire créer un nouveau stackframe).
  3. Nous ne pouvons pas avancer *qcar il n'y a plus de câble éligible, nous devons donc revenir en arrière (supprimer un stackframe et marquer le câble précédent et son jumeau comme n'étant plus «utilisé»).
  4. Nous ne pouvons pas avancer *qcar aucun autre câble éligible n'existe et nous ne pouvons pas revenir en arrière car nous avons atteint le bas de la pile. Cela signifie qu'il n'y a pas de solution.

Le corps de la boucle vérifie chacune de ces quatre conditions dans cet ordre. Voici les détails:

  1. Réglez met psur 1 et dans une boucle while, incrémentez pde 5 (itérant ainsi à travers les câbles) et vérifiez si *(p+4)(«en cours d'utilisation») est défini. Si ce n'est pas le cas, définissez-le msur 0. À la fin de cette boucle, mnous indique si tous les câbles sont utilisés. Si tel est le cas, définissez-le notdonesur 0 pour terminer la boucle principale. Sinon, passez à l'étape 2 ci-dessous.

  2. Réglez psur *q(le câble en haut de la pile) et dans une boucle de temps similaire à celle ci-dessus, incrémentez pde 5 pour parcourir les câbles. Commencer par *qgarantit que nous ne considérons que ceux que nous n'avons pas déjà pris en compte auparavant; cependant, n'oubliez pas que la valeur initiale d'un nouveau stackframe est 1, donc le premier câble examiné est celui de la cellule 6, qui est en effet le premier câble.

    Pour chaque câble, nous devons vérifier *(p+4)qu'il n'est pas déjà utilisé, et aussi que soit *(q-1) zéro (ce qui signifie que nous sommes au bas de la pile, donc il n'y a pas de contrainte sur la prise de démarrage), ou *p (le début du câble fiche) est égal à *(*(q-1)+2)(la fiche d'extrémité du câble juste en dessous sur la pile). Nous vérifions l'égalité en définissant ato *(*(q-1)+2)et mto *p+1puis en décrémentant les deux dans une boucle while. Le +1is mest décrémenté à l'intérieur de la condition while, il est donc décrémenté une fois de plus a. Si aest nul à la fin de cela, les deux fiches sont égales.

    Ainsi, si l'un *(q-1)était égal à zéro ou la comparaison d'égalité réussie, le câble est éligible. Réglez *qpour premplacer le câble en haut de la pile par le nouveau; réglé msur le même pour indiquer que nous avons trouvé un câble correspondant; puis décrémenter p. Cette décrémentation est une petite astuce pour provoquer la fin de la boucle while (itération à travers les câbles); il augmentera pà nouveau de 5, l'amenant ainsi à la cellule contenant l'indicateur «in use» de ce câble, et nous savons que c'est zéro parce que nous venons de le vérifier. Enfin, après la boucle itérative du câble, nous vérifions si elle mest non nulle. Si tel est le cas, nous avons trouvé un câble correspondant et ppointons l'indicateur «en cours d'utilisation» pour ce câble correspondant. Réglez-le sur 1 pour le marquer comme utilisé. Définir également*(*(p-1) ? p+5 : p-5)à 1 pour marquer son jumeau comme en cours d'utilisation. Enfin, incrémentez qet définissez le nouveau *qsur 1 pour créer un nouveau stackframe.

  3. Si, après la boucle itérative du câble, nous trouvons mzéro, il n'y a plus de câbles correspondants, nous devons donc revenir en arrière. Décrémenter qpour descendre la pile et vérifier si elle pointe toujours vers un câble (une valeur non nulle). Si c'est le cas, marquez ce câble et son jumeau comme n'étant plus utilisé. (Nous conservons la valeur *qen ppour rendre cette expression plus courte dans le code.)

  4. Si, après décrémentation q, nous constatons qu'il pointe vers une valeur nulle, alors c'est le «terminateur zéro», ce qui signifie que nous avons dépassé la pile. Nous concluons qu'il n'y a pas de solution. Nous avons mis notdoneà 0 pour terminer la boucle principale.

Le troisième étage est l'étage de sortie. Deux choses peuvent se produire:

  • la boucle principale a trouvé une solution que nous devons produire, ou
  • la boucle principale a conclu qu'il n'y avait pas de solution et nous ne sortons rien.

Commodément, s'il n'y avait pas de solution, pest zéro parce que nous l'avons mis à la valeur de *qavant de vérifier cela pour zéro; et s'il y avait une solution, ppointe le «terminateur zéro» parce qu'il vient d'itérer à travers les câbles, nous pouvons donc maintenant utiliser ppour itérer à travers la pile. Il suffit donc d'itérer dans la pile, de sortir pour chaque câble la prise de départ ( *(*p)), les tirets (en décrémentant *(*p+1)dans une boucle while; et en utilisant le code ASCII de trait d'union stocké dans la cellule # 5), et la prise de fin ( *(*p+2)). Peu importe que cela détruise les informations de longueur de câble; nous n'en avons plus besoin.

Timwi
la source
3

CJam, 67

qN%e!{_,2,m*\f{.{_{"()[]{}<>--"_@#1^=}%W%?}_2ew{~\W=#}%0-{;}&}~}%1<

Essayez-le en ligne

Remarque: le lien utilise le dernier code du référentiel (poussé mais pas encore publié), car il contient un correctif de bogue.

Explication:

Le programme essaie simplement toutes les permutations et toutes les orientations des cordes.

qN%             read the input and split into lines
e!              generate all permutations
{…}%            map each permutation of cords
  _,            get the number of cords (n)
  2,m*          generate all patterns of n bits (cartesian power of [0 1])
  \f{…}         for each bit pattern and the cord permutation
    .{…}        apply the block to each bit and cord (flipping cords for bit 0)
      _         duplicate the cord
      {…}%      map each character of the cord
        "…"_    push the string of all the plugs (and 2 dashes) and duplicate it
        @#      get the index of the character in the string
        1^      XOR with 1
        =       get the character at this new index (plugs get toggled)
      W%        reverse the cord
                 the stack now has the bit, the original cord and the flipped cord
      ?         if the bit is 1, use the original cord, else use the flipped one
    _           duplicate the array of cords
    2ew         get all pairs of adjacent cords
    {…}%        map each pair of cords
      ~\        dump the 2 cords on the stack and swap them
      W=        get the right plug of the first cord
      #         find its position in the second cord (if 0, we have a match)
    0-          remove all the zeros
    {…}&        if the array is not empty (i.e. we have a mismatch)
      ;         pop the array of cords
  ~             dump all the results for this permutation on the stack
                 (to avoid nested arrays)
1<              get the first result (if any) from the array of all results
aditsu
la source
Peut-être une explication de comment cela fonctionne exactement?
Timwi
@Timwi ok, je l'ai également joué un peu plus
aditsu
Cette solution n'est pas valide car elle ne produit aucune sortie pour l'entrée (-] ]-> >-} }-) )-[ [-< <-{ {-(.
R. Kap
@ R.Kap, il résout cette entrée, mais cet interprète en ligne particulier a un délai d'attente (et est assez silencieux à ce sujet). Vous pouvez l'essayer ici à la place (et lui donner plusieurs minutes) ou utiliser l'interpréteur java (le plus rapide)
aditsu
En fait, l'interpréteur que j'ai lié ci-dessus prendra probablement beaucoup de temps pour résoudre cette entrée. L' interprète java le résout en moins de 1,5 min sur mon ordinateur.
aditsu
2

JavaScript (ES6), 206

Fonction récursive

f=(l,a=l.pop(),x=x=>(z='<>[]{}()')[z.indexOf(x)^1])=>l[0]?l.some((b,i)=>r=[b,x([...b].pop())+b.slice(1,-1)+x(b[0])] .some(b=>r=a[0]==[...b].pop()?b+a:b[0]==[...a].pop()?a+b:0)&&(l=[...l],l[i]=r,f(l)))?r:'':a

Plus lisible

f=(l,a=l.pop(),x=x=>(z='<>[]{}()')[z.indexOf(x)^1])=>
  l[0]?
  l.some((b,i)=>
     r=[b,x([...b].pop())+b.slice(1,-1)+x(b[0])]
     .some(b=>r=a[0]==[...b].pop()?b+a:b[0]==[...a].pop()?a+b:0)
     &&(l=[...l],l[i]=r,f(l))
    )?r:''
 :a

Tester

f=(l,a=l.pop(),x=x=>(z='<>[]{}()')[z.indexOf(x)^1])=>l[0]?l.some((b,i)=>r=[b,x([...b].pop())+b.slice(1,-1)+x(b[0])] .some(b=>r=a[0]==[...b].pop()?b+a:b[0]==[...a].pop()?a+b:0)&&(l=[...l],l[i]=r,f(l)))?r:'':a

console.log=(...x)=>O.textContent+=x+'\n'

;[
 //OK
 ['[-->','{---]','>----{']
,['(-[','}--]']
,['(-)']
,['[--{']
,['[-]',']-[']
,['[----->',')------------[','{--<','}---)']
,['>-->','>->','>--->']
,['(-]',']->','>-}','}-)',')-[','[-<','<-{','{-(']
 //KO
,['[-->','{---]']
,['[-]','[-]']
,['(-]',']->','}-)']
,['>->','>-->',']---]']
,['[-------]',']-------[','[-------]','[---------]'] // shortened a little,
,['{--[',']--}']
].forEach(t=>{
  console.log(t+' : "'+f(t)+'"\n')
})
<pre id=O></pre>

edc65
la source
1

Javascript, 800 octets

Loin d'une solution optimisée, mais voici un hack rapide ensemble en javascript (pas d'ecma5 sophistiqué ou quoi que ce soit, car je ne le sais pas).

function a(r){function t(r,t){var n=r.slice();return n.splice(t,1),n}function n(r){var t,n={"[":"]","]":"[",">":"<","<":">","(":")",")":"(","{":"}","}":"{"},e=r.split("").reverse();for(t=0;t<e.length;t++)n.hasOwnProperty(e[t])&&(e[t]=n[e[t]]);return e.join("")}function e(r,t){return r.unshift(t),r}var h,u,f=[];if(1==r.length)return r[0];for(h=0;h<r.length;h++){var l=r[h],i=t(r,h),c=l.charAt(0),g=l.charAt(l.length-1);for(u=0;u<i.length;u++){var o=i[u],s=o.charAt(0),p=o.charAt(o.length-1);c==p&&f.push(e(t(i,u),o+l)),g==s&&f.push(e(t(i,u),l+o)),o=n(o),s=o.charAt(0),p=o.charAt(o.length-1),c==p&&f.push(e(t(i,u),o+l)),g==s&&f.push(e(t(i,u),l+o))}}if(f.length<1)return!1;for(h=0;h<f.length;h++){if(1===f[h].length)return f[h][0];f[h]=a(f[h])}for(h=0;h<f.length;h++)if(f[h]!==!1)return f[h];return!1}

Ungolfed, le voici ... Je suis sûr qu'au moins 2 boucles sont inutiles ici et que la vérification d'une entrée d'élément unique en haut et d'une correspondance d'élément unique en bas est stanky ... mais cela semble fonctionner et traite les entrées de test.

function a(inputs)
{
	var i, ii, matches = [];
	if (inputs.length == 1) {
		return inputs[0];
	}
	// For each of the elements in inputs (e1)
	for (i = 0; i < inputs.length; i++) {
		var e1 = inputs[i],
			others = except(inputs,i),
			e1s = e1.charAt(0),
			e1e = e1.charAt(e1.length-1);
		// Compare to each of the other elements in inputs (e2)
		for (ii = 0; ii < others.length; ii++) {
			// get the start and end of the elements to compare (e1s,e1e,e2s,e2e)
			var e2 = others[ii],
				e2s = e2.charAt(0),
				e2e = e2.charAt(e2.length-1);
			// if any of them match up (e1s == e2e || e1s == e2s || e1e == e2s || e1e = e2e)
			// Make a new array of inputs containing the joined elements (as a single element) and all other elements which might join with them
			if (e1s == e2e) {
				matches.push(addTo(except(others,ii),e2+e1));
			}
			if (e1e == e2s) {
				matches.push(addTo(except(others,ii),e1+e2));
			}
			e2 = flip(e2);
			e2s = e2.charAt(0);
			e2e = e2.charAt(e2.length-1);
			if (e1s == e2e) {
				matches.push(addTo(except(others,ii),e2+e1));
			}
			if (e1e == e2s) {
				matches.push(addTo(except(others,ii),e1+e2));
			}
		}
	}

	if (matches.length < 1) {
		return false;
	}

	for (i = 0; i < matches.length; i++) {
		if (matches[i].length  === 1) {
			return matches[i][0];
		} else {
			matches[i] = a(matches[i]);
		}
	};

	for (i = 0; i < matches.length; i++) {
		if (matches[i] !== false) {
			return matches[i];
		}
	};

	return false;

	function except(list,idx)
	{
		var newList = list.slice();
		newList.splice(idx,1);
		return newList;
	}
	function flip(s) {
		var replacements = {
			'[':']',
			']':'[',
			'>':'<',
			'<':'>',
			'(':')',
			')':'(',
			'{':'}',
			'}':'{'
		}, i, a = s.split('').reverse();
		for (i = 0; i < a.length; i++) {
			if (replacements.hasOwnProperty(a[i])) {
				a[i] = replacements[a[i]];
			}
		}

		return a.join('');
	}
	function addTo(arr,newEl)
	{
		arr.unshift(newEl);
		return arr;
	}
}

Chris O'Kelly
la source
1
Vous pouvez renommer les fonctions pour économiser quelques octets. stackoverflow.com/questions/6156319/…
noɥʇʎԀʎzɐɹƆ
1
évitez .charAt dans n'importe quelle version de JavaScript. s.charAt(x)===s[x]
edc65
1

Python 3, 217 octets

from itertools import*
a='()[]{}<>'
all(any(c[-1]!=d[0]for c,d in zip(q,q[1:]))or print(''.join(q))for p in permutations(open(0))for q in product(*[(c[:-1],a[a.find(c[-2])^1]+c[-3:0:-1]+a[a.find(c[0])^1])for c in p]))

( Démo sur Ideone )

Anders Kaseorg
la source
Comment cela prend-il des informations?
R. Kap
@ R.Kap Sur stdin, un cordon par ligne.
Anders Kaseorg
Ça ne semble pas, du moins quand je l'ai couru.
R. Kap
De plus, à quelle vitesse peut-il trouver la bonne réponse (-] ]-> >-} }-) )-[ [-< <-{ {-(?
R. Kap
@ R.Kap Voir la démo sur Ideone pour un exemple de prise d'entrée et de production de sortie. (Cela peut ne pas fonctionner sous Windows, si c'est ce que vous essayez de faire?) Il s'exécute ~ instantanément sur votre scénario de test. Il y a bien sûr des cas qui prendront un temps exponentiel.
Anders Kaseorg
0

Lua, 477 octets

function r(s)return s:reverse():gsub("[()%[%]{}<>]",{["("]=")",[")"]="(",["["]="]",["]"]="[",["{"]="}",["}"]="{",["<"]=">",[">"]="<"})end
function a(c,b)for i, v in next,b do
m=c:sub(-1,-1)n=v:sub(1,1)o=r(c):sub(-1,-1)p=r(v):sub(1,1)l=table.remove(b,i)if m==n then
return a(c..v,b)elseif o==n then
return a(r(c)..v,b)elseif m==p then
return a(c..r(v),b)elseif o==p then
return a(r(c)..r(v),b)end
table.insert(b,i,l)end
return#b>0 and""or c
end
print(a(table.remove(arg,1),arg))

Accepte les cordons comme arguments de ligne de commande

Trébuchette
la source
0

Python 3.5, 448 432 427 424 286 311 octets:

( +25 car il y avait un bug où la sortie peut être plus longue qu'elle ne devrait l'être pour certaines entrées )

def g3(z):
 B=z.split();M='i[::-1].translate({41:40,40:41,125:123,123:125,62:60,60:62,93:91,91:93})';f=B+[eval(M)for i in B if eval(M)not in B];d=[f.pop(0)]
 for h in d:
  try:[d.append([f.pop(f.index(c))for c in f if h[-1]==c[0]][0])if len(d)<len(B)else E]
  except:break
 return''.join(d)if len(d)>=len(B)else''

Fonctionne parfaitement! sauf pour les entrées de 7 valeurs ou plus. Cela prend beaucoup de temps pour ceux-ci, probablement parce qu'il doit passer par toutes ces permutations de l'entrée plus l'entrée inversée . J'essaierai de résoudre ce problème si et quand je le peux, mais pour l'instant, cela semble suffisant. Tout va bien maintenant! Si seulement je pouvais en quelque sorte utiliser ce try-exceptbloc dans la compréhension de la liste, il pourrait être un peu plus court et beaucoup plus joli. Néanmoins, il fonctionne maintenant pour tous les cas de test et, surtout, il n'utilise aucune importation! :)

Essayez-le en ligne! (Ideone) (284 octets ici)

(Astuce: Pour l'essayer, sélectionnez simplement "fork", puis entrez vos choix, séparés par des espaces , et sélectionnez "exécuter")

Explication

Fondamentalement, ce qui se passe est ...

  1. Une liste,, Best créée à partir de l'entrée en la divisant au niveau de l'espace en ses "cordons".
  2. Mest une chaîne que j'ai créée qui, lorsqu'elle est évaluée, renvoie une liste basée sur Blaquelle contient tous les cordons, mais cette fois en arrière .
  3. La liste créée à partir de Mest finalement concaténée avec Belle-même pour créer une liste f, avec toutes les orientations possibles des "cordons".
  4. Une autre liste dest créée, qui sera initialisée avec la première valeur (valeur f[0]) de f.
  5. Enfin, toutes les valeurs dans dsont itérées, et le dernier caractère de chaque valeur est comparé au premier caractère de chaque élément dans f, et lorsqu'une correspondance est trouvée, ce caractère est sauté (ou supprimé) et renvoyé de la liste f. Cela se produit jusqu'à ce que a IndexErrorsoit augmenté, ou que la longueur de la liste ddépasse Bet que a NameErrorsoit déclenché après l'appel à E, les deux étant traités, puis dle contenu de la liste est joint dans une chaîne et renvoyé tant que la longueur de la liste dest supérieure. supérieur ou égal à la longueur de la liste B. Sinon, une chaîne vide est retournée ( ''), car dn'étant pas de la même longueur que Bsignifie que tous les "cordons" de la listeB ne peut pas être réuni en un long "cordon".
R. Kap
la source
@KennyLau Qu'avez-vous changé? D'après ce que je peux voir, vous venez d'ajouter <!-- language: lang-python -->. Qu'est-ce que cela change?
R. Kap
Cela peut activer la mise en évidence de la syntaxe pour votre code.
Leaky Nun
@KennyLau Wow, c'est cool. Je me demandais comment je ferais cela sur PPCG. Maintenant je sais! Merci! :)
R. Kap