Scala Tree/Graph Implementation - algorithm

I have a problem about a "customer invitation" where a person can invite another person and the invitation is only valid if the invited person invitee someone.
To solve this problem, i was thinking to write a Tree algorithm instead a Graph algorithm.
I'm trying to write this tree structure in Scala and here is how i've started:
case class MyNode(key:Int, children:Option[List[MyNode]] = None)
class MyNodeManager {
def find(key: Int, tree: Option[List[MyNode]]) = tree match {
case None => None
case (h :: t) =>
println("aa")
/*if(h.key == key)
Option(h)
else
find(h ::: t)
*/
}
}
The input will be something like:
val invites = List((1, 2), (1, 3), (3, 6))
I would like to work with Option[List[MyNode]] because children are option and if the node has been invited, i would like to set value an empty list instead None.
Tree is the best structure to solve my problem or should i go to Graph or something like that (a node in a graph can have multiple children?)? And the other question..what's the difference on those lines (h :: t) and (h ::: t)?
The following code has a compile error:
Error:(16, 13) constructor cannot be instantiated to expected type;
found : scala.collection.immutable.::[B]
required: Option[List[MyNode]]
case (h :: t) =>
^
How can i work with Option[List]?

Should be
def find(key: Int, tree: Option[List[MyNode]]) = tree match {
case None => None
case Some(h :: t) =>
println("aa")
/*if(h.key == key)
Option(h)
else
find(h ::: t)
*/}
You are match Option object not tuple.
This match is not exhaustive because you are missing
case Some(Nil) => ....
I find it will be better to use only list without Optional. This is mostly about semantic. Optional means something is empty. We have value for empty list (Nil) so we don't need to use additional object to mark such situation. Empty list should be enough
::: function adds the elements of a given list in front of your list. Simply this function is used to concatenate two list
:: is function which add element at the begging of the list.
Also in Scala :: is a case class which have head and tail. If you want to know more about List implementation I suggest you to read https://www.amazon.com/Functional-Programming-Scala-Paul-Chiusano/dp/1617290653

Related

Getting the Shorest Path question right in Kotlin

