ASCII Непарний / парний шифр


13

Ми визначимо ASCII непарний / парний шифр за допомогою наведеного нижче псевдокоду:

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

Наприклад, для введення Hello, вихід є emmol, оскільки

  • У Hчерзі до \0 | 'e'якої єe
  • eПовертається 'e' | 'l', або 101 | 108, що 109абоm
  • Перший lтакож звертається до 101 | 108абоm
  • Другий lзвертається до того 108 | 111, що є 111абоo
  • oПовертається 108 | \0, абоl

Вхідні дані

  • Речення, що складається виключно з символів ASCII для друку, у будь-якому відповідному форматі .
  • У реченні можуть бути періоди, пробіли та інші розділові знаки, але вони будуть колись одним рядком.
  • У реченні буде довжина не менше трьох символів.

Вихідні дані

  • Отриманий шифр, виходячи з правил, описаних вище, повертається як рядок або вихід.

Правила

  • Прийнятна або повна програма, або функція.
  • Стандартні лазівки заборонені.
  • Це тому застосовуються всі звичайні правила гольфу, і найкоротший код (у байтах) виграє.

Приклади

Введіть один рядок, виведіть на наступному. Пусті рядки - окремі приклади.

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
Це справді шифр? Здається, це не спосіб розшифрувати.
труба

З огляду на те, що oзміни lу першому прикладі я впевнений, що ваші характеристики забезпечують, щоб перший oне змінився на lдругому прикладі. Це має змінитись на 'l' | ',', що б там не було, правда?
Грег Мартін

@pipe Так. Насправді не "шифр", але не дуже впевнений, як його назвати. Це насправді не хеш. З тегів, які ми отримали, "шифр" здався найближчим, так що саме з цим я пішов.
AdmBorkBork

@GregMartin Так, це переходить до того 'l' | ',', що є 108 | 44 --> 1101111 | 0101100, що стає 108, що є l. ,Відбувається вибудовуватися з l, так що немає ніяких змін при довічним або відбувається.
AdmBorkBork

О, це дійсно двійкове-АБО ... Я думав, що бінарний-XOR. Дякую за роз’яснення. З іншого боку, це ще більше говорить про спостереження труби про те, що ця "шифра" насправді не може бути розшифрована, наскільки я можу сказати.
Грег Мартін

Відповіді:



4

Perl, 63 62 байт

Включає +4 для -lp

Введіть дані про STDIN

oddeven.pl:

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

Це працює так, як показано, але для отримання заявленого балу це потрібно помістити у файл без остаточного ;та нового рядка, а \xhhвиходи повинні бути замінені їх буквальними значеннями. Це можна зробити, поставивши код вище у файл та запустивши:

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

3

Пітон 2, 138 131 байт

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

Спробуйте в Інтернеті (містить усі тестові приклади)

Менше гольфу:

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

Спробуйте його в Інтернеті (ungolfed)

Я додаю \x00обидві сторони рядка, щоб мені не доводилося турбуватися про це під час бітового або ін-го. Я проводжу вздовж початкових символів рядка, роблячи побітові операції та додаючи їх до результату, дотримуючись правил парності.


Данг, я заздрю ​​цьому |=... еквівалент PowerShell$a=$a-bor$b
AdmBorkBork

@TimmyD Я насправді не використовував його, але так. Це гарно. Якби тільки Python мав a?b:cяк JS.
mbomb007

Ви можете замінити, якщо% 2: # непарний | | ord (s [i-1]) іншим: # even a | = ord (s [i + 1]) на | | ord (s [i + 1- 2 * (a% 2)])
NoSeatbelts

@NoSeatbelts Це мій неперевершений код, який буде залишений як такий - для читабельності. Подання в гольф - це найкраща програма.
mbomb007

2

C - 101 байт

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 недійсні.

Пояснення

Досить просто:

Використовуйте & 1 для перевірки на непарні / парні та потрійні вирази для заміни if / elses. Збільшити char * p, щоб зменшити кількість необхідних дужок.


Приємна відповідь - ласкаво просимо до PPCG!
AdmBorkBork

2

Математика, 152 байти

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

Пояснення

ToCharacterCode@#

Перетворює рядок у коди ASCII

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

Розбиття ASCII-кодів на довжину 3, зсув 1-х розділів з прокладеними 0.

...~MapIndexed~...

Застосовує функцію для кожного розділу.

Which[...]

If...else if... elseв Математиці .

OddQ@Max@#2

Перевіряє, чи індекс (# 2) непарний. ( Maxпризначений для вирівнювання); оскільки індекс Mathematica починається з 1, я OddQтут використовував , ніEvenQ

Drop[#,{2}]

Бере коди ASCII лівих і правих сусідів.

OddQ@#[[2]]

Перевіряє, чи є код ASCII відповідного символу непарним.

Most@#

Бере ASCII коди персонажа та лівого сусіда.

Rest@#

Бере коди ASCII персонажа та правильного сусіда.

BitOr

Застосовує або-операцію.

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

Замінює всі числа, що перевищують 126, на 32 (пробіл).

FromCharacterCode

Перетворює код ASCII назад в символи та приєднується до них.


Ласкаво просимо до PPCG! Чи можете ви додати трохи пояснень людям (як я), які недостатньо добре розбираються в Mathematica? Також не забудьте ознайомитись із порадами щодо гольфу в Mathematica . Насолодитися перебуванням!
AdmBorkBork

1
Кілька вдосконалень: Прийняття та повернення списку символів замість фактичного рядкового об'єкта є повністю чудовим і значно заощаджує на цих From/ToCharacterCodeфункціях. Тоді це виглядає як ваша Dropможуть використовувати інфіксне запис: #~Drop~{2}. І, здається, ви застосовуєте BitOrвсі можливі результати, Whichто чому б не застосувати його згодом і лише один раз?
Мартін Ендер

2

Ruby 133 128 108 106 байт

Джордан допоміг мені зберегти 20 байт, а cia_rana допоміг мені зберегти 2 байти :)

->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 приймається як вхідний рядок.

Приклад виведення з s="Test 123 with odd characters. R@*SKA0z8d862":

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

Пояснення

Вищеописаний код дуже нечитабельний, тому ось пояснення. Код начебто хакі, я перейшов на нову рубін, тому, думаю, є коротший спосіб зробити це :)

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

Я впевнений, що вихід повинен бути на одному рядку, оскільки вхід також є.
mbomb007

@ mbomb007 бампер, тоді мені доведеться використовувати printзамість p: p
Лінус

@TimmyD о, так що я не можу надрукувати його на вихід у різний час?
Лінус

@TimmyD гаразд, значить, дозволено вище? Тепер він друкує все на одному рядку.
Лінус

1
Ви можете написати так, як показано нижче:->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 байти

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

Використовує властивість, яку дієслова J можуть застосовувати по черзі, використовуючи герундій `для певних прислівників, таких як інфікс \.

Використання

   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

Пояснення

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 байт

Збентежено довго, але charCodeAtі String.fromCharCodeпоодинці - 29 байт. : - /

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

Як це працює

Кожен символ у позиції iперекладається з наступною формулою, яка охоплює всі правила одразу:

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

де C(n)повертає ASCII код 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"));


1

PHP, 107 97 байт

ймовірно, гольф.

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 байт

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

Повна програма з методом unolfolf та тестовими кейсами:

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

Це виявилося довше, ніж я думав ...

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.