Skip to main content
19 of 30
added 927 characters in body
Albert Renshaw
  • 3.1k
  • 1
  • 17
  • 37

#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));}

Try it online


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

Albert Renshaw
  • 3.1k
  • 1
  • 17
  • 37