XOROR序列


23

细胞自动机确实令人着迷。通常谈论的是二进制的,即可以用数字表示的那些。但是,在我看来,这些做法已经死了。三元CA更有趣,但是我们要考虑所有ASCII!那会是多么有趣!

我将为您介绍一个简单的决定规则,而不是为每个角色决定一个规则集。为了决定下一代产品,我们看一下三个“顶部”细胞,就像细胞自动机一样。观察一个例子:

QWERTY
X Y Z

的“顶部” YWER上方,右侧,上方,上方和左侧的单元格。Y将是我要定义的函数的结果,该函数是三字符字符串的函数。的“顶部” X QW或者是不存在/缺少的单元格中填充的空间

现在,为乐趣功能!由于某种原因,我将此序列称为XOROR序列。让A是左上角单元格则charCode,B是上述细胞则charCode,并且C是右上角的细胞则charCode。然后,将得到的细胞是其charCode为特点(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,输出n与种子XOROR序列个串s,与n = 0作为字符串的第一个转变。
  2. 给定一个字符串s,输出(对于程序)或生成(对于函数/生成器)带有种子的XOROR序列的无限流s。如果序列重复,您可以选择停止,但这不是必需的。

s 将始终仅由可打印的ASCII字符组成,从空格到波浪号加制表符(无换行符)。

这是一个,因此以字节为单位的最短程序获胜。


我无法解析句子“因此,无论我要在三字符字符串上定义的任何函数,Y都会变成”。是否可以改写为:“ Y将是我要定义的函数的结果,该函数基于三字符字符串。”?
hYPotenuser

3
所有这些o使它看起来像是虫族的狂奔
mbomb007'3

3
观察:由于XOR和OR保留位数,而所有ASCII均为7位,因此CHARCODE> 126的唯一情况是如果它是127。因此,您可以用空格(32)代替它127%127+32==32
CAD97

2
为什么n=0不是原始字符串?
尼尔

3
@FatalSleep对于您的第一个投诉,我说过,如果不存在任何单元格,则结果是一个空格,所以宁愿是(d^!)|(space)。至于第二个问题,请在执行XOROR (CHAR%127)+32 之后执行。
科纳·奥布莱恩

Answers:


4

MATL33 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

Mathematica,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]

“ Hello,World!”的60次迭代

plotCA[bXORnotb, 100]

哈姆雷特(Hamlet)自言自语的100次迭代

plotCA[raven, 100]

Poe的100次迭代


1
您不能只提供CellularAutomaton更新功能吗?(具有127个有效状态的实际规则编号是疯狂的。)
Martin Ender

@MartinBüttner可以,但是要尝试解决边缘的行为,以使其符合规范,这是一种拖累。BlockMap []只是更短。
hYPotenuser

7

Java,193185字节

因为Java。

通过切换到循环而不是递归将其设为匿名函数,可以达到-8个字节

返回s上XOROR的第n次迭代。

(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}*因为chars预模运算不会超过127
Luis

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字节(带n)| 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个字节)。
黑洞

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-Sequence使这更加令人困惑:(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个字符

哇,Swift比Java差!(所有带有长名称的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只有127时才能大于126。

我还意识到您不需要在A ^ B | C周围加上括号,因为XORing是在ORing之前完成的,因此为我节省了一些字节。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.