99 bugs in the code

47

7

99 bugs in the code

The adaption of "99 bottles of beer on the wall" for computer science where the bugs increase instead of the bottles decreasing is often re-posted around the internet. Example T-Shirt Here.

I think it'll be interesting to see potential recursion and random number generation across a huge variety of languages and finding the most efficient ways to do it.

There's a fair few other challenges to do with 99 bottles of beer but none seem to have an increasing and decreasing number!

Challenge

Your program or function should take no input and then print

99 bugs in the code

99 bugs in the code

Take one down and patch it around

X bugs in the code

(blank line)

Where X is the previous integer minus 1 plus a random integer in the range [-15,5].
You can merge the minus 1 into the random integer, hence allowing the range [-16,4].
Ranges can be exclusive, so minus one plus (-16,6) or (-17,5).

The random integers don't have to be evenly distributed they just have to all be possible.

The program always starts with 99 bugs.

You can ignore the grammatical error of "1 bugs".

The program should stop when the number of bugs is 0 or negative and print

0 bugs in the code

There should never be a negative number of bugs. The ending should look like

Y bugs in the code

Y bugs in the code

Take one down and patch it around

0 bugs in the code

(blank line)

0 bugs in the code

A trailing new line is acceptable.

  • Your code can be a full program or a function.
  • There is no input.
  • The output should be to stdout or returned.
  • Warnings/errors in logs/STDERR are okay as long as STDOUT has the required text. See here for more info.

This is code-golf so the shortest code in bytes wins.

Example Output

Paste bin example output rigged for -11 bugs each time

Sam Dean

Posted 2018-05-29T14:04:23.357

Reputation: 639

1

Related: 1 2 (difference: in this challenge the output can be arbitrarily long).

– user202729 – 2018-05-29T14:16:06.983

why is merging the 1 in the random only allowed if the random distribution is uniform? It makes no difference (AFAICT), as rand(-15,5)-1 could get simplified to rand()*21 - 15 - 1 = rand()*21 - 16 for any random number generation implementation. – dzaima – 2018-05-29T14:23:26.883

We always will start at 99 correct ? – Muhammad Salman – 2018-05-29T14:26:15.933

@dzaima that's exactly what i assumed – The random guy – 2018-05-29T14:33:58.770

@dzaima yes you're right. I'd got it in my head that it would affect the averages or something. I'll change it – Sam Dean – 2018-05-29T14:43:07.053

@MuhammadSalman yep always starts at 99 – Sam Dean – 2018-05-29T14:44:21.497

16A more realistic scenario would be if the sign of the random number was flipped! – Stewie Griffin – 2018-05-29T15:21:03.373

9I am disappointed, that the requirements don't include that the program must have a bug once a negative number is encountered, like crashing, overflowing to max int or similar ;). – allo – 2018-05-30T09:58:49.020

@allo I guess in theory all the answers will crash if the random number keeps being positive! – Sam Dean – 2018-05-30T10:26:59.847

3

"The random integers don't have to be evenly distributed they just have to all be possible." reminded me of https://xkcd.com/221/

– Ivo Beckers – 2018-05-30T12:33:30.233

1Is the fact that the output isn't to match the metre of the original bugging anyone else, or is it just me? – Baldrickk – 2018-05-30T12:52:50.127

2

It's a shame 99 has no random number generation.

– Jonathan Allan – 2018-05-30T21:07:48.547

1Are trailing newlines allowed? – Giuseppe – 2018-05-31T11:24:18.470

Title should be "Quantum Bugs in the Code" – Magic Octopus Urn – 2018-06-01T00:55:29.613

Is the "continuously print" an actual requirement? (Some answers actually produce the whole string.) – Jonathan Allan – 2018-06-01T15:40:39.803

"Warnings in logs are okay." Does this mean warnings (or errors) in stderr are acceptable? – Reinstate Monica -- notmaynard – 2018-06-01T16:15:22.790

How strict is the output format? In QBasic, it's WAY easier if the numbers are allowed to have a leading space. – DLosc – 2018-06-01T19:49:06.093

@JonathanAllan I would prefer the whole string not all be printed at the end but I think it's a little late to enforce that now – Sam Dean – 2018-06-04T09:10:09.823

1Agreed - maybe edit the challenge to just say "print" then. – Jonathan Allan – 2018-06-04T09:11:14.170

@DLosc That output format is HIGHLY preferred but I have allowed COBOL to have signs before numbers because formatting adds so many characters so I'll allow it in general for languages that struggle formatting numbers. – Sam Dean – 2018-06-04T09:13:19.397

1

RE: @iamnotmaynard's question: I believe that the default is that if the chosen output is somewhere other than STDERR then any coincident STDERR may simply be ignored (This is along with the fact that we may choose to output to STDERR or as the top of the stack etc, and ignore other coincident output(s)) - I would suggest actually removing the requirement "The output should be to stdout or returned" (use defaults)

– Jonathan Allan – 2018-06-04T09:22:34.723

1...also your comment "so for now I'm going to say they're not okay" would invalidate my Python 2 answer since it adhere's to the spec as written - it outputs to stdout - but performs a divide by zero to force an early exit. – Jonathan Allan – 2018-06-04T09:41:23.637

As per @Giuseppe's question, are trailing newlines (plural) allowed? – JayCe – 2018-06-04T14:53:38.560

@JayCe a single trailing new line is allowed – Sam Dean – 2018-06-04T15:24:55.080

a single trailing new line is allowed: That would make the recent javascript and C# entries invalid judging from the TIO links. – JayCe – 2018-06-08T19:02:03.373

@JayCe Yes they are invalid. The above wasn't a rule change, the main post always said "A trailing new line". – Sam Dean – 2018-06-11T09:33:55.060

Answers

18

R, 182 140 138 135 bytes

n=99;while(n)cat(n,b<-" bugs in the code
",n,b,"take one down and patch it around
",n<-max(0,n-sample(21,1)+5),b,"
",c(n,b)[!n],sep="")

Try it online!

while being reasonably good at random number generation, R is terrible at strings and printing. JayCe found about a billion bytes, and continues to find new ways to golf this!

Giuseppe

Posted 2018-05-29T14:04:23.357

Reputation: 21 077

1Where did JayCe find all those bytes? Was it just happenstance or was JayCe actively looking for them? – Stewie Griffin – 2018-05-30T07:31:12.297

2

@StewieGriffing one billion and one :) from Jonathan Allan's Python solution

– JayCe – 2018-05-31T00:25:03.457

Isn't the +5 costing you another 2 bytes? why not just sample(26,6))? – theforestecologist – 2018-05-31T17:16:03.393

2@theforestecologist Welcome to PPCG ! I suggest you take a closer look at the question... there is a minus sign in front sample – JayCe – 2018-05-31T18:23:15.720

