More cowbell…!

You are providing tech support to the Bruce Dickenson as he produces a Blue Öyster Cult recording session. When he asks for more cowbell, you can give it to him.

Write a program or function that takes a string (or equivalent in your language) as input, and outputs a related string containing one more cowbell.

How many cowbells does a string contain?

The number of cowbells a string contains equals the maximum number of distinct copies of "cowbell" that can be obtained by permuting the characters of the string. For example, "bbbccceeellllllooowwwwwwwww" contains 3 cowbells, while "bbccceeellllllooowwwwwwwww" and "bbbccceeelllllooowwwwwwwww" each contain 2 cowbells, and "cowbel" contains 0 cowbells.

How should the output be related to the input?

The output should consist of the concatenation, in this order, of the input string and the shortest prefix of the input string needed to increase the number of cowbells.

For example, "bbbccceeelllllooowwwwwwwww" only needs one additional "l" to contain 3 cowbells instead of 2; the shortest prefix that contains that "l" is "bbbccceeel". Therefore, if the input is "bbbccceeelllllooowwwwwwwww", then the output should be "bbbccceeelllllooowwwwwwwwwbbbccceeel".

Technicalities

• You may assume that the input contains only printable ASCII characters. If there are one or two characters that are annoying for your language's string processing (such as newlines or \), you can assume that the input doesn't contain them—just mention this restriction.
• You may further assume that the alphabetic characters in the input are all lowercase, or all uppercase. If you choose not to assume one of these, count cowbells case-insensitively.
• You may further assume that the input contains at least one copy of each of the characters b, c, e, l, o, and w. This is equivalent to assuming that some prefix of the string can be concatenated to it to produce a string that contains more cowbell. (Note that the input string itself need not contain a cowbell.)
• If your language has a builtin that solves this problem ... then totally use it, seriously, how awesome is that.

Gold-plated diapers

Since recording studio time is expensive, your code must be as short as possible. The entry with the fewest bytes is the winner!

Test cases

Test input #1: "christopher walken begs for more cowbell!"

Test output #1: "christopher walken begs for more cowbell!christopher wal"

Test input #2: "the quick brown fox jumps over the lazy dog"

Test output #2: "the quick brown fox jumps over the lazy dogthe quick brown fox jumps over the l"

Test input #3: "cowbell"

Test output #3: "cowbellcowbell"

Test input #4: "cowbell cowbell cowbell"

Test output #4: "cowbell cowbell cowbellcowbell"

Test input #5: "cowbell cowbell cowbel"

Test output #5: "cowbell cowbell cowbelcowbel"

Test input #6: "bcelow"

Test output #6: "bcelowbcel"

Test input #7: "abcdefghijklmnopqrstuvwxyz"

Test output #7: "abcdefghijklmnopqrstuvwxyzabcdefghijkl"

Test input #8: "cccowwwwbbeeeeelllll"

Test output #8: "cccowwwwbbeeeeelllllccco"

Test input #9: "be well, programming puzzles & code golf"

Test output #9: "be well, programming puzzles & code golfbe well, programming puzzles & c"

Test input #10: "lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. wow!"

Test output #10: "lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. wow!lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut lab"

Test input #11:

"c-c-b-c

i have a cow, i have a bell.
uh! bell-cow!
i have a cow, i have a cowbell.
uh! cowbell-cow!

bell-cow, cowbell-cow.
uh! cow-cowbell-bell-cow.
cow-cowbell-bell-cow!
"


Test output #11:

"c-c-b-c

i have a cow, i have a bell.
uh! bell-cow!
i have a cow, i have a cowbell.
uh! cowbell-cow!

bell-cow, cowbell-cow.
uh! cow-cowbell-bell-cow.
cow-cowbell-bell-cow!
c-c-b-c

i have a cow, i have a bell"

