ASCII Ganjil / Genap Cipher

13

Kami akan mendefinisikan ASCII Odd / Even Cipher melalui pseudocode di bawah ini:

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

Misalnya, untuk input Hello, outputnya adalah emmol, sejak

  • The Hbergantian untuk \0 | 'e'yange
  • The eberubah menjadi 'e' | 'l', atau 101 | 108, yang 109ataum
  • Yang pertama ljuga berubah menjadi 101 | 108ataum
  • Yang kedua lberubah menjadi 108 | 111, yaitu 111atauo
  • The oberubah menjadi 108 | \0, ataul

Memasukkan

  • Sebuah kalimat yang hanya terdiri dari karakter ASCII yang dapat dicetak, dalam format apa pun yang sesuai .
  • Kalimat tersebut mungkin memiliki titik, spasi, dan tanda baca lainnya, tetapi hanya akan menjadi satu baris.
  • Panjang kalimat setidaknya tiga karakter.

Keluaran

  • Cipher yang dihasilkan, berdasarkan aturan yang dijelaskan di atas, dikembalikan sebagai string atau output.

Aturan

  • Program lengkap atau fungsi dapat diterima.
  • Celah standar dilarang.
  • Ini adalah sehingga semua aturan golf biasa berlaku, dan kode terpendek (dalam byte) menang.

Contohnya

Input pada satu baris, output pada baris berikut. Baris kosong memisahkan contoh.

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
AdmBorkBork
sumber
3
Apakah ini benar-benar sandi? Tampaknya bukan cara untuk menguraikannya.
pipa
Mengingat bahwa operubahan lpada contoh pertama, saya cukup yakin spesifikasi Anda memastikan bahwa yang pertama otidak berubah lpada contoh kedua. Itu harus berubah menjadi 'l' | ',', apa pun itu, kan?
Greg Martin
@pipe Ya. Tidak benar-benar "sandi" tetapi, tidak benar-benar yakin harus menyebutnya apa. Ini bukan hash juga. Dari tag yang kami miliki, "sandi" tampak paling dekat, jadi itulah yang saya gunakan.
AdmBorkBork
@GregMartin Ya, ia pergi ke 'l' | ',', yang 108 | 44 --> 1101111 | 0101100, yang menjadi 108, yang l. The ,terjadi untuk berbaris dengan l, jadi tidak ada perubahan saat biner-atau berlangsung.
AdmBorkBork
Oh, ini benar-benar biner-ATAU ... Saya sedang memikirkan biner-XOR. Terimakasih atas klarifikasinya. Di sisi lain, ini berbicara lebih jauh ke pengamatan pipa bahwa "sandi" ini tidak bisa benar-benar diuraikan, sejauh yang saya tahu.
Greg Martin

Jawaban:

1

Jelly , 33 31 byte

2ịḂị|2\
|ṚḢ,Ç
O0,0jṡ3µÇ€⁸JḂ¤ị"Ọ

Pendekatan langsung yang pasti bisa dibuat lebih pendek.

Cobalah online!

mil
sumber
4

Perl, 63 62 byte

Termasuk +4 untuk -lp

Berikan masukan pada STDIN

oddeven.pl:

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

Ini berfungsi seperti yang ditunjukkan, tetapi untuk mendapatkan skor yang diklaim ini harus dimasukkan ke dalam file tanpa akhir ;dan baris baru dan \xhhlolos harus diganti dengan nilai literalnya. Anda dapat melakukan ini dengan meletakkan kode di atas dalam file dan menjalankan:

perl -0pi -e 's/\\x(..)/chr hex $1/eg;s/;\n$//' oddeven.pl
Ton Hospel
sumber
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

Cobalah secara online (berisi semua kasus uji)

Kurang golf:

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

Coba online (tidak disunat)

Saya menambahkan \x00ke kedua sisi string sehingga saya tidak perlu khawatir tentang itu selama bitwise atau ing. Saya mengulangi karakter asli string, melakukan operasi bitwise dan menambahkannya ke hasilnya, mengikuti aturan paritas.

mbomb007
sumber
Dang, aku iri dengan itu |=... setara di PowerShell akan$a=$a-bor$b
AdmBorkBork
@ TimmyD Saya sebenarnya tidak menggunakannya, tapi ya. Itu bagus. Andai saja Python a?b:cseperti JS.
mbomb007
Anda dapat mengganti jika% 2: # odd a | = ord (s [i-1]) lain: # even a | = ord (s [i + 1]) dengan a | = ord (s [i + 1- 2 * (a% 2)])
NoSeatbelts
@NoSeatbelts Itu adalah kode unungolfed saya, yang akan dibiarkan apa adanya untuk tujuan keterbacaan. Pengajuan golf adalah program teratas.
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:' ');}

