Here is O(log(n)) solution using Kotlin. We use the arithmetic progression formula to calculate the sum from 1 to n without a loop with O(1) complexity. And after we use the binary search to find the number of iterations needed with O(log(n)) complexity. This will work for very large values of n, although I do not think anybody will have such a big number of beers on the wall:)
Result for n=Long.MAX_VALUE=9223372036854775807 is (4294967296, 2147483647).
importjava.math.BigInteger/** * @param n initial number of beers on the wall * @return Pair(number of iterations needed to remove all the bottles, number of bottles removed in the last iteration) */funbottlesOfBeer(n:BigInteger):Pair<BigInteger,BigInteger>{require(n>=BigInteger.ZERO)if(n==BigInteger.ZERO)returnPair(BigInteger.ZERO,BigInteger.ZERO);if(n==BigInteger.ONE)returnPair(BigInteger.ONE,BigInteger.ONE);valnumberOfIterations=findIndex(n);valsum=sumFromOneTo(numberOfIterations);returnif(sum!=n){Pair(numberOfIterations.inc(),n-sum);}else{Pair(numberOfIterations,n-sumFromOneTo(numberOfIterations.dec()))}}/** * Calculate the sum using arithmetic progression formula (a1=1, d=1) with O(1) complexity * @param n positive number * @return sum of all numbers from 1 to n inclusive (1+2+...+(n-1)+n) */funsumFromOneTo(n:BigInteger):BigInteger{require(n>=BigInteger.ONE);returnn*(n+BigInteger.ONE)/(2.toBigInteger());}/** * @param n positive number * @return i: (sumFromOneTo(i) <= n) and (sumFromOneTo(i + 1) > n) */privatefunfindIndex(n:BigInteger):BigInteger{require(n>=BigInteger.ONE);returnbinarySearchIndex(BigInteger.ONE,n,n);}privatefuncheckIndex(i:BigInteger,n:BigInteger):Boolean{require(i>=BigInteger.ONE);require(n>=BigInteger.ONE);return(sumFromOneTo(i)<=n)&&(sumFromOneTo(i.inc())>n);}/** * @param start start of the search interval * @param end end of the search interval * @param n positive number * @return i: (sumFromOneTo(i) <= n) and (sumFromOneTo(i + 1) > n) and (start <= i <= end) */privatefunbinarySearchIndex(start:BigInteger,end:BigInteger,n:BigInteger):BigInteger{require(start>=BigInteger.ONE);require(start<=end);require(n>=BigInteger.ONE);if(checkIndex(start,n))returnstart;if(checkIndex(end,n))returnend;require(start!=end){"Index does not exist"};valmid=(start+end)/2.toBigInteger();valsumToMid=sumFromOneTo(mid);returnif(sumToMid>n){binarySearchIndex(start,mid,n);}else{binarySearchIndex(mid,end,n);}}
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Here is O(log(n)) solution using Kotlin. We use the arithmetic progression formula to calculate the sum from 1 to n without a loop with O(1) complexity. And after we use the binary search to find the number of iterations needed with O(log(n)) complexity. This will work for very large values of n, although I do not think anybody will have such a big number of beers on the wall:)
Result for n=Long.MAX_VALUE=9223372036854775807 is (4294967296, 2147483647).