• Anyone who answers in COW earns ten internet points. – Pavel Jan 30 '17 at 4:12
• I think it would be much easier for people to handle the input/output cases if you formatted them in a single code block. As it stands it takes up a lot of space and isn't very copy paste friendly. – FryAmTheEggman Jan 30 '17 at 4:36
• Pastebin link added for copy/pasting. If there's a way to hide/collapse/show the test cases in this post, thus saving vertical space, I'd love to learn it. – Greg Martin Jan 30 '17 at 4:42
• Well normally people use test case -> result in one large preformatted code block. It's much nicer aesthetically and easier to copy paste. – FlipTack Jan 30 '17 at 7:24
• @MatthewRoh Apart from the fact that there are two Ls in the word, this is not what the challenge asks. – Martin Ender Jan 30 '17 at 10:37

Pip, 5042 38 bytes

T$<(MN{_NaM"lcowbe"}//^2M[aYa@<i])++iy  Pass the string in as a command-line argument, quoted if necessary. Try it online! Explanation I'm going to explain this in two parts: the cowbell function and the full program. First, here's the function that computes the amount of cowbell in a string: MN{_NaM"lcowbe"}//^2  {...} defines a function. Many Pip operators, when applied to a function, return another function; for example, -{a+1} is the same as {-(a+1)}. So the above is equivalent to {MN(_NaM"lcowbe")//^2}  which works as follows: { } Function, in which a is the 1st argument (the string) _Na Lambda fn: returns number of times its argument occurs in a M"lcowbe" Map that function to the characters of "lcowbe" ^2 A devious way to get [2]: split the scalar 2 into characters ( )// Int-divide the list of character counts by [2] Since the lists are not the same length, this divides the first element (# of l's) by 2 and leaves the others alone MN Take the min of the resulting list  Now that we have that, here's the full program: T$<(MN{_NaM"lcowbe"}//^2M[aYa@<i])++iy
a is 1st cmdline arg, i is 0 (implicit)
T                                       Loop till condition is true:
a@<i        Slice leftmost i characters of a
Y            Yank that into y variable
[a     ]       List containing a and that value
M               To that list, map...
MN{_NaM"lcowbe"}//^2                ... the cowbell function
Result: a list containing the amount of cowbell
in the original string and the amount in the slice
$<( ) Fold on less-than: true if the first element is less than the second, otherwise false ++i In the loop, increment i y Once the loop exits, print y (the latest slice)  • I entered cowbell cowbell cowbee and the output was cowbellcowbelcowbel but I might be using the IDE wrong (new to PIP) – Albert Renshaw Jan 30 '17 at 7:10 • @AlbertRenshaw I get cowbell cowbell cowbeecowbell (try it online). Are you using TIO or a local copy? – DLosc Jan 30 '17 at 7:17 • Oh nice! I was sticking it under the field "input" not under the argument add. +1 – Albert Renshaw Jan 30 '17 at 7:19 • Really top class. I ported it to javascript. – edc65 Jan 30 '17 at 15:22 C, 511488474470463 454 void f(char*a){char*s;int i=-1,c,o,w,b,e=b=w=o=c=1,l=3,n,r,z=i;for(;s=a[++i];c+=s==67,o+=s==79,w+=s==87,b+=s==66,e+=s==69,l+=s==76);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:0)if(l%2)l=2;else l=1,c=o=w=b=e=0;else l+=l%2;n=c+o+w+b+e+l;for(printf("%s",a);s=n?a[++z]:0;s==67&&c?n--,c--:0,s==79&&o?n--,o--:0,s==87&&w?n--,w--:0,s==66&&b?n--,b--:0,s==69&&e?n--,e--:0,s==76&&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=1,l=3,n,r,z=i;//c,o,w,b,e all start at 1; L starts at 3 for(;s=a[++i];c+=s==67,o+=s==79,w+=s==87,b+=s==66,e+=s==69,l+=s==76); //loop to obtain number of times each character C,O,W,B,E,L is found in string (using the ASCII numeric values of each letter) //to get an extra cowbell we need to increment C,O,W,B,E by 1 and L by 2 (two Ls in cowbell); except we don't have to because we already did that by starting them at c=1, o=1, w=1, b=1, e=1, L=3 when we declared them. r=~-l/2; //r is half of (1 less the number of times L is in string (+ init value)) 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:0)//if L-1/2 is [or is tied for] least occurring character do below logic, else set l to 0 and skip to else 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; else //add 1 to L if it's divisible by 2 (meaning just 1 more L is needed in addition to possibly other C,O,W,B,E letters) (*Note: L count started at 3, so a count of 4 would be divisible by 2 and there is only 1 L in the string) l+=l%2; 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==67&&c?n--,c--:0,s==79&&o?n--,o--:0,s==87&&w?n--,w--:0,s==66&&b?n--,b--:0,s==69&&e?n--,e--:0,s==76&&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. (Edit: Thanks to @Titus I know do this with all COWBELL letters by using uppercase input only which are all 2 bytes numeric ascii values) r=~-l/2 is r=(l-1)/2 using bitshifts a[++i] I'm getting the character at index(i) and iterating the index all at the same time. I just start i at i=-1 instead of i=0 (I do the same with z and start it as z=i to save another byte) • Save 8 bytes with uppercase input: all ASCII codes below 100. – Titus Jan 30 '17 at 19:52 • @Titus Brilliant! Thank you Titus, editing now – Albert Renshaw Jan 30 '17 at 20:27 • We currently have a question regarding your statement "The second defined int (in this case c) is always set as 1 [...]." We'd be glad to have your statement as to why you think so over there because it just seems odd to some of us. – cadaniluk Jan 30 '17 at 22:01 • @Albert could it be that your program just relies on c,o,w,b,e to be initialized to the same value, instead of 1? Because your hint #2 seems to be not true, not for the C I know at least. Can you clarify? SO question – Felix Dombek Jan 30 '17 at 22:03 • @FelixDombek thanks for pointing it out too! It is def. undefined behavior, I just simulated it (looped) on many IDEs and it seems to always init the int as 0. I probably could leave it after all, though my logic was designed to have them all set at 1; the fact that the test cases are working with it at 0 is coincidence I think. Cheers – Albert Renshaw Jan 30 '17 at 22:52 Python 2, 125113 112 bytes n=lambda s:min(s.count(c)>>(c=='l')for c in "cowbel") def f(s,i=0): while n(s)==n(s+s[:i]):i+=1 return s+s[:i]  n counts the number of cowbells -12 bytes thanks to @Rod -1 byte thanks to @Titus • you dont need [] for the list comprehension when it's the only parameter, also you can drop enumerate :min(s.count(c)/-~(c=='l')for c in"cowbel") where -~(n=='l') is a shorter way to write 1+(n=='l') – Rod Jan 30 '17 at 12:24 • Wouldn´t >> be shorter than /-~? – Titus Jan 30 '17 at 19:39 • @Titus you're right – ovs Jan 30 '17 at 19:59 • There was an attempted edit that would have removed a byte by replacing the last newline space with a single semicolon. – Wheat Wizard Jan 31 '17 at 6:19 • @Möbius Wouldn't the return be in the while-loop then? – ovs Jan 31 '17 at 6:28 Perl 6, 91 bytes {my &c={.comb.Bag.&{|.<c o w b e>,.<l>div 2}.min} first *.&c>.&c,($_ X~[\,](.comb)».join)}


Assumes lower-case input.

How it works

Inside the lambda, another lambda for counting the number of cowbells in a string is defined as such:

my &c={                                        }  # Lambda, assigned to a variable.
.comb                                      # Split the string into characters.
.Bag                                  # Create a Bag (maps items to counts).
.&{                       }       # Transform it into:
|.<c o w b e>,                 #   The counts of those letters, and
.<l>div 2        #   half the count of "l" rounded down.
.min   # Take the minimum count.


The rest of the code uses this inner lambda &c to find the result, like this:

                     [\,](.comb)».join   # All prefixes of the input,
($_ X~ ) # each appended to the input. first , # Return the first one for which: *.&c> # The cowbell count is greater than .&c # the cowbell count of the input.  MATL, 38 37 bytes 1 byte off thanks to @DLosc's idea of using the template string lcowbe instead of cowbel nGt@q:)hXK!'lcowbe'=s32BQ/kX<wy-Q]xK  Input characters are all lowercase. If the input contains newlines, the newline character needs to be entered as its ASCII code concatenated with the normal characters (see last input in the link with all test cases). JavaScript (ES6), 106 107 113 126 141 A porting to javascript of the Pip answer by @DLosc. I needed some time to fully understand it, and it's genius. Edit -15 bytes following the hint by @Titus, directly appending chars to the input string a and avoiding early return (so no for/if) Edit 2 enumerating the 6 value for the Min function saves other 13 bytes Edit 3 changed c function again. I thought the verbose length and split would be too lengthy. I was wrong. Assuming lowercase input a=>[...a].some(z=>c(a+=z)>b,c=a=>Math.min(...[...'lcowbe'].map((c,i)=>~-a.split(c).length>>!i)),b=c(a))&&a  Less golfed a=>{ c=a=>{ // cowbell functions - count cowbells k = [... 'lcowbe'].map((c,i) => (a.split(c).length - 1) // count occurrences of c in a / (!i + 1) // divide by 2 if first in list ('l') ); return Math.min(...k); }; b = c(a); // starting number of cowbells [...a].some(z => ( // iterate for all chars of a until true a += z, c(a) > b // exit when I have more cowbells )); return a; }  Test f= a=>[...a].some(z=>c(a+=z)>b,c=a=>Math.min(...[...'lcowbe'].map((c,i)=>~-a.split(c).length>>!i)),b=c(a))&&a ;["christopher walken begs for more cowbell!" ,"the quick brown fox jumps over the lazy dog" ,"cowbell" ,"cowbell cowbell cowbell" ,"cowbell cowbell cowbel" ,"bcelow" ,"abcdefghijklmnopqrstuvwxyz" ,"cccowwwwbbeeeeelllll" ,"be well, programming puzzles & code golf" ,"lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. wow!" ,c-c-b-c i have a cow, i have a bell. uh! bell-cow! i have a cow, i have a cowbell. uh! cowbell-cow! bell-cow, cowbell-cow. uh! cow-cowbell-bell-cow. cow-cowbell-bell-cow! ].forEach(x=>console.log(x+'\n\n'+f(x))) • I guess that k[x]++ would fail due to undefined. But I am pretty certain that for(i=0;c(a)==c(a+=a[i++]);),a works. – Titus Jan 30 '17 at 17:05 • @Titus I'm not sure to understand. I'll give it a try – edc65 Jan 30 '17 at 19:41 • @Titus wow 15 bytes saved, thanks alot – edc65 Jan 30 '17 at 19:56 • >>!i saves 3 bytes. Why don´t you use c(a+=z)? – Titus Feb 3 '17 at 11:31 • @Titus I use c(a+=z). Not in the less golfed version, as it is, you see, less golfed. Using >>!i saves 1 byte (in the golfed version). Thanks again – edc65 Feb 3 '17 at 11:47 Bash + Unix utilities, 184 bytes f()(tr -cd cowbel<<<"$1"|sed 's/$$.$$/\1\
/g'|sort|uniq -c|awk '{print int($1/(($2=="l")?2:1))}'|sort -n|head -1)
for((m=1;f "$1${1:0:m}"!=$[f "$1"+1];m++)){ :;}
echo "$1${1:0:$m}"  Try it online! Thanks to @AlbertRenshaw for golfing 2 bytes off. • This can be golfed further for example just removing the spaces before and after the != – Albert Renshaw Jan 30 '17 at 8:14 • @AlbertRenshaw Thank you -- I thought I had tried that and gotten a syntax error, but you're right. The awk part may be golfable more too; I'm not very familiar with awk. – Mitchell Spector Jan 30 '17 at 8:26 • Yeah I naively tried removing other spaces and linebreaks in your code and was getting syntax errors but on that one it worked ¯_(ツ)_/¯ – Albert Renshaw Jan 30 '17 at 8:31 JavaScript (ES6), 124 114 bytes Thanks to Neil for saving a few bytes a=>eval("for(c=0,d=a;(A=$=>Math.min([...'cowbel'].map(_=>($.split(_).length-1)>>(_=='l'))))(a)==A(d+=a[c++]););d")  Since this is quite different from the already existing JavaScript answer, and I put quite some time into this, I decided to create an answer myself. Usage f=a=>eval("for(c=0,d=a;(A=$=>Math.min([...'cowbel'].map(_=>($.split(_).length-1)>>(_=='l'))))(a)==A(d+=a[c++]););d") f("cowbell")  Output "cowbellcowbell"  • .sort()[0] is a marvellous idea. eval is evil. :D – Titus Jan 30 '17 at 19:35 • Thanks ;-) I first used Math.min(), but that cost a lot of characters, and I figured there'd be a shorter way. And yes, eval is really nice for golfing. – Luke Jan 30 '17 at 20:07 • If only .sort()[0] worked, it would only cost 10 bytes, but it doesn't, and .sort((a,b)=>a-b)[0] costs 20 bytes but Math.min(...) only costs 13. – Neil Jan 31 '17 at 0:32 Octave, 8087 97 bytes s=input('');k=1;do;until(x=@(A)min(fix(sum('cowbel'==A')./('111112'-48))))(b=[s s(1:++k)])>x(s);b  Try It Online! • This doesn't work when we need two ls to complete the additional cowbell. For example, on input cowbell, it incorrectly returns cowbellcowbel rather than cowbellcowbell. (I hope you can fix it—I like the atypical algorithm!) – Greg Martin Jan 30 '17 at 17:38 • @GregMartin Thanks! I will chek it! – rahnema1 Jan 30 '17 at 17:51 CJam, 37 q___S\+{+"cowbel"1$fe=)2/+:e<\}%()#)<


Try it online

If I can exclude the " and \ characters, then…

35 bytes

q___{+"cowbel"1$fe=)2/+:e<\}%()#)<  Try it online Explanation The code successively appends each character of the string to the initial string (going from original to doubled), determines the number of cowbells for each string (counting the number of occurrences of each character in "cowbel" and dividing the one for 'l' by 2, then taking the minimum), finds the position of the first string where the number of cowbells increases by 1, then takes the corresponding prefix of the input and puts it after the input string. In order to include the original string too (with no character appended), the code prepends a neutral character to the string that's being iterated. The first version prepends a space, and the 2nd version uses the string representation, i.e. the string between double quotes. q___ read input and make 3 more copies: one for output, one for prefix, one for appending and one for iterating S\+ prepend a space to the iterating string or  get the string representation {…}% map each character of the string + append the character to the previous string "cowbel" push this string 1$          copy the appended string
fe=         get the number of occurrences of each "cowbel" character
)2/+        take out the last number, divide by 2 and put it back
:e<         find the minimum
\           swap with the appended string
(             take out the first number (cowbells in the initial string)
)#            increment and find the index of this value in the array
)             increment the index (compensating for taking out one element before)
<             get the corresponding prefix
another copy of the input is still on the stack
and they are both printed at the end

• I'm fine with you excluding the " and \ characters! – Greg Martin Feb 11 '17 at 8:43

PHP, 133 bytes

a PHP port of @edc65´s JavaScript port of DLosc´s Pip answer.

function f($s){for(;$c=lcowbe[$i];)$a[$c]=substr_count($s,$c)>>!$i++;return min($a);}for($s=$argv[1];f($s)==f($s.=$s[$i++]););echo$s;


takes lower case input from command line argument. Run with -nr.

breakdown

// function to count the cowbells:
function f($s) { for(;$c=lcowbe[$i];) # loop through "cowbel" characters$a[$c]=substr_count($s,$c) # count occurences in$s
>>!$i++; # divide by 2 if character is "l" (first position) return min($a);             # return minimum value
}
for($s=$argv[1];    # copy input to $s, loop: f($s)               # 1. count cowbells in $s == # 3. keep looping while cowbell counts are equal f($s.=$s[$i++])     # 2. append $i-th character of$s to $s, count cowbells ;); echo$s;             # print \$s
`