Trình tự XOROR


23

Cellular Automata thực sự hấp dẫn. Những cái thường được nói đến là những cái nhị phân, tức là những cái được đại diện bởi một số. Tuy nhiên, những người, theo tôi, đã được thực hiện cho đến chết. CA Ternary thú vị hơn, nhưng chúng tôi có tất cả ASCII để xem xét! Điều gì có thể vui vẻ!

Thay vì quyết định một quy tắc cho mỗi nhân vật, tôi sẽ sử dụng quy tắc quyết định đơn giản mà tôi sẽ nói về sớm. Để quyết định thế hệ tiếp theo, chúng tôi xem xét ba ô "trên cùng", giống như một máy tự động di động. Quan sát một ví dụ:

QWERTY
X Y Z

"Trên cùng" YWER, là các ô bên trên và bên phải, bên trên và bên trên và bên trái. Y sẽ là kết quả của hàm tôi sắp định nghĩa, là hàm trên chuỗi ba char. "Đỉnh" của X QW, hoặc một khoảng trắng điền vào ô không tồn tại / bị thiếu .

Bây giờ, cho các chức năng thú vị ! Tôi gọi trình tự này là trình tự XOROR vì một lý do. Đặt Amã char ô trên cùng bên trái, Blà mã char cell ở trên và Clà charcode ô trên cùng bên phải. Sau đó, ô kết quả là ký tự có charcode là (A XOR B) OR C, nghĩa là (A^B)|C. (Nếu giá trị kết quả lớn hơn 126, thì nó được đặt thành (CHARCODE % 127) + 32. Không có gì được thực hiện nếu giá trị nhỏ hơn 32.) Đây là một ví dụ về hạt giống 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

Và chúng ta có thể tiến hành trong một thời gian sau đây. Việc sửa đổi chuỗi này được gọi là chuỗi XOROR.

Mục tiêu Bạn phải viết một chương trình hoặc chức năng thực hiện một trong các nhiệm vụ sau:

  1. Cho một chuỗi svà một số n >= 0, xuất nchuỗi thứ n trên chuỗi XOROR với seed s, với n = 0phép biến đổi đầu tiên của chuỗi.
  2. Đưa ra một chuỗi s, đầu ra (cho các chương trình) hoặc tạo (cho các hàm / trình tạo) một luồng vô hạn của chuỗi XOROR với seed s. Bạn có thể chọn dừng lại nếu trình tự lặp lại, nhưng điều này là không cần thiết.

s sẽ luôn chỉ bao gồm các ký tự ASCII có thể in được, từ dấu cách đến dấu ngã cộng với các tab (không có dòng mới.)

Đây là một , vì vậy chương trình ngắn nhất tính bằng byte sẽ thắng.


Tôi gặp khó khăn khi phân tích câu "Vì vậy, bất kỳ chức năng nào tôi sắp định nghĩa trên chuỗi ba ký tự, Y sẽ trở thành." Điều này có thể được điều chỉnh lại: "Y sẽ là kết quả của hàm tôi sắp định nghĩa, một hàm trên chuỗi ba char."?
hYPotenuser

3
Tất cả các os làm cho nó trông giống như một cơn sốt Zerg .
mbomb007

3
Quan sát: Vì XOR và OR bảo toàn số bit và tất cả ASCII là 7 bit, trường hợp duy nhất khi CHARCODE> 126 là nếu nó là 127. Do đó, bạn chỉ có thể thay thế nó bằng khoảng trắng (32) 127%127+32==32.
CAD97

2
Tại sao n=0không phải là chuỗi gốc?
Neil

3
@FirthS ngủ Đối với khiếu nại đầu tiên của bạn, tôi đã nói rằng, nếu không có ô nào, kết quả là một khoảng trắng, vì vậy nó sẽ tốt hơn (d^!)|(space). Đối với câu hỏi thứ hai của bạn, bạn thực hiện (CHAR%127)+32 sau khi XOROR được thực hiện.
Conor O'Brien

Câu trả lời:


4

MATL , 33 31 byte

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

Điều này hoạt động trong phiên bản 13.1.0 của ngôn ngữ / trình biên dịch, trước thách thức.

Đầu vào đầu tiên là số, thứ hai là chuỗi.

Hãy thử trực tuyến!

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

Toán học, 133 byte

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

Nó sẽ là tốt đẹp để làm cho một CellularAutomaton[]giải pháp làm việc, nhưng tôi tiếp tục đến ngắn. Bất kỳ ai?

Chỉnh sửa: một số hình ảnh đẹp (bấm vào để phóng to)

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

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

60 lần lặp lại "Xin chào, Thế giới!"

plotCA[bXORnotb, 100]:

100 lần lặp lại của Hamlet soliloquy

plotCA[raven, 100]:

100 lần lặp của Poe


1
Bạn có thể chỉ cung cấp CellularAutomatonchức năng cập nhật của bạn? (Số quy tắc thực tế với 127 trạng thái hợp lệ sẽ là điên rồ.)
Martin Ender

