Is there a way to only keep the last two saved values of the recursion in a dictionary and delete the rest? - python-3.7

i am using memoization to save the last calculated values of fibonacci numbers in a dictionary. Since (i suppose) that we don't need all of the values that were previously calculated in our dictionary so, i want to delete them. specifically i only want to keep only the last two calculated fibonacci numbers, is there a way to do it?
import sys
sys.setrecursionlimit(10000)
cache = {}
def fib(n):
if n in cache:
return cache[n]
elif n <= 2:
value = 1
else:
value = fib(n-1) + fib(n-2)
cache[n] = value
return value
print(fib(1000))

ok i found it.
cache = {}
for x in range(1, 1000001):
if x > 4:
cache.pop(x-3, x-4)
if x <= 2:
value = 1
cache[x] = value
else:
value = cache[x - 1] + cache[x - 2]
cache[x] = value
print(value)

Related

Logic behind Two Number Sum Algorithm

Could someone explain to me the logic behind this hashMap algorithm? I'm getting confused about how the algorithm receives the total sum. I'm starting to learn about algorithms, so it's a little confusing for me. I made comments in my code to pinpoint each line code, but I'm not sure I'm grasping logic correctly. I'm just looking for an easier way to understand how the algorithm works to avoid confusing myself.
//**calculate Two Number Sum
func twoNumberSum(_ array: [Int], _ targetSum: Int) -> [Int] {
//1) initilize our Array to hold Integer Value: Boolean value to store value into hashTable
var numbersHashMap = [Int:Bool]()
//2) create placeHolder called number that iterates through our Array.
for number in array {
//3) variable = y - x
let match = targetSum - number
//4) ??
if let exists = numbersHashMap[match], exists {
//5) match = y / number = x
return [match, number] //
} else {
//6) Store number in HashTable and repeats
numbersHashMap[number] = true
}
}
return []
}
twoNumberSum([3,5,-4, 8, 11, 1, -1, -6], 10)
// x = Number
// y = Unknown *Solve for Y*
Sure, I can walk you through it. So we have a list of numbers, are we are trying to find two numbers that add together to make the specified target. To do this, for each number x, we check if (target - x) is in the list. If it is not, then we add x to the list. If it is, then we return x and (target - x).
Step 4 in your code is the part where we check if (target - x) is in the list. To see why this makes sense, let's walk through an example.
Say we have [2, 3, -1] and our target is 1. In this case, we first consider x = 2 and check our hashmap for (target - x) = (1 - 2) = -1. Since -1 is not in the hashmap, we add 2 to the hashmap. We then consider x = 3 and check for (1 - 3) = -2. Again, -2 is not in the hashmap, so we add it. Now we check x - -1. In this case, when we check (target - x) = (1 - (-1)) = 2, 2 is in the hashmap. Intuitively, we have already "seen" 2, and know that 2 and -1 can be added to get our value.
This is what provides the speed optimization over checking every two numbers in the list.

Check if assigned elements satisfy a condition in OR-Tools

I have say 100 elements that I want to assign to say 10 spots.
# the elements list holds 100 variables that signify the assignment to a spot
elements = [model.NewIntVar(1, 10) for i in range(100)]
Each of my element has a specific size. Now I want to model one (set of) constraint(s) per spot that says: The added sizes of all elements assigned to this spot lies in a fixed range.
So if spot 1 gets elements 1, 16 and 64 assigned, and their sizes are 1521, 1732, 1431 and my range is (3000, 6000) that would be ok. But if too many or too large elements (or too few/small) get assigned to spot 1, that would not be ok.
Something like the following, which does not work:
for spot in range(10):
sum_ = sum([get_size(e) for e in elements if e == spot]) # if think if e == spot is what fails
model.Add(sum_ >= 3000)
model.Add(sum_ <= 6000)
How can I model such a thing? I have looked at channeling constraints but I can't quite wrap my head around it.
I think it is better to model the assignment as a boolean:
from ortools.sat.python import cp_model
model = cp_model.CpModel()
solver = cp_model.CpSolver()
all_spots = range(10)
all_elems = range(100)
elements = {
(elem, spot): model.NewBoolVar(f"{elem} in spot {spot}")
for elem in all_elems
for spot in all_spots
}
# only one spot for element
for elem in all_elems:
model.Add(sum(elements[elem, spot] for spot in all_spots) == 1)
for spot in all_spots:
# taking the element id as its size
sum_ = sum(elements[elem, spot] * elem for elem in all_elems)
model.Add(sum_ >= 0)
model.Add(sum_ <= 500)
solver.Solve(model)
for (elem, spot), boolean in elements.items():
if solver.Value(boolean):
print(boolean)
See:
https://github.com/google/or-tools/blob/stable/ortools/sat/samples/multiple_knapsack_sat.py
https://github.com/google/or-tools/blob/stable/ortools/sat/samples/binpacking_problem_sat.py
https://github.com/google/or-tools/blob/stable/examples/python/balance_group_sat.py#L102

