Here below a little program in Kotlin that implements 2 classes (+ an extra utility Stopwatch class from my previous post http://carlosqt.blogspot.com/2011/05/stopwatch-class-for-java.html). There is the main class, called Fiborial (Fibo(nnacci)+(Facto)rial) that implements the Fibonacci and the Factorial algorithms in two ways, one Recursive (using recursion) and the other Imperative (using loops and states). The second class is just an instance class that does the same thing, but its there just to show the difference between static and instance classes, and finally the third one is the main function which has the execution entry point.
You can also find 3 more little examples at the bottom. One prints out the Factorial's Series and Fibonacci's Series, the second one just shows a class that mixes both: static and instance members (or 2 separate classes in the case of Kotlin since it does not supports staitc methods in a class), and finally the third one that uses different return types (including java.math.BigInteger) for the Factorial method to compare the timing and result.
As with the previous posts, you can copy and paste the code below in your favorite IDE/Editor and start playing and learning with it. This little "working" program will teach you some more basics of the Programming Language.
There are some "comments" on the code added just to tell you what are or how are some features called. In case you want to review the theory, you can read my previous post, where I give a definition of each of the concepts mentioned on the code. You can find it here: http://carlosqt.blogspot.com/2011/01/new-series-factorial-and-fibonacci.html
The Fiborial Program
// Factorial and Fibonacci in Kotlin package com.series import java.math.BigInteger import com.series.Stopwatch // Instance (Singleton) Class that works as a Module/Utils class // static is not a class modifier in Kotlin object StaticFiborial { // 'Static' Field private var className : String = "'Static' Constructor" // no available static __constructor support // Static Initializer Method instead, but need to be explicitly invoked fun constructor() { className = "'Static' Constructor"; println(className) } // 'Static' Method - Factorial Recursive fun factorialR(n : Int) : BigInteger? { if (n == 1) return BigInteger.ONE else return BigInteger.valueOf(n.toLong())?.multiply(factorialR(n - 1)) } // 'Static' Method - Factorial Imperative fun factorialI(var n : Int) : BigInteger? { var res: BigInteger? = BigInteger.ONE while (n > 1) { res = res?.multiply(BigInteger.valueOf(n.toLong())) n -= 1 } return res } // 'Static' Method - Fibonacci Recursive fun fibonacciR(n : Int) : Long { if (n < 2) return 1 else return fibonacciR(n - 1) + fibonacciR(n - 2) } // 'Static' Method - Fibonacci Imperative fun fibonacciI(n : Int) : Long { var pre : Long = 1 var cur : Long = 1 var tmp : Long for (i in 2..n) { tmp = cur + pre pre = cur cur = tmp } return cur } // 'Static' Method - Benchmarking Algorithms fun benchmarkAlgorithm(algorithm : Int, values : Array<Int>) { val timer : Stopwatch = Stopwatch() var testValue : Int var i : Int = 1 var facTimeResult : BigInteger? = BigInteger.ZERO var fibTimeResult : Long when (algorithm) { 1 -> { println("\nFactorial Imperative:"); // "For" Loop Statement for (j in 1..values.size - 1) { testValue = values[j] // Taking Time timer.start() facTimeResult = factorialI(testValue) timer.stop() // Getting Time println(" (${testValue}) = ${timer.getElapsed()}") } } 2 -> { println("\nFactorial Recursive:") // "While" Loop Statement while (i < values.size) { testValue = values[i] // Taking Time timer.start() facTimeResult = factorialR(testValue) timer.stop() // Getting Time println(" (${testValue}) = ${timer.getElapsed()}") i += 1 } } 3 -> { println("\nFibonacci Imperative:") // "Do-While" Loop Statement do { testValue = values[i] // Taking Time timer.start() fibTimeResult = fibonacciI(testValue) timer.stop() // Getting Time println(" (${testValue}) = ${timer.getElapsed()}") i++ } while (i < values.size) } 4 -> { println("\nFibonacci Recursive:") // "For Each" Loop Statement for (j in values) { testValue = j // Taking Time timer.start() fibTimeResult = fibonacciR(testValue) timer.stop() // Getting Time println(" (${testValue}) = ${timer.getElapsed()}") } } else -> println("DONG!") } } } // Instance Class // Instance Field class InstanceFiborial(private var className : String) { // Instance Constructor this() : this("Instance Constructor") { println(this.className) } // Instance Method - Factorial Recursive fun factorialR(n : Int) : BigInteger? { // Calling Static Method return StaticFiborial.factorialR(n) } // Instance Method - Factorial Imperative fun factorialI(n : Int) : BigInteger? { // Calling Static Method return StaticFiborial.factorialI(n) } // Instance Method - Fibonacci Recursive fun fibonacciR(n : Int) : Long { // Calling Static Method return StaticFiborial.fibonacciR(n) } // Instance Method - Fibonacci Imperative fun fibonacciI(n : Int) : Long { // Calling Static Method return StaticFiborial.fibonacciI(n) } } fun main(args: Array<String>) { println("\n'Static' Class"); // Calling 'Static' Class and Methods // No instantiation needed. Calling method directly from the class StaticFiborial.constructor() println("FacImp(5) = ${StaticFiborial.factorialI(5)}") println("FacRec(5) = ${StaticFiborial.factorialR(5)}") println("FibImp(11)= ${StaticFiborial.fibonacciI(11)}") println("FibRec(11)= ${StaticFiborial.fibonacciR(11)}") println("\nInstance Class"); // Calling Instance Class and Methods // Need to instantiate before using. Call method from instantiated object val ff = InstanceFiborial() println("FacImp(5) = ${ff.factorialI(5)}") println("FacRec(5) = ${ff.factorialR(5)}") println("FibImp(11)= ${ff.fibonacciI(11)}") println("FibRec(11)= ${ff.fibonacciR(11)}") // Create a (generic) list of integer values to test // From 5 to 50 by 5 val values = Array<Int>(11, {i -> i * 5}) // Benchmarking Fibonacci // 1 = Factorial Imperative StaticFiborial.benchmarkAlgorithm(1, values) // 2 = Factorial Recursive StaticFiborial.benchmarkAlgorithm(2, values) // Benchmarking Factorial // 3 = Fibonacci Imperative StaticFiborial.benchmarkAlgorithm(3, values) // 4 = Fibonacci Recursive StaticFiborial.benchmarkAlgorithm(4, values) // Stop and exit println("Press any key to exit...") //val ins: Scanner = Scanner(System.in) //var line: String? = ins.nextLine() //ins.close() }
And the Output is:
Printing the Factorial and Fibonacci Series
package com.series import java.math.BigInteger import java.lang.StringBuffer object Fiborial { // Using a StringBuffer as a list of string elements fun getFactorialSeries(n : Int) : String? { val series = StringBuffer() // We begin by concatenating the number you want to calculate // in the following format: "!# =" series.append("!") series.append(n) series.append(" = ") // We iterate backwards through the elements of the series // Reversed ranges are not supported... using while instead //for (i in n..0) { var i : Int = n while (i > 0) { // and append it to the list series.append(i) if (i > 1) series.append(" * ") else series.append(" = ") i-- } // Get the result from the Factorial Method // and append it to the end of the list series.append(factorial(n)) return series.toString() } // Using a StringBuffer as a list of string elements fun getFibonnaciSeries(n : Int) : String? { // Create the String that will hold the list val series = StringBuffer() // We begin by concatenating the first 3 values which // are always constant series.append("0, 1, 1") // Then we calculate the Fibonacci of each element // and add append it to the list for (i in 2..n) { if (i < n) series.append(", ") else series.append(" = ") series.append(fibonacci(i)) } // return the list as a string return series.toString() } fun factorial(n : Int) : BigInteger? { if (n == 1) return BigInteger.ONE else return BigInteger.valueOf(n.toLong())?.multiply(factorial(n - 1)) } fun fibonacci(n : Int) : Long { if (n < 2) return 1 else return fibonacci(n - 1) + fibonacci(n - 2) } } fun main(args : Array<String>) { // Printing Factorial Series println("") println(Fiborial.getFactorialSeries(5)) println(Fiborial.getFactorialSeries(7)) println(Fiborial.getFactorialSeries(9)) println(Fiborial.getFactorialSeries(11)) println(Fiborial.getFactorialSeries(40)) // Printing Fibonacci Series println("") println(Fiborial.getFibonnaciSeries(5)) println(Fiborial.getFibonnaciSeries(7)) println(Fiborial.getFibonnaciSeries(9)) println(Fiborial.getFibonnaciSeries(11)) println(Fiborial.getFibonnaciSeries(40)) }
And the Output is:
Mixing Instance and Static Members in the same Class
Normally, instance classes can contain both, instance and static members such as: fields, getters, constructors/initializers, methods, etc. However, In Kotlin, unlike Java, classes do not have static methods, so it doesn't support mixing both of them on the same object or class. In the following code I had to create one Object and one Class to build this example.
package com.series // 'Static' Class object StaticFiborial { // 'Static' Field/Property private var _staticCount : Int = 0 // 'Static' Read-Only Property public val StaticCount : Int get() { return _staticCount } // 'Static' Constructor //this() : this() { // No constructor support for Objects - failed to get descriptor for secondary constructor // using an explicit initializer method instead fun constructor() { println("\nStatic Constructor ${_staticCount}") } // 'Static' Method fun fibonacci(n : Int) { _staticCount += 1 println("\nFibonacci(${n})") } } // Instance Class // Instance Field/Property class InstanceFiborial(private var _instanceCount : Int) { // Instance Read-Only Property public val InstanceCount : Int get() { return this._instanceCount } // Instance Constructor this() : this(0) { println("\nInstance Constructor ${this._instanceCount}") } // Instance Method fun factorial(n : Int) { this._instanceCount += 1 println("\nFactorial(${n})") } } fun main(args : Array<String>) { // Calling Static Constructor and Methods // No need to instantiate StaticFiborial.constructor() StaticFiborial.fibonacci(5) // Calling Instance Constructor and Methods // Instance required val fib = InstanceFiborial() fib.factorial(5) StaticFiborial.fibonacci(15) fib.factorial(5) // Calling Instance Constructor and Methods // for a second object val fib2 = InstanceFiborial() fib2.factorial(5) println("") // Calling Static Property println("Static Count = ${StaticFiborial.StaticCount}") // Calling Instance Property of object 1 and 2 println("Instance 1 Count = ${fib.InstanceCount}") println("Instance 2 Count = ${fib2.InstanceCount}") }
And the Output is:
Factorial using java.lang.Long, java.lang.Double, java.math.BigInteger
package com.series import java.math.BigInteger import com.series.Stopwatch // Long Factorial fun factorialInt64(n : Int) : Long { if (n == 1) return 1 else return n * factorialInt64(n - 1) } // Double Factorial fun factorialDouble(n : Int) : Double { if (n == 1) return 1.0 else return n * factorialDouble(n - 1) } // BigInteger Factorial fun factorialBigInteger(n : Int) : BigInteger? { if (n == 1) return BigInteger.ONE else return BigInteger.valueOf(n.toLong())?.multiply(factorialBigInteger(n - 1)) } fun main(args: Array<String>) { val timer = Stopwatch() var facIntResult : Long = 0 var facDblResult : Double = 0.0 var facBigResult = BigInteger.ZERO println("\nFactorial using Int64") // Benchmark Factorial using Int64 var i = 5 while (i < 55) { timer.start() facIntResult = factorialInt64(i) timer.stop() println(" (${i}) = ${timer.getElapsed()} : ${facIntResult}") i += 5 } println("\nFactorial using Double") // Benchmark Factorial using Double i = 5 while (i < 55) { timer.start() facDblResult = factorialDouble(i) timer.stop() println(" (${i}) = ${timer.getElapsed()} : ${facDblResult}") i += 5 } println("\nFactorial using BigInteger") // Benchmark Factorial using BigInteger i = 5 while (i < 55) { timer.start() facBigResult = factorialBigInteger(i) timer.stop() println(" (${i}) = ${timer.getElapsed()} : ${facBigResult}") i += 5 } }
And the Output is:
So, now that you tried it, what is your feelings about that langage?
ReplyDeleteWell, not too much (yet). It looks similar to gosu and scala. The IDE support is very nice... I think I need to try out more features.
DeleteNext series will be about inheritance and later on on functional programming features. will have more comments by then.
Hi Sir, i can you help me?
ReplyDeletei don't know how to solve for the right code for Fibonacci Factorial
here is a example.if i will enter 5
it will output 130
(here's the logic first it will do the fibonacci sequence which is 1 1 2 3 5, after that it will get the factorial of the sequence, 1! = 1 ,1!-1x1 =1, 2!-1X2 = 2, 3! 1x2x3 = 6, 5! = 1x2x3x4x5 = 120.after that...
it will add all the factorial...1+1+2+6+120 = 130;)