Warnsdorff’s algorithm for custom move in Scala - scala

I have written a program to find the list for move required to cover all square of the chessboard using Warnsdorff’s algorithm. it is perfectly working for 7x7 board but not working for board like 8x8, 10x10 or 16x16. Its goes on running for long. The below are the code. Please point out where I am going wrong.
object PawnTourMain {
def main(args: Array[ String ]): Unit = {
val kt = PawnTour(7)
kt.findTour(0, 1, 0)
kt.printSolution
}
class PawnTour(size: Int, board: Array[ Array[ Int ] ], possibleMoves: Array[ Array[ Array[ Point ] ] ]) {
val UNUSED = -1
def findTour(x: Int, y: Int, current: Int): Boolean = {
if (board(x)(y) != UNUSED) return false
//Mark current position as 'current'
board(x)(y) = current
if (current == size * size - 1) { //done :)
return true
}
for (d <- possibleMoves(x)(y)) {
if (findTour(d.x, d.y, current + 1)) return true
}
//if we are here, all our options ran out :(
//reset the current cell and return false
board(x)(y) = UNUSED
false
}
def printSolution: Unit = {
board foreach {
row =>
row foreach (number => print(number + " ")); println
}
}
}
case class Point(x: Int, y: Int)
object PawnTour {
val DIRECTIONS = Array(Point(3, 0), Point(-3, 0), Point(2, -2), Point(2, 2), Point(0, 3), Point(0, -3), Point(-2, -2), Point(2, 2))
def apply(n: Int): PawnTour = {
val board = Array.fill[ Int ](n, n)(-1)
val possibleMoves = Array.tabulate(n, n) { (x, y) =>
DIRECTIONS.flatMap { d =>
val nx = x + d.x
val ny = y + d.y
if ((nx >= 0 && nx < n) && (ny >= 0 && ny < n)) Option(Point(nx, ny)) else None
}
}
var x = 0
while (x < n) {
var y = 0
while (y < n) {
val moves: Array[ Point ] = possibleMoves(x)(y)
moves.sortBy((o1: Point) => possibleMoves(o1.x)(o1.y).size)
y += 1
println(moves.toList)
}
x += 1
}
new PawnTour(n, board, possibleMoves)
}
def printSolution(array: Array[ Array[ Int ] ]): Unit = {
array foreach {
row =>
row foreach (number => print(number + " ")); println
}
}
}
}

From Wikipedia
The knight is moved so that it always proceeds to the square from which the knight will have the fewest onward moves
Your implementation does not take into account already visited squares. It creates and sorts possible moves on empty board but forgets to update them when algorithm makes a move.
When square is visited you should remove it from possible moves and then reorder possible moves again

Related

Parallel FP Growth in Spark