So I got a question that was delivered as a 2D List
val SPE = listOf(
listOf('w', 'x'),
listOf('x', 'y'),
listOf('z', 'y'),
listOf('z', 'v'),
listOf('w', 'v')
)
It asks to find the shortest path between w and z. So obviously, BFS would be the best course of action here to find that path the fastest. Here's my code for it
fun shortestPath(edges: List<List<Char>>, root: Char, destination: Char): Int {
val graph = buildGraph3(edges)
val visited = hashSetOf(root)
val queue = mutableListOf(mutableListOf(root, 0))
while (queue.size > 0){
val node = queue[0].removeFirst()
val distance = queue[0].removeAt(1)
if (node == destination) return distance as Int
graph[node]!!.forEach{
if (!visited.contains(it)){
visited.add(it)
queue.add(mutableListOf(it, distance + 1))
}
}
}
queue.sortedByDescending { it.size }
return queue[0][1]
}
fun buildGraph3(edges: List<List<Char>>): HashMap<Char, MutableList<Char>> {
val graph = HashMap<Char, MutableList<Char>>()
for (i in edges.indices){
for (n in 0 until edges[i].size){
var a = edges[i][0]
var b = edges[i][1]
if (!graph.containsKey(a)) { graph[a] = mutableListOf() }
if (!graph.containsKey(b)) { graph[b] = mutableListOf() }
graph[a]?.add(b)
graph[b]?.add(b)
}
}
return graph
}
I am stuck on the return part. I wanted to use a list to keep track of the incrementation of the char, but it wont let me return the number. I could have done this wrong, so any help is appreciated. Thanks.
If I paste your code into an editor I get this warning on your return queue[0][1] statement:
Type mismatch: inferred type is {Comparable<*> & java.io.Serializable} but Int was expected
The problem here is queue contains lists that hold Chars and Int distances, mixed together. You haven't specified the type that list holds, so Kotlin has to infer it from the types of the things you've put in the list. The most general type that covers both is Any?, but the compiler tries to be as specific as it can, inferring the most specific type that covers both Char and Int.
In this case, that's Comparable<*> & java.io.Serializable. So when you pull an item out with queue[0][1], the value you get is a Comparable<*> & java.io.Serializable, not an Int, which is what your function is supposed to be returning.
You can "fix" this by casting - since you know how your list is meant to be organised, two elements with a Char then an Int, you can provide that information to the compiler, since it has no idea what you're doing beyond what it can infer:
val node = queue[0].removeFirst() as Char
val distance = queue[0].removeAt(1) as Int
...
return queue[0][1] as Int
But ideally you'd be using the type system to create some structure around your data, so the compiler knows exactly what everything is. The most simple, generic one of these is a Pair (or a Triple if you need 3 elements):
val queue = mutableListOf(Pair<Char, Int>(root, 0))
// or if you don't want to explicitly specify the type
val queue = mutableListOf(root to 0)
Now the type system knows that the items in your queue are Pairs where the first element is a Char, and the second is an Int. No need to cast anything, and it will be able to help you as you try to work with that data, and tell you if you're doing the wrong thing.
It might be better to make actual classes that reflect your data, e.g.
data class Step(node: Char, distance: Int)
because a Pair is pretty general, but it's up to you. You can pull the data out of it like this:
val node = queue[0].first
val distance = queue[0].second
// or use destructuring to assign the components to multiple variables at once
val (node, distance) = queue[0]
If you make those changes, you'll have to rework some of your algorithm - but you'll have to do that anyway, it's broken in a few ways. I'll just give you some pointers:
your return queue[0][1] line can only be reached when queue is empty
queue[0].removeAt(1) is happening on a list that now has 1 element (i.e. at index 0)
don't you need to remove items from your queue instead?
when building your graph, you call add(b) twice
try printing your graph, the queue at each stage in the loop etc to see what's happening! Make sure it's doing what you expect. Comment out any code that doesn't work so you can make sure the stuff that runs before that is working.
Good luck with it! Hopefully once you get your types sorted out things will start to fall into place more easily

I did not get the Desired Outcome for this Question in Kotlin?

So I was creating an adjacency list from an Undirected Graph
val presentedGraph = listOf(
listOf('i', 'j'),
listOf('k', 'i'),
listOf('m', 'k'),
listOf('k', 'l'),
listOf('o', 'n')
)
The outcome that I was looking for was this
hashMapOf(
'i' to listOf('j', 'k'),
'j' to listOf('i'),
'k' to listOf('i', 'm', 'l'),
'm' to listOf('k'),
'l' to listOf('k'),
'o' to listOf('n'),
'n' to listOf('o')
)
But got this instead
{i=[i], j=[j], k=[k], l=[l], m=[m], n=[n], o=[o]}
Here's the code for it
fun undirectedPath (edges: List<List<Char>>, root: Char, destination: Char){
val graph = buildGraph(edges)
println(graph)
}
fun buildGraph(edges: List<List<Char>>): HashMap<Char, List<Char>>{
val graph = hashMapOf<Char, List<Char>>()
for (i in edges.indices){
for (j in edges[i].indices){
val a = edges[i][j]
val b = edges[i][j]
if (!graph.containsKey(a)) { graph[a] = listOf() }
if (!graph.containsKey(b)) { graph[b] = listOf() }
graph[a] = listOf(b)
graph[b] = listOf(a)
}
}
return graph
}
Any help will be appreciated, Thank You.
Several things wrong here:
The fact that you're setting both a and b to the same expression ought to be a clue that one of them is wrong! In fact a should be set to edges[i][0].
Because j runs from 0, it effectively assumes an extra edge from each node to itself. To avoid that, j should skip the first item and start from 1.
Each time you assign graph[a] and graph[b], you discard any previous items. That's why the result has only one target for each edge. To fix that, you need to add() the target to the existing list…
…which means that each target list must be a MutableList.
Those changes should be enough to get the result you want.
However, there are still several code smells present. For one thing, the input is a list of lists — but each of the inner lists has exactly two items. It would be neater to use a more precise structure, such as a Pair.
And it's always worth being aware of the standard library, which includes a wide range of manipulations and algorithms. In this case, you could replace the whole function with a one-liner:
fun buildGraph(edges: List<Pair<Char, Char>>)
= (edges + edges.map{ it.second to it.first })
.groupBy({ it.first }, { it.second })
As well as being a good deal shorter, that also makes it a good deal clearer what it's doing: combining the list of edges with the reverse list, and returning a map from each node to the list of nodes it connects to/from.
You can try this.
val hashMap = HashMap<Char, ArrayList<Char>>()
presentedGraph.forEach { list ->
list.forEach { char ->
if (!hashMap.containsKey(char)) {
hashMap[char] = arrayListOf()
}
hashMap[char]?.addAll(list.filter { char != it }.toList().distinct())
}
}
println(hashMap)
Output:
{i=[j, k], j=[i], k=[i, m, l], l=[k], m=[k], n=[o], o=[n]}

