7
\$\begingroup\$

Implement a function or program that can run simplified BitCycle code. The functions you must implement are:

<^>v: Change the direction of a bit to the direction this is pointing.

+: Turn all 0s left and all 1s right.

\ and /: Reflect one bit 90 degrees, then become inactive. In regular BitCycle, this is displayed as - or |, but that isn't required here. There are no collectors in this implementation, so these will never reset.

?: Take one bit at a time from input and send it east until all input is gone. You only need to worry about one input here. Bits only input from ?.

!: Output and delete the bit present here. Only one output is required.

~: Send the inputted bit right and a negated version of it left.

@: When a bit hits this device, terminate the program.

The =, 0, and 1 operations, multiple inputs/outputs, and collectors are not included in this specification. Other than that, everything should behave the same as in regular BitCycle.

Basic BitCycle Rules

The program itself forms a rectangular grid. A list of bits, either 0 or 1, will be taken as input, and a potentially-empty list of bits will be given as output. Bits travel rightwards at a rate of 1 character per cycle (which is the term I will try to use for each "tick" of the program) until they hit some sort of operation character. In those cases, they will behave as specified by the operator. Code will stop running upon hitting a @ character, or, depending on your output specification, also after some amount of time.

Left-right turns (from +) are relative to the direction of input. For example, if the character entered from the right, 0s will head downwards and 1s upward.

In standard BitCycle, values output as soon as they reach a ! character. However you may instead save all the bits and output them at the end, as long as your interpreter will stop evaluation after some amount of time. Any bit which leaves the grid is destroyed.

For the purpose of this challenge, if it doesn't otherwise interfere with your code (ignoring integer overflow of their position), you may choose to not destroy the bits and just have them continue moving in the direction they were.

All undefined characters are no-ops.

Example Programs (mostly taken from the BitCycle github)

?!

Cat program

v ~
!+~
?^<

Truth Machine

? v
 ~ /
>! <

Negate the first bit, output the rest

?~
@+!

Output all 0s before the first 1

Rules

This is , so lowest byte count wins.

Standard I/O rules apply for both the bits and the program.

You may choose whether to output as bits, a signed integer, or an unsigned integer, however, you must always be able to handle a case with only 1 or 0 bits as output AND if you don't output as bits, your program must meet the output-at-end rules. This is because any integer-output version wouldn't output anything on an infinite loop unless there was some form of max round number.

If you are outputting all bits at the end, your code must stop after some number of rounds. You may handle this in any "reasonable" way, as long as most simple programs will fully evaluate before your code automatically halts them.

