Dịch chuyển ca làm việc


13

Sự miêu tả

Một ca Caesar là một mật mã đơn âm rất đơn giản trong đó mỗi chữ cái được thay thế bằng một chữ cái sau nó trong bảng chữ cái. Thí dụ:

Hello world! -> IFMMP XPSME!

( IBSLR, EGUFV!là đầu ra cho thử thách thực tế, đây là một ví dụ về dịch chuyển bằng 1.)

Như bạn có thể thấy, khoảng cách và dấu chấm câu vẫn không được đánh dấu. Tuy nhiên, để tránh việc đoán tin nhắn, tất cả các chữ cái đều được viết hoa. Bằng cách chuyển các chữ cái trở lại, tin nhắn đã được giải mã, thuận tiện, nhưng cũng thực sự dễ dàng giải mã bởi những người được cho là không biết tin nhắn có nghĩa là gì.

Vì vậy, chúng tôi sẽ giúp Caesar một chút bằng cách sử dụng một hình thức mật mã nâng cao của anh ấy: Dịch chuyển Caesar tự dịch chuyển !

Thử thách

Nhiệm vụ của bạn là viết một chương trình hoặc hàm, được cung cấp một chuỗi để mã hóa, đưa ra chuỗi được mã hóa tương ứng với đầu vào. Ca Caesar tiên tiến hoạt động như thế này:

1. Compute letter differences of all adjacent letters: 
    1.1. Letter difference is computed like this:

         Position of 2nd letter in the alphabet
        -Position of 1st letter in the alphabet
        =======================================
                              Letter difference

    1.2. Example input: Hello
         H - e|e -  l|l  -  l|l  -  o
         7 - 5|5 - 12|12 - 12|12 - 15 Letter differences: 3; -7; 0; -3
            =3|   =-7|     =0|    =-3

2. Assign the letters continously a letter difference from the list,
   starting at the second letter and inverting the differences:
    2.1. 2nd letter: first difference, 3rd letter: second difference, etc.

    2.2. The first letter is assigned a 1.

    2.3. Example input: Hello with differences 3; -7; 0; -3

         Letter || Value
         =======||======
            H   ||   1
            E   ||  -3
            L   ||   7
            L   ||   0
            O   ||   3

3. Shift the letters by the value x they have been assigned:
    3.1. In case of a positive x, the letter is shifted x letters to the right.
    3.2. In case of a negative x, the letter is shifted |x| letters to the left.
    3.3. In case of x = 0, the letter is not shifted.

    3.4. If the shift would surpass the limits of the alphabet, it gets wrapped around
         Example: Y + Shift of 2 --> A

    3.5. Example input: See the table under 2.3.

                ||       || Shifted
         Letter || Value || Letter
         =======||=======||=========
            H   ||   1   ||    I
            E   ||  -3   ||    B     Program output:
            L   ||   7   ||    S     IBSLR
            L   ||   0   ||    L
            O   ||   3   ||    R

Dấu cách và các ký hiệu đặc biệt khác, chẳng hạn như dấu chấm câu được bỏ qua trong quy trình này. Đảm bảo rằng chương trình của bạn sẽ được cung cấp một chuỗi chỉ chứa các ký tự ASCII có thể in được. Đầu ra của chức năng / chương trình của bạn chỉ phải ở dạng chữ hoa.

Đây là , vì vậy các sơ hở tiêu chuẩn được áp dụng và có thể câu trả lời ngắn nhất bằng byte sẽ thắng!


2
Có phải không E -3?
Leaky Nun

3
Điều gì xảy ra nếu sự khác biệt chữ cái mang chữ cái ra khỏi bảng chữ cái? Giống như ZEN, ví dụ. Zthay đổi 1 là ... A? (như một ghi chú bên lề, câu trả lời 05AB1E biến Zthành A)
Ông Xcoder

6
Xin vui lòng kiểm tra trường hợp. Ngoài ra, những nhân vật được bỏ qua chính xác? Và nó có nghĩa gì đối với họ bị bỏ qua? Chúng có bị loại bỏ hoàn toàn không, hay chúng phải ở lại đầu ra?
Luis Mendo

1
@Giuseppe xem các câu trả lời nâng cao cho các trường hợp thử nghiệm, chúng đã được OP xác nhận là chính xác, tôi giả sử hoặc chúng có các điểm hạ gục.
Bạch tuộc ma thuật Urn

2
Ý của bạn là những từ như RELIEFRELIEScả hai đều mã hóa cho cùng một kết quả SRSFAG?
Anders Kaseorg

Câu trả lời:


5

05AB1E , 28 27 24 byte

láÇ¥R`XIlvyaiAyk+Aèëy}u?

Hãy thử trực tuyến!

Giải trình

l                          # convert input to lower case
 á                         # keep only letters
  ǥ                       # compute deltas of character codes
    R`                     # reverse and push separated to stack
      X                    # push 1
       Ilv                 # for each char y in lower case input
          yai              # if y is a letter
             Ayk           # get the index of y in the alphabet
                +          # add the next delta
                 Aè        # index into the alphabet with this
            ëy             # else push y
              }            # end if
            u?             # print as upper case

