Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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.

Your task

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

(pastebin link for easier copy/pasting)

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"
share|improve this question
7  
Anyone who answers in COW earns ten internet points. – Pavel 6 hours ago
3  
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 6 hours ago
    
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 6 hours ago
2  
Well normally people use test case -> result in one large preformatted code block. It's much nicer aesthetically and easier to copy paste. – FlipTack 3 hours ago
    
Pardon my ignorance, but who is Bruce Dickenson, and how is he related to BOC? Edit: made my way through my confusion, and found this wikipedia page – Right Leg 3 hours ago

Pip, 50 42 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)
share|improve this answer
    
I entered cowbell cowbell cowbee and the output was cowbellcowbelcowbel but I might be using the IDE wrong (new to PIP) – Albert Renshaw 3 hours ago
    
@AlbertRenshaw I get cowbell cowbell cowbeecowbell (try it online). Are you using TIO or a local copy? – DLosc 3 hours ago
    
Oh nice! I was sticking it under the field "input" not under the argument add. +1 – Albert Renshaw 3 hours ago

Bash, 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.

share|improve this answer
    
This can be golfed further for example just removing the spaces before and after the != – Albert Renshaw 2 hours ago
1  
@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 2 hours ago
    
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 2 hours ago

C, 511 488 474 470

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(r==n){if(!(l%2)){l=1;c=o=w=b=e=0;}else{l=2;}}else{l=1+l%2;}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:

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(r==n){
    if(!(l%2)){
        l=1;c=o=w=b=e=0;
    }else{
        l=2;
    }
}else{
    l=1+l%2;
}

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));}
share|improve this answer
    
Since your submission is a function, you should be able to put char*a in the argument list and call it good. Getting input from a predefined variable is generally frowned upon. ;) It's fine to hard-code the string in your test harness, just not in your submission. – DLosc 3 hours ago
    
Thanks @DLosc I'll do that now! – Albert Renshaw 3 hours ago

Python 2, 125 bytes

n=lambda s:min([s.count(c)/(1+a/5)for a,c in enumerate("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

share|improve this answer

Perl 6, 91 bytes

{my &c={.comb.Bag.&{|.<c o w b e>,.<l>div 2}.min}
first *.&c>.&c,($_ X~[\,](.comb)».join)}

How it works

Inside the lambda, another lambda for counting the number of cowbells in a string is defines 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.
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.