Послідовність XOROR


23

Стільникові автомати справді захоплюючі. Ті, про які зазвичай говорять, - це двійкові, тобто ті, що можуть бути представлені числом. Однак, на мою думку, це було зроблено до смерті. Термінальні ЦА цікавіші, але ми маємо враховувати всі ASCII! Що це може бути весело!

Замість того, щоб визначити набір правил для кожного символу, я буду використовувати просте правило, про яке я поговорю найближчим часом. Щоб вирішити наступне покоління, ми дивимось на три "верхніх" комірки, подібно до стільникових автоматів. Подивіться приклад:

QWERTY
X Y Z

"Вершина" Y- WERце клітини вправо, вгорі, вгорі і вгорі і вліво. Y буде результатом функції, яку я збираюся визначити, що є функцією на трьох рядках. «Вершина» Xє QW, або заповнення простору в неіснуючої / відсутню клітці .

Тепер, для веселої функції! Я називаю цю послідовність послідовністю XOROR з причини. Нехай це Aбуде верхній лівий шаркод клітини, Bбути вищенаведеним charcode коду та Cбути угорі правого верхнього коду комірки. Потім, отримана комірка є символом, чиїм кодом є (A XOR B) OR C, тобто (A^B)|C. (Якщо отримане значення перевищує 126, тоді воно встановлюється (CHARCODE % 127) + 32. Нічого не робиться, якщо значення менше 32.) Ось приклад насіння Hello, World!:

S: Hello, World!
0: mmmo/c_ z}~)e
   m = ( )^(H)|(e) = (32^72)|101 = 104|101 = 109 (m)
    m = (H)^(e)|(l) = (72^101)|108 = 45|108 = 109 (m)
    etc.
1: mmo/c_<   +wl
2: mo/c_<c< + |;
3: o/c_<c  ?+  g
4: oc_<c c??4+gg
5: 0_<c c  4+ o 
6: _<c ccc4??ooo
7:  c ccc4 ?o o 
8: ccccc4w? pooo
9: cccc4w h   o 
A: ccc4wc hh ooo
B: cc4wc4kh ooo 
C: c4wc4  #ooo o
D: wwc4w4#ooo oo
E: wc4wwc oo oo 
F: w4wwc4oo oo o
G: wwwc4   oo oo
H: wwc4w4 oo oo 
I: w4wwc4oooo oo
J: wwwc4  oo oo 
K: wwc4w4oo oo o
L: wc4wwo  oo oo
M: w4wwo8ooo oo 
N: wwwo8  o oo o
O: wwo8w8oooo oo

І ми можемо продовжити деякий час далі. Ця модифікація рядка називається послідовністю XOROR.

Завдання: Ви повинні написати програму або функцію, яка виконує одне з наступних завдань:

  1. Задавши рядок sі число n >= 0, виведіть nth рядок у послідовності XOROR з насінням s, при n = 0цьому це буде першим перетворенням рядка.
  2. Дано рядок s, вивести (для програм) або генерувати (для функцій / генераторів) нескінченний потік послідовності XOROR із насінням s. Ви можете зупинити, якщо послідовність повторюється, але це не обов'язково.

s завжди буде складатися лише з символів для друку ASCII, від простору до тильди та вкладок (немає нових рядків.)

Це , тому виграє найкоротша програма в байтах.


У мене виникають проблеми з розбором речення "Отже, яку б функцію я не міг визначити на триголовій строці, Y стане". Чи можна це переформулювати: "Y стане результатом функції, яку я збираюся визначити, функцією на трьох рядках".
hYPotenuser

3
Всі з них oроблять це схожим на зургу .
mbomb007

3
Спостереження: Оскільки XOR і АБО зберігають кількість бітів, а всі ASCII складають 7 біт, єдиний випадок, коли CHARCODE> 126, якщо це 127. Для цього ви можете просто замінити його пробілом (32) 127%127+32==32.
CAD97

2
Чому n=0не є початковий рядок?
Ніл

3
@FatalSleep Що стосується вашої першої скарги, я заявив, що якщо жодної комірки немає, то результат - пробіл, і, швидше, це буде (d^!)|(space). Що стосується вашого другого питання, ви виконуєте (CHAR%127)+32 після виконання XOROR.
Conor O'Brien

Відповіді:


4

MATL , 33 31 байт

Q:"32XKhKwh3YCPo2$1Z}Z~Z|127KYX

Це працює у випуску 13.1.0 мови / компілятора, що передує виклику.

Перший вхід - це число, другий - рядок.

Спробуйте в Інтернеті!