I am trying to understand the "add" and "extract" methods of the FPTree class:
(https://github.com/apache/spark/blob/master/mllib/src/main/scala/org/apache/spark/mllib/fpm/FPGrowth.scala).
What is the purpose of 'summaries' variable?
where is the Group list?
I assume it is the following, am I correct:
val numParts = if (numPartitions > 0) numPartitions else data.partitions.length
val partitioner = new HashPartitioner(numParts)
What will 'summaries contain for 3 transactions of {a,b,c} , {a,b} , {b,c} where all are frequent?
def add(t: Iterable[T], count: Long = 1L): FPTree[T] = {
require(count > 0)
var curr = root
curr.count += count
t.foreach { item =>
val summary = summaries.getOrElseUpdate(item, new Summary)
summary.count += count
val child = curr.children.getOrElseUpdate(item, {
val newNode = new Node(curr)
newNode.item = item
summary.nodes += newNode
newNode
})
child.count += count
curr = child
}
this
}
def extract(
minCount: Long,
validateSuffix: T => Boolean = _ => true): Iterator[(List[T], Long)] = {
summaries.iterator.flatMap { case (item, summary) =>
if (validateSuffix(item) && summary.count >= minCount) {
Iterator.single((item :: Nil, summary.count)) ++
project(item).extract(minCount).map { case (t, c) =>
(item :: t, c)
}
} else {
Iterator.empty
}
}
}
After a bit experiments, it is pretty straight forward:
1+2) The partition is indeed the Group representative.
It is also how the conditional transactions calculated:
private def genCondTransactions[Item: ClassTag](
transaction: Array[Item],
itemToRank: Map[Item, Int],
partitioner: Partitioner): mutable.Map[Int, Array[Int]] = {
val output = mutable.Map.empty[Int, Array[Int]]
// Filter the basket by frequent items pattern and sort their ranks.
val filtered = transaction.flatMap(itemToRank.get)
ju.Arrays.sort(filtered)
val n = filtered.length
var i = n - 1
while (i >= 0) {
val item = filtered(i)
val part = partitioner.getPartition(item)
if (!output.contains(part)) {
output(part) = filtered.slice(0, i + 1)
}
i -= 1
}
output
}
The summaries is just a helper to save the count of items in transaction
The extract/project will generate the FIS by using up/down recursion and dependent FP-Trees (project), while checking summaries if traversal that path is needed.
summaries of node 'a' will have {b:2,c:1} and children of node 'a' are 'b' and 'c'.

scala tictactoe avoid mutable variable

I wrote a simple implementation of the tic tac toe game in scala.
package tiktaktoe
/**
* Created by donbeo on 28/12/15.
*/
class Board {
val size = 3
// size of the board
val goal = 3
// number in line. These values are assumed to be always 3 and 3
val board = Array.fill(size, size)(0) // the board
def isValidPosition(pos: Pos): Boolean = {
if (pos._1 >= 0 && pos._2 >= 0 && pos._1 < size && pos._2 < size && board(pos._1)(pos._2) == 0) true
else false
}
def setPosition(pos: Pos, number: Int): Unit = {
if (isValidPosition(pos)) {
board(pos._1)(pos._2) = number
println(this)
val winner = winningPlayer
if (winner != 0) println("The winner is: Player " + winner)
}
else throw new Exception("Not Valid Position")
}
def winningPlayer: Int = {
if (isLine(0) != 0) isLine(0)
if (isLine(1) != 0) isLine(1)
if (isLine(2) != 0) isLine(2)
if (isColumn(0) != 0) isColumn(0)
if (isColumn(1) != 0) isColumn(1)
if (isColumn(2) != 0) isColumn(2)
if (isDiagonal != 0) isDiagonal
else 0
}
private def isLine(line: Int): Int = {
// this works only if goal = size
val number = board(line)(0)
if (number == 0) return 0
else if (board(line) == Array.fill(size)(number)) return number
else 0
}
private def isColumn(column: Int): Int = {
val number = board(0)(column)
if (number == 0) 0
else if (board(1)(column) == number && board(2)(column) == number) number
else 0
}
private def isDiagonal: Int = {
val number = board(1)(1)
if (board(2)(2) == number && board(1)(1) == number) number
else if (board(0)(2) == number && board(2)(0) == number) number
else 0
}
override def toString = "Board=\n" + board.deep.mkString("\n") + "\n"
}
class Player(number: Int) {
private def computeNextMove(board: Board): Pos = {
(2, 3)
}
def nextMove(board: Board, pos: Pos): Unit = {
board.setPosition(pos, number)
}
}
object PlayGame {
def main(args: Array[String]) {
val board = new Board
val players = List(new Player(1), new Player(2))
println("Start the game \n\n" + board)
players(0).nextMove(board, (1, 0))
players(1).nextMove(board, (1, 1))
players(0).nextMove(board, (1, 2))
players(1).nextMove(board, (0, 0))
players(0).nextMove(board, (2, 1))
players(1).nextMove(board, (2, 2))
}
}
The game is based on the function Player.nextMove that modifies the status of the board. As far as I know it is better to avoid mutable variables in scala.
I am wondering how can I implement the game without using the mutable board

