Cifrado impar / par ASCII

13

Definiremos el cifrado impar / par ASCII a través del pseudocódigo siguiente:

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

Por ejemplo, para la entrada Hello, la salida es emmol, ya que

  • Los Hturnos a los \0 | 'e'cuales ese
  • Los egiros a 'e' | 'l', o 101 | 108, que es 109om
  • El primero ltambién se convierte en 101 | 108om
  • El segundo se lconvierte en 108 | 111, que es 111oo
  • Los oturnos a 108 | \0, ol

Entrada

  • Una oración compuesta únicamente de caracteres ASCII imprimibles, en cualquier formato adecuado .
  • La oración puede tener puntos, espacios y otros signos de puntuación, pero solo será una línea.
  • La oración tendrá al menos tres caracteres de longitud.

Salida

  • El cifrado resultante, basado en las reglas descritas anteriormente, devuelto como una cadena o salida.

Las normas

  • Un programa completo o una función son aceptables.
  • Las lagunas estándar están prohibidas.
  • Este es el por lo que se aplican todas las reglas habituales de golf, y gana el código más corto (en bytes).

Ejemplos

Entrada en una línea, salida en lo siguiente. Las líneas en blanco separan ejemplos.

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
fuente
3
¿Es esto realmente una cifra? No parece ser una forma de descifrarlo.
tubería
Dado que los ocambios len el primer ejemplo, estoy bastante seguro de que sus especificaciones aseguran que el primero ono cambie len el segundo ejemplo. Debería cambiar a 'l' | ',', sea lo que sea, ¿verdad?
Greg Martin
@pipe Sí. No es realmente un "cifrado", pero no estoy seguro de cómo llamarlo. Tampoco es realmente un hash. De las etiquetas que tenemos, "cifrar" parecía más cercano, así que eso es lo que elegí.
AdmBorkBork
@GregMartin Sí, va a 'l' | ',', que es 108 | 44 --> 1101111 | 0101100, que se convierte 108, que es l. El ,pasa a alinearse con el l, así que no hay ningún cambio cuando el binario o se lleva a cabo.
AdmBorkBork
Oh, es realmente el binario-O ... Estaba pensando en el binario-XOR. Gracias por la aclaración. Por otro lado, esto habla aún más a la observación de la tubería de que este "cifrado" no puede descifrarse realmente, por lo que puedo decir.
Greg Martin

Respuestas:

1

Jalea , 33 31 bytes

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

Un enfoque directo que seguramente se puede acortar.

Pruébalo en línea!

millas
fuente
4

Perl, 63 62 bytes

Incluye +4 para -lp

Dar entrada sobre STDIN

oddeven.pl:

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

Esto funciona como se muestra, pero para obtener la puntuación reclamada, esto debe colocarse en un archivo sin; línea final y nueva y los \xhhescapes deben reemplazarse por sus valores literales. Puede hacer esto poniendo el código anterior en el archivo y ejecutando:

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

Pruébelo en línea (contiene todos los casos de prueba)

Menos golfizado:

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

Pruébelo en línea (sin golf)

Agrego \x00a ambos lados de la cadena para que no tenga que preocuparme por eso durante el proceso bit a bit. Recorro los caracteres originales de la cadena, hago operaciones bit a bit y las agrego al resultado, siguiendo las reglas de paridad.

mbomb007
fuente
Dang, estoy celoso de eso |=... equivalente en PowerShell sería$a=$a-bor$b
AdmBorkBork
@TimmyD En realidad no terminé usándolo, pero sí. Es agradable. Si tan solo Python tuviera a?b:ccomo JS.
mbomb007
Puede reemplazar si a% 2: # impar a | = ord (s [i-1]) más: # par a | = ord (s [i + 1]) con a | = ord (s [i + 1- 2 * (a% 2)])
NoSeatbelts
@NoSeatbelts Ese es mi código no protegido, que se dejará como está para propósitos de legibilidad. La presentación de golf es el mejor programa.
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:' ');}