@Giuseppe I saw your comment to the question re: newline at the beginning... I just realized I have one newline too many :( – JayCe – 2018-05-31T18:27:30.033

11

Java 8, 161 160 bytes

v->{String s="",t=" bugs in the code\n";for(int i=99;i>0;s+=i+t+i+t+"Take one down and patch it around\n"+((i-=Math.random()*21+4)<0?0:i)+t+"\n");return s+0+t;}

-1 byte thanks to @JonathanAllan.

Try it online.

Explanation:

v->{                   // Method with empty unused parameter and String return-type
  String s="",         //  Result-String, starting empty
         t=" bugs in the code\n";
                       //  Temp-String we use multiple times
  for(int i=99;i>0;    //  Start `i` at 99, and loop as long as it's larger than 0
    s+=                //   Append to the result-String:
       i+t             //    The first line of the verse
       +i+t            //    The second (duplicated) line of the verse
       +"Take one down and patch it around\n"
                       //    The third line of the verse
       +((i-=Math.random()*21-4)
                       //    Decrease `i` by a random integer in the range [-16, 4]
         <0?0:i)       //    If `i` is now negative, set it to 0
        +t+"\n");      //    And append the fourth line of the verse
  return s             //  Return the result,
         +0+t;}        //  appended with an additional line for 0 at the very end

Kevin Cruijssen

Posted 2018-05-29T14:04:23.357

Reputation: 67 575

Seems you are not using r for anything? – O.O.Balance – 2018-05-29T15:12:45.920

1

Removing ,r appears to still work: Try it online!

– Kamil Drakari – 2018-05-29T15:45:13.490

@O.O.Balance Oops.. Not sure why I got that there.. >.> Thanks for noticing. – Kevin Cruijssen – 2018-05-29T17:13:42.950

1i-=...+5 saves one (although I think the range should be [-16 4] not [-15,5]) – Jonathan Allan – 2018-05-31T00:35:14.680

1@O.O.Balance yes r is not used, because he is using java ;-) – Anand Rockzz – 2018-05-31T05:44:24.553

@JonathanAllan It should actually be i-=...-4 instead of +4, but thanks for the -1 byte (and fixed range)! – Kevin Cruijssen – 2018-05-31T06:28:10.147

Use Java 10 so you can replace everything with var ;) – Jacob G. – 2018-06-01T00:42:28.047

@JacobG. The only thing I can replace with var in my answer is the int, which doesn't save anything I'm afraid. :) And I could change String s="",t="..."; to var s="";var t="...";, but that wouldn't save bytes either (in fact, it increases the byte-count by 1). – Kevin Cruijssen – 2018-06-01T06:46:23.750

10

PowerShell, 137 135 133 131 bytes

$b=' bugs in the code';for($a=99;$a){,"$a$b"*2;"Take one down and patch it around";$a+=-16..4|Random;if($a-lt0){$a=0}"$a$b`n"}"0$b"

Try it online!

The "bugs in the code" section is saved into $b for later use. Sets $a to 99, enters a for loop on $a. First we create an array of two strings ," "*2, with the string being the "X bugs in the code".

Next is just the string "Take one down and patch it around". Then we increment $a by selecting a Random integer from the range [-16,4]. After that, we clamp $a to be at minimum zero using an if if($a-lt0){$a=0}. Then the string "Y bugs in the code".

Finally, after the loop is finished, we put the string "0 bugs in the code" onto the pipeline. All of those strings are gathered from the pipeline, and an implicit Write-Output gives us newlines between them for free.

Saved two bytes using a for loop instead of a while loop.
Saved two bytes by moving $b onto its own section.
Saved two bytes thanks to Adrian Blackburn.

AdmBorkBork

Posted 2018-05-29T14:04:23.357

Reputation: 41 581

You could replace $a=(0,$a)[$a-gt0]; with If($a-lt0){$a=0} for a couple of bytes – Adrian – 2018-11-30T06:06:36.703

@AdrianBlackburn Thanks! – AdmBorkBork – 2018-11-30T13:28:18.453

9

JavaScript (Node.js), 127 bytes

f=(i=99,t=` bugs in the code
`)=>i>0?i+t+`Take one down and patch it around
`+((i+=0|Math.random()*21-15)<0?0:i)+t+`
`+f(i):0+t

Try it online!


Explanation :

f = (                                          // start of our recursive function
    i=99,t=` bugs in the code                 // parameters, 1. num bugs , 2. text
`)                                           // using string literal end text with \n
=>                                          // start function
    i > 0 ?                                // if i is greater than 0
        i + t +                           // return value of i, value of t and  
    `Take one down and patch it around   // and this text 
    `                                   // + new line
    + (( i +=                          // and add 
        0|Math.random()*21-15) < 0 ?  // remove decimal from value obtained by multiplying
                                     // random number (between 0 and 1) multiplied by 21 
                                    // and then subtracting 15 from it
                                   // if that value is less than 0
        0 :                       // add 0 to i
        i                        // otherwise add value of i  
        )                       // end the parenthesis 
    + t                        // add value of t to that
    + `\n`                    // along with a new line 
    + f(i)                   // and repeat the process (this is recursive)
    :                       // if i > 0 condition not met then
        0 + t              // return 0 + t. Zero is there so the last line can be 
                          // repeated

Thanks to @tsh for the idea of recursion and implementation (saved some bytes)

Any suggestions to golf this further are welcome.

Muhammad Salman

Posted 2018-05-29T14:04:23.357

Reputation: 2 361

Use recursion save some bytes – tsh – 2018-05-30T03:16:14.763

1Why was 0+ removed? It seems to be required output. – tsh – 2018-05-30T08:55:11.973

@tsh : Is it ? I didn't read that part. – Muhammad Salman – 2018-05-30T09:14:51.590

7

05AB1E, 59 bytes

