Functional Programming Using Scala

Functional programming (often abbreviated FP) is the process of building software by composing pure functions, avoiding shared state, mutable data, and side-effects. Functional programming is declarative rather than imperative, and the application state flows through pure functions. Contrast with object-oriented programming, where the application state is usually shared and colocated with methods in objects.

These are some examples of functional programming problems.

Introduction

1. The temperature is 35C; convert this temperature into Fahrenheit. ΒΊF =ΒΊC * 1.8000 + 32.00

def convert(x:Double):Double=x*1.8000+32.00

println(convert(35))

2.The volume of a sphere with radius r is 4/3 Pi r3. What is the volume of a sphere with radius 5?

def volume(x:Double):Double=4/3*math.Pi*x*x*x
println(volume(5))

3. Suppose the cover price of a book is Rs. 24.95, but bookstores get a 40% discount. Shipping costs Rs. 3 for the first 50 copy and 75 cents for each additional copy. What is the total wholesale cost for 60 copies?

def book_price(x:Int):Double=x*24.95

def discount(amount:Double):Double=amount*.4

def shipping_cost(x:Int):Double=3*x+(x-50)*.75

println(book_price(60)-discount(book_price(60))+shipping_cost(60))


Pure Functions

1. Company XYZ & Co. pays all its employees Rs.150 per normal working hour and Rs. 75 per OT hour. A typical employee works 40 (normal) and 20(OT) hours per week has to pay a 10% tax. Develop a functional program that determines the take-home salary of an employee from the number of working hours and OT hours given.

def normal_working_salary(x:Int)=x*150

def ot_working_salary(x:Int)=x*75

def full_salary(x:Int,y:Int)=normal_working_salary(x)+ot_working_salary(y)

def tax(full_salary:Int)=full_salary*.1

def final_salary(x:Int,y:Int)=full_salary(x,y)-tax(full_salary(x,y))

println(final_salary(40,20))

2.  Imagine the owner of a movie theater who has complete freedom in setting ticket prices. The more he charges, the fewer the people who can afford tickets. In a recent experiment, the owner determined a precise relationship between the price of a ticket and average attendance.  At a price of Rs 15.00 per ticket, 120 people attend a performance. Decreasing the price by  5 Rupees increases attendance by 20 and increasing the price by  5 Rupees decreases attendance by 20. Unfortunately, the increased attendance also comes at an increased cost. Every performance costs the owner Rs.500. Each attendee costs another 3 Rupees. The owner would like to know the exact relationship between profit and ticket price so that he can determine the price at which he can make the highest profit. Implement a functional program to find out the best ticket price.

def attendees(x:Int):Int=120+(15-x)/5*20

def revenue(x:Int):Int = attendees(x)*x

def cost(x:Int):Int=500+attendees(x)*3

def profit(x:Int):Int =revenue(x)- cost(x)

println(profit(5))

println(profit(10))

println(profit(15))

println(profit(20))

println(profit(25))

println(profit(30))

println(profit(35))

println(profit(40))

println(profit(45))

println(profit(50))


Recursive Functions

1. Can you write a recursive function prime(n) that returns true for a prime number and false for the other? For example prime(5) should return true and prime(8) should return false.

def gcd(x:Int,y:Int):Int= y match{

case 0 => x

case y if (y>x) => gcd(y,x)

case _ => gcd(y,x%y)

}

def prime(a:Int,b:Int=2):Boolean=b match{

case x if(a==x)=> true

case x if(gcd(a,x)>1)=>false

case x =>prime(a,x+1)

}

println(prime(5))

println(prime(8))

2. Can you write a recursive function primeSeq(n) that prints all prime numbers which less than n? For example prime(10) should print 2,3,5, and 7 on the terminal.

def prime(a:Int,b:Int=2):Boolean={

if(a<=2) if(a<2) false else true

    else if(a%b==0)  false

else if(b*b>a)  true

else  prime(a,b+1)

}

def primeSeq(a:Int):Unit={

if(a>0) primeSeq(a-1)

if(prime(a)) println(a) 

}

println(primeSeq(10));

3. Can you write a recursive function that returns the addition of numbers from1 to n? For example, sum(5) should print 15.

def sum(x:Int):Int={

if (x==1) 1 else x+sum(x-1)

}

println(sum(5))

4. Can you write a recursive function to determine even and odd numbers? 

def is_even(x:Int):Boolean= x match{

case 0 => true

case _ => is_odd(x-1)

}

