Thursday Code Puzzler: Investment Predictor
Thursday is code puzzler day here at DZone. The idea is simple: solve the coding problem as efficiently as you can, in any language or framework that you find suitable.
Note: Even though there really is nothing stopping you from finding a solution to this on the internet, try to keep honest, and come up with your own answer. It's all about the participation!
Do you have code puzzlers that you'd like to share with the DZone community? If so, please submit here.
Investment Predictor
With an initial investment of 1,000, and a daily increase of 1%, how long would it take for the initial amount to double?
Catch up on all our previous puzzlers here.






Comments
Vijay Nathani replied on Thu, 2012/11/22 - 4:46am
Groovy code that prints 70 as answer
Mihai Dinca - P... replied on Thu, 2012/11/22 - 7:01am
in response to:
Vijay Nathani
You should use Math.ceil instead of Math.round
Mark Howard replied on Thu, 2012/11/22 - 8:26am
I did it like so, in Java with a recursive static method:
public static void investmentPrediction(double balance, double percentage, int target, int weeks){ if(balance<target){ weeks++; balance = balance+(balance*(percentage/100)); investmentPrediction(balance, percentage, target, weeks); } else{ System.out.println("It will take "+weeks+" weeks to reach 2000"); } }Daniel Seidler replied on Thu, 2012/11/22 - 8:51am
Kotlin
val s = 1000.0 val e = s * 2 val inc = 1.0 //Log ceil(log(e/s) / log(1 + (inc / 100))) //Recursive fun interest(start: Double, i: Int = 0): Int { if(start >= e) return i else return interest(start + start * inc / 100, i + 1) } // Iterative fun interest(var start: Double, var days: Int = 0) : Int{ while (start < e) { days++ start += start * inc/100 } return days }Iterativ is the fastest Solution:
Verny Bonilla replied on Thu, 2012/11/22 - 10:10am
In Oracle / PL-SQL
DECLARE vInt NUMBER := .01; vMonto NUMBER := 1000; vResul NUMBER := vMonto; vDias NUMBER(3) := 1; BEGIN LOOP vResul := vResul + (vResul * vInt); EXIT WHEN vResul > (vMonto * 2); vDias := vDias + 1; END LOOP; DBMS_OUTPUT.PUT_LINE(vDias || ' Días'); END;Vijay Nathani replied on Thu, 2012/11/22 - 10:27am
Iterative will always be faster than recursive.
Log is slow in Java because multiple mathematical need to be performed. Accelerated Math libraries are available in C++ for Intel and AMD processor that ask the processor to compute log to the base 2 in a single instruction. Unfortunately Java 7 does not use this optimization. So Log is slower than iterative calculation.
If later versions of Java optimize calculation of log by asking microprocessor to perform the same, then log may be faster than iterative. Obviously this optimization is not a high priority for Oracle.
Vijay Nathani replied on Thu, 2012/11/22 - 2:45pm
in response to:
Vijay Nathani
using System; namespace LearnCS { internal class Compute { private const double RateOfInterest = 1.0, TimesAmount = 2.0; private static void Run(string message, Func<long> task) { var start = DateTime.Now; for (int i=1; i< 10000; ++i) task(); //delay var returnValue = task(); var timeTaken = (DateTime.Now.Ticks - start.Ticks); // 1 nano second = 100 ticks Console.WriteLine("{0} returned {1} and took {2} ticks", message, returnValue, timeTaken); } private long LogCompute() { return (long) Math.Ceiling(Math.Log(TimesAmount, 1 + RateOfInterest/100)); } private long ItrativeCompute() { long days = 0; for (var start = 1.0; start < TimesAmount; days++) start += start*RateOfInterest/100; return days; } public void Main1() { //Warm-up LogCompute(); ItrativeCompute(); Run("Start of Test", () => 0 ); //Actual run Run("Log", LogCompute); Run("Iterative", ItrativeCompute); } } } /* * The ouput of the code was Start of Test returned 0 and took 19531 ticks Log returned 70 and took 9765 ticks Iterative returned 70 and took 78125 ticks * So apparently, log is faster in C# than in Java because C# uses processor to compute the log function, * while Java apparently does not use this optimization. This also seems logical because Java is popular * on server, where the need to use log function is minimal. C# is very popular for desktop applications, * where log function is probably needed. */Boyko Bantchev replied on Wed, 2012/11/28 - 10:11am
In J:
>.1.01^.2
Apperson Johnson replied on Wed, 2012/11/28 - 11:00am
http://www.google.com/#hl=en&q=(ln+2)%2F(ln+1.01)
Mike Lynch replied on Wed, 2012/11/28 - 12:01pm
in response to:
Daniel Seidler
Is anyone else suprised that a one liner is slower then a function! Great info!
Rohit Rai replied on Wed, 2012/11/28 - 2:47pm
Scala
Boyko Bantchev replied on Wed, 2012/11/28 - 4:01pm
in response to:
Mike Lynch
The problem statement says nothing about program speed — it says 'solve the coding problem as efficiently as you can'. Picking a proper language for the problem, and then making 10 keystrokes (including the carriage return) to obtain the solution seems like an efficient problem solving to me. Especially when compared to writing several tens of li[n]es in some other language :)
Manoj Balu replied on Thu, 2012/11/29 - 12:45am
runtime
20140 nanosecondsebenezer raj replied on Fri, 2012/11/30 - 10:27am
Using q
{ceiling(log y%x)%log 1+z%1e2}[1000;2000;1]
prints 70
Andrius S. replied on Thu, 2012/12/06 - 8:23am
I just devide 70 by percentage and get in how many time it would double. Say, with 1%, 70/1=70 would double in 70 days.
Ed Griebel replied on Wed, 2012/12/12 - 10:11am
Here are two basic Clojure (Java-based Lisp variant) versions. The first is easier to understand but could lead to a stack overflow for large values of to because it doesn't use the recur primitive that simulates tail recursion.
(defn calc_v1 ([amt to] (if (>= amt to) 0 (inc (calc_v1 (* amt 1.01) to)) ) ) )The recur in this version will recursively call calc but not add each individual frame to the call stack.
(defn calc_v2 ([amt to] (calc_v2 amt to 0)) ([amt to i] (if(>= amt to) i (recur (* amt 1.01) to (inc i)) ) ) )To run either one, call like this: (calc 1000 2000)