99[Ð16(4ŸΩ+¾‚{θ©3F“ÿ±À€†€€ƒË“Š}“ƒ¶€µ„‹€ƒš¡€•…¡“ªsõ®>#®]sDŠ»

Try it online!

Emigna

Posted 2018-05-29T14:04:23.357

Reputation: 50 798

6

JavaScript, 189 176 168 162 bytes

f=(x=99)=>{c=console.log;m=Math;a=` bugs in the code
`;c(x+a+x+a+"Take one down and patch it around"+(x=m.max(x+m.ceil(m.random()*21-15),0))+a)
x?f(x):c(`
`+x+a)}

Try it online!

Thanks for Muhammad Salman for the missing console.log replacement, and for Oliver for the x test improvement

Thanks for l4m2 for golfing this by 8 bytes

The random guy

Posted 2018-05-29T14:04:23.357

Reputation: 1 262

I'm no node expert, but I believe "The program should stop when the number of bugs is 0 or negative" means you need x<=0?console.log("\n"+0+a):f(x) at the end. – NoOneIsHere – 2018-05-29T14:38:13.237

that's what i do with x==0?console.log("\n"+x+a):f(x) – The random guy – 2018-05-29T14:41:13.530

1Ok, sorry. One more thing: if you need to recurse in an anonymous function, you need to explicitly name it (+2 bytes) – NoOneIsHere – 2018-05-29T14:42:25.873

You can ignore those 2 bytes, you'll see that in most of JS answers here – The random guy – 2018-05-29T14:47:30.660

Not if the function requires itself to be named f. – NoOneIsHere – 2018-05-29T14:51:48.503

1can't that last "console.log" be replaced with "c"? – Sam Dean – 2018-05-29T14:51:49.660

@Therandomguy : saved a ton of bytes

– Muhammad Salman – 2018-05-29T14:55:48.350

1Also @NoOneIsHere is right. You do need that f declaration. Voted down till updated to fix that. (Also my link needs an update too) – Muhammad Salman – 2018-05-29T14:57:22.513

2The point I'm trying to make here is your code doesn't work if the function isn't called f, which you can't assume. – NoOneIsHere – 2018-05-29T14:58:03.467

@Oliver : Yeah, you could, but you should tell the author and not me – Muhammad Salman – 2018-05-29T20:57:54.127

@Therandomguy : Thanks for update. I undownvoted this – Muhammad Salman – 2018-05-29T20:58:30.577

(x+a).repeat(2) for what no direct add? – l4m2 – 2018-05-30T10:49:02.587

Could you save a byte using with? TIO

– Craig Ayre – 2018-05-30T15:46:46.783

Node.js is not necessary here. It's just pure JavaScript (version 6?) – n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ – 2018-05-31T01:35:13.897

6

Python 3, 156 138 bytes

Thanks to Jonathan's Python 2 answer for the id trick

r=n=99
z='%d bugs in the code\n'
while n:x=n;r+=id(r);n-=min(n,r%21-4);print((z%x)*2+'Take one down and patch it around\n'+z%n)
print(z%n)

Try it online!

Explanation:

r=n=99       #Initialise r and n to 99
z='%d bugs in the code\n'  #Save n
while n:     #Loop while n is not 0
    x=n      #Save value of n
    r+=id(r) #Modify value of r, which changes the hash value
    n-=min(n,r%21-4)  #Change n's value by a random number between 4 and -16
    print((z%x)*2+'Take one down and patch it around\n'+z%n)   #Print the message
print(z%n)  #And print the final line

Jo King

Posted 2018-05-29T14:04:23.357

Reputation: 38 234

6

Charcoal, 81 bytes

≔⁹⁹θ≔”⧴"pWº⁴tSn/{yBⅈ⁺”ζW›θ⁰«×²﹪ζθ”↶0⪫\`3+¤⸿Zν(z¬hLÀTj'ZXεPraF”≧⁺⁻⁴‽²¹θ﹪ζ×θ›θ⁰¶»﹪ζ⁰

Try it online! Link is to verbose version of code. Explanation:

≔⁹⁹θ

Start with 99 bugs in the code.

≔”⧴"pWº⁴tSn/{yBⅈ⁺”ζ

Save the compressed string "%d bugs in the code\n".

W›θ⁰«

Repeat while there are a positive number of bugs remaining.

ײ﹪ζθ

Print the number of bugs in the code twice.

”↶0⪫\`3+¤⸿Zν(z¬hLÀTj'ZXεPraF”

Print "Take one down and patch it around".

≧⁺⁻⁴‽²¹θ

Add a random number of bugs between -17 (exclusive) and 4 (inclusive).

﹪ζ×θ›θ⁰

Print the number of bugs remaining, or 0 if negative.

Leave a blank line between verses.

»﹪ζ⁰

After the last verse, print 0 bugs in the code again.

Neil

Posted 2018-05-29T14:04:23.357

Reputation: 95 035

Need that final repeated "0 bugs in the code"! – Sam Dean – 2018-05-30T09:17:57.387

1@SamDean Sorry I'd overlooked that, fixed. – Neil – 2018-05-30T09:42:56.563

5

Octave, 149 148 bytes

Saved one byte by changing randi(21) and %i to 21*rand and %.f. %.f ensures the output is a float with zero decimals (i.e. and integer).

Inserted a bunch of line breaks instead of commas and semicolons to ease readability. It feels wrong, but it's not longer than the one-liner.

x=99;do(p=@(i)printf('%.f bugs in the code\n',i))(x)
p(x)
disp('Take one down and patch it around')
p(max([0,x+=21*rand-17]))
disp('')until x<1
p(0)

Try it online!

Explanation:

x=99;               % Initialize the number of bugs to 99
do ...  until x<1   % Loop until the number of bugs is less than 1
 (p=@(i)printf('%.f bugs in the code\n',i))(x)  % Create a function handle p that takes
                                                % the number of bugs as input and outputs
                                                % the string x bugs ... \n
 p(x)                % Call that function with the same number of bugs to get two lines
 ,disp('Take on down and patch it around')       % Outputs that line, including a newline
 ,p(max([0,x+=21*rand-17]))                    % Call p again, while updating the number
                                                 % of bugs. The number of bugs will be 
                                                 % the old one plus the random number, or 0
                                                 % if it would have turned negative
 ,disp('')        % A newline
p(0)              % Finally, the last single line.

Using p((x+=21*rand-17)*(x>0) instead of max saves a byte, but the last line outputs -0 bugs ... instead of 0 bugs. It works with randi(21)-17, but then it's the same length as the one above. Try it online!

Stewie Griffin

Posted 2018-05-29T14:04:23.357

Reputation: 43 471

5

Python 2, 151 bytes

Nice trick j=i+max(-i,randint(-16,4)) by Jo King, exploiting allowed uneven distribution

Saved couple bytes thanks to Mnemonic

from random import*
i,s=99,'bugs in the code\n'
while i:j=max(0,i+randint(-16,4));print i,s,i,s,'Take one down and patch it around\n',j,s;i=j
print i,s

Try it online!

Dead Possum

Posted 2018-05-29T14:04:23.357

Reputation: 3 256

1You can save a byte by using j=max(0,i+randint(-16,4)). – None – 2018-05-29T15:19:15.987

Also, it's 'bugs in the code'. – None – 2018-05-29T15:20:42.690

Using 0 to compare wiil make not all numbers possible. Thanks for nothing 'the' :D – Dead Possum – 2018-05-29T15:23:20.737

Same trick as my answer, 151 bytes

– Jo King – 2018-05-29T15:24:45.237

They're not possible anyway. You're not allowed to go below 0. – None – 2018-05-29T15:24:49.920

@DeadPossum : which numbers will be made impossible ? – Muhammad Salman – 2018-05-29T15:28:39.570

@Mnemonic Now I get it, didn't pay enough attention( – Dead Possum – 2018-05-29T15:36:34.173

5

COBOL (GnuCOBOL), 317 294 279 270 bytes

data division.working-storage section. 1 i pic S99 value 99.procedure division.perform until i=0 perform a 2 times display"Take one down and patch it around"compute i=i-(random*21- 4)if i<0 compute i=0 end-if perform a display""end-perform.a.display i" bugs in the code"

Try it online!

Ungolfed

data division.                     <-- Define the variables we want to use
working-storage section.           <-- Define global variables used in this
                                       program

1 i pic S99 value 99.              <-- Define variable i with datatype signed
                                       numeric and with two digits

procedure division.                <-- Define our program

perform until i = 0                <-- Perform the following code until i = 0
    perform a 2 times              <-- Execute the procedure called 'a' twice,
                                       see below

    display "Take one down and patch it around"   <-- Display this sentence
    compute i = i -                <-- Subtract from i some random value
        (random * 21 - 4)

    if i < 0                       <-- if i < 0
        compute i=0                <-- then assign 0 to i
    end-if
    perform a                      <-- Execute the procedure 'a'
    display ""                     <-- Display an empty string; needed because
                                       of the blank line
end-perform.

a.                                 <-- Define procedure called 'a'.
    display i " bugs in the code"  <-- Display the value of i and then the
                                       given string literal

Note: the last sentence is still printed, because COBOL executes the whole program, and after the perform until loop it "falls-through" the label a, executing its statements. This behaviour is similar to a switch case without break.

PS: The numbers are not exactly displayed as required, but COBOL is not that good at auto-converting numbers to a pretty textual representation.

MC Emperor

Posted 2018-05-29T14:04:23.357

Reputation: 171

1Hi. Welcome to PPCG. – Muhammad Salman – 2018-05-31T10:10:21.543

I think that minus 4 should be plus 4. I'm guessing you went for (i-(rand-4) == (i-rand+4). But there's no brackets so the sign needs to change. Also can the signs of the numbers be removed or is that a feature of the language? But nice work with a non gold friendly language! – Sam Dean – 2018-05-31T10:29:46.120

1

@SamDean Thanks! I fixed that mistake. I got to admit that the actual random calculated was inspired from Kevin Cruijssen's answer. But he uses a compound assignment operator (-= in i-=Math.random()*21-4), which implies parenthesis around the whole righthand operand. I forgot to make them explicit, but it is now fixed, I think.

– MC Emperor – 2018-05-31T11:49:06.397

@MCEmperor looks good to me now! – Sam Dean – 2018-05-31T12:21:48.913

Can't you use +4 and save the brackets? – raznagul – 2018-06-01T13:08:45.127

@raznagul No, I can't, the compiler start whining. – MC Emperor – 2018-11-09T14:13:22.113

4

C,  169  165 bytes

Thanks to @ceilingcat for saving four bytes!

*s=" bugs in the code";f(i,j){for(i=99;i>0;i=j)printf("%d%s\n%d%s\nTake one down and patch it around\n%d%s\n\n",i,s,i,s,(j=i+rand()%19-15)<0?0:j,s);printf("0%s",s);}

Try it online!

Steadybox

Posted 2018-05-29T14:04:23.357

Reputation: 15 798

4

VBA: 212 163 Bytes

This solution is based on the one by Chronocidal posted yesterday. This my first post and I don't have enough reputation to comment on his post.

This revision contains two enhancements.

  1. Using While/Wend instead of For/Next saves a few characters.
  2. Calling a Sub named with a single character is shorter than GoSub and the Exit Sub and Return lines needed to support it.

Edit:
3. Removed whitespace and characters that the VBA editor will automatically add back in. See Tips for golfing in VBA
4. Added suggestions by @EricF, then saw his paste bin algorithm was even smaller so I replaced my algorithm with his and removed whitespace. A key change was appending vbLF to the output string so Debug.Print did not have to be called as often. Kudos to EricF.


Sub b()
s=" bugs in the code"&vbLf
c=99
While c
Debug.? c &s &c &s &"Take one down and patch it around
c=c+5-Int(Rnd()*20)
c=IIf(c<0,0,c)
Debug.? c &s
Wend
End Sub

This was a fun challenge. If you know of an online interpreter like TIO for VB6/VBScript/VBA please leave a comment.

If you want to test this code and have Microsoft Excel, Word, Access, or Outlook installed (Windows only), press Alt+F11 to open the VBA IDE. Insert a new code module (Alt+I,M) and clear out Option Explicit. Then paste in the code and press F5 to run it. The results should appear in the Immediate Window (press Ctrl+G if you don't see it).

Ben

Posted 2018-05-29T14:04:23.357

Reputation: 201

4Welcome to the site! – Post Rock Garf Hunter – 2018-06-02T03:50:34.830

1

You can get it down to 197 characters if you combine strings, use c instead of c>0 as your While condition, and use c=Iif(c<0,0,c) instead of If c<0 [...]: https://pastebin.com/nFGtGqdE

– ErikF – 2018-06-04T19:33:11.857

4

LaTeX, 368 304 293 287 245 240 bytes

While not really competitive compared to the other programs in terms of bytes, I just wanted to see how to do this in LaTeX.

\documentclass{proc}\newcount\b\b99\usepackage[first=-16,last=5]{lcg}\def~{\the\b\ bugs in the code\\}\def\|{\loop~~Take one down and patch it around\\\rand\advance\b\value{rand}\ifnum\b>0 ~\\\repeat\b0 ~\\~}\begin{document}\|\end{document}

More readable:

\documentclass{proc}               %shortest document class
\newcount\b                        %short variable name
\b 99                              %set the value to 99
\usepackage[first=-16,last=5]{lcg} %random number generator
%\the prints the value of the variable behind it
%\def is shorter than \newcommand and can redefine commands
\def~{\the\b\ bugs in the code\\}
\def\|{                            %the function
    \loop
        ~
        ~
        Take one down and patch it around\\
        %\rand creates a counter named rand and                                        
        %stores the random value in it
        \rand \advance\b\value{rand} 
        %if the counter is smaller than 0, it becomes 0
        \ifnum\b>0 
            ~ \\                  %extra newline as required
    \repeat
    %if b is equal or smaller than 0, set it to 0
    \b 0 
    ~ \\                          %then print like normal
    %extra print at the end
    ~
}
\begin{document}
    \|                             %calling the function
\end{document}

Improvements (per edit):

  1. "x bugs in the code" is now a function instead of 4 lines
  2. Rewrote the \if clause for the \repeat as a \else
  3. Apparently \value{b}=x works for initialisation but not in the loop (instead of \setcounter{b}{x})
  4. Apparently \relax should be used for point 3, but that can also be achieved by inserting a space. Removed the \else, used TeX commands instead of LaTeX as these are shorter, and replaced \' by ~.
  5. Some code didn't need to be relaxed for some reason.

Simon Klaver

Posted 2018-05-29T14:04:23.357

Reputation: 161

1Welcome to PPCG. – Muhammad Salman – 2018-06-02T15:17:54.013

Welcome to PPCG! I haven't run your code but shouldn't it be \ifnum\value{b}<1 rather than <0? – JayCe – 2018-06-04T14:01:19.107

@JayCe: It doesn't really matter, once b is 0 it escapes the loop anyway. It may just be less intuitive that when b is 0 the else case is printed indeed, but effectively there is no difference I think. – Simon Klaver – 2018-06-04T15:37:02.830

@JayCe shortened the code, now it doesn't matter anymore ;) – Simon Klaver – 2018-06-04T16:49:20.567

3

SAS, 210 bytes

%macro t;%let b=bugs in the code;%let a=99;%do%until(&a<=0);%put&a &b;%put&a &b;%put Take one down, pass it around;%let a=%eval(&a-%sysfunc(ranbin(0,20,.3))+4);%if &a<0%then%let a=0;%put&a &b;%put;%end;%mend;%t

Ungolfed:

%macro t;
%let b=bugs in the code;
%let a=99;
%do%until(&a<=0);
  %put &a &b;
  %put &a &b;
  %put Take one down, pass it around;    
  %let a=%eval(&a-%sysfunc(ranbin(0,20,.3))+4);
  %if &a<0%then%let a=0;
  %put &a &b; 
  %put;
%end;
%mend;
%t

Can save a few bytes if warnings in the log are permitted (put the &a into the &b macro variable, but that generates an initial warning).

Joe

Posted 2018-05-29T14:04:23.357

Reputation: 283

A few others have warnings so I'll go with they are allowed. – Sam Dean – 2018-05-30T09:20:57.963

3

C (gcc), 141 137 bytes

I used preprocessor macros for great justice (warning: TV Tropes)

#define _(a)printf("%d bugs in the code\n"#a,i)
f(i){for(i=99;_(),i;i+=rand()%21-16,i*=i>0,_(\n))_(Take one down and patch it around\n);}

Try it online!

ErikF

Posted 2018-05-29T14:04:23.357

Reputation: 2 149

3

Clean, 245 234 bytes

import StdEnv,Math.Random,System.Time,System._Unsafe,Text
f[n,v:l]b|n>0=n<+b<+n<+b+"Take one down and patch it around\n"<+max 0v<+b+"\n"+f[v:l]b=0<+b

f(scan(+)99[n rem 20-16\\n<-genRandInt(toInt(accUnsafe time))])" bugs in the code\n"

Try it online!

Οurous

Posted 2018-05-29T14:04:23.357

Reputation: 7 916

Any chance you can remove the quotes at the start and end? – Sam Dean – 2018-05-30T09:15:05.430

1@SamDean Oh that's just a compiler option I forgot about. I'll throw that in. – Οurous – 2018-05-30T21:59:25.063

3

PHP, 126 bytes

Run on the command line, using php -r 'code here':

$b=" bugs in the code
";for($x=99;print$x.$b,$x;)echo"$x{$b}Take one down and patch it around
",$x-=min($x,rand(-4,16)),"$b
";

PleaseStand

Posted 2018-05-29T14:04:23.357

Reputation: 5 369

Try it online! – MC Emperor – 2018-05-31T15:27:01.340

3

ABAP, 295 bytes

...because why the heck not!

REPORT z.DATA:a(16),c TYPE qfranint.a = 'bugs in the code'.data(b) = 99.WRITE:/ b,a.WHILE b > 0.WRITE:/ b,a,/'Take one down and patch it around'.CALL FUNCTION
'QF05_RANDOM_INTEGER' EXPORTING ran_int_max = 21 IMPORTING ran_int = c.b = b + c - 17.IF b < 1.b = 0.ENDIF.WRITE:/ b,a,/,/ b,a.ENDWHILE.

It's certainly not competitive compared to other languages, but I even managed to slim it down from 330 bytes I wrote initially, so I count it as a personal win.

Since ABAP doesn't allow lines longer than 255 characters, I had to replace a space with a line break. On Windows this initially increased the size to 296 bytes due to CRLF, but it runs fine with just the LF in there. ABAP sure requires many spaces though, so this is no big deal.

WRITE simply dumps text the GUI, so I guess that is kind of like stdout? I could probably save some bytes here by using a structure or table, but due to how SAP handles mixed structures (containing chars and numbers) the approach I imagined would only work on non-Unicode systems... Which I personally consider a no-go, despite having access to both.

The function module for random numbers is the only one I could find in our system, I suppose there could be one with a shorter name or parameters. No idea!

More or less readable code, comments included:

REPORT z.
  "Define a (text) and c (random)
  DATA: a(16),
        c TYPE qfranint. "A stupid data type for a random INT

  "This is shorter than using VALUE (saves 3 bytes)
  a = 'bugs in the code'.
  "This is slightly shorter than doing ',b TYPE i' and 'b = 99'. (saves 2 bytes)
  data(b) = 99.

  "first line has to be outside of loop due to our exit condition (saved me ~5 bytes)
  WRITE: / b,a. "\n xx bugs in the code

  WHILE b > 0.
    WRITE: / b,a, "\n xx bugs in the code
    /'Take one down and patch it around'.

    "This ridiculous function for random numbers...
    "To save some bytes, I leave ran_int_min at it's default
    "of 1, and set the max to 21 instead, from which I remove
    "17 later on, resulting in a range of [-16,4]
    "Compare:
    "   ' - 17'              =  5 bytes
    "   ' ran_int_min = -16' = 18 bytes
    "(saves 13 bytes)

    CALL FUNCTION 'QF05_RANDOM_INTEGER'
        EXPORTING ran_int_max = 21
        IMPORTING ran_int = c.

    "Maximum number of bugs added:     4 = 21 - 17
    "Maximum number of bugs removed: -16 =  1 - 17
    b = b + c - 17.

    IF b <= 0.
        b = 0.
    ENDIF.

    WRITE: / b,a,/,/ b,a. "\nxx bugs in the code\n\nxx bugs in the code
  ENDWHILE.

Thanks for the challenge!
To my boss: Please don't fire me, I'm just educating myself!

Maz

Posted 2018-05-29T14:04:23.357

Reputation: 191

3

C#, 184 181 bytes

My first Code Golf answer!

(Based on Java answer from @Kevin Cruijssen)

Func<String>c=()=>{String s="",t=" bugs in the code\n";for(int i=99;i>0;s+=i+t+i+t+"Take one down and patch it around\n"+((i-=new Random().Next(21)-4)<0?0:i)+t+"\n");return s+0+t;};

Try it online!

Ben Noble

Posted 2018-05-29T14:04:23.357

Reputation: 31

1Welcome to PPCG :) – Shaggy – 2018-06-05T08:56:59.003

2

T-SQL, 188 bytes

DECLARE @ INT=99,@b CHAR(18)=' bugs in the code
'a:PRINT CONCAT(@,@b,@,@b,'Take one down and patch it around
')SET @+=5-22*RAND()IF @<0SET @=0PRINT CONCAT(@,@b,'
')IF @>0GOTO a;PRINT '0'+@b

SQL allows returns inside string literals, so that helps.

CONCAT() does an implicit conversion to text so I don't have to worry about CAST or CONVERT.

BradC

Posted 2018-05-29T14:04:23.357

Reputation: 6 099

2

Jelly, 61 bytes

;“,Ȥm46Ṛṛ⁽eɼḞF»
ÇȮ“"ḃḲɠ⁼ċTṪʠ/Ạ⁺ṗḍ^ẸƘⱮṖ8»20X+_«¥©17Ç⁷®ßÇ®?
99Ç

A niladic link which also works as a full program.

Try it online! (output is flushed after execution is complete but it prints paragraph by paragraph)

How?

;“,Ȥm46Ṛṛ⁽eɼḞF» - Link 1, helper to construct count-text: number
 “,Ȥm46Ṛṛ⁽eɼḞF» - compressed string (list of characters) = " bugs in the code\n"
;               - concatenate the number with that list of characters

ÇȮ“"ḃḲɠ⁼ċTṪʠ/Ạ⁺ṗḍ^ẸƘⱮṖ8»20X+_«¥©17Ç⁷®ßÇ®? - Link 2, print stuff: number
Ç                                         - call the last Link (1) as a monad
 Ȯ                                        - print and yield that
                                          - ...at this point that is then printed again
                                          -    implicitly due to the start of a new leading
                                          -    constant chain below
  “"ḃḲɠ⁼ċTṪʠ/Ạ⁺ṗḍ^ẸƘⱮṖ8»                  - compressed string (list of characters)
                                          -     = "Take one down and patch it around\n"
                                          - ...once again an implicit print, same reason
                        20                - twenty
                          X               - random int from [1,20] 
                           +              - add the left argument, the number
                                17        - seventeen
                              ¥           - last two links as a dyad:
                             «            -   minimum (of rand[1,20]+n and 17) 
                            _             -   subtract
                               ©          - copy this newNumber to the register
                                  Ç       - call last Link (1) as a monad = f(newNumber)
                                          - here we get another implicit print, same reason
                                   ⁷      - a new line character
                                          - yet another implicit print, same reason
                                    ®     - recall newNumber from the register
                                        ? - if... 
                                       ®  - ...condition: recall from register again
                                          -               (i.e. if non-zero)
                                     ß    - ...then: call this Link (2) as a monad
                                          -          = Link 2(newNumber)
                                      Ç   - ...else: call the last Link (1) as a monad
                                          -          = Link 1(0) (since newNumber=0)

99Ç - Main Link: no arguments
99  - yep, you guessed it, ninety nine
  Ç - call the last Link (2) as a monad

Jonathan Allan

Posted 2018-05-29T14:04:23.357

Reputation: 67 804

2

JavaScript, 138 bytes

_=>(I=i=>`Take one down and patch it around
${l=(i>0?i:0)+` bugs in the code
`}
`+l+l+(i>0&&I(i+Math.random()*21-15|0)))(99).slice(55,-25)

f=

_=>(I=i=>`Take one down and patch it around
${l=(i>0?i:0)+` bugs in the code
`}
`+l+l+(i>0&&I(i+Math.random()*21-15|0)))(99).slice(55,-25)

console.log(f())

darrylyeo

Posted 2018-05-29T14:04:23.357

Reputation: 6 214

2

QB64, 134 bytes

From my brother.

S$="bugs in the code":I=99:WHILE I>0:?I;S$:?I;S$:?"Take one down and patch it around":I=I+INT(RND*21)-15:I=-(I>0)*I:?I;S$:?:WEND:?I;S$

ErikF

Posted 2018-05-29T14:04:23.357

Reputation: 2 149

2

Pyth, 94 92 bytes

J99WJ%jb[K"%d bugs in the code"K"Take one down and patch it around"Kk)[JJ=JeS,Z+J-O21 16;%KZ

Try it online


Previous version: 94 bytes

J99WJp%jb[K"%d bugs in the code"K"Take one down and patch it around"K)[JJ=JeS,Z+J-O21 16)b;%KZ

Sok

Posted 2018-05-29T14:04:23.357

Reputation: 5 592

2

Python 2,  138 134 133 131  127 bytes

-1 Thanks to Jo King (rearrange so as to use the logic bugs-=min(bugs,randomNumber) rather than bugs=max(0,bugs-randomNumber)). This allowed the force-quit using a division by zero error, saving a further 6 bytes!

r=n=99
t="bugs in the code\n"
while 1:r+=id(r);b=n;n-=min(n,r%21-4);print b,t,1/b|b,t,"Take one down and patch it around\n",n,t

Try it online!

Jonathan Allan

Posted 2018-05-29T14:04:23.357

Reputation: 67 804

Turns out I don't need to create tuples at all. – Jonathan Allan – 2018-05-30T23:25:28.133

133 bytes – Jo King – 2018-06-01T07:59:52.713

@JoKing Thanks! (I really should've spotted that since it's more like what I do in my Jelly answer.) – Jonathan Allan – 2018-06-01T08:13:13.347

2@JoKing ...which means we can force quit with a division by zero error to save --two-- six more :) – Jonathan Allan – 2018-06-01T08:28:32.767

2

Perl, 132 bytes

$c=" bugs in the code
";for($i=99;$i>0;$i+=~~rand(21)-16){print$t.$/,($t=$i.$c)x2,"Take one down and patch it around
"}print"0$c
"x2

Trenton Trama

Posted 2018-05-29T14:04:23.357

Reputation: 121

2

VBA: 225 233 Bytes

Sub b()
For c = 99 To 0 Step -1
GoSub d
GoSub d
Debug.Print "Take one down and patch it around"
c = c + 5 - Int(rnd() * 20)
If c < 0 Then c = 0
GoSub d
Debug.Print
Next c
Exit Sub
d:
Debug.Print c & " bugs in the code"
Return
End Sub

{EDIT} Added the missing rnd()*

Notes:
Uses GoSub to print the triplicated line, because it's slightly shorter than assigning the line to a variable and Debug.Printing it.
Debug.Print without any arguments prints an empty line (no need for a Null or an empty string) A WorksheetFunction.Max line would be too long, so I used an "if less than" to prevent negatives.

 

With indentation and comments

Sub b()
    For c = 99 To 0 Step -1
        GoSub d '"# bugs in the code"
        GoSub d '"# bugs in the code"
        Debug.Print "Take one down and patch it around"
        c = c + 5 - Int(rnd() * 20)
        If c < 0 Then c = 0 'Non-negative
        GoSub d '"# bugs in the code"
        Debug.Print
    Next c
    Exit Sub
d: 'This is our GoSub bit
    Debug.Print c & " bugs in the code"
    Return
End Sub

Chronocidal

Posted 2018-05-29T14:04:23.357

Reputation: 571

1That's a very efficient way to do random numbers! – Sam Dean – 2018-05-31T13:40:46.780

@SamDean Not sure how I forgot to include the rnd() * in there - I think I was busy tallying up if it was less characters to Dim c% (i.e. "c is an Integer") and drop the Int() – Chronocidal – 2018-05-31T14:31:54.640

haha no worries! Nice to see a VBA answer as I haven't used it in years! – Sam Dean – 2018-05-31T14:50:17.227

2

Bash, 182 178 151 149 bytes

i=99;b=" bugs in the code";a(){ echo $i$b;};while((i>0));do a;a;echo Take one down and patch it around;i=$[i-$RANDOM%21+4];((i<0))&&i=0;a;echo;done;a

Try it online!

Ungolfed

i=99;                             # Var i as current number of bugs
b=" bugs in the code";            # b to shortcut our string

a() {                             # Define function 'a'
    echo $i$b;                    # to shortcut displaying or number of bugs
};

while((i>0)); do                  # Repeat as long as var i is greater than 0
    a;a                           # Execute 'a' twice
    echo Take one down and...     # Display some bugs taken down
    i=                            # Assign the following value to $i:
      $[i-$RANDOM%21+4]           # i minus a random value between -4 and 16
                                  #     $RANDOM is a bash builtin function to generate a
                                  #     pseudorandom value between 0 and 32767 inclusive.
                                  #     I have applied a modulo 21 to get 21 possible
                                  #     values. We take advantage of the allowed uneven
                                  #     distribution.

    ((i<0))                       # Perform the expression i < 0
           &&                     # and assign 0 to i only if the previous
             i=0                  # command completed successfully

    a                             # Execute 'a'
    echo                          # Display a blank line
done
a                                 # Execute 'a'

Thanks to muru and Sam Dean for their improvements, they saved me 31 bytes.

MC Emperor

Posted 2018-05-29T14:04:23.357

Reputation: 171

can't you remove the " -e" after the first echo? – Sam Dean – 2018-05-31T14:52:06.620

removed the " -e" and a whitespace "; i" Try it online!

– Sam Dean – 2018-05-31T14:53:35.083

You can replace if [[ $i -lt 0 ]];then i=0;fi with ((i<0))&&i=0, [[ $i -gt 0 ]] with ((i>0)), i=$((i-$RANDOM%21+4)) with i=$[i-RANDOM%21+4] to get 152 bytes

– muru – 2018-06-01T06:33:55.773

@muru Thanks, I'll add it. – MC Emperor – 2018-06-01T07:39:17.303

2

Ruby: 149 bytes

n=99;f=" bugs in the code\n";loop{puts"#{n}#{f}"*2+"Take one down and patch it around\n";(n+=rand -16..4)>0?puts("#{n}#{f}\n"):break};puts"0#{f}\n"*2

Should work in pretty much any version of Ruby >= 1.8

I think it might be possible to optimise the strings a bit more, but in general I'm pretty pleased with it - in particular the combo assignment/comparison/break statement and the abuse of optional brackets.

Note: the output technically has two trailing newlines; if that needs to be accounted for then it goes up by 4 characters.

DaveMongoose

Posted 2018-05-29T14:04:23.357

Reputation: 231

Hello, and welcome to PPCG! We do count trailing newlines, but if it works on Linux you can only count the \n (no \r). – NoOneIsHere – 2018-05-31T17:05:35.847

@NoOneIsHere Thanks :) I've updated my answer to clarify - I was referring to newlines on the output because the question specifies that having one is acceptable, but I wasn't sure about two. – DaveMongoose – 2018-06-01T08:37:01.713

I see. I think that's fine – NoOneIsHere – 2018-06-01T17:09:29.303

2

Zsh, 133 bytes

b="%d bugs in the code
";for ((n=99;n;)){printf $b$b"Take one down and patch it around
$b
" n n n-=RANDOM%21-4,n=n\>0\?n:0};printf $b

Try it online!


This takes advantage of a few zsh features.

  • the alternative loop form: while list; do list; done can be written as while list {list}
  • If a format specifier in printf is numeric, the corresponding argument is evaluated as an arithmetic expression. So:
    • we get the value of n for free without using a $
    • n -= RANDOM % 21 - 4, n = n > 0 ? n : 0 is again evaluated without having to use $((...)), $[...] or similar. The > and ? had to be escaped.
    • The printf $b at the end evaluates an empty argument as 0 for %d.
  • Word splitting on parameter expansion is off by default, so I do not have to quote $b anywhere.
    • This allows allows me to write $b$b"Take..." instead of "$b${b}Take...".

  • Saved a few bytes by using actual newlines instead of \n, and for((n=99;n;)) instead of n=99;while ((n)).

muru

Posted 2018-05-29T14:04:23.357

Reputation: 331

I think it should be -4. "-=" looks like its compound so it does the +4 first then subtracts it all. – Sam Dean – 2018-06-01T12:04:04.700

@SamDean oops, corrected. – muru – 2018-06-01T12:38:28.360

2

javascript: 142

i=99
t=` bugs in the code
`;s='';while(i){s+=i+t+i+t+`Take one down and patch it around
`;i+=4-Math.random()*20|0;i=i<0?0:i;s+=i+t+`
`}s+=i+t;

Try it online

Str34k

Posted 2018-05-29T14:04:23.357

Reputation: 21

2

C (GCC), 138 bytes

i=99;main(v){for(;i-v--;printf("%d bugs in the code\n%s",i*=i>0,v?v+1?i-=rand()%21-4,"\n":"Take one down and patch it around\n":""))v%=3;}

Note: I managed to get it down to 141 bytes by myself (no external help); later I saved three bytes by applying a technique that ErikF used (i*=i>0 instead of i=i<0?0:i). My original solo version:

i=99;main(v){for(;i-v--;printf("%d bugs in the code\n%s",i=i<0?0:i,v?v+1?i-=rand()%21-4,"\n":"Take one down and patch it around\n":""))v%=3;}

david.werecat

Posted 2018-05-29T14:04:23.357

Reputation: 41

Nice golf! Also, you should provide a way to test the code - for example, a link to https://tio.run

– None – 2018-11-09T20:19:23.330

2

Python 3, 187 bytes

from random import randint as r
p=print;b=99
def l(x): p(x if x > 0 else 0,"bugs in the code.")
while b > 0: l(b);l(b);p("Take one down and patch it around.");b+=r(-16,4);l(b);p("")
l(0)

So it turns out that dealing with IO/Random in Haskell is a nightmare, so changed the solution to Python. First attempt, not too great :( But at least it's working.

Kamil Jarosz

Posted 2018-05-29T14:04:23.357

Reputation: 121

2

Python 3, 199 191 171 bytes

-8 bytes thanks to @Stephen
-20 bytes thanks to @Jo King

import random
x=99
l="bugs in the code\n"
p=print
while x>0:p(f"{x} {l}"*2+"Take one down and patch it around");x=max(0,x+random.choice(range(-16,5)));p(f"{x} {l}")
p(0,l)

Try it online!

glietz

Posted 2018-05-29T14:04:23.357

Reputation: 101

191 bytes by putting the while body on one line and using import random and random.choice – Stephen – 2018-11-09T16:03:33.260

Assign print to a variable, join the prints, and actually moving the while loop to one line. 171 bytes

– Jo King – 2018-11-10T01:21:59.343

2

SAS 153 146 145 bytes

data;a=99;b='bugs in the code';do while(a>0);put a b/a b;put'Take one down and patch it around';a=max(a+int(ranuni(0)*20-16),0);put a b/;end;run;

The original version is Joe's answer, thanks him.

whymath

Posted 2018-05-29T14:04:23.357

Reputation: 21

3You have to specify the language and the length in bytes (since it is code golf). Also, you have to at least try to golf it, e.g. remove unnecessary spaces or newlines. – Bubbler – 2018-11-26T04:53:47.953

@Bubbler Sorry, it is just a variant version by Joe: SAS, 210 Bytes. And I will try to golf it only if I know better how to edit my answer. – whymath – 2018-11-26T05:15:11.607

@whymath Edit by pressing the edit button. Also, if this is a small improvement in another user's answer, submit it as a comment instead, which you can do after obtaining a small amount of reputation from upvotes. – lirtosiast – 2018-11-26T05:51:04.357

Thanks, @lirtosiast .kind of difficult cause I am not so good at this operation. By the way, why some answers' title also have a link? I mean, the name of the language. – whymath – 2018-11-26T10:25:14.007

@JonathanFrech okay, I already handled this. – whymath – 2018-11-26T10:30:27.723

1

Japt, 124 123 121 120 116 110 107 bytes

U=U||99P=` Þï  e ¬¸`OpU+POpU+P  Op`Take e ܵ, p®  ÂÐ` U=Mr0-15,5 +U-1U=Uc  (U>0 ?(OpU+P+R ,ßU  :Oo0+P

Try it online!

Logern

Posted 2018-05-29T14:04:23.357

Reputation: 845

I'm guessing I need some headers/footers for it to work in TIO? Try it online!

– Sam Dean – 2018-05-30T09:10:18.207

Fixed Try it online!

– Logern – 2018-05-30T12:54:41.927

@SamDean it looks like there are non-printing characters in the compressed string that aren't getting copied, it works in the TIO I posted. Here is the difference: https://www.diffchecker.com/MATxOdMv

– Logern – 2018-05-30T13:00:31.100

Strings looking good now! You do need to change that "," for " and" though! "Take one down and patch it around" – Sam Dean – 2018-05-31T08:28:14.983

Oh, didn't notice there was another Japt solution when I posted mine. Can see quite a few potential savings here but I'm on my phone so they'll have to wait 'til the morning. Welcome to PPCG, and Japt :) – Shaggy – 2018-05-31T22:56:39.447

1

Python 3, 144 bytes

from pylab import*
s='bugs in the code\n'
X=99
while X>0:i=randint(-16,5);print(X,s,X,s,'\ntake one down and patch it around',max(X+i,0),s);X+=i

user2699

Posted 2018-05-29T14:04:23.357

Reputation: 538

Formatting is incorrect - the leading spaces may be ok if you ask, but this misses some new lines and does not print the final extra "0 bugs in the code" as required. – Jonathan Allan – 2018-05-30T22:32:28.853

1

Red, 166 163 bytes

b: 99 forever[if b > 1[print[b t:{bugs in the code}s:"^/"b t
s{Take one down and patch it around}]if
0 > b: b + 4 - random 20[prin[0 t s s 0 t]break]print[b t s]]]

Try it online!

More readable:

b: 99
t: {bugs in the code}
s: "^/" 
forever [
    if b > 1 [
        print [ b t s b t s {Take one down and patch it around} ]
        if 0 > b: b + 4 - random 20 [
            prin [ 0 t s s 0 t ]
            break
        ]
        print [ b t s ]
    ]
]

Galen Ivanov

Posted 2018-05-29T14:04:23.357

Reputation: 13 815

1

.COM opcode, 137 bytes

0000h: BE 63 00 E8 3B 00 85 F6 75 01 C3 E8 33 00 B2 61
0010h: CD 21 0F C7 F0 F7 26 87 01 01 D6 83 EE 10 73 02
0020h: 31 F6 E8 1C 00 B2 5E CD 21 EB D8 99 F7 36 85 01
0030h: 85 C0 74 05 52 E8 F3 FF 5A B4 02 80 CA 30 CD 21
0040h: C3 89 F0 E8 E5 FF B4 09 BA 4D 01 EB F1 20 62 75
0050h: 67 73 20 69 6E 20 74 68 65 20 63 6F 64 65 0D 0A
0060h: 24 54 61 6B 65 20 6F 6E 65 20 64 6F 77 6E 20 61
0070h: 6E 64 20 70 61 74 63 68 20 69 74 20 61 72 6F 75
0080h: 6E 64 0D 0A 24 0A 00 15 00                     

        org 100h

        mov si, 99
lp:     call put2
        test si, si
        jnz @f
            ret
        @@:
        call put2
        mov dl, str2 - 256
        int 33
        rdrand ax
        ;mov ax, 65536*14/21+1
        mul [twentyone]
        add si, dx
        sub si, 16
        ;lea si, [esi+edx-16]
        jnc @f
            xor si, si
        @@:
        call put2
        mov dl, str2 - 256 - 3
        int 33
        jmp lp

put1:   cwd
        div [ten]
        test ax, ax
        jz @f
            push dx
            call put1
            pop dx
        @@:
        mov ah, 2
        or dl, 48
int33:  int 33
        ret

put2:   mov ax, si
        call put1
        mov ah, 9
        mov dx, str1
        jmp int33

str1:   db ' bugs in the code', 13, 10, '$'
str2:   db 'Take one down and patch it around', 13, 10, '$'
ten     dw 10
twentyone dw 21

l4m2

Posted 2018-05-29T14:04:23.357

Reputation: 5 985

p.s. with upper 60000+, if not consider it running up so high (in 250) can save some bytes – l4m2 – 2018-05-30T16:47:04.060

1

Japt -R, 83 79 75 73 bytes

Includes a trailing newline

#c
` Þï  e ¬¸
`
@§T}a@Np[UVUV`ìǦÓnÓlp®äNh
`qʸTwU±Gn#ö¹V]¬ÃpViT

Test it


Explanation

#c                                         :99
\n                                         :Assign to variable U
`...`                                      :The compressed string " bugs in the code\n"
\n                                         :Assign to variable V
        [UVUV                  V]          :Build an array with U as the 1st & 3rd elements,
                                           : V as the 2nd, 4th & 7th
                                           : and the following as the 5th & 6th:
             `...`                         :  The compressed string "Takeloneldownlandlpatchlitlaround\n"
                  qÊ                       :   Split on "l"
                    ¸                      :   Join with spaces
                      w       ¹            :  Maximum of
                     T                     :   0 and
                           #               :    21
                             ö             :    Random number in the range [0,21)
                          n                :    Subtract
                         G                 :    16
                       U±                  :    Add to U
                                 ¬         :Join to a string
      Np                                   :Push to N, initially an empty array
@  }a@                            Ã        :Repeat until
 §T                                        :  U is less than or equal to 0
                                   p       :Push
                                    ViT    :  V prepended with 0
                                           :Implicitly join with newlines and output

Shaggy

Posted 2018-05-29T14:04:23.357

Reputation: 24 623

1

Ruby, 128 bytes

N=99
def f;puts"#{N} bugs in the code"end
(f;f
puts"Take one down and patch it around"
N-=[N,15-rand(21)].min
f
puts)while 0<N
f

Try it online!

Reinstate Monica -- notmaynard

Posted 2018-05-29T14:04:23.357

Reputation: 1 053

1

C# (.NET Core), 175 bytes

var s="";var r=new Random();for(int p=99;p>0;){var d=" bugs in the code\n";s+=p+d+p+d+"Take one down and patch it around\n";p+=r.Next(-17,5);s+=(p>0?p:0)+d+"\n";}return s;

Try it online!

C# uses a class for randomizing. Without the "Random" object, the response would be around 148 bytes. Using a for loop instead of a while loop removes one byte. using "new Random.Next()" will not work, since creating multiple Random objects within a loop wont make the Randomizer actually random.

Qapples

Posted 2018-05-29T14:04:23.357

Reputation: 11

Welcome to PPCG. – Muhammad Salman – 2018-06-05T22:46:00.667

You need to add that final "0 bugs in the code" but nice answer! – Sam Dean – 2018-06-06T10:13:51.683

1

BLZ 2.6, 155 bytes

b=99
while b>0
n={text.newline}
s=" bugs in the code"+n
p=(x->print(99+s+99+s+"Take one down and patch it around"+n+b+s))
p()
b=b+random(-16,5)
end
b=0
p()

Reminds me that I need to make "\n" a newline so I can save some of those characters from {text.newline}

blazingkin

Posted 2018-05-29T14:04:23.357

Reputation: 111

anyway we can test that? also can you remove the space before "5" in the random function? – Sam Dean – 2018-06-06T10:15:50.933

1

@SamDean Good call on the space, down to 155 bytes. You can test it by installing blz if you want. There's a guide here https://github.com/blazingkin/blz-ospl/wiki/Installation You'd also have to checkout the v2.6 branch

– blazingkin – 2018-06-06T18:44:48.697

1

Clojure, 192 188 bytes

#(loop[b 99](def s"bugs in the code")(printf"%s %s\n%s %s\nTake one down and patch it around\n"b s b s)(def n(max(+ b(rand-int 21)-16)0))(println n s"\n")(if(= n 0)(println n s)(recur n)))

Try it online!

Explanation

#(loop [b 99] ; Initialize a loop with b=99
  (def s "bugs in the code") ; Define a variable s that equals "bugs in the code"
  (printf "%s %s\n%s %s\nTake one down and patch it around\n" b s b s) ; Prints 
    ;    "99 bugs in the code
    ;     99 bugs in the code
    ;     Take one down and patch it around" with the correct formatting.
  (def n (max (+ b (rand-int 21) -16) 0)) ; Let n = max(b+<some random number between -16 and 4 inclusive>, 0) This prevents negative numbers by replacing them with 0
  (println n s "\n") ; Prints "<n> bugs in the code" followed by an extra newline
  (if (= n 0) ; If n equals 0
    (println n s) ; Prints "<n> bugs in the code"
    (recur n))) ; Otherwise run the loop again with b=n

TheGreatGeek

Posted 2018-05-29T14:04:23.357

Reputation: 111

1

Dart, 173 169 bytes

import'dart:math';f({n=99,m=' bugs in the code\n'}){while(n>0){print('$n$m$n$m\Take one down and patch it around');n=n+Random().nextInt(20)-16;n=n<0?0:n;print('$n$m');}}

Try it online!

Almost competing with other Java-like languages for once

Elcan

Posted 2018-05-29T14:04:23.357

Reputation: 913