def is_odd(x:Int):Boolean = !(is_even(x))

println(is_even(4))

println(is_even(5))

println(is_odd(8))

println(is_odd(9))

5. Can you write a recursive function to get the addition of all even numbers less than given n.

def is_even(x:Int):String= x match{

case 0 => "True"

case 1 => "False"

case _ => is_even(x-2)

}

def sum(x:Int):Int= x match{

case 0 => 0;

case x if(is_even(x)=="True") => x+sum(x-1)

case x if(is_even(x)=="False") => 0+sum(x-1)

}

println(sum(6))

6. The Fibonacci Sequence is the series of numbers: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, . . . Each subsequent number is the sum of the previous two.  Write a recursive function print fist n Fibonacci numbers for given n.

def fibonacci(x:Int):Int=x match{

case x if x==0 => 0

case x if x==1 => 1

case x => fibonacci(x-1)+fibonacci(x-2)

}

def fibonacci_sequnce(x:Int):Any={

if (x>0) fibonacci_sequnce(x-1)

println(fibonacci(x))

}

println(fibonacci_sequnce(10))


Map Reduce

The Caesar cipher is one of the earliest known and simplest ciphers. It is a type of substitution cipher in which each letter in the plaintext is 'shifted' a certain number of places down the alphabet. For example, with a shift of 1, A would be replaced by B, B would become C, and so on. The method is named after Julius Caesar, who apparently used it to communicate with his generals.

Implement Encryption and Decryption functions of Caesar cipher.

Then implement a Cipher function that takes Encryption and Decryption functions to process the data.

//alphabet

val alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

//get number of swifts

val shift = (scala.io.StdIn.readLine("Enter The Number You Want To Swift: ").toInt + alphabet.size) % alphabet.size

//get input message

val input_text = scala.io.StdIn.readLine("Enter Your Message: ")

//function to encrypt