Returning all the subsets. (Issue with recursion)

class Solution(object):
lista=[]
def subsets(self, nums):
subset=[]
i=0
self.helper(nums,subset,i)
return self.lista
def helper(self,nums,subset,i):
if(i==len(nums)):
print(self.lista)
self.lista.append(subset)
print(subset)
return
subset.append(nums[i])
self.helper(nums,subset,i+1)
subset.pop()
self.helper(nums,subset,i+1)
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
So the question is https://leetcode.com/problems/subsets/
Can someone help me understand where I am going wrong? My code only returns an empty list. I understand that the last call of the recursion returns nullset but my lista is declared globally and so whenever I append something in the base case of the recursion function, shouldn't it append to the existing global list?. So, should it not append that to the lista and work properly? Any help is appreciated.
Your logic for generating subsets is fine. The main issue here is that self.lista.append(subset) inserts a reference to subset into lista. You can read more about object references in relation to lists here.
This means that any changes you make to subset will persist in all references of subset in lista. In this case, the final state of subset will be an empty list, hence lista contains a bunch of empty lists [].
One way to fix this would be to make a copy of subset on insertion, i.e change
self.lista.append(subset)
to
self.lista.append(subset.copy()) (if you're using Python >= 3.3, otherwise you can slice it or use copy).
for this recursion it can be simplified as the following:
(you can compare and see the difference then)
class Solution:
def subsets(self, nums: List[int]) -> List[List[int]]:
if not nums:
return [[]]
without = self.subsets(nums[1:])
return without + [s + [nums[0]] for s in without]
Or a simple straight-forward iterative can do the work too:
def subsets(self, nums):
result = [[]]
for n in nums:
result += [x+[n] for x in result]
return result

Finding first and last element of the list using recursive

I am trying to write recursive function in Scala returning first and last element of the list (pair). I'd like to only use .head and .tail without match using simple (not tail) recursive (without defining additional function). Is it possible?
Last element I can find using this code:
def foo(x: List[Int]): (Int) = {
if (x.tail.isEmpty) (x.head)
else foo(x.tail)
}
I'd like to return pair with first and last element (Int, Int). Parameter is (x: List[Int]). It is easy if I pass head as parameter but is it possible without doing it?
You can use a inner, recursive function for the tail, and have an outer function for the head.
However - whether this is still in the spirit of the exercise, is another question.
Here is a very inefficient solution:
def firstAndLast (list: List[Int]): (Int, Int) = {
if (list.isEmpty) (0, 0)
else if (list.size == 1) (list.head, list.head)
else if (list.size == 2)
(list.head, list.tail.head)
else
firstAndLast (list.head :: list.tail.tail)
}
It carries the head not as a separate parameter, but by reappending it at head of the rest of rest of the list, if it is longer than 2.
For a meaningful return for the empty case, I had no good idea. Return Option of tuple in general would be a way.
Another approach
def headTail(l:List[Int]) : (Int, Int) = {
if(l.isEmpty) (-1, -1)
else if(l.tail == List()) (l.head, -1)
else if(l.tail.tail.isEmpty) (l.head, l.tail.head)
else headTail(l.head :: l.tail.tail) //eliminates second element for every iteration
}

How does pattern matching work behind the scenes in F#?

I am completely new to F# (and functional programming in general) but I see pattern matching used everywhere in sample code. I am wondering for example how pattern matching actually works? For example, I imagine it working the same as a for loop in other languages and checking for matches on each item in a collection. This is probably far from correct, how does it actually work behind the scenes?
How does pattern matching actually work? The same as a for loop?
It is about as far from a for loop as you could imagine: instead of looping, a pattern match is compiled to an efficient automaton. There are two styles of automaton, which I call the "decision tree" and the "French style." Each style offers different advantages: the decision tree inspects the minimum number of values needed to make a decision, but a naive implementation may require exponential code space in the worst case. The French style offers a different time-space tradeoff, with good but not optimal guarantees for both.
But the absolutely definitive work on this problem is Luc Maranget's excellent paper "Compiling Pattern Matching to Good Decisions Trees from the 2008 ML Workshop. Luc's paper basically shows how to get the best of both worlds. If you want a treatment that may be slightly more accessible to the amateur, I humbly recommend my own offering When Do Match-Compilation Heuristics Matter?
Writing a pattern-match compiler is easy and fun!
It depends on what kind of pattern matching do you mean - it is quite powerful construct and can be used in all sorts of ways. However, I'll try to explain how pattern matching works on lists. You can write for example these patterns:
match l with
| [1; 2; 3] -> // specific list of 3 elements
| 1::rest -> // list starting with 1 followed by more elements
| x::xs -> // non-empty list with element 'x' followed by a list
| [] -> // empty list (no elements)
The F# list is actually a discriminated union containing two cases - [] representing an empty list or x::xs representing a list with first element x followed by some other elements. In C#, this might be represented like this:
// Represents any list
abstract class List<T> { }
// Case '[]' representing an empty list
class EmptyList<T> : List<T> { }
// Case 'x::xs' representing list with element followed by other list
class ConsList<T> : List<T> {
public T Value { get; set; }
public List<T> Rest { get; set; }
}
The patterns above would be compiled to the following (I'm using pseudo-code to make this simpler):
if (l is ConsList) && (l.Value == 1) &&
(l.Rest is ConsList) && (l.Rest.Value == 2) &&
(l.Rest.Rest is ConsList) && (l.Rest.Rest.Value == 3) &&
(l.Rest.Rest.Rest is EmptyList) then
// specific list of 3 elements
else if (l is ConsList) && (l.Value == 1) then
var rest = l.Rest;
// list starting with 1 followed by more elements
else if (l is ConsList) then
var x = l.Value, xs = l.Rest;
// non-empty list with element 'x' followed by a list
else if (l is EmptyList) then
// empty list (no elements)
As you can see, there is no looping involved. When processing lists in F#, you would use recursion to implement looping, but pattern matching is used on individual elements (ConsList) that together compose the entire list.
Pattern matching on lists is a specific case of discriminated union which is discussed by sepp2k. There are other constructs that may appear in pattern matching, but essentially all of them are compiled using some (complicated) if statement.
No, it doesn't loop. If you have a pattern match like this
match x with
| Foo a b -> a + b
| Bar c -> c
this compiles down to something like this pseudo code:
if (x is a Foo)
let a = (first element of x) in
let b = (second element of x) in
a+b
else if (x is a Bar)
let c = (first element of x) in
c
If Foo and Bar are constructors from an algebraic data type (i.e. a type defined like type FooBar = Foo int int | Bar int) the operations x is a Foo and x is a Bar are simple comparisons. If they are defined by an active pattern, the operations are defined by that pattern.
If you compile your F# code to an .exe then take a look with Reflector you can see what the C# "equivalent" of the F# code.
I've used this method to look at F# examples quite a bit.

Resources