How to implement Linked List Recursion in KOtlin - kotlin

I am learning linked list and came across a problem where you are required to reverse a linked list using recursion. Here is the code I wrote:
fun reverseRecurseTraverse1(firstNode: Node<Int>?): Node<Int>? {
if (firstNode?.next == null) {
return firstNode
} else {
val finalNode = reverseRecurseTraverse1(firstNode.next)
finalNode?.next = firstNode
firstNode.next = null
return finalNode
}
}
Input:
01234
Output:
40
I get the desired output If I change the line from
finalNode?.next = firstNode
to
firstNode.next!!.next = firstNode
What am I doing wrong here?
When I try to whiteboard finalNode?.next = firstNode makes perfect sense to me and based on my understanding those two lines are essentially doing the same thing.
Kindly help me understand this.

It would be useful if you share your "whiteboard logic" and why do you assume finalNode?.next = firstNode is correct and functionally the same as firstNode.next!!.next = firstNode.
Let's get your example: 01234. In the first step firstNode is 0 and after reversing of the remaining sublist, we get 4321. finalNode points at the first element of this reversed sublist, so at 4. Then you add 0 after 4 which is wrong. You should add 0 after 1.
On the other hand, firstNode.next is still pointing at the item that was next to 0 in the original list. It points at 1. By assigning to its next we add 0 where it should be - after 1.

You are almost there, but one line is wrong.
What you are doing is:
If your item is null, return it. That seems okay.
If your item is already the last item, return it as first item. Also looks okay.
If your item is not the last item, reverse the rest of the list. Okay.
Take the old last and now first item, and append your old first now last item to it? That doesn't seem right. Don't you want to append your old first and now last item to the last item of the reversed rest?
It would probably help to write a function
fun Node.last(): Node? = if(next == null) this else next!!.last()
that provides the last item of a linked list.
You could use that to append your previously first item to the last item of the reversed rest.
Considering a call reverseRecurseTraverse1(x), can we maybe always tell what reverseRecurseTraverse1(x).last() is without calculating it?

Related

How to filter items in QListWidget

