how to build a tree then traverse every leaf (from root node to leaf every time)? - algorithm

there is a file content as below("1.txt")
1.txt :
a,b
b,c
c,d
c,e
a,i
a,f
f,g
f,h
the tree structure like:
a
b i f
c g h
d e
expected:
a->b->c->d
a->b->c->e
a->i
a->f->g
a->f->h

This should work. I have skipped the part where the tree is built from reading the text file since it is simple enough.
case class Node(node: String, children: Seq[Node] = Seq()) {
override def equals(that: Any): Boolean =
that match {
case that: Node if this.node == that.node => true
case _ => false
}
override def toString = node
}
val d= Node("d")
val e = Node("e")
val g = Node("g")
val h = Node("h")
val i = Node("i")
val c = Node("c", Seq(d,e))
val f = Node("f", Seq(g, h))
val b = Node("b", Seq(c))
val a = Node("a", Seq(b,f,i))
val tree = a :: b :: c :: d :: e :: f :: g :: h :: i :: Nil
def traverse(tree: Seq[Node]): Seq[Seq[Node]] = {
import scala.annotation.tailrec
val leafNodes = tree.filter(x => x.children.isEmpty)
#tailrec
def walk(node: Node, descendants: Seq[Node] = Seq()): Seq[Node] = {
tree.find(x => x.children.contains(node)) match {
case Some(x) => walk(x, (descendants :+ node))
case None => descendants :+ node
}
}
leafNodes.map(walk(_, Seq()).reverse)
}
output:
scala> traverse(tree)
res26: Seq[Seq[Node]] = List(List(a, b, c, d), List(a, b, c, e), List(a, f, g), List(a, f, h), List(a, i))

Related

Scala how to define an ordering for Rationals

I have to implement compareRationals as something like
(a, b) => {
the body goes here
}
to compare to fractions, transform them so they both have the same denominator, then order the two results by their numerator to make sure they have the same denominator, need to find out the Least Common Denominator so my code works for println(insertionSort2(List(rationals))) and currently works for all the println statements besides that. I really need help to define compareRationals so println(insertionSort2(List(rationals))) shouldBe List(fourth, third, half)
Object {
def insertionSort2[A](xs: List[A])(implicit ord: Ordering[A]): List[A] = {
def insert2(y: A, ys: List[A]): List[A] =
ys match {
case List() => y :: List()
case z :: zs =>
if (ord.lt(y, z)) y :: z :: zs
else z :: insert2(y, zs)
}
xs match {
case List() => List()
case y :: ys => insert2(y, insertionSort2(ys))
}
}
class Rational(x: Int, y: Int) {
private def gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b)
private val g = gcd(x, y)
lazy val numer: Int = x / g
lazy val denom: Int = y / g
}
val compareRationals: (Rational, Rational) => Int =
implicit val rationalOrder: Ordering[Rational] =
new Ordering[Rational] {
def compare(x: Rational, y: Rational): Int = compareRationals(x, y)
}
def main(args: Array[String]): Unit = {
val half = new Rational(1, 2)
val third = new Rational(1, 3)
val fourth = new Rational(1, 4)
val rationals = List(third, half, fourth)
println(insertionSort2(List(4,2,9,5,8))(Ordering.Int))
println(insertionSort2(List(4,2,9,5,8)))
println(insertionSort2(List(rationals)))
}
}
}
I think this is all you need.
val compareRationals: (Rational, Rational) => Int =
(x,y) => x.numer * y.denom - y.numer * x.denom

Tail recursive solution in Scala for Linked-List chaining

