Cifra par / ímpar ASCII

13

Definiremos o ASCII Odd / Even Cipher através do pseudocódigo abaixo:

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 exemplo, para entrada Hello, a saída é emmol, desde

  • As Hvoltas para as \0 | 'e'quais ée
  • As evoltas para 'e' | 'l', ou 101 | 108, que é 109oum
  • O primeiro ltambém se volta para 101 | 108oum
  • A segunda lvolta para 108 | 111, que é 111ouo
  • As ovoltas para 108 | \0, oul

Entrada

  • Uma frase composta apenas por caracteres ASCII imprimíveis, em qualquer formato adequado .
  • A sentença pode ter períodos, espaços e outras pontuações, mas sempre terá apenas uma linha.
  • A frase terá pelo menos três caracteres.

Resultado

  • A cifra resultante, com base nas regras descritas acima, retornou como uma sequência ou saída.

As regras

  • Um programa completo ou uma função são aceitáveis.
  • Lacunas padrão são proibidas.
  • Isso é portanto todas as regras usuais de golfe se aplicam e o código mais curto (em bytes) vence.

Exemplos

Entrada em uma linha, saída na seguinte. Linhas em branco separam exemplos.

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
fonte
3
Isso é realmente uma cifra? Não parece ser uma maneira de decifrá-lo.
pipe
Dado que as oalterações lno primeiro exemplo, tenho certeza de que suas especificações garantem que o primeiro onão seja alterado lno segundo exemplo. Deve mudar para 'l' | ',', seja o que for, certo?
Greg Martin
@pipe Yeah. Não é realmente uma "cifra", mas não tem muita certeza do que chamar. Também não é realmente um hash. Das tags que temos, "cifra" parecia mais próxima, então foi com isso que eu fui.
AdmBorkBork 26/09/16
@GregMartin Sim, ele vai para o 'l' | ','que é 108 | 44 --> 1101111 | 0101100, o que se torna 108, o que é l. O ,alinhamento acontece com o l, portanto, não há alterações quando o binário - ou ocorre.
AdmBorkBork 26/09
Oh, é realmente o binário-OU ... eu estava pensando o binário-XOR. Obrigado pelo esclarecimento. Por outro lado, isso fala ainda mais da observação de pipe de que essa "cifra" não pode realmente ser decifrada, tanto quanto eu sei.
Greg Martin

Respostas:

1

Geléia , 33 31 bytes

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

Uma abordagem direta que certamente pode ser reduzida.

Experimente online!

milhas
fonte
4

Perl, 63 62 bytes

Inclui +4 para -lp

Dê entrada no STDIN

oddeven.pl:

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

Isso funciona como mostrado, mas para obter a pontuação reivindicada, isso deve ser colocado em um arquivo sem final ;e nova linha e as \xhhfugas devem ser substituídas por seus valores literais. Você pode fazer isso colocando o código acima no arquivo e executando:

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

Experimente online (contém todos os casos de teste)

Menos golfe:

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

Experimente online (sem limites)

Eu adiciono os \x00dois lados da string para não precisar me preocupar com isso durante a leitura bit a bit. Eu faço loop nos caracteres originais da string, fazendo operações bit a bit e adicionando-as ao resultado, seguindo as regras de paridade.

mbomb007
fonte
Dang, eu estou com ciúmes de que |=... equivalente em PowerShell seria$a=$a-bor$b
AdmBorkBork
@ TimmyD Eu realmente não acabei usando, mas sim. É legal. Se ao menos o Python tivesse a?b:ccomo o JS.
mbomb007
Você pode substituir se um% 2: # ímpar a | = ord (s [i-1]) else: # par a | = ord (s [i + 1]) por um | = ord (s [i + 1- 2 * (a% 2)])
NoSeatbelts 25/09
@NoSeatbelts Esse é o meu código não destruído, que será deixado como está para fins de legibilidade. O envio de golfe é o programa principal.
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:' ');}

