Simulate Bitwise Cyclic Tag

11

Challenge

Given two strings in any default I/O format, do the following:

NOTE: The challenge will refer to the first string as the "data" and the second referred to as the "program".

  1. Change the program to an infinite string which is just the program repeated infinitely (e.g. 10 --> 1010101010...). The challenge will refer to this as the "infinite program"
  2. While the data is non-empty, do the following while looping over the infinite program:

    a. If the current command is "0", delete the left-most bit in the data. If the data is empty, "0" does not do anything.

    b. If the current command is "1", append the next character in the program to the data if the left-most bit in the data is a one.

    c. If the data is not empty now, output the data.

Test Cases

Data is the left side of the input and the program is the right side.

100, 0 --> 00, 0
1111, 1 --> 11111, 111111, 1111111, ...
10, 011 --> 0, 0, 0
1110, 011 --> 110, 1101, 11010, 1010...

Notes

  • The data and program will consist of only 0s and 1s
  • For data/programs that do not halt, your program does not need to halt.
  • The data and program will not be empty in the input.
  • You may have multiple trailing and leading newlines
  • Standard Loopholes are forbidden
  • You can use any convenient I/O format

As always with , shortest code wins!

MilkyWay90

Posted 2019-04-07T17:09:37.220

Reputation: 2 264

@Sanchises Seems like a borderline duplicate to that, but you have to get the result at a certain generation and that is for any cyclic tag system. – MilkyWay90 – 2019-04-07T17:49:05.683

in the first test case, 100 goes to 10 on cmd 0, whose definition is "delete the left-most bit in the data." wouldn't the leftmost bit of 100 be 1? – Jonah – 2019-04-07T17:52:09.667

@Jonah Oh, missed that – MilkyWay90 – 2019-04-07T17:55:09.527

in case (b), if you do the append, does the instruction pointer move right one or two characters? – Sparr – 2019-04-07T18:08:47.607

@Sparr It moves right one. See the section labeled Challenge. – MilkyWay90 – 2019-04-07T18:11:48.883

Your example submission produces a different result on the last test cast than what you have listed above in the post. Your example program's output matches my program's output, so I expect the flaw is in the test case – Jonah – 2019-04-07T18:55:51.780

@Jonah Sorry, forgot that one too. I keep on forgetting that 0 removes the left-most data bit, not the right-most one – MilkyWay90 – 2019-04-07T18:56:53.137

I read "You can use any convenient I/O format" and used lists of zeroes and ones. I'm noticing now that "any convenient format" conflicts with the "Given two strings" requirement. I've already submitted my answer, but you may want to clarify this for others. – Jonah – 2019-04-07T19:08:55.793

@Jonah I can't come up with a way to rephrase the question, can you help? – MilkyWay90 – 2019-04-07T19:11:06.067

I would just say "Given two strings, two lists of booleans, or other equivalent format, ..." in the first sentence. – Jonah – 2019-04-07T19:12:29.240

Are we allowed to have multiple trailing newlines? – Embodiment of Ignorance – 2019-04-07T20:48:21.260

@EmbodimentofIgnorance Yes – MilkyWay90 – 2019-04-07T21:45:18.943

@Jonah technically in math a string is just a list of symbols :P so a list of anything is a string :P – ASCII-only – 2019-04-08T01:01:30.917

@MilkyWay90 "see the section labeled Challenge" is not a great response when I am asking a question specifically already referring to that same section. – Sparr – 2019-04-08T23:37:28.293

@Sparr Oh yeah, didn't notice that. Sorry! – MilkyWay90 – 2019-04-09T00:34:23.983

Answers

4

Haskell, 77 71 62 bytes

f@(d:e)#(p:q)=f:[e,f++take d q]!!p#q
_#_=[]
a!b=tail$a#cycle b

Try it online!

Edit: -9 bytes thanks to @xnor.

nimi

Posted 2019-04-07T17:09:37.220

Reputation: 34 639

1In the first line, you can do f:[e,f++take d q]!!p#q. – xnor – 2019-04-09T03:26:21.507

2

C# (Visual C# Interactive Compiler), 82 bytes

m=>n=>{for(int i=0;m!="";Print(m=n[i++]<49?m.Substring(1):m[0]>48?m+n[i]:m))n+=n;}

Try it online!

Embodiment of Ignorance

Posted 2019-04-07T17:09:37.220

Reputation: 7 014

what are the significance of the 48 and 49, out of curiosity? – Jonah – 2019-04-07T18:59:48.233

1@Jonah 48 is the ASCII value of 0, and 49 is the ASCII value of 1 – Embodiment of Ignorance – 2019-04-07T19:02:03.390

shouldn't you use 0 and 1 instead here :P – ASCII-only – 2019-04-08T01:02:04.353

@ASCII-only I'm using a string, not an array. – Embodiment of Ignorance – 2019-04-08T01:03:19.393

@EmbodimentofIgnorance why not use a List and Skip, or something like that – ASCII-only – 2019-04-08T01:04:34.870

@ASCII-only Then I would have to add a check for when the list was empty, with m.Count>1, then I would have to transform m+n[i] into m.Append(n[i]) – Embodiment of Ignorance – 2019-04-08T01:15:50.740

1

J, 65 bytes

