ASCII Tek / Çift Şifre


13

ASCII Tek / Çift Şifresini aşağıdaki sahte kod aracılığıyla tanımlayacağız :

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

Örneğin, giriş Hello, çıkış emmol, çünkü

  • HKıvrımın \0 | 'e'hangie
  • eDöner 'e' | 'l'ya da 101 | 108olan 109veyam
  • İlki layrıca 101 | 108veyam
  • İkinci lkıvrımın 108 | 111olduğu 111ya dao
  • oDöner 108 | \0, ya dal

Giriş

  • Herhangi bir uygun biçimde yalnızca yazdırılabilir ASCII karakterlerinden oluşan bir cümle .
  • Cümlenin noktaları, boşlukları ve diğer noktalama işaretleri olabilir, ancak yalnızca bir satır olacaktır.
  • Cümle en az üç karakter uzunluğunda olacaktır.

Çıktı

  • Ortaya çıkan şifre, yukarıda açıklanan kurallara dayanarak, bir dize veya çıktı olarak döndürülür.

Kurallar

  • Tam bir program veya bir işlev kabul edilebilir.
  • Standart boşluklar yasaktır.
  • Bu bu nedenle her zamanki golf kuralları geçerlidir ve en kısa kod (bayt cinsinden) kazanır.

Örnekler

Bir satırdan giriş, aşağıdaki satırdan çıkış. Boş satırlar örnekleri ayırır.

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
Bu gerçekten bir şifre mi? Bunu deşifre etmenin bir yolu gibi görünmüyor.
boru

İlk örnekte yapılan odeğişiklikler göz önüne alındığında, lteknik özelliklerinizin ilk örnekte ikinci örnekte odeğişmemesini sağladığından eminim l. Ne 'l' | ','olursa olsun değişmeli , değil mi?
Greg Martin

@pipe Evet. Gerçekten bir "şifre" değil, ama ne dediğimizden emin değilim. Gerçekten de bir karma değil. Elimizdeki etiketlerden "şifre" en yakın görünüyordu, işte bu yüzden gittim.
AdmBorkBork

Evet @GregMartin, bu gider 'l' | ','olan 108 | 44 --> 1101111 | 0101100hale geldiği, 108hangi l. ,İle hizaya olur l, böylece ikili-veya gerçekleştiğinde herhangi bir değişiklik yoktur.
AdmBorkBork

Oh, bu gerçekten ikili-VEYA ... Ben ikili-XOR düşünüyordum. Açıklama için teşekkürler. Öte yandan, bu, "bu şifrenin" gerçekten deşifre edemeyeceği gözlemine göre daha da çok şey anlatıyor.
Greg Martin

Yanıtlar:



4

Perl, 63 62 bayt

İçin +4 içerir -lp

STDIN'e giriş verin

oddeven.pl:

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

Bu şekilde gösterildiği gibi çalışır, ancak talep edilen puanı elde etmek için bu son ve yeni satır olmadan bir dosyaya konulmalı ;ve \xhhkaçışlar değişmez değerleriyle değiştirilmelidir. Bunu, yukarıdaki kodu dosyaya koyarak ve çalıştırarak yapabilirsiniz:

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

3

Python 2, 138131 bayt

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

Çevrimiçi deneyin (tüm test senaryolarını içerir)

Daha az 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

Çevrimiçi deneyin (ungolfed)

\x00Dize her iki tarafına eklemek , böylece bitwise veya ing sırasında bu konuda endişelenmenize gerek yok. Paritenin kurallarına uyarak, dizenin orijinal karakterleri boyunca döngü yapıyorum, bitsel işlemler yapıyor ve sonuca ekliyorum.


Dang, bunu kıskanıyorum |=... PowerShell'de eşdeğer olur$a=$a-bor$b
AdmBorkBork

@TimmyD Aslında onu kullanmadım, ama evet. Bu iyi. Keşke Python'un JS'si olsaydı a?b:c.
mbomb007

% 2: # tek bir | = ord (s [i-1]) başkaysa: # bile bir | = ord (s [i + 1]) ile bir = = ord (s [i + 1-) 2 * (a% 2)])
NoSeatbelts

@NoSeatbelts Okunabilirlik amacıyla olduğu gibi bırakılacak olan kodlanmamış kodum bu. Golfçü başvuru en iyi programdır.
mbomb007

2

C - 101 bayt

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:' ');}

