#algos-and-data-structs
1 messages · Page 3 of 1
for i in range(1, m) :
for j in range(1, n) :
dp[i] [j] = min(dp[i] [j-1]+1, dp[i] [j-1]+1, dp[i-1] [j-1]+(str1[j-1]==str2[i-1]
why does it still work on most cases if i put n+1 and m+1 instead of n, m shoulsn't I get an error
and why does it not work in this case in particular
problem is, how do I even create the tuple without making either a very long line e.g. tup = (1,2,3,4,5,6,7,etc) or adding a bunch of separate lines e.g. category = 123 tup += category or make my code more confusing by not naming these parameters and going straight to storing them in the tuple/list e.g. tup += 123?
Hey @dark aurora!
You either uploaded a .txt file or entered a message that was too long. Please use our paste bin instead.
I wish there was a way to use a dictionary for inserting to mysql. That would solve my problem most elegantly. But there does not seem to be command that turns {"category": 123, "url": 456} into (123, 456) Or is there?
EDIT: may have found answer in https://stackoverflow.com/questions/9336270/using-a-python-dict-for-a-sql-insert-statement
so I imagined rewriting the functions to return a namedtuple and accept a namedtuple as argument in this code
.values(), though relying on dict ordering always feels a bit iffy
namedtuple is a better fit for this imo
e.g. my_tuple(category=123, url=567)
assuming the function where the variables are set goes like this:
url = 567```
how do I turn this into a named tuple?
wait, what is a namedtuple? I thought you were talking about a tuple with a name lol
let me google one sec
my_tuple = namedtuple('my_tuple', ['category', 'url'])
it's a tuple but with named fields
so you can write
my_tuple(category=123, url=567)
```to create a tuple or
```py
existing_tuple = (123, 567)
my_tuple(*existing_tuple)
```to create from an existing tuple
can i break it down to chunks? otherwise it would still create a very long line, I think
I mean, you can always add newlines to make things more readable, e.g.
my_tuple(
category=123,
url=567
)
nice!
share the full code?
who knows how to solve a rubik's cube
can anyone help me kadane algo?
how can i calculate/code, given m and n, the amount of longest path (except in cases like 2x2, essentially all positions must be visited) solutions to traverse from the top left to the bottom right of that grid with dimensions m x n?
seems like this but on a general grid and not a square grid http://oeis.org/A121788
i don’t really understand what that means
can y'all read the problems in CLRS and start dreaming up solutions? i feel like most of them i read and I'm completely in the dark on even where to begin. is this normal?
what is CLRS
Introduction to Algorithms is a book on computer programming by Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. The book has been widely used as the textbook for algorithms courses at many universities and is commonly cited as a reference for algorithms in published papers, with over 10,000 citations documented on C...
can someone tell me why solution A results in 40 but solution B results in 59 for [4,-2,-3,4,1]. It's driving me crazy because they are functionally IDENTICAL!! Question here https://leetcode.com/problems/sum-of-subarray-ranges/
Solution A
sum = 0
for i in range(len(nums)):
for j in range(i, len(nums)):
sum += (max(nums[i], nums[j]) - min(nums[i], nums[j]))
return sum
Solution B
res = 0
for i in range(len(nums)):
minVal = nums[i]
maxVal = nums[i]
for j in range(i, len(nums)):
minVal = min(minVal, nums[j])
maxVal = max(maxVal, nums[j])
res += maxVal - minVal
return res
basically like the bible for algorithms
god a book
its over 1200 pages
still dont know what to make of this line in the pseudocode
https://leetcode.com/problems/rotate-image/
this is the ENTIRE solution, i want to ask what is that A[:] doing ?
class Solution:
def rotate(self, A):
A[:] = zip(*A[::-1])
if you reverse the rows and transpose, it ends up being a 90 degree rotation, A[::-1] reverses, the zip is a transpose
the assignment to A[:] is to replace the entire slice of A
to assign A in-place
they aren't identical, B keeps track of the prefix maximum/minimum as it goes, A does the max/min of adjacent values
this change should make them identical, though this is a lot slower
sum = 0
for i in range(len(nums)):
for j in range(i, len(nums)):
sum += max(nums[i:j+1]) - min(nums[i:j+1])
return sum
i see they are in-place with A[:], thank you
it's just a set union, python has a built in set you can use
in fact return {a[m]} | recursivecall(...) is valid python
(although not optimal performance-wise)
this is a better option for performance
s = recursivecall(...)
s.add(a[m])
return s
dicts and sets are very similar
one gotcha is that the empty set is set()
because {} is a dict
is time complexity synonymous with lines of code executed
or rather is it approximately equal to
this question comes from the cover files of a given script and my exercise yesterday where i added up all the lines executed by randomized quicksort to see how it runs compared with the expected running time
and it was more than expected for a given input, but as another user pointed out, thats bc i neglected to take into account the constant in the theta notation
and some small constant like 5 could easily upper bound the lines executed for the given input of one input array of n=1000 elements
i think im understanding it correctly unless there is some deeper layer of like computations that the code is doing that i cannot see with a cover file, and that those computations are what is meant by time complexity
in reality different cpu instructions take different amount of time
Omg thank you so much
when analyzing algorithms you assume that there is some set of operations that take constant time, and work from there
so would it be in error for me to work from the cover file and show that the expected runtime is consistent with the number of lines executed for a given input n?
like for example, randomized quicksort is O(nlgn). my version ran and executed 43k lines. for my given input of an array of n=1000 integers, 1000*lg(1000) = 9,965. so while it took more lines (computations?) than expected, this is easily upper bounded by say, c of 5, and so it is indeed true that randomized quicksort if O(nlgn)
this is a legitimate analysis i think unless i'm completely off base
trying to say anything from a single data point is going to be iffy
you could run for some different n and plot the results
but if you do that, why not just plot the time taken for different n instead?
the number of operations is used as a proxy for time, when possible measuring the real deal will be more useful
so let say i wanted to analyze the same algorithm but with arrays of n=1000, n=10k, n=50k, n=100k. what would a rudimentary analysis be comprised of
furthermore if i were to plot the number of lines executed (after adding up all the lines from each cover file) for each, would it be helpful to ask excel to plot an equation of that line?
Plotting the n and time taken for each. Trying to create a function that matches/fits that curve / guessing the complexity. Using that guess as the goal in a proof to show that it is actually that runtime.
hmm makes sense ok
(You can just use whatever plotting program, desmos is fine)
Also you want multiple runs averaged.
so you mean multiple runs at n=1k, multiple at 10k, etc
If you run your program and it takes 10 time units the first run, 20 the second, 13 the third, etc. You just average them and plot those.
Just to deal with the randomness.
Like maybe your PC happened to be running something in the background.
i'm not looking at time units but the cover file and adding up all the lines executed
which i suppose could be my "time units"
Yeah ticks / time units / steps.
ok
im going to also track time elapsed within python, but that is secondary to the steps
./ not as important
Even real time will be fine if you just average the runs.
eh thats a no-no for my course
It's just to get a guess for the proof.
as said, number of operations is a proxy for time, so if you can measure time why not do it directly?
The proof is the formal part. Real time is what ends up mattering in engineering / real programming (because it's the reality of how long it runs).
But whatever, courses have their ways.
i am measuring time directly using pythons time function but the prof said that takes backseat to operations performed / steps
time complexity for expected growth, real time to have a baseline
real time measurements, especially in lower level languages, is quite fun
i've sort of lost my way in CLRS, need to get back to reading chapters. i am all over the place
Reality + prediction for further because you probably don't want to test all possible N (good luck with that :))
you can often see where you start missing cache, because the slope for the time taken can change dramatically
In software engineer, I don't ever count steps. Just real time and proof of runtime complexity for prediction for large N.
Steps can be seen by just looking at the code, no need to actually count it with a program.
(Although it can be nice, just don't really need it in practice (except maybe some rare cases))
good to know
i was gonna ask whether y'all build heaps out of classes or arrays but then i remembered python has a built in heap function, so nvm
clrs seems to imply you can implement them as arrays
Arrays.
(Not in Python)
(This gets into more details about how modern machines work so I would not worry about it)
if y'all wanna ask me anything you think i should know going into a grad lvl algos course, i am all ears
e.g. in a loop like
for i in range(n):
for j in range(i+1, n):
thing
```I know the `thing` will run like n(n-1)/2 times because math, I don't really need to count
im going to try to write this in summation form as practice
(You counted in the math sense of counting (combinatorics), but not by program or manually by hand)
heapq uses lists for the heap
lazy counting :P
Yeah efficient / more advanced counting. In math it's the branch of "counting". Which includes stuff like counting how many combinations a Rubick's cube has (without just counting each one by one manually).
(And also how many times steps in an algorithm run)
just put the question/code here, someone might look at it
is this described in one summation or two
either really, it's a nested summation of ones, or a single summation n-1 + n-2 + ...
easy enough to check with a print, no?
why not classes?
you mean defining a node class and whatever? it's generally slower
hmm ok
having stuff nearby in memory is important for performance, so storing the data in an array rather than a node based structure is better
i guess my binary trees will be slow then
I mean, it depends. If you're doing recursion in python you'll have a fun time in general
for i in range(n):
i+=1```
(python is at the kind of slowness where I'm not scared about cache misses)
Just to clarify and make sure we are on the same page, what do you mean by classes? I kind of made an assumption, but could you write it out?
class = Node:
__init__(self, somestuff)
class = BinTree:
__init__```
And each node has a left, right?
yes each node will have properties like left, right, maybe a color in the case of red black trees
Yeah, so, when you create an object in Python, it allocates memory for it. And it does so on a heap.
(Or if you did it in another language this way you would probably also have it on a heap)
do you mean the heaps as in CLRS heapsort algorithm?
the heap data structure?
im getting a feeling thats a different heap than the data structure
Memory pool would probably be a better term.
What matters here is that when it allocates those objects, they may not be next to each other in memory, they can be scattered all about.
not really. besides, the loop you wrote is weird, it doesn't compute a sum, it increments the index which will be overwritten on the next iteration anyway
Yeah arrays are often contiguous chunks of memory.
is this correct:
i=0
for i in range(11):
i+=1
print(i)
And the reason that matters is because of how you need to get data / memory from devices such as RAM to the CPU so it can perform work on it.
list in python is a contiguous array of pointers, though the actual objects are stored elsewhere
If you get the first element of an array, the CPU won't get just that one element, one-by-one, because now it's bottlenecked by having to wait on each of them. By the time a single element from the array arrives at the CPU, the CPU could have sorted a small array.
(CPUs are that fast (ridiculous))
you mean to write this, right?
s=0
for i in range(11):
s+=1
So to help solve this issue, the CPU will fetch memory in chunks. And if you have a nice contiguous array, and it sees that you are just looping over that, it can predict what it will need next and fetch a whole bunch all at once.
If your nodes are randomly located in memory, it will have a very hard time.
no, seems like a very greedy problem
it works the way i wrote it as well, but yes perhaps for clarity's sake that is better. so might i describe this loop as:
(It's jumping around)
ok i'm with you. the reason i implemented my binary trees as classes is bc i think thats how the pseudocode was written, in other words i don't think the pseudocode would work on a binary tree built based on an array. that or i couldn't figure out how to build one from an array
no that's not how you write sums, my loop is s = \sum_{i=0}^{10} 1
is there a LaTeX bot here?
.latex $\sum_{i=0}^{10} 1$
Implementing them as arrays is an optimization, and does not matter as much in Python because Python is already slow. Use what you think makes it easier to understand until it becomes a problem (slowing down your program when profiling).
I should petition enabling the latex thing here...
(For these kinds of things it's best to do the simple to understand solution until it's actually a problem)
i can paste this in the math server and copy here
(For a non-garbage-collected programming language it can be easier to just use the array approach (so faster and more simple to work with))
(And technically freeing your heap is now O(1) instead of O(n) (the entire heap, if you want it all gone))
but yeah, that's
s = sum(1 for i in range(11))
or
s = 0
for i in range(11):
s += 1
i'm feeling pretty good about starting class this month until i see stuff like this
the exercises on mergesort with insertionsort once the subproblems get small enough were suprisingly intuitive
Depends on what you want to do. Many programmer have probably not made a data structure in years other than for interviews.
i've been practicing using substitution and master's theorem yeah
this is what i should practice up on now tbh
If you want to make new things, and not just reuse code / libraries, etc, you will probably need to be able to do it from scratch.
Then you need both the memorization and from scratch practice.
so what would you example then be, the n(n-1)/2 one in math notation? i'll repaste
for i in range(n):
for j in range(i+1, n):
thing
if you write the notation i can convert to latex
you don't need the latex command
You want both the fast pattern matching based on what you have memorized and the slower from scratch analytical ability.
It helps to write it out by hand. Play around with simple cases (base cases and near base cases) and then see how those cases relate to each other (it may be a recursive / DP thing).
meh, I'm used enough to writing LaTeX, though this should really be in some equation environment
\sum_{i=0}^{n-1} \sum_{j=i+1}^{n-1} 1
= \sum_{i=0}^{n-1} n - (i+1)
= \frac{n (n-1)} 2
sorry i meant if you write the latex i can put it through and get the output
I don't have a LaTeX environment readily available on my phone, sadly :P
I made a request to activate it here
You would expect this channel of all channels to support latex.
it should be fixed soon enough
but yeah, that
ok perfect thank you
for better or worse I've written enough LaTeX to read the source code as math pretty fluently
its certainly better for your wallet/career
if you're not writing even things like shopping lists in LaTeX, what are you even doing? 
im just happy i read something about a heap and knew the min or max elements would be something in the realm of 2^h nodes where h is the height of the heap
i still can't read that summation notation 🙄
maybe it doesn't matter. i just need my B
\section{To buy}
\begin{itemize}
\item bananas \\
\item chocolate \\
\item milk
\end{itemize}
shopping list with class
the Σ notation overall? it's not so weird
this is all there is to it
\sum_{i=a}^b f(i) = f(a) + f(a+1) + \ldots + f(b-1) + f(b)
it's just a shorthand to write such a long sum
i thought that \sum is the inline text style, and that \Sum was the normal style, but i guess that's not the case. apparently inline depends on context, and may or may not require \displaystyle to say otherwise
depends if it's inline or display math, yeah
I’m not understanding in CLRS when they talk about an array having the aspect heapsize. I can call len(array) in Python, does there exist a similar heap(array) function?
How would I add a parent attribute to my binary tree based on node classes
In an array based approach I think it’d be tied to the indices
I’ll have to take a look at my code, I’m just in the book rn
in python you let the storage be dynamic size, so len == heap-size if you use heapq
you just store the parent, much like you would the children?
class Node:
def __init__(self, key):
self.key = key
self.left = None
self.right = None
def __repr__(self):
return str(self.key)
class BinaryTree:
def __init__(self, root):
self.root = Node(root)
tree = BinaryTree(7)
def tree_insert(root, key):
if key <= root.key:
if root.left is not None:
tree_insert(root.left, key)
else:
root.left = Node(key)
else:
if root.right is not None:
tree_insert(root.right, key)
else:
root.right = Node(key)
looks like i'll need to add parent and child attributes to class Node
lg(2^k) becomes k
that's the most i know 😂
Hello here , hope you feel good, I'm here to learn more to create apps or tools other than CRUD applications. I think about how advanced developer implement protocols in a langage for exemple ? or systems... Something different, I'm beginner and all your help or advice will be usefull
Because you are just multiplying by 2 one more time than k
right i guess the parentheses confuse me. but we can also see that with the rule a^b * a^c = a^(b+c)
ty @lament totem one last thing
wow i just realized the CLRS publishers literally posted python implementations of every algorithm on their website 🤦♂️
probably better i didn't know that while i was learning
i wonder if we should pin that here or if it'd be detrimental to learning purposes
i'm still not printing my entire sorted arrays with my return statements, if anyone may know what thats about
what code?
Anything I run where the array is too large, just gets lopped off at the end of the print statement there must be a max character return in the print function
Maybe it’s a vscode thing. I can share code when I’m back at my pc but it’s happening code agnostic
quick googling gave me https://stackoverflow.com/questions/57764639/how-to-stop-vs-code-from-truncating-python-data-in-the-console#58203545
I wouldn't know these issues, I just work in a terminal 😛
hmm i'm not seeing the Data Science setting of the python extension. i'll keep looking. thanks for this
i forget why i migrated from the default IDE that ships with python but at some point i did for some reason
hmmmm
just realized in the beginning of CLRS they put:
(x number of instructions) / (y number of instructions/second) to get computational time. that's the formula i will follow once i get the number of instructions per second of my processor
can i look up the instructions per second for my cpu or must it be calculated
it depends on the instruction
wiki says i can do it in this manner:
i will be doing that as well
this seems to be what i want given what i was trying to calculate before
as always, counting instructions will at best be a bad approximation of time taken
especially if you count lines in python
if you look at individual instructions you can start to count the number of cycles needed for a sequence of operations, but it gets very complicated very quickly
IPS is a pretty bad measure of processor speed on modern machines.
i guess that makes sense given clrs was written 30 years ago
ok. i'm just trying to figure out how to use those lines executed in my analyses
beyond "we can see the bulk of the work is here"
finally recognized that k+1 = lg(2^(k+1)) 😂
this has been a wild ride coming from the RNA sequencing and biochem world
there are some cool dimensional analyses we do
Hey is there a library in python that could decode iso646
can someone help me understand this runtime:
looks like the first summation runs from i=1 to n-1, so i understand what's written above and below, but why is it n-i
It seems both loops run nopen-1 times
so here they have split out the summation into the summation of n being n*(n-1) and are subtracting the i summation is it?
it's a decent proxy for ballpark time estimates, 10^9 cheap operations in a compiled language might be ~1s
in python...a lot fewer operations in 1s
like 100x less
i'm sorry that i keep asking about this btw
again, parentheses matter, I'll complain until you do it right :P
i know its frustrating, the summations just haven't clicked yet
yeah, you can split a (finite) sum
Σ(a + b) = Σa + Σb
can anyone hop in voice? i'd love to talk through the bottom line and say "this is how i interpret this" and see if i'm comprehending things properly
The outer loop runs n-1 times. The inner runs starting from i+1 to n. So if i is 1 then it's 2 to n and if it's 2 then 3 to n. So if say it was starting at i rather than i+1 and i started at 0 rather than 1, then at most it's 0 to n, which is n. And every time i increases it's n - i.
n - 1, n - 2, n - 3, ...
(Because the range gets smaller by i going up)
(The reason I let i start at 0 is because it makes it more obvious (IMO), but it still applies when you do the i = 1 to start and all that they are doing)
When you have a summation in math, the summation not only adds stuff up, but the index (i in this case) can be used to know which iteration you are currently in, and that is important in this case because which iteration you are in affects how many iterations the inner loop does.
so they're capturing the entire complexity of the algo with a single summation and not mentioning the variable j used in the internal loop?
how would the summation change if the internal loop weren't present
just summation(i)?
Then it would be constant time. If no inner loop.
So sum over a constant term.
(Unless there is recursion or something)
you could write a nested sum, but it's a boring sum over ones
Like it's it just did foo += 1 inside the loop instead of another loop or calling another function or something.
So if you had the sum from i = 1 to N for the outer loop, and inside there was no inner loop, just a single instruction, it would be the sum from i = 1 to N of 1. Or just N, because it's doing 1+1+1+... N times, which is how multiplication works (1 * N).
ok so it looks as if the n summation is just equal to n(n-1) and the i summation becomes equal to (n^2 - n)/2?
In this case, the inner loop is the one being replace by N, except not exactly N, because of how i starts further and further.
and yeah, the i sum should be familiar by now
i guess what's tripping me up is we aren't summing an integer or something, we're using it to mean the summation of all the lines executed, which is more abstract
we are summing integers
You can think of it as counting the number of times the inner most lines are being executed that are O(1).
lines 3-7 should be O(n)?
On their own in isolation can't say, because don't know what i is.
If we assume that i = 1 or 0 (such that it's the maximum, it would be N times).
technically true, because O is an upper bound, but it's not Θ(n)
can someone give me a bit of code and i'll try to write the equivalent summation which describes the loop and/or loops?
if youd like to pr its just adding this channel id to https://github.com/python-discord/sir-lancebot/blob/main/bot/constants.py#L109 and https://github.com/python-discord/sir-lancebot/blob/main/bot/exts/fun/latex.py#L36 👀
although not sure if an admin/coredev already approved yet
it's just doing Dijkstra, isn't it?
modified?
you just need Dijkstra afaict
that doesn't really change much
?
Remember you are counting how many times foo is executed. And foo is a single instruction (counts as 1).
How about first try this: ```py
for i in range(n):
bar
e.g. a grid like this corresponds to the graph below
1 2
3 7
o--1--o
| |
2 5
| |
o--4--o
idk, sounds more annoying than it's worth
And if bar counts as 1 operation?
you binary search for the smallest distance for which the dfs reaches the goal
?
though idk how that dfs would even be written, you kinda need dijkstra to get the right ordering
Yes, but finally, note that in math summations it's [,], not [,). So if you are starting at index 0, your max index is?
n-1
wow, one of the first solutions I see in the discussions say "BFS(Dijkstra)" 🤢
BFS is not Dijkstra, different things
There is no n-1 at the end, it's always 1 inside the sum, just a bunch of 1s added together.
Try a concrete value for n, like 10. What does the sum expand to?
Yeah.
they do, but writing it like that give me like 0 confidence in the author
10
And how did you compute that?
i thought of a loop adding +1 to a variable 10 times beginning at var = 0
Which looks like: 1+1+1+1+1+1+1+1+1+1.
So sum from i = 1 to 10 is: 1+1+1+1+1+1+1+1+1+1.
But repeated addition is just multiplication.
I'm suspect of the dfs+binary search one, I'm not convinced it works
Yes.
idk what it is but summations are so nonintuitive to me
why wouldn't the dfs just go down in this case and get the wrong distance to the goal?
1 1 9
9 1 9
1 1 9
1 9 9
1 1 1
like having "the summation one" just adds so much unnecessary ambiguity
are we adding one? to what? are we beginning at one? is it both?
In the same way you do 1+5+3. What is it adding to? Nothing, it's just there.
You can combine them all into 1 value.
And the summation notation denotes that combined thing.
here we are beginning with a single term 1, and adding 2 terms 5 and 3 to it. the order could be any different which way and it wouldn't change things, but its the same basic operations
why? it's literally just a short form
\sum_{i=a}^b f(i) = f(a) + f(a+1) + ... + f(b-1) + f(b)
for whatever function f
Yea, but let's say we have 1+2+3+4+5+...+984357893763979865. Would you want to write that all out?
Instead we can just say sum from i = 1 to 984357893763979865. Basically when there is a pattern, you can compress things, symbolically, etc. And that notation lets us do that.
i guess my brain just doesn't work that way idk
the dfs doesn't go in a specific direction, it just goes while the distance is less than some limit
and how would you do this mathematically
I add twos, n plus one times.
2+2+2+2+...+2 (n+1 times)
(There are n+1 twos)
Because you started at i = 0 rather than 1.
Try n = 3: Then i is [0, 1, 2, 3].
(4 things)
alright i'll change my index to begin at 1 but in python i think it'd be zero
Yeah, you can just make the end n-1.
To make up for the +1 from starting at 0.
Which is what Python does. The index is never equal to n, it's as most n-1.
When you do for i in range(5), i is [0, 1, 2, 3, 4]. (5 total iterations)
The last one is n+1.
dang!! ok lol
(When i = n)
Summation notation starts on the start value and ends on the end value.
like ) or ]
[]
so including
ok. i'm starting to get it although the idea of describing two loops with a single summation still has me 😵💫 🥴
We will get to that, first do you understand why the last is n+1?
bc we started at i=1 not i=0
wait, I read the problem wrong :/
Nope.
it's the max along the path, not sum
What is the start i value and what is the end value?
Yes.
i begins a 1 and ends at n
And what is the value inside the sum at 1 and at n?
you can write it with two sums if you want to
\sum_{i=1}^{n-1} \sum{j=i+1}^n 1
err, I'm missing an _
after the 2nd \sum
if you add that it should work properly
when i=1 its 1+1 = 2 and when i=n its 2+3+4...+n+1
I meant the specific part of the sum at n, not up to n.
fixed```
\sum_{i=1}^{n-1} \sum_{j=i+1}^n 1
n+1
@haughty mountain what code is this describing
Yeah so, do you see why it's 2+3+4+5+...+(n+1) and not 2+3+4+5+...+n?
the selection sort you posted
no i only said it was n+1 bc of the expression in the summation e.g. (i+1)
Well, if i = 1 gives you the first value in the sum (2), and i = n gives you the last value in the sum, then the last value is not n, it's n+1.
2 + 3 + 4 + 5 + ... + (n+1)
i = 1 2 3 4 ... n
(The summation is doing i+1 for each term)
i think we're confusing the expression with the maximum range
maybe it would be worth practicing some sums? e.g. what is this sum in the sigma notation?
4 + 9 + 16 + ... + 64 + 81
cool, so you get how that one fits together 
How about 4 + 9 + 16 + ... + n^2?
yeah like i said it makes sense when its integers, not theoretical lines of code run
lms
we are just counting how many times the interior of the inner loops run, it's all integers
What happens when i = n^2?
well, the upper limit isn't quite right
idk what happens
wat
(n^2)^2
wat??? it should just be up until i = n^2???
It is up until i = n^2.
If you substitute you get i^2 = (n^2)^2.
the thing in your sum is i²
if you put i=n² in there you get...badness
i.e. n⁴
The i^2 inside the sum is the value of each term in the sum.
much like your upper limit before was sqrt(81) = 9, the new limit is sqrt(n²) = n
right..
When i = 1, you get 1^2, when i = n^2, you get (n^2)^2.
no i'm lost
like, how did you figure out the limits in the sum 4 + ... + 81?
you just go up until i=9
why i=9?
(it's correct, I just want to see why you arrived at it)
working on it
bc that captures the final term in your sequence
i^2 = 81
because 9² = 81, right
what about when the last term is n^2?
you can apply the same logic
i can't evaluate this bc i don't know when i=n^2
ugh this is so frustrating. i can tell that y'all want me to change the upper bound to n instead of n^2 but i have no idea why
Goal (n = 3):
1^2 + 2^2 + 3^2
Using your summation (n = 3 also):
1^2 + 2^2 + 3^2 + 4^2 + 5^2 + 6^2 + 7^2 + 8^2 + 9^2
i = 1 2 3 4 5 6 7 8 9
Because n^2 = 9, and your summation ends on n^2.
or like, i can't see how the expression would change the upper bound in such a manner
i^2 = 81 -> i = 9
i^2 = n^2 -> i = ???
right ok
you can do operations with variables just like you can do with regular numbers
i.e. the logic for the limit remained the same
sqrt(81) = 9
sqrt(n²) = n
If you summation ends on n: ```
(n = 3 again):
1^2 + 2^2 + 3^2
i = 1 2 3
i think all the variables get me or the math part of my brain is.. limited..
Now instead of n = 3, what if n = n?
(Not a specific value)
for this one:
?
variables are basically just placeholders for some number, you don't know the number yet, but you can still do operations on it
e.g. x+x = 2x
x*x = x²
sqrt(x²) = x
and whatnot
in the end, here it's just some integer
it behaves just like an integer would
i guess variables are variable eg x and constants are fixed eg k
If variables are placeholders, then think of 1+4+9+16+...+n^2 as another placeholder. The entire thing waits for some value of n.
But you can still do operations on it until then.
i thought it 'waits' on a certain value i, eg when i =n^2
You can think of it generating the entire thing up until the end value which depends on what n is.
And to generate it step by step, it uses i.
As a result n also determines how many generation steps are needed.
but to be clear it terminates when the index of summation i is equal to n (or n^2)
When it's equal to whatever the end is.
In this case it would be n.
Because each term is i^2.
We generate each term by i^2.
And we want the last generated term to be equal to n^2.
So we must choose the correct end value for the summation, which in this case is n.
Because (n)^2 when you replace i with n.
wdym replace i with n
It needs the match the 1+4+9+16+...+n^2 pattern.
i thought its when i = n
sorry when do you 'replace' the upper bound with i??
Other way around.
i with the upper bound, is the last term.
i gets set to the upper bound.
i := n
(i becomes n)
At first i becomes 1, then i becomes 2, then i becomes 3, etc until i becomes n.
That would match 1+2+3+4+...+n on its own (sum of i from i = 1 to n).
To get it to match 1+4+9+16+...+n^2. we just square i.
ohhhh
i think something just clicked
with "the max value is i^2, but the max i is n"
in \sum_a^b i sweeps from a up to b, and you get one term for every step
i=a, i=a+1, ..., i=b-1, i=b
and you evaluate what's in the sum for every of those values for i and sum the results
The index is used to generate the value.
The index max is not the same as the value max.
(Unless the value is just i)
you need _ and ^ for start and end
dammit, forgot the _ again 😭
This will give you the indices. But now you need to choose what your values will be, which can be based on the indices.
is it not possible to fork from the mobile website or am I blind?
hence why I write
\sum_{i=a}^b f(i) = f(a) + ... + f(b)
the thing you sum is some expression in terms of i
i.e. some function of i
not sure im on phone too but im not signed in
alright i need to look at the selectionsort and the two loops and see if its clicking
searching around all I see is "switch to desktop mode", which is just sad
What is 1+4+9+16+...+n^2 though now? With that notation.
(Can you get the right side to match / align?)
(What is f(i) = ?)
That is correct.
its correct that the notation is needlessly confusing
f(i) = i^2, f(a) = 1, f(b) = n^2.
(It matches the 1+4+9+16+...+n^2, you can tell by checking the ends)
i really don't see how n has anything to do with getting squared, its just when you stop your computations, when i = n
i guess its when i = n you could think of it as n^2, but its really just end on i when i equals n and square i as the last term
anyway, thanks for all your help today y'all
some day i will write out the neat conversion i used to do in the lab btwn ng/uL DNA and [nM]
if anyone is interested
the neat thing of it is that the [nM] concentration is based on the size of the DNA fragments, so you have to measure that, get an average, and then use the average DNA molecule length in your calculation
bc the instruments wanted to be loaded at a certain pM concentration, not pg/uL
that is, for optimum loading they wanted trillionths of one mole per liter
say like 20 trillionths of one mole or similar
IIRC
welp, let's see what happens https://github.com/python-discord/sir-lancebot/pull/1083
n^2 has to do with getting squared though :P
Yeah i = n, theni^2 = n^2. Last index n, last value n^2.
woot, merged
$\sum{i=a}^b$
.latex $\int_{-\infty}^\infty \mathrm{e}^{-x^2} \mathrm{d}x = \sqrt{\pi}$
.latex $\sum{i=a}^b$
ew inline
does $$...$$ work for display math?
¯_(ツ)_/¯
.latex $$\sum_{i=1}^{n}{i^2}$$
Finally no more hand-waving for this stuff.
yeah, this will be useful for a bunch of the math flying around
.latex $$\sum_{i=1}^{n}{\color{red}i^2}$$
Aw.
color needs a package I think
.latex $$\sum_{i=1}^{n}{\color{red}{i^2}}$$
Which one?
xcolor, I think
.latex \usepackage{xcolor} $$\sum_{i=1}^{n}{\color{red}{i^2}}$$
.help latex
Haha that’s unfortunate
.latex \usepackage{xcolor} $$\sum_{i=1}^{n}{\color{red}{i^2}}$$
Nope.
I don’t entirely understand latex, but we use an external API for it
I believe they document what they support
package includes need to be before \begin{document} iirc, so I don't think this will work sadly
hey y'all were helping me with my recursive mergesort before but i guess i never got it working? anyone remember what was wrong? i'll paste the code
import time
import math
import random
def merge(array,p,q,r):
n1 = q-p
n2 = r-q
left = [0 for x in range(n1)]
right = [0 for x in range(n2)]
for i in range(n1):
left[i] = array[p+i]
for j in range(n2):
right[j] = array[q+j]
left.append(math.inf)
right.append(math.inf)
i = 0
j = 0
for k in range(p,r):
if left[i]<=right[j]:
array[k]=left[i]
i+=1
else:
array[k] = right[j]
j+=1
def mergesort(array,p,r):
if p < r:
q=(p+r)//2
mergesort(array,p,q)
mergesort(array,q+1,r)
merge(array,p,q,r)
a = []
for x in range(100):
a.append(random.randint(1,1000))
print('the array before sorting is: ' + (str(a)) + '\n')
start=time.time()
mergesort(a,0,(len(a)))
print('the array after sorting is: ' + str(a))
start=time.time()
you could send a PR to add it to the template the bot uses https://github.com/python-discord/sir-lancebot/blob/main/bot/resources/fun/latex_template.txt
you're mixing indexing standards
e.g. the q+1 should just be q in mergesort
that's the obvious thing I see at least
I suspect CLRS uses dumb indexing, and you've half-converted to the saner one
def mergesort(array,p,r):
if r - p > 1:
q=(p+r)//2
mergesort(array,p,q)
mergesort(array,q,r)
merge(array,p,q,r)
the if check is also slightly different with [p, r) indexing
in short, if there are 2 or more elements, use merge sort to sort the halves
maybe r - p >= 2 is nicer, but whatever
@haughty mountain you are a wizard
why would they have py if p < r: in the pseudocode
lol, it was easy enough to find the other fix needed after actually running the code and seeing the error
they use different indexing, they use inclusive-inclusive, i.e. [p, r] rather than [p, r)
[p, r) is a much nicer way of indexing, it removes a lot of +1s all over the place
like, the halves are [p, q) [q, r)
yeah i think it was squiggle that helped me work this out
or yourself
either way i'm familiar with the "up to but not including" aspect of pythonic ranges now
it's just a nicer standard in general imo
e.g. the length of [p, r) is just r-p
right. and it works with my initial call bc the upper bound is len(array), which conveniently terminates at and including the array's highest index
wow mergesort is fast!
0.11s on average to sort an array of 10k randomly generated integers btwn 1-10k
yeah, it's quite good
it has some disadvantages, but it's a very solid sorting algo
lets try an array of 100k 🙂
will it scale linearly? i guess not if its nlgn runtime
n lg n, yeah
eg we'd expect it to do 1.1s if it scaled linearly
but i guess it doesn't bc its n * lg(n)
lets see
i don't want to fry my cpu, i should pull up some diagnostics
eh it is almost linear, its taking like 1.2s for array of 100k. that's, insane
everything is default its not even overclocked or anything
i could overclock up to 4.3GHz ish
still not returning the entire arrays on output, super annoying. i'll have to get that worked out
array size of n=1m ints btwn 1-100k takes 13.5s
looks not quite linear, these are avg runtime for a bunch of samples
1: 5.502268240088597e-07s
10: 4.7196618240559475e-05s
100: 0.0005869835479999893s
1000: 0.007533813875983469s
10000: 0.09336091971956194s
100000: 1.115556204796303s
i.e. slightly superlinear
smells like a log factor
Want to make your implementation faster?
sure. one sec i am in a call
@opal oriole i don't think i'll get time tonight i have office hrs in 15m
Apparently deques as recommended to use over lists. What about versus Numpy arrays?
deques aren't recommended over lists in general, only in certain situations
same with numpy arrays. all 3 are used because all have different things they're good at
deques are good when you need to append/pop a lot at both ends
hello, does somebody know how to print a graphic of this "df_boston.plot(kind='scatter', x= 'Rooms', y= 'Value')" with the library statsmodels, the guy of the tutorial is using jupyter and he just entered and that's it, but am using vscode and it doesn't work
#data-science-and-ml might be better-suited for your question. Jupyter is an interactive notebook and DataFrame.plot() simply displays in the notebook. In VSCode, you’ll have to do import matplotlib.pyplot as plt and plt.show() iirc
Oh okay, yeah thanks dude, i'll do it with matplot then
Is it necessary to master data structures and algorithms for a data scientist?
Where I can learn python easily?
!resources
The Resources page on our website contains a list of hand-selected learning resources that we regularly recommend to both beginners and experts.
also, #python-discussion is a better channel to ask that
Is that the specific use case of deques? Just popping and appending?
yes
Interesting, I mean I've had to pop or append a few times but never like more than once
I wonder what deques would be best applied to
they're used for queues
They're nice when you want a rolling window over some bigger data for example
That way you can append to the right, and pop from the left
Oh yeah that makes sense, I can see how deques can be very useful for that
just found this resource:
https://pimbook.org/
A Programmer's Introduction to Mathematics
my braincells are getting fried
yeah tell me about it. i'm focusing on this stuff and proofs bc its the most difficult material for me
it's a consequence of the property that log_b(a) = log_c(a)/log_c(b), where c is an arbitrary third base.
meanwhile im stuck on doing college physics questions compared the logrimithics are big diff but i do code for fun or macros
i did two college physics courses but they were the dumbdumb ones, algebra based not calc based
which really doesn't make sense
actually in some situations, avoiding calc makes things very very annoying
yeah i could see that. i don't recall how bad it was, only at one point i thought i had an epiphany about reversing the concept of an electric generator and instead using the magnetism to drive the rotation of an axel, i talked to the prof about it and he said "you just described an electric motor" so i guess i sort of found my way to that concept which made me happy
i took brief calc but that was brutal bc i was also in organic chem and micro and stuff
i'd love to go back and relearn it
hmm i just thought of something,
for i in range(10)``` goes up to and does not include 10, (pythonic range function is [x,y), but how about when you are stepping by ```-1```
eg for i in range(mid,low,-1):
i suppose a simple reversal would indicate that it begins at mid, and goes down to and includes low
actually, this would seem that it goes down to and does not include low
bc of the [mid,low) nature of the function
i hate algebra but like its non making sense of sht
like how did the x get converted into the answer
basiclly that but in advance lv
lets keep this focused on algos and data structures, feel free to PM me
right, that's why I much prefer to do reversed(range(...)) instead
right i recall you mentioning that before, i wonder if reimplementing that in my code would solve my recursion error
so if range(1,10) begins at and includes 1 and goes up to and does not include 10, then reversed(range(1,10)), begins at and includes? 10 and goes down to and does not include 1?
could you clarify? alternatively i will search for the answer
i can just print these things
or not
keep getting range_iterator object
use list on it to get a list
ty
ok so looks like it begins at and does not include 10, just as we might expect of the reversed range
x = range(1,10)
x = reversed(x)
print(str(list(x)))
prints:
[9, 8, 7, 6, 5, 4, 3, 2, 1]```
omg i'm doing my python certs all over again 🤦♂️
well you know what they say, you don't use it you lose it
do we have a python runtime environment in here
where we can run code within discord
!e
code
!eval [python_version] <code, ...>
Can also use: e
*Run Python code and get the results.
This command supports multiple lines of code, including code wrapped inside a formatted code block. Code can be re-evaluated by editing the original message within 10 seconds and clicking the reaction that subsequently appears.
If multiple codeblocks are in a message, all of them will be joined and evaluated, ignoring the text outside of them.
By default your code is run on Python's 3.11 beta release, to assist with testing. If you run into issues related to this Python version, you can request the bot to use Python 3.10 by specifying the python_version arg and setting it to 3.10.
We've done our best to make this sandboxed, but do let us know if you manage to find an issue with it!*
!e x = range(1,10)
x = reversed(x)
print(str(list(x)))
@fiery cosmos :white_check_mark: Your 3.11 eval job has completed with return code 0.
[9, 8, 7, 6, 5, 4, 3, 2, 1]
@fiery cosmos :white_check_mark: Your 3.11 eval job has completed with return code 0.
Hello World!
!e
import math
from math import floor
def findmaxcrossingsubarray(a,low,mid,high):
left_sum = -math.inf
sum = 0
for i in reversed(range(low,mid)):
sum = sum+a[i]
if sum > left_sum:
left_sum = sum
max_left=i
right_sum = -math.inf
sum = 0
for j in range(mid,high):
sum = sum+a[j]
if sum>right_sum:
right_sum = sum
max_right = j
return(max_left,max_right,left_sum+right_sum)
def findmaxsubarray(a,low,high):
if high == low:
return(low,high,a[low])
else:
mid = floor((low+high)/2)
(left_low,left_high,left_sum) = findmaxsubarray(a,low,mid)
(right_low,right_high,right_sum) = findmaxsubarray(a,mid,high)
(cross_low,cross_high,cross_sum) = findmaxcrossingsubarray(a,low,mid,high)
if left_sum>=right_sum and left_sum>=cross_sum:
return (left_low,left_high,left_sum)
elif right_sum >= left_sum and right_sum >= cross_sum:
return (right_low,right_high,right_sum)
else:
return(cross_low,cross_high,cross_sum)
a = [10,-12,2,-6,8,5,-3,4,7,-13,25,-22,89,71]
# print(findmaxcrossingsubarray(a,0,((floor(len(a)/2))),len(a)))
print(findmaxsubarray(a,0,len(a)))
@fiery cosmos :x: Your 3.11 eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 43, in <module>
003 | File "<string>", line 29, in findmaxsubarray
004 | File "<string>", line 29, in findmaxsubarray
005 | File "<string>", line 29, in findmaxsubarray
006 | File "<string>", line 30, in findmaxsubarray
007 | File "<string>", line 30, in findmaxsubarray
008 | File "<string>", line 30, in findmaxsubarray
009 | [Previous line repeated 992 more times]
010 | File "<string>", line 28, in findmaxsubarray
011 | RecursionError: maximum recursion depth exceeded while calling a Python object
I mean, it's just the same range, just in reverse order
right i was musing about how the list would change if the inclusions were also reversed, but clearly that does not happen
eg [1,10) --> (1,10]. but no, that was incorrect way of thinking about it
ok so i'm trying to solve the recurrence T(n) = 2T(floor(n/2) + 17) + n
via substitution
and in an exemplary problem i learned to solve a similar recurrence (which did not include the 17), and substitute in m = n/2 into my guess of O(nlgn), getting the form T(n) < c(n/2)lg(n/2), and then substituting in this guess into the recurrence. my question is, how do i handle this problem given the 17 there. must i use m = (n/2)+17?
i get that T(n) <= (cn+17)(lg(n+34)-1+n == O(cnlgn)
did anyone else solve?
i also have a question regarding recursion trees
I can't be bothered to do the details with the constants, but slightly sloppy
T(n) = 2T(floor(n/2) + 17) + n
Guess T(n) = a * n log n
T(n) = 2(a (floor(n/2) + 17) log(floor(n/2) + 17)) + n
<= 2 a (n/2 + 17) log(n/2 + 17) + n
= 2 a n/2 log(n/2 + 17) + O(n)
<= a n log(n) + O(n) # for n >= 17
ok thanks @haughty mountain
anyone have good resources for where to practice proofs by substitution?
Would anyone be able to help me out with the problem I've listed below? I've tried to solve it using the simplex method but I can't figure out how to do it. I've come up with a solution I think is in polynomial time which would be to draw lines between each colored pair point until a valid line is found that would divide up the points but I'm not sure if that approach is actually valid.
would someone pls point out flaws in my logic / where i have gone wrong, thank you:
this part isn't given, it's what you want to show
or wait 
let me re-read
no you're right i sort of did it backwards. i'm supposed to first derive this:
and plug this into the c n lgn expression
so you want to show that this is bounded by c n lg n
.latex $$T(2^{k+1}) = 2 T(2^k) + n$$
yeah, what you wrote
The question is asking to show that T(n) = nlgn right?
i'm doing it the longhanded algebraic way rn
correct
No big O involved.
Not really even a CS question, just induction to get a closed form.
yea i should be posting in the math server
It shows up in CS, but it's more generic than that technically. Just as most induction goes with recurrence.
lol what is algmyy typing
so, something like this
assume T(n) = n lg n
T(2n)
= 2T(n) + 2n
= 2n lg n + 2n
= 2n lg n + 2n lg 2
= 2n lg(2n)
I should probably derive my expressions in a text editor and then copy it over rather than type for forever here :P
thats what i do
wait
that's not what we wanted to show...
we wanted to show =
err...
oh
I lost a 2
fixed it
we wanted to show that when n=2^k for k>1, the solution to the recurrence T(n) = 2T(n/2)+2 = nlgn
oh. can you do it that way and avoid all the specifics?
oh, having it in form 2^k isn't too helpful it turns out
your last line should be 2n lg(2n)
oh i didn't write this, i've just been spending a lot of time to understand what they did algebraically
which i now get by some miracle
T(n) = 2T(n/2) + n = nlg(n)
T(2n) = 2T(n) + 2n
(by induction hypothesis)
T(2n) = 2(nlg(n)) + 2n
T(2n) = 2nlg(n) + 2n
T(2n) = 2nlg(n) + 2nlg(2)
T(2n) = 2n(lg(n) + lg(2))
T(2n) = 2nlg(2n)
(lg(2) = 1)
(Can also go the 2^k route)
you can totally do it in the world of k rather than n if you want to
we want to show that T(2^k) = 2^k lg 2^k = k 2^k
assume T(2^k) = k 2^k
T(2^(k+1))
= 2T(2^k) + 2^(k+1)
= 2 k 2^k + 2^(k+1)
= k 2^(k+1) + 2^(k+1)
= (k+1) 2^(k+1)
(Same thing but working in exponents rather than logs, I prefer logs for less parens here (not a problem with actual work on paper))
it's a bit awkward to jump back and forth between n and k here imo, I would either work in n, or translate the whole problem to use k
2^(k+1) would be 2n.
(not n on your final step)
(although you could argue trivial change in variables, but depends on your grader / teacher (you can reuse variable letters but I would avoid this unless you have more experience with how algebras and proofs work in more detail))
oh yeah, I pointer that out earlier
using n to mean something different later is certainly an error
Technically you can, but I would not recommend. I really dislike it when it's done.
(It's something I see when a mathematician is trying to impress / skip steps)
I can see three paths
- work with n the whole time
- translate expression to k and translate back later
- translate the whole problem to k and solve it
These are the ways yeah.
@opal oriole it looks like in this line:
T(2n) = 2nlg(n) + 2nlg(2)
you multiplied by 1 in the form of lg(2) so that you could combine terms
(You could do ridiculous things for fun, but they are not practical (like put in some calc for no reason))
I would still call it a clear error as written. Adding "where n = 2n" wouldn't really help either :P
Multiply by fancy form of 1 yeah.
yes, remember the deadly weapons
adding 0
multiplying by 1
(log edition this time)
it actually has been practical in this situation bc i've been forced to learn the algebra and logarithm rules
but yeah i get what youre saying
I think there is a third one, but I can't remember :/
There are a few for more advanced stuff like intergal of the derivative, e^log(x), etc.
the deadly tricks were a sayings from a lecturer at my university before my time there, stories that's been passed down between generations of students
(basically f^-1(f(x)))
this tells me if you have two terms with logs of the same base and are adding them, you can instead take lg(term1*term2)
Yes, log sum rule.
(Or product rule depends on where you start)
fwiw these are the same rule in different forms
lg(a)+lg(b) = lg(a b)
2^a 2^b = 2^(a+b)
addition being multiplication in the log world has fun applications
e.g. slide rules
(And log probabilities for summations instead of products)
yeah, log probabilities are nice
can y'all think of a recursion i could try as practice
practicing solving using a substitution proof?
Pick some pattern sequence.
(For which you know the recurrence)
(Or try to figure it out first (extra credit))
i was doing that before but i want to stick with recurrences. i guess i could try to prove the fibonacci numbers but that seems too complicated
I can give you a boring one that you've probably solved before
T(n) = T(n/2) + 1
what is an algo with this recurrence?
is there more randomness in the first or last five digits of pythons hash?
what even is python's hash algo?
python has an inbuilt hash function?
it does
based on what it could be anything
Depends on what type given.
the python hash for integers is...bad
fast though
no i mean how did they pick one, it could be any function that someone thought was appropriate
CLRS gets into hashing functions a bit
something something prime number that splits not quite evenly
trial and error, basically, based on a good guess
knuth has written about this
well, some proofs of properties as well
A lot of hash functions in programming have been picked by trial and error and some are wide spread but undocumented, nobody even knows the authors.
Others are more seriously analyzed.
hm
the int hash is so silly, it's basically
def int_hash(n):
if x != -1:
return x
return -2
because python uses -1 to signal "the operation failed"
because fun
Nothing beats the speed of doing nothing.
nothing except in one case
so you always have a branch
unless you can write it branchless, idk
return -2 * (x == -1) + x * (x != -1) (The (x == -1) can be reused, compilers will optimize this for you (including making it branchelss, not sure if CPython does in its bytecode))
it's still amusing that -1 is an illegal hash value
Branchless is often just multiplying by the boolean checks.
because sketchy error handling
(Although on actual machine code, there is a specific instruction to make things branchless (often, depends on ISA))
hey i'm gonna ask a really dumb question
when evaluating T(n) = T(n/2) + 1, let's say i input 2, I get T(2) = T(1) + 1, so i must therefore have to go and lookup/calculate T(1) to get the answer yeah?
assume T(1) = 1, so you have a base case
You just declare what T(1) is. Like how in the problem you gave they had a piecewise function.
(But it's just a detail that is not super important for this practice)
T(4) = T(2) + 1 = T(1) + 1 + 1 = 1 + 1 + 1
so its T(1) = 1, and T(n/2) + 1 otherwise (when n>1)
n>1 at least
(=/= could include negatives and zero)
n<1 feels like badness
for n not a power of two you would need to add a floor/ceil, but that's not so interesting
how would you eval T(3)
as said, you would need to have T(ceil(n/2)) or similar
or just assume n = 2^k
it doesn't matter for the result
i think i have the core of whats required but its so scatterbrained i don't make the point and/or its circular logic:
i think im just memorizing a pattern and not really understanding. i think i would have come to the same conclusion even if i guessed the wrong answer
like i would have shown that lgn of the equation is lgn whether n=2^k or some other form
i guess the base case of T(2) = 2 = nlgn makes it hold
The question was what is an example of an algorithm with that recurrence.
@fiery cosmos
well, the solution as well
identifying an algo with that recurrence is more of an extra
the answer is not n lg n
i was thats how i wound up at T(3)
or T(16)
as for what an algo like this is, I read
T(n) = T(n/2) + 1
```as: do some constant amount of work and then consider only one half of the data
e.g. ||binary search||
binary search is lgn?
try: ||log_2 n||
yep
we use lg to mean log_2
oh lmaooo my bad
the recurrence basically counts how many times you can divide the data in half
(sol) ||T(n/2)+1= lg(n/2)+lg(2)=lg(n)||
ok
log_2(n) + 1
what does sltn mean 😭
solution
maybe with a parenthesis to not confuse with lg(n+1), but yes
i knew it was off bc i was putting in T(16) and getting 32
anyway lets get back to basics
are you changing the sltn or the base case
if we change the base itll work
no need to make it lgn+1
btwn in the book they explicitly state, lgxny = lg(x)ny
they say the lg only applies to the immediately proceeding term
and no others
T(8) = T(4) + 1 = T(2) + 1 + 1
= T(1) + 1 + 1 + 1 = 1 + 1 + 1 + 1 = 4
lg(8) + 1 = 4
yes, my base case was a bit off if I wanted to have the answer be exactly lg n
but you need to change one or the other not both
as I stated it initially the exact solution (for n = 2^k) is lg(n) + 1
with T(1) = ?
if T(1) = 1
ok
general sol is lgn+T(1) if interested btw
right
which is reasonable bc u can just subtract both sides by T(1)
alright im gonna make my base case T(2) = T(1)+1 = lg(2)+1 = 2
now i'll get a form for T(n), assume it to be true, then prove that the n+1 form will take the same form, namely lg(n)+1
T(1) = 1 is already a fine base case, no?
2n form in this case
oh yeah bc you could do lg(1)+1
the next higher step
it's the same trick as last one
T(2n)
= T(n) + 1
= lg(n) + 1 + 1
= lg(n) + lg(2) + 1
= lg(2n) + 1
it's more that you show that the guess you make works for 2n if it works for n
i.e. you can jump one step up
and we're doing that to get rid of the T(n/2) in the recurrence to make the math easier
right, you make a guess to get something you can more easily solve
one step up the recurrence invocation 🧠
alright i guess that's all for me today, gonna take a break my brain is frazzled. hopefully this will all sink in
it feels like ive been stuck on the same stuff for a month
please teach how to keras
is there shame in making a python gui for nmap and put it on my repository to show off to potential employers
i have a question like ,i was solving exercise question from a textbook ,there i got a question where it asked me to do a factorial there are soo many ways to do it when i searched in the net and i got confused ,so my question is as a beginner where do i draw the line this is enough for now or else i would be looking at different answers for whole day ,i don't want to waste my time
study as much as you need or are interested;
every algorithm problem you will ever run into will have multiple solutions; different ones will run more efficiently than other ones depending on the situation;
other constraints such as space may pose additional constraints
generally reading from good (modern) textbooks ensure you that you are at least exposed to the most useful algorithms, and if a specific problem needs further optimization, you can do your own additional research from there on
algorithm complexity/efficiency may give you more insight into these things
Does anyone know if Elements of Programming Interview book is suitable for beginner who has never taken Data Structure and Algorithm before?
Are there any courses on DSA in python?
I want to study DSA first then start doing leetcode. I don't have a CS background
thank you sm for that detailed explanation
- I haven't read the book, sorry.
- Most DSA courses will unfortunately be in Java, as it was widely popular and is simpler than C++, more common among competitive programmers due it to its general faster speed. Python is extremely slow in comparison, so you likely won't see many rip. https://usaco.guide/ is a great free resource that has many Python examples and offers a roadmap-styled resource. Bronze/silver should be good enough for most Leetcode problems imo. [MIT 6.006 has many Python examples and is pinned in this channel.]
Thanks for this. The link looks great.
Would you still recommend using python to study DSA and leetcode with the ultimate goal of getting a job at one of the companies that do leetcode style questions?
or would it be better to learn java and practise it using java?
You shouldn’t need a double loop to do this
alternate approach?
Let me hop on my pc
just do ARR * K
concatedarray = []
array = [0,-1,2]
k=3
for x in range(3):
concatedarray = array*k
print(concatedarray)
just ditch the loop
you could also write it like a function that takes as input the array and the integer k and returns the new array
right
i wonder what the searching algorithm is in the upper right hand corner
the discord one? whatever it is it's pretty terrible
very hard to find exact matches
like, does it just go through line by line and search every x word combination for the phrase
speaking of bad search stuff, github is also really terrible. phrases I know exist don't show up in searches
i would think github would be among the best, what with all the knowledge there on the subject
you can do smart precomputations, e.g. precompute what posts contain certain ngrams (sequences of n characters)
Trigram search is a method of searching for text when the exact syntax or spelling of the target object is not precisely known or when queries may be regular expressions. It finds objects which match the maximum number of three consecutive character strings (i.e. trigrams) in the entered search terms, which are generally near matches. Two string...
i'm going to start a career discussion in the other chan
issues probably get fixed over time, but I've found github search very unreliable
lol the deepfried memoji
int[] ans = new int[m*n] how to write the same in python?
probably just ans = [0] * (m * n)
It's an array of integers right?
@tepid bolt
if you use numpy, you can also do ans = np.array(shape=(m * n))
zeros. array converts an array-like input to an array.