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
Related
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]}
I stumbled upon this challenge on stackoverflow while learning about property based testing in scala using ScalaCheck.
Find the smallest positive integer that does not occur in a given sequence
I thought of trying to write a generator driven property based test for this problem to check the validity of my program but can't seem to be able to think of a how to write a relevant test case. I understand that I could write a table driven property based testing for this use case but that limit the number of properties I could test this algo with.
import scala.annotation.tailrec
object Solution extends App {
def solution(a: Array[Int]): Int = {
val posNums = a.toSet.filter(_ > 0)
#tailrec
def checkForSmallestNum(ls: Set[Int], nextMin: Int): Int = {
if (ls.contains(nextMin)) checkForSmallestNum(ls, nextMin + 1)
else nextMin
}
checkForSmallestNum(posNums, 1)
}
}
Using Scalatest's (since you did tag scalatest) Scalacheck integration and Scalatest matchers, something like
forAll(Gen.listOf(Gen.posNum[Int]) -> "ints") { ints =>
val asSet = ints.toSet
val smallestNI = Solution.solution(ints.toArray)
asSet shouldNot contain(smallestNI)
// verify that adding non-positive ints doesn't change the result
forAll(
Gen.frequency(
1 -> Gen.const(0),
10 -> Gen.negNum[Int]
) -> "nonPos"
) { nonPos =>
// Adding a non-positive integer to the input shouldn't affect the result
Solution.solution((nonPos :: ints).toArray) shouldBe smallestNI
}
// More of a property-based approach
if (smallestNI > 1) {
forAll(Gen.oneOf(1 until smallestNI) -> "x") { x =>
asSet should contain(x)
}
} else succeed // vacuous
// Alternatively, but perhaps in a less property-based way
(1 until smallestNI).foreach { x =>
asSet should contain(x)
}
}
Note that if scalatest is set to try forAlls 100 times, the nested property check will check values 10k times. Since smallestNI will nearly always be less than the number of trials (as listOf rarely generates long lists), the exhaustive check will in practice be faster than the nested property check.
The overall trick, is that if something is the least positive integer for which some predicate applies, that's the same as saying that for all positive integers less than that something the predicate does not apply.
I have a list of A class objects
data class A{
val abc: Abc
val values: Int?
}
val list = List<A>
If I want to count how many objects I have in list I use:
val count= a.count()
or val count= a.count(it -> {})
How to append all values in the list of objects A avoiding for loop? Generaly Im looking for proper kotlin syntax with avoiding code below
if (a!= null) {
for (i in list) {
counter += i.values!!
}
}
Either use sumBy or sum in case you have a list of non-nullable numbers already available, i.e.:
val counter = list.sumBy { it.values ?: 0 }
// or
val counter = extractedNonNullValues.sum()
The latter only makes sense if you already mapped your A.values before to a list of non-nullable values, e.g. something like:
val extractedNonNullValues= list.mapNotNull { it.values } // set somewhere else before because you needed it...
If you do not need such an intermediate extractedNonNullValues-list then just go for the sumBy-variant.
I don't see you doing any appending to a list in the question. Based on your for loop I believe what you meant was "How do I sum properties of objects in my list". If that's the case you can use sumBy, the extension function on list that takes a labmda: ((T) -> Int) and returns an Int like so:
val sum = list.sumBy { a -> a.values ?: 0 }
Also, calling an Int property values is pretty confusing, I think it should be called value. The plural indicates a list...
On another note, there is a possible NPE in your original for loop. Avoid using !! on nullable values as, if the value is null, you will get an NPE. Instead, use null coalescing (aka elvis) operator to fall back to a default value ?: - this is perfectly acceptable in a sum function. If the iteration is not to do with summing, you may need to handle the null case differently.
I'm totally newbie in C++ and I need to solve a problem with vectors. What I need is to merge two existing vectors and create third one. While I saw several answers, the difference here is I need vector #3 (values3) to contain not all values, but only those which are in both vectors #1 (values1) and #2 (values2). So, if integer 2 is in vector 1 but is not in vector 2, this number does not fit me. I should use a function provided below. Commented lines are which I don't know what to write in. Other lines are working.
void CommonValues(vector<MainClass> & values1, vector<MainClass> & values2, vector<MainClass> & values3)
{
MainClass Class;
string pav;
int kiek;
vector<MainClass>::iterator iter3; // ?
for (vector<MainClass>::iterator iter1 = values1.begin(); iter1 != values1.end(); iter1++)
{
for (vector<MainClass>::iterator iter2 = values2.begin(); iter2 != values2.end(); iter2++)
{
if (iter1 == iter2)
{
pav = iter2->TakePav();
iter3->TakePav(pav); // ?
kiek = iter1->TakeKiek() + iter2->TakeKiek();
iter3->TakeKie(kiek); // ?
iter3++; // ?
}
}
}
}
You can sort values1 and values2, then use std::intersection: http://en.cppreference.com/w/cpp/algorithm/set_intersection
Your code at the moment won't work, among other problems, you are comparing iterator from vector 1 with iterator from vector 2, which doesn't make any sense. If you want to do it by looping, you should iterate through one vector and check if the value, for example *iter1, is in the 2nd vector.
so the title essentially says it all. I am writing a symbol table in c++ for a compiler project I am working on, and all is going well except for looking up identifiers in the table.
So this is how I store into the table (pseudo like):
vector<symbolTable*>* symbolStack = new symbolTable();
//where a symbolStack is a vector of unordered_maps (symbolTables),
//each iteration in vector referencing a new block of code.
string* check = new string(root->children[0]->lexicode->c_str());
symbol* sym = new symbol();
...... //setting sym info
symbol_entry pair = make_pair(check, test)
//the unordered_map has keys of (string*, symbol*)
symbolStack[tableNumber]->insert(pair);
I am pretty solid that this works, as I have tested printing the size/infos from the map and it all seems to be storing as expect. Here is where the problem is happening for me (this takes place in a different function later):
for(int i = 0; i =< tableNumber;i++){
auto finder = symbolStack[i]->find(checkS) //checkS == check from above
if(finder == symbolStack[i]->end()) cout<<not found;
else cout<<we did it!!!!
My else is never reached. However, if I do this assuming the string*->c_str() == "test":
cout<<string->c_str(); // prints out "test"
cout<<finder->second->c_str() //prints out "test".
So the question. Why is it finding the key, and knowing it found the key, but at the same time returning that is has reached the end of the symbol stack without finding it? I have been trying to figure this out for a good 4 days solid now. Is it that my pointers are somehow off? Any insight is appreciated greatly.
So somewhat answer to my own question.
First I will say this: I have concluded the comparison with find() or similar methods do not work because for some reason the pointers are not matching up. I have no clue why this is still, or what I am doing wrong.
What I did to solve my issue and complete my code is this:
for(int k = 0; k<= tableNumber; k++){
unordered_map<string*,symbol*>::iterator it;
for(it = symbolStack[k]->begin(); it != symbolStack[k]->end(); it++)
{
string a = targetString->c_str();
string b = it->first->c_str();
if(a.compare(b) == 0) cout<<"You have found the match! \n";
}
}
}
So this answers how to get it working pragmatically if somebody else is in a similar ship, however not really answers why my other attempt failed other than noticing the pointer values were different.
In symbolTable you store pointers to strings as keys, not strings themselves. Therefore unordered_map compares pointers, not strings, and cannot find matching items. When you reconstruct the key string (as in your answer, using string b = it->first->c_str()), the comparison on strings works again. So, either you need to store string instead of string * in symbolTable, or you need to provide your own comparison function that will compare keys of type string *.