Inverser la polarité

12

Le but de ce challenge est d'écrire un programme qui remplit les conditions suivantes:

  • Le programme n'est ni palindromique, ni essentiellement palindromique (ce qui signifie qu'il est possible de supprimer des caractères pour en faire un palindrome sans modifier les effets du programme).

  • Le programme n'est pas une involution (ce qui signifie qu'il ne produit pas son entrée d'origine lorsqu'il est exécuté sur sa sortie)

  • Le programme à polarité inversée est l'inverse du programme normal; ainsi, lorsque le programme inversé est exécuté sur la sortie du programme normal, il renvoie l'entrée d'origine.

Que signifie polarité inversée ? Eh bien, cela diffère entre les langues.

  • Pour la plupart des non-esolangs, cela signifie également inverser l'ordre des sous-opérations en une seule opération, inverser l'ordre des arguments et inverser le contenu des listes / tableaux / tuples / dictionnaires / piles / files d'attente / etc codés en dur, ainsi comme inversant l'ordre des blocs de code et des lignes autonomes (mais pas les lignes à l'intérieur des blocs)

Exemples:

Haskell : x`mod`y-> y`mod`x; zipWith ((*3).(+)) [1,2,3] [4,5,6]->zipWith ((+).(*3)) [6,5,4] [3,2,1]

Python : 2**3-> 3**2; for x,y in [(1,2),(3,4),(5,6)]->for y,x in [(6,5),(4,3),(2,1)]

  • Pour les langues qui ont des fonctions à 1 caractère (comme Pyth, APL), inversez simplement la chaîne d'instructions

  • Pour les esolangs à une dimension comme BF, inversez les instructions ou échangez la polarité; les échanges de polarité sont []-> {}, +-> -, --> +, >-> <, <-> >, .-> ,et ,-> .(mais pas les deux)

  • Pour les esolangs bidimensionnels comme Befunge, vous pouvez soit effectuer une réflexion sur les axes x ou y ou une diagonale, faire une rotation de 180 degrés, soit combiner une réflexion et une rotation

Les opérations commutatives sont autorisées, mais celles palindromiques ne le sont pas: 2*xc'est bien, mais x+xc'est mauvais. La définition d'une inversion de polarité est assez vague, mais utilisez votre jugement sur ce qui a du sens; le but n'est pas de trouver la faille la plus intelligente, mais de trouver la solution la plus intelligente.

Il s'agit d'un concours de popularité, donc une échappatoire très intelligente peut être populaire, mais essayez de rester dans l'esprit de ce défi. Le gagnant sera annoncé une fois qu'il y aura au moins 10 solutions avec au moins 1 vote positif, et qu'il y aura au moins une solution avec plus de votes positifs qu'il n'y a de soumissions avec au moins 1 vote positif; ou en 1 mois, selon la première éventualité. C'est mon premier défi, alors essayez d'être juste et donnez-moi des commentaires constructifs, mais faites-moi également savoir s'il s'agit d'un défi déraisonnable ou s'il est en quelque sorte mal catégorisé ou ambigu. Si vous avez des questions sur une langue qui ne correspond à aucun des pigeonniers que j'ai exposés ici, commentez et je me plierai à la volonté de la communauté s'il y a un tollé fort pour une clarification particulière ou un changement de règle.

MISE À JOUR

Cela fait exactement 1 mois depuis le début de ce concours (il m'est arrivé de le vérifier par hasard, ne sachant pas que j'étais en fait à l'heure). Comme il s'agit d'un concours de popularité, le gagnant (par un glissement de terrain) est Pietu1998-Befunge . Même si les composants du bas (l'inverseur de texte et l'alphabet inversé) sont tous deux des involutions, l'encodeur / décodeur ne le sont pas, donc il n'y a pas de problème là-bas. Points bonus (dans mon esprit) pour avoir réussi à écrire "BEFUNGE" au milieu. J'ai personnellement aimé la nouveauté de la solution Theseus de Zgarb , car la langue a l'air cool (si elle est restreinte). Merci à tous pour votre participation, et bien que le gagnant ait été choisi, je laisse ce concours complètement ouvert et je souhaite la bienvenue aux candidatures futures.

archaephyrryx
la source
1
Que voulez-vous dire par le programme à polarité inversée est l' inverse du programme normal? La sortie diffère-t-elle d'une manière ou d'une autre?
Sp3000
Il effectue l'opération inverse; lorsque le programme inversé est exécuté sur la sortie du programme normal, il renvoie l'entrée d'origine.
archaephyrryx
Désolé pour l'erreur; Je n'en avais jamais entendu parler auparavant, et cela me semblait un peu grotesque, donc je devais supposer que c'était un Esolang; Je vais changer ça.
archaephyrryx
1
Juste quelque chose qui devrait probablement être spécifié - est ()palindromique? Techniquement, c'est l'inverse )(.
Sp3000
1
Dans l'exemple Haskell, pourquoi l'argument de fonction n'est-il pas mélangé à la fin? Les inversions sont-elles choisies de manière à préserver la sécurité du type? Sommes-nous autorisés à choisir certains détails de l'opération d'inversion de polarité?
John Dvorak

Réponses:

41

Befunge

Whoa, c'était un travail, même avec l' éditeur que j'ai fait pour ce défi. Voici ce que j'ai eu, un joli bloc 11x12:

v$,g6<6g,$v
v,$ _^_ $,v
1W>v\B\v>L1
~T+:1E1:-O~
+F00-F-02L+
>:|6gUg6|:>
{a@>^N^>@z`
>1+|@G$| +>
:^9< E<  ^1
~>7^@_,#:>:
 xD>65 ^=P~
v,-\+**<  v

Il fait deux ou trois choses, malheureusement uniquement pour les lettres minuscules.

Ce qu'il fait

Lorsqu'il est exécuté normalement, il effectue un chiffrement César sur l'entrée.

abcxyz      -> bcdyza
exampletext -> fybnqmfufyu

Lorsqu'elle est retournée horizontalement, elle inverse ledit chiffre. C'est l'exigence du défi, mais cela ne s'arrête pas là.

bcdyza      -> abcxyz
fybnqmfufyu -> exampletext

Lorsqu'il est retourné verticalement , il chiffre les entrées avec un alphabet inversé. Cela peut être considéré comme l'approche opposée au chiffre de César.

abcxyz      -> zyxcba
exampletext -> vcznkovgvcg

Enfin, lorsqu'il pivote à 180 degrés, il inverse la saisie. J'ai le sentiment que cela doit être l'inverse de quelque chose (indice: l'entrée).

abcxyz      -> zyxcba
exampletext -> txetelpmaxe

Comment ça fonctionne

Le bloc se compose essentiellement de quatre algorithmes semi-chevauchants.

Encodeur de chiffrement César

v$,g6<
v,$ _^
1 >v\
~ +:1
+ 00-
>:|6g
{a@>^

Décodeur de chiffrement César (retourné horizontalement)

v$,g6<
v,$ _^
1 >v\
~ -:1
+ 20-
>:|6g
`z@>^

Chiffre alphabétique inversé (retourné verticalement)

v,-\+**<
   >65 ^
~>7^
:^9<
>1+|@
   >^

Inverseur de texte (pivoté à 180 degrés)

v  <
~      
:>:#,_@
1^  <
>+ |$
   >^
PurkkaKoodari
la source
2
Je suppose que Befunge a un léger avantage ici, car vous pouvez toujours simplement utiliser le quadrant supérieur gauche et ignorer complètement ce qui se trouve dans le reste du code. Beau travail quand même!
Martin Ender
1
Hou la la! Je dois voter contre, même si cela signifie que je descends à la troisième place.
Level River St
18

Brainfuck, 5

,+.-,

Peut-être pour la première fois, Brainfuck produit une réponse compétitive sur la longueur du code. Dommage que ce ne soit pas une question de code-golf.

Entre un octet (caractère), l'incrémente et sort le résultat. La virgule à la fin attend une autre entrée qui, si elle est donnée, sera ignorée. Il n'y a rien dans la spécification sur la terminaison appropriée: -) *

* (ou de faire quelque chose d'utile avec tout le code dans les deux sens)

Résultats typiques (le deuxième caractère s'il est donné est ignoré).

Transférer: B->C

Inverse: B-> Aou C->B

Level River St
la source
11

Marbelous

En voici un simple pour commencer. Il lit un caractère dans STDIN, l'incrémente et l'imprime.

--
]]
00
]]
++

