Vérificateur de “palindrome commode”

39

Si vous avez déjà essayé d’écrire du code palindromique, vous sauriez combien de crochets ont tendance à vous gêner. ()()n'est pas un palindrome, même si elle ressemble un peu comme il devrait être, tout ())(et ()(sont à la fois palindrome et à la fois très stupide regarder. Ne serait-ce pas pratique si c'était l'inverse?

Une chaîne est commodément palindromique si elle est égale à la chaîne dérivée lorsque son inverse a toutes ses parenthèses ( ()), crochets ( []) et accolades ( {}) retournés. Aucun autre caractère n'est spécial et nécessite de basculer. ( <>sont parfois jumelés mais souvent pas, ils sont donc laissés de côté.)

Votre tâche consiste à écrire, dans votre langue, un programme (prenant une entrée sur STDIN) ou une fonction (prenant un seul argument de chaîne) qui (a) donne une valeur vraie cohérente * lorsque son argument est commodément palindromique et une valeur différente, cohérente valeur autrement, et (b) est elle - même idéalement palindromique.

Par exemple, les entrées suivantes sont commodément palindromiques:

racecar
(a)(bb)(a)
void main(int argc, *char[] argv) {} (vgra []rahc* ,cgra tni)niam diov

Et ce qui suit ne sont pas:

non-palindrome
A nut for a jar of tuna?
(old [style] parens) )snerap ]elyts[ dlo(
ingirumimusnocte)etconsumimurigni

Vous ne pouvez pas vous fier à un état externe (nom de fichier spécifique, structure de répertoire, autre entrée utilisateur, accès Web, etc.) à l'exception des indicateurs interprète / compilateur.

En outre, vous ne pouvez pas utiliser "l'astuce de commentaire" pour commenter ou rendre du code inutilisé en tirant parti des fonctionnalités de commentaire de votre langue. Par exemple, tous les éléments suivants ne sont pas autorisés, car ils contiennent des parties non fonctionnelles qui peuvent être supprimées ou détruites en toute sécurité (au détriment de la perte commode-palindromique):

{some code} // {edoc emos}
{some code} NB.BN {edoc emos}
"n\" ;{edoc emos} ;"; {some code}; "\n"

Évidemment, cela ne couvrira peut-être pas tous les cas de ce genre, mais l’esprit du défi ici n’est pas d’utiliser des commentaires et du code non analysé ** pour obtenir la couleur claire, mais plutôt d’utiliser les parenthèses et parenthèses corrigées. Je te regarde, LISP, Brainfuck.

C'est un , donc le code le plus court gagne, mais toutes les longueurs de code sont les bienvenues.

* Par valeurs vraies et fausses cohérentes, je veux dire que vous pouvez renvoyer une paire de valeurs, telles que 1vrai et 0faux, ou Falsevrai et "no"faux, tant que ces valeurs sont différentes les unes des autres et qu'elles ne le sont pas. changez d'une exécution à l'autre de votre programme. Utilisez tout ce qui vous sauve des personnages.

** Ne pas confondre avec non exécuté : un code valide qui pourrait faire des choses étranges mais jamais appelé convient.

algorithmeshark
la source
Qu'en est-il des choses comme if(false){some code}ou des variables non utilisées? Sont-ils autorisés?
pastebin.com slash 0mr8spkT
@ace Si votre langue analyse ou vérifie si le code non exécuté est en accord de type ou en validité syntaxique, c'est très bien. Si cela équivaut à un commentaire parce que votre langue ne vérifie pas l'intérieur de ce bloc, il y a une erreur de syntaxe s'il le fait, ce n'est pas bien. Je pense que si vous pouvez trouver un usage valide (eslaf)fi, vous devez l’utiliser if(false).
algorithmshark
58
Il m'a fallu beaucoup trop de temps pour comprendre pourquoi ce ()()n'est pas un palindrome
David dit Rétablir Monica
Le code doit-il fonctionner avec une entrée multiligne?
Ventero
@Ventero Les retours à la ligne et les retours à la ligne sont des caractères et ils n'ont pas de paires avec lesquelles retourner, alors je dirais qu'ils comptent comme des caractères normaux.
algorithmshark

Réponses:

13

J (60)

(|.-:'())([]][{}}{'&charsub) :: (busrahc&'}{{}][[])(()':-.|)

C'est une fonction qui prend un argument:

   (|.-:'())([]][{}}{'&charsub) :: (busrahc&'}{{}][[])(()':-.|) 'ingirumimusnocte)etconsumimurigni'
0
   (|.-:'())([]][{}}{'&charsub) :: (busrahc&'}{{}][[])(()':-.|) '(a)(bb)(a)'
1

Explication:

  • f :: gexécute la fonction fsur l'entrée et renvoie le résultat s'il renvoie sans erreur. Si féchoue, il s'exécute à la gplace.

  • La fvoici (|.-:'())([]][{}}{'&charsub), qui fait le travail réel:

    • |.: sens inverse
    • -:: est égal à
    • '())([]][{}}{'&charsub: remplacement de chaque support par son support opposé
  • La gfonction is (busrahc&'}{{}][[])(()':-.|), ce qui est absurde, mais syntaxiquement valide. busrahcn'est pas défini, mais cela n'a pas d'importance, car il n'est résolu que lorsqu'il est exécuté (et il ne fonctionnera pas).
marinus
la source
Vous pouvez sauvegarder un personnage en vous transformant f :: gen g@-@f. gest équivalent au crochet à (-.|)cause des :sorties -1 et de la liste vide pour palindromique et non, respectivement.
algorithmshark
34

GolfScript, 107 91

.4:ab-1:ba=;1
%ba%{...fi@@=
c43.=;)('"([{
}])"'~?~'"([{
}])"')(;=.34c
=@@if...}%ab%
1;=ab:1-ba:4.

