ASCII Odd / Even Cipher


13

Wir definieren den ASCII Odd / Even Cipher über den folgenden Pseudocode:

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

Beispielsweise ist für die Eingabe Hellodie Ausgabe emmolda

  • Der Hdreht sich um\0 | 'e' was zue
  • Das edreht sich um 'e' | 'l', oder 101 | 108, was ist109 oderm
  • Der erste lwendet sich auch an 101 | 108oderm
  • Die Sekunde ldreht sich um 108 | 111, welche 111oder isto
  • Der owendet sich an 108 | \0, oderl

Eingang

  • Ein Satz, der ausschließlich aus druckbaren ASCII-Zeichen in einem geeigneten Format besteht .
  • Der Satz kann Punkte, Leerzeichen und andere Satzzeichen enthalten, besteht jedoch immer nur aus einer Zeile.
  • Der Satz besteht aus mindestens drei Zeichen.

Ausgabe

  • Die resultierende Chiffre, die auf den oben beschriebenen Regeln basiert, wird als Zeichenfolge oder Ausgabe zurückgegeben.

Die Regeln

  • Es ist entweder ein vollständiges Programm oder eine Funktion zulässig.
  • Standardlücken sind verboten.
  • Dies ist daher gelten alle üblichen Golfregeln, und der kürzeste Code (in Byte) gewinnt.

Beispiele

Eingabe in einer Zeile, Ausgabe in der folgenden Zeile. Leerzeilen trennen Beispiele.

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
Ist das wirklich eine Chiffre? Scheint kein Weg zu sein, es zu entziffern.
Pipe

Angesichts der oÄnderungen lim ersten Beispiel bin ich mir ziemlich sicher, dass Ihre Spezifikationen sicherstellen, dass sich im zweiten Beispiel die erste onicht ändert l. Es sollte sich ändern zu 'l' | ',', was auch immer das ist, oder?
Greg Martin

@pipe Ja. Nicht wirklich eine "Chiffre", aber nicht wirklich sicher, wie man es nennt. Es ist auch kein wirklicher Hasch. Von den Tags, die wir haben, schien "Chiffre" am nächsten zu sein, also ging ich damit um.
AdmBorkBork

@ GregMartin Ja, es geht darum 'l' | ',', was ist 108 | 44 --> 1101111 | 0101100, was wird 108, was ist l. Das ,stimmt mit dem lüberein, es ändert sich also nichts, wenn das Binary-or stattfindet.
AdmBorkBork

Oh, es ist wirklich die binäre ODER-Verknüpfung. Ich dachte an die binäre XOR-Verknüpfung. Danke für die Abklärung. Auf der anderen Seite spricht dies umso mehr für Pipes Beobachtung, dass diese "Chiffre", soweit ich das beurteilen kann, nicht wirklich entschlüsselt werden kann.
Greg Martin

Antworten:



4

Perl, 63 62 Bytes

Beinhaltet +4 für -lp

Geben Sie eine Eingabe für STDIN ein

oddeven.pl:

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

Dies funktioniert wie gezeigt, aber um die beanspruchte Punktzahl zu erhalten, muss diese in eine Datei ohne End- ;und Zeilenumbruch eingefügt werden und die Escapezeichen \xhhmüssen durch ihre Literalwerte ersetzt werden. Sie können dies tun, indem Sie den obigen Code in die Datei einfügen und ausführen:

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

3

Python 2, 138 131 Bytes

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

Online testen (enthält alle Testfälle)

Weniger golfen:

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

Probieren Sie es online (ungolfed)

Ich füge \x00beide Seiten des Strings hinzu, damit ich mich beim bitweisen Or-ing nicht darum kümmern muss. Ich durchlaufe die ursprünglichen Zeichen der Zeichenfolge, führe bitweise Operationen durch und füge sie dem Ergebnis hinzu, wobei ich die Regeln für die Parität befolge.


Dang, ich bin eifersüchtig |=... Äquivalent in PowerShell wäre$a=$a-bor$b
AdmBorkBork

@TimmyD Ich habe es eigentlich nicht benutzt, aber ja. Es ist schön. Wenn nur Python a?b:cwie JS hätte.
mbomb007

Sie können ersetzen, wenn a% 2: # ungerade a | = ord (s [i-1]) sonst: # gerade a | = ord (s [i + 1]) mit a | = ord (s [i + 1]) 2 * (a% 2)])
NoSeatbelts

@NoSeatbelts Das ist mein ungolfed Code, der aus Gründen der Lesbarkeit unverändert bleibt. Die Golf-Einreichung ist das Top-Programm.
mbomb007

2

C - 101 Bytes

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