I wanted to write a tail-recursive solution for the following problem on Leetcode -
You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contains a single digit. Add the two numbers and return it as a linked list.
You may assume the two numbers do not contain any leading zero, except the number 0 itself.
Example:
*Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)*
*Output: 7 -> 0 -> 8*
*Explanation: 342 + 465 = 807.*
Link to the problem on Leetcode
I was not able to figure out a way to call the recursive function in the last line.
What I am trying to achieve here is the recursive calling of the add function that adds the heads of the two lists with a carry and returns a node. The returned node is chained with the node in the calling stack.
I am pretty new to scala, I am guessing I may have missed some useful constructs.
/**
* Definition for singly-linked list.
* class ListNode(_x: Int = 0, _next: ListNode = null) {
* var next: ListNode = _next
* var x: Int = _x
* }
*/
import scala.annotation.tailrec
object Solution {
def addTwoNumbers(l1: ListNode, l2: ListNode): ListNode = {
add(l1, l2, 0)
}
//#tailrec
def add(l1: ListNode, l2: ListNode, carry: Int): ListNode = {
var sum = 0;
sum = (if(l1!=null) l1.x else 0) + (if(l2!=null) l2.x else 0) + carry;
if(l1 != null || l2 != null || sum > 0)
ListNode(sum%10,add(if(l1!=null) l1.next else null, if(l2!=null) l2.next else null,sum/10))
else null;
}
}
You have a couple of problems, which can mostly be reduced as being not idiomatic.
Things like var and null are not common in Scala and usually, you would use a tail-recursive algorithm to avoid that kind of things.
Finally, remember that a tail-recursive algorithm requires that the last expression is either a plain value or a recursive call. For doing that, you usually keep track of the remaining job as well as an accumulator.
Here is a possible solution:
type Digit = Int // Refined [0..9]
type Number = List[Digit] // Refined NonEmpty.
def sum(n1: Number, n2: Number): Number = {
def aux(d1: Digit, d2: Digit, carry: Digit): (Digit, Digit) = {
val tmp = d1 + d2 + carry
val d = tmp % 10
val c = tmp / 10
d -> c
}
#annotation.tailrec
def loop(r1: Number, r2: Number, acc: Number, carry: Digit): Number =
(r1, r2) match {
case (d1 :: tail1, d2 :: tail2) =>
val (d, c) = aux(d1, d2, carry)
loop(r1 = tail1, r2 = tail2, d :: acc, carry = c)
case (Nil, d2 :: tail2) =>
val (d, c) = aux(d1 = 0, d2, carry)
loop(r1 = Nil, r2 = tail2, d :: acc, carry = c)
case (d1 :: tail1, Nil) =>
val (d, c) = aux(d1, d2 = 0, carry)
loop(r1 = tail1, r2 = Nil, d :: acc, carry = c)
case (Nil, Nil) =>
acc
}
loop(r1 = n1, r2 = n2, acc = List.empty, carry = 0).reverse
}
Now, this kind of recursions tends to be very verbose.
Usually, the stdlib provide ways to make this same algorithm more concise:
// This is a solution that do not require the numbers to be already reversed and the output is also in the correct order.
def sum(n1: Number, n2: Number): Number = {
val (result, carry) = n1.reverseIterator.zipAll(n2.reverseIterator, 0, 0).foldLeft(List.empty[Digit] -> 0) {
case ((acc, carry), (d1, d2)) =>
val tmp = d1 + d2 + carry
val d = tmp % 10
val c = tmp / 10
(d :: acc) -> c
}
if (carry > 0) carry :: result else result
}
Scala is less popular on LeetCode, but this Solution (which is not the best) would get accepted by LeetCode's online judge:
import scala.collection.mutable._
object Solution {
def addTwoNumbers(listA: ListNode, listB: ListNode): ListNode = {
var tempBufferA: ListBuffer[Int] = ListBuffer.empty
var tempBufferB: ListBuffer[Int] = ListBuffer.empty
tempBufferA.clear()
tempBufferB.clear()
def listTraversalA(listA: ListNode): ListBuffer[Int] = {
if (listA == null) {
return tempBufferA
} else {
tempBufferA += listA.x
listTraversalA(listA.next)
}
}
def listTraversalB(listB: ListNode): ListBuffer[Int] = {
if (listB == null) {
return tempBufferB
} else {
tempBufferB += listB.x
listTraversalB(listB.next)
}
}
val resultA: ListBuffer[Int] = listTraversalA(listA)
val resultB: ListBuffer[Int] = listTraversalB(listB)
val resultSum: BigInt = BigInt(resultA.reverse.mkString) + BigInt(resultB.reverse.mkString)
var listNodeResult: ListBuffer[ListNode] = ListBuffer.empty
val resultList = resultSum.toString.toList
var lastListNode: ListNode = null
for (i <-0 until resultList.size) {
if (i == 0) {
lastListNode = new ListNode(resultList(i).toString.toInt)
listNodeResult += lastListNode
} else {
lastListNode = new ListNode(resultList(i).toString.toInt, lastListNode)
listNodeResult += lastListNode
}
}
return listNodeResult.reverse(0)
}
}
References
For additional details, you can see the Discussion Board. There are plenty of accepted solutions, explanations, efficient algorithms with a variety of languages, and time/space complexity analysis in there.

