Sekwencja XOROR

23

Automaty komórkowe są naprawdę fascynujące. Te, o których zwykle się mówi, to te binarne, tzn. Te reprezentowane przez liczbę. Jednak te, moim zdaniem, zostały skazane na śmierć. Trójstronne urzędy certyfikacji są bardziej interesujące, ale musimy wziąć pod uwagę wszystkie ASCII! Cóż to może być za przyjemność!

Zamiast decydować o zestawie reguł dla każdej postaci, użyję prostej reguły decydującej, o której powiem wkrótce. Aby zdecydować o następnej generacji, patrzymy na trzy „górne” komórki, podobnie jak automaty komórkowe. Obserwuj przykład:

QWERTY
X Y Z

„Góra” Yto WERkomórki powyżej i po prawej, powyżej i powyżej oraz po lewej stronie. Y będzie wynikiem funkcji, którą zamierzam zdefiniować, która jest funkcją na łańcuchach trójznakowych. „Top” o Xto QW, czy wypełnienie przestrzeni w nieistniejącej / brakujące ogniwa .

Teraz funkcja zabawy ! Nie bez powodu nazywam tę sekwencję sekwencją XOROR. Niech Abędzie górnym lewym kodem komórki, Bpowyższym kodem komórki i Cbędzie prawym górnym kodem komórki. Następnie uzyskany komórka jest postać, której charCode to (A XOR B) OR C, że jest (A^B)|C. (Jeśli wynikowa wartość jest większa niż 126, wówczas jest ustawiona na (CHARCODE % 127) + 32. Nic nie jest robione, jeśli wartość jest mniejsza niż 32.) Oto przykład ziarna 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

I możemy kontynuować przez jakiś czas. Ta modyfikacja ciągu nazywana jest sekwencją XOROR.

Cel Masz napisać program lub funkcję, która wykonuje jedno z następujących zadań:

  1. Biorąc pod uwagę ciąg si liczbę n >= 0, nwyślij th ciąg w sekwencji XOROR z nasionem s, n = 0będąc pierwszą transformacją łańcucha.
  2. Podany ciąg swyjściowy (dla programów) lub wygenerowany (dla funkcji / generatorów) nieskończony strumień sekwencji XOROR z ziarnem s. Możesz zatrzymać, jeśli sekwencja się powtarza, ale nie jest to konieczne.

s zawsze będzie się składać wyłącznie z drukowalnych znaków ASCII, od spacji do tyldy plus tabulatorów (bez nowych linii).

To jest , więc wygrywa najkrótszy program w bajtach.

Conor O'Brien
źródło
Mam problem z parsowaniem zdania „Jakakolwiek funkcja, którą zamierzam zdefiniować na trzyznakowym ciągu, stanie się Y”. Czy można to przeredagować: „Y będzie wynikiem funkcji, którą zamierzam zdefiniować, funkcji na łańcuchach trójznakowych.”?
hYPotenuser
3
Wszystkie osprawiają, że wygląda jak przypływ zergów .
mbomb007
3
Obserwacja: Ponieważ XOR i OR zachowują liczbę bitów, a wszystkie ASCII to 7 bitów, jedynym przypadkiem, gdy CHARCODE> 126 jest, jeśli jest to 127. Od tego czasu możesz po prostu zastąpić go spacją (32) 127%127+32==32.
97 CAD
2
Dlaczego n=0nie jest oryginalny ciąg?
Neil
3
@FatalSleep Jeśli chodzi o twoją pierwszą skargę, stwierdziłem, że jeśli żadna komórka nie jest obecna, wynikiem jest spacja, więc wolałaby być (d^!)|(space). Co do drugiego pytania, wykonujesz (CHAR%127)+32 po wykonaniu XOROR.
Conor O'Brien

Odpowiedzi:

4

MATL , 33 31 bajtów

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

Działa to w wersji 13.1.0 języka / kompilatora, która poprzedza wyzwanie.

Pierwsze wejście to liczba, drugie to ciąg.

Wypróbuj 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
źródło
21

Mathematica, 133 bajty

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

Byłoby miło, gdyby CellularAutomaton[]rozwiązanie zadziałało, ale ciągle brakowało mi. Ktoś?

Edycja: kilka ładnych zdjęć (kliknij, aby powiększyć)

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

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

60 iteracji „Witaj, świecie!”

plotCA[bXORnotb, 100]:

100 iteracji monologu Hamleta

plotCA[raven, 100]:

100 iteracji Poe

hYPotenuser
źródło
1
Nie możesz po prostu podać CellularAutomatonswojej funkcji aktualizacji? (Rzeczywisty numer reguły z 127 ważnymi stanami byłby szalony.)
Martin Ender
@ MartinBüttner Możesz, ale przeciąganie próbuje wyjaśnić zachowanie na krawędziach, aby było zgodne ze specyfikacją. BlockMap [] był po prostu krótszy.
hYPotenuser
7