@ MartinBüttner Bạn có thể, nhưng đó là một nỗ lực cố gắng giải thích cho hành vi ở các cạnh, để làm cho nó phù hợp với thông số kỹ thuật. BlockMap [] chỉ ngắn hơn.
hYPotenuser

7

Java, 193 185 byte

Vì Java.

-8 byte bằng cách chuyển sang lặp thay vì đệ quy để biến nó thành một hàm ẩn danh

Trả về lần lặp thứ n của XOROR trên 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;}

Phiên bản dễ đọc:

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

Khá nhiều triển khai theo nghĩa đen của thông số kỹ thuật, với một vòng lặp đệ quy để áp dụng thao tác n lần. Tuy nhiên, một số byte đã được lưu với quan sát của tôi rằng mệnh đề CHARCODE> 126 sẽ chỉ xảy ra với CHARCODE == 127, dẫn đến việc lưu SPACEthay vì DEL.

Tôi đã chạy mã của mình qua một vài chuỗi được chọn tùy ý và tìm thấy chu trình tuyệt vời này:

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

5
Câu trả lời này có vẻ ok!
Conor O'Brien


5

CJam, 38 byte

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

Kiểm tra nó ở đây.

Giải trình

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.
  }%
}*

Tôi nghĩ rằng bạn có thể tiết kiệm một vài byte với lri){2S*\*3ew{)\:^|}%127c' er}*bởi vì hoạt động tiền modun chars không bao giờ vượt quá 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)

Điều này trả về một luồng vô hạn của chuỗi XOROR. Ví dụ sử dụng (in 5 phần tử đầu tiên của hạt giống "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"

Làm thế nào nó hoạt động:

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 byte (với n) | 177 byte (vô hạn)

Hóa ra in vô hạn thì ngắn hơn ...

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

Ung dung với 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;
}

Vô hạn:

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
Nó vẫn có thể được chơi golf rất nhiều. Chẳng hạn, 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);}dài 141 byte (-36 byte).
Hố đen

2

C ++

Chuỗi thứ 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;}}

Không chơi gôn

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 sử dụng cú pháp con trỏ thay vì cú pháp mảng để làm cho điều này trở nên khó hiểu hơn: (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;}}

Không chơi gôn

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

Chức năng gỡ lỗi (Để giải trí)

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
Khá chắc chắn rằng kết quả nói rằng bạn phải xuất kết quả, không chỉ đơn giản là trả lại nó.
Vịt Mooing

1
Tôi đã viết một phiên bản C ++ từ đầu, so với bản của bạn và sau đó hợp nhất chúng và nhận được bản này, ở 158 byte: coliru.stacked-crooking.com/a/838c29e5d496d2a6
Vịt Mooing

@MooingDuck Đẹp quá! Có lẽ có thể giảm nó hơn nữa với trình biên dịch ngầm định bằng cách chuyển sang C.
FatalS ngủ

Tất nhiên đi trước! Bạn đã viết một nửa mã đó
Ducking Moo

2

JAVA 240/280 byte

Phiên bản Java phổ biến tại thời điểm tôi viết này được tuyên bố là 185 byte, nhưng có hai điểm mờ nhạt đáng kể. Đầu tiên, phép đo có lẽ chỉ dành cho chức năng, không phải cho nguồn làm việc hoàn chỉnh. Có lẽ không phải là một vấn đề như vậy. Thứ hai, nó sử dụng BiFunction mà không cần nhập hoặc tên đủ điều kiện. Việc thêm các bit cần thiết để chạy nó nguyên trạng (sau đó thu nhỏ nó một cách công bằng) đã đưa nó lên mức 349 byte. Chỉ thêm tên đủ điều kiện của lớp BiFunction sẽ mang lại cho nó tới 248 byte.

Ngược lại, tôi tin rằng của tôi là 240 byte khi chơi theo cùng một quy tắc (không có lớp, không có đầu ra thực tế, chỉ là thịt). Lớp có thể chạy đầy đủ là 280 byte và trông như thế này (chưa được tối ưu hóa):

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

Hoặc, rút ​​gọn:

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 byte

Bao gồm +2 cho -lp

Chạy với đầu vào trên STDIN, vd perl -lp xoror.pl <<< "Hello, World!" | head -26

xoror.pl:

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

Điều này hoạt động như là, nhưng thay thế \x7fbằng giá trị nhị phân tương ứng để có được số điểm nhất định


1

Swift: 273 Nhân vật

Wow, Swift còn tệ hơn cả Java! (Tất cả các API có tên dài !: 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)}}

Ung dung:

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

Cảm ơn @ CAD97 đã đề cập rằng (A ^ B) | C chỉ có thể lớn hơn 126 khi nó là 127.

Tôi cũng nhận ra rằng bạn không cần dấu ngoặc đơn quanh A ^ B | C vì XORing được thực hiện trước khi ORing, do đó đã tiết kiệm cho tôi một vài byte.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.