The code works but I am confused. When n==1, I am assigning a=1, shouldn't that overwrite the value and return only 1?
format compact
fct(5)
function a = fct(n)
if n==1
a = 1;
else
a = n*fct(n-1);
end
end
This is how I picture it... Below is a recursion/factorial diagram that shows the cascading effect of the recursive calls. At the deepest recursive call fct(1) is evaluated which is equal to 1 given by the first if statement. Each recursive call is therefore defined by a deeper recursive call. I typically like to decompose the recursive function until reaching its terminating case. I guess a way to phrase it is "a function within function" not so much of a loop.
Where, fct(1) → 1
format compact
fct(5)
function a = fct(n)
if n == 1
a = 1;
else
a = n*fct(n-1);
fprintf("%d\n",a);
end
end
Cumulative/Recursive Results:
2
6
24
120
ans =
120
My Preferred Structuring:
format compact
fct(5)
function a = fct(n)
if n > 1
a = n*fct(n-1);
else
a = n;
end
end
Let's assume that we have first paragraph in our google document:
Wo1rd word so2me word he3re last.
We need to search and replace some parts of text but it must be highlighted in editions history just like we changed only that parts and we must not loose our format (bold, italic, color etc).
What i have/understood for that moment: capturing groups didn't work in replaceText() as described in documentation. We can use pure js replace(), but it can be used only for strings. Our google document is array of objects, not strings. So i did a lot of tries and stopped at that code, attached in this message later.
Can't beat: how i can replace only part of what i've found. Capturing groups is very powerful and suitable instrument, but i can't use it for replacement. They didn't work or i can replace whole paragraph, that is unacceptable because of editions history will show full paragraph replace and paragraphs will lose formatting. What if what we searching will be in each and every paragraph, but only one letter must be changed? We will see full document replacement in history and it will be hard to find what really changed.
My first idea was to compare strings, that replace() gives to me with contents of paragraph then compare symbol after symbol and replace what is different, but i understand, that it will work only if we are sure that only one letter changed. But what if replace will delete/add some words, how it can be synced? It will be a lot bigger problem.
All topics that i've found and read triple times didn't helped and didn't moved me from the dead point.
So, is there any ideas how to beat that problem?
function RegExp_test() {
var docParagraphs = DocumentApp.getActiveDocument().getBody().getParagraphs();
var i = 0, text0, text1, test1, re, rt, count;
// equivalent of .asText() ???
text0 = docParagraphs[i].editAsText(); // obj
// equivalent of .editAsText().getText(), .asText().getText()
text1 = docParagraphs[i].getText(); // str
if (text1 !== '') {
re = new RegExp(/(?:([Ww]o)\d(rd))|(?:([Ss]o)\d(me))|(?:([Hh]e)\d(re))/g); // v1
// re = new RegExp(/(?:([Ww]o)\d(rd))/); // v2
count = (text1.match(re) || []).length; // re v1: 7, re v2: 3
if (count) {
test1 = text1.match(re); // v1: ["Wo1rd", "Wo", "rd", , , , , ]
// for (var j = 0; j < count; j++) {
// test1 = text1.match(re)[j];
// }
text0.replaceText("(?:([Ww]o)\\d(rd))", '\1-A-\2'); // GAS func
// #1: \1, \2 etc - didn't work: " -A- word so2me word he3re last."
test1 = text0.getText();
// js func, text2 OK: "Wo1rd word so-B-me word he3re last.", just in memory now
text1 = text1.replace(/(?:([Ss]o)\d(me))/, '$1-B-$2'); // working with str, not obj
// rt OK: "Wo1rd word so-B-me word he-C-re last."
rt = text1.replace(/(?:([Hh]e)\d(re))/, '$1-C-$2');
// #2: we used capturing groups ok, but replaced whole line and lost all formatting
text0.replaceText(".*", rt);
test1 = text0.getText();
}
}
Logger.log('Test finished')
}
Found a solution. It's a primitive enough but it can be a base for a more complex procedure that can fix all occurrences of capture groups, detect them, mix them etc. If someone wants to improve that - you are welcome!
function replaceTextCG(text0, re, to) {
var res, pos_f, pos_l;
var matches = text0.getText().match(re);
var count = (matches || []).length;
to = to.replace(/(\$\d+)/g, ',$1,').replace(/^,/, '').replace(/,$/, '').split(",");
for (var i = 0; i < count; i++) {
res = re.exec(text0.getText())
for (var j = 1; j < res.length - 1; j++) {
pos_f = res.index + res[j].length;
pos_l = re.lastIndex - res[j + 1].length - 1;
text0.deleteText(pos_f, pos_l);
text0.insertText(pos_f, to[1]);
}
}
return count;
}
function RegExp_test() {
var docParagraphs = DocumentApp.getActiveDocument().getBody().getParagraphs();
var i = 0, text0, count;
// equivalent of .asText() ???
text0 = docParagraphs[i].editAsText(); // obj
if (text0.getText() !== '') {
count = replaceTextCG(text0, /(?:([Ww]o)\d(rd))/g, '$1A$2');
count = replaceTextCG(text0, /(?:([Ss]o)\d(me))/g, '$1B$2');
count = replaceTextCG(text0, /(?:([Hh]e)\d(re))/g, '$1C$2');
}
Logger.log('Test finished')
}
I have a code that starts as a small amount of variables and makes more elements using those initial variables.
function new( x, y, width, height )
local object = {}
--border
object.border = { x = x, y = y, width = width, height = height }
--body
object.body = { x = x+1, y = y+1, width = width-2, height = height-2 }
--font
object.font = {}
object.font.size = (object.body.height+2)-(math.floor((object.body.height+2)/4)+1)
object.font.height = love.graphics.setNewFont( object.font.size ):getHeight()
--padding
object.padding = {}
object.padding.height = math.floor(object.border.height*(2/29))
object.padding.width = object.padding.height*3
--text
object.text = { input = '' }
object.text.centerHeight = math.ceil(object.body.y+((object.body.height-object.font.height)/2))
object.text.left = object.body.x+object.padding.width+object.padding.height
--backspacing
object.backspace = {key = false, rate = 3, time = 0, pausetime = 20, pause = true}
--config
object.config = { active = true, devmode = false, debug = false, id = gui.id(), type = 'textbox' }
gui.add(object)
return object.config.id
end
and when I modify something in the middle part, the whole thing becomes a mess because starting from the one i changed until the bottom ones value doesn't agree with each other
local x = gui.get(2)
x.body.height = 50
I'm looking if there's a way for these variables to be redefined, starting from them until the bottom, without: (a) making functions for each of the variables. and (b) editing the required parameters in the function.
and If there's none, are the an alternate way to do this efficiently?
EDIT:
the structure of the variables is as follow:
border->body->padding->font
what i needed is a way i can define any of them so that the one that follows also changes like:
object.body.x = 15
and it would collapse from that redefined variable until the bottom:
body->padding->font
i could just redefine them from the edited variable until the bottom like this:
--not the actual code, just an example of variables dependent on the variable above
object.body.x = 15
object.padding.width = object.body.x+1
object.font.size = object.padding.width+1
but that means I have to do the same when redefining the padding until the font which is extremely inefficient especially when I extended more elements.
example:
--padding->font
object.padding.width = 5
object.font.size = object.padding.width+1
I was bored and saw this question (again) along with a duplicate.
I started writing some code for fun, leading to this:
local function getNeededVars(tab,func)
local needed,this = {}
this = setmetatable({},{
__index = function(s,k)
-- See if the requested variable exists.
-- If it doesn't, we obviously complain.
-- If it does, we log it and return the value.
local var = tab.vars[k]
if not var then
error("Eh, "..k.." isn't registered (yet?)",5)
end needed[k] = true return tab.vals[k]
end;
}) func(this) return needed
end
local function updateStuff(self,key,done)
for k,v in pairs(self.levars) do
if v.needed and v.needed[key] then
if not done[v] then done[v] = true
self.vals[v.name] = v.func(self)
updateStuff(self,v.name,done)
end
end
end
end
local function createSubTable(self,key,tab)
return setmetatable({},{
__newindex = function(s,k,v)
tab[k] = v updateStuff(self,key,{})
end; __index = tab;
})
end
local dependenceMeta
dependenceMeta = {
__index = function(self,k)
-- Allow methods, because OOP
local method = dependenceMeta[k]
if method then return method end
local variable = self.vars[k]
if not variable then
error("Variable "..k.." not found",2)
end return self.vals[k]
end;
__newindex = function(self,k,v)
local variable = self.vars[k]
if not variable then
error("Use :Register() to add stuff",2)
elseif type(v) == "table" then
self.vals[k] = createSubTable(self,k,v)
return updateStuff(self,k,{})
end self.vals[k] = v updateStuff(self,k,{})
end
}
function dependenceMeta:Register(var,value)
local varobject = {func=value,name=var}
self.vars[var] = varobject
table.insert(self.levars,varobject)
if type(value) == "function" then
varobject.needed = getNeededVars(self,value)
self.vals[var] = value(self)
elseif type(value) == "table" then
self.vals[var] = createSubTable(self,var,value)
elseif value then
self.vals[var] = value
end
end
function dependenceMeta:RegisterAll(tab)
for k,v in pairs(tab) do
self:Register(k,v)
end
end
local function DependenceTable()
return setmetatable({
levars = {};
vars = {};
vals = {};
},dependenceMeta)
end
local test = DependenceTable()
test:Register("border",{
x=20; y=50;
height=200;
width=100;
})
test:Register("body",function(self)
return {x=self.border.x+1,y=self.border.y+1,
height=self.border.height-2,
width=self.border.width-2}
end)
test:Register("font",function(self)
local size = (self.body.height+2)-(math.floor((self.body.height+2)/4)+1);
return { size = size; -- Since we use it in the table constructor...
height = size-4; --love.graphics.setNewFont( self.font.size ):getHeight();
-- I don't run this on love, so can't use the above line. Should work though.
}
end)
test:Register("padding",function(self)
local height = math.floor(self.border.height*(2/29))
return { height = height; width = height*3 } -- again dependency
end)
test:Register("text",{input=""}) -- Need this initially to keep input
test:Register("text",function(self)
return { input = self.text.input;
centerHeight = math.ceil(self.body.y+((self.body.height-self.font.height)/2));
left = self.body.x+self.padding.width+self.padding.height;
}
end)
test:Register("backspace",{key = false, rate = 3, time = 0, pausetime = 20, pause = true})
-- Again, didn't use gui.id() on the line below because my lack of LÖVE
test:Register("config",{active=true,devmode=false,debug=false,id=123,type='textbox'})
print("border.x=20, test.text.left="..test.text.left)
test.border = {x=30; y=50; height=200; width=100;}
print("border.x=30, test.text.left="..test.text.left)
test.border.x = 40
print("border.x=40, test.text.left="..test.text.left)
It's a lot of code, but I liked writing it. It gives this nice output:
border.x=20, test.text.left=73
border.x=30, test.text.left=83
border.x=40, test.text.left=93
All properties only get recalculated when one of its dependencies is edited. I made it also work with subtables, which was a bit tricky, but at the end actually seems quite easy. You can edit (for example) the body field by setting it to a completely new table or by setting a field in the already existing table, as seen in the last few lines of the code snippet. When you assign it to a new table, it'll set a metatable on it. You can't use pairs (& co) neither, unless you use 5.2 and can use __pairs.
It might solve your problem. If not, I had fun writing it, so at least it'll always be something positive that I wrote this. (And you have to admit, that's some beautiful code. Well, the way it works, not the actual formatting)
Note: If you're gonna use it, uncomment the love.graphics and gui.id part, as I don't have LÖVE and I obviously had to test the code.
Here's a quick "summary" of my thing's API, as it might be confusing in the beginning:
local hmm = DependenceTable() -- Create a new one
print(hmm.field) -- Would error, "field" doesn't exist yet
-- Sets the property 'idk' to 123.
-- Everything except functions and tables are "primitive".
-- They're like constants, they never change unless you do it.
hmm:Register("idk",123)
-- If you want to actually set a regular table/function, you
-- can register a random value, then do hmm.idk = func/table
-- (the "constructor registering" only happens during :Register())
-- Sets the field to a constructor, which first gets validated.
-- During registering, the constructor is already called once.
-- Afterwards, it'll get called when it has to update.
-- (Whenever 'idk' changes, since 'field' depends on 'idk' here)
hmm:Register("field",function(self) return self.idk+1 end)
-- This errors because 'nonexistant' isn't reigstered yet
hmm:Register("error",function(self) return self.nonexistant end)
-- Basicly calls hmm:Register() twice with key/value as parameters
hmm:RegisterAll{
lower = function(self) return self.field - 5 end;
higher = function(self) return self.field + 5 end;
}
-- This sets the property 'idk' to 5.
-- Since 'field' depends on this property, it'll also update.
-- Since 'lower' and 'higher' depend on 'field', they too.
-- (It happens in order, so there should be no conflicts)
hmm.idk = 5
-- This prints 6 since 'idk' is 5 and 'field' is idk+1
print(hmm.field)
You could use setfenv (if Lua 5.1) to remove the need of 'self.FIELD'. With some environment magic you can have the constructor for 'field' (as an example) just be function() return idk+1 end.
You could make use of metatables, more specific, the __newindex field:
(Well, need to combine it with the __index field, but eh)
function new(x, y, width, height )
local object = {
font = {}, padding = {}, text = {input=''}, -- tables themself are static
-- also I assume text.input will change and has to stay the way it is
}
-- more static data here (yes yes, I know. The code is a bit ugly, but if it works fine...)
object.config = { active = true, devmode = false, debug = false, id = gui.id(), type = 'textbox' }
object.backspace = {key = false, rate = 3, time = 0, pausetime = 20, pause = true}
object.border = { x = x, y = y, width = width, height = height }
-- stuff that has to be calculated from the above variables goes below
local border = object.border
local function calculate()
--border
--body
object.body = { x = border.x+1, y = border.y+1, width = border.width-2, height = border.height-2 }
--font
object.font.size = height-(math.floor(height/4)+1)
object.font.height = love.graphics.setNewFont( object.font.size ):getHeight()
--padding
object.padding.height = math.floor(object.border.height*(2/29))
object.padding.width = object.padding.height*3
--text
object.text.centerHeight = math.ceil(object.body.y+((object.body.height-object.font.height)/2))
object.text.left = object.body.x+object.padding.width+object.padding.height
--backspacing
--config
end
calculate()
local proxy = setmetatable({},{
__index = object; -- proxy.abc returns object.abc (to get width, use proxy.border.width)
__newindex = function(s,k,v)
-- fires whenever 'proxy[k] = v' is done
-- I assume you'll only change x/y/width/height, as other properties are dynamic
-- Doing 'proxy.x = 123' is the same as 'object.border.x = 123' + recalculating
object.border[k] = v -- Actually apply the change
calculate() -- Recalculate the other properties that depends on the above
end;
})
gui.add(object)
return object.config.id
end
You can run code like proxy.x = 12 to edit the X property. All values will be recalculated. It's not the best, but your code a tiny bit annoying to improve. (But hey, if it works fine for you, it's good)
Note: You can only set x, y, width and height. You can get all properties the old way though, e.g. proxy.padding.width (Mind that proxy.x doesn't work. Use proxy.border.x)
I managed to do it, some other way.
but I have a question, I had this code before
def jumphunt(start, mylist, count = 0):
if count < len(mylist):
place = mylist[start]
print(place)
if place == 0:
return True
elif start >= len(mylist) or start < 0:
return False
move_left = (start - place)
move_right = (start + place)
return jumphunt(move_right, mylist, count+1) or jumphunt(move_left, mylist, count+1)
else:
return False
but for some reason it's not trying both ways
to get to the last item on the list.
for example: [1,2,2,3,4,5,3,2,1,7,0] and ,start=mylist[0]
it supposed to jump like this (from 1-2-4-1-left to 2-left to 5-right to 0)
but it keeps trying to go right and then index is out of range etc.
I thought that if u use return of or this or that, it will try both until it reaches True, why won't it work here?
Thanks!
Include the value you want to keep as a default parameter for the method, like this:
def my_func(int, list, i=0):
a = (i + int)
if int == 0:
return True
elif a > len(list):
i -= int
else:
i += int
int = list[i]
my_func(int, list, i)
Bear in mind that it may not even always be possible to arrive at the end of the list doing the jumping pattern you describe, and even if it is possible, this method may choose the wrong branch.
A better algorithm would look like this:
def branching_search(list, start):
marks = [0]*len(list)
pos = start
while list[pos]!=0:
marks[pos]++
if marks[pos] % 2 == 0 and pos + list[pos] < len(list):
pos += list[pos]
elif marks[pos] % 2 == 1 and pos - list[pos] >= 0:
pos -= list[pos]
else:
return False
if all(item == 0 or item > 1 for item in list)
return False
return True
This way, if it comes to an item that it has already visited, it will decide to go the opposite direction that it went last time. Also, if it comes to an item that it can't leave without going out-of-bounds, or if there is not way to get to the end, it will give up and return.
EDIT: I realized there are a number of flaws in this algorithm! Although it is better than the first approach, it is not guaranteed to work, although the reasons are somewhat complicated.
Just imagine this array (the unimportant elements are left blank):
1, 2, , 5, , , , , 5, 0
The first two elements would get only one mark (thus the loop checking condition would not work), but it would still get stuck looping between the two fives.
Here is a method that will always work:
def flood_search(list):
marks = [[]]*len(list)
marks[0] = [0]
still_moving = True
while still_moving:
still_moving = False
for pos in range(0,len(list)):
if marks[pos]:
if pos + list[pos] < len(list) and not marks[pos + list[pos]]:
marks[pos + list[pos]] = marks[pos] + [list[pos]];
pos += list[pos]
still_moving = True
if pos - list[pos] >= 0 and not marks[pos - list[pos]]:
marks[pos - list[pos]] = marks[pos] + [-list[pos]];
pos -= list[pos]
still_moving = True
return marks[-1]
This works by taking every possible branch at the same time.
You can also use the method to get the actual route taken to get to the end. It can still be used as a condition, since it returns an empty list if no path is found (a falsy value), or a list containing the path if a path is found (a truthy value).
However, you can always just use list[-1] to get the last item.
I have a problem with a function in matlab. This specific function is for filtering light signals. As you can see below I added the coding I’ve used in the function and in the while loop itself. The code is written for a NXT Lego robot.
Is there any tip how to get the count variable ( i = i + 1 ) to work in the function, so we can plot Light(i)? Because we’re getting a bunch of error messages when we try different codes to make it work.
function [light] = filter_func( i)
lightI(i) = GetLight(SENSOR_3);
if i==1
light(i)=lightI(i)
elseif i==2
light(i) = 0.55*lightI(i) + 0.45*lightI(i-1)
else
light(i) = 0.4*lightI(i) + 0.3*lightI(i-1) + 0.3*lightI(i-2);
end
end
i=1
while true
lightI(i) = GetLight(SENSOR_3); % Get’s a lightvalue between 0 and 1024.
if i>2
light =filter_func(i)
light=round(light);
else
light(i) = GetLight(SENSOR_3);;
end
i=1+i
plot(light(end-90:end), 'r-');
title('Lightvalue')
axis([0 100 0 1023]) ;
end
You probably mainly get errors because you are not allowed to mix script and functions like this in MATLAB (like you are in Python).
Your filter function is only used when i>2 so why are you doing the first 2 tests? It seems like you want lightI as a global variable, but that is not what you have done. The lightI inside the function is not the same as the one in the while loop.
Since your while loop runs forever, maybe you don't need to worry about updating the plot the first two times. In that case you can do this:
filter = [0.4 0.3 0.3]';
latest_filtered_light = nan(90,1);
lightI = [];
p = plot(latest_filtered_light, 'r-');
title('Lightvalue')
axis([0 100 0 1023]) ;
while True
lightI(end+1,1) = rand*1024; % Get’s a lightvalue between 0 and 1024.
if i>=3
new_val = lightI(end-2:end,1)'*filter;
latest_filtered_light = [latest_filtered_light(2:end);...
new_val];
set(p, 'ydata', latest_filtered_light)
drawnow
end
end
I think it is an important point to not call plot every time - at least if you are the least concerned about performance.