Nem precisamos verificar se é o último item da cadeia, porque as cadeias em C são terminadas em nulo.

Explicação

Bastante simples:

Use & 1 para testar expressões ímpares / iguais e ternárias para substituir if / elses. Incremente o caractere * p para reduzir o número de colchetes necessários.

NoSeatbelts
fonte
Boa resposta - bem-vindo ao PPCG!
AdmBorkBork 23/09
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]]&

Explicação

ToCharacterCode@#

Converte string em códigos ASCII

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

Particiona os códigos ASCII no comprimento 3, desloca 1 partições, com 0s preenchidos.

...~MapIndexed~...

Aplica uma função para cada partição.

Which[...]

If...else if... elseno Mathematica .

OddQ@Max@#2

Verifica se o índice (# 2) é ímpar. ( Maxé para aplainar); desde o índice Mathematica começa em 1, eu useiOddQ aqui, nãoEvenQ

Drop[#,{2}]

Toma os códigos ASCII dos vizinhos esquerdo e direito.

OddQ@#[[2]]

Verifica se o código ASCII do caractere correspondente é ímpar.

Most@#

Pega os códigos ASCII do caractere e do vizinho esquerdo.

Rest@#

Pega os códigos ASCII do personagem e do vizinho certo.

BitOr

Aplica-se ou operação.

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

Substitui todos os números maiores que 126 por 32 (espaço).

FromCharacterCode

Converte o código ASCII em caracteres e os une.

JungHwan Min
fonte
Bem-vindo ao PPCG! Você poderia adicionar um pouco de explicação para pessoas (como eu) que não são bem versadas no Mathematica? Não deixe de conferir as dicas para jogar golfe no Mathematica para obter algumas sugestões. Aproveite sua estadia!
AdmBorkBork 23/09
1
Algumas melhorias: Aceitar e retornar uma lista de caracteres em vez de um objeto de string real é completamente bom e economiza muito nessas From/ToCharacterCodefunções. Então parece que sua Dropnotação uso infix lata: #~Drop~{2}. E parece que você está aplicando BitOra todas as saídas possíveis do Whichentão por que não aplicá-lo depois e apenas uma vez?
Martin Ender
2

Rubi 133 128 108 106 bytes

Jordan me ajudou a economizar 20 bytes e cia_rana me ajudou a economizar 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 é tomado como a sequência de entrada.

Exemplo de saída com s="Test 123 with odd characters. R@*SKA0z8d862":

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

Explicação

O código acima é muito ilegível, então aqui está uma explicação. O código é meio hacky, eu sou novo no ruby, então aposto que há uma maneira mais curta de fazer isso :)

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
fonte
Estou bastante certo de que a saída precisa estar em uma linha, pois a entrada também está.
mbomb007
@ mbomb007 chatice, então eu tenho que usar em printvez de p: p
Linus
@ TimmyD oh, então não posso imprimi-lo na saída em momentos diferentes?
Linus
@ TimmyD ok, então o acima é permitido? Agora ele imprime tudo em uma linha.
Linus
1
Você pode escrever como mostrado abaixo:->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:

Usa a propriedade de que verbos em J podem ser aplicados de forma alternada usando um gerúndio `para certos advérbios, 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

Explicação

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
milhas
fonte
1

JavaScript (ES6), 125 118 114 bytes

Embaraçosamente muito tempo, mas charCodeAte String.fromCharCodesozinhos são 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``

Como funciona

Cada personagem na posição i é traduzido com a seguinte fórmula, que abrange todas as regras de uma só vez:

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

Onde C(n) retorna o código ASCII do n-ésimo caractere da sequência de entrada.

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

PHP, 107 97 bytes

provavelmente jogável.

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
fonte
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 com método não destruído e casos de teste:

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

Acabou sendo mais do que eu pensava ...

adrianmp
fonte