(([:(][echo)(}.@[)`([,{.@[#1{],])@.({.@]));1|.])&>/^:(0<0#@{>)^:5

Try it online!

I may golf this further later. Note the 5 at the end would be infinity _ in the actual program, but I've left it there to make running the non-halting examples easier.

Jonah

Posted 2019-04-07T17:09:37.220

Reputation: 8 729

1

Python 3, 74 bytes

def f(d,p):
 while d:c,*p=p+p[:1];d=(d[1:],d+p[:1]*d[0])[c];d and print(d)

Try it online!

Arguments: d: data, p: program.

Erik the Outgolfer

Posted 2019-04-07T17:09:37.220

Reputation: 38 134

1

05AB1E, 24 21 bytes

[¹Nèi¬i¹N>è«}ë¦}DõQ#=

Takes the program as first input and data as second input.input.

Try it online.

Explanation:

[             # Start an infinite loop:
 ¹Nè          #  Get the N'th digit of the first (program) input
              #  (NOTES: N is the index of the infinite loop;
              #          indexing in 05AB1E automatically wraps around)
    i         #  If this digit is 1:
     ¬        #   Push the head of the current data (without popping it)
              #   (will take the second (data) input implicitly if it's the first iteration)
      i     } #   If this head is 1:
       ¹N>è   #    Get the (N+1)'th digit of the first (program) input
           «  #    And append it to the current data
    ë }       #  Else (the digit is a 0 instead):
     ¦        #   Remove the first digit from the current data
              #   (will take the second input (data) implicitly if it's the first iteration)
 DõQ          #  If the current data is an empty string:
    #         #   Stop the infinite loop
 =            #  Print the current data with trailing newline (without popping it)

Kevin Cruijssen

Posted 2019-04-07T17:09:37.220

Reputation: 67 575

1

Ruby, 62 59 bytes

->c,d{p(d)while(a,*c=c;b,*d=d;c<<a;[]!=d=[b]*a+d+c[0,a*b])}

Try it online!

How

  • Get the first bit from code c and data d, call them a and b. Put a back at the end of c.
  • Put back b at the beginning of d if a==1. This can be shortened to [b]*a
  • Put the first byte of c at the end of d if a==1 and b==1. This can be shortened to c[0,a*b].
  • If we have more data, print and repeat.

G B

Posted 2019-04-07T17:09:37.220

Reputation: 11 099

0

Python 1, 75 bytes

a,b=input()
while a:b=b[1:]+b[:1];a=[a[1:],a+b[:1]*a[0]][b[0]];print a or''

Try it online!

Embodiment of Ignorance

Posted 2019-04-07T17:09:37.220

Reputation: 7 014

Nice! A niggle: for data '100', program '0', this will print the empty string once: but rule c says "If the data is not empty now, output the data." – Chas Brown – 2019-04-07T19:33:52.760

@ChasBrown Small typo, I'm waiting for clarification from the OP if trailing newlines are ok – Embodiment of Ignorance – 2019-04-07T21:13:35.880

@ChasBrown The OP says multiple trailing newlines are allowed, see here

– Embodiment of Ignorance – 2019-04-07T21:46:33.557

But after switching to arrays of 1's and 0s, now you're printing an empty array [] instead of a newline on e.g., data [1,0,0] , program [0]. – Chas Brown – 2019-04-07T23:47:27.297

1python 1? python 2 doesn't work? – ASCII-only – 2019-04-08T00:29:37.440

@ASCII-only It is obvious that Python 1 is superior to Python 2 – MilkyWay90 – 2019-06-01T14:05:55.487

0

Python 2, 96 82 bytes

def g(d,p):
 while d:
	c=p[0];p=p[1:]+[c];d=[d[1:],d+[p[0]]*d[0]][c]
	if d:yield d

Try it online!

Stealing a bit from Emodiment of Ignorance's answer...

A generator which uses lists of 1's and 0's for input / output.

Chas Brown

Posted 2019-04-07T17:09:37.220

Reputation: 8 959

0

Jelly, 40 bytes

;€Ø2œịxØ1œị$Ʋ$Ḋ€2,1œị$?1¦ṙ€1$2¦µ⁺1ịGṄƲ¿Ḣ

Try it online!

I’ve assumed trailing newlines are ok. I’ve also gone with a list of two lists of zeros and ones as input, and output to stdout.

Nick Kennedy

Posted 2019-04-07T17:09:37.220

Reputation: 11 829

0

C++ (gcc), 294 289 272 bytes

-22 bytes thanks to @ceilingcat

#import<cstdio>
#import<queue>
void a(char*e,char*p){std::queue<char>d;for(;*e;)d.push(*e++);for(char*c=p;d.size();c=*++c?c:p){*c-49?d.pop():d.front()-48?d.push(c[1]?c[1]:*p):a("","");if(d.size()){for(int i=0;i++<d.size();d.pop())d.push(putchar(d.front()));putchar(32);}}}

Try it online!

Fairly straightforward algorithm. Copies the data into a queue, and repeatedly loops through the program. On a "0", it removes the first element in the queue (the first "bit"). On a 1, it adds the next "bit" of the program to the data if the first "bit" of the data is 1. Then it loops through the data, printing it "bit" by "bit", and finally prints a space to separate successive data entries.

Neil A.

Posted 2019-04-07T17:09:37.220

Reputation: 2 038

@ceilingcat Clever (ab)use of c[1]! Updated. – Neil A. – 2019-04-09T23:20:56.503

0

C++ (gcc), 178 bytes

void a(std::string s,std::string d){while(!s.empty())for(int i=0;i<d.size();i++){if(d[i]=='0')s.erase(0,1);else if(s[0]=='1')s.push_back(d[(i+1)>=d.size()?0:i+1]);std::cout<<s;}}

Try it online!

peterzuger

Posted 2019-04-07T17:09:37.220

Reputation: 73

1163 bytes – ceilingcat – 2019-04-10T21:02:36.080