#C, 511 488 474 470 463 456
void f(char*a){char*s;int i=-1,c,o,w,b,e=b=w=o=c,l=3,n,r,z=i,y=0;for(;s=a[++i];c+=s==99,o+=s=='o',w+=s=='w',b+=s==98,e+=s=='e',l+=s=='l');r=~-l/2;n=c<o?c:o;n=w<n?w:n;n=b<n?b:n;n=e<n?e:n;n=r<n?r:n;c=c==n;o=o==n;w=w==n;b=b==n;e=e==n;if(l=r==n?l,l:0)if(l%2)l=2;else l=1,c=o=w=b=e=0;n=c+o+w+b+e+l;for(printf("%s",a);s=n?a[++z]:0;s==99&&c?n--,c--:0,s=='o'&&o?n--,o--:0,s=='w'&&w?n--,w--:0,s==98&&b?n--,b--:0,s=='e'&&e?n--,e--:0,s=='l'&&l?n--,l--:0,putchar(s));}
Readable format + explanation:
void f(char*a){
//a = input
char*s;
int i=-1,c,o,w,b,e=b=w=o=c,l=3,n,r,z=i,y=0;
for(;s=a[++i];c+=s==99,o+=s=='o',w+=s=='w',b+=s==98,e+=s=='e',l+=s=='l');
//loop to obtain number of times each character c,o,w,b,e,l is found in string
r=~-l/2;
//r is half of 1 less the number of times L is in string
n=c<o?c:o;n=w<n?w:n;n=b<n?b:n;n=e<n?e:n;n=r<n?r:n;
//n is the number of times that the least occouring character appears in the string, (use R instead of L since cowbell has two L's in it and we just need ~-l/2)
c=c==n;o=o==n;w=w==n;b=b==n;e=e==n;
//convert c,o,w,b,e to BOOL of whether or not we need 1 more of that letter to create one more cowbell (logic for L handled below since it's trickier)
if(l=r==n?l,l:0)//if L-1/2 is [or is tied for] least occurring character do below logic, else set l to 0 and terminate conditional
if(l%2)//if l is divisible by 2 then we need 2 more Ls
l=2;
else //otherwise we just need 1 more l and no other letters
l=1,c=o=w=b=e=0;
n=c+o+w+b+e+l;
//n = number of specific characters we need before we reach 1 more cowbell
for(printf("%s",a);s=n?a[++z]:0;s==99&&c?n--,c--:0,s=='o'&&o?n--,o--:0,s=='w'&&w?n--,w--:0,s==98&&b?n--,b--:0,s=='e'&&e?n--,e--:0,s=='l'&&l?n--,l--:0,putchar(s));}
//loop starts by printing the original string, then starts printing it again one character at a time until the required number of c,o,w,b,e,l letters are reached, then break (s=n?a[++z]:0) will return 0 when n is 0. Each letter subtracts from n only when it still requires letters of its type (e.g. b?n--,b--:0)
Some Fun Tricks Used:
•When checking characters I type 'w'
for the char w which is 3 bytes, but for the characters 'c'
and 'b'
I can type their ASCII values 99 and 98 respectively to save a byte each time.
•The second defined int (in this case c
) is always set as 1, so I can shorten c=1,o=1,w=1,b=1,e=1
to c,o,w,b,e=b=w=o=c
•r=~-l/2
is r=(l-1)/2
using bitshifts
•a[++i]
I'm getting the character at and index and iterating the index all at the same time. I just start i
at i=-1
now (I do the same with z
and start it as z=i
to save another byte