Tower of Hanoi using Scala Pure function - scala

I am new to functional Programming and I'm trying to implement scala Iterative way of implementing tower of Hanoi. I could solve it using the recursion way but I have difficulty trying to implement it using Iterative method in Scala pure function. The code below is what I have coded so far.
I am using Iterative function since I can simply use it as a stack. So I am trying to avoid using separate functions of implementing it. I have no idea how I can continue from here
/**
* The three pegs of the game. The game starts with all N disks on peg 1 and
* needs to end with all disks on peg 3.
*/
type Peg = 1 | 2 | 3
case class Move(from: Peg, to: Peg):
assert(from != to) // Throws and ends the program if violated.
def towerOfHanoiRecursive(n: Int): Iterator[Move] = {
var a: Iterator[Move] = Iterator()
def helper(n: Int, from: Peg, to: Peg, aux: Peg): Iterator[Move] =
if (n<=0) return a.iterator
helper(n-1, from, aux, to)
a = a ++ Iterator(Move(from,to))
helper(n-1, aux, to , from)
helper(n, 1, 3, 2)
}
def towerOfHanoiIterative(n: Int): Iterator[Move] =
def helper(n: Int, from: Peg, to: Peg, aux: Peg): Iterator[Move] =
Iterator.iterate((List(Problem(n, from, to, aux)), Iterator.empty[Move])) {
case (Problem(0, _, _, _) :: _, _) =>
(List(), Iterator())
case (Problem(1, x, y, _) :: stackTail, _) if (stackTail == List() && x == 1 && y ==3 )=> {
if (stackTail == List() )
( stackTail , Iterator(Move(x,y)))
else if ((stackTail.length %2) == 0)
(stackTail , Iterator(Move(y,x)))
else
(stackTail , Iterator(Move(y,x)))
}
case (Problem(1, x, y, z) :: stackTail, _) =>
if ((stackTail.length %3) == 0)
( stackTail , Iterator(Move(z,x)))
else if ((stackTail.length %3) == 1)
( stackTail , Iterator(Move(z,y)))
else
( stackTail , Iterator(Move(z,y)))
case (Problem(k, f, t, a)::stackTail, _) if (n%2) == 0 => {
if ((stackTail.length %3) ==0)
(List(Problem(k-1, f, t, a))::: List(Problem(k-1, t,f ,a)) ::: stackTail ,Iterator(Move(f,a)))
else if ((stackTail.length % 3) ==1)
(List(Problem(k-1, f, a, t))::: List(Problem(k-1, a,f ,t)) ::: stackTail ,Iterator(Move(f,a)))
else
println("3rd")
(List(Problem(k-1, a, t, f))::: List(Problem(k-1, a,f ,t)) ::: stackTail ,Iterator(Move(a,t)))
}
case (Problem(k, f, t, a)::stackTail, _) if (n %2) == 1 => {
if ((stackTail.length %3) ==0)
(List(Problem(k-1, f, t, a))::: List(Problem(k-1, a,f ,t)) ::: stackTail ,Iterator(Move(f,t)))
else if ((stackTail.length % 3) ==1)
(List(Problem(k-1, f, a, t))::: List(Problem(k-1, f,a ,t)) ::: stackTail ,Iterator(Move(f,a)))
else
(List(Problem(k-1, a, t, f))::: List(Problem(k-1, f,t ,a)) ::: stackTail ,Iterator(Move(a,t)))
}
case (Nil, _) =>
println("nil")
(List(),Iterator())
}.takeWhile { case (p,o) => p.nonEmpty || o.nonEmpty }.flatMap(_._2)
helper(n, 1, 3, 2)

Related

SCALA: Generating a list of Tuple2 objects meeting some criteria