Wir müssen nicht einmal prüfen, ob es sich um das letzte Element in der Zeichenfolge handelt, da die Zeichenfolgen in C mit Nullen abgeschlossen sind.

Erläuterung

Ziemlich einfach:

Verwenden Sie & 1, um nach ungeraden / geraden und ternären Ausdrücken zu suchen, die if / elses ersetzen sollen. Erhöhen Sie das Zeichen * p, um die Anzahl der erforderlichen Klammern zu verringern.


Schöne Antwort - Willkommen bei PPCG!
AdmBorkBork

2

Mathematica, 152 Bytes

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

Erläuterung

ToCharacterCode@#

Konvertiert Zeichenfolgen in ASCII-Codes

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

Partitioniert die ASCII-Codes auf Länge 3, versetzt 1 Partitionen mit aufgefüllten Nullen.

...~MapIndexed~...

Wendet eine Funktion für jede Partition an.

Which[...]

If...else if... elsein Mathematica .

OddQ@Max@#2

Überprüft, ob der Index (# 2) ungerade ist. ( Maxdient zum Abflachen); Da der Mathematica- Index bei 1 beginnt, habe ich OddQhier nicht verwendetEvenQ

Drop[#,{2}]

Übernimmt die ASCII-Codes der linken und rechten Nachbarn.

OddQ@#[[2]]

Überprüft, ob der ASCII-Code des entsprechenden Zeichens ungerade ist.

Most@#

Übernimmt die ASCII-Codes des Zeichens und des linken Nachbarn.

Rest@#

Übernimmt die ASCII-Codes des Zeichens und des rechten Nachbarn.

BitOr

Wendet or-operation an.

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

Ersetzt alle Zahlen größer als 126 durch 32 (Leerzeichen).

FromCharacterCode

Konvertiert den ASCII-Code zurück in Zeichen und fügt sie hinzu.


Willkommen bei PPCG! Könnten Sie ein paar Erklärungen für Leute (wie mich) hinzufügen, die sich mit Mathematica nicht auskennen? Lesen Sie auch die Tipps zum Golfen in Mathematica, um Vorschläge zu erhalten. Genieße deinen Aufenthalt!
AdmBorkBork

1
Einige Verbesserungen: Das Akzeptieren und Zurückgeben einer Liste von Zeichen anstelle eines tatsächlichen Zeichenfolgenobjekts ist völlig in Ordnung und spart viel an diesen From/ToCharacterCodeFunktionen. Dann sieht es aus wie Ihre DropDose Verwendung Infixschreibweise: #~Drop~{2}. Und es scheint, dass Sie sich bewerbenBitOr auf jede mögliche Ausgabe von Whichanwenden, warum also nicht danach und nur einmal anwenden?
Martin Ender

2

Ruby 133 128 108 106 Bytes

Jordan hat mir geholfen, 20 Bytes zu sparen und cia_rana hat mir geholfen, 2 Bytes zu sparen :)

->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 wird als Eingabezeichenfolge verwendet.

Beispielausgabe mit s="Test 123 with odd characters. R@*SKA0z8d862":

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

Erläuterung

Der obige Code ist sehr unlesbar, daher hier eine Erklärung. Der Code ist irgendwie hacky, ich bin ganz neu in Ruby, also gibt es bestimmt einen kürzeren Weg, dies zu tun :)

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

Ich bin mir ziemlich sicher, dass die Ausgabe in einer Zeile erfolgen muss, da auch die Eingabe erfolgt.
mbomb007

@ mbomb007 blöd, dann muss ich printstatt p: p
Linus

@TimmyD oh, also kann ich es nicht zu verschiedenen Zeiten auf die Ausgabe drucken?
Linus

@TimmyD ok, obiges ist also erlaubt? Jetzt wird alles in einer Zeile gedruckt.
Linus

1
Sie können wie ->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]}
folgt

1

J, 42 Bytes

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

Verwendet die Eigenschaft, dass Verben in J alternierend mit einem Gerund angewendet werden können ` für bestimmte Adverbien wie Infix\ .

Verwendung

   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

Erläuterung

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

Peinlich lang, aber charCodeAtund String.fromCharCodesind allein 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``

Wie es funktioniert

Jedes Zeichen an der Position iwird mit der folgenden Formel übersetzt, die alle Regeln gleichzeitig abdeckt:

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

Dabei wird C(n)der ASCII-Code des n-ten Zeichens der Eingabezeichenfolge zurückgegeben.

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


1

PHP, 107 97 Bytes

wahrscheinlich golfen.

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

145 Bytes

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

Volles Programm mit ungolfed Methode und Testfällen:

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

Es stellte sich heraus, dass dies länger war als ich dachte ...

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.