Urutan XOROR

23

Cellata Automata benar-benar menarik. Yang biasanya dibicarakan adalah yang biner, yaitu yang diwakili oleh angka. Namun, menurut saya, itu sudah dilakukan sampai mati. CA ternary lebih menarik, tetapi kita memiliki semua ASCII untuk dipertimbangkan! Betapa menyenangkannya itu!

Alih-alih memutuskan aturan untuk setiap karakter, saya akan menggunakan aturan memutuskan sederhana yang akan saya bicarakan segera. Untuk memutuskan generasi berikutnya, kita melihat tiga sel "atas", mirip seperti automata seluler. Perhatikan sebuah contoh:

QWERTY
X Y Z

"Atas" Yadalah WER, menjadi sel-sel di atas-dan-kanan, di atas, dan di atas-dan kiri. Y akan menjadi hasil dari fungsi yang akan saya definisikan, yang merupakan fungsi pada string tiga-char. Bagian "atas" Xadalah QW, atau ruang yang mengisi sel yang tidak ada / hilang .

Sekarang, untuk fungsi yang menyenangkan ! Saya menyebut urutan ini urutan XOROR karena suatu alasan. Biarkan Amenjadi charcode sel kiri atas, Bmenjadi charcode sel di atas, dan Cmenjadi charcode sel kanan atas. Lalu, sel yang dihasilkan adalah karakter yang karakternya adalah (A XOR B) OR C, yaitu (A^B)|C,. (Jika nilai yang dihasilkan lebih besar dari 126, maka diatur ke (CHARCODE % 127) + 32. Tidak ada yang dilakukan jika nilai kurang dari 32.) Berikut adalah contoh dari seed 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

Dan kita bisa melanjutkan untuk sementara waktu selanjutnya. Modifikasi string ini disebut urutan XOROR.

Tujuan Anda menulis program atau fungsi yang melakukan salah satu dari tugas-tugas berikut:

  1. Diberikan string sdan angka n >= 0, mengeluarkan nstring th pada urutan XOROR dengan seed s, dengan n = 0menjadi transformasi pertama string.
  2. Diberikan string s, output (untuk program) atau menghasilkan (untuk fungsi / generator) aliran tak terbatas dari urutan XOROR dengan seed s. Anda dapat memilih untuk berhenti jika urutannya berulang, tetapi ini tidak perlu.

s akan selalu hanya terdiri dari karakter ASCII yang dapat dicetak, dari ruang hingga tilde plus tab (tidak ada baris baru.)

Ini adalah , sehingga program terpendek dalam byte menang.

Conor O'Brien
sumber
Saya mengalami kesulitan menguraikan kalimat "Jadi, fungsi apa pun yang akan saya definisikan pada string tiga-char, Anda akan menjadi Y." Mungkinkah ini ditulis ulang: "Y akan menjadi hasil dari fungsi yang akan saya definisikan, fungsi pada string tiga-char."?
hYPotenuser
3
Semua oitu membuatnya terlihat seperti terburu-buru zerg .
mbomb007
3
Pengamatan: Karena XOR dan OR mempertahankan jumlah bit dan semua ASCII adalah 7 bit, satu-satunya kasus ketika CHARCODE adalah> 126 adalah jika itu adalah 127. Oleh karena itu, Anda dapat menggantinya dengan spasi (32) sejak itu 127%127+32==32.
CAD97
2
Mengapa n=0bukan string asli?
Neil
3
@FatalSleep Adapun keluhan pertama Anda, saya menyatakan bahwa, jika tidak ada sel, hasilnya adalah spasi, jadi itu lebih baik (d^!)|(space). Sedangkan untuk Anda pertanyaan kedua, Anda tampil (CHAR%127)+32 setelah XOROR dilakukan.
Conor O'Brien

Jawaban:

4

MATL , 33 31 byte

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

Ini berfungsi di rilis 13.1.0 dari bahasa / kompiler, yang mendahului tantangan.

Input pertama adalah nomor, yang kedua adalah string.

Cobalah online!

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
Luis Mendo
sumber
21

Mathematica, 133 byte

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

Akan lebih baik untuk membuat CellularAutomaton[]solusi bekerja, tetapi saya terus berdiskusi. Siapa saja?

Sunting: beberapa gambar cantik (klik untuk memperbesar)

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

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

60 iterasi "Halo, Dunia!"

plotCA[bXORnotb, 100]:

100 iterasi dari Hamlet soliloquy

plotCA[raven, 100]:

100 iterasi Poe

hYPotenuser
sumber
1
Tidak bisakah Anda memberikan CellularAutomatonfungsi pembaruan Anda saja? (Angka aturan aktual dengan 127 negara bagian yang valid akan menjadi gila.)
Martin Ender
@ MartinBüttner Anda bisa, tetapi itu adalah hambatan yang mencoba menjelaskan perilaku di tepinya, untuk membuatnya sesuai dengan spesifikasi. BlockMap [] hanya lebih pendek.
hYPotenuser
7