Copy top fifteen elements from one array to another one

I'm trying to make a simple one top fifteen with this code:
var top = Array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
val numbers = Array(4,5,8,1,33,23,45,6,11,10,87,46,43,66,55,98,78,71,19,20)
def getTop() : Unit = {
for ( i <- 0 to (numbers.length - 1)) {
set(0, numbers(i), top)
}
top.map(x => println(x))
}
def set(index: Int, number: Int, top: Array[Int]) : Unit = {
if (index <= top.length-1) {
if(top(index) < number) {
top(index) = number
}
else {
set(index+1, number, top)
}
}
}
The function should copy the top fifteen elements that are in the array numbers to array top, but currently I get only:
98,78,71,20,0,0,0,0,0,0,0,0,0,0,0
What am I doing wrong?
Your code doesn't work because you overriding previously set numbers:
top = Array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) //initially
top = Array(4,0,0,0,0,0,0,0,0,0,0,0,0,0,0) // let's call set for '4'
top = Array(5,0,0,0,0,0,0,0,0,0,0,0,0,0,0) // now for 5 ...
top = Array(8,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
top = Array(8,1,0,0,0,0,0,0,0,0,0,0,0,0,0)
....
You can fix it with adjacent placing number you're replacing to the right place:
val top = Array.fill(15)(0)
val numbers = Array(4,5,8,1,33,23,45,6,11,10,87,46,43,66,55,98,78,71,19,20)
def printTop() : Unit = {
for (n <- numbers) {
set(0, n, top)
}
top.foreach(x => println(x))
}
def set(index: Int, number: Int, top: Array[Int]) : Unit = {
if (index < top.length) {
val current = top(index)
if(current < number) {
top(index) = number
set(index+1, current, top) // send replaced number down the street
}
else {
set(index+1, number, top)
}
}
}

Palindromes using Scala

I came across this problem from CodeChef. The problem states the following:
A positive integer is called a palindrome if its representation in the
decimal system is the same when read from left to right and from right
to left. For a given positive integer K of not more than 1000000
digits, write the value of the smallest palindrome larger than K to
output.
I can define a isPalindrome method as follows:
def isPalindrome(someNumber:String):Boolean = someNumber.reverse.mkString == someNumber
The problem that I am facing is how do I loop from the initial given number and break and return the first palindrome when the integer satisfies the isPalindrome method? Also, is there a better(efficient) way to write the isPalindrome method?
It will be great to get some guidance here
If you have a number like 123xxx you know, that either xxx has to be below 321 - then the next palindrom is 123321.
Or xxx is above, then the 3 can't be kept, and 124421 has to be the next one.
Here is some code without guarantees, not very elegant, but the case of (multiple) Nines in the middle is a bit hairy (19992):
object Palindrome extends App {
def nextPalindrome (inNumber: String): String = {
val len = inNumber.length ()
if (len == 1 && inNumber (0) != '9')
"" + (inNumber.toInt + 1) else {
val head = inNumber.substring (0, len/2)
val tail = inNumber.reverse.substring (0, len/2)
val h = if (head.length > 0) BigInt (head) else BigInt (0)
val t = if (tail.length > 0) BigInt (tail) else BigInt (0)
if (t < h) {
if (len % 2 == 0) head + (head.reverse)
else inNumber.substring (0, len/2 + 1) + (head.reverse)
} else {
if (len % 2 == 1) {
val s2 = inNumber.substring (0, len/2 + 1) // 4=> 4
val h2 = BigInt (s2) + 1 // 5
nextPalindrome (h2 + (List.fill (len/2) ('0').mkString)) // 5 + ""
} else {
val h = BigInt (head) + 1
h.toString + (h.toString.reverse)
}
}
}
}
def check (in: String, expected: String) = {
if (nextPalindrome (in) == expected)
println ("ok: " + in) else
println (" - fail: " + nextPalindrome (in) + " != " + expected + " for: " + in)
}
//
val nums = List (("12345", "12421"), // f
("123456", "124421"),
("54321", "54345"),
("654321", "654456"),
("19992", "20002"),
("29991", "29992"),
("999", "1001"),
("31", "33"),
("13", "22"),
("9", "11"),
("99", "101"),
("131", "141"),
("3", "4")
)
nums.foreach (n => check (n._1, n._2))
println (nextPalindrome ("123456678901234564579898989891254392051039410809512345667890123456457989898989125439205103941080951234566789012345645798989898912543920510394108095"))
}
I guess it will handle the case of a one-million-digit-Int too.
Doing reverse is not the greatest idea. It's better to start at the beginning and end of the string and iterate and compare element by element. You're wasting time copying the entire String and reversing it even in cases where the first and last element don't match. On something with a million digits, that's going to be a huge waste.
This is a few orders of magnitude faster than reverse for bigger numbers:
def isPalindrome2(someNumber:String):Boolean = {
val len = someNumber.length;
for(i <- 0 until len/2) {
if(someNumber(i) != someNumber(len-i-1)) return false;
}
return true;
}
There's probably even a faster method, based on mirroring the first half of the string. I'll see if I can get that now...
update So this should find the next palindrome in almost constant time. No loops. I just sort of scratched it out, so I'm sure it can be cleaned up.
def nextPalindrome(someNumber:String):String = {
val len = someNumber.length;
if(len==1) return "11";
val half = scala.math.floor(len/2).toInt;
var firstHalf = someNumber.substring(0,half);
var secondHalf = if(len % 2 == 1) {
someNumber.substring(half+1,len);
} else {
someNumber.substring(half,len);
}
if(BigInt(secondHalf) > BigInt(firstHalf.reverse)) {
if(len % 2 == 1) {
firstHalf += someNumber.substring(half, half+1);
firstHalf = (BigInt(firstHalf)+1).toString;
firstHalf + firstHalf.substring(0,firstHalf.length-1).reverse
} else {
firstHalf = (BigInt(firstHalf)+1).toString;
firstHalf + firstHalf.reverse;
}
} else {
if(len % 2 == 1) {
firstHalf + someNumber.substring(half,half+1) + firstHalf.reverse;
} else {
firstHalf + firstHalf.reverse;
}
}
}
This is most general and clear solution that I can achieve:
Edit: got rid of BigInt's, now it takes less than a second to calculate million digits number.
def incStr(num: String) = { // helper method to increment number as String
val idx = num.lastIndexWhere('9'!=, num.length-1)
num.take(idx) + (num.charAt(idx)+1).toChar + "0"*(num.length-idx-1)
}
def palindromeAfter(num: String) = {
val lengthIsOdd = num.length % 2
val halfLength = num.length / 2 + lengthIsOdd
val leftHalf = num.take(halfLength) // first half of number (including central digit)
val rightHalf = num.drop(halfLength - lengthIsOdd) // second half of number (also including central digit)
val (newLeftHalf, newLengthIsOdd) = // we need to calculate first half of new palindrome and whether it's length is odd or even
if (rightHalf.compareTo(leftHalf.reverse) < 0) // simplest case - input number is like 123xxx and xxx < 321
(leftHalf, lengthIsOdd)
else if (leftHalf forall ('9'==)) // special case - if number is like '999...', then next palindrome will be like '10...01' and one digit longer
("1" + "0" * (halfLength - lengthIsOdd), 1 - lengthIsOdd)
else // other cases - increment first half of input number before making palindrome
(incStr(leftHalf), lengthIsOdd)
// now we can create palindrome itself
newLeftHalf + newLeftHalf.dropRight(newLengthIsOdd).reverse
}
According to your range-less proposal: the same thing but using Stream:
def isPalindrome(n:Int):Boolean = n.toString.reverse == n.toString
def ints(n: Int): Stream[Int] = Stream.cons(n, ints(n+1))
val result = ints(100).find(isPalindrome)
And with iterator (and different call method, the same thing you can do with Stream, actually):
val result = Iterator.from(100).find(isPalindrome)
But as #user unknown stated, it is direct bruteforce and not practical with large numbers.
To check if List of Any Type is palindrome using slice, without any Loops
def palindrome[T](list: List[T]): Boolean = {
if(list.length==1 || list.length==0 ){
false
}else {
val leftSlice: List[T] = list.slice(0, list.length / 2)
var rightSlice :List[T]=Nil
if (list.length % 2 != 0) {
rightSlice = list.slice(list.length / 2 + 1, list.length).reverse
} else {
rightSlice = list.slice(list.length / 2, list.length).reverse
}
leftSlice ==rightSlice
}
}
Though the simplest solution would be
def palindrome[T](list: List[T]): Boolean = {
list == list.reverse
}
You can simply use the find method on collections to find the first element matching a given predicate:
def isPalindrome(n:Int):Boolean = n.toString.reverse == n.toString
val (start, end) = (100, 1000)
val result: Option[Int] = (start to end).find(isPalindrome)
result foreach println
>Some(101)
Solution to verify if a String is a palindrome
This solution doesn't reverse the String. However I am not sure that it will be faster.
def isPalindrome(s:String):Boolean = {
s.isEmpty ||
((s.last == s.head) && isPalindrome(s.tail.dropRight(1)))
}
Solution to find next palindrome given a String
This solution is not the best for scala (pretty the same as Java solution) but it only deals with Strings and is suitable for large numbers
You just have to mirror the first half of the number you want, check if it is higher than the begin number, otherwise, increase by one the last digit of the first half and mirror it again.
First, a function to increment the string representation of an int by 1:
def incrementString(s:String):String = {
if(s.nonEmpty){
if (s.last == '9')
incrementString(s.dropRight(1))+'0'
else
s.dropRight(1) + (s.last.toInt +1).toChar
}else
"1"
}
Then, a function to compare to string representation of ints: (the function 'compare' doesn't work for that case)
/* is less that 0 if x<y, is more than 0 if x<y, is equal to 0 if x==y */
def compareInts(x:String, y:String):Int = {
if (x.length !=y.length)
(x.length).compare(y.length)
else
x.compare(y)
}
Now the function to compute the next palindrome:
def nextPalindrome(origin_ :String):String = {
/*Comment if you want to have a strictly bigger number, even if you already have a palindrome as input */
val origin = origin_
/* Uncomment if you want to have a strictly bigger number, even if you already have a palindrome as input */
//val origin = incrementString(origin_)
val length = origin.length
if(length % 2 == 0){
val (first, last) = origin.splitAt(length/2);
val reversed = first.reverse
if (compareInts(reversed,last) > -1)
first ++ reversed
else{
val firstIncr = incrementString(first)
firstIncr ++ firstIncr.reverse
}
} else {
val (first,last) = origin.splitAt((length+1)/2)
val reversed = first.dropRight(1).reverse
if (compareInts(reversed,last) != -1)
first ++ reversed
else{
val firstIncr = incrementString(first)
firstIncr ++ firstIncr.dropRight(1).reverse
}
}
}
You could try something like this, I'm using basic recursive:
object Palindromo {
def main(args: Array[String]): Unit = {
var s: String = "arara"
println(verificaPalindromo(s))
}
def verificaPalindromo(s: String): String = {
if (s.length == 0 || s.length == 1)
"true"
else
if (s.charAt(0).toLower == s.charAt(s.length - 1).toLower)
verificaPalindromo(s.substring(1, s.length - 1))
else
"false"
}
}
#tailrec
def palindrome(str: String, start: Int, end: Int): Boolean = {
if (start == end)
true
else if (str(start) != str(end))
false
else
pali(str, start + 1, end - 1)
}
println(palindrome("arora", 0, str.length - 1))

Finite Growable Array in Scala

I would like to be able to grow an Array-like structure up to a maximum size, after which the oldest (1st) element would be dropped off the structure every time a new element is added. I don't know what the best way to do this is, but one way would be to extend the ArrayBuffer class, and override the += operator so that if the maximum size has been reached, the first element is dropped every time a new one is added. I haven't figured out how to properly extend collections yet. What I have so far is:
class FiniteGrowableArray[A](maxLength:Int) extends scala.collection.mutable.ArrayBuffer {
override def +=(elem:A): <insert some return type here> = {
// append element
if(length > maxLength) remove(0)
<returned collection>
}
}
Can someone suggest a better path and/or help me along this one? NOTE: I will need to arbitrarily access elements within the structure multiple times in between the += operations.
Thanks
As others have discussed, you want a ring buffer. However, you also have to decide if you actually want all of the collections methods or not, and if so, what happens when you filter a ring buffer of maximum size N--does it keep its maximum size, or what?
If you're okay with merely being able to view your ring buffer as part of the collections hierarchy (but don't want to use collections efficiently to generate new ring buffers) then you can just:
class RingBuffer[T: ClassManifest](maxsize: Int) {
private[this] val buffer = new Array[T](maxsize+1)
private[this] var i0,i1 = 0
private[this] def i0up = { i0 += 1; if (i0>=buffer.length) i0 -= buffer.length }
private[this] def i0dn = { i0 -= 1; if (i0<0) i0 += buffer.length }
private[this] def i1up = { i1 += 1; if (i1>=buffer.length) i1 -= buffer.length }
private[this] def i1dn = { i1 -= 1; if (i1<0) i1 += buffer.length }
private[this] def me = this
def apply(i: Int) = {
val j = i+i0
if (j >= buffer.length) buffer(j-buffer.length) else buffer(j)
}
def size = if (i1<i0) buffer.length+i1-i0 else i1-i0
def :+(t: T) = {
buffer(i1) = t
i1up; if (i1==i0) i0up
this
}
def +:(t: T) = {
i0dn; if (i0==i1) i1dn
buffer(i0) = t
this
}
def popt = {
if (i1==i0) throw new java.util.NoSuchElementException
i1dn; buffer(i1)
}
def poph = {
if (i1==i0) throw new java.util.NoSuchElementException
val ans = buffer(i0); i0up; ans
}
def seqView = new IndexedSeq[T] {
def apply(i: Int) = me(i)
def length = me.size
}
}
Now you can use this easily directly, and you can jump out to IndexedSeq when needed:
val r = new RingBuffer[Int](4)
r :+ 7 :+ 9 :+ 2
r.seqView.mkString(" ") // Prints 7 9 2
r.popt // Returns 2
r.poph // Returns 7
r :+ 6 :+ 5 :+ 4 :+ 3
r.seqView.mkString(" ") // Prints 6 5 4 3 -- 7 fell off the end
0 +: 1 +: 2 +: r
r.seqView.mkString(" ") // Prints 0 1 2 6 -- added to front; 3,4,5 fell off
r.seqView.filter(_>1) // Vector(2,6)
and if you want to put things back into a ring buffer, you can
class RingBufferImplicit[T: ClassManifest](ts: Traversable[T]) {
def ring(maxsize: Int) = {
val rb = new RingBuffer[T](maxsize)
ts.foreach(rb :+ _)
rb
}
}
implicit def traversable2ringbuffer[T: ClassManifest](ts: Traversable[T]) = {
new RingBufferImplicit(ts)
}
and then you can do things like
val rr = List(1,2,3,4,5).ring(4)
rr.seqView.mkString(" ") // Prints 2,3,4,5