Q           % take input (number) implicitly and add 1
:"          % repeat that many times
  32XK      %   push 32 (space). Copy to clipboard K.
  h         %   concatenate. Takes input (string) implicitly the first time
  Kwh       %   push space, swap, concatenate
  3YC       %   overlapping blocks of length 3 as columns of 2D array
  P         %   flip upside-down 
  o         %   convert to numbers
  2$1Z}     %   separate the three rows and push them
  Z~        %   bitwise XOR (note the rows are in reverse order)
  Z|        %   bitwise OR
  127KYX    %   replace 127 by space using regexprep, which converts to char
            % end loop
            % implicitly display

21

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

FromCharacterCode@Nest[BlockMap[If[#>126,#~Mod~127+32,#]&[BitXor[#,#2]~BitOr~#3]&@@#&,ArrayPad[#,1,32],3,1]&,ToCharacterCode@#,#2+1]&

Було б непогано зробити CellularAutomaton[]рішення, але я все-таки підходив недовго. Хтось?

Редагувати: кілька гарних зображень (натисніть, щоб збільшити)

plotCA[str_, n_] := ArrayPlot[NestList[foo[str],n], ColorFunction -> "Rainbow"]

plotCA["Hello, World!", 60]:

60 ітерацій "Привіт, світ!"

plotCA[bXORnotb, 100]:

100 ітерацій розмови Гамлета

plotCA[raven, 100]:

100 ітерацій По


1
Ви не можете просто надати CellularAutomatonфункцію оновлення? (Дійсне число правил із 127 дійсних штатів було б божевільним.)
Мартін Ендер

@ MartinBüttner Ви можете, але це спроба врахувати поведінку на краях, щоб вона відповідала специфікації. BlockMap [] був просто коротшим.
hYPotenuser

7

Java, 193 185 байт

Тому що Java.

-8 байт, перейшовши на циклічне, а не повторне, щоб зробити його анонімною функцією

Повертає n-ю ітерацію XOROR на s.

(s,n)->{String o=s;for(;n-->=0;){o="";for(int i=0;i<s.length();i++){char c=(char)((i>1?s.charAt(i-1):' ')^s.charAt(i)|(i<s.length()-1?s.charAt(i+1):' '));o+=c>126?' ':c;}s=o;}return o;}

Читаема версія:

static BiFunction<String, Integer, String> f = (s,n)->{
    String o=s;
    for(;n-->=0;) {
        o = "";
        for (int i=0;i<s.length();i++) {
            char c=(char)((i>1?s.charAt(i-1):' ')^s.charAt(i)|(i<s.length()-1?s.charAt(i+1):' '));
            o+=c>126?' ':c;
        }
        s=o;
    }
    return o;
};

public static void main(String[]a) {
    System.out.println(f.apply("Hello, World",1));
}

Досить буквальна реалізація специфікації, з рекурсивним циклом, щоб застосувати операцію n разів. Однак деякі байти було збережено, моє зауваження, що пункт CHARCODE> 126 коли-небудь трапиться із CHARCODE == 127, що призводить до економії SPACEзамість DEL.

Я провів свій код по декількох довільно вибраних рядках і знайшов цей чудовий цикл:

oook$ok$ok$ok$
ook$ok$ok$ok$o
oo$ok$ok$ok$ok
oook$ok$ok$ok$

5
Ця відповідь виглядає ok!
Conor O'Brien


5

CJam, 38 байт

lri){2S*\*3ew{)\:^|_'~>{i127%' +}&}%}*

Перевірте це тут.

Пояснення

l                e# Read string.
ri               e# Read n.
){               e# Run this block n+1 times...
  2S*\*          e#   Wrap in two spaces.
  3ew            e#   Get all (overlapping) substrings of length 3.
  {              e#   Map this block over all those substrings...
    )\           e#     Pull off the third character and put it below the other two.
    :^           e#     Take XOR of the other two.
    |            e#     OR with the third one.
    _'~>         e#     Duplicate and check if it's greater than '~'.
    {i127%' +}&  e#     If so, mod 127, add to space.
  }%
}*

Я думаю, ви можете заощадити кілька байтів, lri){2S*\*3ew{)\:^|}%127c' er}*тому що
Луїс Мендо

5

Haskell, 123 байти

import Data.Bits
f s=toEnum.a<$>zipWith3(((.|.).).xor)(32:s)s(tail s++[32])
a x|x>126=32|1<2=x
tail.iterate(f.map fromEnum)

Це повертає нескінченний потік послідовності XOROR. Приклад використання (надрукуйте перші 5 елементів насіння "Hello, World!"):

*Main> mapM_ print $ take 5 $ (tail.iterate(f.map fromEnum)) "Hello, World!"
"mmmo/c_ z}~)e"
"mmo/c_<   +wl"
"mo/c_<c< + |;"
"o/c_<c  ?+  g"
"oc_<c c??4+gg"

Як це працює:

tail.iterate(f.map fromEnum)               -- repeat forever: convert to ASCII
                                           -- value and call f, discard the first
                                           -- element (the seed).

                                           -- one iteration is:
  zipWith3(   )(32:s) s (tail s++[32])     -- zip the elements from the three lists
                                           -- (space:s), s and tail of s ++ space,
                                           -- e.g. s = "Hello!":
                                           --   | Hello|
                                           --   |Hello!|
                                           --   |ello! |
                                           -- (shortest list cuts off)

         ((.|.).).xor                      -- the function to zip with is a
                                           -- point-free version of (x xor y) or z

toEnum.a<$>                                -- adjust every element >126 and convert
                                           -- back to characters

4

PHP, 186 байт (з п) | 177 байт (нескінченно)

Виявилося, що нескінченний друк коротший ...

// With n
function x($s,$n){while($n-->=0){for($i=0,$r='';$i<strlen($s);$i++){$b=ord($s[$i-1])or$b=32;$a=ord($s[$i+1])or$a=32;$t=($b^ord($s[$i]))|$a;$r.=chr($t>126?($t%127)+32:$t);}$s=$r;}echo$s;}

// Infinite
function i($s){while(true){for($i=0,$r='';$i<strlen($s);$i++){$b=ord($s[$i-1])or$b=32;$a=ord($s[$i+1])or$a=32;$t=($b^ord($s[$i]))|$a;$r.=chr($t>126?($t%127)+32:$t);}echo$s=$r;}}

Невольф з n:

function x($s, $n) { // $s - string to process; $n - which string to output
  while ($n-- >= 0) {
    for ($i = 0, $r = ''; $i < strlen($s); $i++) {
      $b = ord($s[$i - 1]) or $b = 32;
      $a = ord($s[$i + 1]) or $a = 32;
      $t = ($b ^ ord($s[$i])) | $a;
      $r .= chr($t > 126 ? ($t % 127) + 32 : $t);
    }
  $s = $r;
  }
  echo $s;
}

Нескінченний нескінченний:

function x($s) { // $s - string to process
  while (true) {
    for ($i = 0, $r = ''; $i < strlen($s); $i++) {
      $b = ord($s[$i - 1]) or $b = 32;
      $a = ord($s[$i + 1]) or $a = 32;
      $t = ($b ^ ord($s[$i])) | $a;
      $r .= chr($t > 126 ? ($t % 127) + 32 : $t);
    }
    echo $s = $r;
  }
}

1
Ще можна багато в гольф. Наприклад, function i($s){for(;;$i=0,print$s=$r)for($r='';$i<strlen($s);$r.=chr($t>126?32:$t))$t=((ord($s[$i-1])?:32)^ord($s[$i]))|(ord($s[++$i])?:32);}завдовжки 141 байт (-36 байт).
Blackhole

2

C ++

N-послідовність (212)

void x(char*s,int l,int n){for (;n-->0;) {char*t=new char[l-1](),w;for(int i=0;i<l-1;i++)t[i]=((w=(((i-1>= 0)?s[i-1]:32)^s[i])|((i+1<l-1)?s[i+1]:32))>126)?((w%127)+32):w;for(int i=0;i<l-1;i++)s[i]=t[i];delete[]t;}}

Без гольфу

void x(char*s, int l, int n){
    for (;n-- > 0;) {
        char*t=new char[l-1](),w;
        for(int i = 0;i < l-1; i++)
            t[i] = ((w = (((i-1>= 0) ? s[i-1] : 32)^s[i]) | ((i+1 < l-1) ? s[i+1] : 32)) > 126) ? ((w % 127) + 32) : w;

        for(int i = 0; i < l-1; i++)
            s[i] = t[i];
        delete[]t;
    }
}

Nth-Послідовність, використовуючи синтаксис вказівника замість синтаксису масиву, щоб зробити це ще більше заплутаним: (231)

void x(char*s,int l,int n){for(int x=0;x++<n;) {char*t=new char[l-1](),w;for(int i=0;i<l-1; i++)*(t+i)=((w=(((i-1>= 0)?*(s+i-1):32)^*(s+i))|((i+1<l-1)?*(s+i+1):32))>126)?((w%127)+32):w;for(int i=0;i<l-1;i++)*(s+i)=*(t+i);delete[]t;}}

Без гольфу

void x(char* s, int l, int n){
    for (;n-- > 0;) {
        char*t = new char[l-1](),w;
        for(int i = 0; i < l-1; i++)
            *(t+i) = ((w = (((i-1>= 0) ? *(s+i-1) : 32)^ *(s+i)) | ((i+1<l-1) ? *(s+i+1) : 32)) > 126) ? ((w%127)+32) : w;

        for(int i = 0;i < l-1; i++)
            s[i] = t[i];
        delete[]t;
    }
}

Функція налагодження (для задоволення)

