Atbash Palindromes ตนเอง


27

พิจารณาการเปลี่ยนแปลง 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

ที่ A ⇔ Z และ L ⇔ O เช่นมีคุณสมบัติที่น่าสนใจซึ่งบางคำแบ่งปัน เมื่อมีการแปลสตริงบางรายการให้เทียบเท่ากับ atbash คำแปลนั้นจะกลับคำเดิม ผมเรียกเหล่านี้Atbash เอง Palindromes

ตัวอย่างเช่นลองแปลWIZARD :

W → D
ฉัน→ R
Z → A
A → Z
R →ฉัน
D → W

ผลลัพธ์คือDRAZIWซึ่งตรงกันข้ามกับWIZARD ดังนั้นWIZARDจึงเป็น atbash palindrome ตนเอง

วัตถุประสงค์รับสตริงของอักขระ ASCII ที่พิมพ์ได้ออกหรือส่งคืนค่าความจริงหากสตริงนั้นเป็น atbash self palindrome และค่า falsey (สิ่งนี้ทำผ่าน STDIN, เทียบเท่าที่ใกล้เคียงที่สุด, อินพุตที่ใช้งานได้ ฯลฯ หากภาษาของคุณไม่สามารถทำสิ่งใด ๆ เหล่านี้ได้ให้ลองเลือกภาษาอื่นที่คุณอาจ hardcode การป้อนข้อมูล) หากอินพุตเป็น palindrome และไม่ได้รับผลกระทบจาก atbash seqeunce คุณควรยังคงเอาท์พุทจริงเนื่องจาก palindrome + นั้นเป็น palindrome นี่คือดังนั้นโปรแกรมที่สั้นที่สุดในหน่วยไบต์ชนะ

กรณีทดสอบ

"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

ลีดเดอร์บอร์ด

สแต็คส่วนย่อยที่ด้านล่างของโพสต์นี้สร้างแคตตาล็อกจากคำตอบ a) เป็นรายการคำตอบสั้นที่สุดต่อภาษาและ b) เป็นลีดเดอร์บอร์ดโดยรวม

เพื่อให้แน่ใจว่าคำตอบของคุณปรากฏขึ้นโปรดเริ่มคำตอบด้วยหัวข้อโดยใช้เทมเพลต Markdown ต่อไปนี้:

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


ที่เกี่ยวข้อง: Swap ตัวอักษร
nicael

4
AtBash ไม่ใช่เรื่องใหม่ มันคือการเปลี่ยนแปลงตัวอักษรภาษาฮิบรู Kabala (ชาวยิวเวทย์มนต์) เทียบเท่ากับสิ่งนี้ เนื่องจากฮีบรูเขียนด้วย wovels เท่านั้นสตริงตัวอักษรใด ๆ สามารถอ่านได้โดยการแทรก wovels แบบสุ่ม ATB (a) SH เป็นตัวช่วยในการเปลี่ยน Alef (อักษรฮีบรูตัวแรก) เป็น Tav (สุดท้าย), Beis (วินาที) เป็น SHin (ถัดไปจนถึงสุดท้าย)
Adám

1
ลองพิจารณาให้ -1000000 คะแนนถ้ารหัสโซลูชันของใครบางคนเป็น atbash palindrome ตนเอง? : p
kojiro