I want to generate a list of Tuple2 objects. Each tuple (a,b) in the list should meeting the conditions:a and b both are perfect squares,(b/30)<a<b
and a>N and b>N ( N can even be a BigInt)
I am trying to write a scala function to generate the List of Tuples meeting the above requirements?
This is my attempt..it works fine for Ints and Longs..But for BigInt there is sqrt problem I am facing..Here is my approach in coding as below:
scala> def genTups(N:Long) ={
| val x = for(s<- 1L to Math.sqrt(N).toLong) yield s*s;
| val y = x.combinations(2).map{ case Vector(a,b) => (a,b)}.toList
| y.filter(t=> (t._1*30/t._2)>=1)
| }
genTups: (N: Long)List[(Long, Long)]
scala> genTups(30)
res32: List[(Long, Long)] = List((1,4), (1,9), (1,16), (1,25), (4,9), (4,16), (4,25), (9,16), (9,25), (16,25))
Improved this using BigInt square-root algorithm as below:
def genTups(N1:BigInt,N2:BigInt) ={
def sqt(n:BigInt):BigInt = {
var a = BigInt(1)
var b = (n>>5)+BigInt(8)
while((b-a) >= 0) {
var mid:BigInt = (a+b)>>1
if(mid*mid-n> 0) b = mid-1
else a = mid+1
}; a-1 }
val x = for(s<- sqt(N1) to sqt(N2)) yield s*s;
val y = x.combinations(2).map{ case Vector(a,b) => (a,b)}.toList
y.filter(t=> (t._1*30/t._2)>=1)
}
I appreciate any help to improve in my algorithm .
You can avoid sqrt in you algorithm by changing the way you calculate x to this:
val x = (BigInt(1) to N).map(x => x*x).takeWhile(_ <= N)
The final function is then:
def genTups(N: BigInt) = {
val x = (BigInt(1) to N).map(x => x*x).takeWhile(_ <= N)
val y = x.combinations(2).map { case Vector(a, b) if (a < b) => (a, b) }.toList
y.filter(t => (t._1 * 30 / t._2) >= 1)
}
You can also re-write this as a single chain of operations like this:
def genTups(N: BigInt) =
(BigInt(1) to N)
.map(x => x * x)
.takeWhile(_ <= N)
.combinations(2)
.map { case Vector(a, b) if a < b => (a, b) }
.filter(t => (t._1 * 30 / t._2) >= 1)
.toList
In a quest for performance, I came up with this recursive version that appears to be significantly faster
def genTups(N1: BigInt, N2: BigInt) = {
def sqt(n: BigInt): BigInt = {
var a = BigInt(1)
var b = (n >> 5) + BigInt(8)
while ((b - a) >= 0) {
var mid: BigInt = (a + b) >> 1
if (mid * mid - n > 0) {
b = mid - 1
} else {
a = mid + 1
}
}
a - 1
}
#tailrec
def loop(a: BigInt, rem: List[BigInt], res: List[(BigInt, BigInt)]): List[(BigInt, BigInt)] =
rem match {
case Nil => res
case head :: tail =>
val a30 = a * 30
val thisRes = rem.takeWhile(_ <= a30).map(b => (a, b))
loop(head, tail, thisRes.reverse ::: res)
}
val squares = (sqt(N1) to sqt(N2)).map(s => s * s).toList
loop(squares.head, squares.tail, Nil).reverse
}
Each recursion of the loop adds all the matching pairs for a given value of a. The result is built in reverse because adding to the front of a long list is much faster than adding to the tail.
Firstly create a function to check if number if perfect square or not.
def squareRootOfPerfectSquare(a: Int): Option[Int] = {
val sqrt = math.sqrt(a)
if (sqrt % 1 == 0)
Some(sqrt.toInt)
else
None
}
Then, create another func that will calculate this list of tuples according to the conditions mentioned above.
def generateTuples(n1:Int,n2:Int)={
for{
b <- 1 to n2;
a <- 1 to n1 if(b>a && squareRootOfPerfectSquare(b).isDefined && squareRootOfPerfectSquare(a).isDefined)
} yield ( (a,b) )
}
Then on calling the function with parameters generateTuples(5,10)
you will get an output as
res0: scala.collection.immutable.IndexedSeq[(Int, Int)] = Vector((1,4), (1,9), (4,9))
Hope that helps !!!