Java, 193 185 bajtów

Ponieważ Java.

-8 bajtów, przełączając się na zapętlanie zamiast rekurencji, aby uczynić go anonimową funkcją

Zwraca n-tą iterację XOROR na 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;}

Wersja do odczytu:

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

Dosłownie implementacja specyfikacji, z rekurencyjną pętlą do zastosowania operacji n razy. Niektóre bajty zostały jednak zapisane, z moimi spostrzeżeniami, że klauzula CHARCODE> 126 wystąpi tylko z CHARCODE == 127, co spowoduje zapisanie SPACEzamiast DEL.

Uruchomiłem mój kod na kilku dowolnie wybranych ciągach i znalazłem ten cudowny cykl:

oook$ok$ok$ok$
ook$ok$ok$ok$o
oo$ok$ok$ok$ok
oook$ok$ok$ok$
CAD97
źródło
5
Ta odpowiedź wygląda ok!
Conor O'Brien
3
esolangs.org/wiki/ook !
The Vee
5

CJam, 38 bajtów

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

Sprawdź to tutaj.

Wyjaśnienie

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
źródło
Myślę, że możesz zaoszczędzić kilka bajtów, lri){2S*\*3ew{)\:^|}%127c' er}*ponieważ operacja pre-modulo znaków nigdy nie przekracza 127
Luis Mendo
5

Haskell, 123 bajty

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)

Zwraca nieskończony strumień sekwencji XOROR. Przykład użycia (wydrukuj pierwsze 5 elementów nasion "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"

Jak to działa:

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
źródło
4

PHP, 186 bajtów (z n) | 177 bajtów (nieskończony)

Okazało się, że druk nieskończony jest krótszy ...

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

Nie golfił z 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;
}

Nieskończony nieskończony:

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
źródło
1
Nadal można dużo grać w golfa. Na przykład 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);}ma 141 bajtów (-36 bajtów).
Blackhole
2

C ++

Sekwencja n-ta (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;}}

Bez golfa

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

Sekwencja n-ta używa składni wskaźnika zamiast składni tablicowej, aby uczynić to tym bardziej zagmatwanym: (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;}}

Bez golfa

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

Funkcja debugowania (dla zabawy)

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
źródło
1
Całkiem pewne, że wyniki mówią, że musisz wyprowadzić wynik, a nie tylko go zwrócić.
Mooing Duck
1
Napisałem wersję C ++ od podstaw, w porównaniu do twojej, a następnie połączyłem je i otrzymałem to, w 158 bajtach: coliru.stacked-crooked.com/a/838c29e5d496d2a6
Duck
@MooingDuck Nice! Prawdopodobnie można by to jeszcze bardziej zmniejszyć za pomocą niejawnej int przez kompilator, przechodząc do C.
FatalSleep
oczywiście, śmiało! Napisałeś już połowę tego kodu
Mooing Duck
2

JAVA 240/280 Bytes

Popularna wersja Java w chwili, gdy ją pisałem, twierdziła, że ​​ma 185 bajtów, ale istnieją dwa znaczące punkty krówki. Po pierwsze, pomiar jest przypuszczalnie tylko dla funkcji, a nie dla pełnego źródła pracy. Może nie taki problem. Po drugie, używa BiFunction bez importu lub pełnej nazwy. Dodanie wymaganych bitów, aby uruchomić go takim, jaki jest (a następnie zminimalizować, całkiem), doprowadziło go do 348 bajtów. Dodanie tylko pełnej nazwy klasy BiFunction sprowadza ją do 248 bajtów.

Przeciwnie, uważam, że mój ma 240 bajtów, gdy gra się na tych samych zasadach (bez klasy, bez rzeczywistej wydajności, tylko mięso). Pełna klasa uruchamialna ma 280 bajtów i wygląda następująco (nieupoważniona):

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

Lub zminimalizowane:

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
źródło
2

Perl, 47 bajtów

Obejmuje +2 za -lp

Uruchom z wejściem na STDIN, np perl -lp xoror.pl <<< "Hello, World!" | head -26

xoror.pl:

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

Działa to tak, jak jest, ale zastąp \x7fje odpowiednią wartością binarną, aby uzyskać podany wynik

Ton Hospel
źródło
1

Swift: 273 znaków

Wow, Swift jest gorszy niż Java! (Wszystkie te interfejsy API o długich nazwach!: 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)}}

Nie golfowany:

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

Dzięki @ CAD97 za wspomnienie, że (A ^ B) | C może być większe niż 126, gdy wynosi 127.

Uświadomiłem sobie również, że nie potrzebujesz nawiasów wokół A ^ B | C, ponieważ XORing jest wykonywany przed ORingiem, dzięki czemu zaoszczędziłem kilka bajtów.

ty
źródło