How to get a termination reason from a recursive function?

Suppose a function is looped to produce a numeric result. The looping is stopped either if the iterations maximum is reached or the "optimality" condition is met. In either case, the value from the current loop is output. What is a functional way to get both this result and the stopping reason?
For illustration, here's my Scala implementation of the "Square Roots" example in 4.1 of https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf.
object SquareRootAlg {
def next(a: Double)(x: Double): Double = (x + a/x)/2
def repeat[A](f: A=>A, a: A): Stream[A] = a #:: repeat(f, f(a))
def loopConditional[A](stop: (A, A) => Boolean)(s: => Stream[A] ): A = s match {
case a #:: t if t.isEmpty => a
case a #:: t => if (stop(a, t.head)) t.head else loopConditional(stop)(t)}
}
Eg, to find the square root of 4:
import SquareRootAlg._
val cond = (a: Double, b: Double) => (a-b).abs < 0.01
val alg = loopConditional(cond) _
val s = repeat(next(4.0), 4.0)
alg(s.take(3)) // = 2.05, "maxIters exceeded"
alg(s.take(5)) // = 2.00000009, "optimality reached"
This code works, but doesn't give me the stopping reason. So
I'm trying to write a method
def loopConditionalInfo[A](stop: (A, A)=> Boolean)(s: => Stream[A]): (A, Boolean)
outputting (2.05, false) in the first case above, and (2.00000009, true) in the second. Is there a way to write this method without modifying the next and repeat methods? Or would another functional approach work better?
Typically, you need to return a value that includes both a stopping reason and the result. Using the (A, Boolean) return signature you propose allows for this.
Your code would then become:
import scala.annotation.tailrec
object SquareRootAlg {
def next(a: Double)(x: Double): Double = (x + a/x)/2
def repeat[A](f: A=>A, a: A): Stream[A] = a #:: repeat(f, f(a))
#tailrec // Checks function is truly tail recursive.
def loopConditional[A](stop: (A, A) => Boolean)(s: => Stream[A] ): (A, Boolean) = {
val a = s.head
val t = s.tail
if(t.isEmpty) (a, false)
else if(stop(a, t.head)) (t.head, true)
else loopConditional(stop)(t)
}
}
Just return the booleans without modifying anything else:
object SquareRootAlg {
def next(a: Double)(x: Double): Double = (x + a/x)/2
def repeat[A](f: A => A, a: A): Stream[A] = a #:: repeat(f, f(a))
def loopConditionalInfo[A]
(stop: (A, A)=> Boolean)
(s: => Stream[A])
: (A, Boolean) = s match {
case a #:: t if t.isEmpty => (a, false)
case a #:: t =>
if (stop(a, t.head)) (t.head, true)
else loopConditionalInfo(stop)(t)
}
}
import SquareRootAlg._
val cond = (a: Double, b: Double) => (a-b).abs < 0.01
val alg = loopConditionalInfo(cond) _
val s = repeat(next(4.0), 4.0)
println(alg(s.take(3))) // = 2.05, "maxIters exceeded"
println(alg(s.take(5)))
prints
(2.05,false)
(2.0000000929222947,true)

Boost:Graph recursive traverse and graph-copy

I had some first experience with creating and traversing
graphs. But now I have a problem, of which I don't now,
if boost::graph has some algorithms to solve it.
Here is my graph-definition:
const int _AND = 1001;
const int _OR = 1002;
const int _ITEM = 1003;
struct gEdgeProperties
{
string label;
};
struct gVertexProperties
{
string label;
int typ; // _AND, _OR, ITEM
};
typedef adjacency_list< vecS, vecS, undirectedS, gVertexProperties, gEdgeProperties>
BGraph;
So BGraph contains items and logical relations between them.
Now I would like to transform this graph into multiple graphs,
each of which should contains NO or-relations, but represent
all by the OR-vertices defind combinatorial alternates
of items and their AND-relations.
An example: if there are three items A, B, C
related so: A AND ( B OR C)
then the result of the traversal should be two graphs,
containing the following combinations:
(1) A AND B
(2) A AND C
My (simple) idea now is to traverse the graph, and each time
the traversal finds an OR-vertex, to copy the whole
graph and follow from there on each part of the OR-node recursive:
if graph[vertex] == OR {
for (... // each child vertex of vertex
BGraph newGraph = copy(Graph);
traverse(newGraph,childVertex);
}
}
This won't work correctly, because my recursive call of each child
would miss the stack structure (the information, how to come back upwards
in the graph). This means: the traversal would climb down correct,
but not upwards again.
I have no idea, if there is a more (or at all) efficient way to solve such
a problem with boost::graph and its embedded algorithms.
But to me it seems to be an interesting problem, so I would like to
discuss it here, maybe it leads to a deeper insight of boost::graph.
Thank you!
My overall approach would be to do a depth-first walk of the input graph, and construct the output graphs bottom-up. Because you want to construct an arbitrary number of graphs, the traversal function has to return a list of graphs.
So here's an algorithm in pseudo-code
-- syntax: [xxx,xxx,...] is a list, and (xxx AND yyy) is a node.
traverse (node):
if typeof(node) == term
return [ node ]
else
leftlist = traverse(node.left)
rightlist = traverse(node.right)
if node.condition == OR
result = leftlist .appendAll( rightlist )
else if node.condition == AND
result = [ ]
foreach left in leftlist
foreach right in rightlist
result .append( (left AND right) )
else
panic("unknown condition")
return result
For example: pass in ((A OR B) AND (C OR D))
The individual terms compile to simple lists:
A -> [A]
B -> [B]
C -> [C]
D -> [D]
The OR conditions simply become parallel queries:
(A OR B) -> [A] OR [B] -> [A, B]
(C OR D) -> [C] OR [D] -> [C, D]
The AND condition must be combined in all possible permutations:
(... AND ...) -> [A, B] AND [C, D] ->
[(A AND C), (A AND D), (B AND C), (B AND D)]
Hope this helps. If you cast it into C++, you'll have to take care of housekeeping, i.e., destroying intermediate list objects after they are no longer needed.
Here the adoption to python as addition (Thanks again, it works great!!!):
_AND = 1
_OR = 2
_ITEM = 3
class Node:
def __init__(self, name):
self.name = name
self.condition = _ITEM
self.left = None
self.right = None
def showList(aList):
for node in aList:
print " elem cond: " , node.condition, " left: ", node.left.name, " right: ", node.right.name
def traverse (node):
leftlist = None
if node.condition == _ITEM:
return [ node ]
else:
leftlist = traverse(node.left)
rightlist = traverse(node.right)
found = 0
if node.condition == _OR:
found = 1
result = leftlist
for right in rightlist:
result.append(right)
else:
if node.condition == _AND:
found = 1
result = [ ]
for left in leftlist:
for right in rightlist:
newNode = Node(left.name + "_AND_" + right.name)
newNode.left = left
newNode.right = right
result.append(newNode)
if (found != 1):
print "unknown condition"
raise Exception("unknown condition")
return result
#EXAMPLE ((A OR B) AND (C OR D)):
node1 = Node("A")
node2 = Node("B")
node3 = Node("C")
node4 = Node("D")
node12 = Node("A_or_B")
node12.condition = _OR;
node12.left = node1
node12.right = node2
node34 = Node("C_or_D")
node34.condition = _OR;
node34.left = node3
node34.right = node4
root = Node("root")
root.condition = _AND;
root.left = node12
root.right = node34
aList = traverse(root)
showList(aList)

Compute median of up to 5 in Scala

So, while answering some other question I stumbled upon the necessity of computing the median of 5. Now, there's a similar question in another language, but I want a Scala algorithm for it, and I'm not sure I'm happy with mine.
Here's an immutable Scala version that has the minimum number of compares (6) and doesn't look too ugly:
def med5(five: (Int,Int,Int,Int,Int)) = {
// Return a sorted tuple (one compare)
def order(a: Int, b: Int) = if (a<b) (a,b) else (b,a)
// Given two self-sorted pairs, pick the 2nd of 4 (two compares)
def pairs(p: (Int,Int), q: (Int,Int)) = {
(if (p._1 < q._1) order(p._2,q._1) else order(q._2,p._1))._1
}
// Strategy is to throw away smallest or second smallest, leaving two self-sorted pairs
val ltwo = order(five._1,five._2)
val rtwo = order(five._4,five._5)
if (ltwo._1 < rtwo._1) pairs(rtwo,order(ltwo._2,five._3))
else pairs(ltwo,order(rtwo._2,five._3))
}
Edit: As requested by Daniel, here's a modification to work with all sizes, and in arrays so it should be efficient. I can't make it pretty, so efficiency is the next best thing. (>200M medians/sec with a pre-allocated array of 5, which is slightly more than 100x faster than Daniel's version, and 8x faster than my immutable version above (for lengths of 5)).
def med5b(five: Array[Int]): Int = {
def order2(a: Array[Int], i: Int, j: Int) = {
if (a(i)>a(j)) { val t = a(i); a(i) = a(j); a(j) = t }
}
def pairs(a: Array[Int], i: Int, j: Int, k: Int, l: Int) = {
if (a(i)<a(k)) { order2(a,j,k); a(j) }
else { order2(a,i,l); a(i) }
}
if (five.length < 2) return five(0)
order2(five,0,1)
if (five.length < 4) return (
if (five.length==2 || five(2) < five(0)) five(0)
else if (five(2) > five(1)) five(1)
else five(2)
)
order2(five,2,3)
if (five.length < 5) pairs(five,0,1,2,3)
else if (five(0) < five(2)) { order2(five,1,4); pairs(five,1,4,2,3) }
else { order2(five,3,4); pairs(five,0,1,3,4) }
}
Jeez, way to over-think it, guys.
def med5(a : Int, b: Int, c : Int, d : Int, e : Int) =
List(a, b, c, d, e).sort(_ > _)(2)
As suggested, here's my own algorithm:
def medianUpTo5(arr: Array[Double]): Double = {
def oneAndOrderedPair(a: Double, smaller: Double, bigger: Double): Double =
if (bigger < a) bigger
else if (a < smaller) smaller else a
def partialOrder(a: Double, b: Double, c: Double, d: Double) = {
val (s1, b1) = if (a < b) (a, b) else (b, a)
val (s2, b2) = if (c < d) (c, d) else (d, c)
(s1, b1, s2, b2)
}
def medianOf4(a: Double, b: Double, c: Double, d: Double): Double = {
val (s1, b1, s2, b2) = partialOrder(a, b, c, d)
if (b1 < b2) oneAndOrderedPair(s2, s1, b1)
else oneAndOrderedPair(s1, s2, b2)
}
arr match {
case Array(a) => a
case Array(a, b) => a min b
case Array(a, b, c) =>
if (a < b) oneAndOrderedPair(c, a, b)
else oneAndOrderedPair(c, b, a)
case Array(a, b, c, d) => medianOf4(a, b, c, d)
case Array(a, b, c, d, e) =>
val (s1, b1, s2, b2) = partialOrder(a, b, c, d)
if (s1 < s2) medianOf4(e, b1, s2, b2)
else medianOf4(e, b2, s1, b1)
}
}

Resources