Atbash Self Palindromes


27

Considere la transformación de Atbash :

A|B|C|D|E|F|G|H|I|J|K|L|M
Z|Y|X|W|V|U|T|S|R|Q|P|O|N

Donde A ⇔ Z y L ⇔ O, por ejemplo, hay una propiedad interesante que comparten algunas palabras. Cuando algunas cadenas se traducen a su equivalente atbash, dicha traducción es la palabra original invertida. Yo lo denomino Atbash Auto palíndromos .

Como ejemplo, traduzcamos WIZARD :

W → D
I → R
Z → A
A → Z
R → I
D → W

El resultado es DRAZIW , que es WIZARD invertido. Por lo tanto, WIZARD es un auto-palíndromo atbash.

Objetivo Dada una cadena de caracteres ASCII imprimibles, genera o devuelve un valor verdadero si esa cadena es un palíndromo automático atbash, y un valor falsey de lo contrario. (Esto se hace a través de STDIN, el equivalente más cercano, la entrada funcional, etc. Si su idioma no puede hacer nada de esto, considere elegir un idioma diferente para codificar la entrada). Debe hacerlo sin distinción entre mayúsculas y minúsculas. Si la entrada es un palíndromo y no se ve afectada por la secuencia atbash, aún debe generar verdadero, ya que un palíndromo + en sí mismo es un palíndromo. Este es un , por lo que gana el programa más corto en bytes.

Casos de prueba

"Input" => true, false

"WIZARD" => true
"Wizard" => true // case doesn't matter
"wIzArD" => true 
"W I Z A R D" => true
"W IZ ARD" => false // the atbash of this is D RA ZIW, which is not a palindrome of W IZ ARD
"ABCXYZ" => true // ZYXCBA
"345 09%" => false // is not a palindrome
"ev" => true // ve
"AZGDFSSF IJHSDFIU HFIA" => false
"Zyba" => true
"-AZ" => false // -ZA is not a reverse of -AZ
"Tree vvig" => true // Givv eert 
"$%%$" => true // palindrome
"A$&$z" => true // z$&$A

Tabla de clasificación

El Fragmento de pila al final de esta publicación genera el catálogo a partir de las respuestas a) como una lista de la solución más corta por idioma yb) como una tabla de clasificación general.

Para asegurarse de que su respuesta se muestre, comience con un título, utilizando la siguiente plantilla de Markdown:

## Language Name, N bytes

¿Dónde Nestá el tamaño de su envío? Si mejora su puntaje, puede mantener los puntajes antiguos en el título, tachándolos. Por ejemplo:

## Ruby, <s>104</s> <s>101</s> 96 bytes

Si desea incluir varios números en su encabezado (por ejemplo, porque su puntaje es la suma de dos archivos o desea enumerar las penalizaciones de la bandera del intérprete por separado), asegúrese de que el puntaje real sea el último número en el encabezado:

## Perl, 43 + 2 (-p flag) = 45 bytes

También puede hacer que el nombre del idioma sea un enlace que luego aparecerá en el fragmento:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes



44
AtBash en realidad no es algo nuevo. Es la transformación de la letra hebrea Kabala (misticismo judío) equivalente a esto. Dado que el hebreo se escribe solo con wovels, cualquier cadena de letras se puede leer insertando wovels al azar. ATB (a) SH es un mnemotécnico para transformar Alef (primera letra hebrea) en Tav (último), Beis (segundo) en SHin (penúltimo).
Adám

1
¿Considera dar -1000000 puntos si el código de solución de alguien es en sí mismo un palindrome de atbash? : p
kojiro