Haskell to Scala

Im new to Scala but I know something about functional programing thanks to Haskell and I'm looking for some examples, can you tell me how this would be in Scala?
scalarProduct :: [Int] -> [Int] -> Int
scalarProduct [] _ = 0
scalarProduct _ [] = 0
scalarProduct (x:xs) (y:ys) = if length(xs) == length (ys) then x*y + scalarProduct xs ys else 0
lessThan :: [Float] -> Float -> Int
lessThan [] _ = 0
lessThan (x:xs) n = if x < n then 1 + lessThan xs n else lessThan xs n
removeLast :: [a] -> [a]
removeLast [] = []
removeLast (x:xs) = if length(xs) == 0 then [] else [x] ++ removeLast xs
funcion :: Int -> Float
funcion x | x >= 6 = fromIntegral(product[9..x*2])
| x > 0 = fromIntegral(x) ** (1/4)
| x <= 0 = fromIntegral(product[1..(-x)]) * 5.0**fromIntegral(x)
If you want literal transformations, I think the below is as close as you will get. Bear in mind you have to put this inside an object/class/trait for this to compile (or just past it into the REPL).
def scalarProduct(list1: List[Int], list2: List[Int]): Int = (list1,list2) match {
case (Nil,_) => 0
case (_,Nil) => 0
case (x :: xs, y :: ys) => if (xs.length == ys.length) x*y + scalarProduct(xs,ys) else 0
}
def lessThan(floats: List[Float], bound: Float): Int = floats match {
case Nil => 0
case x :: xs => if (x < bound) 1 + lessThan(xs,n) else lessThan(xs,n)
}
def removeLast[A](list: List[A]): List[A] = list match {
case Nil => Nil
case x :: xs => if (xs.length == 0) Nil else List(x) ++ removeLast(xs)
}
def funcion(x: Int): Double = {
if (x >= 6)
(9 to x*2).product
else if (x > 0)
Math.pow(x,0.25)
else
(1 to -x).product.toDouble * Math.pow(5.0,x)
}
This code is pretty un-Scala-like. For example, the Scala way of doing the first three would probably be with an implicit conversion class RichList[A]. Also, these can all be done much more simply using library functions - but I don't think that's what you are looking for (else you would've used the corresponding library functions for the Haskell code).

Scala pattern matching with disjunctions not working

I am learning Scala and don't understand why the following is not working.
I want to refactor a (tested) mergeAndCount function which is part of a counting inversions algorithm to utilize pattern matching. Here is the unrefactored method:
def mergeAndCount(b: Vector[Int], c: Vector[Int]): (Int, Vector[Int]) = {
if (b.isEmpty && c.isEmpty)
(0, Vector())
else if (!b.isEmpty && (c.isEmpty || b.head < c.head)) {
val (count, r) = mergeAndCount(b drop 1, c)
(count, b.head +: r)
} else {
val (count, r) = mergeAndCount(b, c drop 1)
(count + b.length, c.head +: r)
}
}
Here is my refactored method mergeAndCount2. Which is working fine.
def mergeAndCount2(b: Vector[Int], c: Vector[Int]): (Int, Vector[Int]) = (b, c) match {
case (Vector(), Vector()) =>
(0, Vector())
case (bh +: br, Vector()) =>
val (count, r) = mergeAndCount2(br, c)
(count, bh +: r)
case (bh +: br, ch +: cr) if bh < ch =>
val (count, r) = mergeAndCount2(br, c)
(count, bh +: r)
case (_, ch +: cr) =>
val (count, r) = mergeAndCount2(b, cr)
(count + b.length, ch +: r)
}
However as you can see the second and third case are duplicate code. I therefore wanted to combine them using the disjunction like this:
case (bh +: br, Vector()) | (bh +: br, ch +: cr) if bh < ch =>
val (count, r) = mergeAndCount2(br, c)
(count, bh +: r)
This gives me an error though (on the case line): illegal variable in pattern alternative.
What am I doing wrong?
Any help (also on style) is greatly appreciated.
Update: thanks to your suggestions here is my result:
#tailrec
def mergeAndCount3(b: Vector[Int], c: Vector[Int], acc : (Int, Vector[Int])): (Int, Vector[Int]) = (b, c) match {
case (Vector(), Vector()) =>
acc
case (bh +: br, _) if c.isEmpty || bh < c.head =>
mergeAndCount3(br, c, (acc._1, acc._2 :+ bh))
case (_, ch +: cr) =>
mergeAndCount3(b, cr, (acc._1 + b.length, acc._2 :+ ch))
}
When pattern matching with pipe (|) you are not allowed to bind any variable other than wildcard (_).
This is easy to understand: in the body of your case, what would be the actual type of bh or br for example if your two alternatives match different types?
Edit - from the scala reference:
8.1.11 Pattern Alternatives Syntax: Pattern ::= Pattern1 { ‘|’ Pattern1 } A pattern alternative p 1 | . . . | p n consists of a
number of alternative patterns p i . All alternative patterns are type
checked with the expected type of the pattern. They may no bind
variables other than wildcards. The alternative pattern matches a
value v if at least one its alternatives matches v.
Edit after first comment - you can use the wildcard to match something like this for example:
try {
...
} catch {
case (_: NullPointerException | _: IllegalArgumentException) => ...
}
If you think about that, looking at your case clause, how should the compiler know if in the case body it should be allowed to use ch and cr or not?
This sort of questions make it very hard to make the compiler support disjunction and variable binding in the same case clause, thus this is not allowed at all.
Your mergeAndCount2 function looks quite fine with respect to pattern matching. I think that its most evident problem is not being tail-recursive and thus not running in constant stack space. If you can solve this problem you will probably end with something that is less repetitive as well.
You can rewrite the case expression and move the disjunction to the if part
case (bh +: br, cr) if cr.isEmpty || bh < cr.head =>
val (count, r) = mergeAndCount2(br, c)
(count, bh +: r)
Update:
You can yet simplify a little bit:
#tailrec
def mergeAndCount3(b: Vector[Int], c: Vector[Int],
count: Int = 0, r: Vector[Int] = Vector()): (Int, Vector[Int]) =
(b, c) match {
case (bh +: br, _) if c.isEmpty || bh < c.head =>
mergeAndCount3(br, c, count, bh +: r)
case (_, ch +: cr) =>
mergeAndCount3(b, cr, count + b.length, ch +: r)
case _ => (count, r)
}

Scala - can 'for-yield' clause yields nothing for some condition?

In Scala language, I want to write a function that yields odd numbers within a given range. The function prints some log when iterating even numbers. The first version of the function is:
def getOdds(N: Int): Traversable[Int] = {
val list = new mutable.MutableList[Int]
for (n <- 0 until N) {
if (n % 2 == 1) {
list += n
} else {
println("skip even number " + n)
}
}
return list
}
If I omit printing logs, the implementation become very simple:
def getOddsWithoutPrint(N: Int) =
for (n <- 0 until N if (n % 2 == 1)) yield n
However, I don't want to miss the logging part. How do I rewrite the first version more compactly? It would be great if it can be rewritten similar to this:
def IWantToDoSomethingSimilar(N: Int) =
for (n <- 0 until N) if (n % 2 == 1) yield n else println("skip even number " + n)
def IWantToDoSomethingSimilar(N: Int) =
for {
n <- 0 until N
if n % 2 != 0 || { println("skip even number " + n); false }
} yield n
Using filter instead of a for expression would be slightly simpler though.
I you want to keep the sequentiality of your traitement (processing odds and evens in order, not separately), you can use something like that (edited) :
def IWantToDoSomethingSimilar(N: Int) =
(for (n <- (0 until N)) yield {
if (n % 2 == 1) {
Option(n)
} else {
println("skip even number " + n)
None
}
// Flatten transforms the Seq[Option[Int]] into Seq[Int]
}).flatten
EDIT, following the same concept, a shorter solution :
def IWantToDoSomethingSimilar(N: Int) =
(0 until N) map {
case n if n % 2 == 0 => println("skip even number "+ n)
case n => n
} collect {case i:Int => i}
If you will to dig into a functional approach, something like the following is a good point to start.
First some common definitions:
// use scalaz 7
import scalaz._, Scalaz._
// transforms a function returning either E or B into a
// function returning an optional B and optionally writing a log of type E
def logged[A, E, B, F[_]](f: A => E \/ B)(
implicit FM: Monoid[F[E]], FP: Pointed[F]): (A => Writer[F[E], Option[B]]) =
(a: A) => f(a).fold(
e => Writer(FP.point(e), None),
b => Writer(FM.zero, Some(b)))
// helper for fixing the log storage format to List
def listLogged[A, E, B](f: A => E \/ B) = logged[A, E, B, List](f)
// shorthand for a String logger with List storage
type W[+A] = Writer[List[String], A]
Now all you have to do is write your filtering function:
def keepOdd(n: Int): String \/ Int =
if (n % 2 == 1) \/.right(n) else \/.left(n + " was even")
You can try it instantly:
scala> List(5, 6) map(keepOdd)
res0: List[scalaz.\/[String,Int]] = List(\/-(5), -\/(6 was even))
Then you can use the traverse function to apply your function to a list of inputs, and collect both the logs written and the results:
scala> val x = List(5, 6).traverse[W, Option[Int]](listLogged(keepOdd))
x: W[List[Option[Int]]] = scalaz.WriterTFunctions$$anon$26#503d0400
// unwrap the results
scala> x.run
res11: (List[String], List[Option[Int]]) = (List(6 was even),List(Some(5), None))
// we may even drop the None-s from the output
scala> val (logs, results) = x.map(_.flatten).run
logs: List[String] = List(6 was even)
results: List[Int] = List(5)
I don't think this can be done easily with a for comprehension. But you could use partition.
def getOffs(N:Int) = {
val (evens, odds) = 0 until N partition { x => x % 2 == 0 }
evens foreach { x => println("skipping " + x) }
odds
}
EDIT: To avoid printing the log messages after the partitioning is done, you can change the first line of the method like this:
val (evens, odds) = (0 until N).view.partition { x => x % 2 == 0 }

Integer partitioning in Scala

Given n ( say 3 people ) and s ( say 100$ ), we'd like to partition s among n people.
So we need all possible n-tuples that sum to s
My Scala code below:
def weights(n:Int,s:Int):List[List[Int]] = {
List.concat( (0 to s).toList.map(List.fill(n)(_)).flatten, (0 to s).toList).
combinations(n).filter(_.sum==s).map(_.permutations.toList).toList.flatten
}
println(weights(3,100))
This works for small values of n. ( n=1, 2, 3 or 4).
Beyond n=4, it takes a very long time, practically unusable.
I'm looking for ways to rework my code using lazy evaluation/ Stream.
My requirements : Must work for n upto 10.
Warning : The problem gets really big really fast. My results from Matlab -
---For s =100, n = 1 thru 5 results are ---
n=1 :1 combinations
n=2 :101 combinations
n=3 :5151 combinations
n=4 :176851 combinations
n=5: 4598126 combinations
---
You need dynamic programming, or memoization. Same concept, anyway.
Let's say you have to divide s among n. Recursively, that's defined like this:
def permutations(s: Int, n: Int): List[List[Int]] = n match {
case 0 => Nil
case 1 => List(List(s))
case _ => (0 to s).toList flatMap (x => permutations(s - x, n - 1) map (x :: _))
}
Now, this will STILL be slow as hell, but there's a catch here... you don't need to recompute permutations(s, n) for numbers you have already computed. So you can do this instead:
val memoP = collection.mutable.Map.empty[(Int, Int), List[List[Int]]]
def permutations(s: Int, n: Int): List[List[Int]] = {
def permutationsWithHead(x: Int) = permutations(s - x, n - 1) map (x :: _)
n match {
case 0 => Nil
case 1 => List(List(s))
case _ =>
memoP getOrElseUpdate ((s, n),
(0 to s).toList flatMap permutationsWithHead)
}
}
And this can be even further improved, because it will compute every permutation. You only need to compute every combination, and then permute that without recomputing.
To compute every combination, we can change the code like this:
val memoC = collection.mutable.Map.empty[(Int, Int, Int), List[List[Int]]]
def combinations(s: Int, n: Int, min: Int = 0): List[List[Int]] = {
def combinationsWithHead(x: Int) = combinations(s - x, n - 1, x) map (x :: _)
n match {
case 0 => Nil
case 1 => List(List(s))
case _ =>
memoC getOrElseUpdate ((s, n, min),
(min to s / 2).toList flatMap combinationsWithHead)
}
}
Running combinations(100, 10) is still slow, given the sheer numbers of combinations alone. The permutations for each combination can be obtained simply calling .permutation on the combination.
Here's a quick and dirty Stream solution:
def weights(n: Int, s: Int) = (1 until s).foldLeft(Stream(Nil: List[Int])) {
(a, _) => a.flatMap(c => Stream.range(0, n - c.sum + 1).map(_ :: c))
}.map(c => (n - c.sum) :: c)
It works for n = 6 in about 15 seconds on my machine:
scala> var x = 0
scala> weights(100, 6).foreach(_ => x += 1)
scala> x
res81: Int = 96560646
As a side note: by the time you get to n = 10, there are 4,263,421,511,271 of these things. That's going to take days just to stream through.
My solution of this problem, it can computer n till 6:
object Partition {
implicit def i2p(n: Int): Partition = new Partition(n)
def main(args : Array[String]) : Unit = {
for(n <- 1 to 6) println(100.partitions(n).size)
}
}
class Partition(n: Int){
def partitions(m: Int):Iterator[List[Int]] = new Iterator[List[Int]] {
val nums = Array.ofDim[Int](m)
nums(0) = n
var hasNext = m > 0 && n > 0
override def next: List[Int] = {
if(hasNext){
val result = nums.toList
var idx = 0
while(idx < m-1 && nums(idx) == 0) idx = idx + 1
if(idx == m-1) hasNext = false
else {
nums(idx+1) = nums(idx+1) + 1
nums(0) = nums(idx) - 1
if(idx != 0) nums(idx) = 0
}
result
}
else Iterator.empty.next
}
}
}
1
101
5151
176851
4598126
96560646
However , we can just show the number of the possible n-tuples:
val pt: (Int,Int) => BigInt = {
val buf = collection.mutable.Map[(Int,Int),BigInt]()
(s,n) => buf.getOrElseUpdate((s,n),
if(n == 0 && s > 0) BigInt(0)
else if(s == 0) BigInt(1)
else (0 to s).map{k => pt(s-k,n-1)}.sum
)
}
for(n <- 1 to 20) printf("%2d :%s%n",n,pt(100,n).toString)
1 :1
2 :101
3 :5151
4 :176851
5 :4598126
6 :96560646
7 :1705904746
8 :26075972546
9 :352025629371
10 :4263421511271
11 :46897636623981
12 :473239787751081
13 :4416904685676756
14 :38393094575497956
15 :312629484400483356
16 :2396826047070372396
17 :17376988841260199871
18 :119594570260437846171
19 :784008849485092547121
20 :4910371215196105953021