Despite you only appending to a single StringBuilder, internally a new array will be allocated with larger capacity on the heap when current capacity is reached. Note how error message indicates call to Arrays.copyOf:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:3332)
at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:124)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:448)
There are two possible issues with your code. One is already explained by texasbruce regarding missing recursion exit point. The other might be regarding behaviour of count variable. Try initialising it to equal start value and then decrement it
val start = 100
var count = start
...
count -= 1
instead of incrementing it
var count = 0
...
count += 1
In fact we can drop count variable all-together. Try the following example
object Example extends App {
val song = StringBuilder.newBuilder
def recite(start : Int, end : Int): String = {
start match {
case 1 => song.append(s"$start bottles of beer on the wall, $start bottles of beer.\nTake one down and pass it around, no more bottles of beer on the wall.\n")
case 0 => song.append("No more bottles of beer on the wall, no more bottles of beer. Go to the store and buy some more, 99 bottles of beer on the wall.")
case _ => song.append(s"$start bottles of beer on the wall, $start bottles of beer.\nTake one down and pass it around, ${start.toInt - 1} bottles of beer on the wall.\n")
}
if (start == end) {
song.toString()
}
else recite(start - 1, end)
}
println(recite(100, 0))
}
which outputs
100 bottles of beer on the wall, 100 bottles of beer.
Take one down and pass it around, 99 bottles of beer on the wall.
99 bottles of beer on the wall, 99 bottles of beer.
Take one down and pass it around, 98 bottles of beer on the wall.
98 bottles of beer on the wall, 98 bottles of beer.
...
3 bottles of beer on the wall, 3 bottles of beer.
Take one down and pass it around, 2 bottles of beer on the wall.
2 bottles of beer on the wall, 2 bottles of beer.
Take one down and pass it around, 1 bottles of beer on the wall.
1 bottles of beer on the wall, 1 bottles of beer.
Take one down and pass it around, no more bottles of beer on the wall.
No more bottles of beer on the wall, no more bottles of beer. Go to the store and buy some more, 99 bottles of beer on the wall.
Note how we used start == end as exit condition.
recite()method has no exit. There's no way for it to terminate.startandendvalue to terminate the recursive logic.reciteand with what values forstartandend?