3
@kojiro ไม่ใช่เรื่องแปลกเมื่อเทียบกับcode {Comment-symbol}{Atbash'ed Comment-symbol} Atbash'ed code...
Adám

1
@ mbomb007 ฉันบอกว่าฉันอาจเสนอเงินรางวัลหากพบโปรแกรมที่ไม่สำคัญเช่นนั้น
Conor O'Brien

คำตอบ:


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.

ลองที่นี่ !


ดังนั้นภาษาเองทำงานอย่างไรจริง ๆ มันเป็นภาษาการประมวลผลสตริงแบบกองซ้อนหรือไม่? นี่เป็นเรื่องที่น่าประทับใจจริงๆ แต่เท่าที่ฉันสามารถบอกได้ว่ายังไม่มีวิธีการวนซ้ำในภาษาซึ่งหมายความว่ามันไม่น่าเป็นไปได้อย่างมากที่จะเป็นไปตามมาตรฐานของภาษาการเขียนโปรแกรมของเราในขั้นตอนนี้
Martin Ender

@ MartinBüttnerภาษานี้มีพื้นฐานมาจากการประมวลผลอินพุตโดยใช้โมเดลสแต็ก มันไม่ได้ใช้จำนวนเต็ม (และอาจจะไม่เคย) ฉันใช้ลูปแล้ว แต่เวอร์ชันนั้นยังไม่ออก
Adnan

@ มาร์ตินเรกซ์มีความสามารถในการทดสอบขั้นต้นด้วยตัวเองดังนั้นฉันค่อนข้างมั่นใจว่ามันถูกต้อง
lirtosiast

@ThomasKwa เท่าที่ฉันเห็นล่ามจะไม่ใช้การแสดงออกปกติใด ๆ
Martin Ender

@ มาร์ตินอืมคุณพูดถูก
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

Julia, 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 utils, 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 สำหรับความสำเร็จ (ความจริง) และ 1 สำหรับความล้มเหลว (Falsey)


5

เรติน่า 44 ไบต์

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

พิมพ์หรือ1 0จำนวนไบต์ถือว่าเป็นไฟล์ที่เข้ารหัสตาม ISO 8859-1

ลองออนไลน์!

คำตอบนี้ได้รับแรงบันดาลใจส่วนใหญ่จากคำตอบที่ถูกต้องของ DigitalTraumaแต่แล้วฉันเดาอีกครั้งว่ามีหลายวิธีในการท้าทายนี้ในตอนแรก

คำอธิบาย

เมื่อใดก็ตามที่คุณเห็น a สิ่งแรกที่ Retina ทำหลังจากแยกรหัสเป็นบรรทัดคือการแทนที่ pilcrows ทั้งหมดด้วย linefeeds สิ่งนี้ทำให้การรวม linefeeds สำหรับหนึ่งไบต์แม้ว่า linefeeds เป็นตัวคั่นระยะของ Retina

$
¶$_

เราเริ่มต้นด้วยการป้อนข้อมูลซ้ำ เราจับคู่ส่วนท้ายของอินพุตด้วย$และแทรก linefeed พร้อมกับอินพุตเอง (โดยใช้$_)

T`lL`Ro`.+$

ขั้นตอนการถอดเสียง เริ่มต้นให้กับ regex .+$นี้: มันตรงกับสำเนาที่สองของอินพุต (โดยให้แน่ใจว่าการจับคู่ไปจนถึงจุดสิ้นสุดของสตริง) ดังนั้นตัวอักษรในสำเนาที่สองเท่านั้นที่จะถูกทับศัพท์ การทับศัพท์ใช้ประโยชน์จากคุณสมบัติล่าสุดบางอย่าง lและLเป็นคลาสของตัวอักษรสำหรับตัวอักษรพิมพ์เล็กและพิมพ์ใหญ่ตามลำดับ oอ้างถึงชุดอักขระอื่นของการทับศัพท์และRย้อนกลับ ดังนั้นชุดอักขระทั้งสองจึงขยายเป็น:

abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba

คุณจะสังเกตเห็นว่ากรณีนี้เป็นการสลับสับเปลี่ยนในขณะที่ทำ Atbash cypher แต่เราจะทำการเปรียบเทียบขั้นสุดท้าย

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

ตอนนี้เรากลับสำเนาที่สอง น่าเสียดายที่ Retina ยังไม่มีวิธีที่สะดวกในการทำเช่นนั้นดังนั้นเราจะต้องย้ายตัวละครตัวหนึ่งจากท้ายสุดไปข้างหน้าทีละครั้ง สิ่งนี้ทำได้โดยการกำหนดตัวแยกบรรทัดป้อนใหม่เป็นเครื่องหมายซึ่งส่วนที่ยังไม่ได้รับการย้อนกลับ เราจับคู่ส่วนนั้น แต่จับตัวอักขระสุดท้ายแยกกัน ตัวละครนั้นจะไปข้างหน้าและส่วนที่เหลือจะไม่เปลี่ยนแปลง +บอก Retina การทำเช่นนี้ซ้ำ ๆ จนกระทั่งมันเป็นไปไม่ได้ (เพราะเป็นที่สิ้นสุดของสตริง)

i`^(.+)\1$

ในที่สุดเราตรวจสอบว่าทั้งสองสายเหมือนกัน ตัวแบบiทำให้ตัวพิมพ์เล็กและตัวพิมพ์เล็ก - สะดวกใน. NET ซึ่งหมายความว่า backreferences นั้นต้องตรงตามตัวพิมพ์ใหญ่และตัวพิมพ์เล็ก คุณอาจสังเกตเห็นว่าเราไม่มีตัวคั่นระหว่างอินพุตต้นฉบับและสำเนาที่แก้ไขแล้ว เราไม่จำเป็นต้องใช้อันใดอันหนึ่งเพราะมันมีความยาวเท่ากันและถ้าตอนนี้สตริงประกอบด้วยสตริงเดียวกันทุกประการสองครั้ง (จนถึงกรณี) ดังนั้นสตริงนั้นต้องเป็นสตริงดั้งเดิมและสตริงที่แก้ไข หากคุณสงสัยว่าเกิดอะไรขึ้นกับตัวดึงข้อมูลบรรทัดต่อท้ายที่เราใช้เป็นตัวทำเครื่องหมายมันยังคงมีอยู่ แต่ในหลาย ๆ รสชาติของ regex จะ$จับคู่ก่อนอักขระตัวสุดท้ายของสตริงถ้าตัวละครนั้นเป็นตัวป้อนบรรทัด

เนื่องจากสเตจนี้ประกอบด้วยเพียงไลน์เดียวจึงเป็นสเตจการจับคู่ซึ่งนับจำนวนการแข่งขัน ถ้าใส่เป็น palindrome Atbash 1เราจะได้รับสิ่งหนึ่งในการแข่งขันและการส่งออกเป็น ถ้าไม่เช่นนั้น regex 0นี้จะไม่ตรงและการส่งออกจะได้รับ


ฉันเดาว่าการมี linefeeds ดีกว่านั้นคือตัวคั่นเวทีและ pilcrows เป็นตัวอักษรมากกว่าตัวกลับกัน
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴเพื่อความสะดวกคุณสามารถแทรก linefeeds ได้ด้วย escape sequences \n ใน regex และ$nในการเปลี่ยนตัว แต่นั่นเป็นจำนวนไบต์ที่สูญเปล่าสำหรับการเล่นกอล์ฟ ;)
Martin Ender