Ni siquiera tenemos que verificar si es el último elemento de la cadena porque las cadenas en C tienen terminación nula.

Explicación

Bastante simple:

Use & 1 para probar expresiones impares / pares y expresiones ternarias para reemplazar if / elses. Incremente el char * p para reducir la cantidad de paréntesis requeridos.

No cinturones de seguridad
fuente
Buena respuesta: ¡bienvenido a 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]]&

Explicación

ToCharacterCode@#

Convierte cadenas a códigos ASCII

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

Particiona los códigos ASCII a la longitud 3, compensa 1 particiones, con ceros rellenos.

...~MapIndexed~...

Aplica una función para cada partición.

Which[...]

If...else if... elseen Mathematica .

OddQ@Max@#2

Comprueba si el índice (# 2) es impar. ( Maxes para aplanar); desde Mathematica índice comienza en 1, he utilizado OddQaquí, noEvenQ

Drop[#,{2}]

Toma los códigos ASCII de los vecinos izquierdo y derecho.

OddQ@#[[2]]

Comprueba si el código ASCII del carácter correspondiente es impar.

Most@#

Toma los códigos ASCII del personaje y el vecino izquierdo.

Rest@#

Toma los códigos ASCII del personaje y el vecino correcto.

BitOr

Aplica u-operación.

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

Reemplaza todos los números mayores que 126 con 32 (espacio).

FromCharacterCode

Convierte el código ASCII nuevamente en caracteres y se une a ellos.

JungHwan Min
fuente
Bienvenido a PPCG! ¿Podría agregar un poco de explicación para las personas (como yo) que no conocen bien Mathematica? También asegúrese de consultar Consejos para jugar golf en Mathematica para obtener algunas sugerencias. ¡Disfruta tu estancia!
AdmBorkBork
1
Algunas mejoras: aceptar y devolver una lista de caracteres en lugar de un objeto de cadena real está completamente bien y ahorra mucho en esas From/ToCharacterCodefunciones. Entonces parece que su Droplata notación infija uso: #~Drop~{2}. Y parece que se está aplicando BitOra cada salida posible de la, Which¿por qué no aplicarlo después y solo una vez?
Martin Ender
2

Rubí 133 128 108 106 bytes

Jordan me ayudó a ahorrar 20 bytes y cia_rana me ayudó a ahorrar 2 bytes :)

->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 se toma como la cadena de entrada.

Ejemplo de salida con s="Test 123 with odd characters. R@*SKA0z8d862" :

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

Explicación

El código anterior es muy ilegible, así que aquí hay una explicación. El código es un poco hacky, dejo de ser nuevo en Ruby, así que apuesto a que hay una forma más corta de hacerlo :)

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
fuente
Estoy bastante seguro de que la salida debe estar en una línea, ya que la entrada también lo está.
mbomb007
@ mbomb007 bummer, entonces tengo que usar en printlugar de p: p
Linus
@TimmyD oh, ¿entonces no puedo imprimirlo en la salida en diferentes momentos?
Linus
@TimmyD ok, ¿entonces lo anterior está permitido? Ahora imprime todo en una línea.
Linus
1
Puede escribir como se muestra a continuación:->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 bytes

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

Utiliza la propiedad de que los verbos en J se pueden aplicar de forma alterna usando un gerundio `para ciertos adverbios como infix \.

Uso

   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

Explicación

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
millas
fuente
1

JavaScript (ES6), 125 118 114 bytes

Vergonzosamente largo, pero charCodeAty String.fromCharCodesolo son 29 bytes. : - /

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

Cómo funciona

Cada carácter en la posición ise traduce con la siguiente fórmula, que cubre todas las reglas a la vez:

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

donde C(n)devuelve el código ASCII del enésimo carácter de la cadena de entrada.

Manifestación

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
fuente
1

PHP, 107 97 bytes

Probablemente golfable.

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
fuente
1

C #, 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;};

Programa completo con método no protegido y casos de prueba:

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

Esto resultó ser más largo de lo que pensaba ...

adrianmp
fuente