Si nous le faisons pivoter de 180 ° (sans permuter les crochets), ou si nous le reflétons sur l'axe des x, nous obtenons

++
]]
00
]]
--

qui lit un octet de STDIN et le décrémente.

Vous pouvez le tester ici .

Je pourrais examiner des programmes Marbelous plus compliqués, mais je suis sûr que es1024 me battra. ;)

Explication

Il 00s'agit d'une bille de valeur 0 (arbitraire). Les ]]appareils lisent un octet de STDIN - c'est-à-dire que si une bille tombe à travers eux, la valeur de la bille est changée en octet de lecture. Les appareils ++et --incrémentent ou décrémentent simplement la valeur d'une bille (mod 256) et la laissent passer. Lorsqu'une bille tombe du plateau, l'octet est écrit dans STDOUT.

Par conséquent, les deux appareils en haut sont simplement ignorés car le flux de contrôle ne les atteint jamais.

Martin Ender
la source
Alternativement, vous pouvez remplacer vos trois rangées du milieu par un seul périphérique d'entrée.
overactor
@overactor Ou voulez-vous dire }0et l'utiliser comme sous-tableau?
Martin Ender
}0comme entrée de ligne de commande pour être précis.
suracteur
5

Marbelous

Cette carte prend un argument ( x) et retourne (101 * x) mod 256.