5

GNU Sed, 105

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

เอาท์พุท 1 สำหรับความจริงและ 0 สำหรับความเท็จ

ฉันพยายามทำสิ่งนี้ใน Retina แต่ไม่สามารถหาวิธีบันทึกสตริงก่อนการทับศัพท์ของ Atbash เพื่อเปรียบเทียบย้อนหลังได้ อาจจะมีวิธีที่ดีกว่า

yคำสั่งการถอดเสียงของ Sed ทำให้ต้องได้รับความนิยมอย่างมาก


ใช่สิ่ง "จัดเก็บ" ยังคงยุ่งยากใน Retina คุณจะต้องทำซ้ำสตริงแล้วแปลและย้อนกลับเพียงหนึ่งสำเนา ฉันต้องการเพิ่มฟีเจอร์การแยก / การฟอร์กกิ้งในอนาคต แต่ฉันยังไม่แน่ใจเกี่ยวกับรายละเอียด
Martin Ender

อ่าฉันคิดว่าฉันเห็น - ฉันพยายามทำสิ่งที่คล้ายกันโดยแยกสตริงก่อนและหลังกับลำไส้ใหญ่ ฉันล้มลงกับ regex เมื่อสิ้นสุดT- ฉันคิดว่ามันใช้กับตัวละครแต่ละตัว แต่ถ้าความเข้าใจของฉันถูกต้องมันใช้กับพื้นที่รูปแบบทั้งหมดซึ่งมีประโยชน์มากกว่า
Digital Trauma

1
regex ใน T ถูกนำไปใช้กับสายป้อน การถอดเสียงจะดำเนินการภายในการแข่งขันของ regex นั้นเท่านั้นและทุกสิ่งที่ไม่ตรงกันจะไม่เปลี่ยนแปลง ค่าเริ่มต้นของ regex เป็น[\s\S]+เช่นนั้นโดยการละเว้นมันคุณกำลังถอดเสียงทุกอย่าง
Martin Ender