I have the following QlistWidget:
self.myListWidget1 = QListWidget()
os.chdir("./Downloads")
for file in glob.glob("*.pdf"):
QListWidgetItem(file, self.myListWidget1)
self.myListWidget1.sortItems()
How can I add a QLineEdit that is able to filter items in self.myListWidget1 by partial
string?
The currently accepted answer by Papooch is not very good unfortunately. The reason is that it will not keep the current row event if it remains withing filter criteria. You do not want to generate a new list. You actually want to hide items which are not withing filter criteria. Do it like this:
void ItemsListWidget::filterItems(QString filter)
{
for (int row = 0; row < count(); ++row)
{
item(row)->setHidden(!item(row)->text().contains(filter, Qt::CaseInsensitive)); // you can leave out the case insensitivity if you do not want it
}
}
(it is Qt/C++ code but I am pretty sure you can easily adapt it for Python)
You are going to need a separate list on which you will do the filtering and then display the filtered list in the QListWidget.
The most basic example could look like this:
self.myLineEdit = QLineEdit()
self.myListWidget1 = QListWidget()
self.listOfPdfs = [] # this will hold the complete list of files
os.chdir("./Downloads")
for file in glob.glob("*.pdf"):
self.listOfPdfs.append(file) # fill the list
QListWidgetItem(file, self.myListWidget1)
# connect the signal textChanged to the filter function
self.myLineEdit.textChanged.connect(self.filterList)
def filterList(self, text):
self.myListWidget1.clear() # clear the list widget
for file on self.listOfPdfs:
if text in file: # only add the line if it passes the filter
QListWidgetItem(file, self.myListWidget1)
(note that I didn't check the validity of the code, minor modifications might be needed)

Non-greedy configurations across steps

I'm using late acceptance as local search algorithm and here is how it actually picks moves:
If my forager is 5, it'll pick 5 moves and then get 1 random move to be applied for every step.
At every step it only picks moves that are increasing scores ie greedy picking across steps.
Forager.pickMove()
public LocalSearchMoveScope pickMove(LocalSearchStepScope stepScope) {
stepScope.setSelectedMoveCount(selectedMoveCount);
stepScope.setAcceptedMoveCount(acceptedMoveCount);
if (earlyPickedMoveScope != null) {
return earlyPickedMoveScope;
}
List<LocalSearchMoveScope> finalistList = finalistPodium.getFinalistList();
if (finalistList.isEmpty()) {
return null;
}
if (finalistList.size() == 1 || !breakTieRandomly) {
return finalistList.get(0);
}
int randomIndex = stepScope.getWorkingRandom().nextInt(finalistList.size());// should have checked for best here
return finalistList.get(randomIndex);
}
I have two questions:
In first, can we make forager to pick the best of 5 instead of pick 1 randomly.
Can we allow move to pick that degrades score but can increase score later(no way to know it)?
Look for acceptedCountLimit and selectedCountLimit in the docs. Those do exactly that.
That's already the case (especially with Late Acceptance and Simulated Annealing). In the DEBUG log, just look at the step score vs the best score. Or ask for the step score statistic in optaplanner-benchmark.

Vue - How modify this code so not new selects shows up?

This fiddle has almost all I want:
http://jsfiddle.net/jjpfvx5q/1/
However I want just the first sub select to appear.
As for now, if you first select first item in main select and something from the sub select that appaears, and go back to main and select second option, then a new third selectbox is appearing.
I don't want that to happen. I just want to have one main select and a second that populates depending on choice in the first one. So just these two, no matter of how many times I reselect from the main one.
I am new to Vue and find it hard to see where to make that change.
The problem is, when you select a city, you are pushing same cities into cityPacks array. No matter what, exists or not, performing this action. That populates new selectbox according to new data.
Simply, you can empty your cityPacks array before switch statement.
this.cityPacks = [];
#Tugayİlik's answer is correct, but in case you want to retain a 'history' of use selections in cityPacks, you can add a v-if to the second select
v-if="index === coInit.map(co => co.id).indexOf(country)"
There's probably some other optimizations you could make to the data structures, depending on the intention of the app. For instance, it's not clear why you use getCities method and not just nest the cities inside the coInit array (and why you need to use setTimeout).
You could also use a coumputed to get the cities for the second select
computed: {
cities() {
return this.country ?
? this.country === 2 ? this.cFrance
? this.country === 3 ? this.cUSA
: []
}
},

How to check if a Gun unordered list is empty?

Given the following, how would one go about determining if the machines list is empty in order to add a machine?
let gun = new Gun();
let machines = gun.get('machines');
How do I check if the machines list is empty?
This from Mark Nadal:
// machineId and location defined elsewhere
machines.val(table => {
if (Gun.obj.empty(table, '_') {
// table is empty so we can add something to it
let machine = gun.get('machine/' + machineId);
machine.put({machineId, location}};
machines.set(machine);
} else {
// table is not empty
})
table is a data node that has all the row pointers in it (not the actual sub-objects)
so if table has 0 items on it, then it is empty! Or if table is null or undefined
HOWEVER, gun has its {_: {...}} meta data it includes on every node, so you need to ignore that.
Gun.obj.empty({}) tests if an object is empty (you can use lodash or something else), the second parameter tells it to IGNORE a key, like in this case '_'. So it will still say that yes it is empty if it has 0 properties other than the metadata property.

SQL: Use a predefined list in the where clause

Here is an example of what I am trying to do:
def famlist = selection.getUnique('Family_code')
... Where “””...
and testedWaferPass.family_code in $famlist
“””...
famlist is a list of objects
‘selection’ will change every run, so the list is always changing.
I want to return only columns from my SQL search where the row is found in the list that I have created.
I realize it is supposed to look like: in ('foo','bar')
But no matter what I do, my list will not get like that. So I have to turn my list into a string?
('\${famlist.join("', '")}')
Ive tried the above, idk. Wasn’t working for me. Just thought I would throw that in there. Would love some suggestions. Thanks.
I am willing to bet there is a Groovier way to implement this than shown below - but this works. Here's the important part of my sample script. nameList original contains the string names. Need to quote each entry in the list, then string the [ and ] from the toString result. I tried passing as prepared statement but for that you need to dynamically create the string for the ? for each element in the list. This quick-hack doesn't use a prepared statement.
def nameList = ['Reports', 'Customer', 'Associates']
def nameListString = nameList.collect{"'${it}'"}.toString().substring(1)
nameListString = nameListString.substring(0, nameListString.length()-1)
String stmt = "select * from action_group_i18n where name in ( $nameListString)"
db.eachRow( stmt ) { row ->
println "$row.action_group_id, $row.language, $row.name"
}
Hope this helps!