.. @5 .. }0 }0 @1 .. @0 .. @2 .. 
.. /\ Dp << \\ .. &0 >0 &1 .. .. 
!! @3 .. << }0 .. \/ -- \/ .. }0 
@4 .. .. &0 @1 /\ &0 65 &1 /\ @2 
/\ Dp .. @4 .. .. @3 @0 @5 !! \\

La mise en miroir des cellules le long de l'axe des y se traduira par une carte qui prend un argument ( y) et renvoie (101 * y + 8 * y) mod 256, qui est l'inverse de la première carte.

.. @2 .. @0 .. @1 }0 }0 .. @5 ..
.. .. &1 >0 &0 .. \\ << Dp /\ ..
}0 .. \/ -- \/ .. }0 << .. @3 !!
@2 /\ &1 65 &0 /\ @1 &0 .. .. @4
\\ !! @5 @0 @3 .. .. @4 .. Dp /\

Testez ceci ici . Les tableaux cylindriques et les bibliothèques Inclure doivent tous deux être vérifiés.

Exemple d'entrée / sortie :

Original Board:      Mirrored Board:
Input   Output       Input    Output
025     221          221      025
042     146          146      042
226     042          042      226

Veuillez noter que Marbelous ne permet que le passage des entiers positifs comme arguments, et ces entiers sont passés dans le programme modulo 256 par l'interpréteur.

101a été choisi pour deux raisons: il s'agit d'un nombre premier (et chaque entrée possible dans ce programme entraîne une sortie unique), et l'opération inverse impliquée 109, qui est à une distance pratique de 8 101.

Brève explication

La colonne contenant les cellules (de haut en bas) @0 >0 -- 65 @0fonctionne de la même manière dans les deux tableaux et boucle plusieurs 101fois avant de se diriger vers la droite. De chaque côté de la >0branche se trouve un synchroniseur différent; lequel est choisi dépend de la mise en miroir ou non de la carte.

De chaque côté, en synchronisation avec la boucle centrale, l'entrée est sommée à plusieurs reprises, obtenant ainsi 101*x mod 256. Sur la carte inversée, deux copies de l'entrée sont également décalées deux fois vers la gauche ( input * 4), puis additionnées et laissées dans un synchroniseur.

Une fois la boucle centrale terminée, les billes résumées sont envoyées pour l'impression, qui se trouve sur le côté du plateau (à gauche pour le plateau d'origine, à droite pour le miroir). Après l'impression, une !!cellule est atteinte, terminant la carte. Notez que la boucle qui a donné 101 * xcontinue de fonctionner d'elle-même jusqu'à ce que la carte soit terminée.

Dp imprime simplement le résultat sous forme de nombre décimal.

es1024
la source
5

Thésée

Cela peut être considéré comme une échappatoire, mais j'aime la langue, alors voici. Ce programme définit une fonction fsur les nombres naturels qui mappe 3n à 3n + 1 , 3n + 1 à 3n + 2 et 3n + 2 à 3n , pour chaque n .

data Num = Zero | Succ Num

iso f :: Num <-> Num
  | n                          <-> iter $ Zero, n
  | iter $ m, Succ Succ Succ n <-> iter $ Succ m, n
  | iter $ m, Succ Succ Zero   <-> back $ m, Zero
  | iter $ m, Succ Zero        <-> back $ m, Succ Succ Zero
  | iter $ m, Zero             <-> back $ m, Succ Zero
  | back $ Succ m, n           <-> back $ m, Succ Succ Succ n
  | back $ Zero, n             <-> n
  where iter :: Num * Num
        back :: Num * Num

Theseus est un langage réversible avec une syntaxe de type Haskell, où chaque fonction est inversible (actualisant les problèmes de non-terminaison). Il est hautement expérimental et conçu à des fins de recherche. Le code ci-dessus définit un type de données pour les nombres naturels et la fonction f. Étant donné un numéro d'entrée, vous le faites correspondre sur le côté gauche (il correspond toujours n). Ensuite, vous regardez le motif à droite. Si ce motif a une étiquette (iciiter), vous procédez à la mise en correspondance de motifs sur le côté gauche et vous prenez à nouveau la valeur correspondante sur le côté droit. Cela se répète jusqu'à ce que vous ayez une valeur sans étiquette à droite, et c'est votre sortie. Les motifs à gauche et à droite doivent être exhaustifs et non superposés (séparément pour chaque étiquette). Maintenant, pour "inverser la polarité" de f, je fais ce qui suit.

  • Échangez les deux valeurs de chaque étiquette. Cela ne change pas la sémantique de f.
  • Échangez les côtés droit et gauche dans le corps de fonction. Ceci définit la fonction inverse de f by design .