Merging to dataset together according to key

I have two datasets stored in a cell array and a double array, respectively. The design of the two arrays is:
Array 1 (name: res) (double) is composed of two columns; a unique id column and a data column.
Array 2 (name: config) (cell array) contains 3 column cells, each with a string inside. The last cell in the array contains a id double integer matching the id's in Array 1. The double integer in the cell array is converted to a double when necessary.
I want to merge the two datasets in order to have the 3 cells in the cell array AND the result column in Array 1 in one common cell array. How do I do this?
I have the following code. The code does not return the correct order of the results.
function resMat = buildResultMatrix(res, config)
resMat = {};
count = 1;
count_max = size(res,1)/130;
for i = 1 : size(res,1)
for j = 1 : size(res,1)
if isequal(res(i),str2double(config{j,3}))
if i == 1
resMat(end+1,:) = {config{j,:} res(j,2:end)};
else
if count == 1
resMat(end+1,:) = {config{j,:} res(j,2:end)};
elseif count == count_max
resMat(end+1,:) = {config{j,:} res(j,2:end)};
else
resMat(end+1,:) = {config{j,:} res(j,2:end)};
end
count = count + 1;
end
end
end
count = 1;
end
end
First convert the id in config to numbers:
config(:,3) = num2cell(str2double(config(:,3)));
Then run this:
res = sortrows(res,1);
config(:,4) = num2cell(res(cell2mat(config(:,3)),2))
this will put the data from res in the 4th column in config in the row with the same id.

Exercises in programming style with Scala

