ASCII Odd/Even Cipher
Perl, 63 62 bytes
Includes +4 for -lp
Give input on STDIN
oddeven.pl
:
#!/usr/bin/perl -lp
s%.%(--$|?$n|$':$&|(ord$&&1?$n:$'))&($n=$&,~v0)%eg;y;\x7f-\xff; ;
This works as shown, but to get the claimed score this must be put in a file without final ;
and newline and the \xhh
escapes must be replaced by their literal values. You can do this by putting the code above in the file and running:
perl -0pi -e 's/\\x(..)/chr hex $1/eg;s/;\n$//' oddeven.pl
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
Try it online (contains all test cases)
Less golfed:
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
Try it online (ungolfed)
I add \x00
to both sides of the string so that I don't have to worry about that during bitwise or-ing. I loop along the string's original characters, doing bitwise operations and adding them to the result, following the rules for parity.
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]]&
Explanation
ToCharacterCode@#
Converts string to ASCII codes
Partition[...,3,1,2,0]
Partitions the ASCII codes to length 3, offset 1 partitions, with padded 0s.
...~MapIndexed~...
Applys a function for each partition.
Which[...]
If...else if... else
in Mathematica.
OddQ@Max@#2
Checks whether the index (#2) is odd. (Max
is for flattening); since Mathematica index starts at 1, I used OddQ
here, not EvenQ
Drop[#,{2}]
Takes the ASCII codes of the left and right neighbors.
OddQ@#[[2]]
Checks whether the ASCII code of the corresponding character is odd.
Most@#
Takes the ASCII codes of the character and the left neighbor.
Rest@#
Takes the ASCII codes of the character and the right neighbor.
BitOr
Applys or-operation.
/._?(#>126&)->32
Replaces all numbers greater than 126 with 32 (space).
FromCharacterCode
Converts ASCII code back to characters and join them.