A few examples of a valid method for halting the code:

  • A button that shows the round number, and when pressed, outputs all bits and halts the program.
  • A program which halts in n cycles, where n based on the number of flags it is given (as long as the max size of n isn't unreasonably small)
  • A third input which specifies the number of cycles it should do.
  • A program that always halts after 1000 cycles.
  • A function which halts after going 100 cycles with no new I/O.
asked May 13, 2022 at 20:16
\$\endgroup\$
9
  • 8
    \$\begingroup\$ An overview of how the language works in the post would make it all so much clearer. \$\endgroup\$ Commented May 13, 2022 at 22:38
  • 1
    \$\begingroup\$ Will the inputted programs be ran normally, under the -u flag (unsigned integers), or under the -U flag (signed integers)? Reason why I'm asking is because programs will have different outputs based on what flag the program is ran under. \$\endgroup\$ Commented May 13, 2022 at 23:27
  • 1
    \$\begingroup\$ For example, the program 11! will output 11 when ran normally, but will output 2 when ran under the -u or -U flag. \$\endgroup\$ Commented May 13, 2022 at 23:32
  • 1
    \$\begingroup\$ I would assume that the program is ran normally, as indicated by the truth machine example (it would not output an infinite stream of 1's if under any of the flags). If so, please specify that in the post. \$\endgroup\$ Commented May 13, 2022 at 23:45
  • 1
    \$\begingroup\$ Undefined behavior, I think. \$\endgroup\$ Commented May 17, 2022 at 1:01

2 Answers 2

6
+100
\$\begingroup\$

Python 3, 442 bytes

def f(s,I):
 if[0]>I:return[]
 N='\n';l=s.split(N);W=max(map(len,l))+1;s=[*N.join(i.ljust(W-1)for i in l)+N*W];Q=s.index('?');B=[(Q,I.pop(0),1)];O=[];R=999;L=[-1,-W,1,W]
 while B*R:
 C=[];R-=1
 for p,v,d in B:p+=d;c=s[p];z=L[L.index(d)-3];d=dict(zip('<^>v+~\/',L+[z*2*v-z,z,W//d,-W//d])).get(c,d);O+=[v]*(c=='!');R*=c!='@';s[p]=[c,' '][c in'\/'];C+=[(p,1-v,-d)]*(c=='~')+[(p,v,d)]*(c not in'!?\n')
 if I:C+=[(Q,I.pop(0),1)]
 B=C
 return O

Try it online!

Test cases adapted from those in @Ajax1234's answer

Ungolfed:

def f(s, I):
 if I == []: return []
 l = s.split('\n')
 width = max(map(len, l))+1 # including newline
 s = list('\n'.join(i.ljust(width-1) for i in l) + '\n'*width)
 Q = s.index('?') # location input bits start at
 # directions are 1, -1, width, -width corresponding to right, left, down, up
 bits = [(Q, I.pop(0), 1)]
 O = [] # output
 R = 999 # rounds remaining
 directions = [-1, -width, 1, width]
 while bits and R:
 C = []
 R -= 1
 for pos, val, dir in bits:
 pos += dir
 char = s[pos]
 z = directions[directions.index(dir) - 3] # dir turned right
 dir = {'<':-1, '^':-width, '>':1, 'v':width, '+':z*(2*val - 1), '~':z, '\\':width//dir, '/':-width//dir}.get(char, dir)
 if char == '!':
 O.append(val)
 if char == '@':
 R = 0
 if char in '\/':
 s[pos] = ' '
 if char == '~':
 C.append((pos, 1-val, -dir))
 if char not in '!?\n':
 C.append((pos, val, dir))
 if I:
 C.append((Q, I.pop(0), 1))
 bits = C
 return O
answered May 17, 2022 at 1:12
\$\endgroup\$
5
\$\begingroup\$

Python3, 789 bytes:

E=enumerate
def f(p,s):
 b=[*map(list,p.split('\n'))]
 x,y=[(x,y)for x,a in E(b)for y,c in E(a)if'?'==c][0]
 q,C,s,D=[(x,y,0,1,a,[(x,y)],i)for i,a in E(s)],[],[],{(0,1):[(-1,0),(1,0)],(0,-1):[(1,0),(-1,0)],(-1,0):[(0,-1),(0,1)],(1,0):[(0,1),(0,-1)]}
 while q:
 x,y,X,Y,B,p,I=q.pop(0)
 if(p,I)not in s and 0<=(x:=x+X)<len(b)and 0<=(y:=y+Y)<len(b[0]):
 s+=[(p,I)]
 if(O:=b[x][y])in(L:={'>':(0,1),'<':(0,-1),'v':(1,0),'^':(-1,0)}):q+=[(x,y,*L[O],B,p+[(x,y)],I)]
 if'+'==O:q+=[(x,y,*D[(X,Y)][B],B,p+[(x,y)],I)]
 if O in['\\','/']:q+=[(x,y,*((Y,X)if X==0 else(0,[1,-1][X==1])),B,p+[(x,y)],I)];b[x][y]=' '
 if'~'==O:q+=[(x,y,*D[(X,Y)][0],not B,[(x,y)],I)];q+=[(x,y,*D[(X,Y)][1],B,[(x,y)],I)]
 if'!'==O:C+=[int(B)]
 if'@'==O:q=[]
 if' '==O:q+=[(x,y,X,Y,B,p+[(x,y)],I)]
 return C

Try it online!

answered May 16, 2022 at 17:59
\$\endgroup\$
1
  • \$\begingroup\$ 707 bytes \$\endgroup\$ Commented Aug 12 at 7:22

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.