I've started to read the "Exercises in programming style" book recently and one of the tasks there is to implement each programming style in a language of your choice. I decided to go with Scala (I'm fairly new to it) and I'm already stuck with the first "good old school" style. The constraints are:
Very small amount of primary memory, typically orders of magnitude smaller than the data that needs to be processed/generated. (The example sets the limit to 1024 cells)
No labels -- i.e. no variable names or tagged memory addresses. All we have is memory that is addressable with numbers.
Original example (which reads a file line by line and counts the words) is in Python and goes like this:
data = []
data.append([]) # data[1] is line (max 80 characters)
data.append(None) # data[2] is index of the start_char of word
data.append(0) # data[3] is index on characters, i = 0
data.append(False) # data[4] is flag indicating if word was found
data.append('') # data[5] is the word
data.append('') # data[6] is word,NNNN
data.append(0) # data[7] is frequency
...
f = open(sys.argv[1])
# Loop over input file's lines
while True:
data[1] = [f.readline()]
...
So we see there are some variables (f and data) but the main idea is to keep it to a minimum and use python array as a bunch of "memory addresses".
Is it even possible to implement old-school-programming style (no variable names or tagged memory addresses) in Scala? Specifically is there a way to avoid "line" variable when reading file content?
for (line <- Source.fromFile("example.txt").getLines) {
println(line.toUpperCase)
}
Reading the file content into an array similar to the original example doesn't work because it's doesn't have an extractor (value data is not a case class, nor does it have an unapply/unapplySeq member).
P.S. I'm very well aware of the fact that the whole task is probably a 5-liner in Scala but that's not the point.
Sure you can abstain from introducing variables besides the data-array (and solve the problem imperative-style). Simply put everything into your array instead of assigning it to a local variable.
Obviously, the code will be a nightmare, because the array won't be typed and you won't have any meaningful names for any of your data, but I'm assuming that's what you're aiming for with this exercise.
import scala.io.Source
/**
* data 0 : file as line iterator
* data 1 : index of first unused data cell
* data 2 : current line
* data 3 : index of the first letter of the current word
* data 4 : index of the last letter of the current word
* data 5 : current word
* data 6 : temp index to find already initialized words
* data 7 : flag: Word found
* data 8, 10, 12, ... words
* data 9, 11, 13, ... frequencies
*/
object GoodOldSchool {
def main(args: Array[String]): Unit = {
val data: Array[Any] = new Array[Any](1024)
data(0) = Source.fromFile(args(0)).getLines()
data(1) = 8 // first free cell
while (data(0).asInstanceOf[Iterator[String]].hasNext) {
data(2) = data(0).asInstanceOf[Iterator[String]].next()
data(3) = 0 // index first letter of current word
data(4) = 0 // index last letter of current word
// find index last letter of current word
while (data(4).asInstanceOf[Int] < data(2).asInstanceOf[String].length) {
// find the next space (we ignore punctuation)
while (data(4).asInstanceOf[Int] < data(2).asInstanceOf[String].length && data(2).asInstanceOf[String].charAt(data(4).asInstanceOf[Int]) != ' ') {
data(4) = data(4).asInstanceOf[Int] + 1
}
data(5) = data(2).asInstanceOf[String].substring(data(3).asInstanceOf[Int], data(4).asInstanceOf[Int]) // current word
data(6) = 8 // cell index
data(7) = false // word already found
8 until data(1).asInstanceOf[Int] by 2 foreach { _ =>
// Here, we do a case-sensitive word comparison
if (data(5) == data(data(6).asInstanceOf[Int])) {
data(data(6).asInstanceOf[Int] + 1) = data(data(6).asInstanceOf[Int] + 1).asInstanceOf[Int] + 1 // increment frequency
data(7) = true
}
data(6) = data(6).asInstanceOf[Int] + 2
}
if (data(7) == false) {
// create new frequency, because word was not discovered before
data(data(1).asInstanceOf[Int]) = data(5) // set word
data(data(1).asInstanceOf[Int] + 1) = 1 // set frequency
data(1) = data(1).asInstanceOf[Int] + 2 // used up two cells, update index of next free cell
}
// move to next word
data(3) = data(4).asInstanceOf[Int] + 1
data(4) = data(3)
}
}
data foreach println // let's have a look at our result
}
}
To get the total words count in the given file, the following scala code can be used:
Source.fromFile("example.txt")
.getLines.map { line => line.trim.split(" ").length}
.reduceLeft { _ + _ }

How to convert string to integer in JES

I am trying to do an assignment in JES a student jython program. I need to convert our student number taken as a string input variable to pass through our function i.e.
def assignment(stringID) and convert it into integers. The exact instructions are:
Step 1
Define an array called id which will store your 7 digit number as integers (the numbers you set in the array does not matter, it will be over written with your student number in the next step).
Step 2 Your student number has been passed in to your function as a String. You must separate the digits and assign them to your array id. This can do this manually line by line or using a loop. You will need to type cast each character from stringID to an integer before storing it in id.
I have tried so many different ways using the int and float functions but I am really stuck.
Thanks in advance!
>>> a = "545.2222"
>>> float(a)
545.22220000000004
>>> int(float(a))
545
I had to do some jython scripting for a websphere server. It must be a really old version of python it didn't have the ** operator or the len() function. I had to use an exception to find the end of a string.
Anyways I hope this saves someone else some time
def pow(x, y):
total = 1;
if (y > 0):
rng = y
else:
rng = -1 * y
print ("range", rng)
for itt in range (rng):
total *= x
if (y < 0):
total = 1.0 / float(total)
return total
#This will return an int if the percision restricts it from parsing decimal places
def parseNum(string, percision):
decIndex = string.index(".")
total = 0
print("decIndex: ", decIndex)
index = 0
string = string[0:decIndex] + string[decIndex + 1:]
try:
while string[index]:
if (ord(string[index]) >= ord("0") and ord(string[index]) <= ord("9")):
times = pow(10, decIndex - index - 1)
val = ord(string[index]) - ord("0")
print(times, " X ", val)
if (times < percision):
break
total += times * val
index += 1
except:
print "broke out"
return total
Warning! - make sure the string is a number. The function will not fail but you will get strange and almost assuredly, useless output.