Dama "Comodo palindromo"


39

Se non avessi mai provato a scrivere un codice palindromico prima, sapresti quante parentesi tendono ad ostacolarti. ()()non è un palindromo, anche se sembra che dovrebbe essere, mentre ())(e ()(sono entrambi palindromici ed entrambi molto stupidi. Non sarebbe conveniente se fosse il contrario?

Una stringa è convenientemente palindromica se è uguale alla stringa derivata quando al suo rovescio sono capovolte tutte le parentesi ( ()), parentesi ( []) e parentesi graffe ( {}). Nessun altro personaggio è speciale e richiede il lancio. (a <>volte sono accoppiati ma spesso non così vengono esclusi).

Il tuo compito è quello di scrivere, nella tua lingua, un programma (prendendo input su STDIN) o una funzione (prendendo un singolo argomento stringa) che (a) dia un valore vero coerente * quando il suo argomento è convenientemente palindromico e un falso diverso, coerente altrimenti, e (b) è di per convenientemente palindromico.

Ad esempio, i seguenti input sono comodamente palindromici:

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

E i seguenti non sono:

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

Non è possibile fare affidamento su alcuno stato esterno (nome file specifico, struttura di directory, input di altri utenti, accesso Web, ecc.) Ad eccezione dei flag di interprete / compilatore.

Inoltre, non è possibile utilizzare "il trucco dei commenti" in cui commentare o rendere inutilizzato un pezzo di codice sfruttando le funzionalità di commento della propria lingua. Ad esempio, non sono consentiti tutti i seguenti elementi, poiché contengono parti non funzionali che possono essere rimosse o distrutte in modo sicuro (a scapito della perdita della palindromicità):

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

Ovviamente questo potrebbe non coprire tutti questi casi, ma lo spirito della sfida qui non è quello di usare commenti e codice ** non analizzato per ottenere la palindrosità, facendo invece uso delle parentesi e parentesi corrette. Ti sto guardando, LISP, Brainfuck.

Questo è un , quindi vince il codice più corto, ma sono gradite tutte le lunghezze di codice.

* Per valori reali e falsi coerenti, intendo che è possibile restituire uno di una coppia di valori, come 1true e 0false, oppure Falsetrue e "no"false, purché questi valori siano diversi l'uno dall'altro e non passa da un programma all'altro. Usa qualunque cosa ti salvi i personaggi.

** Da non confondere con non eseguito : codice valido e che può fare cose strane ma mai chiamato va bene.


Che dire di cose come if(false){some code}o variabili inutilizzate? Sono ammessi?
pastebin.com slash 0mr8spkT

@ace Se la tua lingua analizza o controlla in qualche modo il codice non eseguito per l'accordo di tipo o la validità sintattica, va bene. Se equivale a un commento perché la tua lingua non controlla l'interno di quel blocco, quando genererebbe un errore di sintassi, non va bene. Penso che se riesci a trovare un uso valido per (eslaf)fi, puoi usarlo if(false).
algoritmo

58
Mi ci è voluto troppo tempo per capire perché ()()non è un palindromo
David dice Reinstate Monica

Il codice deve funzionare con input multilinea?
Ventero,

@Ventero Newline e ritorni a capo sono personaggi e non hanno coppie da invertire, quindi direi che contano come personaggi normali.
algoritmo

Risposte:


13

J (60)

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

Questa è una funzione che accetta un argomento:

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

Spiegazione:

  • f :: gesegue la funzione fsull'input e restituisce il risultato se restituisce senza errori. Se ffallisce, funziona ginvece.

  • Il fqui è (|.-:'())([]][{}}{'&charsub), che fa il vero lavoro:

    • |.: retromarcia
    • -:: è uguale a
    • '())([]][{}}{'&charsub: sostituzione di ogni staffa con la relativa staffa opposta
  • La gfunzione è (busrahc&'}{{}][[])(()':-.|), che è senza senso ma sintatticamente valida. busrahcnon è definito, ma non importa perché viene risolto solo quando viene eseguito (e non funzionerà).

Puoi salvare un personaggio trasformandolo f :: gin g@-@f. gequivale all'hook a (-.|)causa di :ciò le uscite diventano -1 e l'elenco vuoto per convenientemente palindromico e non, rispettivamente.
algoritmo

34

GolfScript, 107 91

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

Le newline sono artistiche. fi, c43E csono noops, ma viene eseguito l'intero codice.

Stampa -3-1-1per comodi palindromi, -4-1-1altrimenti. Provalo online!

Versione alternativa, 155 byte

Al costo di 64 byte, questo può essere migliorato su:

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

Come prima, l'intero codice viene eseguito e ogni singolo byte influisce sull'output.

Stampa 010per comodi palindromi, -100altrimenti. Provalo online!

Test ed esempi

$ 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

Come funziona

.             # 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.

13

Ruby, 110

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

Stampa truese l'ingresso è un comodo palindromo e falsese non lo è. Si noti che questa soluzione presuppone che l'input non sia terminato da una nuova riga, quindi testarlo con 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

Questa è una porta piuttosto semplice della mia risposta a Palindromic Palindrome Checker (e finora non ho giocato a golf). Il trucco principale utilizzato è che la prima espressione tra parentesi ritorna sempre 1, quindi la seconda metà dell'espressione booleana non viene mai valutata (ma viene analizzata).

L'unica difficoltà nell'adattare questo era capire come aggiungere la chiamata a in z.trmodo che anche il suo "comodo contrario" fosse sintatticamente valido - ma potrei semplicemente usare lo stesso trucco che ho già usato put:, *che nella prima metà viene analizzato come operatore splat (usa i contenuti dell'array come parametri di funzione) e come operatore della moltiplicazione dell'array (o ripetizione) nella seconda metà.

Ruby, 157 297, tutto il codice eseguito

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

Questa versione (leggermente più lunga) esegue tutto il codice e tutte le righe tranne due influiscono sull'output, che viene stampato nell'ultima riga, ma tutte le righe vengono analizzate ed eseguite senza errori. Questa versione interpreta qualsiasi newline finale come parte dell'input, quindi utilizzare echo -nper testarlo o anteporre l'input con una nuova riga. Stampa truese l'ingresso è un comodo palindromo, e falsealtrimenti.

Spiegazione

# 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

9

GolfScript, 61 caratteri

OK, ecco una soluzione di base in GolfScript. Sono sicuro che potrebbe essere ulteriormente migliorato:

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

Come al solito per GolfScript, questo programma legge il suo input da stdin. Emette:

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

se l'input è un comodo palindromo, come definito nella sfida precedente, e:

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

se non è.

Spiegazione: Questo programma si basa fortemente sulla sentenza secondo cui il codice non eseguito è OK, purché venga analizzato. È costituito da due blocchi di codice, delimitati da parentesi graffe ( { }), che sono immagini speculari l'una dell'altra.

Il primo blocco di codice viene eseguito dal ~seguente e controlla se l'input è un comodo palindromo, emettendo 1se lo è e 0se non lo è. Il secondo blocco di codice non viene eseguito, quindi rimane semplicemente nello stack fino a quando il programma non termina e tutto lo stack viene automaticamente stringa e stampato dall'interprete GolfScript.

Va notato che l'interprete GolfScript fa molto pochi controlli di sintassi in fase di analisi (o mai, è per questo); un letterale blocco di codice GolfScript può contenere quasi tutto, anche se potrebbe bloccarsi quando eseguito. Tuttavia, alcuni errori di sintassi, come i letterali di stringa non terminati, generano un errore anche nel codice non eseguito, quindi credo che questa soluzione (a malapena) rientri nelle regole.

Ps. Osservando il codice effettivamente eseguito, contiene alcuni elementi opportunamente palindromici come @[.]@, la stringa letterale "([{}])"e persino il ciclo %{ ... }%. Questo offre il suggerimento allettante che una soluzione GolfScript "intrinsecamente palindromica", in cui l'intero programma palindromico sarebbe eseguito e funzionale, potrebbe effettivamente essere possibile. Poiché non sono ancora riuscito a produrne uno da solo, offro una ricompensa di +100 rappresentanti alla prima persona che riesce a crearne uno!


3
aspetta, il tuo codice è un palindromo stesso? : O
Fabricio,

Sono propenso a considerare questa soluzione più simile al "n\";X;";X;"\n"tipo di commento, ma ti darò il beneficio del dubbio. Stavo davvero cercando tali soluzioni "intrinsecamente palindromiche" per iniziare, comunque, o almeno quelle in cui la non esecuzione dei blocchi era un po 'più subdola.
algoritmo

La mia risposta ha un noop (variabile non definita) e alcune parti che non ottengono nulla (ad es 1;.). Ciò conta ancora come pienamente funzionale?
Dennis,

@Dennis: Sì, penso di si. Complimenti, è sicuramente abbastanza impressionante. La domanda sembra essere abbastanza nuova da non poter ancora pubblicare la generosità, ma ce la farai tra qualche giorno.
Ilmari Karonen,

1
formato di uscita a vuoto abuuuse :-)
John Dvorak,

4

JavaScript (ES6), 245 byte

Volevo una risposta JS che potesse essere eseguita nel browser, quindi eccola qui.

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

Rimuovendo tutto il codice che non viene mai effettivamente eseguito, otteniamo questo:

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

Che può essere semplificato a questo:

eurt=>eurt==eurt.split("").map(x=>({'{':'}','}':'{','[':']',']':'[','(':')',')':'('})[x]||x).reverse("").join("")

Puoi salvare circa 60 byte usando n1 / 1n invece di true / eurt, virgole in alcuni punti anziché ||, e giocherellando con lo switcher parentesi: n1=>n1==(('',n1))['nioj','split']``['esrever','map'](c=>`()[]{}`[`()[]{}`['indexOf'](c)^1]||c||[1^(c)['fOxedni']`{}[]()`]`{}[]()`>=c)['pam','reverse']``['tilps','join']((1n,''))==1n>=1n(185 byte)
Yair Rand

3

Javascript (ES6) 288

Viene eseguito nella shell della riga di comando di Spidermonkey . Legge una sola riga da STDIN e produce trueo falsedipende dal fatto che l'ingresso sia un comodo palindromo.

((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))

Questo codice è sintatticamente valido, ma tutto ciò che segue &&non viene eseguito, poiché la printfunzione restituisce un valore false.

È possibile eseguire questo codice nella console di Firefox eseguendo prima questo shim per emulare le funzioni readlinee print. Modifica l'ingresso all'interno readlinesecondo necessità:

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

Ed ecco un breve esempio dell'output:

esempio da riga di comando


Approfittarne è &&stato davvero intelligente, ti raccomando (ma sembra un po 'economico)
MayorMonty

2

05AB1E, 35 byte

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

Provalo online!

Spiegazione:

                     # 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.

Non credo che questo aiuterà, poiché la risposta non è valida, ma al posto "()[]{}"tuo puoi farložu„<>-
acrolith,

@daHugLenny È valido ora
Oliver Ni

Il resto del programma è qalmeno analizzato per la validità sintattica? Altrimenti, considererei questo equivale a commentare la seconda metà del codice.
algoritmo

@algorithmshark Risolto.
Oliver Ni,

1

CJam, 38 byte

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

Stampa "=re%W_@%W_q"1se l'ingresso è opportunamente palindromico e "=re%W_@%W_q"0non.

Provalo online nell'interprete CJam .

Come funziona

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.

Dopo aver eseguito il programma, CJam stampa automaticamente tutti e tre gli elementi nello stack: la stringa ispezionata, il valore booleano dal confronto delle stringhe e la stringa vuota.


0

Perl, 83 + 2 = 85 byte

Corri con -nl

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

Il codice esce dopo aver stampato la veridicità dell'input. Tutto ciò che segue il punto e virgola viene interpretato (e andrebbe in crash quando lo script raggiunge quel punto se non fosse per gli exitincontri), ma non eseguito. Se avessi lasciato exit;tixe;fuori il codice, avrebbe comunque stampato correttamente il risultato prima che si arrestasse in modo anomalo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.