Kami bahkan tidak perlu memeriksa apakah itu item terakhir dalam string karena string dalam C diakhiri null.

Penjelasan

Agak sederhana:

Gunakan & 1 untuk menguji ekspresi aneh / merata dan ternary untuk menggantikan if / elses. Tambahkan char * p untuk mengurangi jumlah tanda kurung yang diperlukan.

NoSeatbelts
sumber
Jawaban yang bagus - selamat datang di PPCG!
AdmBorkBork
2

Mathematica, 152 byte

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

Penjelasan

ToCharacterCode@#

Mengubah string menjadi kode ASCII

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

Partisi kode ASCII dengan panjang 3, offset 1 partisi, dengan 0s empuk.

...~MapIndexed~...

Menerapkan fungsi untuk setiap partisi.

Which[...]

If...else if... else di Mathematica .

OddQ@Max@#2

Cek apakah indeks (# 2) ganjil. ( Maxuntuk perataan); sejak Mathematica indeks dimulai pada 1, saya gunakan di OddQsini, tidakEvenQ

Drop[#,{2}]

Mengambil kode ASCII dari tetangga kiri dan kanan.

OddQ@#[[2]]

Cek apakah kode ASCII dari karakter yang sesuai aneh.

Most@#

Mengambil kode karakter ASCII dan tetangga kiri.

Rest@#

Mengambil kode karakter ASCII dan tetangga kanan.

BitOr

Berlaku atau beroperasi.

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

Ganti semua angka yang lebih besar dari 126 dengan 32 (spasi).

FromCharacterCode

Mengonversi kode ASCII kembali ke karakter dan bergabung dengan mereka.

JungHwan Min
sumber
Selamat datang di PPCG! Bisakah Anda menambahkan sedikit penjelasan untuk orang-orang (seperti saya) yang tidak berpengalaman dalam Mathematica? Pastikan juga untuk melihat Tips bermain golf di Mathematica untuk beberapa saran. Selamat menikmati!
AdmBorkBork
1
Beberapa peningkatan: Menerima dan mengembalikan daftar karakter dan bukannya objek string yang sebenarnya baik - baik saja dan menyimpan banyak From/ToCharacterCodefungsi. Maka tampak seperti Anda Dropdapat notasi penggunaan infiks: #~Drop~{2}. Dan tampaknya Anda menerapkan BitOruntuk setiap kemungkinan hasil Whichjadi mengapa tidak menerapkannya setelah itu dan hanya sekali?
Martin Ender
2

Ruby 133 128 108 106 byte

Jordan membantu saya menghemat 20 byte dan cia_rana membantu saya menghemat 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 diambil sebagai string input.

Contoh output dengan s="Test 123 with odd characters. R@*SKA0z8d862":

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

Penjelasan

Kode di atas sangat tidak terbaca jadi inilah penjelasannya. Kode ini agak retas, saya berhenti baru ke ruby ​​jadi saya yakin ada cara yang lebih pendek untuk melakukan ini :)

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
Linus
sumber
Saya cukup yakin bahwa output harus berada pada satu baris, karena inputnya juga.
mbomb007
@ mbomb007 Nyebelin, maka saya harus menggunakan printbukannya p: p
Linus
@ TimmyD oh, jadi saya tidak bisa mencetaknya ke output di waktu yang berbeda?
Linus
@ TimmyD ok, jadi hal di atas diizinkan? Sekarang mencetak semuanya dalam satu baris.
Linus
1
Anda dapat menulis seperti yang ditunjukkan di bawah ini:->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:

Menggunakan properti yang kata kerja dalam J dapat diterapkan secara bergantian menggunakan gerund `untuk kata keterangan tertentu seperti infiks \.

Pemakaian

   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

Penjelasan

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
mil
sumber
1

JavaScript (ES6), 125 118 114 byte

Memalukan lama, tapi charCodeAtdan String.fromCharCodesaja yang 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``

Bagaimana itu bekerja

Setiap karakter pada posisi iditerjemahkan dengan rumus berikut, yang mencakup semua aturan sekaligus:

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

di mana C(n)mengembalikan kode ASCII dari karakter ke-n dari string input.

Demo

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"));

Arnauld
sumber
1

PHP, 107 97 byte

mungkin 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)]));
Titus
sumber
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;};

Program lengkap dengan metode ungolfed dan uji kasus:

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

Ini ternyata lebih lama dari yang saya kira ...

adrianmp
sumber