Les nouvelles lignes sont artistiques. fi, c43et csont noops, mais le code entier est exécuté.

Imprime -3-1-1pour des palindromes pratiques, -4-1-1sinon. Essayez-le en ligne!

Version alternative, 155 octets

Au prix de 64 octets, cela peut être amélioré sur:

0!*1{!}\;:);0:f;0:i;-1:ab;9:ba;
...=;1%ab%{....i@f@@fi@@=@.=@\)
+""'"([{}])"'~+?+~'"([{}])"'""+
(\@=.@=@@if@@f@i....}%ba%1;=...
;ab:9;ba:1-;i:0;f:0;(:;\{!}1*!0

Comme précédemment, tout le code est exécuté et chaque octet affecte la sortie.

Imprime 010pour des palindromes pratiques, -100sinon. Essayez-le en ligne!

Tests et exemples

$ base64 > palindrome.gs -d <<< LjQ6YWItMTpiYT07MSViYSV7Li4uZmlAQD1jNDMuPTspKCciKFt7fV0pIid+P34nIihbe31dKSInKSg7PS4zNGM9QEBpZi4uLn0lYWIlMTs9YWI6MS1iYTo0Lg==
$ wc -c palindrome.gs
91 palindrome.gs
$ rev palindrome.gs | tr '([{}])' ')]}{[(' | diff - palindrome.gs
$ echo -n 'r(a[c{"e"}c]a)r' | golfscript palindrome.gs
-3-1-1
$ echo -n 'totallynotapalindrome' | golfscript palindrome.gs
-4-1-1
$
$ base64 > pal.gs -d <<< MCEqMXshfVw7Oik7MDpmOzA6aTstMTphYjs5OmJhOy4uLj07MSVhYiV7Li4uLmlAZkBAZmlAQD1ALj1AXCkrIiInIihbe31dKSInfis/K34nIihbe31dKSInIiIrKFxAPS5APUBAaWZAQGZAaS4uLi59JWJhJTE7PS4uLjthYjo5O2JhOjEtO2k6MDtmOjA7KDo7XHshfTEqITA=
$ wc -c pal.gs
155 pal.gs
$ rev pal.gs | tr '([{}])' ')]}{[(' | diff - pal.gs
$ echo -n 'r(a[c{"e"}c]a)r' | golfscript pal.gs
010
$ echo -n 'totallynotapalindrome' | golfscript pal.gs
-100
$ for i in {1..154}; do head -c $i pal.gs > tmp.gs; tail -c +$[i+2] pal.gs >> tmp.gs
> [ "$(echo -n 'r(a[c{"e"}c]a)r' | golfscript tmp.gs 2> /dev/null)" = "010" ] && echo $i
> done; rm tmp.gs
1
for i in {1..154}; do head -c $i pal.gs > tmp.gs; tail -c +$[i+2] pal.gs >> tmp.gs
>  [ "$(echo -n '42' | golfscript tmp.gs 2> /dev/null)" = "-100" ] && echo $i
> done | grep '^1$'; rm tmp.gs

Comment ça marche

.             # Duplicate the input string.
4:ab-1:ba     # Save 4 in “ab” and -1 in “ba”.
=;            # Compare 4 to -1 and discard the result.
1%            # Save every element from the input string in a new string.
ab%           # Reverse the input string.
{             # For each character in the input string:
  ...         # Duplicate the character thrice.
  fi          # Variable “fi” is undefined; this does nothing.
  @@=         # Verify that the character is equal to itself; push 1.
  c43         # Variable “c43” is undefined; this does nothing.
  .=;         # Verify that 1 is equal to itself and discard the result.
  )(          # Increment and decrement the character.
  '"([{}])"'~ # Push that string and evaluate it. Result: '([{}])'
  ?           # Retrieve the character's position in '([{}])'. -1 means not found.
  ~           # Negate the position.. Examples: -1 -> 0    0 -> -1    2 -> -3
  '"([{}])"') # Push that string and pop its last element. Result: '"([{}])' 34
  (;          # Decrement 34 (the ASCII code of a double quote) and discard.
  =           # Retrieve the corresponding character.
  .34         # Duplicate the character and push 34.
  c           # Variable “c” is undefined; this does nothing.
  =           # If the character is a double quote, the index was -1.
  @@if        # In that case, replace the double quote with the original character.
  ...         # Duplicate the new character thrice.
}%            #
ab%           # Save every fourth element in a new string to discard dummy values.
1;            # Push 1 and discard.
=             # Push 1 if the modified string matches the original, 0 otherwise.
ab:1-         # Save 4 in “1” and subtract.
ba:4.         # Save -1 in “4” and duplicate.

0!*           # Pop and push the input string.
1{!}\;:);     # Make “)” an alias for “!”.
0:f;0:i;      # Variables.
-1:ab;9:ba;   # Moar variables.
...=;         # Duplicate the input string.
1%ab%         # Reverse the copy.
{             # For each character in the input string:
  ....        # Duplicate the character four times.
  i@          # Push 0 and rotate a string copy on top of it.
  f@@fi@@     # Push 0 and rotate 0 on top of it.
  =@          # Push 1 and rotate a string copy on top of it.
  .=@         # Push 1 and rotate 1 on top of it.
  \)+         # Negate a 1 and add. Result: 1
  ""          # Push that string.
  '"([{}])"'  # Push that string.
   ~+         # Evaluate the second string and concatenate. Result: '([{}])'
   ?          # Retrieve the characters position in '([{}])'. -1 means not found.
   +~         # Add 1 to the position and negate. Ex.: -1 -> -1 | 0 -> -2 | 1 -> -3
  '"([{}])"'  # Push that string.
  ""          # Push that string.
  +           # Concatenate. Result: '"([{}])"' 
  (\          # Pop the first double quote and swap it with the rest of the string.
  @=.         # Retrieve the corresponding character and duplicate it.
  @=          # If the character is a double quote, the index was -1.
  @@if        # In that case, replace the double quote with the original character.
  @@          # Rotate the modified character to the bottom.
  f@i....     # Push dummy values.
  }%          #
  ba%         # Save every ninth element in a new string to discard dummy values.
  1;          # Push 1 and discard.
  =           # Push 1 if the modified string matches the original, 0 otherwise.
  ...;        # Duplicate thrice and discard the last copy.
  ab:9;ba:1-; # Variables.
  i:0;f:0;    # Moar variables.
  (:;\        # Negate, override “;” and swap.
  {!}1*!0     # Negate twice and push 0.
Dennis
la source
13

Ruby, 110

(z=gets;r=z.tr *["([{}])",")]}{[("];p *z==r.reverse;1)||(1;esrever.r==z* p;[")]}{[(","([{}])"]* rt.z=r;steg=z)

Imprime truesi l'entrée est un palindrome pratique et falsesi ce n'est pas le cas. Notez que cette solution suppose que l'entrée n'est pas terminée par une nouvelle ligne. Testez-la donc avec echo -n:

echo -n '(a)(bb)(a)' | ruby convpal.rb
true

echo -n '(a)(bb()a(' | ruby convpal.rb
false

# note that for this to work, the file must not contain a newline
# to remove a trailing newline, pipe it through tr -d $'\n'
cat convpal.rb | ruby convpal.rb
true

Ceci est un port assez simple de ma réponse à Palindromic Palindrome Checker (et pas vraiment joué au golf jusqu'à présent). L'astuce principale utilisée est que la première expression entre parenthèses est toujours renvoyée 1. La seconde partie de l'expression booléenne n'est donc jamais évaluée (mais analysée).

La seule difficulté à adapter cela consistait à trouver comment ajouter l'appel z.trafin que son "retour commode" soit également valide sur le plan syntaxique - mais je pourrais simplement utiliser le même truc que celui que j'avais déjà utilisé:, *qui est analysé comme Opérateur Splat (utiliser le contenu du tableau comme paramètres de fonction) et comme opérateur de multiplication (ou de répétition) du tableau dans la seconde moitié.

Ruby, 157 297, tout code exécuté

w=tsoh=gets p
o=rt=esrever=Gem
q=tsoh.tr *["([{}])",")]}{[("]
q==esrever.host=w=tsoh.reverse==q
[")]}{[(","([{}])"]* rt.host=q
meG=reverse=tr=o
p steg=host=w

Cette version (légèrement plus longue) exécute tout le code et toutes les lignes sauf deux affectent la sortie imprimée à la dernière ligne - mais toutes les lignes sont analysées et exécutées sans erreur. Cette version interprète les retours à la ligne de fond comme partie intégrante de l’entrée. echo -nVous devez donc les tester ou ajouter une nouvelle ligne à vos entrées. Il imprime truesi l'entrée est un palindrome commode, et falsesinon.

Explication

# Read the input by calling gets(nil), which is achieved by passing the return
# value of a call to Kernel#p (which returns nil if no argument is supplied) to
# gets.
w=tsoh=gets p
# Assign the global Gem module to three variables.
# The variable names are the reversed names of methods we have to call later.
# This doesn't necessarily have to be the Gem module, any global module/variable
# (or class that allows object creation through a call to the module itself,
# e.g. Hash or GC) with a writable property would do, but Gem#host was
# the shortest one I could find. This is necessary because Ruby doesn't
# allow setting previously undefined properties through the dot syntax.
o=rt=esrever=Gem
# Replace the parentheses with the corresponding flipped one.
# sserts is the reverse of the property name we're going to use later.
q=tsoh.tr *["([{}])",")]}{[("]
# Do the convinient palindrome check and assign its result to a few variables
# and Gem's host property.
q==esrever.host=w=tsoh.reverse==q
# Here, the * is parsed as array join operator.
[")]}{[(","([{}])"]* rt.host=q
# Nothing special here.
meG=reverse=tr=o
# Print the result of the palindrome check, which was stored in w.
p steg=host=w
Ventero
la source
9

GolfScript, 61 caractères

OK, voici une solution de base dans GolfScript. Je suis sûr que cela pourrait encore être amélioré:

{.-1%{"([{}])".2$?~@[.]@+=}%=}~{=%{=+@[.]@~?$2."([{}])"}%1-.}

Comme d'habitude pour GolfScript, ce programme lit son entrée depuis stdin. Il produit:

1{=%{=+@[.]@~?$2."([{}])"}%1-.}

si l'entrée est un palindrome commode, tel que défini dans le défi ci-dessus, et:

0{=%{=+@[.]@~?$2."([{}])"}%1-.}

si ce n'est pas le cas.

Explication: Ce programme s'appuie fortement sur la décision selon laquelle le code non exécuté est correct, à condition qu'il soit analysé. Il se compose de deux blocs de code, délimités par des accolades ( { }), qui sont des images inversées l’une de l’autre.

Le premier bloc de code est exécuté de la manière ~suivante et vérifie si l'entrée est un palindrome convenable, en indiquant 1si c'est le 0cas ou non. Le deuxième bloc de code n'est pas exécuté et reste donc simplement sur la pile jusqu'à la fin du programme et jusqu'à ce que tout ce qui est sur la pile soit automatiquement codifié et imprimé par l'interpréteur GolfScript.

Il convient de noter que l’interprète GolfScript effectue très peu de vérifications de syntaxe au moment de l’analyse (ou jamais, d'ailleurs); un littéral de bloc de code GolfScript peut contenir presque tout, même s'il risque de se bloquer lorsqu'il est exécuté. Néanmoins, quelques erreurs de syntaxe, telles que des littéraux de chaîne non terminés, génèrent une erreur même dans du code non exécuté, donc je crois que cette solution relève (à peine) des règles.

Ps. En examinant le code réellement exécuté, il contient quelques éléments palindromiques pratiques, tels que @[.]@le littéral chaîne "([{}])"et même la boucle %{ ... }%. Ceci offre la suggestion alléchante qu’une solution GolfScript "intrinsèquement palindromique", dans laquelle le programme palindrome complet serait exécuté et fonctionnel, serait en réalité possible. Comme je n’ai pas encore réussi à en produire un, j’offre par la présente une prime de +100 représentants à la première personne qui parvient à en créer un!

Ilmari Karonen
la source
3
attendez, votre code est un palindrome lui-même? : O
Fabricio
Je suis enclin à considérer cette solution plutôt comme une "n\";X;";X;"\n"sorte de commentaire, mais je vous donnerai le bénéfice du doute. Cependant, je cherchais avant tout de telles solutions "intrinsèquement palindromiques", ou du moins, celles où la non-exécution des blocs était un peu plus sournoise.
algorithmshark
Ma réponse a un noop (variable non définie) et quelques parties qui ne font rien (par exemple, 1;). Cela compte-t-il toujours comme totalement fonctionnel?
Dennis
@ Dennis: Oui, je pense que oui. Félicitations, c'est certainement assez impressionnant. La question semble être suffisamment nouvelle pour que je ne puisse pas encore poster la prime, mais vous l'aurez dans quelques jours.
Ilmari Karonen
1
format de sortie marge de manœuvre abuuuse :-)
John Dvorak
4

JavaScript (ES6), 245 octets

Je voulais une réponse JS pouvant être exécutée dans le navigateur, la voici donc.

eurt=>eurt==(("",eurt))["split"||"nioj"]("")["map"||"esrever"](x=>({'{':'}','}':'{','[':']',']':'[','(':')',')':'('})[x]||x||[x]({')':'(','(':')',']':'[','[':']','}':'{','{':'}'})>=x)["reverse"||"pam"]("")["join"||"tilps"]((true,""))==true>=true

En supprimant tout le code qui n'est jamais réellement exécuté, nous obtenons ceci:

eurt=>eurt==(("",eurt))["split"||"nioj"]("")["map"||"esrever"](x=>({'{':'}','}':'{','[':']',']':'[','(':')',')':'('})[x]||x||[x]({')':'(','(':')',']':'[','[':']','}':'{','{':'}'})>=x)["reverse"||"pam"]("")["join"||"tilps"]((true,""))==true>=true
eurt=>eurt==(("",eurt))["split"        ]("")["map"           ](x=>({'{':'}','}':'{','[':']',']':'[','(':')',')':'('})[x]||x                                                           )["reverse"       ]("")["join"         ]((true,""))==true>=true

Ce qui peut être simplifié à ceci:

eurt=>eurt==eurt.split("").map(x=>({'{':'}','}':'{','[':']',']':'[','(':')',')':'('})[x]||x).reverse("").join("")
ETHproductions
la source
Vous pouvez économiser environ 60 octets en utilisant n1 / 1n au lieu de true / eurt, des virgules à certains endroits au lieu de || et en bidouillant le commutateur de support: n1=>n1==(('',n1))['nioj','split']``['esrever','map'](c=>`()[]{}`[`()[]{}`['indexOf'](c)^1]||c||[1^(c)['fOxedni']`{}[]()`]`{}[]()`>=c)['pam','reverse']``['tilps','join']((1n,''))==1n>=1n(185 octets)
Yair Rand
3

Javascript (ES6) 288

S'exécute dans le shell de ligne de commande Spidermonkey . Lit une seule ligne à partir de STDIN et en sort trueou falseselon que l’entrée est un palindrome commode.

((print)((eval)('r=readline()')==([0]['map']['call'](r,x=>({'{':'}','}':'{','[':']',']':'[','(':')',')':'('})[x]||x)['reverse']()['join']('')))&&((('')['nioj']()['esrever'](x||[x]({')':'(','(':')',']':'[','[':']','}':'{','{':'}'})>=x,r)['llac']['pam'][0])==('()enildaer=r')(lave))(tnirp))

Ce code est syntaxiquement valide, mais tout ce qui suit &&n'est pas exécuté, car la printfonction renvoie une valeur de falsey.

Vous pouvez exécuter ce code dans la console de Firefox en exécutant d'abord ce shim pour émuler les fonctions readlineet print. Éditez l'entrée à l'intérieur readlinesi nécessaire:

readline = function(){ 
    return "void main(int argc, *char[] argv) {} (vgra []rahc* ,cgra tni)niam diov"; 
}, print = console.log.bind(console);

Et voici un exemple rapide de la sortie:

exemple de ligne de commande

Nderscore
la source
Profitant de &&était vraiment intelligent, je vous félicite (mais cela semble un peu tricheur)
MayorMonty
2

05AB1E, 35 octets

"{[()]}"DRr‡`rJ¹Q,Q¹Jr`‡rRD"{[()]}"

Essayez-le en ligne!

Explication:

                     # Implicit input
 "{[()]}"            # Push "{[()]}" onto the stack
         DR          # Pushes a reversed copy onto the stack
           r         # Reverse the order of the stack
            ‡        # Transliterate
             `       # Flatten array on stack
              r      # Reverse order of stack
               J     # Join stack
                ¹Q   # Check equality with first input
                  ,  # Print
                     # Everything after is still syntactically correct, but just does not print anything.
Oliver Ni
la source
Je ne pense pas que cela va aider puisque la réponse est invalide mais au lieu de "()[]{}"vous pouvez le fairežu„<>-
acrolith
@daHugLenny Il est valide maintenant
Oliver Ni
Le reste du programme est-il qanalysé au moins après sa validité syntaxique? Sinon, je considérerais que cela revient à commenter la seconde moitié du code.
algorithmshark
@algorithmshark corrigé.
Oliver Ni
1

CJam, 38 octets

Q~"=re%W_@%W_q"`{[()]}`"q_W%@_W%er="~Q

Imprime "=re%W_@%W_q"1si la saisie est palindromique ou "=re%W_@%W_q"0non.

Essayez-le en ligne dans l' interprète CJam .

Comment ça marche

Q~                                     e# Evaluate an empty string.
  "=re%W_@%W_q"                        e# Push that string.
               `                       e# Inspect. Pushes "\"=re%W_@%W_q\"".
                {[()]}                 e# Push that block.
                      `                e# Inspect. Pushes "{[()]}".
                       "           "~  e# Push and evaluate.
                        q              e# Read from STDIN.
                         _W%           e# Push a reversed copy.
                            @          e# Rotate "{[()]}" on top of the stack.
                             _W%       e# Push a reversed copy.
                                er     e# Perform transliteration.
                                  =    e# Compare to the input string.
                                     Q e# Push an empty string.

Après avoir exécuté le programme, CJam imprime automatiquement les trois éléments de la pile: la chaîne inspectée, le booléen de la comparaison de chaîne et la chaîne vide.

Dennis
la source
0

Perl, 83 + 2 = 85 octets

Courir avec -nl

say$_~~reverse y-"({[]})"-")}][{("-r;exit;tixe;r-")}][{("-"({[]})"-y esrever~~_$yas

Le code se ferme après avoir imprimé la véracité de l'entrée. Tout ce qui est interprété après le point-virgule est interprété (et se bloque lorsque le script atteint ce point si ce n’est pas le cas exit), mais n’est pas exécuté. Si je ne tenais pas exit;tixe;compte du code, le résultat serait toujours imprimé correctement avant le crash.

Gabriel Benamy
la source