# Simulate Bitwise Cyclic Tag

## 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!

• @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. Apr 7, 2019 at 17:49
• 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? Apr 7, 2019 at 17:52
• @Jonah Oh, missed that Apr 7, 2019 at 17:55
• in case (b), if you do the append, does the instruction pointer move right one or two characters? Apr 7, 2019 at 18:08
• @Sparr It moves right one. See the section labeled Challenge. Apr 7, 2019 at 18:11

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. • In the first line, you can do f:[e,f++take d q]!!p#q. – xnor Apr 9, 2019 at 3:26 # 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! • what are the significance of the 48 and 49, out of curiosity? Apr 7, 2019 at 18:59 • @Jonah 48 is the ASCII value of 0, and 49 is the ASCII value of 1 Apr 7, 2019 at 19:02 • shouldn't you use 0 and 1 instead here :P Apr 8, 2019 at 1:02 • @ASCII-only I'm using a string, not an array. Apr 8, 2019 at 1:03 • @EmbodimentofIgnorance why not use a List and Skip, or something like that Apr 8, 2019 at 1:04 # 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)  # 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. # 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. # 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. # 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! • 163 bytes Apr 10, 2019 at 21:02 # 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. # 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.

# 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!

• 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." Apr 7, 2019 at 19:33
• @ChasBrown Small typo, I'm waiting for clarification from the OP if trailing newlines are ok Apr 7, 2019 at 21:13
• @ChasBrown The OP says multiple trailing newlines are allowed, see here Apr 7, 2019 at 21:46
• 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]. Apr 7, 2019 at 23:47
• python 1? python 2 doesn't work? Apr 8, 2019 at 0:29

# C++ (gcc), 294289 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.

• @ceilingcat Clever (ab)use of c[1]`! Updated. Apr 9, 2019 at 23:20
• 259 bytes Feb 8, 2021 at 16:00