C'deki dizelerin boş olduğu için dizede son öğe olup olmadığını kontrol etmek zorunda bile değiliz.

açıklama

Oldukça basit:

Eğer / else yerine tek / eşitliği ve üçlü ifadeleri test etmek için & 1 kullanın. Gereken köşeli parantez sayısını azaltmak için karakteri * p artırın.


Güzel cevap - PPCG'ye hoş geldiniz!
AdmBorkBork

2

Mathematica, 152 bayt

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

açıklama

ToCharacterCode@#

Dizeyi ASCII kodlarına dönüştürür

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

ASCII kodlarını dolgulu 0'larla uzunluk 3, ofset 1 bölümlere ayırır.

...~MapIndexed~...

Her bölüm için bir işlev uygular.

Which[...]

If...else if... elseiçinde Mathematica .

OddQ@Max@#2

Dizinin (# 2) tek olup olmadığını kontrol eder. ( Maxdüzleştirme içindir); Mathematica endeksi 1'de başladığından beri OddQburada kullandım , değilEvenQ

Drop[#,{2}]

Sol ve sağ komşuların ASCII kodlarını alır.

OddQ@#[[2]]

İlgili karakterin ASCII kodunun tek olup olmadığını kontrol eder.

Most@#

Karakterin ve sol komşunun ASCII kodlarını alır.

Rest@#

Karakterin ve sağ komşunun ASCII kodlarını alır.

BitOr

Uygulama veya işlemi uygular.

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

126'dan büyük tüm sayıları 32 (boşluk) ile değiştirir.

FromCharacterCode

ASCII kodunu tekrar karakterlere dönüştürür ve birleştirir.


PPCG'ye Hoşgeldiniz! Mathematica'da iyi bilgili olmayan insanlar (benim gibi) için biraz açıklama ekleyebilir misiniz? Ayrıca bazı öneriler için Mathematica'da golf için ipuçları 'a göz atmayı unutmayın . Keyfini çıkarın!
AdmBorkBork

1
Birkaç iyileştirme: Gerçek bir dize nesnesi yerine bir karakter listesi kabul etmek ve döndürmek tamamen iyidir ve bu From/ToCharacterCodeişlevlerde çok fazla tasarruf sağlar. Sonra sizin gibi görünüyor Dropkutu kullanım infix gösterimde: #~Drop~{2}. Ve öyle görünüyor ki, BitOrolası tüm çıktılara başvuruyorsunuz , Whicho zaman neden daha sonra ve sadece bir kez uygulamıyorsunuz?
Martin Ender

2

Yakut 133 128 108 106 bayt

Ürdün 20 bayt kurtarmama yardım etti ve cia_rana 2 bayt kurtarmama yardım etti :)

->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 girdi dizesi olarak alınır.

Örnek çıktı s="Test 123 with odd characters. R@*SKA0z8d862":

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

açıklama

Yukarıdaki kod çok okunamıyor, bu yüzden burada bir açıklama var. Kod tür hileli, yakut için yeni çıkıyorum bu yüzden bunu yapmanın daha kısa bir yolu var eminim :)

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

Girdi de olduğundan, çıktı bir satırda olması gerektiğinden oldukça eminim.
mbomb007

@ mbomb007 bummer, o zaman printyerine kullanmak zorundayım p: p
Linus

@TimmyD oh, bu yüzden farklı zamanlarda çıktıya yazdıramıyorum?
Linus

@TimmyD tamam, yukarıdakilere izin veriliyor mu? Artık her şeyi tek bir satıra yazdırıyor.
Linus

1
Aşağıda gösterildiği gibi yazabilirsiniz:->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 bayt

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

J'deki fiillerin `infix gibi belirli zarflar için bir mikrop kullanılarak alternatif bir şekilde uygulanabileceği özelliği kullanır \.

kullanım

   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

açıklama

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 bayt

Utanç verici uzun ama charCodeAtve String.fromCharCodeyalnız 29 bayt vardır. : - /

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

Nasıl çalışır

Konumdaki her karakter, itüm kuralları bir kerede kapsayan aşağıdaki formülle çevrilir:

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

Burada C(n), giriş dizesinin n'inci karakterinin ASCII kodunu döndürür.

gösteri

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 bayt

muhtemelen golf oynayabilir.

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 bayt

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

Golfsiz yöntem ve test senaryoları ile tam program:

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

Bu düşündüğümden daha uzun çıktı ...

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.