Le résultat:

iso f :: Num <-> Num
  | iter $ n, Zero             <-> n
  | iter $ n, Succ m           <-> iter $ Succ Succ Succ n, m
  | back $ Zero, m             <-> iter $ Succ Succ Zero, m
  | back $ Succ Succ Zero, m   <-> iter $ Succ Zero, m
  | back $ Succ Zero, m        <-> iter $ Zero, m
  | back $ Succ Succ Succ n, m <-> back $ n, Succ m
  | n                          <-> back $ n, Zero
  where iter :: Num * Num
        back :: Num * Num
Zgarb
la source
3

tr

a b

Exemple:

$ echo "apple" | tr a b
bpple
$ echo "bpple" | tr b a
apple

Seul un vrai inverse sur le domaine des chaînes qui n'inclut pas à la fois «a» et «b».

histocrate
la source
Vous devez en fait restreindre le domaine un peu plus que cela. Par exemple, si vous commencez par "bog", votre programme et son inverse donnent "bog" -> "bog" -> "aog". Donc, toute chaîne contenant «b» est un problème (ou contenant «a», si vous appliquez d'abord le programme inverse).
user19057
Vous pouvez utiliser tr abc bcaavec la version à polarité inversée tr acb cba.
Christian Sievers
2

Une autre réponse Marbelous

La droite d'origine décale l'entrée de ligne de commande (une valeur de 8 bits), en ajoutant une première si un 1 est perdu par décalage. ( 0000 0001 -> 1000 0000)

{0 ..
~~ ..
>> {0
-2 =0
.. ^0
\/ }0
}0 Sb
<< ..
\\ ..
:Sb
// ..
Sb >>
}0 ..
^7 }0
{0 \/

Faire pivoter cette carte de 180 ° (mais en laissant le contenu de chaque cellule identique) Modifie le programme de sorte qu'il laisse des décalages ( 1000 0000 -> 0000 0001)

\/ {0
}0 ^7
.. }0
>> Sb
.. //
:Sb
.. \\
.. <<
Sb }0
}0 \/
^0 ..
=0 -2
{0 >>
.. ~~
.. {0

Vous pouvez le tester ici . (vous devrez activer "Afficher la sortie sous forme de nombres décimaux")

Explication

Les deux programmes se composent de deux cartes, la carte principale (qui obtient l'entrée de ligne de commande) et Sb. Jetons un coup d'œil aux deux versions de la carte principale, en ne regardant que les cellules qui peuvent être atteintes dans leur orientation respective (car les billes ne peuvent généralement pas aller vers le haut et les périphériques d'entrée ne sont pas en haut):

original:      flipped:
   }0          }0
}0 Sb          .. }0
<< ..          >> Sb
\\ ..          .. //

Ce sont des conseils assez simples, les deux prennent deux copies de l'entrée (qui prennent la place des }0cellules. Les aliments d' origine une version dans un dispositif de décalage vers la gauche <<la version basculées met dans un dispositif de décalage vers la droite >>Elles permettent d' effectuer un bitshift mais malheureusement défausse tout C'est là que les Sbcartes entrent en jeu, elles vérifient si le décalage de bits de la valeur qu'elles entraînent entraînera la perte d'un bit et retournera une valeur à ajouter au résultat pour contrer le bit perdu.

Voici la partie pertinente de la Sbcarte d' origine pour le programme d'origine:

}0
^7
{0

Celui-ci est incroyablement simple, `^ 7 'vérifie la valeur du bit le plus significatif. Si celui-ci vaut 1, effectuer un décalage à gauche entraînerait la perte de ce bit. Cette carte délivre donc la valeur de ce bit sous la forme d'une valeur de 8 bits à ajouter au résultat du décalage de bits.

Pour la version inversée, Sbil faut regarder le bit le moins significatif et revenir 128ou 0, c'est un peu plus compliqué:

}0
^0 ..
=0 -2
{0 >>
.. ~~
.. {0

Si le bit le moins significatif (tel que testé par ^0) est 0, il renvoie simplement 0. S'il est égal à un, il ^0sortira 1. Cela échouera au test d'égalité avec 0 =0et sera donc poussé vers la droite. Nous soustrayons ensuite 2 -2pour obtenir 255, décalage >>à gauche pour obtenir 127 et effectuons un binaire ~~pour ne pas obtenir 128 (nous pourrions également simplement en ajouter un ++pour obtenir 128, mais où est le plaisir?)

suracteur
la source