Sunday, July 8, 2012

Factorial and Fibonacci in Xtend



Here below a little program in Xtend that implements 2 classes (in fact, they are 3 + 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 (which will not appear in other languages) is the Program class which has the static execution method "main".

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, 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 Eclipse IDE 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 Xtend  
package com.series
import com.series.Stopwatch
import java.math.BigInteger
import java.util.List

// Instance Class
// static is not a class modifier in Xtend
class StaticFiborial {
    // Static Field
    private static String className = "'Static' Constructor"
    // Static Constructor/Initializer  
    // no available static constructor support  
    // Static Initializer Method instead, but need to be explicitly invoked  
    def static constructor() {  
        className = "'Static' Constructor"  
        println(className)  
    }  
    // Static Method - Factorial Recursive  
    def static BigInteger factorialR(int n) {
        if (n == 1)  
              return 1BI
        else
            return BigInteger::valueOf(n) * factorialR(n - 1)       
    }
    // Static Method - Factorial Imperative  
    def static BigInteger factorialI(int n) {
        var res = 1BI
        var m = n // method parameters are final
        while (m > 1) {
            res = res * BigInteger::valueOf(m)
            m = m - 1    
        }   
        return res     
    }
    // Static Method - Fibonacci Recursive   
    def static long fibonacciR(int n) {
        if (n < 2)
            return 1L
        else
            return fibonacciR(n - 1) + fibonacciR(n - 2)
    } 
    // Static Method - Fibonacci Imperative
    def static long fibonacciI(int n) {
        var pre = 1L
        var cur = 1L
        var tmp = 0L
        for (int i : 2..n) {
            tmp = cur + pre
            pre = cur
            cur = tmp
        }             
        return cur
    }    
    // Static Method - Benchmarking Algorithms  
      def static void benchmarkAlgorithm(int algorithm, List<Integer> values) {  
        val timer = new Stopwatch  
        var testValue = 0
        var facTimeResult = 0BI  
        var fibTimeResult = 0L 
        var i = 0 
        // "Switch" Flow Control Statement
        switch algorithm {
            case 1: {
                println("\nFactorial Imperative:")  
                // "For" Loop Statement  
                for (int j : 0..values.size - 1) {  
                    testValue = values.get(j).intValue
                    // Taking Time
                    timer.start
                    facTimeResult = factorialI(testValue)  
                    timer.stop 
                    // Getting Time  
                    println(''' («testValue») = «timer.getElapsed»''')
                    }
                }
            case 2: {
                println("\nFactorial Recursive:")    
                // "While" Loop Statement                
                while (i < values.size) {                            
                    testValue = values.get(i).intValue    
                    // Taking Time    
                    timer.start    
                    facTimeResult = factorialR(testValue)    
                    timer.stop    
                    // Getting Time    
                    println(''' («testValue») = «timer.getElapsed»''')
                    i = i + 1    
                }
            }
            case 3: {
                println("\nFibonacci Imperative:")   
                // "Do-While" Loop Statement
                do {    
                    testValue = values.get(i).intValue    
                    // Taking Time    
                    timer.start    
                    fibTimeResult = fibonacciI(testValue)    
                    timer.stop
                    // Getting Time    
                    println(''' («testValue») = «timer.getElapsed»''')
                    i = i + 1        
                } while (i < values.size)    
            }
            case 4: {
                println("\nFibonacci Recursive:")    
                // "For Each" Loop Statement    
                for (int item : values) {    
                    testValue = item;    
                    // Taking Time    
                    timer.start    
                    fibTimeResult = fibonacciR(testValue)    
                    timer.stop    
                    // Getting Time    
                    println(''' («testValue») = «timer.getElapsed»''')
                }    
            }
            default : println("DONG!")
        }
    }
}

package com.series
import com.series.StaticFiborial
import java.math.BigInteger

// Instance Class    
class InstanceFiborial {
    // Instance Field    
    private String className    
    // Instance Constructor    
    new() {    
        this.className = "Instance Constructor"
        println(this.className)
    }    
    // Instance Method - Factorial Recursive    
    def BigInteger factorialR(int n) {    
        // Calling Static Method    
        return StaticFiborial::factorialR(n)    
    }    
    // Instance Method - Factorial Imperative    
    def BigInteger factorialI(int n) {    
        // Calling Static Method
        return StaticFiborial::factorialI(n)
    }    
    // Instance Method - Fibonacci Recursive
    def long fibonacciR(int n) {    
        // Calling Static Method    
        return StaticFiborial::fibonacciR(n)    
    }    
    // Instance Method - Factorial Imperative    
    def long fibonacciI(int n) {    
        // Calling Static Method    
        return StaticFiborial::fibonacciI(n);    
    }    
}

package com.series
import com.series.StaticFiborial
import com.series.InstanceFiborial 
import java.util.List
import java.util.ArrayList
import java.util.Scanner

class FiborialProgram {
    def static main(String[] args) {
        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. Calling method from instantiated object    
        val ff = new 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 List<Integer> values = new ArrayList<Integer>
        var i = 5
        while (i < 55) {  
            values.add(i)  
            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 in = new Scanner(System::in)    
        val line = in.nextLine    
        in.close         
    }
}

And the Output is:





Printing the Factorial and Fibonacci Series
package com.series
import java.math.BigInteger
import java.lang.StringBuffer

class Fiborial {
    // Using a StringBuffer as a list of string elements  
    def static String getFactorialSeries(int n) {  
        // Create the String that will hold the list  
        val series = new 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  
        var i = n  
        while (i > 0) {  
            // and append it to the list  
            series.append(i)  
            if (i > 1)  
                series.append(" * ")  
            else  
                series.append(" = ")  
            i = i - 1  
        }  
        // Get the result from the Factorial Method  
        // and append it to the end of the list  
        series.append(factorial(n))  
        // return the list as a string  
        return series.toString
    }  
  
    // Using a StringBuffer as a list of string elements  
    def static String getFibonnaciSeries(int n)  
    {  
        // Create the String that will hold the list  
        val series = new 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 (int i : 2..n) {  
            if (i < n)  
                series.append(", ")  
            else  
                series.append(" = ")  
            series.append(fibonacci(i))  
        }  
        // return the list as a string  
        return series.toString
    }  
  
    def static BigInteger factorial(int n) {
        if (n == 1)  
              return 1BI
        else
            return BigInteger::valueOf(n) * factorial(n - 1)       
    }       
  
    def static long fibonacci(int n) {
        if (n < 2)
            return 1L
        else
            return fibonacci(n - 1) + fibonacci(n - 2)
    }    
}

package com.series
import com.series.Fiborial

class FiborialProgram {
    def static void main(String[] args) {
        // 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

Instance classes can contain both, instance and static members such as: fields, getters/setters, constructors/initializers, methods, etc.

package com.series

class Fiborial {
    // Instance Field    
    var int instanceCount
    // Static Field    
    static var int staticCount
    // Instance Read-Only Getter    
    // Within instance members, you can always use      
    // the "this" reference pointer to access your (instance) members.    
    def int getInstanceCount() {    
        return this.instanceCount     
    }    
    // Static Read-Only Getter        
    // As with Static Methods, you cannot reference your class members    
    // with the "this" reference pointer since static members are not    
    // instantiated.            
    def static int getStaticCount() {    
        return staticCount
    }    
    // Instance Constructor    
    public new() {    
        this.instanceCount = 0
        println    
        println('''Instance Constructor «this.instanceCount»''')   
    }    
    // Static Constructor 
    // not supported in Xtend. Constructor cannot be static.
    // using an explicit initializer method instead    
    def static constructor() { 
        staticCount = 0
        println 
        println('''Static Constructor «staticCount»''') 
    }    
    // Instance Method    
    def void factorial(int n) {    
        this.instanceCount =  this.instanceCount + 1
        println    
        println('''Factorial(«n»)''')    
    }    
  
    // Static Method    
    def static void fibonacci(int n) {    
        staticCount = staticCount + 1
        println    
        println('''Fibonacci(«n»)''');    
    }                    
}

package com.series
import com.series.Fiborial

class FiborialProgram {
    def static void main(String[] args) {
        // Calling Static Initializer and Methods  
        // No need to instantiate  
        Fiborial::constructor  
        Fiborial::fibonacci(5)  
      
        // Calling Instance Constructor and Methods  
        // Instance required  
        val fib = new Fiborial  
        fib.factorial(5)  
      
        Fiborial::fibonacci(15)  
        fib.factorial(5)  
      
        // Calling Instance Constructor and Methods  
        // for a second object  
        val fib2 = new Fiborial  
        fib2.factorial(5)  
      
        println
        // Calling Static Property  
        println('''Static Count = «Fiborial::getStaticCount»''')  
        // Calling Instance Property of object 1 and 2  
        println('''Instance 1 Count = «fib.getInstanceCount»''')  
        println('''Instance 2 Count = «fib2.getInstanceCount»''')          
    } 
}

And the Output is:























Factorial using java.lang.Long, java.lang.Double, java.math.BigInteger


package com.series
import com.series.Stopwatch
import java.math.BigInteger

class Fiborial {
    def static void main(String[] args) {
        val timer = new Stopwatch  
        var facIntResult = 0L
        var facDblResult  = 0d  
        var facBigResult = 0BI 
        var i = 5
        
        println("\nFactorial using Int64")  
        // Benchmark Factorial using Int64  
        while (i < 55) {  
            timer.start
            facIntResult = factorialInt64(i)  
            timer.stop  
              println(''' («i») = «timer.getElapsed» : «facIntResult»''')  
              i = 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 = 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 = i + 5    
        }  
    }
    
    // Long Factorial    
    def static long factorialInt64(int n) {    
        if (n == 1)    
            return 1L  
        else    
            return n * factorialInt64(n - 1)  
    }  
      
    // Double Factorial
    def static double factorialDouble(int n) {    
        if (n == 1)    
            return 1d
        else    
            return n * factorialDouble(n - 1)  
    }  
      
    // BigInteger Factorial   
    def static BigInteger factorialBigInteger(int n) {    
        if (n == 1)    
            return 1BI  
        else    
            return BigInteger::valueOf(n) * factorialBigInteger(n - 1)  
    }  
}



And the Output is:

No comments:

Post a Comment