[Question]
  [
# 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](https://www.reddit.com/r/ProgrammerHumor/comments/8l68th/this_really_how_it_be_tho/?ref=share&ref_source=link).
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](https://codegolf.meta.stackexchange.com/questions/4780/should-submissions-be-allowed-to-exit-with-an-error/4781#4781) 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](https://pastebin.com/Ba4Q8x4Y)
  
[Answer]
# [R](https://www.r-project.org/), ~~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!](https://tio.run/##FY1BDsIgEADvvmLlBHFJrImHxvYlxsMWiBDtQgpN/T3CeSYzW608j@Pj8OHrJCtDRTIukxaw7O8MgaF4ByZadxLYCIpCHweRHdh4MBBbSFSMh1CAtriz7eKkV/rJK7LOtKaWvg04qMtd9UITTL@o55lfmF2ahVC1/gE "R – 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!*
[Answer]
# 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.](https://tio.run/##LVDBTsMwDL3zFVZPCaVVQVxGyPiC7QLiAhy8JFuztUmVOEVo6reXVKvkd7D99PyezzhiddaXWXUYI@zQuusdgHVkwhGVgf3SArxTsO4Ein16q2HkIk@njFyRkKyCPTiQMI/V9rqSoyyKB5IFHNIpZkmg1oDy2ny7Qhx9YPkKWLnZCLttRCylLalcUHzgxYB3BrT/dYBOw4CkWrAEGHxyOiuUjNlK7pDaOmSG7xm/f3qsnvlr89a8WL7oZBoXwVAKDmLZlCSmWdxcD@nQZder@XFJ1efw7Ob96weQr8n/Ipm@9onqIa@IuVoxl7qOr0@Y5n8)
**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
```
[Answer]
# [PowerShell](https://github.com/TryItOnline/TioSetup/wiki/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!](https://tio.run/##HczRCoIwFIDhVzmMgVkpFhHI2EtED9DRzRTXOTInXpjPvkb3//9NvFo/99a5GGWjM2iW9wwDQegttGxspjr2B4m6rpXEfDsLibIRx6sSTxwtMFkwvBIgGZgwtD0MAdDzQkak46SLy70sb99HCvijhi5hhQtVviW02v/ci8QuqsTG@AM "PowerShell – 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.*
[Answer]
# [JavaScript (Node.js)](https://nodejs.org), 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!](https://tio.run/##FcwxEoIwEEDRnlNsmRhhgjMWMAZOYOcBEkOAVcwysGjj3SPW/81/uLdb/YIz55G6kFJvBJqqOrKxcN@GFTACjwH8XjMrTYONblGxsjf3DEAxQEefCC52MDv2IyCDW2iLXWaVEKiM/l4dj8WyE3oJeTiVeXmWF93qGuX/tMNeoKy14uQprjSFYqJB9ELK9AM "JavaScript (Node.js) – 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.
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E), 59 bytes
```
99[Ð16(4ŸΩ+¾‚{θ©3F“ÿ±À€†€€ƒË“Š}“ƒ¶€µ„‹€ƒš¡€•…¡“ªsõ®>#®]sDŠ»
```
[Try it online!](https://tio.run/##MzBNTDJM/f/f0jL68ARDMw2TozvOrdQ@tO9Rw6zqczsOrTR2e9Qw5/D@QxsPNzxqWvOoYQGIbFpzbNLhbqDE0QW1QPLYpEPbgGKHtj5qmPeoYSdY@ujCQwvBGhY9algGZDbMObSq@PDWQ@vslA@tiy12Obrg0O7//wE "05AB1E – Try It Online")
[Answer]
# [Python 3](https://docs.python.org/3/), ~~156~~ 138 bytes
Thanks to [Jonathan's Python 2 answer](https://codegolf.stackexchange.com/a/165781/76162) 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!](https://tio.run/##JcyxDsIgGEXhvU/xLwQQO1hd2oa3cHTBQoSoF4I0rX151Lid5TvpXXzEsdasofu@2TRnlq7z7UUBVLyjKVp3AW8WHx6OMKwaY1Y6WJHliFY/AwT2mXWH9iTHlAOKEBtb5a5T/GzujiIc2biADCwlUyZPoZDJcYb9ntXGIJs//GWtHw "Python 3 – 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
```
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 81 bytes
```
≔⁹⁹θ≔”⧴"pWº⁴tＳn/{yBⅈ⁺”ζＷ›θ⁰«×²﹪ζθ”↶0⪫\`3+¤⸿Zν(z¬hＬÀＴj'ZXεＰraF”≧⁺⁻⁴‽²¹θ﹪ζ×θ›θ⁰¶»﹪ζ⁰
```
[Try it online!](https://tio.run/##XY67agMxEEXr7FdcFgIjUMAxaYwrV6kMxrhMo6zESkQe2XrY4JBvV2R2IY9ymHvuPYNVcQjK17pJyY1Mq5XEWay7@ewfNd7LmOAY2RoMQZs37iVuLXO1zhvQazQqm0hniYUQ@OwedtFxpoM7mkRLiW3QxQe63ZtF4@Z/f1AfBoENdLgyFGucVB4sXIaKobBuS/f4Vp0mnb0bbaadL6mVOi6JXiT2DQxHWj4LManP9T@rk0jT@2v6W2Va@ur@oy22rrU@Xfw3 "Charcoal – Try It Online") Link is to verbose version of code. Explanation:
```
≔⁹⁹θ
```
Start with 99 bugs in the code.
```
≔”⧴"pWº⁴tＳn/{yBⅈ⁺”ζ
```
Save the compressed string "%d bugs in the code\n".
```
Ｗ›θ⁰«
```
Repeat while there are a positive number of bugs remaining.
```
×²﹪ζθ
```
Print the number of bugs in the code twice.
```
”↶0⪫\`3+¤⸿Zν(z¬hＬÀＴj'ZXεＰraF”
```
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.
[Answer]
# 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!](https://tio.run/##FY1BDoIwEEX3nGLCqiPSiIkLJNUTuPMAjKVAlbYEijYxnr3C4u3@@@9Jb5rlpEefW9eoGFvBgihLFJevFNLZ2Q2KD66rjLiR7ysSNTyWbgZtwfcK5GoldSVZyCjbSO/0UuCsgsZ9LJBtYCQve9AeaHKLbdJsTRhuKKyS4VLpgRk@rUtnGO6ORV6ccH9AzAiTcG1ZwLNkdVJv//iLLcP4Bw "JavaScript (Node.js) – Try It Online")
Thanks for [Muhammad Salman](https://codegolf.stackexchange.com/users/79762/muhammad-salman) for the missing `console.log` replacement, and for [Oliver](https://codegolf.stackexchange.com/users/61613/oliver) for the x test improvement
Thanks for [l4m2](https://codegolf.stackexchange.com/users/76323/l4m2) for golfing this by 8 bytes
[Answer]
# COBOL (GnuCOBOL), ~~317~~ ~~294~~ ~~279~~ ~~270~~ ~~269~~ ~~249~~ ~~248~~ 247 bytes
### Using `go to` statements: 247 bytes
```
data division.working-storage section. 1 i pic S99 value 99.procedure division.a.perform b 2 times display"Take one down and patch it around"compute i=4+i- random*21 set i to max(0,i)perform b display""if i>0 go to a.b.display i" bugs in the code"
```
[Try it online!](https://tio.run/##RY4xbsMwDEX3nOLDU5vWQhJ08ZAA3bO1F6AlWiFiiYYkJ@3l68pAiywEgff5@K32OrY@zsv2tBHHscgglopohJOb5LqYKalPFFpxhsziqNCD3TVdJfo2F03kGZntemywh2ASi4@uw43GmdF1q8mymxM/BGQmToOmgB4HFAmcK8zTSN/NJ10ZGmta7xEUHSYq9gIpoKRzdI3VMM2FIce3F2mRakbD9rCvPUotUBSBvp52r/L8@PJvb2SAnHbwuubI9OaPQBr0s8@QiHJhWHXcLGaz/NhhJJ@XdkjMdUosSWIWm4/v5/Mv)
**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
a.                                 <-- Define label a, to jump to
    perform b 2 times              <-- Execute the procedure called 'b'
                                       twice, see below
    display "Take one down and..." <-- Display this sentence
    compute i =
        4 + i - (random * 21)      <-- Subtract from i some random value
    set i to max(0,i)              <-- If i is negative, then assign 0 to i
    perform b                      <-- Execute the procedure 'b'
    display ""                     <-- Display an empty string; needed
                                       because of the blank line
    if i > 0                       <-- If i is still greater than 0, then
                                       we're not done yet
        go to a.                   <-- and we'll jump back to 'a'
b.                                 <-- Define procedure called 'b'.
    display i " bugs in the code"  <-- Display the value of i and then the
                                       given string literal
```
### Using the `perform` statement as loop control: 269 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=4+i-(random*21)if i<0 compute i=0 end-if perform a display""end-perform.a.display i" bugs in the code"
```
[Try it online!](https://tio.run/##TY/NasNADITveYrBpzZljRN6MTSB3nNrX0DZlR0Re2X2J6EvX3cNCe5FiJnRN8jqWQfT@zxvjxtx7JN0YimJeji5SSxLPQXtA41GXE317CjR6t01XMX3JiYN1DMi2@W4xg6CSSy@2hY3GjKjbReSZZcD/4Nz6DSMyKV6gBwaPBXCHklGjiUcp4F@qm@6MtSXa717kHeYKNkLJIGCZu8qq@OUExfO@5uYl1AyOm73u1fpIB8NVr8Be2eKvNY9a6rFecjl44cMqXDOfYR4pAsXlONqrjfzr@0G6uNsusBcpvgUxEex8fB5Ov0B)
**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..." <-- Display this sentence
    compute i =
        4 + i - (random * 21)      <-- Subtract from i some random value
    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`.
---
* Thanks to tail spark rabbit ear, 1 byte has been saved by using the intrinsic function `max` instead of an `if` statement.
* Thanks to tail spark rabbit ear, 1 byte has been saved by replacing the `compute` by the `set` statement.
* Thanks to raznagul, 1 byte has been saved by rewriting the formula for the new number of bugs.
---
*PS: The numbers are not exactly displayed as required, but COBOL is not that good at auto-converting numbers to a pretty textual representation.*
[Answer]
# [Python 2](https://docs.python.org/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!](https://tio.run/##PYzBCsIwEETv@Yq9tdUVVESopX/h0Utsotlod0OaUv36mF48DMPAvBe@yQkfc35EGSFqNqVoDBLTRhFOfdtidZ@fExBDchYGMfbGlVocvS3Qxfej/tR7pO0KE6d6dzjjqWm6EMuC4sA11VW/LAhbMLIwlC8EnQYHlEBHmdkUK3qcOuq9@rM5/wA "Python 2 – Try It Online")
[Answer]
# [Octave](https://www.gnu.org/software/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!](https://tio.run/##NcyxDsIgEIDh3ae4xcBpNcXFNEriQ7ipAwK1F/UgLVXeHtvB5Z@@/MEm8/GlZN00Bxdk1CdJGHvi1Eqx3LZwHx8DEEPqPNjg/JVFRYgy4yLOcTREKc7m6SGwBxe@DIYdRJNsB5TA9GFkJ2b@Nlle6iqv9U6t@klt1P6G/4fAkRO9IB/VZGss5Qc "Octave – 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!](https://tio.run/##NYy7DsIwDAB3vsILis1DallQBUF8BCNLSAK1ipwoTSF/H9qB5ZY7XbDZfHytRXfdyQWM@opMMbHkJ6o1w2N6jcACufdgg/N3UTsmwkKruMDxGFHdzOAhiAcXvgJGHESTbQ@cwaQwiVNLjmWr0ywZDy3t2yNtsFwa@k8UTZL5DeXcznFDtf4A "Octave – Try It Online")
[Answer]
# 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](https://codegolf.stackexchange.com/q/5175/69061)  
 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](https://codegolf.stackexchange.com/users/79060/erikf).
---
```
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](https://tio.run "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).*
[Answer]
# [LaTeX](https://www.latex-project.org/), ~~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.
[Answer]
# 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!](https://tio.run/##NY3BDoIwEETvfMWmCUmrmJSDB6zoT3jkUtsCW@PW0BoPhG9HxDDJbuZtZjPm0Bkzz7tYM7i/uwhIkHoHJljHVMux8GJsw8CxriqFF6mw9uI1IKWWs9zmsaH/vumHg0AObPgQaLLw0sn0gAn0EN5kt2BDrMAirsN9jfthCXORl9WhPIqzvMqTL6JQW4nMI/vxNC8MT43ERTZmsCiurwmfjksh1Hpr@WKm@Qs)
[Answer]
## 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).
[Answer]
## 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
";
```
[Answer]
## [ABAP](https://en.wikipedia.org/wiki/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!*
[Answer]
# [Clean](https://github.com/Ourous/curated-clean-linux), ~~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!](https://tio.run/##NY5PS8NAEMXvfoohp4RNSvQgVBJPeigoiImntMhkd/MHs7MlmcQW/OyumxYvj/cG5r2fHDSSM1bNgwaDPbneHO3IULB6piV@Re4270jKmrg4T6zNpuyN/vefHzRho@NSn/imqSheHoZD/UOPaU6ZqDOxqghK/NJgSYOy3wS@DY7IsoOeAUc7k9pTkAmDJ0iXy4PPoqkuZXnqL65g9FA5NOEkkUIRbbcVwagN3KXJ7f1@T1nSalpJd8Qh21VRyisfsGeOokMUQD23E/QE3GmQVmm/5H5lM2A7uWT34p7OhKaX1/A2IDd2NC6p/wA)
[Answer]
# C#, ~~184~~ 181 bytes
My first Code Golf answer!
(Based on [Java answer](https://codegolf.stackexchange.com/a/165633/80847) 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!](https://tio.run/##LY9BT8MwDIXP7a@wekpUVhXEZWQZByRODCGGxGFwCGloLTYHxS4DTfvtpaNY8uGTnp/f8zzzMYWhZ6QW1j8sYWcmWNkJq5WTzuR@65jhIcU2uR0c8ozFCfo8G2578ou1pPFo6a3SdnmYCNgWxZnYAt76lgEJpAvgYxNeqDDvMSkkAbTzucFlbbi0WEp52uLJfQSIFKCJewJHDXw68R2ggEuxp2Z0KJXCmaWwh8dREHdKV/fhW9TFuZ5d6kV9XV@hPpmNWm1SkD4RcFmXYo5mgP@ZasBXxAZWDknxX/bN6/ioZT02zbPsJhLHbaieE0q4QwrKK61Nnh3z4/AL "C# (.NET Core) – Try It Online")
[Answer]
# [Python 2](https://docs.python.org/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!](https://tio.run/##FcxBC8IgGAbg@37FhxBs5AhHlyX@i45ddEpK9SruGyPov1udnttT3hwzptaqgZnnjo1w232lBOIYaMk@3CC6PaZnIHWpR5N8XwftDDRG80roIethUuN50KUmMDnJUp3c56@42kegjEA@7yALT8XyEikx2Zo3@N8uIbm1Lw "Python 2 – Try It Online")**
[Answer]
# [C (gcc)](https://gcc.gnu.org/), 141 137 bytes
I used preprocessor macros [for great justice (warning: TV Tropes)](http://tvtropes.org/pmwiki/pmwiki.php/Main/ForGreatJustice)
```
#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!](https://tio.run/##VY7BisJAEETv@YrGIHS7UdSDIDF@gexJb0IYp2dMo/ZIMtk9iN8eR2@eCh5FvbLTs7VDLmqvPTvYdJElzJpt9oWucvpmUW4ukSFn50Ud1Gjo3opGj6Mxw6k/dyAKsXFgA7ujjnJTCGUehR4@tCjVel3WSIWU8lO1RhlpvFxMF6tCJpVs50WNRyWqcW8uDkJycPhXSEW4m2gbkAimDb1yqpXPIbnhZkTxLwgTPDKA7jP7voq/h92OqEzQY4rn8AI "C (gcc) – Try It Online")
[Answer]
# 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`.
[Answer]
# 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())
```
[Answer]
# [QB64](https://www.qb64.org/), 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$
```
[Answer]
# [Pyth](https://github.com/isaacg1/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](https://pyth.herokuapp.com/?code=J99WJ%25jb%5BK%22%25d+bugs+in+the+code%22K%22Take+one+down+and+patch+it+around%22Kk%29%5BJJ%3DJeS%2CZ%2BJ-O21+16%3B%25KZ&debug=0)
---
*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
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 61 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page)
```
;“,Ȥm46Ṛṛ⁽eɼḞF»
ÇȮ“"ḃḲɠ⁼ċTṪʠ/Ạ⁺ṗḍ^ẸƘⱮṖ8»20X+_«¥©17Ç⁷®ßÇ®?
99Ç
```
A niladic link which also works as a full program.
**[Try it online!](https://tio.run/##AX0Agv9qZWxsef//O@KAnCzIpG00NuG5muG5m@KBvWXJvOG4nkbCuwrDh8iu4oCcIuG4g@G4ssmg4oG8xItU4bmqyqAv4bqg4oG64bmX4biNXuG6uMaY4rGu4bmWOMK7MjBYK1/Cq8KlwqkxN8OH4oG3wq7Dn8OHwq4/Cjk5w4f//w "Jelly – 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
```
[Answer]
# 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
```
[Answer]
## 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.Print`ing 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
```
[Answer]
# 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.
[Answer]
# [Zsh](https://www.zsh.org/), 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!](https://tio.run/##PcxBC4IwGAbg@37Fy1BQSLDoYmNF0LWC6Ohlc9NJ8E3mJCj67Ysu8dyf1@xS0pLnBnoZZoyE6Cw6byzjovcBRUGyaQSJsnxPYaTYI9OZ5nf1sPBkYfyToMhgUrFzGCNU8AsZlmnGQT@VvB0vp@s536yr7Yoktfu6PdCu/oh/mdIX "Zsh – Try It Online")
---
This takes advantage of a few zsh features.
* the [alternative loop form](http://zsh.sourceforge.net/Doc/Release/Shell-Grammar.html#Alternate-Forms-For-Complex-Commands): `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))`.
]