Jawa, 193 185 byte

Karena jawa

-8 byte dengan beralih ke perulangan daripada berulang untuk menjadikannya fungsi anonim

Mengembalikan iterasi ke-XOR pada tanggal 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;}

Versi yang dapat dibaca:

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

Cukup banyak implementasi spesifikasi secara literal, dengan loop rekursif untuk menerapkan operasi n kali. Namun, beberapa byte telah disimpan, dengan pengamatan saya bahwa klausa CHARCODE> 126 hanya akan terjadi dengan CHARCODE == 127, yang menghasilkan penghematan SPACEalih-alih DEL.

Saya menjalankan kode saya pada beberapa string yang dipilih secara sewenang-wenang dan menemukan siklus yang luar biasa ini:

oook$ok$ok$ok$
ook$ok$ok$ok$o
oo$ok$ok$ok$ok
oook$ok$ok$ok$
CAD97
sumber
5
Jawaban ini terlihat ok!
Conor O'Brien
3
esolangs.org/wiki/ook !
The Vee
5

CJam, 38 byte

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

Uji di sini.

Penjelasan

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.
  }%
}*
Martin Ender
sumber
Saya pikir Anda dapat menyimpan beberapa byte dengan lri){2S*\*3ew{)\:^|}%127c' er}*karena operasi pra-modulo karakter tidak pernah melebihi 127
Luis Mendo
5

Haskell, 123 byte

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)

Ini mengembalikan aliran infinite urutan XOROR. Contoh penggunaan (cetak 5 elemen pertama benih "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"

Bagaimana itu bekerja:

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
nimi
sumber
4

PHP, 186 byte (dengan n) | 177 byte (tak terbatas)

Ternyata pencetakan tanpa batas lebih pendek ...

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

Tidak digabungkan dengan 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;
}

Tak Terbatas tak berbatu:

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;
  }
}
daavko
sumber
1
Masih bisa bermain golf banyak. Misalnya, 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);}panjangnya 141 byte (-36 byte).
Blackhole
2

C ++

Nth-Sequence (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;}}

Tidak Golf

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-Sequence menggunakan sintaks pointer daripada sintaks array untuk membuat ini semakin membingungkan: (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;}}

Tidak Golf

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

Fungsi Debug (Untuk Bersenang-senang)

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;
    }
}
FatalSleep
sumber
1
Cukup yakin hasilnya mengatakan Anda harus menampilkan hasilnya, bukan hanya mengembalikannya.
Mooing Duck
1
Saya menulis versi C ++ dari awal, dibandingkan dengan milik Anda dan kemudian menggabungkannya, dan mendapatkan ini, pada 158 byte: coliru.stacked-crooked.com/a/838c29e5d496d2a6
Mooing Duck
@ MoooDuck Bagus! Mungkin bisa menguranginya lebih jauh dengan int implisit oleh kompiler melalui pindah ke C.
FatalSleep
tentu saja, silakan! Anda sudah menulis setengah dari kode itu
Mooing Duck
2

JAVA 240/280 Bytes

Versi Java yang populer pada saat saya menulis ini diklaim sebagai 185 byte, tetapi ada dua poin fudge yang signifikan. Pertama, pengukuran mungkin hanya untuk fungsi, bukan untuk sumber kerja yang lengkap. Mungkin bukan masalah seperti itu. Kedua, ia menggunakan BiFunction tanpa impor atau nama yang sepenuhnya memenuhi syarat. Menambahkan bit yang diperlukan untuk menjalankannya apa adanya (lalu meminimalkannya, secara wajar) membawanya ke 348 byte. Menambahkan hanya nama yang berkualifikasi penuh dari kelas BiFunction yang membawanya ke 248 byte.

Sebaliknya, saya percaya saya adalah 240 byte ketika bermain dengan aturan yang sama (tidak ada kelas, tidak ada output aktual, hanya daging). Kelas runnable penuh adalah 280 byte, dan terlihat seperti ini (tidak ditambang):

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

Atau, diperkecil:

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];}
vrmxm
sumber
2

Perl, 47 byte

Termasuk +2 untuk -lp

Jalankan dengan input pada STDIN, mis perl -lp xoror.pl <<< "Hello, World!" | head -26

xoror.pl:

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

Ini berfungsi sebagaimana adanya, tetapi ganti \x7fdengan nilai biner yang sesuai untuk mendapatkan skor yang diberikan

Ton Hospel
sumber
1

Swift: 273 Karakter

Wow, Swift lebih buruk dari Jawa! (Semua API dengan nama panjang!: 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)}}

Tidak Disatukan:

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

Terima kasih kepada @ CAD97 untuk menyebutkan bahwa (A ^ B) | C hanya bisa lebih besar dari 126 ketika 127.

Saya juga menyadari bahwa Anda tidak perlu tanda kurung di sekitar A ^ B | C karena XORing dilakukan sebelum ORing, sehingga menyelamatkan saya beberapa byte.

Kamu
sumber