I would like to understand recursion on a deeper level and not just intuitively. I know the concept and I know how to solve a factorial or a fibonacci sequence recursively. But I don't seem to be able to visualize very well what exactly happens in a linked list when used recursively.
More specifically I am struggling to understand the following algorithm:
(It looks for the maximum in a linked list. It does so by recursively searching for the maximum starting from the second element. Then it compares it with the first element and returns the higher one.)
function MaxRec (inRefBegin : tRefList) : tRefList;
{ returns recursively a pointer to the max element in a list }
var
rekMax : tRefList; { variable to point to the recursive maximum
starting from second element }
begin
if inRefBegin = nil then { Base Case, recursion stops }
MaxRec := nil
else
begin
rekMax := MaxRec (inRefBegin^.next);
if rekMax = nil then
MaxRec := inRefBegin
else
if inRefBegin^.info < rekMax^.info then
MaxRec := rekMax
else
MaxRec := inRefBegin
end { if }
end; { MaxRec }
I do understand what in theory should happen. I have trouble visualizing it step by step. What happens at every stack level?
What I don't get is how does this line: rekMax := MaxRec (inRefBegin^.next) can find the maximum.... it only calls the function with a pointer to the next item but is not comparing any values.... Or do I compare each time the function is called??
My thought process is like this:
Let's say I have a linked list like this:
5 => 7 => 10 => 3 => 2 => nil
Function is called and is not nil ((saved to stack))
Function is called and is not nil ((saved to stack))
Function is called and is not nil ((saved to stack))
Function is called and is not nil ((saved to stack))
Function is called and is not nil ((saved to stack))
Recursion stops
Now what happens? Do I compare in each function with the first element? Or is this the point where I already have my recursive max? Can s.o visualize this?
I am very grateful for every help. I know this topic has heaps of sources online and believe me I have read them. But it is still not clear to me what exactly is going on on every level.
7) Now what happens? Do I compare in each function with the first element? Or is this the point where I already have my recursive max? Can s.o visualize this?
At 7) recursion stops because you've reached the end of the list, so nil is returned.
You then continue in the previous call where the result from MaxRec is now nil, so the max for that last part is the current inRefBegin value (again, since nil was returned).
For the other levels, going out of the recursion, the value in the current node is compared to what was returned from the recursive call, and the greatest one is retained, until, finally, you are left with the greatest node for the entire list.
Does that help?
Related
I am very new to SML and functional programming.
I have searched the site but was unable to find an answer to my question.
I am trying to write a basic range function with a start, stop, and step parameter.
For example, range(2, 12, 3) should return the list [2,5,8,11].
I don't get any errors, but when I try running range(2,12,3); the cursor advances to the next line and nothing happens, I can't even type anything into the smlnj app.
Here is my code:
fun range(start, stop, step) =
if start = stop then nil
else start::range(start+step, stop, step);
Which outputs this:
val range = fn : int * int * int -> int list
What changes do I need to make to my code so that when I run range(2,12,3) I get [2,5,8,11] ?
Thank you
Your condition (start = stop) to break the recursion is wrong. In your example you'll perform recursive calls with start=2, start=5, start=8, start=11, start=14, ... leading to an infinite loop. It's not that nothing happens, it's just that smnlj keeps computing...
You have an infinite recursion whenever stop - start is not a multiple of the step size (or zero).
Look at range(11,12,3), which should generate your last number:
if 11 = 12 then nil
else 11::range(11+3, 12, 3)
This will calculate range(14,12,3):
if 14 = 12 then nil
else 14::range(14+3, 12, 3)
and then range(17,12,3), and so on, ad infinitum.
You need to replace = with either > or >=, depending on whether stop should be included or not.
I am new to the game maker. I created a list and I want to compare all the data in the list with a specific value. I used the following code:
for(var i=0;i<ds_list_size(lst);i++;)
{
if ds_list_find_value(lst,i)>tmp
ds_list_replace(lst,i,ds_list_find_value(lst,i)-1);
}
and I face the following error:
Push :: Execution Error - Variable Get -1.lst(100001, -1)
at
gml_Object_object0_RightButtonPressed_1 (line 21) - for(var i=0;i
where is my problem?
Thanks all.
if your first for loop i = 0; and when the first entry in the list is smaller than tmp it tries to replace the first place in the list with a not existing one. so you could either check if its the first entry of the list with
if ( i == 0 ) { }
or your could start the for loop from the second entry with
for(var i=1;i<ds_list_size(lst);i++;)
I think the ; at the end of i++; is unnecessary, you only need to use ; in a for-loop as seperator.
GML gives more freedom to common C# rules though (like how there are no brackets needed around an if-condition), so perhaps that's allowed.
Another possibility might be that the index is out of range at ds_list_replace()
What I am trying to do is a little addon which would let me know how much time I have spent casting during combat in %,
function()
local spell, _, _, _, _, endTime = UnitCastingInfo("player")
-- getting information from the game itself whether im "Casting"
local inCombat = UnitAffectingCombat("player")
-- getting information form the game if combat is true (1) or not (nil)
local casting = {}
local sum = 0
if inCombat == 1 then
if spell then
table.insert(casting, 1)
else
table.insert(casting, 0)
end
else
for k in pairs (casting) do
casting [k] = nil
end
end
for i=1, #casting, 1 do
sum = sum + casting[i]
end
return( sum / #casting ) end
-- creating a list which adds 1 every frame I am casting and I am in combat,
-- or adds 0 every frame I'm not casting and I'm not in combat.
-- Then I sum all the numbers and divide it by the number of inputs to figure
-- out how much % I have spent "casting".
-- In case the combat condition is false, delete the list
For some reason these numbers don't add up at all, I only see "1" when both conditions are satisfied, or 0 if the combat condition is satisfied.
There might be some better approach I'm sure, but I am kind of new to lua and programming in general.
You say you're new to Lua, so I will attempt to explain in detail what is wrong and how it can be improved, so brace yourself for a long read.
I assume that your function will be called every frame/step/tick/whateveryouwanttocallit of your game. Since you set sum = 0 and casting = {} at the beginning of the function, this will be done every time the function is called. That's why you always get 0 or 1 in the end.
Upvalues to the rescue!
Lua has this nice thing called lexical scoping. I won't go into much detail, but the basic idea is: If a variable is accessible (in scope) when a function is defined, that function remembers that variable, no matter where it is called. For example:
local foo
do
local var = 10
foo = function() return var end
end
print(bar) -- nil
print(foo()) -- 10
You can also assign a new value to the variable and the next time you call the function, it will still have that new value. For example, here's a simple counter function:
local counter
do
count = 0
counter = function() count = count + 1; return count; end
end
print(counter()) -- 1
print(counter()) -- 2
-- etc.
Applying that to your situation, what are the values that need to persist from one call to the next?
Number of ticks spent in combat
Number of ticks spent casting
Define those two values outside of your function, and increment / read / reset them as needed; it will persist between repeated calls to your function.
Things to keep in mind:
You need to reset those counters when the player is no longer casting and/or in combat, or they will just continue where they left off.
casting doesn't need to be a table. Tables are slow compared to integers, even if you reuse them. If you need to count stuff, a number is more than enough. Just make casting = 0 when not in combat and increase it by 1 when in combat.
Thank you for feedback everyone, in the end after your suggestions and some research my code looks like this and works great:
function()
local spell, _, _, _, startTime, endTime, _, _, _ = UnitCastingInfo("player")
local inCombat = UnitAffectingCombat("player")
local inLockdown = InCombatLockdown()
local _, duration, _, _ = GetSpellCooldown("Fireball")
casting = casting or {}
local sum = 0
if inCombat == 1 or inLockdown == 1 then
if spell or duration ~= 0 then
casting[#casting+1] = 1
elseif spell == nil or duration == 0 then
casting[#casting+1] = 0
end
else
local next = next
local k = next(casting)
while k ~= nil do
casting[k] = nil
k = next(casting, k)
end
end
for i=1, #casting, 1 do
sum = sum + casting[i]
end
return(("%.1f"):format( (sum / #casting)*100 ).. "%%") end
what i noticed is there was a problem with reseting the table in the original code:
for k in pairs (casting) do
casting [k] = nil
it seemed like either some zeros stayed there, or the table size didnt "shrink" i dont know.
Maybe intereger would be faster then a table, but honestly i dont see any performance issues even when the table gets ridicolously big (5 min, 60 fps, thats 18k inputs) also for the sake of learning a new language its better to do it harder way in my opinion
Regards
How can I check if the value in cell #0 is equal to the value in cell #1? I am trying to write code equivalent to:
if(a == b)
{
//do stuff
}
else
{
//do something else
}
I have read Brainfuck compare 2 numbers as greater than or less than, and the second answer gave me a general idea of what I'd need to do, but I cannot figure it out. (That solution gives if a < b, else.)
I am thinking I need to do something along the lines of decrementing both values, and if they reach 0 at the same time, then they are true. But I keep getting stuck at the same exit point every time I think about it.
How can I check if two cells are equal in brainfuck?
I think I have it, I'm not a brainfuck expert but this question looked interesting. There might be a simpler way to do it, but I went with your method of decrementing values one by one.
In this case, if the two values in cell 0 and 1 are equal jump a ton forward, if they are not equal jump a little forward (second brackets is the not equal case, third brackets is the equal case)
Note that I'm using brainfucks while statements as a ghetto if (cell != 0)
+++++++++++++++++
>
+++++++++++++++++
>+<
[ - < - >] <[>>>>>] >> [>>>>>>>>>>>>>>>>>>>>>]
Try it online: http://fatiherikli.github.io/brainfuck-visualizer/#KysrKysrKysrKysrKysrKysKPgorKysrKysrKysrKysrKysrKwo+KzwKWyAtIDwgLSA+XSA8Wz4+Pj4+XSA+PiBbPj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+XQoKCg==
An example implementation, print T (true) if the two values are equal, F (false) if they are not equal
http://fatiherikli.github.io/brainfuck-visualizer/#KysrCj4KKysrKwo+KzwKWyAtIDwgLSA+XSA8Wz4+PgorKysrKysrKysrKysrKysrKysrKworKysrKysrKysrKysrKysrKysrKworKysrKysrKysrKysrKysrKysrKworKysrKysrKysrCi4KPgoKXSA+PiBbCisrKysrKysrKysrKysrKysrKysrCisrKysrKysrKysrKysrKysrKysrCisrKysrKysrKysrKysrKysrKysrCisrKysrKysrKysrKysrKysrKysrCisrKwouCj4KXQ==
+>>(a+++++)>(b+++++)>>+<<<
[[->]<<]
<
[>>>>>-<<<<<
a>b
]
>>
[->>-<
a<b
]
>>
[-
a=b
]
Pointer ends on the same pointer in the same state but the code within the appropriate brackets has been executed.
I came up with this for my bf compiler thing
basically it subtracts and then checks if the result is 0.
Can be easily changed to execute stuff in if/else-ish way
Layout:
[A] B
>[-<->]+<[>-<[-]]>
Output
0 [result]
Result is 1 if equal
I am trying find nearest RGB value in QMap (I know it probably should be HSV, but that is not the problem). Here is what I got so far:
it = images_map.find(current_rgb);
if(it != images_map.begin()){
mi = images_map.lowerBound(current_rgb).value();
}
else{
mi = images_map.upperBound(current_rgb).value();
}
My map looks like this has that indexes:
images_map[ 4283914078 ]
images_map[ 4284046165 ]
images_map[ 4284902241 ]
images_map[ 4289239953 ]
images_map[ 4282200377 ]
images_map[ 4289440688 ]
When my current_rgb is for example 4285046165 it is OK, but if there is some value greater than greatest index, program crashes. What am I doing wrong?
Possibly because .value() tries to de-reference a non-existing item?
This looks like your own custom map implementation (or wrapper), but your logic appears to be incorrect
You call lowerBound every time - except if the item you are looking for is the first in the map
If it is the first in the map, you do a search again???
If it's not you search again (which if already found is repeating the operation again), else if not found, looks for nearest (which is okay), however do you handle the case where there is none (i.e. in lowerBound)?
The logic should be something like:
it = images_map.find(current_rgb);
if(it == images_map.end())
{
it = images_map.lowerBound(current_rgb);
if (it == images_map.begin())
{
it = images_map.upperBound(current_rgb);
if (it == images_map.end())
// throw error
}
// now you know you have a valid iterator - de-reference
mi = *it.value();
}
Call
images_map.upperBound(current_rgb)
May return
images_map.end()
In that case you should not call value().
You can solve the iterator out of range problem by adding sentinel values 0x000000 and 0xFFFFFF (once). That way, you always have a valid lower- and upperbound. Of course, this may affect the outcome of your algorithm. E.g. if your "smallest" real color was pure blue (0x0000FF), then dark blue (0x00007F) will now find black, not pure blue. This is easily fixed by two comparisons, of course.
With the sentinels in place, call QMap::lower_bound. You need to check whether you've actually found a precise match: if *lower_bound is the value you want, return it. Else, lower_bound points to the first element that's bigger than your input. Therefore, --lowerbound points to the last element that's smaller than your input. Check which of the two is closer.
Note that the only way lower_bound can point to begin is when your input is precisely 0x000000 (the sentinel), in which case you won't get to --lower_bound. No range error there. By the same logic, the end sentinel 0xFFFFFF means you'll always find an lower_bound.