Mật mã lẻ / chẵn ASCII


13

Chúng tôi sẽ xác định Mã hóa lẻ / chẵn ASCII thông qua mã giả dưới đây:

Define 'neighbor' as the characters adjacent to the current letter in the string

If the one of the neighbors is out of bounds of the string, treat it as \0 or null

Take an input string

For each letter in the string, do
  If the 0-based index of the current letter is even, then
    Use the binary-or of the ASCII codes of both its neighbors
  Else
    If the ASCII code of the current letter is odd, then
      Use the binary-or of itself plus the left neighbor
    Else
      Use the binary-or of itself plus the right neighbor
  In all cases,
    Convert the result back to ASCII and return it
  If this would result in a code point 127 or greater to be converted, then
    Instead return a space

Join the results of the For loop back into one string and output it

Ví dụ, đối với đầu vào Hello, đầu ra là emmol, vì

  • Lần Hlượt \0 | 'e'e
  • Lần elượt 'e' | 'l', hoặc 101 | 108, đó là 109hoặcm
  • Đầu tiên lcũng chuyển sang 101 | 108hoặcm
  • Thứ hai lchuyển sang 108 | 111, đó là 111hoặco
  • Lần olượt đến 108 | \0, hoặcl

Đầu vào

  • Một câu chỉ gồm các ký tự ASCII có thể in được, ở bất kỳ định dạng phù hợp nào .
  • Câu có thể có dấu chấm, dấu cách và dấu câu khác, nhưng sẽ chỉ là một dòng.
  • Câu sẽ có ít nhất ba ký tự.

Đầu ra

  • Mật mã kết quả, dựa trên các quy tắc được mô tả ở trên, được trả về dưới dạng chuỗi hoặc đầu ra.

Những quy định

  • Hoặc là một chương trình đầy đủ hoặc một chức năng được chấp nhận.
  • Sơ hở tiêu chuẩn bị cấm.
  • Đây là vì vậy tất cả các quy tắc chơi gôn thông thường đều được áp dụng và mã ngắn nhất (tính bằng byte) sẽ thắng.

Ví dụ

Đầu vào trên một dòng, đầu ra trên sau. Dòng trống ví dụ riêng biệt.

Hello
emmol

Hello, World!
emmol, ww~ved

PPCG
PSWG

Programming Puzzles and Code Golf
r wogsmmoonpuu ~ meannncoooeggonl

abcdefghijklmnopqrstuvwxyz
bcfefgnijknmno~qrsvuvw~yzz

!abcdefghijklmnopqrstuvwxyz
aaccgeggoikkomoo qsswuww yy