Cả hai chúng tôi get IBSLR, EGUFV!cho Hello, World!, đó là đúng? Có phải OP vừa làm hỏng ví dụ đó?
Bạch tuộc ma thuật Urn

1
@MagicOctopusUrn: Ví dụ của anh ấy lúc đầu chỉ là cho thấy sự thay đổi là gì. Nó chỉ thay đổi 1 chữ cái nên khá sai lệch.
Emigna

4

Python 3 , 100 byte

b=0
for c in map(ord,input().upper()):
 if 64<c<91:b,c=c,(c+c-(b or~-c)-65)%26+65
 print(end=chr(c))

Hãy thử trực tuyến!

btheo dõi mã ASCII của chữ cái cuối, hoặc ban đầu bằng không; công thức c+c-(b or~-x)có nghĩa là một chữ cái có mã ASCII cđược dịch chuyển bởi c-bif bkhác không và c-(c-1) == +1nếu bbằng 0 (đối với chữ cái đầu tiên).

bsẽ không bao giờ trở thành số 0 nữa, vì chuỗi được đảm bảo bao gồm các ký tự ASCII có thể in được .

Cuối cùng, 64<c<91kiểm tra xem ccó phải là một chữ cái ASCII viết hoa không và (…-65)%26+65bao bọc mọi thứ trở lại A-Zphạm vi.

ovs lưu một byte. Cảm ơn!





1

MATL , 27 byte

tXkt1Y2mXH)tlwdh+64-lY2w)H(

Hãy thử trực tuyến!

Tôi nghĩ rằng đây là thời gian ngắn nhất tôi có thể nhận được, nhưng có rất nhiều loại khác nhau vì có rất nhiều lần sử dụng lại 'biến' (có 3 t(sao chép) và 2 thao tác w(hoán đổi), clipboard Hđược sử dụng và thậm chí sau đó vẫn còn một bản sao 1Y2...). Đáng buồn thay, tôi không thể lưu byte với Mbảng tạm tự động .

Hơn một nửa chương trình được dành riêng để làm cho chữ hoa và bỏ qua các ký tự không phải là chữ cái - chỉ mật mã là không quá 13 byte ( Hãy thử trực tuyến! )


1

Perl, 90 89

Mặc dù các ngôn ngữ không phải là codegolf hiếm khi cạnh tranh, chúng ta có thể xuống dưới 100;)

@a=split//,<>;say uc(++$a[0]).join'',map{uc chr(2*ord($a[$_+1])-ord($a[$_])+!$_)}0..$#a-1

Tôi đã quyết định hủy bỏ điều này:

@a = split//,<>; Lấy đầu vào từ STDIN, lưu danh sách ký tự (với dòng mới!) Trong @a.

say uc(++$a[0])chữ hoa đầu ra chữ cái đầu tiên được dịch chuyển bởi 1. Hóa ra bạn có thể tăng một chữ cái trong perl nếu bạn sử dụng tiền tố ++. Đây là một đột biến ofc.

2*ord($a[$_+1])-ord($a[$_])+!$_Chúng tôi được yêu cầu lấy ký tự tại x và thêm chênh lệch + (x- (x-1)). Vâng, đó là 2x - (x-1). Tuy nhiên: Tôi đã thay đổi chữ cái đầu tiên! Vì vậy, tôi đã phải sửa lỗi đó, do đó +!$_, sẽ sửa lỗi vì đã trừ đi quá nhiều lỗi ở vị trí 0 (trường hợp duy nhất! $ _ Không phải là không chính xác). Sau đó, chúng tôi uc chrsẽ nhận được một chữ cái viết hoa từ giá trị ASCII được tính toán.

map{ ... } $#a-2- $#alà vị trí để truy cập phần tử mảng cuối cùng. Vì tôi đang thêm một cái tôi muốn $#a-1, nhưng vì dòng mới từ đầu vào cần bỏ qua, nên đây là $#a-2.

Điều này được nối với chữ cái đầu tiên, và chúng ta đã hoàn thành :)


Điều này dường như có một số vấn đề liên quan đến việc bù đắp xung quanh bảng chữ cái và với các ký tự không phải là chữ cái. Hãy thử trực tuyến!
Xcali

1

Perl 5 -F , 73 77 74 byte

/\w/&&($_=chr 65+(2*($n=ord uc)-65-($!||-1+ord uc))%26)&($!=$n)for@F;say@F

Hãy thử trực tuyến!


Điều này không hoàn toàn bỏ qua các chữ cái; nó chỉ không chuyển đổi chúng. Tôi nghĩ Hello, World!nên có kết quả IBSLR, EGUFV!, không IBSLR, XGUFV!.
Tít

Bạn đúng. Đã sửa nó với 4 byte nữa để giữ chữ cái trước đó.
Xcali

1

PHP, 106 98 byte

khá là khó chịu khi một người ... nếu chỉ là base_convertkhông lâu (hoặc ctype_alpha) ...
nhưng tôi đã nhận được nó dưới 100. hài lòng.

for(;$a=ord($c=$argn[$i++]);print ctype_alpha($c)?chr(65+($p?(25-$p+2*$p=$a)%26:$p=$a)):$c)$a&=31;

Chạy như ống với -nRhoặc thử trực tuyến .


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.