Remove all occurrences of the first letter of a string from the entire string
brainfuck, 219 bytes
+[+[>+<+<]>],[<+<+>>-]>[<<[->]>[<]>-]++++[<++++++++>-]<<[[-]----[>-<----]>-<<[>+>+<<-]<,[[>+>>>+>>+>+<<<<<<<-]>>[<<+>>-]<<[>->+<<-]>[[-]+<]>[>]<<[>>+<<-]>>[<-<+>>-]<[[-]+>]>>[<]<<<<[>>>+<<<-]>>>-[>>.<<-]>>>[[-]<]<<<<<,]
(Requires tape that either allows the pointer to go to the negatives or loops to the end if it tries. Also requires ,
to return 0 at EOF. In my experience, most interpreters meet these requirements by default.)
This actually turned out to be pretty easy! I wouldn't be surprised if it's golfable (I have some idea of where there might be wasted bytes but I'm not super sure if it'll pan out). Still, getting it work wasn't really a challenge at all.
This code treats everything with an ASCII value below 97 as an uppercase character. If the first character is space, it'll try to remove any occurrences of a "lowercase space" (i.e. chr(32+32)
, i.e. @
) from the string. This is okay, because only letters and spaces will ever be present.
With comments:
to make comments shorter: everywhere it says "fc" means "first character"
#################################### GET FC ####################################
+[+[>+<+<]>] shortest way to get 96
any number above 89 and less than 97 would work because this
is only for figuring out if the first character is capital
,[<+<+>>-] create two copies of the first character
### current tape: | fc | fc | 000 | 096 | ###
### pointer: ^ ###
########################### FIND MAX(FC MINUS 96; 0) ###########################
>[ 96 times:
<< go to the cell with the first char
[->] if not 0: sub one and move right
### current tape: | fc | char being worked on | 000 | 096 | ###
### pointer: ^ OR ^ ###
>[<]> collapse the wavefunction; sync the branches
-]
### current tape: | fc | fc is lowercase ? nonzero : zero | 000 | 000 | ###
### pointer: ^ ###
############################# GET BOTH CASES OF FC #############################
++++[<++++++++>-] get 32 (add to uppercase character to get lowercase)
<<[ if the character is already lowercase:
[-] clear the lowercase flag
----[>-<----]>- sub 64 from the cell with 32
<]
<[>+>+<<-] add fc to the 32 or minus 32 to get both cases
### current tape: | 000 | fc | other case of fc | ###
### pointer: ^ ###
###################### LOOP THROUGH REMAINING CHARACTERS #######################
<,[ for each character:
[>+>>>+>>+>+<<<<<<<-]
make four copies
(only 3 are strictly needed; 4th will resync a branch)
>> go to the first case of fc
[<<+>>-]<<[>->+<<-] subtract one case of fc from one copy
>[[-]+<] if the result is nonzero set it to 1
>[>]<< go to the other case of fc (and resync branches)
[>>+<<-]>>[<-<+>>-] subtract other case of fc from other copy
<[[-]+>] if the result is nonzero set it to 1
>>[<] resync branches using extra copy
<<<<[>>>+<<<-]>>> add results together
- subtract 1
if the character exactly matched either case: 1 plus 0 minus 1 = 0
if the character exactly matched neither case: 1 plus 1 minus 1 = 1
if the character exactly matched both cases: impossible
[ if the result is 1:
>>.<< output character
- set cell to 0 to kill loop
]
>>>[[-]<] clean up remaining copies
<<<<<, get next character; or end loop if done
]
Perl, 13 bytes
#!perl -p
/./,s/$&//gi
Counting the shebang as one, input is taken from stdin.
Sample Usage
$ echo Testing Testing One Two Three | perl remove-first.pl
esing esing One wo hree
$ echo \ Testing Testing One Two Three | perl primo-remove.pl
TestingTestingOneTwoThree
CJam, 8 bytes
q(_32^+-
Try it online in the CJam interpreter.
How it works
q e# Read all input from STDIN.
( e# Shift out the first character.
_32^ e# Push a copy and XOR its character code with 32.
e# For a letter, this swaps its case.
e# For a space, this pushes a null byte.
+ e# Concatenate these two characters.
- e# Remove all occurrences of both from the input string.