brainfuck, 91 bytes
+[>>,>++++[<-------->-]<]<<[<<]>+[>>++++[>++++++++<-],]<[<]>>-<[>>[<+>>-<-]+>[<->,]<[<.,]>]
Requires an interpreter that either allows negative positions on the tape or wraps if you <
from 0. Also requires ,
to return 0 every time you use it after input runs out. (In my experience these are both the most common behaviour.) Takes input as two words separated by a space.
This was a lot easier than I expected it to be! Usually I decide to write a brainfuck program and end up devoting quite a bit of time to it, but this one played nice. My first idea ended up working well and being rather short, especially for brainfuck.
This works by getting the entire first word and storing the characters in every second cell, then weaving in the second word (e.g. gglloosbsaalr y
). Then, for each pair of characters a
and b
, it copies a
a cell to the left and simultaneously replaces b
with b-a
. The cell a
used to be in becomes NOT (b-a)
. If that's true, a
is printed and the loop continues to the next set of characters. Otherwise, nothing is printed and the loop terminates.
I only used two real golfing tricks in this program. The first was combining two unrelated loops while gathering input. The first word is initially stored with each of its bytes subtracted by 32, so that space becomes 0 and the loop can end. Rather than adding 32 to each of those bytes and then getting the second word, the program does both at the same time. The second trick I used was abuse of ,
when I know the input is empty. The idiomatic way of setting a cell to 0 is [-]
. However, if you know that the program has already read the entire input, most interpreters will let you try to get a byte of input anyway and set the current cell to NUL
, or 0. I use this twice in my program, saving 4 bytes.
Ungolfed:
+[>>,>++++[<-------->-]<] get first word (minus 32 at each byte)
<<[<<]> go back to start
+[>>++++[>++++++++<-],] get second word and add 32 to each byte of
first word
<[<]>>-< go back to start and clean up a little bit
[ main loop
>>[<+>>-<-] subtract letter from second word from
letter of first word
+>[<->,]< logical NOT the result
[<.,]> if the result is 1: print the letter
else: the loop dies and execution is
terminated
]
global
andGLOSSARY
returnglo
or''
? \$\endgroup\$