void d(char* seed, int len, int nth) {
    for (int n = 0; n++ < nth;) {
        char* tout = new char[len - 1]();
        for (int i = 0; i < len - 1; i++) {
            char x, y, z;
            x = ((--i >= 0) ? seed[i] : 32);
            y = seed[++i];
            z = ((++i < len - 1) ? seed[i] : 32);
            char w = (x ^ y) | z;
            tout[--i] = (w > 126) ? ((w % 127) + 32) : w;

            cout << "[" << x << " " << y << " " << z << "] " << w << endl;
        }

        for (int i = 0; i < len - 1; i++)
            seed[i] = tout[i];
        delete[] tout;
        cout << endl;
    }
}

1
Досить впевнений, що результати кажуть, що ви повинні вивести результат, а не просто повернути його.
Mooing Duck

1
Я написав версію C ++ з нуля, порівняв із вашою, а потім об'єднав їх, і отримав це, у 158 байт: coliru.stacked-crooked.com/a/838c29e5d496d2a6
Mooing Duck

@MooingDuck Приємно! Можливо, можливо, це ще більше зменшить за допомогою неявного int компілятором через перехід до C.
FatalSleep

звичайно, вперед! Ви вже написали половину цього коду
Mooing Duck

2

JAVA 240/280 байт

Популярна версія Java в той час, коли я писав це, стверджувала, що вона становить 185 байт, але є два значні моменти. По-перше, вимірювання, мабуть, лише для функції, а не для повного робочого джерела. Можливо, не така проблема. По-друге, він використовує BiFunction без імпорту або повного імені. Додавання необхідних бітів для запуску його як є (потім мінімізація, справедливо) привела його до 348 байт. Додавання лише повноцінного імені класу BiFunction приводить його до 248 байт.

На противагу цьому, я вважаю, що у мене 240 байтів, якщо грати за тими ж правилами (немає класу, немає фактичного виводу, лише м'ясо). Повний клас, який можна виконати, становить 280 байт, і виглядає так (не змінено):

class z{
  public static void main(String[] s){
    int L=s[0].length();
    for(int G=Integer.valueOf(s[1]);G-->0;){
      s[1]="";
      for(int N=0;N<L;N++){
        char C=(char)((N>0?s[0].charAt(N-1):' ')^(s[0].charAt(N))|(N<L-1?s[0].charAt(N+1):' '));
        s[1]+=C>126?' ':C;
      }
      System.out.println(s[1]);
      s[0] =s[1];
    }
  }
}

Або мінімізовано:

void m(String[] s){int L=s[0].length();for(int G=Integer.valueOf(s[1]);G-->0;){s[1]="";for(int N=0;N<L;N++){char C=(char)((N>0?s[0].charAt(N-1):' ')^(s[0].charAt(N))|(N<L-1?s[0].charAt(N+1):' '));s[1]+=C>126?' ':C;}s[0]=s[1];}return s[0];}

2

Perl, 47 байт

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

Виконати з введенням STDIN, наприклад perl -lp xoror.pl <<< "Hello, World!" | head -26

xoror.pl:

/./s;$_=$_.chop^" $_"|"$' ";y/\x7f/ /;print;redo

Це працює як є, але замініть \x7fна відповідне бінарне значення, щоб отримати заданий бал


1

Швидкість: 273 персонажів

Нічого собі, Свіфт гірший за Яву! (Усі ті API з довгими іменами!: P)

func c(s:String,n:Int=0-1){var a=[UInt8](s.utf8);for i in 0...(n>=0 ?n:Int.max-1){var z="";for i in 0..<a.count{let A=i-1<0 ?32:a[i-1],B=a[i],C=i+1<a.count ?a[i+1]:32;var r=A^B|C;r=r<32 ?32:r>126 ?32:r;z+=String(UnicodeScalar(r))};if n<0||i==n{print(z)};a=[UInt8](z.utf8)}}

Безголівки:

func cellularAutoma(s: String,n: Int = -1)
{
    var array = [UInt8](s.utf8)
    for i in 0...(n >= 0 ? n : Int.max - 1)
    {
        var iteration = ""
        for i in 0..<array.count
        {
            let A = i - 1 < 0 ? 32 : array[i - 1], B = array[i], C = i + 1 < array.count ? array[i + 1] : 32
            var r = A ^ B | C
            r = r < 32 ? 32 : r > 126 ? 32 : r
            iteration += String(UnicodeScalar(r))
        }
        if n < 0 || i == n
        {
            print(iteration)
        }
        array=[UInt8](iteration.utf8)
    }
}

Завдяки @ CAD97 за те, що він згадав, що (A ^ B) | C може бути більше 126, коли це 127.

Я також зрозумів, що дужки навколо A ^ B | C вам не потрібні, тому що XORing робиться перед ORing, і це дозволило мені зберегти кілька байт.

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