val output_text1 = input_text.map( (c: Char) => { 

val x = alphabet.indexOf(c.toUpper)

    if (x == -1){

c

    }

else{

alphabet((x + shift) % alphabet.size)

});

//function to decrypt

val output_text2 = output_text1.map( (c: Char) => { 

val x = alphabet.indexOf(c.toUpper)

    if (x == -1){

c

    }

else{

alphabet((x - shift) % alphabet.size)

});

//print message

println("Encrypted Message: ");

println(output_text1);

println("Decrypted Message: ");

println(output_text2);


Functions and Data

1. Implement a Data Structure for Rational Number and create a method neg to class Rational that is used like this: x.neg // evaluates to -x

object MyApp extends App{

val x= new Rational(3,4)

println(x)

println(x.neg)

}

class Rational(n:Int, d:Int){

def numer=n

def denom=d

  override def toString=numer+"/"+denom

def neg=new Rational(-numer,denom)

}

2. Create a method sub to subtract two rational numbers and find an answer x-y-z where x=3/4, y=5/8, z=2/7.

object MyApp extends App{

val x= new Rational(3,4)

val y= new Rational(5,8)

val z= new Rational(2,7)

val a=x.sub(y).sub(z)

println(a)

}

class Rational(n:Int, d:Int){

  require(d>0, "d must be greater than 0")

def numer=n/gcd(Math.abs(n),d)

def denom=d/gcd(Math.abs(n),d)

  def this(n:Int)=this(3,4)

  private def gcd(a:Int, b:Int):Int=if(b==0)a else gcd(b,a%b)

  def add(r:Rational)=new Rational(this.numer*r.denom+this.denom*r.numer,this.denom*r.denom)

  def sub(r:Rational) = this.add(r.neg)

  def neg=new Rational(-this.numer,this.denom)

  override def toString=numer+"/"+denom

}

3. Implement a Data Structure for Account and create a method transfer which transfers the money from this account to a given account.

object MyApp extends App{

var Ac1 = new Account("971701617V",20200729, 15000.15)

var Ac2 = new Account("971701617V",20200729, 0)

Ac1.Transfer(Ac2,1000)

println(Ac1)

println(Ac2)

}

class Account(id:String, n: Int, b: Double){

  val nic:String=id

  val acnumber: Int = n

  var balance: Double = b

  override def toString ="["+nic+":"+acnumber +":"+ balance+"]"

def withdraw(amount:Double)={

          this.balance=this.balance-amount

          if (this.balance<0) println("Balance is insufficient")

      }

def deposit(amount:Double) = this.balance=this.balance+amount

def Transfer(Ac:Account,amount:Double)={

        this.balance=this.balance-amount

        Ac.balance=Ac.balance+amount

        if (this.balance<0) println("Balance is insufficient")

    }

}

4.  A Bank defines a List of Accounts. To implement the following functions:

4.1 List of Accounts with negative balances

4.2 Calculate the sum of all account balances

4.3 Calculate the final balances of all accounts after applying the interest function as follows: If the balance is positive, deposit interest is .05  and if balance is negative, overdraft interest is .1.


object MyApp extends App{

    var Ac1 = new Account("971701617V",20200729, 25000.25)

    var Ac2 = new Account("971701617V",20200729, -1250.50)

    var Ac3 = new Account("971701617V",20200729, 3000.55)

    var Ac4 = new Account("971701617V",20200729, -230.40)

    var Ac5 = new Account("971701617V",20200729, 5611.74)

    var Ac6 = new Account("971701617V",20200729, -234.56)

    var Ac7 = new Account("971701617V",20200729, 4356.43)

    var Ac8 = new Account("971701617V",20200729, -5000.00)

    var Ac9 = new Account("971701617V",20200729, 634.13)

    var Ac10 = new Account("971701617V",20200729, 1457.23)


    var Bank:List[Account]=List(Ac1,Ac2,Ac3,Ac4,Ac5,Ac6,Ac7,Ac8,Ac9,Ac10)


    //question 4.1

   val negAccounts = Bank.filter(x=>x.balance<0)

   println("List of Accounts with negative balances : \n")

   for(element<-negAccounts){

     println(element)

   }

   println("\n")


   //question 4.2

   var list = Bank.map(x=>x.balance)

   val sum = list.reduce((x,y) =>x+y)

   println("Sum of the all account balances : \n ")

   println(sum)

   println("\n")


   //question 4.3

   Bank.map(x=>if(x.balance>0) x.balance=(x.balance)*1.05 else x.balance=(x.balance)*1.1)

   println("Final balances of all accounts after apply the interest : \n")

   for(element<-Bank){

    println(element)

   }

}

class Account(id:String, n:Int, b:Double){

    val nic: String = id

    val acnumber : Int = n

    var balance : Double = b


    override def toString = nic+"  "+acnumber+"  "+balance


    def withdraw(amount:Double)= {

        this.balance=this.balance-amount

        if (this.balance<0) println("Balance is insufficient")

    }

    def deposit(amount:Double) = this.balance=this.balance+amount


    def transfer(acc:Account,amount:Double)= {

        this.balance=this.balance-amount

        acc.balance=acc.balance+amount

        if (this.balance<0) println("Balance is insufficient")

    }

}


Case Class

Implement a case class Point(x,y) and create the following methods:

1. add(+) should add two given points

object MyApp extends App{

val p1 =new Point(2,3)

val p2 =new Point(1,2)

val p3 =p1.add(p2)

println(p3)

}

case class Point(a:Int, b:Int){

  def x:Int=a

  def y:Int=b

  override def toString = "("+x+","+y+")"

  def add(p:Point)=new Point(this.x+p.x,this.y+p.y)

}

2. move should move a point by a given distance dx and dy.

object MyApp extends App{

val p1 =new Point(2,3)

val p2 =p1.move(1,2)

println(p2)

}

case class Point(a:Int, b:Int){

  def x:Int=a

  def y:Int=b

  override def toString = "("+x+","+y+")"

  def move(dx:Int, dy:Int)=Point(this.x+dx,this.y+dy)

}

3. distance should return the distance between two given points.

object MyApp extends App{

val p1 =new Point(2,3)

val p2 =new Point(1,2)

val p3 =p1.distance(p2)

println(p3)

}

case class Point(a: Double, b: Double){

  def x:Double=a

  def y:Double=b

  import math.{ sqrt, pow }

  override def toString = "("+x+","+y+")"

  def distance(p: Point): Double=sqrt(pow(x - p.x, 2) + pow(y - p.y, 2))

}

4. invert should switch the x and y coordinates.

object MyApp extends App{

val p1 =new Point(2,3)

val p2 =p1.invert

println(p2)

}

case class Point(a:Int, b:Int){

  def x:Int=a

  def y:Int=b

  override def toString = "("+x+","+y+")"

  def invert={Point(this.y, this.x)}

}


Comments

Popular posts from this blog

Programming Using GNU Octave

Library Problem

What Is A Gamma Ray Burst?