3
@kojiro No trivial en lugar de code {Comment-symbol}{Atbash'ed Comment-symbol} Atbash'ed code...
Adám

1
@ mbomb007 Dije que podría ofrecer una recompensa si se encuentra dicho programa no trivial
Conor O'Brien

Respuestas:


8

RX , 9 8 bytes

Muy inspirado por Retina, hice esto hace unos días. Código:

prR`w$rM

Explicación:

prR`w$rM

p         # Start pattern
 r        # Reversed lowercase alphabet
  R       # Reversed uppercase alphabet
   `      # Next pattern
    w     # Equivalent to a-zA-Z_0-9 (word pattern)
     $    # End pattern and compute regex
      r   # Reverse input
       M  # Change mode to Match mode, compares the atbash string with the reversed string.

Pruébalo aquí !


Entonces, ¿cómo funciona el lenguaje en sí? ¿Es algún tipo de lenguaje de procesamiento de cadenas basado en pila? Esto es realmente impresionante, pero por lo que puedo decir, todavía no hay forma de repetir el lenguaje, lo que significa que es muy poco probable que cumpla con nuestros estándares de lenguaje de programación en esta etapa.
Martin Ender

@ MartinBüttner Este lenguaje se basa principalmente en el procesamiento de la entrada utilizando un modelo de pila. No usa números enteros (y probablemente nunca lo hará). He implementado un bucle, pero esa versión aún no se ha lanzado.
Adnan

@Martin Regexes son capaces de realizar pruebas de primalidad por sí mismas, así que estoy bastante seguro de que esto es válido.
lirtosiast el

@ThomasKwa Hasta donde puedo ver, el intérprete no usa ninguna expresión regular real.
Martin Ender

@ Martin Hmm, tienes razón.
lirtosiast


6

Julia, 96 bytes

s->join([get(Dict(zip([u=map(Char,65:90);],reverse(u))),c,c)for c=(S=uppercase(s))])==reverse(S)

Esta es una función lambda que acepta una cadena y devuelve una cadena. Para llamarlo, asígnelo a una variable.

Sin golf:

function f(s::AbstractString)
    # Get all of the uppercase letters A-Z
    u = map(Char, 65:90)

    # Create a dictionary for the transformation
    D = Dict(zip(u, reverse(u)))

    # Uppercase the input
    S = uppercase(s)

    return join([get(D, c, c) for c in S]) == reverse(S)
end

5

Bash + utilidades de Linux, 56

tr a-z `printf %s {z..a}`<<<${1,,}|cmp - <(rev<<<${1,,})

Emite la cadena vacía para Truthy y algo así como - /dev/fd/63 differ: byte 1, line 1para Falsey. Si esto no es aceptable, podemos agregar -s3 bytes adicionales y usar los códigos de retorno estándar de Unix de 0 para Éxito (Verdad) y 1 para Fracaso (Falsey).


5

Retina , 44 bytes

$
¶$_
T`lL`Ro`.+$
+`(¶.*)(.)
$2$1
i`^(.+)\1$

Impresiones 1o 0. El recuento de bytes supone que el archivo está codificado como ISO 8859-1.

Pruébalo en línea!

Esta respuesta se inspiró en gran medida en la respuesta sed de DigitalTrauma, pero supongo que no hay muchos enfoques para este desafío en primer lugar.

Explicación

Siempre que vea un , lo primero que hace Retina después de dividir el código en líneas es reemplazar todos esos pilcrows con saltos de línea. Esto permite la inclusión de avances de línea para un solo byte aunque los avances de línea son el separador de etapas de Retina.

$
¶$_

Comenzamos duplicando la entrada. Hacemos coincidir el final de la entrada $e insertamos un salto de línea junto con la entrada en sí (usando $_).

T`lL`Ro`.+$

Una etapa de transliteración. Vamos a empezar con la expresión regular: .+$. Coincide con la segunda copia de la entrada (asegurando que la coincidencia se extiende hasta el final de la cadena) Entonces solo los caracteres en la segunda copia serán transliterados. La transliteración en sí hace uso de algunas características muy recientes. ly Lson clases de caracteres para letras mayúsculas y minúsculas, respectivamente. ose refiere al otro conjunto de caracteres de la transliteración y lo Rinvierte. Entonces los dos conjuntos de caracteres se expanden a:

abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba

Notarás que esto cambia el caso mientras haces el cifrado Atbash, pero de todos modos haremos la comparación final sin distinción entre mayúsculas y minúsculas.

+`(¶.*)(.)
$2$1

Ahora invertimos la segunda copia. Desafortunadamente, Retina aún no tiene una forma conveniente de hacerlo, por lo que tendremos que mover un personaje desde el final al frente a la vez. Esto se hace reutilizando el separador de salto de línea como marcador de qué parte aún no se ha invertido. Emparejamos esa parte pero capturamos el último personaje por separado. Ese personaje va al frente, y el resto no cambia. El +le dice a Retina que haga esto repetidamente hasta que ya no sea posible (porque está al final de la cadena).

i`^(.+)\1$

Finalmente, verificamos si las dos cadenas son iguales. Esto ihace que el patrón no distinga entre mayúsculas y minúsculas: convenientemente, en .NET, esto significa que las referencias posteriores también distinguen entre mayúsculas y minúsculas. Puede notar que ya no tenemos un separador entre la entrada original y la copia modificada. Sin embargo, no necesitamos uno, porque tienen la misma longitud, y si la cadena ahora consta exactamente de la misma cadena dos veces (hasta el caso), entonces deben ser la cadena original y la modificada. Si se pregunta qué sucedió con el avance de línea final que usamos como marcador, todavía está allí, pero en muchos sabores de expresiones regulares $también coincide antes del último carácter de la cadena si ese carácter es un avance de línea.

Como esta etapa solo consiste en una sola línea, se considera una etapa de coincidencia, que cuenta el número de coincidencias. Si la entrada es un palíndromo Atbash, obtendremos exactamente una coincidencia y la salida es 1. De lo contrario, esta expresión regular no coincidirá y la salida sí 0.


Supongo que es mejor que los avances de línea sean los separadores de escenario y que los pilcrows sean literales que viceversa.
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ Por conveniencia, también puede insertar avances de línea por secuencias de escape, \n en expresiones regulares y $nen sustitución, pero eso es bytes perdidos para jugar al golf. ;)
Martin Ender

5

GNU Sed, 105

s/.*/\l&/
h
y/abcdefghijklmnopqrstuvwxyz/zyxwvutsrqponmlkjihgfedcba/
G
:
s/\(.\)\n\1/\n/
t
/^.$/{c1
q}
c0

Salidas 1 para la verdad y 0 para falsey.

Traté de hacer esto en Retina, pero no pude encontrar la manera de guardar la cadena antes de la transcripción de Atbash para una comparación inversa con después. Quizás haya una mejor manera.

El ycomando de transliteración de Sed deja mucho que desear.


Sí, "almacenar" cosas todavía es engorroso en Retina. Tendría que duplicar la cadena y luego transliterar e invertir solo una copia. Quiero agregar algún tipo de función de bifurcación / bifurcación en el futuro, pero aún no estoy muy seguro de los detalles.
Martin Ender

Ah, creo que veo. Intenté hacer algo similar separando las cuerdas antes y después con dos puntos. Me caí con la expresión regular al final de la T- Supuse que se aplicaba a cada personaje por turno, pero si mi comprensión es correcta, se aplica a todo el espacio del patrón, lo cual es mucho más útil
Digital Trauma

1
La expresión regular en T se aplica a la cadena de entrada. La transliteración es la única que se realiza dentro de las coincidencias de esa expresión regular y todo lo que no coincide no se modifica. La expresión regular por defecto es [\s\S]+así, al omitirla, estás transcribiendo todo.
Martin Ender


Como es GNU sed, puede guardar un byte intercambiando el -rindicador por las barras diagonales inversas en \(y \). Estoy de acuerdo contigo en el ycomando!
Toby Speight

4

𝔼𝕊𝕄𝕚𝕟, 15 caracteres / 30 bytes

ïþ)Ī(ᶐ,ᶐᴙ)ᴙ≔ïþ)

Try it here (Firefox only).

Explicación

ïþ)Ī(ᶐ,ᶐᴙ)ᴙ≔ïþ) // implicit: ï=input, ᶐ=A-Z
ïþ)             // ï.toUpperCase()
   Ī(ᶐ,ᶐᴙ)ᴙ     // transliterate input from A-Z to Z-A, then reverse
           ≔ïþ) // check if that's still equal to ï.toUpperCase()
                // implicit output

4

Paréntesis, 658 bytes

((()()())(()(((()))))((()()((())))))((()()())(()(((())))()()())((())()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()))((()()())(()(((())))())((()())((()(((())))()()))((()()()())((()(())(()))(()(((())))()())(()((()))))(()((())))((()((()))())((()(())(())())((()(()))(()(((())))()()())((()(()()))((())()()()()()()()()()()()()()()()()()()()()()()()()())((()(()()))((()(()())())((()((()))(()))(()(((())))()())))(()(((())))()()())))))((()(((())))())((()((()))()())(()(((())))()())))))))((()(())(()))((()()()(()))((()()()()())(()(((()))))))((()(((())))())((()()()()())(()(((())))))))

Solo funciona para todas las mayúsculas sin espacios en blanco en este momento, usando esta versión modificada del script para que admita la lectura de stdin:

#!/usr/bin/env python
from collections import defaultdict
from itertools import izip
import copy
import operator
import os
import sys

# map from paren strings to english names
# for the predefined symbols (lambda, etc)
to_english = defaultdict(lambda:None,\
    {'()': 'lambda',
     '()()': 'define',
     '(())': 'plus',
     '(()())': 'minus',
     '()(())': 'mult',
     '(())()': 'div',
     '()()()': 'if',
     '((()))': 'empty',
     '()()()()': 'charsof',
     '()()(())': 'reverse',
     '()(())()': 'LE',
     '()(()())': 'not',
     '(()())()': 'intofchar',
     '()((()))': 'readline',
     '((()))()': 'cons',
     '(())(())': 'equal',
     '((()))(())': 'car',
     '((()))()()': 'cdr',
     '(())(())()': 'char',
     '(())()(())': 'string'})

# map from english to parenthetic
to_scheme = defaultdict(lambda:None)
for k,v in to_english.iteritems():
    to_scheme[v] = k

def Error(errorString = 'unmatched parens', debug_mode = True):
    if debug_mode:
        print "Error: " + errorString
        sys.exit()
    else:
        raise Exception('paren mismatch')

def bracketsMatch(chars):
    """Returns False if any parentheses in `chars` are not matched
    properly. Returns True otherwise.
    """
    level = 0
    for p in chars:
        if p == '(':
            level += 1
        elif p == ')':
            level -= 1
        if level < 0:
            return False    
    return level == 0

def get_exprs(chars):
    """Returns a list of character sequences such that for each sequence,
    the first and last parenthesis match.
    For example, "(())()()" would be split into ["(())", "()", "()"]
    """
    level = 0
    current = []
    for p in chars:
        if p == '(' or p == ')':
            current.append(p)
        if p == '(':
            level += 1
        elif p == ')':
            level -= 1
        if level == 0:
            yield current
            current = []

## built-in functions ##
def builtin_accumulate(init, accumulate, environment, params):
    """Helper function that handles common logic for builtin functions.
    Given an initial value, and a two-parameter function, the environment, and
    a list of params to reduce, this function will reduce [init] + params using
    the accumulate function and finally returns the resulting value.
    """
    result = init
    for param in params:
        value = interpret(param, environment)
        try: result = accumulate(result, value)
        except: Error(str(value) + ' is not the correct type')
    return result

def builtin_plus(environment, params):
    if len(params) >= 1:
        return builtin_accumulate(interpret(params[0], environment), operator.add, environment, params[1:])
    else:
        return 0.0

def builtin_minus(environment, params):
    if len(params) == 0:
        Error('subtraction requires at least 1 param')
    return builtin_accumulate(interpret(params[0], environment), operator.sub, environment, params[1:])

def builtin_mult(environment, params):
    return builtin_accumulate(1.0, operator.mul, environment, params)

def builtin_div(environment, params):
    if len(params) == 0:
        Error('division requires at least 1 param')
    return builtin_accumulate(interpret(params[0], environment), operator.div, environment, params[1:])

def builtin_LE(environment, params):
    return interpret(params[0], environment) <= interpret(params[1], environment)

def builtin_lambda(environment, params):
    bodies = [body for body in params[1:]]
    params = params[0][1]
    if len(bodies) == 0:
        Error("a function had no body")
    for kind, name in params:
        if kind != 'symbol':
            Error('lambda must have only symbols as arguments')
    def ret(old_environment, arguments):
        #print bodies
        try:
            # create new environment based on args
            environment = copy.copy(old_environment)
            for param, arg in izip(params, arguments):
                environment[param[1]] = interpret(arg, old_environment)
            # evaluate the function bodies using the new environment
            return interpret_trees(bodies, environment, False)
        except:
            Error("Error evaluating a function")
    return ret

def builtin_equal(environment, params):
    for param1, param2 in izip(params[:-1], params[1:]):
        if interpret(param1, environment) != interpret(param2, environment):
            return False
    return True

def builtin_if(environment, params):
    if len(params) != 3:
        Error("'if' takes in exactly 3 params")    
    if interpret(params[0], environment):
        return interpret(params[1], environment)
    return interpret(params[2], environment)

def builtin_not(environment, params):
    return False if interpret(params[0], environment) else True

def builtin_cons(environment, params):
    return (interpret(params[0], environment), interpret(params[1], environment))

def builtin_car(environment, params):
    result = interpret(params[0], environment)
    if not isinstance(result, tuple):
        Error("car must only be called on tuples")
    return result[0]

def builtin_cdr(environment, params):
    result = interpret(params[0], environment)
    if not isinstance(result, tuple):
        Error("cdr must only be called on tuples")
    return result[1]

def builtin_char(environment, params):
    result = interpret(params[0], environment)
    if result != int(result):
        Error("char must only be called on integers")
    return chr(int(result))

def builtin_intofchar(environment, params):
    result = interpret(params[0], environment)
    result = ord(result)
    return result

def builtin_string(environment, params):
    result = ''
    cur = interpret(params[0], environment)
    while cur != ():
        if not isinstance(cur, tuple) or not isinstance(cur[1], tuple):
            Error("string only works on linked lists")
        result += cur[0]
        cur = cur[1]
    return result

def unmakelinked(llist):
    result = ()
    while llist != ():
        if not isinstance(llist, tuple) or not isinstance(llist[1], tuple):
            Error("only works on linked lists")
        result += (llist[0],)
        llist = llist[1]
    return result

def makelinked(tup):
    result = ()
    while tup != ():
        result = (tup[-1],result)
        tup = tup[:-1]
    return result

def builtin_reverse(environment, params):
    result = interpret(params[0], environment)
    result = makelinked(unmakelinked(result)[::-1])
    return result

def builtin_charsof(environment, params):
    result = interpret(params[0], environment)
    result = makelinked(tuple(result))
    return result

def builtin_readline(environment, params):
    result = raw_input()
    return result

# define the default (top-level) scope
default_environment = \
    {to_scheme['plus']: builtin_plus,
     to_scheme['minus']: builtin_minus,
     to_scheme['mult']: builtin_mult,
     to_scheme['div']: builtin_div,
     to_scheme['lambda']: builtin_lambda,
     to_scheme['if']: builtin_if,
     to_scheme['equal']: builtin_equal,
     to_scheme['LE']: builtin_LE,
     to_scheme['not']: builtin_not,
     to_scheme['empty']: (),
     to_scheme['car']: builtin_car,
     to_scheme['cdr']: builtin_cdr,
     to_scheme['cons']: builtin_cons,
     to_scheme['char']: builtin_char,
     to_scheme['string']: builtin_string,
     to_scheme['readline']: builtin_readline,
     to_scheme['charsof']: builtin_charsof,
     to_scheme['reverse']: builtin_reverse,
     to_scheme['intofchar']: builtin_intofchar}

# parse the tokens into an AST
def parse(tokens):
    """Accepts a list of parentheses and returns a list of ASTs.
    Each AST is a pair (type, value).
    If type is 'symbol', value will be the paren sequence corresponding
    to the symbol.
    If type is 'int', value will be a float that is equal to an int.
    If type is expr, value will be a list of ASTs.
    """
    # check for errors
    if not bracketsMatch(tokens):
        Error('paren mismatch')
    # to return - a list of exprs
    exprs = []
    for expr in get_exprs(tokens):
        # check for errors
        if len(expr) < 2:
            Error('too few tokens in: ' + ''.join(expr))
        elif expr[0] != '(' or expr[-1] != ')':
            Error('expression found without () as wrapper')
        # pop off starting and ending ()s
        expr = expr[1:-1]
        # symbol
        if expr[:2] == ['(', ')'] and len(expr) > 2:
            exprs.append(('symbol', ''.join(expr[2:])))
        # integer
        elif expr[:4] == ['(', '(', ')', ')'] and len(expr) >= 4:
            exprs.append(('num', expr[4:].count('(')))
        # expr
        else:
            exprs.append(('expr', parse(expr)))
    return exprs

def interpret(tree, environment):
    """Interpret a single tree (may not be a define) and return the result"""
    kind, value = tree
    if kind == 'num':
        return float(value)
    elif kind == 'symbol':
        if value in environment:
            return environment[value]
        else:
            Error('Unresolved symbol - ' + value)
    elif kind == 'expr':
        function = interpret(value[0], environment)
        if not hasattr(function, '__call__'):
            Error('Symbol "'+value[0]+'" is not a function.')
        return function(environment, value[1:])
    else:
        Error("Unknown tree kind")

def interpret_trees(trees, environment, doprint = True):
    """Interpret a sequence of trees (may contain defines)
    and output the result.
    The trees passed in should be ASTs as returned by parse().
    If doprint is true, the post-interpretation value of each tree is printed.
    """
    environment = copy.copy(environment)
    # hoist define statements (note: trees.sort is stable)
    #trees.sort(key = lambda x: 0 if x[0] == 'expr' and x[1][0][1] == to_scheme['define'] else 1)
    ret = None
    for tree in trees:
        if tree[0] == 'expr' and tree[1][0][0] == 'symbol' and tree[1][0][1] == to_scheme['define']:
            try:
                symbol = tree[1][1]
                if symbol[0] != 'symbol':
                    Error('first argument to define must be a symbol')
                symbol = symbol[1]
                value = tree[1][2]
                environment[symbol] = interpret(value, environment)
            except:
                Error('error evaluating define statement')
        else:
            ret = interpret(tree, environment)
            if doprint:
                print ret,
    return ret

# read in the code ignoring all characters but '(' and ')' 
f = open(sys.argv[1],'r')
code = []
for line in f.readlines():
    code += [c for c in line if c in '()']

# parse and interpret the code. print 'Parenthesis Mismatch'
# if an error occured.
#try:
syntax_trees = parse(code)
interpret_trees(syntax_trees, default_environment)
#except:
#    print 'Parenthesis Mismatch'

Explicación

(
  define
  (() ()())
  input [[[[]]]]
  (() (((()))))
  exec readline
  ( (() ()((()))) )
)
(
  define
  (() ()())
  value of 'A' [[[[]]]] [][][]
  (() (((())))()()())
  65
  ((()) ()()()()()()()()()()
        ()()()()()()()()()()
        ()()()()()()()()()()
        ()()()()()()()()()()
        ()()()()()()()()()()
        ()()()()()()()()()()
        ()()()()())
)
(
  define
  (() ()())
  atbash [[[[]]]] []
  (() (((())))())
  (
    lambda
    (() ())
    (
      list [[[[]]]] [][]
      (() (((())))()())
    )
    (
      if
      (() ()()())
      (
        equal
        (() (())(()))
        list
        (() (((())))()())
        empty
        (() ((())))
      )
      then return empty
      (() ((())))
      else
      (
        cons
        (() ((()))())
        (
          char
          (() (())(())())
          (
            plus
            (() (()))
            value of 'A' 65
            (() (((())))()()())
            (
              minus
              (() (()()))
              25
              ((()) ()()()()()()()()()()
                    ()()()()()()()()()()
                    ()()()()())
              (
                minus
                (() (()()))
                (
                  intofchar
                  (() (()())())
                  (
                    car
                    (() ((()))(()))
                    list
                    (() (((())))()())
                  )
                )
                value of 'A' 65
                (() (((())))()()())
              )
            )
          )
        )
        (
          atbash
          (() (((())))())
          (
            cdr
            (() ((()))()())
            list
            (() (((())))()())
          )
        )
      )
    )
  )
)

(
  equals
  (() (())(()))
  (
    reverse
    (() ()()(()))
    (
      charsof
      (() ()()()())
      input
      (() (((()))))
    )
  )
  (
    atbash
    (() (((())))())
    (
      charsof
      (() ()()()())
      input
      (() (((()))))
    )
  )
)

44
¿Quieres que tu código sea el más largo? : P
Zorgatone

4

Python 3, 90 85 bytes

s=input().upper()
print(s[::-1]==''.join(chr([o,155-o][64<o<91])for o in map(ord,s)))

Convertimos la entrada a mayúsculas, y luego calculamos la cadena Atbashed restando todos los ordinales de 155 si están en el rango del alfabeto en mayúsculas.


4

Kerf , 73 bytes

Kerf es un lenguaje patentado en la misma familia general que APL, J y K. Es posible escribir líneas enigmáticas, compactas y evitar el uso de bucles explícitos:

{[s]s:_ s;n:?isnull i:s search\<a:char 97+^26;f:(/a)[i];s match/f[n]:s[n]}

Sin embargo, el uso de los alias enunciados para los comandos en lugar de los símbolos abreviados y el uso de identificadores significativos hace que el programa sea mucho más claro y bastante fácil de seguir, incluso si no está familiarizado con Kerf:

def atbash_palindrome(str) {
  str:       tolower str
  alpha:     char range(97, 123)
  indices:   str search mapleft alpha
  encoded:   (reverse alpha)[indices]
  notfound:  which isnull indices
  return     str match reverse encoded[notfound]:str[notfound]
}

En acción:

KeRF> p: {[s]s:_ s;n:?isnull i:s search\<a:char 97+^26;f:(/a)[i];s match/f[n]:s[n]};

KeRF> p mapdown ["WIZARD","Wizard","W I Z A R D","ABCXYZ","345 09%","ev","Zyba","$%%$","-AZ"]
  [1, 1, 1, 1, 0, 1, 1, 1, 0]

Kerf probablemente no va a ganar un montón de competiciones de codegolf, especialmente contra lenguajes especialmente diseñados, pero podría valer la pena jugar si le gusta la idea de los lenguajes de la familia APL pero encuentra la sintaxis demasiado extraña. ( Descargo de responsabilidad: soy el autor del manual de referencia para Kerf ) .


3

Prólogo, 121 bytes

a(W):-upcase_atom(W,X),atom_codes(X,C),b(C,Z),!,reverse(Z,C).
b([A|T],[R|S]):-(A>64,A<91,R is 77-A+78;R=A),(b(T,S);S=[]).

Esto se llama con un átomo como entrada, por ejemplo a('WIZARD')..


3

JavaScript (ES6), 91

x=>(x=[...x.toLowerCase()]).every(c=>((v=parseInt(c,36))>9?(45-v).toString(36):c)==x.pop())

PRUEBA

F=x=>(x=[...x.toLowerCase()]).every(c=>((v=parseInt(c,36))>9?(45-v).toString(36):c)==x.pop())

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

;[
 ["WIZARD", true]
,["Wizard", true] // case doesn't matter
,["wIzArD", true]
,["W I Z A R D", true]
,["W IZ ARD", false] // the atbash of this is D RA ZIW, which is not a palindrome of W IZ ARD
,["ABCXYZ", true] // ZYXCBA
,["345 09%", false] // is not a palindrome
,["ev", true] // ve
,["AZGDFSSF IJHSDFIU HFIA", false]
,["Zyba", true]
,["-AZ", false] // -ZA is not a reverse of -AZ
,["Tree vvig", true] // Givv eert 
,["$%%$", true] // palindrome
,["$%ZA%$", true]
].forEach(t=>{var i=t[0],x=t[1],r=F(i);
              console.log(i+' -> '+r+(x==r?' OK':' Fail (expected:'+x+')'))})
<pre id=O></pre>


3

C, 101 97 bytes

Como la pregunta especificaba caracteres ASCII, esto no maneja ninguna otra codificación.

f(char*s){char*p=s+strlen(s);while(*s&&!(isalpha(*--p)?*s<64||*s+*p-27&31:*s-*p))++s;return s>p;}

Explicación

int f(char*s)
{
    char *p = s + strlen(s);
    while (*s && !(isalpha(*--p) ? *s<64||*s+*p-27&31 : *s-*p))
        ++s;
    return s > p;
}

Hacemos un puntero pque comienza al final de la cadena. Luego hacemos un bucle, moviéndonos ambos sy phacia el otro sllega al final. Esto significa que cada par de caracteres se verificará dos veces, pero esto ahorra un par de bytes en comparación con la detención tan pronto como se cruzan los punteros.

En cada iteración, verificamos si *pes una letra. Si es así, verifique que *sesté en el rango de letras (ASCII 64 hacia arriba), *py *sagregue hasta 27 (mod 32). Las letras que no sean más de 64 no pasarán esa prueba, por lo que no necesitamos verificar isalpha(*s).

Si *pno es una letra, entonces simplemente probamos si es igual a *s. En cualquier caso, terminamos el ciclo antes sy lo pcruzamos.

Si sy se phan cruzado, cada par de letras coincidió correctamente, por lo que devolvemos verdadero; de lo contrario, devolvemos falso.

Programa de prueba

Pase las cadenas a probar como argumentos de línea de comandos. Esto produce la salida correcta para todos los casos de prueba. No hay un requisito proporcionado para la cadena vacía; mi implementación devuelve falso para esa entrada.

#include <stdio.h>

int main(int argc, char **argv)
{
    while (*++argv)
        printf("\"%s\" => %s\n", *argv, f(*argv)?"true":"false");
    return 0;
}

puede descartar fla declaración de tipo de un prototipo de estilo K&R:f(char*s)
cat

3

Perl 5, 70 bytes

Una subrutina:

{$"='';reverse(map/[A-Z]/?chr(155-ord):$_,(@_=split'',uc$_[0]))eq"@_"}

Véalo en uso:

print sub{...}->("W i z a r d")

2

MATL, 23 bytes

Utiliza versión actual .

jkt"@@2Y2m?_219+]h]tP=A

Ejemplos

>> matl
 > jkt"@@2Y2m?_219+]h]tP=A
 > 
> Tree vvig
1

>> matl
 > jkt"@@2Y2m?_219+]h]tP=A
 > 
> W IZ ARD
0

2

CJam, 18 bytes

qeu_'[,65>_W%erW%=

Pruébalo en línea

Funciona convirtiendo la entrada a mayúsculas, realizando la traducción de letras, voltea la cadena y verifica la igualdad.


2

Japt, 30 27 bytes

U=Uv)w ¥Ur"[a-z]"_c +4^31 d

Pruébalo en línea!

Cómo funciona

Esto se basa en gran medida en mi respuesta de Japt en Swap the Alphabet.

U=Uv)w ¥Ur"[a-z]"_c +4^31 d
U=Uv)      // Set U to U.toLowerCase().
w ¥        // Reverse it, and check if it is equal to:
Ur"[a-z]"  //  Take the input and replace each letter with:
 _c +4     //   Take its char code and add 4. This results in
           //   the string      "abc...xyz"
           //   becoming        "efg...|}~".
 ^31       //   XOR the result by 31. This flips its last five 5 bits.
           //   We now have     "zyx...cba".
 d         //   Convert back from a char code.
           // Implicit: output last expression

1

Python, 156 112 bytes

a=map(chr,range(65,91))
s=raw_input().upper()
print ''.join([dict(zip(a,a[::-1])).get(i,i) for i in s])==s[::-1]

Básicamente, crea un diccionario de la traducción con letras mayúsculas y la entrada se escribe con mayúscula (si todo fuera minúscula, eso agregaría 5 bytes). Luego, para cada carácter en la entrada en mayúscula, realice la traducción y agregue a una lista a menos que el carácter no esté en el alfabeto, en cuyo caso agregue el carácter como está. Únase a la lista completa y compárela con la lista invertida.

Un agradecimiento a @Artyer por publicar casi exactamente como iba a publicar antes que yo. Pero necesito confirmar, este es mi trabajo y lo hice de forma independiente .

Basado en la respuesta de Julia de Alex A. Pruébalo aquí


Hay un espacio en blanco innecesario después .get(i,i). +1.
Yytsi

1

05AB1E , 8 bytes (no competitivos)

Este lenguaje utiliza características que son posteriores al desafío y, por lo tanto, no compite.

Código:

lDAAR‡RQ

Explicación:

l         # Lowercase the implicit input
 D        # Duplicate top of the stack
  AAR     # Push the lowercase alphabet (A) and the lowercase alphabet reversed (AR)
     ‡    # Transliterate a -> b
      R   # Reverse this string
       Q  # Compare with the input string

Pruébalo en línea!


1

Factor, 118 113 bytes

Esta es una función anónima.

[ >upper dup >array [ 1string 65 90 [a,b] [ 1string ] map dup reverse zip >hashtable at ] map "" join reverse = ]

No conozco una forma más corta de generar una matriz asociativa del alfabeto: c


1

Clojure, 100 bytes

(defn x[b](let[a(.toUpperCase b)c(reverse a)](=(map #(char(if(<= 65(int %)90)(- 155(int %))%))a)c)))

Debería ser posible reducirlo a una sola función anónima, recortando alrededor de 10 bytes más (de declaraciones) pero aún no encontré una manera.


1

Ruby, 79 77 bytes

s=$*[0].upcase
exit(s==s.reverse.tr('A-Z','ZYXWVUTSRQPONMLKJIHGFEDCBA'))?0:1

Acepta la palabra para probar como argumento de línea de comando. Sale con el código 0 (que es verdadero para el shell) si el argumento es un palindrome de atbash, o con el código 1 de lo contrario.


1
¿No sería putsel resultado más corto que salir con un ternario?
gato

FYI $*es un alias para ARGV.
Jordania

1

Ruby, 56 bytes

->s{s.upcase!;s==s.tr(x=[*?A..?Z]*'',x.reverse).reverse}

Es una función anónima que toma una cadena y devuelve trueo false. Es bastante torpe: para guardar algunos bytes, utiliza la variante destructiva de upcase(con un !después). upcase!desafortunadamente regresa nilsi no se cambia nada (como toda la entrada numérica), por lo que se pierden algunos bytes tratando de lidiar con eso. Todavía funciona aunque :)


1

MATLAB, 61 bytes

No es la solución más corta, pero sigue siendo interesante.

f=@(a)~any(changem(upper(a),90:-1:65,65:90)-fliplr(upper(a)))
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.