Test 123 with odd characters. R@*SKA0z8d862
euutu133www|todddchizsscguwssr`jS{SK{z~|v66

3
Đây thực sự là một mật mã? Dường như không phải là một cách để giải mã nó.
đường ống

Cho rằng các othay đổi ltrong ví dụ đầu tiên, tôi khá chắc chắn rằng thông số kỹ thuật của bạn đảm bảo rằng lần đầu tiên okhông thay đổi thành ltrong ví dụ thứ hai. Nó nên thay đổi thành 'l' | ',', bất cứ điều gì, phải không?
Greg Martin

@pipe Vâng. Không thực sự là một "mật mã" nhưng, không thực sự chắc chắn nên gọi nó là gì. Nó cũng không thực sự là một hàm băm. Trong số các thẻ chúng tôi có, "mật mã" có vẻ gần nhất, vì vậy đó là những gì tôi đã sử dụng.
admBorkBork

@GregMartin Vâng, nó đi đến 'l' | ',', cái 108 | 44 --> 1101111 | 0101100nào trở thành 108, cái nào là l. Điều này ,xảy ra để phù hợp với l, vì vậy không có thay đổi khi nhị phân - hoặc diễn ra.
admBorkBork

Ồ, đó thực sự là nhị phân - HOẶC ... Tôi đã nghĩ về XOR nhị phân. Cảm ơn bạn đã làm rõ. Mặt khác, điều này thậm chí còn nói nhiều hơn với quan sát của ống rằng "mật mã" này thực sự không thể được giải mã, theo như tôi có thể nói.
Greg Martin

Câu trả lời:



4

Perl, 63 62 byte

Bao gồm +4 cho -lp

Cung cấp đầu vào trên STDIN

oddeven.pl:

#!/usr/bin/perl -lp
s%.%(--$|?$n|$':$&|(ord$&&1?$n:$'))&($n=$&,~v0)%eg;y;\x7f-\xff; ;

Điều này hoạt động như được hiển thị, nhưng để có được số điểm được yêu cầu, điều này phải được đặt trong một tệp không có; dòng cuối cùng và dòng mới và các \xhhlối thoát phải được thay thế bằng các giá trị theo nghĩa đen của chúng. Bạn có thể làm điều này bằng cách đặt mã ở trên vào tệp và chạy:

perl -0pi -e 's/\\x(..)/chr hex $1/eg;s/;\n$//' oddeven.pl

3

Python 2, 138 131 byte

s="\0%s\0"%input();r=''
for i in range(len(s)-2):L,M,R=map(ord,s[i:i+3]);a=i%2and[R,L][M%2]|M or L|R;r+=chr(a*(a<127)or 32)
print r

Dùng thử trực tuyến (chứa tất cả các trường hợp thử nghiệm)

Ít chơi gôn hơn:

def f(s):
    s="\0%s\0"%s
    r=''
    for i in range(1,len(s)-1):
        if i%2: # even (parity is changed by adding \x00 to the front)
            a=ord(s[i-1]) | ord(s[i+1])
        else:   # odd
            a=ord(s[i])
            if a%2: # odd
                a|=ord(s[i-1])
            else:   # even
                a|=ord(s[i+1])
        r+=chr(a if a<127 else 32)
    print r

Dùng thử trực tuyến (chưa được chỉnh sửa)

Tôi thêm \x00vào cả hai mặt của chuỗi để tôi không phải lo lắng về điều đó trong quá trình bit-bit. Tôi lặp theo các ký tự gốc của chuỗi, thực hiện các thao tác bitwise và thêm chúng vào kết quả, tuân theo các quy tắc cho tính chẵn lẻ.


Dang, tôi ghen tị với điều đó |=... tương đương trong PowerShell sẽ là$a=$a-bor$b
admBorkBork

@TimmyD Tôi thực sự không sử dụng nó, nhưng vâng. Nó đẹp. Nếu chỉ có Python thì a?b:cthích JS.
mbomb007

Bạn có thể thay thế nếu a% 2: # lẻ a | = ord (s [i-1]) khác: # thậm chí a | = ord (s [i + 1]) bằng a | = ord (s [i + 1- 2 * (a% 2)])
Không tin vào

@NoSeatbelts Đó là mã không mã hóa của tôi, sẽ được để nguyên như là cho mục đích dễ đọc. Trình golf là chương trình hàng đầu.
mbomb007

2

C - 101 byte

i,k;f(char*p){for(i=0;*p;++p,++i)putchar((k=i&1?*p&1?*p|p[-1]:*p|p[1]:i?p[-1]|p[1]:p[1])<127?k:' ');}

Chúng tôi thậm chí không phải kiểm tra xem đó có phải là mục cuối cùng trong chuỗi hay không bởi vì các chuỗi trong C bị chấm dứt null.

Giải trình

Khá đơn giản:

Sử dụng & 1 để kiểm tra các biểu thức lẻ / chẵn và ternary để thay thế if / elses. Tăng char * p để giảm số lượng ngoặc cần thiết.


Câu trả lời hay - chào mừng bạn đến với PPCG!
admBorkBork

2

Toán học, 152 byte

FromCharacterCode[BitOr@@Which[OddQ@Max@#2,#~Drop~{2},OddQ@#[[2]],Most@#,True,Rest@#]/._?(#>126&)->32&~MapIndexed~Partition[ToCharacterCode@#,3,1,2,0]]&

Giải trình

ToCharacterCode@#

Chuyển đổi chuỗi thành mã ASCII

Partition[...,3,1,2,0]

Phân vùng mã ASCII thành chiều dài 3, bù 1 phân vùng, với số 0 được đệm.

...~MapIndexed~...

Áp dụng một chức năng cho mỗi phân vùng.

Which[...]

If...else if... elsetrong Mathicala .

OddQ@Max@#2

Kiểm tra xem chỉ số (# 2) có lẻ không. ( Maxlà để làm phẳng); kể từ Mathematica chỉ số bắt đầu từ 1, tôi đã sử dụngOddQ ở đây, khôngEvenQ

Drop[#,{2}]

Lấy mã ASCII của hàng xóm bên trái và bên phải.

OddQ@#[[2]]

Kiểm tra xem mã ASCII của ký tự tương ứng có phải là số lẻ không.

Most@#

Lấy mã ASCII của nhân vật và hàng xóm bên trái.

Rest@#

Lấy mã ASCII của nhân vật và hàng xóm bên phải.

BitOr

Áp dụng hoặc hoạt động.

/._?(#>126&)->32

Thay thế tất cả các số lớn hơn 126 bằng 32 (dấu cách).

FromCharacterCode

Chuyển đổi mã ASCII trở lại ký tự và tham gia chúng.


Chào mừng đến với PPCG! Bạn có thể thêm một chút giải thích cho những người (như tôi), người không rành về Mathicala? Ngoài ra hãy chắc chắn kiểm tra Mẹo chơi golf trong Mathematica để biết một số gợi ý. Tận hưởng kì nghỉ của bạn!
admBorkBork

1
Một vài cải tiến: Chấp nhận và trả về danh sách các ký tự thay vì một đối tượng chuỗi thực sự là hoàn toàn tốt và tiết kiệm rất nhiều cho các From/ToCharacterCodechức năng đó. Sau đó, có vẻ như bạn Dropcó thể sử dụng ký hiệu infix : #~Drop~{2}. Và có vẻ như bạn đang áp dụng BitOrcho mọi đầu ra có thể của Whichvậy, tại sao không áp dụng nó sau đó và chỉ một lần?
Martin Ender

2

Ruby 133 128 108 106 byte

Jordan đã giúp tôi tiết kiệm 20 byte và cia_rana đã giúp tôi tiết kiệm 2 byte :)

->s{p s[-i=-1]+s.bytes.each_cons(3).map{|x,y,z|i+=1;a=i%2>0?x|z :y%2>0?y|x :y|z;a>126?' ':a.chr}*""+s[-2]}

s được lấy làm chuỗi đầu vào.

Ví dụ đầu ra với s="Test 123 with odd characters. R@*SKA0z8d862":

"euutu133www|todddchizsscguwssr`jS{SK{z~|v66"

Giải trình

Đoạn mã trên rất khó đọc nên đây là một lời giải thích. Mã này là một loại hacky, tôi mới thoát khỏi ruby ​​vì vậy tôi cá là có một cách ngắn hơn để làm điều này :)

b=s[1] # for the first character we always use the right neighbour
       # because `\0 | x` will always return x any way. 0 is the
       # left neighbour and x is the right neigbour
s.bytes.each_cons(3).with_index{|c,i| # oh boy, first we convert the string to ascii with each_byte
                                          # we then traverse the resulting array with three elements at
                                          # a time (so for example if s equals "Hello", c will be equal
                                          # to [72, 101, 108])
  if (i+1) % 2 < 1 # if the middle letter (which is considered our current letter) is even
    a = c[0] | c[2] # we use the result of binary-or of its neighbours
  else
    if c[1] % 2 > 0 # if the code of the current letter is odd
      a = c[1] | c[0] # we use the result of binary-or of itself and its left neighbour
    else
      a = c[1] | c[2] # we use the result of binary-or of itself and its right neighbour
    end
  end
  if a>126
    b<<' ' # if the result we use is greater or equal to 127 we use a space
  else
    b<<a.chr # convert the a ascii value back to a character
  end
}
p b+s[-2] # same as the first comment but now we know that x | \0 will always be x
          # this time x is the last characters left neighbour

Tôi khá chắc chắn đầu ra cần phải nằm trên một dòng, vì đầu vào cũng vậy.
mbomb007

@ mbomb007 bummer, sau đó tôi phải sử dụng printthay vì p: p
Linus

@TimmyD oh, vậy tôi không thể in nó ra đầu ra vào những thời điểm khác nhau?
Linus

@TimmyD ok, vậy ở trên có được phép không? Bây giờ nó in mọi thứ trên một dòng.
Linus

1
Bạn có thể viết như hình dưới đây:->s{p s[-i=-1]+s.bytes.each_cons(3).map{|x,y,z|i+=1;a=i%2>0?x|z :y%2>0?y|x :y|z;a>126?' ':a.chr}*""+s[-2]}
cia_rana

1

J, 42 byte

4:u:3({.OR{:)`((2|1&{){2:OR/\|.)\0,~0,3&u:

Sử dụng thuộc tính mà các động từ trong J có thể được áp dụng theo cách xen kẽ bằng cách sử dụng một gerund `cho một số trạng từ nhất định như infix\ .

Sử dụng

   f =: 4:u:3({.OR{:)`((2|1&{){2:OR/\|.)\0,~0,3&u:
   f 'Hello'
emmol
   f 'Hello, World!'
emmol,ww~ved
   f 'PPCG'
PSWG
   f 'Programming Puzzles and Code Golf'
rwogsmmoonpuu~meannncoooeggonl
   f 'abcdefghijklmnopqrstuvwxyz'
bcfefgnijknmno~qrsvuvw~yzz
   f '!abcdefghijklmnopqrstuvwxyz'
aaccgeggoikkomooqsswuwwyy
   f 'Test 123 with odd characters. R@*SKA0z8d862'
euutu133www|todddchizsscguwssr`jS{SK{z~|v66

Giải trình

4:u:3({.OR{:)`((2|1&{){2:OR/\|.)\0,~0,3&u:  Input: string S
                                      3&u:  Convert each char to an ordinal
                                    0,      Prepend 0
                                 0,~        Append 0
    3                           \           For each slice of size 3
     (      )`                                For the first slice (even-index)
          {:                                    Get the tail
      {.                                        Get the head
        OR                                      Bitwise OR the head and tail
             `(                )              For the second slice (odd-index)
                             |.                 Reverse the slice
                       2:   \                   For each pair
                         OR/                      Reduce using bitwise OR
                  1&{                           Get the middle value of the slice
                2|                              Take it modulo 2
                      {                         Index into the bitwise OR pairs and select
                                              Repeat cyclically for the remaining slices
4:u:                                        Convert each ordinal back to a char and return

1

JavaScript (ES6), 125 118 114 byte

Xấu hổ dài, nhưng charCodeAtString.fromCharCodemột mình là 29 byte. : - /

s=>[...s].map((_,i)=>String.fromCharCode((x=(C=i=>s.charCodeAt(i))((i-1)|1)|C(i+1-2*(C(i)&i&1)))>126?32:x)).join``

Làm thế nào nó hoạt động

Mỗi ký tự tại vị trí iđược dịch theo công thức sau, bao gồm tất cả các quy tắc cùng một lúc:

C((i - 1) | 1) | C(i + 1 - 2 * (C(i) & i & 1))

Ở đâu C(n) trả về mã ASCII của ký tự thứ n của chuỗi đầu vào.

Bản giới thiệu

let f =
    
s=>[...s].map((_,i)=>String.fromCharCode((x=(C=i=>s.charCodeAt(i))((i-1)|1)|C(i+1-2*(C(i)&i&1)))>126?32:x)).join``

console.log(f("Hello"));
console.log(f("Hello, World!"));
console.log(f("PPCG"));
console.log(f("Programming Puzzles and Code Golf"));
console.log(f("abcdefghijklmnopqrstuvwxyz"));
console.log(f("!abcdefghijklmnopqrstuvwxyz"));
console.log(f("Test 123 with odd characters. R@*SKA0z8d862"));


1

PHP, 107 97 byte

có lẽ là golf

for(;$i<strlen($s=$argv[1]);$i++)echo chr(ord($s[$i-1+$i%2])|ord($s[$i+1-2*($i&ord($s[$i])&1)]));

1

C #, 145 byte

s=>{var r=s[1]+"";int i=1,l=s.Length,c;for(;i<l;i++){c=i>l-2?0:s[i+1];c=i%2<1?s[i-1]|c:s[i]|(s[i]%2>0?s[i-1]:c);r+=c>'~'?' ':(char)c;}return r;};

Chương trình đầy đủ với phương pháp vô căn cứ và các trường hợp thử nghiệm:

using System;

namespace ASCIIOddEvenCipher
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<string,string>f= s=>
            {
                var r = s[1] + "";
                int i = 1, l = s.Length, c;
                for(;i < l; i++)
                {
                    c = i>l-2 ? 0 : s[i+1];
                    c = i%2<1 ? s[i-1]|c : s[i]|(s[i]%2>0 ? s[i-1] : c);
                    r += c > '~' ? ' ' : (char)c;
                }
                return r;
            };

            //test cases:
            Console.WriteLine(f("Hello"));  //emmol
            Console.WriteLine(f("Hello, World!"));  //emmol, ww~ved
            Console.WriteLine(f("PPCG"));   //PSWG
            Console.WriteLine(f("Programming Puzzles and Code Golf"));  //r wogsmmoonpuu ~ meannncoooeggonl
            Console.WriteLine(f("abcdefghijklmnopqrstuvwxyz")); //bcfefgnijknmno~qrsvuvw~yzz
            Console.WriteLine(f("!abcdefghijklmnopqrstuvwxyz"));    //aaccgeggoikkomoo qsswuww yy
            Console.WriteLine(f("Test 123 with odd characters. R@*SKA0z8d862"));    //euutu133www|todddchizsscguwssr`jS{SK{z~|v66
        }
    }
}

Điều này hóa ra dài hơn tôi nghĩ ...

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.