ตั้งแต่มัน GNU sed คุณสามารถบันทึกไบต์โดยการซื้อขาย-rธงเครื่องหมายในและ\( \)ฉันเห็นด้วยกับคุณในyคำสั่ง!
Toby Speight

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

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

เราแปลงอินพุตเป็นตัวพิมพ์ใหญ่แล้วคำนวณสตริง Atbashed โดยลบเลขลำดับทั้งหมดจาก 155 หากอยู่ในช่วงตัวอักษรตัวพิมพ์ใหญ่


4

Kerf , 73 ไบต์

Kerf เป็นภาษาที่มีกรรมสิทธิ์ในตระกูลทั่วไปเช่นเดียวกับ APL, J และ K เป็นไปได้ที่จะเขียน oneliners แบบเข้ารหัสลับขนาดกะทัดรัดและหลีกเลี่ยงการใช้ลูปที่ชัดเจน:

{[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]

Kerf อาจจะไม่ชนะการแข่งขัน codegolf จำนวนมากโดยเฉพาะกับภาษาที่สร้างขึ้นมาเพื่อวัตถุประสงค์ แต่มันอาจคุ้มค่าหากคุณชอบแนวคิดของภาษาตระกูล APL แต่พบว่าไวยากรณ์แปลกเกินไป ( ข้อจำกัดความรับผิดชอบ: ฉันเป็นผู้เขียนคู่มืออ้างอิงสำหรับ Kerf )


3

Prolog ขนาด 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=[]).

นี้เรียกว่ามีอะตอมเป็น input 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 (mod 32) ที่ไม่ใช่ตัวอักษร 64 isalpha(*s)จะล้มเหลวการทดสอบนั้นดังนั้นเราจึงไม่จำเป็นต้องตรวจสอบ

ถ้าไม่ได้เป็นตัวอักษรแล้วเราก็ทดสอบว่ามันจะมีค่าเท่ากับ*p *sไม่ว่าในกรณีใดเราจะยุติลูปก่อนsและpข้าม

หากsและpมีข้ามแล้วตัวอักษรทุกคู่จับคู่อย่างถูกต้องดังนั้นเรากลับจริง มิฉะนั้นเรากลับเท็จ

โปรแกรมทดสอบ

ผ่านสตริงที่จะทดสอบเป็นอาร์กิวเมนต์บรรทัดคำสั่ง สิ่งนี้จะสร้างเอาต์พุตที่ถูกต้องสำหรับทุกกรณีทดสอบ ไม่มีข้อกำหนดที่ระบุสำหรับสตริงว่าง การนำไปใช้ของฉันคืนค่า 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

ลองออนไลน์!

มันทำงานอย่างไร

นี่ขึ้นอยู่กับคำตอบ Japtของฉันเป็นหลักในการสลับตัวอักษร

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 สำหรับการโพสต์เกือบจะเหมือนกับที่ฉันกำลังโพสต์ก่อนหน้าฉัน แต่ฉันต้องยืนยันนี่คืองานของฉันและฉันทำอย่างนี้ด้วยตัวเอง

ขึ้นอยู่กับคำตอบของ Julia โดย Alex A. ลองที่นี่


มีช่องว่างที่ไม่จำเป็นหลังจาก.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 118ไบต์

นี่คือฟังก์ชั่นที่ไม่ระบุชื่อ

[ >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

Ruby, 79 77 ไบต์

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

ยอมรับคำว่าจะทดสอบเป็นอาร์กิวเมนต์บรรทัดคำสั่ง ออกด้วยรหัส 0 (ซึ่งเป็นความจริงกับเชลล์) ถ้าอาร์กิวเมนต์เป็น palindrome ของตัวเอง atbash หรือด้วยรหัส 1 มิฉะนั้น


1
จะไม่ได้putsผลลัพธ์ที่สั้นกว่าการออกด้วยแบบไตรภาคหรือไม่?
แมว

FYI เป็นนามแฝงสำหรับ$* ARGV
จอร์แดน

1

Ruby, 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)))
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.