Атбаш Сам Палиндромы


27

Рассмотрим преобразование Атбаша :

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

Где A ⇔ Z и L ⇔ O, например. Есть интересное свойство, которое разделяют некоторые слова. Когда некоторые строки переводятся в их эквивалентный atbash, указанный перевод является обратным исходным словом. Я называю эти Атбашские Палиндромы .

В качестве примера давайте переведем WIZARD :

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

В результате DRAZIW , который WIZARD наоборот. Таким образом, WIZARD - это самопалиндром atbash.

Цель. Задать строку печатных символов ASCII, вывести или вернуть истинное значение, если эта строка представляет собой собственный палиндром atbash, а в противном случае - значение false. (Это делается с помощью STDIN, ближайшего аналога, функционального ввода и т. Д. Если ваш язык не может сделать ничего из этого, рассмотрите возможность выбора другого языка, который вы можете жестко закодировать для ввода.) Вы должны делать это без учета регистра. Если вход является палиндромом и не зависит от последовательности atbash, вы все равно должны вывести true, так как сам палиндром + является палиндромом. Это , поэтому выигрывает самая короткая программа в байтах.

Контрольные примеры

"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

Leaderboard

Фрагмент стека в нижней части этого поста создает каталог из ответов а) в виде списка кратчайшего решения для каждого языка и б) в качестве общей таблицы лидеров.

Чтобы убедиться, что ваш ответ обнаружен, начните его с заголовка, используя следующий шаблон уценки:

## Language Name, N bytes

где Nразмер вашего представления. Если вы улучшите свой счет, вы можете сохранить старые результаты в заголовке, вычеркнув их. Например:

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

Если вы хотите включить в заголовок несколько чисел (например, потому что ваш результат равен сумме двух файлов или вы хотите перечислить штрафы за флаг интерпретатора отдельно), убедитесь, что фактический результат является последним числом в заголовке:

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

Вы также можете сделать имя языка ссылкой, которая будет отображаться во фрагменте кода:

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



4
AtBash на самом деле не новость. Это преобразование букв иврита в каббале (еврейский мистицизм) эквивалентно этому. Поскольку на иврите пишется только с помощью woveles, любая буквенная строка может быть прочитана путем вставки случайных wovels. ATB (a) SH является мнемоникой для преобразования алеф (первая буква иврита) в тав (последний), бейс (второй) в SHin (рядом с последним).
Адам

1
Подумайте о том, чтобы дать -1000000 баллов, если чей-то код решения сам по себе является палиндромом atbash? : p
Кодзиро

