#algos-and-data-structs
1 messages · Page 153 of 1
I didn't write any of this, so I'm just trying to figure out why each line is important. It would make sense if the roll()s are written specifically for a flipped kernal
I still don't know how I would go about deriving those values for the translation myself, but it would at least provide an answer as to why they're there.
!e I think the rools are different, yeah. Because I'm able to achieve the same results by adding some additional rolls:
import numpy as np
def convolve(myarray, flip: bool = True):
m, n = myarray.shape
y = np.zeros((m, n))
y[int(m/2-1): int(m/2+2), int(n/2-1): int(n/2+2)] = np.array([[1, 1, 1], [1, 0, 1], [1, 1, 1]])
fr = np.fft.fft2(myarray)
if flip:
fr2 = np.fft.fft2(np.flipud(np.fliplr(y)))
else:
fr2 = np.fft.fft2(y)
#print(f"fr2=\n{fr2}")
m, n = fr.shape
cc = np.real(np.fft.ifft2(fr*fr2))
if flip:
cc = np.roll(cc,1,axis=0)
cc = np.roll(cc,1,axis=1)
#print(f"cc=\n{cc}")
cc = np.roll(cc, - int(m / 2) + 1, axis=0)
cc = np.roll(cc, - int(n / 2) + 1, axis=1)
cc = cc.round()
return cc
myarray = np.random.randint(2, size=(4, 4))
print(convolve(myarray,True))
print(convolve(myarray,False))
@vocal gorge :white_check_mark: Your eval job has completed with return code 0.
001 | [[4. 6. 6. 5.]
002 | [5. 4. 6. 6.]
003 | [4. 5. 6. 4.]
004 | [4. 4. 5. 6.]]
005 | [[4. 6. 6. 5.]
006 | [5. 4. 6. 6.]
007 | [4. 5. 6. 4.]
008 | [4. 4. 5. 6.]]
The ones I wrote will only work for an array of this size obviously (probably)
I made them up, by staring at the results of the cc prints for the two calls.
actually, you know what? it might always be 1
because what makes them needed is the fact the kernel isn't centered
when it's centered (so, when the array has odd size along each dimension), then whether you flip y doesn't matter; it's symmetric after all
Only even dimensions produce problems.
And there, I think it might just need a roll of 1 or something like that
Ok that makes a lot more sense
I still don't understand the intuition behind how the kernal gets applied to all the values at once, but I'm just gonna leave that for now as gospel
fourier transforms are nonlocal by their nature - the value of a single frequency depends on the entire array, and when doing inverse transform, the value of every cell depends on every single frequency
as for how to derive this algorithm, uhhhh
It's okay. I'll probably end up taking a linear algebra class at some point to fill in the holes
I'd say it's calculus and not linear algebra
maybe discrete mathematics
didn't hear anything about fourier on linear algebra, personally
Hmmmm okay good to know.
Maybe EE 201
I guess the jump from hermitian matrices to signal processing is a bit of a departmental jump
here's the exact definition fft2 and ifft2 use
except, oh dear, there's stuff about what order the frequencies go in the output too
I guess I should post the obvious nit that "fft" is a particular family of algorithms to compute fourier transforms quickly (fast fourier transform). In particular fft is the sped up computation of a dft (discrete fourier transform). )
What is a sweep line algorithm?
and if you want to see a good video deriving the fourier transform, there is https://www.youtube.com/watch?v=spUNpyF58BY it gives some very good intuitions and interpretations about the transform, though this video does not cover the convolution theorem
An animated introduction to the Fourier Transform.
Help fund future projects: https://www.patreon.com/3blue1brown
An equally valuable form of support is to simply share some of the videos.
Special thanks to these supporters: http://3b1b.co/fourier-thanks
Learn more about Janestreet: https://janestreet.com/3b1b
Follow-on video about the uncertai...
that convolution is deeply connected to the fourier transform isn't entirely obvious, but it's a very deep connection that falls out easily from the math, if you are comfortable with the calculus involved
Fun thing, fourier transform is also applicable to polynomials. Multiplying polynomials knowing the coefficients is a convolution, multiplying polynomials given the values of the polynomial is just multiplying the corresponding values
And roughly speaking, the transform of polynomial coefficients are the values
generally, algorithms where you deal with points in the order in which a line sweeping across the plane would encounter them
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <cstring>
using std::vector;
#include <iostream>
#include <iterator>
using std::ostream_iterator;
using namespace std;
void calc_constrain_prob(unsigned int end,vector< vector<long double> >& probs)
{
static const unsigned int highcount = 20;
unsigned int highsum = highcount*end;
probs.resize(highcount+1,vector<long double>(highsum+1,0));
probs[0][0] = 1;
for(unsigned int i = 1;i <= highcount;++i) // 20
{
for(unsigned int k = 1;k <= end;++k)
{
for(unsigned int j = 0;j + k <= highsum;++j)
{
probs[i][j+k] += probs[i-1][j]/end;
//printf("(%Lf,%Lf)",probs[i][j+k],probs[i-1][j]);
}
//printf("___");
}
for(unsigned int t = 0;t < sizeof(probs[i]);++t)
{
printf("%Lf",probs[i][t]);
printf("\n");
}
printf("\n_%u_\n",i);
}
}
int main()
{
vector< vector<long double> > probs[21];
calc_constrain_prob(4,probs[4]);
calc_constrain_prob(6,probs[6]);
calc_constrain_prob(8,probs[8]);
calc_constrain_prob(10,probs[10]);
calc_constrain_prob(12,probs[12]);
calc_constrain_prob(20,probs[20]);
static const size_t buff_size = 1000;
static const size_t maxsize = 10*20*20; // 4000
char buff[buff_size] = { 0 };
unsigned int nCases = 0;scanf("%d",&nCases);
for(unsigned int iCases = 1;iCases <= nCases;++iCases)
{
unsigned int h = 0,s = 0,x = 0,y = 0;
scanf("%d%d",&h,&s);
long double ans = 0;
for(unsigned int i = 0;i < s;++i) // 10
{
scanf("%s",buff);
int delta = 0,z = 0;
if(NULL != strchr(buff,'+'))
{
sscanf(buff,"%dd%d+%d",&x,&y,&z);
delta += z;
}
else if(NULL != strchr(buff,'-'))
{
sscanf(buff,"%dd%d-%d",&x,&y,&z);
delta -= z;
}
else
{
sscanf(buff,"%dd%d",&x,&y);
}
long double prob = 0;
if(delta > (int)h) delta = (int)(h - 1);
for(unsigned int i = h - delta;i <= x*y;++i)
{prob += probs[y][x][i];
printf("<><><>");
printf("%Lf",probs[y][x][i]);
}
if(prob > ans) ans = prob;
}
printf("Case #%u: %.9f\n",iCases,(double)(ans));
}
return 0;
}
why the probs variable became 3d array
its an array of vectors of vectors
so its used like a 3d array
also this is python server
what's an efficient way to select the largest number in a very lengthy number list, in each iteration that largest number is halved and reinserted into the list
i could just use max(number_list) in each iteration but it's too inefficient. I've also considered sort the list, pick the last element, and then bisect.insort
use a heap
where it assigned became 3d vector
vector< vector<long double> > probs[21];
after this assigned inside calc_constrain_prob() when printing
for(unsigned int t = 0;t < sizeof(probs[i]);++t)
{
printf("%Lf",probs[i][t]);
printf("\n");
}
that's shown values inside the 2d array
after some lines when print probs
for(unsigned int i = h - delta;i <= x*y;++i)
{prob += probs[y][x][i];
printf("<><><>");
printf("%Lf",probs[y][x][i]);
}
became 3d
where the change happen and which part that push the value into 3d array
I'm not what the confusion is other than overlapping naming, in main you have an array probs of vector of vector, the probs in calc_constrain_prob is one of the elements of the probs you have in main.
Anybody with algos for trading experience?
Hi folks, I have a question for u.
imagine that I want to calculate the ceil of the division of 2 numbers. I can either do -(-X // Y) or do math.ceil(X / Y). So my q is, for instances like these that I want to calculate/do small tasks, is it better to use specifics libs or I should do things in the "vanilla" way?
i'd much prefer the latter. there's no thinking required to figure out what you mean by math.ceil
-(-X // Y) is more accurate, i always try to avoid floating number
the ceil version is clearer, but less accurate in general
I would personally do a third option
(X + Y - 1) // Y
assuming X and Y are positive, I think the ones with negatives does the right thing in the more general case in python
hi all,
trying to learn algorithms from my CLRS text. i don't understand the loop invariant.
well i don't understand their pseudocode either, but thats a different story
in addition, is anyone good with runtime analysis? the way it is presented in the book is beyond confusing
i can probably help explain some details
ok that would be excellent. for example, in looking at insertion sort i am struggling to understand their nomenclature surrounding the times cost. i can post a photo
sure
wow is that a physical copy? 👀
yes
ok, which part is confusing?
so on the previous page, they state, "we let t_j denote the number of times the while loop test in line 5 is executed for that particular value of j"
right
it seems redundant. isn't that what they are saying in the previous expression, the summation of the number of times the while loop runs for given n when j=2
maybe i'm reading that incorrectly
also, not understanding the next sections where they prove best and worst case runtime, because they end up getting different terms an^2 +bn + c for a single input array A
also why is it t_j-1 on line 6
they assume the loop body is executed 1 less time than the loop test
it's the same reason why line 2 is n - 1 times
yeah, if you think about what happens in a loop. first the test is checked, then the loop body is run if the test is true
if the test is false, then the body isn't run, so the test is run 1 more time than the body when it ends
the order of the elements is different. the point of finding worst and best cases is to find inputs that would yield the best and worst runtimes
here is the computation of the running time given the above photo
sorry i just don't understand any of it. for me to go online and find a python implementation of insertion sort and see how it runs line by line is trivial. but for me to come up with a mathematical model of pseudocode is impossible.. any advice?
for example many of the exercises in the book are either "write the pseudocode for" or conduct a runtime analysis of some algorithm and im totally in the dark trying to learn it in this manner
you don't actually have to use pseudocode, and it's probably better to write it in an actual language, that way you can test it
if i understand my upcoming course correctly, many of the assignments are going to be write pseudocode in english and implement these runtime summations where appropriate
so i need to be able to convert back and forth between pseudocode and python and conduct runtime analysis on pseudocode
😵💫
maybe i need to just read on and not get hung up in the weeds, but then the book isn't really doing anything for me
conducting runtime analysis on real code seems difficult enough, for example i don't know when to declare something as log_2(n)
something to do with binary i know but then why isn't it instead O(0.5) or O(2)? so confused
the book is a bit difficult. you should be able to ask your prof for help
i'm not taking this until the fall, trying to understand it now before the course starts as i will have other graduate courses
it seems you're missing a lot of basics here
i am well aware of that and have been unable to find those to help me including discord, online tutors, in person tutors with math PhDs, etc
it seems the people that truly understand this stuff are too busy to help others
do you know about binary search?
no
can anyone explain this code
s = [i for i in s.lower() if i.isalnum()]
it's basically regex
it's not regex
. it just takes the alphanumeric characters from a string, and lowercases the alpha ones
hm, ok. basically, the idea is you can halve the search space on each iteration, so it takes log n time, because it takes log n iterations to reduce the space to 1 or 0 elements
i thought logarithm was the inverse of exponentiation
it is
so why is halving equated with logn and not n/2
in binary search, because we halve on each iteration, log measures how many times we need to halve before we get to 1
log should be equated with n/n if anything
i'm not sure what you mean by that
dividing something in half is mathematically equal to multiplying by 0.5 or dividing by 2
so where does this log even come from
this comes from if log is truly the inverse of exponentiation
we're not just dividing by 2, we divide by 2 until we reach 1
if we have 2^n = x, then log_2(x) = n
ok i think the caveat here is that in runtime analysis theyre talking log_2 of some input n, not log_10
but then is it typically log_2 because of the nature of memory itself or because what the algorithm is doing
it's log_2 because we divide in half each time
log answers the question "how many times do we need to divide in half to reach 1"
hence, the running time is log n
ok so you used the example of binary search, which perhaps i will come across. i think the example of nlog_n in my books runtime analysis was that of mergesort?
mergesort is O(n log n), yes
do you know why the book uses theta for worst runtime analysis and not O?
i mean, to symbolize worst case runtime?
i think theta is an upper and lower bound and big O is only upper bound?
but if theta were upper and lower bound then it couldnt be worst-case, which is upper bound
theta is simply an asymptotically tight bound for a function. it doesn't say whether that function describes the best, average, or worst cases
thanks for your help btw something about log just clicked i realized that you cannot have an inverse of exponentiation in division, because you'd just reach 1 after the first step
ok they use theta as worst case runtime notation in the book, i'll have to see the formal def later
if i have a list full of numbers
can i sort the numbers from highest to lowest ?
for example we have ```py
numbers_list = [3, 3, 4, 5, 7, 1]
like is there something like a module or something that can do that?
so if im using the example
numbers_list.sort(reverse=True)
huh?
;-;
try it
numbers = input()
numbers_list = list(numbers)
print(numbers_list.sort(reverse=True))
!e
numbers_list = [3, 3, 4, 5, 7, 1]
numbers_list.sort(reverse=True)
print(numbers_list)
@agile sundial :white_check_mark: Your eval job has completed with return code 0.
[7, 5, 4, 3, 3, 1]
it returns None and modifies the list in-place
oh
you probably want to convert your input to ints too
oh thats bc im actually trying to print the actual conversion of the
list..
jeez, thanks a lot btw
yep but ik how to do that xd, just needed the conversion of ints in a list to go from highest to lowest
appreciate it
can someone help me to understand mergesort? I don't understand their inputs p,q,r
the text reads "A is an array and p,q,r are indices into the array such that p<=q<r
also i'm still not understanding the math behind the analysis of insertionsort
what exactly are u studying btw? i can barely understand anything from the image u sent , just curious what exactly ur studying
algos?
or its smth more complex
algorithms. the text is the famous introduction to algorithms text aka CLRS
their pseudocode is needlessly confusing and the runtime analysis is very mathy for no reason. for example
this is their analysis of the worst case runtime for insertionsort...
that's CLRS for you, it's very rigorous on purpose
its very unhelpful for those that are new to algos
they use p, q, and r to determine where in the large array are the sub-arrays that you're trying to merge
huh? they are required
It would be better as a second pass to algos. There is a difference between just looking at something and kind of knowing what the runtime is, and proving it to be so.
but when you call mergesort its on some input array A, not that plus subarrays
i'm going by what is required for my course
Also this is mathematician bad variable naming, there is a reason why in every programming course they teach you to use long descriptive variable names.
the method shown is merge, not mergesort
what are you gonna call them lol. "left", "right", "center"?
i agree it makes it needlessly confusing which is why i am struggling
ohhh
Yup, anything is better than a single letter, make them an entire sentence if needed.
looking forward to the mergesort algo, i'll need to understand the p q and r variables, and they once again show them as input arguments for reasons i dont get
well not q although it is used later in a merge argument
so it can call itself recursively with smaller bounds
I guess for clarity: what merge does is to take the sorted subarrays with indices [p, q) and [q, r) and merge them together into one big sorted range [p, r)
soo the way its written above makes it seem as if i've gone through the array myself beforehand and identified the indices which will split the array..
all of this needlessly complicated logic ur trying to understand is whats pushing ur logical thinking to the next level
its like punching a wall lmao, each time ur fist gets harder and harder
so tryna study all this complex logic is rlly good tbh
no, to start, you just call it with the array, the first index, and the last index
unless you only want to sort a subset ig
input output example
[1, 4, 6, 2, 3, 7] and p = 0, q = 3, r = 6
------- -------
sub1 sub2
[1, 2, 3, 4, 6, 7]
----------------
result
fair enough but im struggling to understand their most basic nomeclature
eg, #algos-and-data-structs message these summation statements
for how long have yall been studying such complex code btw? im curious
oh wow, I actually aligned stuff properly on my phone
such complex logic*
wait u wrote that on phone ? 💀 wtf
the algo isn't complex
i've been studying python for awhile but have to take a formal grad level algos course next semester with no CS background
are you not majoring in CS or something?
oh jesus 💀
the analysisnis more complivated than what I would want to do though, that's for sure
it really is for someone who hasnt studied it
yep
maybe of one of yall explained it fully i can prob understand smth idk
no
I'm more for having multiple passes, I feel that it's needed anyhow to actually remember it after you finish and having that first pass that is not rigorous makes the second pass that more efficient to get through. But if you have already done a lot of this kind of thinking before, then you may be able to skip that first pass and go straight to the more rigorous part (e.g. you have done a lot of math and can just pick up some new book for some other branch and be fine with all the notation and abstract ideas).
oh ok
so q and r are just like A[q] and A[r]?
well u are right , yeah
arent they ?
no, they're just indexes
oh
so like 0 - len(A)?
something like that, yeah
ok
again this makes it seem as if you have to precompute the indices which'll split the array
no, because you only need to pass the first and last to the mergesort routine
the equivalent python would probably be clearer
inf = <some large value>
def merge(A, p, q, r):
L = A[p:q] + [inf]
R = A[q:r] + [inf]
i = 0
j = 0
for k in range(p, r):
if L[i] <= R[j]:
A[k] = L[i]
i += 1
else:
A[k] = R[j]
j += 1
yes, it is clearer
then what is up with their n_1 = q-p+1?
your example makes much more sense
array length
their arrays are 1-indexed iirc
The Python version can avoid some loops.
yeah, but that doesn't change too much
but again, this is getting back to the heart of my issue, where understanding a real implementation line by line is straightforward but the pseudocode doesn't make sense. perhaps i need to go through with their pseudocode and a real implementation line by line, and discover for myself that "by this pseudocode they mean (real python line)"
not really, only superficially, since the loops you avoid are just replaced by slicing
in CLRS they are, correct
learning to read and translate the different kinds of pseudocode people might write takes some practice
what is the + [inf] bit about
I personally don't like this detailed pseudocode
i didn't like their more simplistic example either
Visually, yeah, it's higher level.
Theirs is more like what C might look like (no fancy built-in slicing (slicing is amazing and pretty much every lang should have it these days IMO (and the new ones do))).
try to run some simple example in your head and try to see what happens if we don't have the inf at the end
hmm
in particular, what happens if we have picked all the elements from one of the lists? we still need to move the rest of the elements in the other array over, but we have no element to compare with from the first array
there are other typical implementations as well that don't add inf at the end
e.g.
def merge(A, p, q, r):
L = A[p:q] + [inf]
R = A[q:r] + [inf]
i = 0
j = 0
k = p
while i < len(L) and j < len(R):
if L[i] <= R[j]:
A[k] = L[i]
i += 1
else:
A[k] = R[j]
j += 1
k += 1
while i < len(L):
A[k] = L[i]
k += 1
i += 1
while j < len(R):
A[k] = R[j]
k += 1
j += 1
now the main loop just runs until we run out of elements in one of the lists, and then it adds the remaining elements afterwards
adding the inf means we don't really have to do this handling, we can just keep picking the smallest element
I've never actually seen the version where you append an inf, it's pretty neat 
this kind of technique is kinda common for things like string algorithms, you sometimes can add an extra character at the end to remove a bunch of complicated bounds checking and whatnot
what is [inf]? A[p:q] is a subarray of the elements from index p through index q yeah?
p up until and including q - 1)
then list ends up as
[A[p], A[p+1], ..., A[q-2], A[q-1], inf]
and as I mentioned, tacking the inf at the end is there to make the rest of the logic cleaner
wat
mergesort is supposed to take as input some unsorted array of integers and return them in sorted array
the input array to merge is A 
where is the infinity coming from
or why is it in the example rather
are you just using that so say for arbitrarily large A?
oh my gosh im seeing the array index minus the other again in this python implementation of mergesort online.. what gives???
def merge(arr, l, m, r): n1 = m - l + 1 n2 = r - m
same as in book
say I'm merging lists
L = [1, 3] R = [2, 4]
^ ^
i j
```1 < 2, add 1 to output
L = [1, 3] R = [2, 4]
^ ^
i j
L = [1, 3] R = [2, 4]
^ ^
i j
```3 < 4, add 1 to output, but what now? i will be incremented outside the list
if I add an extra element that will never be the minimum I don't have to worry about this case
and of course, any number in my input will be < inf, so I can put that at the end
it's just computing the sizes the new arrays L and R need to be
I kinda get most of that for free in python with slicing
If L[i] is inf (it reached the end), R[j] will always be lesser, so the else branch is always run from then onward, which is equivalent to the third while loop above, which copies the remaining elements.
So you no longer need the extra separate loops for the remaining.
in reality the code underlying the slicing will have to compute sizes and copy over elements, much like in the pseudocode
*Depending on the language and what you are slicing in it, it may not actually create a copy, and it's important to know when it copies and when it does not, or it will break things.
!code
Here's how to format Python code on Discord:
```py
print('Hello world!')
```
These are backticks, not quotes. Check this out if you can't find the backtick key.
ok
I'm quite confused why n2 doesn't have a + 1 as well, it feels like it should. That or I misunderstood how they define their indices
i need to test my next question but i don't understand the p, q, r being inputs into the algorithm
Two examples of when it copies and not in Python, numpy does not copy unless it has to (or you tell it to) (some algos require that you copy): ```py
A = [0, 1, 2, 3, 4, 5, 6, 7, 8]
l = A[1:3]
l
[1, 2]
l[0] = 10
l
[10, 2]
A
[0, 1, 2, 3, 4, 5, 6, 7, 8]
import numpy as np
A = np.arange(9)
A
array([0, 1, 2, 3, 4, 5, 6, 7, 8])
l = A[1:3]
l
array([1, 2])
l[0] = 10
l
array([10, 2])
A
array([ 0, 10, 2, 3, 4, 5, 6, 7, 8])
it seems to me like they wouldn't exist until you slice through the input array and declare variables
I could call (my) merge like
A = [2, 4, 1, 2, 3]
merge(A, 0, 2, 5)
and it would make A into [1, 2, 2, 3, 4]
def some_function(A,p,q,r):
for item in range(1,len(A)):
return item
A = [9,5,2,6,3]
some_function(A)
if i run this made up code with an input array, its going to tell me im missing 3 required positional arguments
how then can you define a mergesort function with required positional arguments of indices that need to be predefined
merge and mergesort are not the same thing. mergesort uses merge.
right, mergesort makes use of merge for merging sorted ranges
You would call mergesort on an array, which internally uses merge.
how does merge get its required arguments
lets take for example this code from google
do you know conceptually how merge sort works?
# Python program for implementation of MergeSort
# Merges two subarrays of arr[].
# First subarray is arr[l..m]
# Second subarray is arr[m+1..r]
def merge(arr, l, m, r):
n1 = m - l + 1
n2 = r - m
# create temp arrays
L = [0] * (n1)
R = [0] * (n2)
# Copy data to temp arrays L[] and R[]
for i in range(0, n1):
L[i] = arr[l + i]
for j in range(0, n2):
R[j] = arr[m + 1 + j]
# Merge the temp arrays back into arr[l..r]
i = 0 # Initial index of first subarray
j = 0 # Initial index of second subarray
k = l # Initial index of merged subarray
while i < n1 and j < n2:
if L[i] <= R[j]:
arr[k] = L[i]
i += 1
else:
arr[k] = R[j]
j += 1
k += 1
# Copy the remaining elements of L[], if there
# are any
while i < n1:
arr[k] = L[i]
i += 1
k += 1
# Copy the remaining elements of R[], if there
# are any
while j < n2:
arr[k] = R[j]
j += 1
k += 1
# l is for left index and r is right index of the
# sub-array of arr to be sorted
def mergeSort(arr, l, r):
if l < r:
# Same as (l+r)//2, but avoids overflow for
# large l and h
m = l+(r-l)//2
# Sort first and second halves
mergeSort(arr, l, m)
mergeSort(arr, m+1, r)
merge(arr, l, m, r)
# Driver code to test above
arr = [12, 11, 13, 5, 6, 7]
n = len(arr)
print("Given array is")
for i in range(n):
print("%d" % arr[i],end=" ")
mergeSort(arr, 0, n-1)
print("\n\nSorted array is")
for i in range(n):
print("%d" % arr[i],end=" ")
# This code is contributed by Mohit Kumra
well thats sort of what im trying to understand but given their pseudocode
Mergesort sorts the left and the right, and then merges those two parts, recursively. It's that straight forward and elegant, merge contains all the actual work in terms of programming.
conceptually, mergesort splits the input into two halves, sorts each half, and merges the sorted halves
and for the "sorts each half" part, it uses mergesort, but now with fewer elements
the mergeSort function calls the merge function (on the merge(arr, l, m, r) line) that's how merge gets the args (Maybe I'm missing the real context of the question though
)
that's mostly irrelevant to the question here
it looks like l, m, r don't yet exist
m is defined on the line m = l+(r-l)//2 and l and r are args to mergeSort so they are defined
err, ok, you do need the indices for mergesort if it wants to call itself, my bad
how can one function have access to a variable defined within another function, isn't that "out of scope"?
it passes l, m, and r in so they become local variables in the called function
# sort range [l, r)
def mergesort(A, l, r):
mid = (l + r)//2
mergesort(A, l, mid)
mergesort(A, mid, r)
merge(A, l, mid, r)
this is basically merge sort
you just need to handle the base case where you have 1 element
a list with 1 element is of course sorted
i.e.
# sort range [l, r)
def mergesort(A, l, r):
if r - l <= 1:
return
mid = (l + r)//2
mergesort(A, l, mid)
mergesort(A, mid, r)
merge(A, l, mid, r)
!e consider ```py
def called(arg1, arg2):
print('called with ', arg1, arg2)
def caller(a, b):
print('calling called with', a, b)
called(a, b)
caller(3, 4)``` a and b get sent to called so arg1 is 3 in the scope of called and arg2 is 4 in the scope of called
@fiery cosmos :white_check_mark: Your eval job has completed with return code 0.
001 | calling called with 3 4
002 | called with 3 4
for Graph problem, I think they have 2 forms : the table and the graph (attached images). Are there any differences in term of solving the algorithm ?
the top is what you might call an "implicit graph", where the graph is sorta implicit in the data structure
there isn't really a difference in the algorithm
thank you for helping me
Although if the graph is constrained to a lattice in that way, you may be able to use that fact to your advantage, depending on what kind of problem you're trying to solve.
how can I generate a random 4 digit number which doesn't have the number 8 or 9
you could random.choice(...) 4 times on a list of digits 0-7
or choices
Anyone know of a good way to learn more about parsing text specifically? I'm trying to parse something like this:
Name: Skin Care Product
Ingredients: ingredient 1, ingredient 2, ingredient 3
Out of plain text files. The Name: part was easy for me, I just do a f.readlines(), iterate through the lines removing Name: from the line and what's left is the product name. However, with ingredients, it is trickier because there can be any number of lines of ingredients... I guess the only way to tell if it's the end is if there are two newline chars. Anyway, I'm a bit rusty with this hence my question about these type of string/text parsing algorithms.
I also thought about just using YAML for example, but thought if nothing else doing my original plan there would be a good learning exercise. 🙂
I guess the real question is, is there any way to use some pythonic stuff for this or will I likely need to get nitty gritty with the indexing of the strings? I can think of ways to do this but it's going to involve while loops with i,j etc...
https://docs.python.org/3/library/stdtypes.html#str.split can be used for all of these kinds of things.
>>> s = "Name: Foo"
>>> s.split(": ")
['Name', 'Foo']
>>>
Hmm ok I'll take a look at those docs thanks
However, with ingredients, it is trickier because there can be any number of lines of ingredients... I guess the only way to tell if it's the end is if there are two newline chars
You can start by splitting by"\n\n"then.
Below is my answer to the linked list cycle detection question on hackerrank.
https://www.hackerrank.com/challenges/detect-whether-a-linked-list-contains-a-cycle/problem?isFullScreen=true
def has_cycle(head):
if head==None:
return 0
pointer=head
seen_nodes=set()
while pointer != None:
if pointer in seen_nodes:
return 1
seen_nodes.add(pointer)
pointer=pointer.next
return 0
How could I improve this?
You can reduce the space complexity to constant by using a "two pointer" approach
Basically, there is a slow pointer and a fast pointer. The slow moves one node at a time while the fast moves two nodes at a time. If the pointers equal each other then you know there's a collision.
Because in order for the fast pointer to equal the slow one, it means it must have gone backwards (i.e. a cycle)
v v
a->b->c->d
What if the fast pointer is pointing a in this case? Then they won't be equal but there will still be a cycle
you could do something like this to avoid using set ¯_(ツ)_/¯
def has_cycle(head):
if head == None: return 0
pointer = head
while pointer != None:
if hasattr(pointer, "v"): return 1
pointer.v = 1
pointer = pointer.next
return 0
What is vfor?
just something to mark if the node has been visited
but pointer class has no such field? In this case node class
python actually lets you set one outside
oh. that's cool
This code below to validate whether a string of brackets is balanced
def isBalanced(s):
brackets = {']':'[','}':'{',')':'('}
open_bracket = []
for bracket in s:
if bracket in brackets.values():
open_bracket.append(bracket)
elif len(open_bracket)>0 and open_bracket[-1]==brackets[bracket]:
open_bracket.pop()
else:
return 'NO'
return 'YES'
This is failing the online judge. what do you think is wrong with it? I can't seem to identify the issue here
https://www.hackerrank.com/challenges/balanced-brackets/problem?isFullScreen=true
It won't be equal immediately but it will be the next iteration. Slow will go to C since it moves 1 at a time. Fast will also move to C since it moves 2 at a time.
🤯
You need to return "NO" if the stack is non-empty when the for loop ends.
Why do I miss these things all the time. ugh
What is the best practice when it comes to null checking in python?
I usually use if len(mylist)==0: or if mylist==None
if mylist is really a list then it can't be None, but if not mylist: works to check if a list is empty
I see. That makes sense. Although, I find if not.. notation not as readable in this context. What other alternatives are there?
if not mylist: is probably the "Pythonic" way, though I agree it feels less readable. Otherwise if len(mylist) == 0: is fine (if not len(mylist): also works but is a weird in-between)
though if not mylist: also checks that mylist is None (which you may or may not want)
I agree. Thank you for the insight on this.
When should I use a linked list over a regular list?
So far ive only found it better in performance when inserting/deleting an element at or near the head of the list, since with a regular list youd have to shift over all those elements after the insertion/deletion point.
With regular lists you can also append at O(1) compared to O(n) for linked lists, and accessing an element at a given index is also only O(1) compared to O(n) for linked lists/
You can append but can't add in between at linear speed.
Also another question, when you're inserting a new element into a list of full capacity, is it correct that the program finds another random area of memory with 2x the allocated memory space of the original list to copy the new inserted list over to, then it performs the insert operation of shifting elements after the insert index one index down?
If so, what happens to the original list, is it deleted?
Also, how do you make a list reach full capacity? Do all lists have a default capacity, or is this capacity just the number of elements you initialise a list with e.g. with, ['a','b','c','d'], the program allocates a memory capacity of 4
That is definitely a probable implementation (idk precisely what Python does - it may depend on version and Python implementation, the number is not necessarily 2x ) the old list would get deleted or garbage collected, yeah
Again, this is probably an implementation specific thing you'd have to go hunting in the source for (at least idk default list capacity off the top of my head
) but allocating just what it needs at first (or maybe first nearest power of 2) seems reasonable
And note that you can append to append to a linked list in O(1) if you have a reference to the tail of the list (see: https://docs.python.org/3/library/collections.html#collections.deque)
Thanks!
Could you also help answer this question if youve got time haha, thanks so much
Hmm, yeah your scenario of inserting at the head of the list is the main reason to use one. This comes up maybe most commonly with a queue (see collections.deque again), thought a queue can also be made with a normal array and a circular buffer https://en.wikipedia.org/wiki/Circular_buffer so the LL is not crucial
tbh linked lists almost never seem necessary in practice, in my experience at least
, arrays, dicts, sets and graphs come up way more (though LLs are really just a special case of a directed graph). I view linked lists as more of a quirky DSA learning tool than a super practical data structure 
Sounds good haha, thanks
It comes up, but then it's probably doubly linked, and only really if you are doing systems programming (or a game engine) (so not in Python).
Another key thing is that when it does come up, the nodes are not small, not like 1 integer per node. Like maybe an entire big chunk of memory per node (array or whatever in there).
what's an Active Edge Table
Hello!
I need better solution or an improvement for my code for this problem. I think I'm doing it right ( i've got all test passed but it's taking 17seconds and i know it can be a lot lot faster)
It's graph algorithm. Some modification of MST
We have an array A with towns. each town is represent by (x,y).
The weight of the streets is the lenght among each town given by formula :
len =sqrt((x1-x2)^2 + (y1 - y2)^2)
The time need to build the street is
ceil(len)
We need to create streets among all towns that the all towns are connected and the time to build all street is the lowest possible.
We assume that we are creating each street simultaneously.
So we have to minimize the building time of all streets.
My approach
- Sort edges by time ASC
- take first edge (the lowest time ) and for all edges
- Create edges_copy which will contain all edges with cost reduced by the current_lowest_one
If the reduced time is < 0 then it's INF - MST by Kruskal
Example:
A =[(10,10),(15,25),(20,20),(30,40)]
Result: 7
Because the streets is
0 -1, 0 - 2, 1-3
That's my code
from math import ceil
class Node:
def __init__(self, vale): # makeSet
self.value = vale
self.parent = self
self.rank = 0
def find(x):
if x.parent != x:
x.parent = find(x.parent)
return x.parent
def union(a, b):
repA = find(a)
repB = find(b)
if repA == repB:
return
if repA.rank > repB.rank:
repB.parent = repA
else:
repA.parent = repB
if repA.rank == repB.rank:
repB.rank += 1
def mst_kruskal(G, index, edges):
A = []
findUnion = [Node(i) for i in range(len(G))]
min_edge = float('inf')
max_edge = 0
i = index # index of curr el in findUnion
e = 0 # number of edges that are in our MST ( should be lower than len(G) - 2 )
while i < len(edges) and e < len(G) - 1:
u, v, cost = edges[i]
u, v = findUnion[u], findUnion[v]
if find(u) != find(v):
e += 1
# A.append(edges[i])
min_edge = min(min_edge, cost)
max_edge = max(max_edge, cost)
union(u, v)
i += 1
if e == len(G) - 1:
return max_edge - min_edge
return float('inf')
def highway( A ):
# estimate the cost
ans = float('inf')
V = len(A)
edges = []
for i in range(V):
for j in range(i + 1, V):
cost = ceil(((A[i][0]-A[j][0])**2 + (A[i][1]-A[j][1])**2)**(1/2))
edges.append((i, j, cost))
edges.sort(key=lambda x: x[2])
E = len(edges)
for i in range(E):
fixed_edge_cost = edges[i][2]
edges_copy = []
for e in range(i, E):
if fixed_edge_cost <= edges[e][2]:
edges_copy.append((edges[e][0], edges[e][1], edges[e][2] - fixed_edge_cost))
else:
edges_copy.append((edges[e][0], edges[e][1], float('inf')))
edges_copy.sort(key=lambda x: x[2])
ans = min(mst_kruskal(A, 0, edges_copy), ans)
return ans
- we never execute this line
else:
edges_copy.append((edges[e][0], edges[e][1], float('inf')))
if I understand correctly, I don't think you need MST at all
if you're building the roads simultaneously, and all you care about is the build time, all you care about is minimizing the maximum road
I'd sort your roads, then add the next longest to the graph until the graph is connected
Hmm next longest?
So it's basically mst
how so?
But the only mst is not working here because if all roads are built for example in 5 days. and we have to add one that build in 30 days
the result will be 30 - 5 so 25.
Look example that i gave
are you talking about in the problem or in your algorithm
are you not trying to minimize the build time
We have array of towns
A = [(23, 56), (12, 120), (45, 98), (73, 37), (1, 101)]
When i create (u,v,cost) array we have
edges = [(1, 2, 8), (0, 2, 15), (0, 1, 16), (1, 3, 22), (2, 3, 23), (0, 3, 37)]
and only the mst algorithm will give us
[(1, 2, 8), (0, 2, 15), (1, 3, 22)]
This is the solution by your idea if i understand correctly
so we have
22 - 8 = 14 days to build all roads
But the correct answer is 7 days
explain why you're subtracting those
that's the time between when the first road finishes and last road finishes
(also that wouldn't be my solution)
my solution builds every road shorter than the longest road included in the solution
Okey we need that because we want to know how many time we will need to build all roads ( we are building them simultaneously) So if the road with lowest cost is 7 ( so we will build the road in 7 days) and the highest road is for example 25 ( we are building these roads in the same time so)
that gives us 25 - 7 days in total to build all roads
I'd argue that gives you 25 days to build all roads
Yes that's right
But the answer we need is "the number of days separating the opening of the first and last highway."
Sorry i wasn't precise
so first highway we open after 7 days and the last one in 25 days so
25 - 7 = 18 is our answer here if there would be such an case
Hmm i can't get your idea 😅 Can you do it in pseudocode or on example that i gave?
I don't think it'll help with this problem
Okey
My idea is that some edge weight has to be the minimum edge weight among the edges in an optimal spanning tree; so fix a minimum edge weight and find an MST that only contains edges heavier than that. Since all MSTs are also minimum bottleneck spanning trees, this will work.
yeah it should, but it's like O(E^2 log E)
Yep that's right i know it's possible in O(E log V ) but i don't have idea how
I found something similiar on stack overflow but i don't know how to do update(connected) here
that just means check if the current edges form a connected graph
worst case is O(E) by doing flood every time
it's easy to amortize the adding an edge part... not sure about removing edges though
maybe you could maintain a list of cut-edges as you build up the graph, then you'd know whether removing one disconnects the graph
idk how to maintain that list efficiently though
me too
I'm struggling with this for 3 days
If i use cProfiler in pyton to see what takes the most time i see the MST takes a lot
If only there will be option to pick the appropriate edge first and then do the MST to check rather than just picking the lowest one and then increase
Because now it's O (E * MST) so O(E^2 * log E )
I was trying to print hello in python but it doesn't work
hello. is this channel appropriate for speeding up math based functions / algorithms?
yeah see I was not experienced enough with split() to know all the possibilities... Its pretty powerful!
I am working on the hackerrank "define a queue using two stacks" question. Please se my code below:
class Que:
def __init__(self):
self.enqstack = []
self.deqstack = []
def enque(self, val):
self.enqstack.append(val)
def deque(self):
if self.deqstack:
self.deqstack.pop()
elif self.enqstack:
self.deqstack[:]=self.enqstack[::-1]
self.deqstack.pop()
def write(self):
if self.deqstack:
print(self.deqstack[-1])
How could have avoided using so many self statements? What else do you think can be improved?
It's hard to avoid using self a lot. You could assign the attributes to local variables in the methods, although I wouldn't really recommend that.
Other suggestions:
You could simplify the logic of deque slightly (such that you don't repeat the line self.deqstack.pop()).
Also, are you remembering to clear self.enqstack after moving its items over to self.deqstack?
And also, you need to remember to return a value from the deque method.
def binary_search(list_of_numbers, item_searched):
the_lowest_element_in_the_list = 0
the_highest_element_in_the_list = len(list_of_numbers)-1
while the_lowest_element_in_the_list <= the_highest_element_in_the_list:
the_middle_of_the_list = (the_lowest_element_in_the_list + the_highest_element_in_the_list) // 2
guessed_number = list_of_numbers[the_middle_of_the_list]
print(guessed_number)
if guessed_number == item_searched:
return guessed_number
elif guessed_number > list_of_numbers[the_middle_of_the_list]:
the_lowest_element_in_the_list = the_middle_of_the_list + 1
else:
the_highest_element_in_the_list = the_middle_of_the_list - 1
binary_search([1,6,7,9,11,14,18,19,21,25,27,29,33,36,40], 40)
why this binary search doesn't work?
I still can't see how I could simplify it. I added a line for reseting the enqstack and that part seems to be working.
Another question: why the write function below is not working? It is supposed to print the last element of the que once triggered.
class Que: def __init__(self):
self.enqstack = []
self.deqstack = []
def enque(self, val:int):
self.enqstack.append(val)
def deque(self):
if self.deqstack:
self.deqstack.pop()
elif self.enqstack:
self.deqstack[:]=self.enqstack[::-1]
self.enqstack=[]
self.deqstack.pop()
def write(self):
if self.deqstack:
print(self.deqstack[-1])
query_count = int(input())
q = Que()
for i in range(query_count):
query = [int(n) for n in input().split(' ')]
if query[0]==1:
q.enque(query[1])
elif query[0]==2:
q.deque()
elif query[0]==3:
q.write()
Because your loop condition is incorrect.
Write a small list and run the logic on your notebook
before writing the code
see the logic first
when your loop should stop
You can use another MST algorithm like boruvka
It'd work better in this case
What if not self.deqstack (in the write method)?
Sorry, that was meant to be a reply to @fiery cosmos
Btw, this is what I was getting at when I talked about simplifying the logic of deque: ```py
def deque(self):
if not self.deqstack:
self.deqstack.extend(reversed(self.enqstack))
self.enqstack.clear()
return self.deqstack.pop()
Because you perform the pop whether or not you perform the stack transfer.
But what if deque was called when they are both empty? then pop will return error?
Yep. You usually don't need to consider user error for these kinds of programming challenges (they guarantee you will not get bad input). But if you were writing a class for use in the real world, you would probably want to raise your own exception.
def kth_largest(self, k: int) -> AVLTreeNode:
"""
Returns the kth largest element in the tree.
k=1 would return the largest.
WC TC: O(logN)
"""
if(self.root is None):
return -1
self.kth_largest_aux(self.root,k)
self.count = 0#reset count
return self.result
def kth_largest_aux(self,current: AVLTreeNode,k):
"""auxilary function for kth_largest"""
if current is None or self.count >= k:
return
self.kth_largest_aux(current.right,k)
self.count += 1
if self.count is k:
self.result = current
return current
self.kth_largest_aux(current.left,k)```
Hi, can someone tell me if this method's time complexity will be O(logN) in an balanced AVL tree or would it be O(k)
bc if it isnt O(logN) i need to refactor
ping if needed
It's still E^2 log E with MST by boruvka
idk
you could use prim with k-d tree
Then it'd be E log E or E log^2 E
i have never implemented it tho
also boruvka would make it E^2, which is still better than E^2 log E nevertheless
The only MST algo is not the answer here
What do you mean?
We need to minimize the number of building days separating the shortest road and the longest road.
So we have to do the MST through all edges
So E * MST_complexity
We assume that we are creating each street simultaneously.
Yes
It means that each street start builds in the same time
The time is max number of days that is need to build the longest one road
But our answer is
Yeah I see now
You can do it in log2(E) * MST
by using binary search
Wait you don't even need MST
Or am I still understanding it incorrectly
I don't think so the binary search should help here because how it helps. I start searching the answer from the smallest cost one already
What's the approach without MST?
Why doesn't it help though
Let's say you fix a certain value to be the minimum build time possible to connect all the edges
Then it is obvious that any value greater than it is also valid
hence you can binary search for that value
log2(E) is much faster than E
You don't really have to find the mst
You just have to find any spanning tree
So a simple dfs is enough I guess
Yes, but that doesn't assure us that taking the edge with a smaller cost than we set will give us a larger value of the difference between the end of building the longest road and the end of building the shortest one
I don't get it
how does the shortest one affect the answer
isn't it only about the longest one
It is further possible that taking the edge with the smaller cost will result in a smaller difference
It's about
the_longest_one_time - the_shortest_one_time
I see
to "open" roads as close together as possible after being built
We need to create streets among all towns that the all towns are connected and the time to build all street is the lowest possible.
you should have interpreted it more clearly 🙂
Yes i see 😅 Everyone has a problem with this
Even i when i first read this i though oh its just mst and done
i see now why you used kruskal and not another mst algorithm
only kruskal works in this case
Prim's MST works as well but it's slower and not convenient
I currently has 1.56s to complete all test in my code because I add If -> break condition to prevent doing algorithm for no reason
There's a way to use 2 pointer with link cut tree to get E log E
but idk if someone would bother implementing link cut tree in python
You know that i was trying to to that? But it overwhelmed me and nothing was working
wow
isn't that fast enough
Noo my classmates has like 0,04s xD
But we can't talk about the code and ideas because we have a serious palagit system here
is it alright that you are asking it on this server :)
Yes i think so. If something would go wrong no one before me asked about that so i would justify myself
okay
can you try implementing that in c++ or sth because i'm sure it's gonna be much faster
python is quite slow in competitive programming
I know that but we are doing all stuff in python currently
oh
i came up with something in O(E log^3 E)
but lets move this to DMs ig
Okey that's interesting
I didn't read the problem closely, but shouldn't O(E log E) be fairly easy? Sort edges by weight, use a DSU data structure to add edges one by one until everything is connected.
The worst part of the complexity is just from sorting the edges, the DSU part is cheap
they're trying to minimize the difference between the longest edge and shortest edge
(which you should really mention up front because it's a very different problem)
so not minimize max edge cost?
right
for reference, this problem
Find the sum of integers between 1 and N (inclusive) that are not multiples of A or B.
You are given N, A and B.
the naive way is to iterate from 1 to N and check if it's divisible by A or B
or we can use the AP formula
then do sum of all - sum of multiples of A - sum of multiples of B - sum of multiples of B + sum of multiples of both A and B
are there other ways?
the second way seems like it'd be the best one
this is a simple depth first search here, anyone know why we use * in the last line /
def depth_first_values(root):
if not root:
return []
left_values = depth_first_values(root.left)
right_values = depth_first_values(root.right)
return [ root.val, *left_values, *right_values ]
Hey Guys
I want to take input from user in binary tree but it is showing the error (ValueError: invalid literal for int() with base 10: '').
This is the code:
`class treenode:
def init(self,data):
self.data=data
self.left=None
self.right=None
def printtree(root):
if root==None:
return
print(root.data, end=":")
if root.left!=None:
print("L",root.left.data,end=",")
if root.right!=None:
print("R",root.right.data,end="")
print()
printtree(root.left)
printtree(root.right)
def treeinput():
rootdata= int(input())
if rootdata == -1:
return None
root=treenode(rootdata)
lefttree=treeinput()
righttree=treeinput()
root.left= lefttree
root.right= righttree
return root
root= treeinput()
printtree(root)`
Pls correct why it's not working
What is the purpose of an activation function?
A. To decide whether a neuron will fire or not
B. To increase the depth of a neural network
C. To create connectivity among hidden layers
D. To normalize the inputs
The problem here is when you try to enter a blank value
def treeinput():
try: rootdata= int(input("enter number"))
except: return None
root=treenode(rootdata)
lefttree=treeinput()
righttree=treeinput()
root.left= lefttree
root.right= righttree
return root
Yeah I got it.
What would be the most appropriate data structure for the following use:
lookup (preferably O(1)) whether an element exist in the dataset?
How can I prepopulate a dictionary using enumerate but keys and values will be flipped?
word = ['p','y','t','h','o','n']
dictionary = dict(enumerate(word))
leads to {0:'p', 1:'y', 2:'t', 3:'h', 4:'o', 5:'n'}
but I want {'p':0, 'y':1, 't':2, 'h':3, 'o':4, 'n':5} instead
How to use binary search tree but without classes and objects just with lists and stuff like that?
You can use a dict comprehension
Probably a set, although depends on the details
for binary tree,
i feel like DFS recursion has faster runtime than BFS queue, even though both speed are O(n), right ?
also we need O(n) space for queue and DFS is O(1), right ?
no, since the call stack takes space too
!e
dictionary = dict(enumerate(word))
flipped = {v: k for k, v in dictionary.items()}
print(flipped)```
@ancient ermine :white_check_mark: Your eval job has completed with return code 0.
{'p': 0, 'y': 1, 't': 2, 'h': 3, 'o': 4, 'n': 5}
Hi
Hi
str1="hi this is your chap"
vowels=["a","e","i","o","u"]
reslt=""
def func1(str1,vowels,reslt):
for i in str1:
if i not in vowels:
reslt.join(i)
return reslt
func1(str1,vowels,reslt)
Could anyone assist me with the above function as to why itss not returning the complete sentence without vowels using joins
Below is my attempted solution to the 98. Validate Binary Search Tree leetcode question. It is failing the online judge. What is it that I am missing? I see nothing wrong with it.
class Solution:
def isValidBST(self, root: Optional[TreeNode]) -> bool:
return self.validator(root, None, None)
def validator(self, node, minimum, maximum) -> bool:
if not node:
return True
minbounds:bool=minimum and node.val<=minimum
maxbounds:bool=maximum and node.val>=maximum
if minbounds or maxbounds:
return False
return self.validator(node.left, minimum, node.val) and self.validator(node.right, node.val, maximum)
Join doesnt mutate, it returns the result
Use rslt += i
thanks @silk canyon for the info.
Can I ask my doubt here?
I am unable to clear 2 test cases I think I tried all the cases but still don't know the error
Are there any disadvantages to implement __hash__ like this, when I need my class to be hashable?
def __hash__(self) -> int:
return id(self)```
I don't care about two objects having equal attributes and not having an equal hash, I just wan't single objects to be hashable
x == y must imply hash(x) == hash(y), otherwise you will get errors when you use your objects in some collections
add this to your class```py
def eq(self, other: object) -> bool:
return self is other
ah, thank you 😃
That is the default hash behaviour anyway. It might also be clearer to just do __hash__ = object.__hash__ and the same with __eq__.
Hey guys, I was wondering if there was any way to produce this sort of behaviour :)
class Foo:
def __init__(self) -> None:
self.a = 0
def set(self, var, val) -> None:
# If it exists, set this object's
# var = val
pass
thing = Foo()
thing.set("a", 3)
lol, thank you
you can use the builtin function settattr: https://docs.python.org/3/library/functions.html?highlight=setattr#setattr
conversely, there's also getattr
e.g. setattr(thing, "a", 3)
but this will set regardless of if it already exists
@fleet adder I am curious for what you need this, I only remember using this for some little hackery
Is it possible to pass/receive comparison operators as parameters?
without using conditional statements and treating them as strings but instead processing them directly
def comparison(num1, operator, num2)->bool:
return num1 operator num2
comparison(5, <, 3) will return false
on the other hand
comparison(1, >, 0) will return true
No, not possible. But there are functions for every operator in the operator module:
import operator
operator.add(1, 2) == 3```
You could pass these functions
wait, but id(1) is a huge number and hash(1) == 1
Integers return themselves as the hash value.
!e
print(hash(2**64))
@lean walrus :white_check_mark: Your eval job has completed with return code 0.
8
🧐
up to a certain limit
Ah, so int has its own __hash__
hello,
i do not understand this definition of mathematical induction
Specifically what I do not understand is "assuming P(k) is true" (they say what the kth element is, but not how it would be true or false) and also I do not understand their math following "to both sides of P(k), obtaining..."
They show that something equals (k+1)^2 and then "which is P(k+1) and I don't follow that simplification.
@fiery cosmos The core idea behind induction is:
- You prove that if a statement is true for some number
n, then it also true for the next number (n + 1) - You prove that the statement is true for some initial number (like 1)
- Then if follows that it's true for 1, therefore it holds for 2, therefore it holds for 3 etc.
P(k) is an equation that says that the sum of odd numbers (*2) is equal to that number squared
So that is why P(k) can be true or false
It's a claim
yep, it's like a function returning a bool
it's not the function returning the sum from 1 to k
What they say in text is different from the equation they show though which is weird
they say sum of odd numbers up to n, but then they go to 2n-1
Oh wait nvm
the first n odd numbers
...so what the textbook is saying:
- if
P(k)holds, thenP(k+1)also holds P(1)holds- Therefore,
Pholds for all natural numbers.
in other words:
- if
the sum of the first n numbers is n^2, thenthe sum of the first (n+1) numbers is (n+1)^2 the sum of the first (1) numbers is (1)- Therefore, for any
k,the sum of the first k numbers is k^2
...they prove point 1 (P(k) => P(k+1)) in this way:
- The
kth odd number is2*k - 1 - Then, the sum of the first
knumbers isS(k) = 1 + 3 + 5 + 7 + ... + (2k - 1) - The sum of the first
k + 1numbers isS(k+1) = S(k) + (2k + 1) - So if
S(k)isk^2, thenS(k+1) = k^2 + 2k + 1 k^2 + 2k + 1is(k + 1)^2- In total, if
S(k) = k^2,thenS(k + 1) = (k + 1)^2
right why then do they just drop the exponent
they finish by saying =(k+1)^2 which is P(k+1)
what gives?
another thing, what does the right arrow mean in set theory
Plug k+1 into P.
i can see that P(n) = n^2 and that must have something to do with the answer to what youre pointing out but at this point i dont understand at all
What is P(k+1)?
i don't know. i'm trying to bridge the gap from these all being random symbols. to me it looks like logical gobbledegook
anyone understand this definition?
https://cses.fi/problemset/task/1091 solution in python?, Does anyone know?
what does the arrow mean
i'm very familiar with functions both programming and math wise. not so much relations on sets
for example
"Goes to" / "maps to".
what is this about? is the relation R on the set A not A*A?
if it is A*A, why is 1,1 not in the set of ordered output pairs?
A*A ?
relation on a set is literally just the arrows of each node to other node
so (1, 2) means there is an arrow from node 1 to node 2
and you can see (2, 2) as the arrow from 2 pointing to itself
@fiery cosmos
That is what the right arrow means for set theory yes, note that that is different from these relation arrows @fiery cosmos
every node can have any arrow to 0, 1 or multiple other nodes
can you make sense of this:
"if R is a relation from set A to itself, that is, if R is a subset of A^2 = A*A, then we say R is a relation on A"
Do you mean the Cartesian product (usually "x" as the operator)? https://en.wikipedia.org/wiki/Cartesian_product
no so A*A, if A = {1,2}, is = {(1,1),(1,2),(2,2),(2,1)}
so given this information #algos-and-data-structs message, #algos-and-data-structs message, in what way are we to interpret the directed graph, more specifically, what is meant by "relation R on the set A = {1,2,3,4}"
They say that they would explain it in chapter 8
so maybe it is best to wait for that
Perhaps using sets without numbers in them might make it make more sense for you?
"if R is a relation from set A to itself, that is, if R is a subset of A^2 = A*A, then we say R is a relation on A"
any ideas???
literally none of this makes sense to me. like i don't understand how this is going to be helpful in proving what they set out to prove or even what they're trying to say to begin with
especially with that function definition
A relation is generalization of a function.
And a function is the kind of function normally found in high school math, they might give a more advanced definition of it, but it's the same thing.
If you have something like ```py
def foo(x):
return x * x
You can give it whatever input you want, and it gives one output for that input.
If you list all the input output pairs, for example: ```
(1, 1)
(2, 4)
(3, 9)
...
Maybe you can see how it relates the inputs to the outputs.
In this case my input was the set {1, 2, 3}.
It relates two sets.
If we want to represent all possible input output pairs we could simply write it as AxB.
can we pick this statement apart:
"a function f: A -> B is a relation from A to B(e.g. a subset of A x B) such that each a in the set of A belongs to a unique ordered pair (a,b) in f"
"f is some function / relation that maps from A to B"
like that maps an element a in A to an element b in B?
Yes.
ok so where does the (a,b) come in
From what I showed above for foo.
(a,b) "in" f
Yes, let me put it this way
Let's say foo only takes inputs 1, 2 and 3, and nothing else.
I can replace foo with a lookup table now.
First column is the input {1, 2, 3} and second is the output {1, 4, 9}.
ah this is why they are specifying that relations are only binary unless otherwise specified
So I can define foo as that table / set of ordered pairs.
bc we input a set of discrete elements (a) in set A and via the function map them to b elements of set B
Yes, but the cool thing is that it does not need to be finite, either of the sets.
For example, set of all real numbers to all real numbers.
n-ary relations involve ordered n-tuples
text states "the term relation shall then mean binary relation unless otherwise stated or implied"
The table version would only take 1, 2, 3, unless I had an infinite table which I don't, so I would not use a table for that.
But the order pairs are still there implicitly.
The pop up as I compute them.
Like if I give 100 to foo it spits out whatever.
@opal oriole the explanation for how the function relates elements in one set to elements in another has helped. so relating a set to itself is simply A x A, = cartesian product = A^2
One important thing to note that makes it less general than any relationship, is that functions needs to map to exactly one thing. While for example R has 2 go to two different things.
Like if I have (2, 3), and (2, 2). Then I can't draw a single arrow from 2 to the output for 2.
There are two arrows.
woah lost me now
.
since we're talking about relation, instead of using spitting out whatever, I'd suggest an example of
def does_relate(a, b):
return a%b==0
like this stating that relation ship exists between a and b given that a belongs to A(domain) and b belongs to B(co-domain)
domain and codomain definitely are coming up in my book so i'll reread that section
but that would be true for a function not a relation.
aren't you mixing things up?
Probably.
assuming relation is >= on N=>N (5,2) and (5,3) are both valid.
In mathematics, a function from a set X to a set Y assigns to each element of X exactly one element of Y. The set X is called the domain of the function and the set Y is called the codomain of the function.Functions were originally the idealization of how a varying quantity depends on another quantity. For example, the position of a planet is a ...
In mathematics, a function from a set X to a set Y assigns to each element of X exactly one element of Y. The set X is called the domain of the function and the set Y is called the codomain of the function.Functions were originally the idealization of how a varying quantity depends on another quantity. For example, the position of a planet is a ...
yeah so you mentioned function, saying that for same input, you can't expect 2 different outputs, but that is not always a case with relation.
relation is just a subset of cartesian product of domain and codomain.
sounds like for functions domain = input and codomain = output
I'd say domain = set of input, same for codomain.
should I take an example?
Function is relation, but may not be the other way around.
for relation?
also we're discussing binary relation rn, so, It's better to not mix up lol.
function spits out in your terminology, while relation just exists or doesn't exist
Yeah. Binary.
Create some relation which happens to be a function, and then that can be used to plug in some value and spit out another (binary relation in this case).
Spits out is not exactly a mathematical term here. It's the analogy of a function being some machine you put something into and it gives out a value.
yeah I'm aware but we can use it as long as the guy understands lol.
Yeah i'm not sure if i'm making this any easier at this point lol.
i understand probably 2% of what I read in the book, trying to change that
okay may be start from basics, what is the question?
i'm typically very in tune with what they're saying and then abruptly have no idea
the question is how can I learn enough discrete math to learn enough algorithms to get a necessary B in grad school algos in the engineering school. currently the probability of that is 0%. trying to change that
so i got this book, Schaum's outlines Discrete Mathematics 3rd edition
I also have Discrete Mathematics and its applications 6th edition, but havent really used it
oh jesus, I mean start reading the book, and if you're stuck, ask here, we got math people.
so are you stuck on relation?
you can learn discrete math by reading those books yeah, and yes, its okay to be stuck. we all get stuck.
and its okay to be confused.
none of it makes sense to me. just seems like a bunch of letters and symbols. i've been focusing on the first three chapters, set theory, relations, and functions and algorithms
okay nice, do you understand sets?
and the operations on them? intersection, union and stuff!!!
I bet you'll love logic 😄
about symbols, you can make notes, that U means union, and we define union by this.
you don't need to remember it at first time.
definitely not to any helpful extent. but in their essence yes. the set union is "or" and the set intersection is "and"
symbols can be confusing intially, but you get a hang of it.
which have logical equivalents
that is to a helpful extent, means given 2 sets you can do both operations of them right?
yeah seems easy
nice! so thats more than 0%.
well i haven't even gotten into the algos book yet 😅
i have 2 discrete math books to understand first
I am going to leave this book title here, you can skip to relevant parts in it (it covers a whole bunch of different mathematics in a very non-rigorous way): Concepts of Modern Mathematics by Ian Stewart. It may help you if you are lost, as a first pass to some topic (it's not in-depth / a "real" math text book).
ok thanks @opal oriole
how much time you got?
i want to be ready for the fall semester.. so awhile
few months
THATS TIME!!
it'll be here before i know it
*Chapter 5 is "What is a Function?", so you have a whole chapter for that.
see if you're afraid of symbols thats understandable. I'd say make a note of every weirdo symbol, make a note of them, like
for all is reverse of A thingy.
belongs to is line on C thingy.
make a note of them with small example of sets, and you'll find them helpful.
i'm not concerned with the symbols so much as when i read a logical statement i don't even understand what is it they're trying to say, much less how it'll be helpful for proving something or computing something
like the relation A on A is like wtf??????
like my initial notes would be
union of 2 sets => members of both sets(non repeatitive):
symbol: A U B
(and may be a venn diagram)
intersection of 2 sets => members common in both sets:
symbol: A ^ B (reverse of U to be precise)
(and may be a venn diagram)
*Here the beginning of chapter 4 "The Language of Sets": ```
"Almost any book on 'modern mathematics' talks about sets, and is liberally bespattered with strange symbols ..."
dang i need to get that book. i'll check amazon
it is saying that you will take some element from A, some element of A(again), and we'll check if this ordered pair exists in relation or not(which is a subset of cartesian product of A with itself)
It also tells you purpose, why you care about sets.
It also has a programming section, but it's very old. Still can be useful though.
So say for
A = {1,2,3}
we have relation
R:A=>A (you can read like relation from A to A)
R = ((1,1), (1,2), (2,3))
first, this is relation because this IS subset of cartesian product of AxA
is that understandable?
what about (2,2),(3,2),(3,3)?
(1,3)?
uhm, symbols are not spam at all.
they do not belong in this relation, there can be MANY relations.
oh ok ok
you can invent any supposed R and check if it exists
They sometimes are, sometimes not. Often not, but it's more relatable to the reader this way / makes it easier to get into.
wait but @fiery cosmos
the cartesian product of A = {1,2,3}, let me see if i can compute it
sure, take your time.
= {(1,1),(1,2),(1,3),(2,1),(2,2),(2,3),(3,1),(3,2),(3,3)}?
I'd say Cartesian product of A and A where A = {1,2,3}
yep, exactly.
ok
glad i at least understand that. but in the cartesian product A x B the output is the same (set of ordered pairs) and so A x B =/= B x A
they are ordered pairs
so no, they are not same.
so in computing the output, the matrix you set up to solve, how does one know to put A as the rows or columns?
i think in the book it states to put A as the rows..
it may not necessarily be a table, you can just use it as a set, and mathematically set is a correct word. cartesian product is a set and relation is also a set(subset of cartesian product)
i would not think of it as a table.
ok fair enough, but so to compute the output above i used a series of rows and columns and computed accordingly
AxB = {(a,b) \forall a in A \forall b in B}
for easy of your mind yes, but there are no rows and columns mathematically
.latex
$AxB = \{(a,b) \forall a \in A \forall b \in B\}$
eh
@fiery cosmos I need to go eat dinner but I look forward to speaking with you more in the future thank you
you can ping me here I'll help when I can.
thank you!!
but yeah, I may not be able to answer now soon since its 3 39 AM.
woah.. where are you? get some sleep!!
India. yeah. I was coding some stuff.
thats cool i'm going to go eat some sambar rice
have fun!
no j/k but i do have some friends from south india 😉
haha alr, have fun and take it easy, math is fun!
Can anybody spot what's wrong with my merge sort? I'm new to recursion. The code runs but the array is ordered incorrectly ```py
def mergesort(array):
if len(array) > 1:
mid = len(array) // 2
l = array[:mid]
r = array[mid:]
print(l)
print(r)
mergesort(l)
mergesort(r)
merged_array = []
i = j = k = 0
while len(l) > i and len(r) > j:
if l[i] < r[j]:
merged_array.append(l[i])
i += 1
else:
merged_array.append(r[j])
j += 1
while len(l) > i:
merged_array.append(l[i])
i += 1
while len(r) > j:
merged_array.append(r[j])
j += 1
return merged_array
mylist = [1, 8, 7, 4, 10, 2]
t = mergesort(mylist)
print(f"{t}.")```
Thanks
hi. I'm not sure where I should ask this, but I'm trying to figure out how to shift an item n spaces in an array by its current index. I was challenged with taking a string
alphabet = "abcdefghijklmnopqrstuvwxyz"
``` and shifting each letter by it's current index. A = 1, B = 2, C = 3 and so on where A is the letter of current iteration, and 1 is the number to shift by. I have been trying to figure this out for the past hour trying everything I can think of, plus everything I could find on stack overflow/google with trying to solve this. Help please. Thanks in advance!
off the top of my head, wouldn't making a list of empty strings twice as long and making every other entry a letter do it?
['', 'a', '', 'b', '', 'c' ... ]
When I do
for i in range(n):
if i in hashmap:
print('python')
will my in lookup be O(1) or O(n)?
checking for containment in hashmaps is O(1)
it can be O(n) worst case because of hash collisions, but generally O(1)
O(n) can be assumed to never happen
According to the documentation the worst case is O(n)
the average and best case is O(1)
the only time O(n) comes up in python is if your input is malicious
it's possible with ints, but again, your input needs to be malicious
creating malicious input for ints isn't too hard, sadly https://codeforces.com/blog/entry/101817
so if your user can control the input to your hash table, be vary
hey i'm doing a backtracking question and i'm kind of confused on how state is passed between recursive calls
the question is asking to print all the paths of a ternary tree
why is this code wrong?
def dfs(node, cur_path, paths):
cur_path.append(str(node.val))
if all(c is None for c in node.children):
paths.append('->'.join(cur_path))
return
for child in node.children:
if child is not None:
dfs(child, cur_path, paths)
paths = []
if root:
dfs(root, [], paths)
return paths```
this is the correct code:
def dfs(node, cur_path, paths):
if all(c is None for c in node.children):
paths.append('->'.join(cur_path) + '->' + str(node.val))
return
for child in node.children:
if child is not None:
dfs(child, cur_path + [str(node.val)], paths)
paths = []
if root:
dfs(root, [], paths)
return paths```
cur_path is the path from root to the current node
why can't i append the value of the current node at the beginning, and must instead do it while i call the next recursive call?
One simple problem is to assume the edge case that you only have one node, in which case the paths list is different than what is expected
your function returns ['node.val'] while the solution wants ['->node.val']
anyone know good resources to learn asymptotic analysis
why is the behaviour of [dict()]*9 different from [dict() for i in range(9)]
ps. the behaviour seems to be same if dict() is replaced by a non container like an integer 0
doing list * int copies the references of the things inside the list, it doesn't make new things or copy what the references are referencing
you don't see a difference with ints because ints are immutable, so it doesn't really matter if they're all the same reference
book or video type resource
ah that makes sense
but if you use range, even then do all the items in the list have the same reference?
no, since with the list comp, you're putting a new dict in on each iteration
!e
you can check with id,
A = [dict()] * 9
print(" ".join(map(str, map(id, A))))
B = [dict() for i in range(9)]
print(" ".join(map(str, map(id, B))))
@agile sundial :white_check_mark: Your eval job has completed with return code 0.
001 | 140338032649856 140338032649856 140338032649856 140338032649856 140338032649856 140338032649856 140338032649856 140338032649856 140338032649856
002 | 140338032650944 140338032651008 140338032651072 140338032651264 140338032651328 140338032651456 140338032651520 140338032651584 140338032650368
they're all the same in the first one, so they're the same object
wow thanks that clears stuff out
ok also in the case of non containers, like lets say an int 0, the reference remains the same in list comp or mult, but since ints are immutable they are updated separately?
i cant seem to get my head around how immutability changes the behaviour of updates for ints
Yup. Ints can't be changed inplace, so any time an int element is "updated", it's actually replaced by a new object.
it doesn't change the behavior, it's just the result of that behavior that changes
if it's immutable, then it doesn't matter if you have 2 different 4s, or the same 4
I guess one way to think of it is that x += b is a fancy operation that, depending on whether the object x is pointing to is mutable, either changes the object itself, or is equivalent to x = x + b (which replaces x with a new object).
(This applies even when x is a fancy name like a[5] (an element of a list/value of a dict))
Thanks, it makes a lot of sense now 😄
either, preferably non book as i already have 3 i'm working with
You could look up "Abdul Bari asymptotic analysis" on youtube if youre not aware already,
He's got a lot of DSA stuff and bunch of videos on asymptotic analysis (which you can watch at 1.5x)
DSA?
Data Structures and Algorithms
ok thanks
for some reason this code isn't working for 10 and above
but it is sorting for values below 10
Here's how to format Python code on Discord:
```py
print('Hello world!')
```
These are backticks, not quotes. Check this out if you can't find the backtick key.
def insertionSort(arr):
# for i in range(1, len(arr)):
# val = arr[i]
# index = i - 1
# while index >= 0 and val > arr[index]:
# arr[index + 1] = arr[index]
# index -= 1
# arr[index + 1] = val
for i in range(1, len(arr)):
key = arr[i]
# Move elements of arr[0..i-1], that are
# greater than key, to one position ahead
# of their current position
j = i-1
while (j >= 0 and key < arr[j]) :
arr[j + 1] = arr[j]
j -= 1
arr[j + 1] = key
return arr
size = (int(input("Enter size og the array: ")))
arr = []
for i in range(size):
arr.append(input("Enter the value: "))
print(arr)
#print(bubbleSort(arr, size))
print(insertionSort(arr))
hm
i debugged it as well and it goes only once in the while loop and then never if greater than 10 values
here is the output as well
ah
ok for one thing, you're not converting the inputted items to ints
ooohhhhhhh
but your algorithm is also deleting some elements
is it?
yeah using int sorts the array thank you
oh, nevermind, it's not
when referring to decision tree learning, are those different trees than the binary tree data structure?
nvm, seems like they are
(are different)
Hello! I have another not funny problem but now I don't have any idea that isn't just stupid brute force.
In a country, there are cities connected by a network of one-way pipelines, each with a specific capacity. The oil fields have been depleted, but an inexhaustible source of a new type of fuel has been discovered in one of the cities. It was decided to **build two factories** in different cities to purify the new fuel. **For some reason, these factories cannot be located in a city
where the new fuel was discovered** and the new fuel will be transported through the existing pipeline network. Indicate the two cities where the factories should be built to maximize the production of refined fuel.
Please implement the function maxflow(G,s) that for an existing pipeline network G and a city in which deposit s was discovered, returns the maximum total throughput to the two cities in which factories should be built. The cities are numbered consecutively with the numbers 0, 1, 2, ... The pipeline network is described by a list of triples: **(the city where the pipeline starts, the city where the pipeline ends, pipeline capacity)**
Example:
G = [(0,1,7),(0,3,3),(1,3,4),(1,4,6),(2,0,9),(2,3,7),(2,5,9),(3,4,9),(3,6,2),(5,3,3),(5,6,4),(6,4,8)]
s = 2
The result is: 25 (city 4 and 5)
Another example but did in online graph maker
whats Digital Signature Algorithm ?
What is map() time complexity?
map(int)
I suppose int's time complexity is linear based on the length of the string
So if you have a list of n strings of length k, map(int, lst) is O(n * k) but I am taking a guess on int's time complexity I haven't seen its actual implementation.
I guess a map-like function with 0(1) time complexity doesn't exist?
That would have to be something that maps in parallel
Actually not even
The problem is that you give it a list and it has to apply the function to each element, so if you have a list of length n it needs to call the function n times
yeah that makes sense, but I was still hoping for something, thanks
There's a concurrent version and you could use it with a process pool executor to get parallelism, but it still has to at least iterate the list you gave once I believe. https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.Executor.map
Parallelism doesn't change the complexity anyway, but if you're looking for some sort of performance increase, look into that.
will do so, thanks
hi i wanna make a program in python that calculated the approximation of (for example ln2) using the trapezoidal method
🙏
does breath first search on trees has pre-order, post-order, in-order versions like depth first search does?
anyone knowledgeable in support, lift, and confidence for comparisons? Need to make a function to compare movies given user reviews:
movies = {'User_1': {'Movie_55': 5,
'Movie_203': 4,
'Movie_183': 5,
'Movie_150': 5,
'Movie_68': 4,
'Movie_201': 3}, User_2: {'Movie_55': 1,
'Movie_203': 2,
'Movie_183': 3,
'Movie_150': 5,
'Movie_68': 4,
'Movie_201': 3}}```
Trying to solve minimum span tree on a graph of nodes. What's making it tricky-different in this case, the edges can only travel strait horizontal or vertically. IE if 0,0 and 1,1 are the closest points that should be connected, the edge that connect them have to first go to 0,1 or 1,0 on its way.
First idea was to create all the needed virtual points where things can intersect (like 0,1 and 1,0), But not sure how to setup MST algorithm to allow the use of those points without it routing to all of those as if they were required targets.
Other idea is to compute the weighs as if it was taking the long way without the points. IE 0,0 to 1,1 = distance of 2, without actually keeping track that it goes 0,0 to 0,1 -> then 0,1 to 1,1. Problem here is then these partial edges cannot be reused - But they should be. IE if we have edge from 0,0 to 0,1 already - then we should be able to get from 0,0 to 0,3 by only having to add 2 to the overall MST, not 3. By not keeping track of the 'half' edges the overall solution won't work.
Trying to wrap my head around the graph you're dealing with. Is it some subset of points on a grid? and you have a predefined set of edges between some of them?
Hey @spare olive!
It looks like you tried to attach file type(s) that we do not allow (). We currently allow the following file types: .gif, .jpg, .jpeg, .mov, .mp4, .mpg, .png, .mp3, .wav, .ogg, .webm, .webp, .flac, .m4a, .csv, .json.
Feel free to ask in #community-meta if you think this is a mistake.
!paste maybe you can post it here
Pasting large amounts of code
If your code is too long to fit in a codeblock in discord, you can paste your code here:
https://paste.pythondiscord.com/
After pasting your code, save it by clicking the floppy disk icon in the top right, or by typing ctrl + S. After doing that, the URL should change. Copy the URL and post it here so others can see it.
Top one would be 5 'target' points.
Bottom image - a MST solution that involved adding 3 new virtual points.
How are the edges defined? is it some sort of a clique?
There are no edges. I am generating a potential edge list using a list of X and Y from the targets. If targets = [
(50, 30),
(40, 30),
(30, 20),
(00, 50),
(20, 10)
]
Then I sort and loop X's = [0, 20, 30, 40, 50]
Then Y's = [10, 20, 30, 50]
Then I made a nested loop that uses those to build edges. IE to build all the Horizontal edges, start with first Y of 10 and make edge from (0,10 to 20,10) (20,10 to 30,10) (40,10 to 50,10) etc
Then I do another loop to build all Vertical edges - Start with first X, and loop Y's (0, 10 to 0,20) (0,20 to 0,30) etc.
In the end MST incorrectly connects everything, making some optional is what i don't understand
hey all,
trying to understand the concept of inorder successor of a binary search tree. so far I have:
-if node has right subtree, its inorder successor is the left most node of the right subtree
-if node has no right subtree, the inorder successor is the parent node for which the given node would be in the parents left subtree
am i missing anything?
After adding all those edges/virtual points - this what MST result would be - it routes all points not just my target points - obviously not what i want.
Thinking out loud here. If we take Prim's algorithm as a basis, we can treat this as a clique, and generate each time the next edge with the smallest weight (if you do it smartly there might be a way to avoid having to actually generate all edges, focusing on a subset of candidates). Whenever you create a virtual point, you'll have to update the weights of the existing edges to account for the existence of this new vertex. The challenge will be figuring out which virtual vertex needs to be created (since if you're going from point A to point B you have two ways of going parallel to the axes). If you don't pick the right virtual point you won't get an optimal solution, but it should at least be better than the solution you have below.
Always ask your question. If someone who can answer stumble on it they will 🙂
That's kind of what I was thinking, I need almost modify the grid / add the points as the algo finds its path and not pre-create all the points. Just havn't wrapped my head around it yet.
i'm just asking generally bc this is my syllabus:
looks like it is mostly asymptotics
I'm guessing you'll be learning those algorithms and comparing between them with asymptotic analysis
yeah for sure. right now i'm learning the data structures i'm not yet familiar with (binary search trees, red black trees, others) but I'd like to start with the "basics of asymptotic notation and analysis" bullet as well
yeah you should start with that actually
It will give you context on when it's best to use one data structure over another, and why one even exists
i bounce around a lot. i have 3 different books i've been learning data structures, big O, the algos themselves from. i just learned that big O was introduced in 1892 🤯
the implementation of a binary tree is analogous to that of a linked list (at least the way it is structured in memory). i don't think in one million years i'd sit around and figure out that such a data structure is that much more efficient than implementing some simpler structure on a PC, but at least i know what they're talking about now (eg why it exists) 😅
What do you think is a simpler structure? 😄
To answer that question you first need a problem you need to solve
my lack of mathematical intuition is such that i'd think operations on a binary tree are more steps and thus having greater runtime complexity than say, searching through an array for some element. clearly that is not the case
yeah, a BST, if balanced, allows you to search for values in time comparable to binary search in a flat array
Apparently what I have is the node-weighted Steiner tree problem. https://stackoverflow.com/questions/10056212/minimum-spanning-tree-between-a-start-location-and-a-set-of-required-nodes
TIL, thanks for the link! I'm not surprised at all that some versions of this problem are NP-hard.
694 problems to practice in algorithms with implementations in python
Is there any advantage of implementing a stack using a linked list vs an array/list?
no, unless you're in a super memory constrained environment where you can't amortize properly
I'd expect that on such memory constrained environments, the overhead of the linked list would be higher than the overhead of the array. A doubly linked list's memory overhead is 2 pointers per element, after all
hmm, you can lower that with the trick python's deque uses, though 🤔. that reduces the overhead to 2 pointers per some constant number of elements
sure, but then you're back to using an array/list
but yeah, deques are way better for implementing queues or stacks than linked lists are.
an array, you mean?
no, I meant deques
I was saying that your point is correct, and a doubly linked list of arrays (a deque) is a much better data structure for implementing a queue or a stack than a doubly linked list of elements is
i see. i was confused because i'm used to deque as an adt, like queues or stacks.
since you can also make a deque with a circular buffer
right, Rust does it that way. C++, Python, and Java all implement their deque with the doubly linked list of chunks, so that's what comes to mind first for me
in paricular you have this problem https://en.wikipedia.org/wiki/Rectilinear_Steiner_tree
The rectilinear Steiner tree problem, minimum rectilinear Steiner tree problem (MRST), or rectilinear Steiner minimum tree problem (RSMT) is a variant of the geometric Steiner tree problem in the plane, in which the Euclidean distance is replaced with the rectilinear distance. The problem may be formally stated as follows: given n points in the ...
I think the complexity should be O(n log n)
it does work on a range of size d - s, and then proceeds to call recursively twice for ranges of size (d - s)/2
in short the recurrence is
T(n) = n + 2 T(n / 2)
I could look up the more general formula for getting what that boils down to, but this is the same thing as what quicksort would do for perfect choice of pivot
so O(n log n)
but where is the mistake in my computation then?
I have no clue what is happening after the 3rd line on the right
simple derivation of the correct complexity, starting from T(n) = 2 T(n / 2) + n
Hello peeps, I need help with implementing a tree traversal that deletes odd valued nodes from a binary search tree, how would i go about that?
I mean, isn't it just about doing the recursion? The fact that it's a BST is close to irrelevant for the task
as long as you have a working delete function ig
what delete function? just don't include the odd values in the new tree
ah, that is a better way
what would the time complexity be in that case?
you can easily do O(1) work per node in the traversal
actually, seems like deleting nodes can cause some non-trivial reshuffling to make sure that every node has a value afterwards 
so yes, I guess the delete operation is the important part
Thank you didn't find that on my own!
Was writing a general steiner tree solver last night that added one target point at a time as an end point and solve with dijkstra's, starting from everything else I already have in my path. (was someone's shared pseudocode) Pretty sure this still only gives a 'close enough' answer and not actual minimum but hopefully good enough for what I actually need it for.
After looking at that Rectilinear Steiner tree wiki article, maybe I could improve results by starting with some single trunk trees between subsets. I'm using this for pipe/plumbing/wire routing inside buildings - mainly for estimating pricing.
sharing a small victory here, i implemented a working insertion sort in python using no outside resources, only reading the CLRS book 🙂
hello, i am currently working using the CLRS text and writing from the various algorithmic pseudocodes. i do not understand which expression to use for their "sentinel card" in their mergesort algo, that is, when they set expressions equal to infinity in their pseudocode.
i'm thinking it can be any special value like none or null but perhaps it must be infinity so that the expressions are always set to a value larger than an arbitrarily large number passed into the algorithm
do you understand why they use infinity?
so that whenever that "card" (in their analogy) is exposed, it cannot be the smaller of the two card values being compared
exactly
thats fair i just can't think how i'd model infinity in a real implementation
i mean trivially one could always say somevalue = somevalue+=1
in aiming for the same effect
the float spec defines how to represent infinity in a float
val = float('inf') 
it's special cased to be greater than all numbers

also float('-inf') is a thing though same as -float('inf')
so i know float is a reserved keyword, its just a special version of the keyword float?
float is the builtin to convert things to float (technically a class, and you can reassign it, just bad practice), that is a special input though, yeah
hm ok. in the pseudocode they are setting array[someslicing] = ∞
so i can effectively just set that = float(inf)?
sure
ok!
great to know, thanks
or maybe = [float(inf)] * slicelength if they mean assigning a whole slice
(though that might be weird in practice
could also loop and assign and whatnot)
yeah its a bit esoteric
import math
x = math.inf
``` Is another option.
thank you, one of my questions was going to be about if i would need to import anything
what is the terminology, one is importing, a library?
a module?
nvm googled, it is a module.
I think both are understood, but module is more precise.
as much as i disliked it several months back, asymptotics are actually quite interesting
What is the time complexity of list(i)
O(n)
Hi guys
what is better then list(map(int, lst)) or [int(x) for x in lst]
better in what sense?
they have the exact same time complexity
write whatever is more readable
if you care about that level of performance you're using the wrong language
What would be the overall time complexity for the equation below:
O((2^n - 1)^2)
that simplified should be O(2^(2n))
(2^n - 1)^2 = (2^(2n) - 2^(n+1) + 1), and O(2^(2n)) consumes the other two as clearly smaller
2^(2n) is same as 2^n
What does the line below do?
string = (str)(A)
it isnt
same as str(A), it gets the string representation of the object A
I think it is because 2 in power doesn't scale with n.
https://www.desmos.com/calculator/ph1iikdhja
for 2^(2n) to belong to O(2^n),
2^(2n) < c 2^n
=> 2n log 2 < log c + n log 2
=> n < log_2 c
which'd mean n is bounded by a finite constant
As n approaches to infinity they will become parallel. Similar to how O(n) and O(2n) would behave right?
no, 2^2n is 2^n times larger than 2^n, which is more than a constant facttor