3
@kojiro Нетривиально, в отличие от code {Comment-symbol}{Atbash'ed Comment-symbol} Atbash'ed code...
Адам

1
@ mbomb007 Я сказал, что могу предложить вознаграждение, если будет найдена такая нетривиальная программа
Конор О'Брайен

Ответы:


8

RX , 9 8 байт

Сильно вдохновленный Retina, я сделал это несколько дней назад. Код:

prR`w$rM

Объяснение:

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.

Попробуй это здесь !


Так как же на самом деле работает сам язык? Это какой-то язык обработки строк в стеке? Это действительно впечатляет, но, насколько я могу судить, пока еще нет способа зацикливаться в языке, а это означает, что на данном этапе вряд ли это соответствует нашим стандартам языка программирования .
Мартин Эндер

@ MartinBüttner Этот язык в основном основан на обработке ввода с использованием стековой модели. Он не использует целые числа (и, вероятно, никогда не будет). Я реализовал цикл, но эта версия еще не была выпущена.
Аднан

@Martin Regexes способны самостоятельно проверять простоту, поэтому я уверен, что это действительно так.
lirtosiast

@ThomasKwa Насколько я понимаю, интерпретатор не использует никаких реальных регулярных выражений.
Мартин Эндер

@ Мартин Хмм, ты прав.
lirtosiast

11

Pyth, 10 9 байтов

qJrz0_XJG

Попробуйте эту скрипку онлайн или проверьте все тестовые случаи одновременно.

объяснение

qJrz0_XJG
  rz0      Lowercase input
 J         Store a copy in J
     _XJG  Translate J with the reverse alphabet and reverse
q          Compare

3
Поскольку вы используете rz0дважды, не короче ли вы сохранить его в переменную?
xnor

1
Как подсказывает @xnor, q_Jrz0XJGна один байт короче.
PurkkaKoodari

6

Юлия, 96 байт

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

Это лямбда-функция, которая принимает строку и возвращает строку. Чтобы вызвать его, присвойте его переменной.

Ungolfed:

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 + Linux, 56

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

Выводит пустую строку для Truthy и что-то вроде - /dev/fd/63 differ: byte 1, line 1Falsey. Если это неприемлемо, тогда мы можем добавить -sдополнительные 3 байта и использовать стандартные коды возврата Unix, равные 0 для успеха (Truthy) и 1 для сбоя (Falsey).


5

Сетчатка , 44 байта

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

Отпечатки 1или 0. Подсчет байтов предполагает, что файл закодирован как ISO 8859-1.

Попробуйте онлайн!

Этот ответ был в значительной степени вдохновлен ответом sed DigitalTrauma, но, опять же, я думаю, что, во-первых, не так много подходов к этому вызову.

объяснение

Всякий раз, когда вы видите , первое, что делает Retina после разбиения кода на строки, - это заменяет все эти пики на перевод строки. Это позволяет включать перевод строки для одного байта, даже если перевод строки является разделителем стадии Retina.

$
¶$_

Мы начнем с дублирования ввода. Мы сопоставляем конец ввода с $и вставляем перевод строки вместе с самим вводом (используя $_).

T`lL`Ro`.+$

Стадия транслитерации. Давайте начнем с регулярным выражением: .+$. Он совпадает со второй копией ввода (гарантируя, что совпадение продолжается до конца строки). Поэтому только символы во втором экземпляре будут транслитерированы. Сама транслитерация использует некоторые новейшие функции. lи Lявляются классами символов для строчных и прописных букв соответственно. oотносится к другому набору символов транслитерации и Rобращает его вспять. Таким образом, два набора символов расширяются до:

abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba

Вы заметите, что это меняет регистр при выполнении шифра Atbash, но мы все равно будем делать окончательное сравнение без учета регистра.

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

Теперь мы переворачиваем второй экземпляр. К сожалению, в Retina пока нет удобного способа сделать это, поэтому нам придется перемещать одного персонажа с конца на передний план за раз. Это делается путем повторного использования разделителя перевода строки в качестве маркера, часть которого еще не была перевернута. Мы сопоставляем эту часть, но захватываем последний символ отдельно. Этот персонаж идет впереди, а остальная часть остается неизменной. +Не говорит Retina сделать это несколько раз , пока не будет уже невозможно (потому что в конце строки).

i`^(.+)\1$

Наконец, мы проверяем, являются ли две строки одинаковыми. Это iделает шаблон нечувствительным к регистру - удобно, в .NET, это означает, что обратные ссылки также нечувствительны к регистру. Вы можете заметить, что у нас больше нет разделителя между исходным вводом и измененной копией. Однако он нам не нужен, потому что они имеют одинаковую длину, и если строка теперь состоит из одной и той же строки дважды (с точностью до регистра), то они должны быть исходной и измененной строкой. Если вам интересно , что случилось с завершающим переводом строки , которую мы использовали в качестве маркера, он все еще там, но и во многих регулярных выражений ароматизаторов $также соответствует до того последнего символа строки , если этот символ перевода строки.

Поскольку этот этап состоит только из одной строки, он считается этапом совпадения, который подсчитывает количество совпадений. Если входной сигнал является палиндромом Atbash, мы получим ровно одно совпадение, и выходной результат будет 1. Если нет, то это регулярное выражение не будет совпадать, и результат будет 0.


Я полагаю, лучше, чтобы переводы строк были разделителями, а пики - буквальными, а не наоборот.
Конор О'Брайен

@ CᴏɴᴏʀO'Bʀɪᴇɴ Для удобства вы также можете вставлять переводы строк с помощью escape-последовательностей, \n в регулярных выражениях и $nв замене, но это пустая трата байтов для игры в гольф. ;)
Мартин Эндер

5

GNU Sed, 105

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

Выходы 1 для правды и 0 для фальси.

Я пытался сделать это в Retina, но не мог понять, как сохранить строку перед транслитерацией Atbash для обратного сравнения с последующим. Возможно, есть лучший способ.

yКоманда транслитерации Седа оставляет желать лучшего.


Да, «хранить» вещи в Retina все еще громоздко. Вам нужно будет продублировать строку, а затем транслитерировать и перевернуть только одну копию. Я хочу добавить какую-то функцию ветвления / разветвления в будущем, но я не совсем уверен в деталях.
Мартин Эндер

Ах, я думаю, я вижу - я попытался сделать что-то подобное, разделив строки до и после двоеточием. Я упал с регулярным выражением в конце T- я предполагал, что оно применяется к каждому символу по очереди, но если мое понимание верно, оно применяется ко всему пространству паттернов, что гораздо полезнее
Digital Trauma

1
Регулярное выражение в T применяется к входной строке. Транслитерация является единственной, выполняемой в матчах этого регулярного выражения, и все несопоставленные остаются без изменений. По умолчанию это регулярное выражение [\s\S]+, опуская его, вы транслитерируете все.
Мартин Эндер


Так как это GNU sed, вы можете сохранить байт, поменяв -rфлаг обратной косой черты в \(и \). Я согласен с вами по yкоманде!
Тоби Спейт

4

𝔼𝕊𝕄𝕚𝕟, 15 символов / 30 байтов

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

Try it here (Firefox only).

объяснение

ïþ)Ī(ᶐ,ᶐᴙ)ᴙ≔ïþ) // 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

Родительский, 658 байт

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

Сейчас работает только для всех заглавных букв без пробелов, используя эту модифицированную версию скрипта, так что он поддерживает чтение из 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'

объяснение

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

4
Хотите, чтобы ваш код был самым длинным? : P
Зоргатоне

4

Python 3, 90 85 байт

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

Мы преобразуем ввод в верхний регистр, а затем вычисляем строку Atbashed, вычитая все порядковые числа из 155, если они находятся в диапазоне прописных букв.


4

Kerf , 73 байта

Kerf является проприетарным языком из того же общего семейства, что и APL, J и K. Можно писать загадочные, компактные однослойные и избегать использования явных циклов:

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

Тем не менее, использование прописных псевдонимов для команд вместо сокращенных символов и использование значимых идентификаторов делает программу намного более понятной и довольно простой для понимания, даже если вы не знакомы с 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]
}

В бою:

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]

Керф, вероятно, не собирается выиграть кучу соревнований по кодгольфу, особенно против специально созданных языков, но, возможно, стоит повозиться, если вам нравится идея языков семейства APL, но вы находите синтаксис слишком странным. ( Отказ от ответственности: я автор справочного руководства для Kerf. )


3

Пролог, 121 байт

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=[]).

Это вызывается с атомом в качестве входа, например a('WIZARD')..


3

JavaScript (ES6), 91

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

ТЕСТ

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 байт

Поскольку в вопросе указаны символы ASCII, это не относится к другим кодировкам.

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

объяснение

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;
}

Мы делаем указатель, pкоторый начинается в конце строки. Затем мы зациклились, двигаясь sи pдруг к другу, и sдостигли конца. Это означает, что каждая пара символов будет проверяться дважды, но это экономит пару байтов по сравнению с остановкой, как только указатели пересекаются.

На каждой итерации мы проверяем, *pявляется ли буква. Если это так, проверьте, что *sэто в диапазоне букв (ASCII 64 и выше), и это *pи *sдобавить до 27 (мод 32). Не-буквы старше 64 не пройдут этот тест, поэтому нам не нужно проверять isalpha(*s).

Если *pэто не буква, то мы просто проверяем, равно ли оно *s. В любом случае, мы прекращаем цикл раньше sи pпереходим.

Если sи pпересекли, то каждая пара букв соответствует правильно, поэтому мы возвращаем true; в противном случае мы возвращаем false.

Тестовая программа

Передайте строки для проверки в качестве аргументов командной строки. Это дает правильный вывод для всех тестовых случаев. Там нет поставляемого требования для пустой строки; моя реализация возвращает ложь для этого ввода.

#include <stdio.h>

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

вы можете оставить fобъявление типа для прототипа в стиле K & R:f(char*s)
cat

3

Perl 5, 70 байт

Подпрограмма:

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

Смотрите это в использовании:

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


2

CJam, 18 байт

qeu_'[,65>_W%erW%=

Попробуйте онлайн

Работает путем преобразования ввода в верхний регистр, выполнения перевода букв, переворачивания строки и проверки на равенство.


2

Japt, 30 27 байт

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

Попробуйте онлайн!

Как это работает

Во многом это основано на моем ответе Джапта об обмене алфавитом.

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 байт

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]

По сути, он составляет словарь перевода с заглавными буквами, а ввод заглавными (если бы все было строчными, то это добавило бы 5 байтов). Затем для каждого символа в вводе с заглавной буквы выполните перевод и добавьте в список, если символ не находится в алфавите, и в этом случае добавьте символ как есть. Присоединитесь ко всему списку и сравните с перевернутым списком.

Привет @Artyer за то, что он опубликовал почти так же, как я собирался опубликовать до меня. Но я должен подтвердить, что это моя работа, и я сделал это самостоятельно .

Основано на ответе Юлии Алексея. Попробуйте здесь


После этого появляется ненужный пробел .get(i,i). +1.
Yytsi

1

05AB1E , 8 байт (не конкурирует)

Этот язык использует функции, которые устарели и поэтому не конкурируют.

Код:

lDAAR‡RQ

Объяснение:

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

Попробуйте онлайн!


1

Фактор 118 113 байт

Это анонимная функция.

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

Я не знаю более короткого способа генерирования ассоциативного массива алфавита: c


1

Clojure, 100 байт

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

Должна быть возможность сократить его до одной анонимной функции, сократив еще около 10 байтов (объявлений), но я пока не нашел пути.


1

Рубин, 79 77 байт

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

Принимает слово для проверки в качестве аргумента командной строки. Выход с кодом 0 (который является правдивым для оболочки), если аргумент является самопалиндромом atbash, или с кодом 1 в противном случае.


1
Разве putsрезультат не будет короче, чем выход с тройной?
кот

К вашему сведению $*это псевдоним ARGV.
Джордан

1

Рубин, 56 байт

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

Это анонимная функция, которая принимает строку и возвращает trueили false. Это довольно неуклюже: чтобы сэкономить несколько байтов, он использует деструктивный вариант upcase!последующим после него). upcase!к сожалению, возвращается, nilесли ничего не изменилось (как и все числовые данные), поэтому некоторые байты теряются при попытке справиться с этим. Все еще работает, хотя :)


1

MATLAB, 61 байт

Не самое короткое решение, но все же интересно

f=@(a)~any(changem(upper(a),90:-1:65,65:90)-fliplr(upper(a)))
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.