#algos-and-data-structs
1 messages · Page 151 of 1
like here, the 4 7 and 2 part, only the 7 wotn have a partner to compare to so it will be simply adde don
like no need for a while loop there
i would really appreciate any help on the matter, thank you1
why cant this block of code just be replaced with:
if leftpointer < len(left_array):
array[mergedpointer] = left_array[leftpointer]
#no need to update pointers as last step
elif rightpointer < len(right_array):
array[mergedpointer] = right_array[rightpointer]
!e
def merge_sort(array):
if len(array) > 1:
midpoint = int(len(array) / 2)
left_array = array[:midpoint]
right_array = array[midpoint:]
#recursive call on left and right side
merge_sort(left_array)
merge_sort(right_array)
#merge step, compare the left most element of one array to the left most of the other
leftpointer = 0
rightpointer = 0
mergedpointer = 0
while leftpointer < len(left_array) and rightpointer < len(right_array): #check if both left and right have values in it
if left_array[leftpointer] < right_array[rightpointer]:
array[mergedpointer] = left_array[leftpointer]
leftpointer += 1
else:
array[mergedpointer] = right_array[rightpointer]
rightpointer += 1
mergedpointer += 1 #increment the position of the merged pointer we do this for both cases
#once we have ran out of elements in either one of the sublists, we can add the remaining elements to the array
if leftpointer < len(left_array):
array[mergedpointer] = left_array[leftpointer]
#no need to update pointers as last step
elif rightpointer < len(right_array):
array[mergedpointer] = right_array[rightpointer]
array = [5,23,1,2,45,6,4,2,1,5,6,1,3,4,6,3,2,1,3,4,5,6,3,2]
merge_sort(array)
print(array)```
@fiery cosmos :white_check_mark: Your eval job has completed with return code 0.
[1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 2, 1, 4, 3, 2, 4, 3, 4, 5, 6, 3, 2]
it's not about the sizes being similar, you might need to merge something like [3, 4], [1, 2] where you will end up picking all elements from one list, and then the later loops will move the remaining elements over
(also, who calls these pointers, that's just wrong, they are indices)
I had a situation earlier where I found that a floodfill to calculate distances followed by tracing back from the target to find a shortest path was faster than implementing Dijkstra's algorithm using the heapq module. I'm curious why this is.
Isn’t floodfill O(V+E) while dijkstra has an extra log factor
It’s faster if your graph isn’t weighted
has anyone heard of or seen an audio analysis algorithm that distinguishes the different tones made by a conga drum? i'm working on that and looking for prior work to cite.
and if anyone is interested in hearing about or working on the project i'm all for including you
that sounds very specific
I'd guess you'd have to use some sort of general audio analysis and figure out how to distinguish congo drum tones yourself
fft based stuff should be your go-to technique for frequency anysis
Which channel is better for this?
I think that was a response to someone else who deleted their message. But you might also want to try #data-science-and-ml
We were actually discussing adding a multimedia-processing channel at the last staff meeting.
Yes, good idea. I'm using fft. The algo already works fine
I'll try data science and ai, too, then. Thanks
Can anyone recommend any books for learning data structures and algorithms that uses python code?
What's the time complexity of sqrt() ?
@flint lichen math.sqrt()? It should be constant time, to a very good approximation. math.sqrt(1e308) will take roughly the same time to compute as math.sqrt(1.1). If you're passing a Python int to math.sqrt you'd also need to take into account the time for the implicit conversion to float; that conversion does potentially depend on the size of the input (but only in a fairly limited way).
But if you're asking about math.isqrt, that's a whole nother ball game.
Hi, Anyone please correct my understanding(Involves insertion sort algorithm)
When an element is copied in the list like below, it’s overriding the existing value.
Output:
But, when the same copy functionality is used in Insertion sort algorithm, instead of overriding, the value is getting inserted & the remaining values are moving to right.
Output:
if you were to merge 3,4 and 1,2 it would be done in this part of the code
while leftpointer < len(left_array) and rightpointer < len(right_array): #check if both left and right have values in it
if left_array[leftpointer] < right_array[rightpointer]:
array[mergedpointer] = left_array[leftpointer]
leftpointer += 1
else:
array[mergedpointer] = right_array[rightpointer]
rightpointer += 1
mergedpointer += 1 #increment the position of the merged pointer we do this for both cases
#once we have ran out of elements in either one of the sublists, we can add the remaining elements to the array```
no?
because of this part
you are creating a temp variable and then assinging it after
that part would put elements 1 and 2 into the output
i was under the impression that 3,4 and 1,2 are both sub lists, and then what happens is the left most element from both are compared (3 and 1) and then the next left most is compared (4 and 2)
so if it was like 3,4 and 1,2,3 then 3 would be compared with nothing and would just simply get appended
Step by step instructions showing how to run merge sort.
Code: https://github.com/msambol/youtube/blob/master/sort/merge_sort.py (different than video, I added this retroactively)
Source: Data Structures and Abstractions with Java by Frank M. Carrano & http://www.algorithmist.com/index.php/Merge_sort
LinkedIn: https://www.linkedin.com/in/mich...
like what happens at this timestamp
the 2 is compared with the 3 and the 5 with the 8
no, conceptually this is what happens
output = [], left = [3, 4], right = [1, 2, 3]
# 1 < 3
output = [1], left = [3, 4], right = [2, 3]
# 2 < 3
output = [1, 2], left = [3, 4], right = [3]
# 3 == 3, just pick one of them
output = [1, 2, 3], left = [3, 4], right = []
# no elements left in the "right" list, loop ends
OHHH that makes sense
i was under the impression that when 3 is added then 1 also has to be added
like i thought output would be 1,3,2,4,3
that's what makes merge sort work
the merge step takes two sorted sequences and merges them into a new bigger sorted sequence
Thanks ! Exactly what I was looking for.
yeah that makes sooo much more sense! idk what i was thinking, the example was a great way of explaining it
Also, anyone got a good resource to learn how to calculate time complexity of a DP problem ?
I can compute the time complexity of a decision tree, but when I start to memoize the solution I start getting confused.
idk if I can ask this question here but is python capable of making a stock trading algorithm?
Sure, almost any language would be capable. (Though if you're talking using some api or storing lots of stock data some would be more convenient than others)
What exactly do you mean by stock trading algorithm?
Though Python is probably not a bad choice
So in an interview, can we say something like, "We could try x approach, but it wouldnt work because of y" and so on?
Need
is grokking algorithms good for beginners?
yeah
can anyone help me excel in python specificly writing in cells
That makes it sound like your proposing an approach that won't work. Mentioning some alternatives and mentioning the advantages/disadvantages is a good thing, but the way you described it isn't
e.g. often there are several different approaches that might work, but each might have issues, e.g. approach 1 might be slow for large parameters X, and approach 2 might be slow for large parameters Y
which one is the best fit will depend on problem constraints
Hey can anyone help me with my concatenation issue. Problem is that column names and indexes are different and so I cannot concatenate the files. How do I automate renaming? https://stackoverflow.com/q/72052396
# Construct a tree from an adjacency list. Adjacency list can be any order.
# Input: [(1, [4]), (3, [1, 2])]
# Output: Node(3, [
# Node(1, [
# Node(4, [])
# ]),
# Node(2, [])
# ]
from dataclasses import dataclass
from typing import List, Tuple
@dataclass
class Node:
name: int
children: List['Node']
def build_tree(adjacency_list: List[Tuple[int, List[int]]]) -> Node:
# Convert to dictionary so we can quickly look up parents/children
d = {key: value for (key, value) in adjacency_list}
# Need to find the root node -- which node is in the parents set but never referred to?
all_parents = set()
all_children = set()
for parent, children in adjacency_list:
all_parents.add(parent)
for child in children:
all_children.add(child)
possible_roots = list(all_parents.difference(children))
if len(possible_roots) != 1:
raise Exception("Could not find root of tree; invalid data?")
root = possible_roots[0]
def inner(name):
if name in d:
children = [inner(child) for child in d[name]]
else:
children = []
return Node(name, children)
return inner(root)
if __name__ == '__main__':
print(build_tree([(1, [4]), (3, [1, 2])]))
@gritty wedge You basically have a tree written as an adjacency list, and you want to build the full tree in memory
The approach I used is to find the root, then use a recursive algorithm to build the tree
fwiw there is rarely much use for not keeping things as adjacency lists
why not adjacency sets? quick target in neibs[node] checks are nice
thank you so much!!
thanks, 🙂
I guess it was more so like, "We could rearrange the string and have it in sorted order, but that wouldnt help because when we sort it substring attained from it will be different from original strings" something along like this.
Talking about our thought process.
I just find it a weird statement, it reads to me as "We could do X but it wouldn't help at all."
if it was "we could do X and it would solve the problem, but it's super expensive so not a good idea" it's another story
the latter can also be helpful since you have found some route through the problem
it might give some key insight about the problem that can be used
e.g. if sorting solves the problem then maybe there are nicer ways to keep something sorted, like a BBST
or maybe you just need to know the minimum (which sorting makes easy) in which case a heap might be useful
In contrast I think the example statement you gave doesn't give any useful information
I think I'm starting to get some idea, if we have an approach in mind we could talk about it's trade offs, pro and cons. Takes less time, more space. How we can improve the approach if it takes too long.
In a nutshell when we are explaining our thought process it needs to have some useful information.
class Solution:
def minimumCardPickup(self, cards: List[int]) -> int:
"""
For array cards:
Return the length of the shortest subset that contains two matching cards
[3,4,2,3,4,7]
eg for this, it's 4.
"""
mydict = {}
answer = float('inf')
for index in range(len(cards)):
card = cards[index]
if card in mydict:
prev_index = mydict[card]
curr_answer = len(cards[prev_index: index + 1])
answer = min(curr_answer, answer)
mydict[card] = index
else:
mydict.setdefault(card, index)
return answer if answer != float('inf') else -1
curr_answer = len(cards[prev_index: index + 1])
curr_answer = index - prev_index + 1```
what's the time complexity of a length of a slice? I thought it would be constant because reflection, but apparently it's actually linear.
hi.. something wrong is happening in the below merge sort code, anyone pls tell me if you find.
def merge_sort(custom_list):
#Code for dividing
if len(custom_list) > 1:
mid_index = len(custom_list) // 2
left_list = custom_list[:mid_index]
right_list = custom_list[mid_index:]
merge_sort(left_list)
merge_sort(right_list)
#Code for merging
i = 0
j = 0
sorted_list = []
while i < len(left_list) and j < len(right_list):
if left_list[i] < right_list[j]:
sorted_list.append(left_list[i])
i += 1
else:
sorted_list.append(right_list[j])
j += 1
while i < len(left_list):
sorted_list.append(left_list[i])
i += 1
while j < len(right_list):
sorted_list.append(right_list[j])
j += 1
return sorted_list
custom_list = [5,4,1,3,2]
print(merge_sort(custom_list))
Output:
general piece of advice
you have too much code in one single method
of merge_sort
if you instead divide merge sort into 3-4 different functions
the main merge sort and some helper functions
I guarantee your bugs will sort themselves out a LOT quicker
yes I can see what's happening
when you reach your LAST recursive cast in merge sort
ie when you have [5,4]
you are not sorting 5, 4 properly
You are recurring a badly sorted array of values
take a step back, take a deep breath, and try and refactor your implementation of merge sort.
def sort_and_merge_2_lists():
def divide_list_in_half():
def mergesort():
mergesort()
try these helper functions
how to generate distinct list 2d matrix example [[1,2],[3,5],[3,6,8]] difference with [[1,2],[3,5]] is [3,6,8]
What are a few of the best performing online complete coverage path planning algorithms?
Join me in this fun interactive session that will help you in exploring Data Analysis and also walk you through the details of the Microsoft Learn Student Ambassador Program.
Key Takeaways:-
-Introduction to Microsoft Learn Student Ambassador
-Overview of what is Data Analysis
-Creating Microsoft Excel Dashboard
-Introduction to Microsoft Power BI
-Quiz and Giveaways
-Q&A
EVENT DETAILS -
Date - 8th May 2022
Day - Sunday
Time - 5:00 PM IST
Duration - 1 Hour
Platform - Microsoft Teams
Event Host - Aditi Gulati (Alpha Microsoft Student Ambassador)
If anyone is interested then DM for registrations
a slice of a list will always make a copy, so linear
import copy
copy.deepcopy(yourlist)
imo moving the merge part out is sensible, dividing the list in two is so short that it might as well be done in place
wish there was a simple way to slice without copying
yes, i wish for views all the time
you don't return anything in the == 1 case, which as mentioned would be a llt easier to see if e.g. the merge was split out into a helper function
i have an implementation somewhere of this
👀
also doing eager returns makes code a lot cleaner
if len(x) == 1:
return x
# do the general case
something like this, without multiple copies:
In [36]: from sacks.sequences import View
In [37]: my_list = list(range(20))
In [38]: my_view = View(my_list)
In [39]: my_view
Out[39]: View(sequence=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], _range=range(0, 20))
In [40]: my_view[5:10]
Out[40]: View(sequence=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], _range=range(5, 10))
In [41]: _[::2]
Out[41]: View(sequence=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], _range=range(5, 10, 2))
In [42]: for i in _:
...: print(i)
5
7
9
mm
this would only be efficient if the sequence was huge though
why?
cause python is pretty fast at making small lists
itertools.islice
surely that copies too
islice doesn't copy
would doing reversed by just reversing the range be sensible?
i mean, it builds up from scratch
i think that's how it's implemented
reversed does the yield
def __reversed__(self):
for i in reversed(self._range):
yield self.sequence[i]
I meant you could almost return self
the _range is providing the indices, you don't want to yield those
also don't want __reversed__ to mutate the object
do you mean return a new view?
you could do that
with the range reversed
I'm still a bit annoyed that reversed(range(...)) doesn't do that
i think self._range = _range or range(self._olen) should check is None explicitly to account for empty ranges being falsy
while range(...)[::-1] does
reversed needs to return an iterator though
will, i think the result in the same --- range(0) should be empty
if an empty range is passed in self._range gets set to the entire length of the seq
is it just me or is allowing insert and delete on a view pretty sketchy?
at least not without mutating the range extents
it's a mutable view -- was sort of the point, it gets invalidated as soon as you insert or delete though
so operations afterwards will raise
if all you do is iterate with it, it won't invalidate
ah, I should read docstrings huh?
Is reversed not implemented like this:
def reversed(iterable):
return iterable[::-1]
I'm used to things like C++ spans where it's literally "this contiguous chunk in memory"
do you mean the reversed function in python?
Yes
it's not
I mean, basically
you can reverse things that are not indexable/slicable
What? Really?
yeah
In [43]: my_dict = dict(enumerate("abcdefg"))
In [44]: list(reversed(my_dict))
Out[44]: [6, 5, 4, 3, 2, 1, 0]
!e
print(reversed(range(10)))
print(range(10)[::-1])
@haughty mountain :white_check_mark: Your eval job has completed with return code 0.
001 | <range_iterator object at 0x7f6f0b879500>
002 | range(9, -1, -1)
this is a pet peeve of mine
!e you lose useful range abilities
print(range(10)[::-1][2])
print(reversed(range(10))[2])
@haughty mountain :x: Your eval job has completed with return code 1.
001 | 7
002 | Traceback (most recent call last):
003 | File "<string>", line 2, in <module>
004 | TypeError: 'range_iterator' object is not subscriptable
Are there specific iterator types for each corresponding iterable type?
i don't know if there is one for each iterable type
not necessarily, yeah
I...do not like that analysis
just looks like O(n) from line 1
Yeah, that's what I was thinking
I think ned tries to do an average case analysis, hence the /2 in places
O(n) has something related to time to execute a program?
What's that
the most confusing thing here for me is where the 3 comes from
yeah, I have no clue about the 3
is nedbat, like, considering how many bytecode instructions a for-loop iteration is?..
the thing is that O(n/2) is the same as O(n) so it's not important
yeah, these coefficients make it more confusing than useful in some ways
like, quicksort is O(n log n) on average, O(n²) worst case
it's impossible to construct a worst case for a quicksort with random pivot choice, right?
Assume it picks the worst random pivot
Tough I don't know how that algorithm works
I don't mind annotating the if with 1*n/2 (though I would have probably preferred O(n)) here. It's annotating "how many times does this thing run" multiplied by cost
yeah, that's questionable
that's confusing, assigning a tuple or getting the next element could be some P number of steps, dunno the bytecode -- and it doesn't change the O(n) whatever the P is
you could get a lot of different factors depending on how far down you need to go until you say stuff are "primitives"
!e
import dis
dis.dis("""
for a,b in iterable:
do_smth(a,b)
""")
@vocal gorge :white_check_mark: Your eval job has completed with return code 0.
001 | 2 0 LOAD_NAME 0 (iterable)
002 | 2 GET_ITER
003 | >> 4 FOR_ITER 9 (to 24)
004 | 6 UNPACK_SEQUENCE 2
005 | 8 STORE_NAME 1 (a)
006 | 10 STORE_NAME 2 (b)
007 |
008 | 3 12 LOAD_NAME 3 (do_smth)
009 | 14 LOAD_NAME 1 (a)
010 | 16 LOAD_NAME 2 (b)
011 | 18 CALL_FUNCTION 2
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/sijupucume.txt?noredirect
I count 4 steps per iteration, not 3 🥴
FOR_ITER, UNPACK_SEQUENCE, 2 STORE_NAMEs
and it's an implementation detail anyway
and no guarantees bytecode instructions are equally fast (almost certainly not)
well, it's not my favorite analysis
for child_name, mom_name in moms: # O(n)
if child == child_name: # O(1)
return mom_name # O(1)
is how i would do it
yeah, but you can still randomly hit it
though it's way worse if you can construct bad input
iirc you can make an actual worst case O(n log n) if you do something like median of medians
but it's just slow in absolute terms
yeah, same, annotating the cost when a line is run is nicer
with the understanding that you need to multiply the relevant stuff to get the actual complexity
Five steps if you don't forget the jump at the end
whoops, yeah, I was going to count that and then forgot 😩
And at the last time it does FOR_ITER and sees it needs to jump outside the loop I guess
I'd probably do something slightly fancier like
for child_name, mom_name in moms: # O(1) setup, does O(n) iterations
if child == child_name: # O(1) each
return mom_name # O(1) (only executes once)
and leave to the reader the calculation of O(1) + O(n)*O(1) + O(1) = O(n)
yup, FOR_ITER is a nice fancy instruction:
FOR_ITER(delta)
TOS is an iterator. Call its next() method. If this yields a new value, push it on the stack (leaving the iterator below it). If the iterator indicates it is exhausted, TOS is popped, and the byte code counter is incremented by delta.
So GET_ITER is to get the iterator of the iterable?
What if you iterated an iterator?
__iter__ on an Iterator needs to usually just does return self. EDIT: no idea if it's a requirement, probably not
that makes all Iterators Iterable (see collections.abc), which is nice
!e
from dis import dis
dis("""for x in iter(range(3)):
print(x)""")
@slender sandal :white_check_mark: Your eval job has completed with return code 0.
001 | 1 0 LOAD_NAME 0 (iter)
002 | 2 LOAD_NAME 1 (range)
003 | 4 LOAD_CONST 0 (3)
004 | 6 CALL_FUNCTION 1
005 | 8 CALL_FUNCTION 1
006 | 10 GET_ITER
007 | >> 12 FOR_ITER 6 (to 26)
008 | 14 STORE_NAME 2 (x)
009 |
010 | 2 16 LOAD_NAME 3 (print)
011 | 18 LOAD_NAME 2 (x)
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/mexukufeqa.txt?noredirect
(related to whether iterators need to be iterable: https://github.com/python/cpython/pull/29170)
i've not found another implementation yet on an iterator -- if you find one, show me
there are for sure cases where constant factors matter in analysis though, like what's the complexity of this?
def f(n):
out = []
m = n
while m > 0:
out += [1]*m
m //= 2
n is just the input parameter
n log n?
O(n)
(-1)//2
Oh yes
yeah yeah, assume n >= 0

@slender sandal :white_check_mark: Your eval job has completed with return code 0.
-1
Oh dear God
hint: 1/2 + 1/4 + 1/8 + ... = 1
Ah but it's positive ns only
point being: you can't just ignore constant factors all the time
you need to kinda know when you can ignore them
Why is this relevant
so you know the number of times you loop add 1 to the list
I...should probably not have re-used n for the thing I'm dividing by 2
I updated the code a bit to be clearer
just O(n) then
the overall complexity is O(n) yes, but if you jump into the analysis ignoring constant factors you could easily arrive at O(n log n)
O(log n) iterations doing O(n) work each
(which is not wrong because of what O-notation is, but it's not a tight bound)
For a ridiculous optimization, use >>= 1 instead of //= 2
pls no
It's floor division on positive integers anyway
code with clarity in mind
Also why add m
I said it's ridiculous for a reason
in sane languages /2 and >>1 do the same thing in the end anyway
I smell an opinion
I mean it's nice to leave that cruft to a compiler and write the obvious code
def f(n):
out = []
m = n
while m > 0: # O(log(n)) iterations
out += [1]*m # m iterations each time
m //= 2 # O(1)
adding the ms gives n + n/2 + ... + 1, sums to 2n, which is O(n) still
just because I didn't want the confusion of having the input parameter n be something I modify in the loop
so I can say O(n) without it being potentially ambiguous
yeah, that's basically the correct analysis
Wait
Why is it 2n - 1
rather than?
Why is it 2n to begin with

That just tells me O(log(n)) == O(n)
n + n/2 + n/4 + ... =
n*(1 + 1/2 + 1/4 + ...) =
2n
well, n+n//2 + n//4 + n//8 + ... + 1 sums to 2n (-1, alright), it's a geometrical progression
it does not 
I know it doesn't
def f(n):
out = []
k = 1
while True:
cur = n//k
if cur==0: return out
out += [1]*cur
k += 1
Here's a fun one for y'all 🥴
Doesn't this loop exactly n times
it does.
O(log(n))?
Or n + 1 times considering it needs to loop one more time to return
smells like harmonic series
nah, note how cur is at least 1 on each of the n iterations
that's right, analysing this requires you sum n//k for k=1 to n
Yeah that's where I looked
yup
factor out the n and you have the harmonic series left
yeah, it's O(n H_n), where H_n is the nth harmonic number, and those grow as O(log n)
Oh you mean adding the out lists
I mean, it's both the leading factor for time and for space, so I didn't see it necessary to specify what to count here
I did the big O for the typical implementation of Eratosthenes' sieve once, you need to go kinda deep to make is somewhat rigorous
there's actually this fancy expansion that illustrates this:
and it's fun to arrive at O(n log log n)
You're basically saying it's O(log(n)) until that n is used to repeat a statement in the loop, then it's O(n)?
derailing, I found an algorithm that uses continuous intervals (and their unions), i think it's really cool: http://roguebasin.com/?title=Restrictive_Precise_Angle_Shadowcasting
I didn't say anything like that; I'm just saying the complexity of this snippet is O(n log n) (both time and space, as it happens)
why the hell is this on a wiki devoted to roguelikes
because they uses some of these shadowcasting algorithms to determine what characters are visible in terminal games
What shadows exist in terminal games
What does casting a shadow on a character do in terminal games
Oh my god this looks gorgeous
"shadow" as in "some object is behind a wall from your character's viewpoint and isn't visible", Roie
line-of-sight is also a common term
yeah, also field-of-view algorithms
kinda, if the work in the loop was O(1) the complexity would be O(log n), similar to the analysis of binary search
what we ended up with in my case is more akin to quickselect in the analysis
Did you write this program?
but it's the only algorithm i've ever found that uses continuous interval math
which i think is really cool
you mean stuff like working with ranges of reals?
that's right
I think it's not that uncommon when you do computational geometry like this
though I haven't done much of it, CG is kinda painful to me
i mean, i've written a couple of raycasters, but they are purely discrete
especially since it tends to be really fiddly when dealing with floats
if I can avoid the question of floating point comparison I will do that 😛
this algorithm keeps track of the blocked intervals of angles on each step and then adds more blocked intervals on other steps, so you want an efficient way to union intervals
interesting here, is that even sympy does O(n**2) interval math i think the last time i checked
but you can do a lot better if your intervals are sorted
Could someone help explain to me how the function below is O(n^2)?
def my_function(twod_arr):
for arr in twod_arr:
for num in arr:
print(num)
my_2d_arr = [[1,2,3],[1,2,3],[1,2,3]]
my_function(my_2d_arr)
Form my perspective, the inner loop, for num in arr should be independent from the input size of twod_arr, because the individual arr isn't really dependent on the input size of twod_arr.
So really, my_function is more sort of like:
def my_function(twod_arr):
for arr in twod_arr:
# execute some code that is O(1)
Where the # execute some code is just a constant, and the runtime depends on the size of twod_arr, and thus the function should be O(n).
This is opposed to another program where I can see it should be O(n^2):
def my_func(n):
for i in range(n):
for j in range(i,n):
print(j)
Since for j in range(i,n is directly dependent on n. So you can multiply:
O(1) from print(j)
n-ish from for j in range(1,n)
n from for i in range(n)
Which gives O(n^2).
Sorry for the long post, to reiterate my question is why is the first code example O(n^2). Thanks haha
what is n? the complexity of your thing is O(number of total elements)
it's n² if n is the side length of the "matrix" you have as input
n=3 in your example
I was watching a yt vid and he said that its O(n^2), (maybe I copied the code example wrong haha)
well, if the input array is n-by-n, then it's O(n^2)
n in the two cases there is 3 and 4 I think
but you generally need to specify what n is
Oh fr
Ohhh I havent gotten to matrices yet so just took the number of lists within the list as n
if n is the total number of elements (e.g. 3*3 = 9) it's O(n)
so the definition of n matters a lot
No, I think im taking n as the number of sides
Could you explain to me step by step how its O(n^2)? How does for each i in row relate to the number of sides in array_2d
there are n rows, each row has n elements
the example is dealing with square matrices
ohh
ohh each row has n elements
yea ok that makes sense
ty haha
Ok then, so if its not a square matrix but instead just a list of lists like so, would it be O(n), if n is the number of lists within the list (which. with my_l, n=4)?
def my_function(my_list):
for l in my_list:
for num in l:
print(num)
my_l = [[1,2,3],[1,2,3],[1,2,3],[1,2,3]]
my_function(my_l)
I'd say it's not valid to ignore the fact that it also scales with the number of elements in each sublist.
if it's constant for some reason, then yeah, O(n). But if it's not, you need to include it in the complexity.
ah alright
By scaling with the no, of elements in each sublist, youre referring to the square matrix right? Where the number of elements in the sublist is directly related to the number of sides?
Im just talking about a list of lists where theyre not related. If I instead have 100,000 integers in each sublist that wouldnt’ affect O(n) (where n is the length of the overarching list) in that case right?
Sure, since 100000 is a constant.
but the length of each sublist shouldnt matter should it? If each sublist increases in length by 1, how would you calculate big o for that?
Well, if each sublist has length m and there's n of them, then the complexity would be O(n*m)
oh actually then yeah, with each larger input into the overarching list youd have an increase of 1 iteration in the sublist
fax fax
Can you have multiple variables in big o notation? Is O(m * n) a valid expression?
It makes sense in terms of if you define all the variables, just never seen it done b4
I'd say that's the main point here, yeah. Before you start calculating the complexity, you should ask "with regards to what variables"? Here, you can consider the number of sublists (let's call it n), the number of elements in each sublist (let's call it m), or the number of elements total (N=n*m).
If you consider only n and take m to be some constant, it's O(n). If you consider only m and take n to be some constant, it's O(m). If you consider both, or consider the number of total elements, it's O(n*m) or O(N) (same thing).
What to consider as variables depends on your task - what actually changes when this snippet is going to be run. Here, I'd say both n and m can change and so are important, but that's just my opinion.
Definitely definitely, thanks for the insight rly appreciate it!
it would be really weird to say "my algorithm runs in O(1), but i define n as (something that doesn't really make sense in the context of the problem)"
Hi.. i am trying to understand how merge sort works. i written the program by seeing couple of websites & code is working fine. Understood most code, except below where recursion involved. if anyone can explain me in simple manner, please..
#Merges two sorted lists
def merge(list1, list2):
combined_list = []
i = 0
j = 0
while i < len(list1) and j < len(list2):
if list1[i] < list2[j]:
combined_list.append(list1[i])
i += 1
else:
combined_list.append(list2[j])
j += 1
while i < len(list1):
combined_list.append(list1[i])
i += 1
while j < len(list2):
combined_list.append(list2[j])
j += 1
return combined_list
#Splits the list untill it contains one element
def merge_sort(custom_list):
if len(custom_list) == 1:
return custom_list
mid_index = int(len(custom_list)/2)
left_list = custom_list[:mid_index]
right_list = custom_list[mid_index:]
return merge(merge_sort(left_list),merge_sort(right_list))
print(merge_sort([3,1,4,2]))
The below line of code where recursion happens is confusing me.
The main idea is fairly simple: merge, given two sorted list, combines them into a sorted list.
Now, note that single-element lists are always sorted.
So if you just divide the initial list into halves, and them into halves and so on, you'll eventually end up with single-element lists that are sorted. You can combine them pairwise into sorted 2-element lists, them into 4-element ones and so on, until you get the original list but sorted.
So the mergesort algorithm is just "divide the list into halves, mergesort each half, merge the sorted halves into a sorted list".
i've got this sort of execution flow between files going on for a UI and i was wondering if there is a better way to avoid circular imports (well they're not really avoided here i'm just avoiding importing partially initialized modules) than to use imports outside the top of the file.
lemme look
it looks like you're over modulizing your code honestly
or is Main_menu a class and not a package
can i see more of your code?
also this isn't really a ds/algos question
well basically i've got these classes that define gui
example:
class Main_menu:
container = pygame_gui.core.UIContainer(display_rect, gui_manager, visible=1)
exit_ = pygame_gui.elements.UIButton(relative_rect([[.01, .94], [.1, .05]], resolution), 'Exit', gui_manager, container)
settings = pygame_gui.elements.UIButton(relative_rect([[.01, .88], [.1, .05]], resolution), 'Settings', gui_manager, container)
load_game = pygame_gui.elements.UIButton(relative_rect([[0.5, 0.5], [0.2, 0.1]], resolution, mode='centered'), 'Load Game', gui_manager, container, object_id='LoadGame')
@staticmethod
@event_response(settings, pygame_gui.UI_BUTTON_PRESSED)
def settings_response(event: Event):
print('entering settings')
Main_menu.container.hide()
from ui.settings import Settings
Settings.container.show()
@staticmethod
@event_response(load_game, pygame_gui.UI_BUTTON_PRESSED)
def load_game_response(event: Event):
print('entering load game screen')
Main_menu.container.hide()
from ui.load_game import Load_game
Load_game.container.show()
Load_game.reload_selection()
@staticmethod
@event_response(exit_, pygame_gui.UI_BUTTON_PRESSED)
def exit_response(event: Event):
print('quitting')
raise SystemExit
and since this is a single ui page, and a rather simple one, having all of them in one file is inconvenient
also this isn't really a ds/algos question
sry i didn't know where to put it where i could paste images
all of the imports in my original question are these classes that store ui in a neat, dot addressable way
this is the file structure
def load_game_response(event: Event):
print('entering load game screen')
Main_menu.container.hide()
from ui.load_game import Load_game
Load_game.container.show()
Load_game.reload_selection()
def load_game_response(event: Event):
print('entering load game screen')
Main_menu.container.hide()
from ui.load_game import load_game_procedure
load_game_procedure()
does this make sense
the whole point of modules is to isolate their code
you're violating the abstraction barrier by doing what you're doing
does that make sense?
long response incoming...
ok so this would make sense but the thing doesn't exactly work like you think.
basically i've got this event loop :
while True:
for e in pygame.event.get():
if e.type == pygame.QUIT:
raise SystemExit
menu.process_events(e)
gui_manager.process_events(e)
which calls this from the ui.menu file :
def process_events(event: Event):
for i in _event_responses:
if i(event):
break
in the same file, _event_responses is populated this way :
_event_responses: List[Callable[[Event], bool]] = []
def event_response(ui_elements: List | UIElement, event_types: List | int): # used as a decorator
if isinstance(ui_elements, UIElement): ui_elements = [ui_elements]
if isinstance(event_types, int): event_types = [event_types]
def _event_response_handler(fnc: Callable) -> Callable[[Event], bool]:
def _event_handler(event: Event):
if event.type in event_types:
if event.ui_element in ui_elements:
fnc(event)
return True
return False
_event_responses.append(_event_handler)
return _event_handler
return _event_response_handler
then, each ui page containing file can add new ui element responses using the event_response decorator
# generic example
class MenuPhase:
container = pygame_gui.core.UIContainer(_display_rect, gui_manager, visible=1)
interactable = pygame_gui.elements.UIButton(relative_rect([[.5, .5], [.2, .2]], resolution, mode='centered'), 'interactable', gui_manager, container)
@staticmethod
@event_response(interactable, pygame_gui.UI_BUTTON_PRESSED)
def interactable_response(event: Event):
print('interacted')
so when i say "pass over execution", that's a lie. the truth is that i load a new ui page, turn off the old page by hiding its container and turn on the new one by showing its container.
there was only 31 characters left in the discord character limit wew
so in truth, nothing actually gets executed from these files except the event_responses. the truth is everything gets handled by the pygame_gui and pygame event loop, and i just turn on and off event handling for different pages
then maybe just do what you're already doing?
it doesn't seem that bad
or try to find some people who use pygame
my python experience is just solely for research/swe purposes
ok i just felt like having these imports here had to be wrong but if there's no inherent issues with non top level indent imports and circular import architecture that's cool
I have a function defined like this:
f(x, y) = 0 if xy == 0 else 1
What is the best way to get the output over a range in numpy. I know about np.vectorize, but the function is evaluated in python. Is there a way to do this like with simple addition, multiplication, comparison of ndarrays?
are you sure that's your function?
f(x, y) = 1 if xy == 0 else 0
other way around 🙂
still, xy=0 is on the x and y axes
im plotting 3d graphs
so this is 1 on the axes and 0 everywhere else?
there are a few other fucntions Im working with, I just picked this one as an example
basically give it your x and y values and it will spit out a rectangular matrix you can use in vectorized operations
I used this already but how do I map the function over the values after this to get a Z?
x*y == 0 is already basically right, though you might want to cast it to some other type than bool
In [11]: import numpy as np
In [12]: x, y = np.meshgrid(np.linspace(-1, 1, 11), np.linspace(-1, 1, 11))
In [13]: z = (x * y == 0).astype(np.float64)
In [14]: z
Out[14]:
array([[0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],
[1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0.]])
if you're not restricted to numpy you could also use sympy to do symbolic plots https://docs.sympy.org/latest/modules/plotting.html
Guys......why am I finding data structures and algs so difficult to learn.....it's irritating
And those leetcode questions are scaring me
It takes a while to get used to
I’d recommend taking Princeton course on it online
Thnx....I will look into it
Have u tried implementing any of the structures?
But still ......iam currently Learning trees ......and......
I tried......but couldn't get any ideas
Hi guys, if i have these 15 numbers, and i apply median of medians quickselect with blocks of three on this array, which element is used as the pivot?
i;m sorta confused on how it works
Hi, please see the below merge sort code once. It’s working fine, when I am understanding the working, have a doubt..
code:
doubt: Input list is custom_list & the code is preparing output also on the same custom_list. doesn't output list override the input list?
Leetcode: 1385
Can anyone tell me what is wrong with this code?
class Solution:
def binary_search(self, nums: List[int], check: int, test: int) -> bool:
low, high = 0, len(nums) - 1
while low <= high:
mid = (low + high) // 2
if abs(nums[mid] - check) > test:
if nums[mid] >= 0:
high = mid - 1
else:
low = mid + 1
else:
return False
return True
def findTheDistanceValue(self, arr1: List[int], arr2: List[int], d: int) -> int:
arr1.sort()
arr2.sort()
distance = 0
for i in range(len(arr1)):
search_res = self.binary_search(arr2, arr1[i], d)
if search_res:
distance += 1
return distance
This is not working for this testcase.
[-803,715,-224,909,121,-296,872,807,715,407,94,-8,572,90,-520,-867,485,-918,-827,-728,-653,-659,865,102,-564,-452,554,-320,229,36,722,-478,-247,-307,-304,-767,-404,-519,776,933,236,596,954,464]
[817,1,-723,187,128,577,-787,-344,-920,-168,-851,-222,773,614,-699,696,-744,-302,-766,259,203,601,896,-226,-844,168,126,-542,159,-833,950,-454,-253,824,-395,155,94,894,-766,-63,836,-433,-780,611,-907,695,-395,-975,256,373,-971,-813,-154,-765,691,812,617,-919,-616,-510,608,201,-138,-669,-764,-77,-658,394,-506,-675,523,730,-790,-109,865,975,-226,651,987,111,862,675,-398,126,-482,457,-24,-356,-795,-575,335,-350,-919,-945,-979,611]
37
Hello, do you have any resources to recommend for learning the Bellman-Ford algorithm?
MIT OpenCourseWare is a web-based publication of virtually all MIT course content. OCW is open and available to the world and is a permanent MIT activity
Thanks !
The main function looks correct. It must be an issue with the binary search. What 'invariant' are you using for the binary search?
The issue is with this part of the code: ```py
if abs(nums[mid] - check) > test:
if nums[mid] >= 0:
high = mid - 1
else:
low = mid + 1
else:
return False
The invariant you're trying to maintain is that:
- all the values that come before index
lowshould be less thancheck - test - all the values that come after index
highshould be greater thancheck + test
So in order to maintain that invariant, you'd want to do something like this: ```py
if nums[mid] - check < test:
low = mid + 1
elif nums[mid] + check > test:
high = mid - 1
else:
return False
Hope that makes sense @lament shale
daily reminder to use [l, r) ranges in your binary search to simplify code
I generally agree with that, although for certain binary searches the symmetry simplifies things I think.
The most important thing for getting a binary search right in my opinion is to use an invariant.
the invariant in the [l, r) case is a lot simpler though
e.g. f(l) is true f(r) is false
rather than f(l) is true and f(r+1) is false, which means a bunch of ±1 to compensate
the try to do early exit also introduces another +1, which is independent of the others, but that's not super clear reading the code 
I don't think the early exit even helps that much, it adds more logic to the body which might even make it slower. This is for sure a topic where I think people are learning things wrong a lot of the time
while r - l > 1:
mid = (l + r)//2
if cond(mid):
l = mid
else:
r = mid
How can I get the head of linkedlist L1?
I want to access the first node of this linked list
That'd be l1 itself. Unless it's empty, in which case l1 is None.
Look at the definition of the ListNode class you're provided with - that's how it's structured. A bunch of objects, each having a reference to the next one.
The goal of their binary search is to determine whether there is any number in the array between check - test and check + test inclusive (it returns False if so). I do think the symmetric approach works well in this case because of the symmetry of the problem.
You probably want to use the condition while curr_node is not None:
It looks like your plan is to convert the two numbers to regular integers first, add them, then convert the result back to a linked list? It would be more in the spirit of the question to see if you can do the addition without converting the two numbers to integers and back.
And actually, the resulting code may end up shorter.
Think about what the usual procedure is for adding two numbers together by hand.
grabbing a calculator with the left and plugging in the numbers with the right?
Thanks @keen hearth I'll definitely try to think of finding a better way to solve this.
is the binary search even needed for this problem?
I think after sorting you can just do a sweep with two indices
and if you do a binary search you only need to find the first index where value[index] >= target, e.g. using my example code
def any_in_range(arr2, center, radius):
def cond(x):
return x < center - radius
l = 0
r = len(arr2)
while r - l > 1:
mid = (l + r)//2
if cond(arr2[mid]):
l = mid
else:
r = mid
# At this point `r` is the first value that could be in range
return center - radius <= arr2[r] <= center + radius
Edit: fixed some mistakes, algo seems overall fine, mostly just stuff like initializing l and r
And sweeping with two indices is pretty simple as well.
It's the exact same idea: find the first value possibly in range, and the index of that value is non-decreasing, so we can do a single sweep.
def count_in_range(radius):
arr1 = sorted(arr1)
arr2 = sorted(arr2) + [10**9] # add "inf" to remove any
# need for boundary checks
n_in_range = 0
i = 0
for x in arr1:
while arr2[i] < x - radius:
i += 1
if x - radius <= arr2[i] <= x + radius:
n_in_range += 1
return n_in_range
(I should probably verify this last one works by submitting it, I haven't test run it at all)
forgot to invert the answer, but other than that it works fine, version to match what leetcode expects
class Solution:
def findTheDistanceValue(self, arr1: List[int], arr2: List[int], radius: int) -> int:
arr1 = sorted(arr1)
arr2 = sorted(arr2) + [10**9] # add "inf" to remove any
# need for boundary checks
n_in_range = 0
i = 0
for x in arr1:
while arr2[i] < x - radius:
i += 1
if x - radius <= arr2[i] <= x + radius:
n_in_range += 1
return len(arr1) - n_in_range
I really dislike how LeetCode makes you wrap everything in a class, like you're writing Java or something 😄
also Java naming conventions
I think I inverted the binary search condition 
Yeah this is probably the way I would have gone.
fun how I have more issues to connect the binary search solution together than writing the linear scan
If you want to go the binary search route, you could also use the bisect module: ```py
class Solution:
def findTheDistanceValue(self, arr1: List[int], arr2: List[int], d: int) -> int:
arr2 = sorted(arr2)
total = 0
for elem in arr1:
i = bisect.bisect_left(arr2, elem - d)
j = bisect.bisect_right(arr2, elem + d)
total += (i >= j)
return total
yeah, bisect works fine in this case
but fwiw it's very specialized for finding the insertion point in a sequence
lol, found the bug
center - radius <= r <= center + radius
```should have been
```py
center - radius <= arr2[r] <= center + radius
this dumb trick of tacking infinity at the end of a list removes so many annoying bounds checks
welp, I also need to start with l at -1 because I don't know of my condition is true at 0
feels like the binary search is kinda fiddly in this case in general 
I could insert -inf before and inf after if i wanted to hackily make it work
in any case it's like 2x slower than the simple and less error prone sweep
lol, thanks copilot
leetcode constraints pls
1 <= arr1.length, arr2.length <= 500
with such small input you can just do whatever silly thing
Yeah that's true
Thanks, this is my code which worked:
class Solution:
def binary_search(self, nums: List[int], check: int, test: int) -> bool:
low, high = 0, len(nums) - 1
while low <= high:
mid = (low + high) // 2
if abs(check - nums[mid]) <= test:
return False
elif check > nums[mid]:
low = mid + 1
else:
high = mid - 1
return True
def findTheDistanceValue(self, arr1: List[int], arr2: List[int], d: int) -> int:
arr2.sort()
distance = 0
for i in range(len(arr1)):
search_res = self.binary_search(arr2, arr1[i], d)
if search_res:
distance += 1
return distance
what the hell
Hi can someone help me with this simple python problem. I may be overthinking https://stackoverflow.com/questions/72093859/how-do-i-delete-a-particular-sheet-in-a-flat-file-with-python?noredirect=1#comment127383697_72093859
what is the best way to optimize a peak finding system so that it can effectively match my data set
i have a realtime use situation where the total variance will vary wildly across individual data sets and across different data sets
and so far i have not managed to achieve useful peak decomposition of my data
im presently using a matlab-equivalent function for it
but i would like to use peakutils with perhaps some kind of matching? i am not a data scientist at all, just a hobbyist trying to adapt an algorithm called intrinsic time -scale decomposition
https://github.com/falseywinchnet/demoframework/blob/main/demo.py i copied a matlab implementation with many weeks of work
but it doesnt adapt well to my data set, or so it seems
the decomposition trends it produces do not seem to correspond significantly to any measurable feature in the data- decomposing it into up to 12 different frames and then removing them before recomposition leads to static
that is to say, again, because i am not skilled or meaningfully educated with data analysis, i have applied this to audio, and then deleted some of the decompositioned trends and reintegrated the others, and then fed-through the frame to the audio output, where i listen and examine specgram with audacity to see what changes
I had some hopes this method could lead to useful intermediate results for noise reduction
It is used commercially at present in EKG and a lot of research has come out in the past 6 years on the method
so i decided to port it to python over the last month
I'm done porting ITD as it was written in matlab
except for the interpolation routine, that part of the baseline decomposing method was contributed by a friend, and consists of akima spline calculations combined with a linear interpolation(im not even sure how it works, i just know it doesnt crash, LOL)
it appears to be a reversable decomposition routine because
when you reintegrate all the frames of the output, despite the complex math involved in their creation
they add up to the input with e-12 precision or better decimal
sometimes exactly
the difference seems to be due to near-NAN values and INF values which do have a habit of appearing in the composition as well
I am not sure how or why that happens, my best effort is to add normalization and pound the keyboard in frustration
seen here, the orange line is the decomposition of the series in jupiterlite
this is a large picture, click open original and then magnifying glass for full detail
Sorry to tell you this after typing all that out, but this is a question for #data-science-and-ml @fiery cosmos
I recommend copying your question over there.
This channel is more for algorithms in the computer science sense than the data science sense.
you say this because i have posted some matplotlib plots to try to visualize the data, but this algorithm is not a statistical analysis algorithm- it is a frequency decomposition algorithm
i have no experience with data science or with matplotlib aside from today and using it for specgram generation
this is the publication, although the algorithm itself is better depicted in another paper. it is presently being used for EKG, mechanical failure analysis, and seismology, all of which I do appreciate use a lot of data science approaches- however, isnt ITD better categorized with FFT, wavelet transforms and EMD as a fundamental algorithm in the computer science sense?
"We introduce a new algorithm, the intrinsic time-scale decomposition (ITD), for efficient and precise time–frequency–energy (TFE) analysis of signals. The ITD method overcomes many of the limitations of both classical (e.g. Fourier transform or wavelet transform based) and more recent (empirical mode decomposition based) approaches to TFE analysis of signals that are nonlinear and/or non-stationary in nature. The ITD method decomposes a signal into (i) a sum of proper rotation components, for which instantaneous frequency and amplitude are well defined, and (ii) a monotonic trend. The decomposition preserves precise temporal information regarding signal critical points and riding waves, with a temporal resolution equal to the time-scale of extrema occurrence in the input signal. We also demonstrate how the ITD enables application of single-wave analysis and how this, in turn, leads to a powerful new class of real-time signal filters, which extract and utilize the inherent instantaneous amplitude and frequency/phase information in combination with other relevant morphological features."
As depicted in the matplotlib graph posted, the data set of 250 was indeed decomposed into a monotonic trend in the second row
it is unironically true that IMD will likely see a great deal of utilization in improving machine learning approaches and data science and makes use of data science interpolation and peak fitting functions, but frankly, i dont understand how those work any better than i understand how ITD does, and if you look at the code, you can tell me which it better relates to - data science or computer science- and i can take it to the relevant expertise
I'm just saying that you'll probably get better answers from the people that frequent that channel. I personally don't know very much about signal processing.
alright, i think i agree
every language has data structures
Haan how is it with Python?
I tried it and found it great. But i m currently on my basics so, wanted to know about higher levels!
I have a question
for a series like 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, ... how do I find the sum of the nth term
i've tried this all week and have no hope or time left,
honestly, I just need an algorithm since apparently I should reduce the complexity and not use loops
a single algo for the sum of nth term of this series
A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.
different problem
hint: if you collapse the identical terms you have 1²+2²+3³+... for which there is a nice closed form formula
now, to make use of that you need to know how many of those runs you can fit in <= n terms
(and then manually handle the small extra, but that part is easy)
so, how high do you get in n terms?
hint: ||1 + 2 + 3 + ... + x <= n||
Wait no but, the nth term does not work with that formula
Like for n = 3, the value is 2
so sum is 5
Hi guys, I currently need help with a python logic problem.
I need to convert a dict with sublist within, then capture this sublists and transform the dict with simple arguments. Like this.
Example:
dict = [[''], ['215'], ['219,320,352,361'], ['225'], ['220'], ['235'], ['250'], ['242'], ['319']] ; len = 9
the sublist ----> ['219,320,352,361']
transform ----> [219, 320, 352, 361] ; len = 4
Update dict ---> [[''], ['215'], ['219'],['320'],['352'],['361'], ['225'], ['220'], ['235'], ['250'], ['242'], ['319']] ; len = 12
Someone can help me please?
str.split(sep=None, maxsplit=- 1)```
Return a list of the words in the string, using *sep* as the delimiter string. If *maxsplit* is given, at most *maxsplit* splits are done (thus, the list will have at most `maxsplit+1` elements). If *maxsplit* is not specified or `-1`, then there is no limit on the number of splits (all possible splits are made).
If *sep* is given, consecutive delimiters are not grouped together and are deemed to delimit empty strings (for example, `'1,,2'.split(',')` returns `['1', '', '2']`). The *sep* argument may consist of multiple characters (for example, `'1<>2<>3'.split('<>')` returns `['1', '2', '3']`). Splitting an empty string with a specified separator returns `['']`.
For example:
what formula?
e.g. n=12 terms
1 + 2 + 3 + 4 = 10 <= 12, so 4 full terms and 2 extra terms
1²+2²+3²+4²+5*2
= 1 + 4 + 9 + 16 + 10 = 40
!e
print(1+2+2+3+3+3+4+4+4+4+5+5)
@haughty mountain :white_check_mark: Your eval job has completed with return code 0.
40
some derivations
1 + 2 + ... + x <= n
x(x+1)/2 <= n
x² + x <= 2n
(x + 1/2)² <= 2n + 1/4
x <= ±sqrt(2n + 1/4) - 1/2
```and I'll just note that
1² + 2² + 3² + ... + x² = x(x+1)(2x+1)/6
!e
from math import sqrt, floor
def f(n):
x = floor(sqrt(2*n + 0.25) - 0.5)
extra = n - x*(x+1)//2
squares = x*(x+1)*(2*x+1)//6
return squares + extra*(x+1)
print(f(12))
@haughty mountain :white_check_mark: Your eval job has completed with return code 0.
40
@warm ibex this and the stuff after
hey guys, I'm having a little trouble with OOP. trying to apply OOP to my secret auction program, and I'm trying to make an Auction class which will keep a list that tracks the highest bidder, then spit out the highest bidder at the end (I don't even know if this is possible)
`from classes import Auction, Bidder
import replit
bidders = {}
print("Welcome to the Auction!")
bid_on = True
while True:
while bid_on == True:
name = input("What is your name?: ")
bid = input("What is your bid?: $")
bidder = Bidder(name, bid)
bidders[name] = bidder
other_bidders = input("Are there any other bidders? (y/n): ").lower()
if other_bidders == 'y' or other_bidders == 'yes':
replit.clear()
continue
elif other_bidders =='n' or other_bidders == 'no':
replit.clear()
bid_on = False
# work out who has highest bid
v_list = list(bidders.values())
k_list = list(bidders.keys())
# pos = v_list.index(max(v_list))
# winner = k_list[pos]
bid_list = []
print("Bidders\n --------")
for k,v in bidders.items():
bid_list.append([k, v.bid])
print(f"{k}: ${v.bid}")
sorted(bidders.values())
print(bidders)
break`
`class Auction():
def init(self):
self.bid_list = []
class Bidder():
def init(self, name, bid):
self.name = name
self.bid = bid`
Hello people, I hope you have a nice day. How could I avoid that when I am making a loop of requests to an API, if the internet cuts me, I lose all the queries that the program had already made and have to start over.
In python is my query
Practically, if the communication is cut, the program waits for it to resume and does not break
hhello down there
Other Insert Sort, Bubble Sort and section sort, what other complicated algorithms are there?
the actually good sorting algos: quicksort, mergesort, heapsort
there's also algorithms completely unrelated to sorting
What about shellsort?
Example?
Well, here's CLRS (Introduction to Algorithms)'s table of contents:
chapter 3 doesn't count
well, ig they use algorithms to make the structure work
cries in bogo sort
it's complexity is O((n-1)*n!)

both sides of the same coin, pretty much
I think that you should ask this in #networks
:incoming_envelope: :ok_hand: applied mute to @fiery cosmos until <t:1651677400:f> (9 minutes and 59 seconds) (reason: duplicates rule: sent 4 duplicated messages in 10s).
please stop
Not the way to get unmuted, that's for sure
xDD
Hi guys, do you guys have like advanced question 1 or 2 related to python datastructures / math with oeprator, which I will use to ask in an interview. Just to get an idea
Check out the channel pins
I have been solving this problem
I have read through the title of the discussion page and it seems like this can only be solved in O(nlogn)
However this was how I solved it
def find(time):
maxLeft, maxRight = time[0][0], time[0][1]
for i,j in time:
maxLeft = max(maxLeft, i)
maxRight = max(maxRight, j)
for i,j in time:
if ((i > maxLeft and i < maxRight) or (j > maxLeft and j < maxRight)):
return False
return True
print(find([[5,8],[9,15]]))
And it's O(n) time with O(1) space. Maybe I'm missing some edge case?
Sadly it's a leetcode premium question so I can't test out my code except for the 2 given example
Basically I just find the maximum range of time through all the input
Then run through the input again and check if there are any start time or end time within that range, if yes there are conflict, if no then no conflict
Nvm that was just a huge oversight
mb
Hey!
Any idea how to get an answer in the most efficient way?
We have undirected graph **G = (V, E) **and 2 vertices s,t.
We need to implement algorithm that will be checking if there exist edge {p,g} from E which deleted cause the shortest path among s and t extend.
We need to return that edge
for example.
( indexes are the vertices and given list indicate the edges between vertices )
G = [ [1, 2], [0, 2], [0, 1]]
s = 0
t = 2
Answer: (0, 2)
Because the shortest path is
0 -> 2
And if we delete edge (0, 2) it cause the shortest path to extend because it's
0 -> 1 -> 2
so it's like, find all shortest paths, then look for an edge they all use
no, then maybe there's no path
well, number of shortest paths can be pretty huge so imo it'd be better to just remove each edge and check if the shortest path's length is same
if bigger then we found that edge
but rn can't think of anything better
that'd be like O(VE) so like O(V^3)
isn't is enough to do that for all edges in a shortest path?
because either there is an edge that is shared by all shortest paths, or there are independent shortest paths
In the former case we find the edge, in the latter no such edge exists
Hmm that's right
I tried implement it now but i have problem with saving all possible paths to the element.
Like I'm doing BFS and saving some stuff then i will try to look which edges are the same in every path in the same length but for now I'm doing something like this
def longer( G, s, t ):
que = deque()
processed = []
que.append(s)
pathSoFar = [None for _ in range(len(G))]
pathSoFar[s] = [s]
paths = []
while len(que) > 0:
v = que.popleft()
for neighbour in G[v]:
if neighbour not in processed:
# processed.append(neighbour)
que.append(neighbour)
if neighbour == t and [*pathSoFar[v], neighbour] not in paths:
paths.append([*pathSoFar[v], neighbour])
if pathSoFar[neighbour] is None:
pathSoFar[neighbour] = [*pathSoFar[v], neighbour]
else:
if len(pathSoFar[neighbour]) > len(pathSoFar[v]) + 1 or pathSoFar[neighbour][-1] == t:
pathSoFar[neighbour] = [*pathSoFar[v], neighbour]
processed.append(v)
print(paths)
return (0,0)
So i know that to get an element I have to get all elements of the parent element. but the memory complexity is increasing
Remembering the edges is helping but how to use it then... 😳
Because if i will have
edges = [
[(0, 1), (0, 4)],
[(0, 1), (1, 2)],
[(1, 2), (2, 3)],
[(2, 3), (3, 5)],
[(0, 4), (4, 5)],
[(3, 5), (4, 5)]
]
For every vertex i still need to know how long is the shortest path
oh yeah, that's true. Didn't think of that
So that would make it O(V^2)
not all possible shortest paths
find one shortest path, remove one of the edges and find the shortest path again, repeat for all edges in the path
Hmm would it be more efficient than getting all possible ways to get an destination of the same length and see which edge is common in all paths?
I can easily create a graph with an exponential number of shortest paths
Because just removing edge seems to me like there should be something better because it's first what came out to mind
That's true too but using BFS we can get the paths in O(V+E)
Then we need only to check which edge is in all paths of the same ( smallest ) length if there is one pick it if not there is no such an edge
we can get the paths in O(V+E)
wdym "get"?
you sure can't process all the paths one by one
or store them
I mean to traverse the graph using BFS and store several paths at once, not just the one being searched for
how many are "several"?
With BFS we will get first the vertex which are one edge far then two etc.
Look at my code It's not working because i can't see something there but look
but you care about what path you took to get there, right?
because you are looking for overlaps in edges
Possible answers : [(0,2)]
But here it's not working because the answer is the only (8,9) but in my array i store 2 path that has more than one edge intersecting
Hmm yes i'm saving the information about the whole path to then check which edges are the same ( this is not coded yet )
here is a very simple graph that has an exponential number of shortest paths
yes, it's probably possible do better than O(V) BFS traversals, but I don't know any obvious way off the top of my head
but trying to explicitly consider all paths is a no-go
Okey so you advice my to make this greedy algorithm with deleting the edge form the shortest path and see if the newest shortest path after deleting is greater than previous if so return the deleted edge yes?
that's a path that will for sure work and that is reasonably efficient
there is probably some max-flow formulation for this problem, but I'm not good with finding flow formulations
lol, when searching for the problem I find the exact solution I proposed mentioned https://stackoverflow.com/a/14592881/7361858
As a hint I will tell that I currently had BFS, DFS, Topological sort, finding euler cycle and finding the bridges in graph
The problem is FPT parameterized on the distance d and number of edges you are allowed to delete, k: The algorithm is as follows: Find an (s,t)-path of length at most d and branch on the d edges to which you can delete. This results in an algorithm which runs in time O(d^k * n^2).
in this case k = 1, and (I'm assuming) n is the number of vertices, which matches the complexity of the thing I proposed
that answer also gives a reference which might be interesting to you
Hmm thanks @haughty mountain. Will go through that tomorrow because today is late a little.
Hi, I have a problem but i'm not sure if someone can help me with that ... I have a grid (4x6) where at first it's empty, the aim of it is to fill all the spaces of the grid in as few attempts as possible with random figures (from a set of six figures). You can skip the figure and get a new one if you want (but this is an extra step)... So my question is, does anyone know about a technique or algorithm in order to minimize the steps to fill the grid?
So like tetris or?
is the channel free to ask?
if you have a question about algorithms and data structures
sure, I have a problem with understanding divide and conquer algorithm, they have showed us a base but I don't really get the conditions of the ifs inside the function
I have the code
I did one problem, but I don't really get the conditions
def _rec_bs_(e, low, high, elements):
if low > high:
return -low - 1
mid = (low + high) // 2
if elements[mid] == e:
return mid
elif e < elements[mid]:
return _rec_bs_(e, low, mid - 1, elements)
else:
return _rec_bs_(e, mid + 1, high, elements)
def rec_binarysearch(e, elements):
return _rec_bs_(e, 0, len(elements) - 1, elements)
so high is the lenght of the base elements you have -1
and low begins as a 0
e is the element of a sample you are given and elements are a bunch of base elements you have
so basically my problem is inside the rec_bs_ function, what do the conditions do for it to work? why first you check if low>high and you would return -low-1
Not sure why you return -low - 1 @misty plume
when low > high that means the element is not present I believe, so you would normally return something like -1
Do you understand binary search, and why it works and is quicker than just going through the elements from left to right?
my guess is that it checks if the item would be on one half or the other of the sample, and from there it gets closer to the values you want based on if it's higher than that mid variable or lower
but I might be quite off
yeah sort of
with each step, you eliminate half of the possible numbers
So first you check for the middle number, is your number higher or lower
if it is lower, than you don't have to check any number higher than the middle number
because the values are sorted
that's why the high becomes mid - 1 on that elif I guess then
yeah, so after you eliminate the right half of the numbers, you are left with the left half
and you take the middle of the left half
and check if your number is higher or lower
etc.
so first low > high would determine if your element exists as such?
Well if you got to a point where low > high, that means your left bound is higher than your right bound
the elements[mid] == e it's if your element is the middle one
and then you check if it's lower or higher than the middle?
So that wouldn't make much sense, this is the base case where you have not found your number
If this is the case, you have found your number
oooo
ok so no matter the problem
it's always
checking middle
higher middle part
lower middle part
until it either exists
well each time it either checks the higher or lower part
or doesn't
because we can eliminate the rest
yea and with each loop the sample if halved
omg I think I actually get it
where N is the amount of elements
sure shoot
ok first one, is related with competitive programming but it's on terms of making an input
I know how to take in one line with many arguments to group it into a list
but then I found this
first 8 and 2
that's a matrix, and the problem is also a divide and conquer one
alright, so your problem is taking the input?
yes, for example for a line
i would do
things_on_one_line = input().strip().split()
Do you know about nested lists?
and then a for with int(things_on_one_line[i])
but I haven't done something like that
yeah, lists within a list
That's how people normally represent a matrix
each sub list is a row, and the outer list contains all rows
hmm and to do that I have to declare something like a list of lists and append a whole line into it?
!e
matrix = []
row_amount = 3
column_amount = 4
for i in range(row_amount):
row = []
for j in range(column_amount):
row.append(j)
matrix.append(row)
print(matrix)
@lament totem :white_check_mark: Your eval job has completed with return code 0.
[[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]
elements = [[]]
for i in range(8):
things_to_introduce = input().strip().split()
elements[i].append(things_to_introduce)
oh I see
and the last question
would be
understanding how to print paths on dijkstra
dijkstra is a method for finding the shortest path between two needs, what do you need to understand about printing?
because I get the part on writing a dijkstra to get the number for the shortest path
but sometimes they ask a modification
where it includes printing the nodes it goes through to get to a selected node
Well you need to somehow remember for each path where it came from
For each node you could store from which node you travelled to it
and then you could basically travel back to see what path you took
n, m = input().strip().split()
g = []
for i in range(int(n)):
g.append([])
for i in range(int(m)):
c1, c2, d = input().strip().split()
g[int(c1)].append((int(c1), int(c2), int(d)))
g[int(c2)].append((int(c2), int(c1), int(d)))
origin, destiny = input().strip().split()
def select_min(distances, visited):
minima = float('inf')
index = 0
for i in range(len(distances)):
if not visited[i] and distances[i] < minima:
minima = distances[i]
index = i
return index
def dijkstra(g, origen):
distances = [float("inf")] * len(g)
visited = [False] * len(g)
visited[origin] = True
distances[origin] = 0
for c1, c2, d in g[origin]:
distances[c2] = d
for i in range(len(g)):
best = select_min(distances, visited)
visited[best] = True
for c1, c2, d in g[best]:
distances[c2] = min(distances[c2], distances[c1] + d)
return distances
result = dijkstra(g, int(origin))
print(result[int(destiny)])```
this is how I do a dijkstra, but I never know how to get the "parent" of the node to trace back the path
It depends on your implementation, but whenever you make a choice of the best node to travel to next, you could update that next node to also store the node at which you are right now
hmm I see
I have an example that does it
but I don't get how
for i in range(1, len(g)):
next_node = select_min(distances, visited)
visited[next_node] = True
path[next_node].append(next_node)
for start, end, weight in g[next_node]:
if distances[start] + weight < distances[end]:
path[end].clear()
distances[end] = distances[start]+weight
for i in range(len(path[start]) - 1):
path[end].append(path[start][i])
path[end].append(start)
print(distances[e])
for i in range(len(path[e])):
print(path[e][i], end = " ") ```
is the same code of before but inside the def_dijkstra they add that bit
is there a way to make it easier or shorter?
I don't have time to look through all this code rn sorry
yea it´s fine
you already helped me a lot with divide and conquer
thank you very much
I do have another question
so this is a matrix that it's NxN based on the first number (the eight on the top left)
and the 2 in this case, represents "cuts" you make on that matrix
and those cuts are horizontal and vertical, on each half and they count for 1, so that 2 would make 16 groups of 4 digits
like that, so how would I do that, the input I did like this
side_length, cuts = input().strip().split()
matrix = []
for i in range(int(side_length)):
numbers_row = input().strip().split()
for i in range(len(numbers_row)):
numbers_row[i] = int(numbers_row[i])
matrix.append(numbers_row)
print(matrix)```
hi.. I am working with a library that has a bug in its __init__ function. Is there any way to edit __init__ function MethodType?
if i have a list and i get n subsets from that list, then i calculate the sum of the subsets and select maximum sum. Do i get it right that the time complexity of that operation is O(n) where n in the number of subsets?
n times subset length
I hope you're not looking at all subsets, because there are 2^len(list) of those
Well calculating the sum of a subset would be constant if the size doesn't change, so only given n as the number of subsets, the operation would be O(n) time complexity. As the runtime scales with the number of subsets.
What sorting algorithm is this? :)
arr = [79, 23, 88, 2, 34, 51, 5, 9, 17]
for currentElement in range(0, len(arr)-1):
for movingElement in range(currentElement+1, len(arr)):
if arr[movingElement] < arr[currentElement]:
temp = arr[currentElement]
arr[currentElement] = arr[movingElement]
arr[movingElement] = temp
print(arr)
Bubble sort
this looks to be bubble sort, methinks
Thanks! How to express the total complexity if the number of subsets are exponential complexity O(1.6**n). As these are subset made of non adjacent positions, so like Fibonacci (n as number of elements in input array). And sum is linear O(n), but n as the number of subsets.
But as i think about it now the subsets size will increase when size of input array (list) from which subsets are created increase. 🤔
.latex if you have $n$ items, then there are $^nC_r$ subsets with a length of $r$, so your total number of iterations would be $\sum_{r=0}^{n} r \cdot {^nC_r} = n2^{n-1}$
.latex in terms of the number of subsets, if $N = 2^n$, $n2^{n-1} = \frac{1}{2}N\log_2N$
Oh nice I've learnt latex command for discord. Thanks. Still trying to digest the complexity though...
.latex what is $^nCr$, i mean the upper $^n$ in front of $C$
its the number of ways of selecting r objects from a set of n objects
n!/((n-r)!r!)
Does it make a difference If the subsets are only made of non adjacent positions?
Is it possible to sort like... if you have a list of numbers of two digits, three digits and four digits. You need to insert the elements in a way like it shows all the 3 types in different lists?
Like we have 10 random numbers upto 4 digits and then we seperate the accordingly into the 3 types
it does, yes - then the number of subsets grows as fib(n) (proof at <#python-discussion message>), so approximately 1.61**n instead of 2**n.
still exponential, though, so you definitely shouldn't even try iterating over all of them, unless your problem limits n to something very small (like, 20 or less) - an if I recall correctly, your problem (https://www.hackerrank.com/challenges/max-array-sum/problem) does n up to 10**6 or something like that 10**5
that's just a ||simple dp problem|| right?
That's actually a common trick in competitive programming: looking at the input limits to estimate what complexity of an algorithm is expected from you. Very very roughly, you can aim for about 10**6-10**9 operations in a second. Since n goes up to 10**5, even an O(n^2) algorithm is likely too slow. I'd guess you're meant to do some divide-and-conquer approach to do it in O(n log n) or lower
|| actually, yeah, that seems like it works too. Wouldn't that be O(n) even? ||
yeah 10^5 suggests something like n log n, maybe n sqrt n if you want to be weird
it would
yes i read your message many times and i think i understand it now :). Thanks again!
yest they test it with large numbers so this will not likely pass.
I am trying to understand how to determine the complexity of the full solution, that means selecting the subsets which is 1.6**n (n - size of the input array) and then next step is to make the sum of elements in the subset and compare with the maximum. The comparison operation, and assignment to new max operations are constant time, so can be skipped i think.
So we have the sum operation, which would be linear time complexity i think if the subset size was the same, so the more subsets to sum over the more time it would take.
But in this case we also have subsets of varying size, the larger the input array n the more larger in size sums to do. Not sure how to combine these to time complexities into one for the complete solution.
what is the actual statement of the problem you're trying to solve?
https://www.hackerrank.com/challenges/max-array-sum/problem
but i want to specifically determine the time complexity of the solution where i generate subsets from array and then i compare the sums of the subsets with stored max and then i slect max in this way.
Well, if you want to calculate the complexity of the naive solution, the formal way would be... for a non-adjacent-subset of length k, the complexity is O(k) (to calculate the sum). To get the total, we need to sum this over all subsets, so you'd calculate something like
.latex sum_{k=0}^n N_k(n) k
lol, so much for latex
where N_k(n) is the number of k-element (!) non-adjacent subsets from an n-element array.
I'm frankly not sure what N_k is, so this sounds hard.
thankfully the intended complexity is easier to count 😏
But we can guess that the sum is going to be O(n fib(n)). This is the upper bound for it for sure (because N_k(n) <= fib(n), and k<=n), and if you pick a random non-adjacent-subset, it's probably going to have n/2 elements on average or so
so the complexity of the naive solution is the nasty O(n 1.6**n) - because the number of non-adjacent-subsets scales like 1.6**n, and also the time to sum an averagely-sized subset scales like n
that was my thinking about it. thank you for confirmation.
is this O(n * 1.6**n) n times 1.6**n ?
yup
thank you!
are you familiar with dynamic programming? if not this is a great task to learn and practice it
i have read about it when solving this task, and i saw solution which i think is dynamic programming, although not sure. it's pretty simple when you look at it. but difficult if you don't know it 🙂
is this dp?
||
def max_subset_sum(arr):
t = 0,0
for v in arr:
t = t[1]+v, max(t)
return max(t)
||
Yup, I'd say that counts as DP still. They essentially cut the DP solution down further by noticing you only care about the values for the last two values of n
it's kinda like computing fibonacci numbers:
# naive solution
def fib(n):
if n<=1: return 1
return fib(n-1) + fib(n-2)
# DP solution
def fib(n):
arr = [1,1]
while len(arr) < n+1:
arr.append(arr[-1]+arr[-2])
return arr[-1]
# Notice we only use the last two values each time, so we don't need to store the rest:
def fib(n):
a,b = 1,1
for i in range(n-2):
a,b = b,a+b
return b
(might be off-by-one-iteration in that third one)
(In fact, I'd say your task and computing fibonacci values are intrinsically connected, so it's no surprise there are parallels like that)
nice one. i like that explanation. thanks! need to read more about dp for sure.
Formulation a dp tends to boil down to coming up with the right parametrization of the problem. A good one in this case: let DP(i, used) be the max value if you're allowed to use the first i items and if used you were allowed to pick the ith item.
In this case this ends up being easy to simplify further in the implementation since you only depend on a few other states
What tree is good for storing Classes?, i have 2 People that have their own characteristics, Hair Color, Eye Color, Height.. Etc etc..
any hints on how I can use recursion efficiently to solve the element uniqueness problem?
atleast better than O(n^2)
if len(self.maxHeap) > len(self.minHeap) + 1:
heappush(self.minHeap, -heappop(self.maxHeap))
elif len(self.maxHeap) < len(self.minHeap):
heappush(self.maxHeap, -heappop(self.minHeap))
Looking through an algorithm in python, why is there a negative in front of popping from the heap?
The question has to do with finding median of input stream using two heaps
you can flip the sign of the elements you store to make a min heap into a max heap (and vice versa)
having a minus on the thing they call minHeap is pretty disturbing though
because the regular thing in python for doing heap operations heapq maintains a min heap
Hello what sorting algorithm is this?
arr = [4,9,3,2,8,1,6,0,5,7]
def sort(array):
for currentElement in range(0, len(array)-1):
currentMin = array[currentElement]
for movingElement in range(currentElement+1, len(array)):
if arr[movingElement] <currentMin:
currentMin = array[movingElement]
swapTemp = array[currentElement]
array[currentElement] = currentMin
array[movingElement] = swapTemp
print(array)
sort(arr)
it's close to selection sort, just more wasteful by doing more swaps than needed
Yoo Fellow Coders, check out the latest solution for Leetcode: 876 "Middle of the Linked List" problem, just solved today,.
Time Complexity: O(N/2)
Space Complexity: O(1)
AH I see, that makes so much sense. Thanks a ton
the light blue in the upper left is the original input. the left side are the baselines. the right are the rotations. the 5th rotation overlays the samples as a thin red line. Check it out, its pretty neat!
i got an exam coming up soon, any one any websites to solve on it? besides hackerrank
Does anyone know of a good resource to learn algorithms and data structures in Python?
Preferably not using OOP
Don't know
I think O(n)
Its O(n^2) because str+str creates new string, and you do it in every iteration
strings are immutable, so creating a new string (e.g by adding a character to an existing one) takes time proportional to the length the string will be
so it's like having an extra linear time thing when the else triggers
ah
But this could be made O(n) with a few changes by using lists
can a binary tree or a ternary tree have null values 😅
amongst other data type values
string = ''
for _ in range(n):
string += 'a'
so this will result in O(n^2)?
wrong reply but whatever
it should, but it doesn't
python optimizes that to O(n)
I think so in theory. Or it can depend on implementation it seems https://stackoverflow.com/questions/37133547/time-complexity-of-string-concatenation-in-python
As of Python 2.4, the CPython implementation avoids creating a new string object when using strA += strB or strA = strA + strB, but this optimisation is both fragile and not portable. Since you use strA = strB + strA (prepending) the optimisation doesn't apply.
So the run length encoding algo above is O(n) after all, assuming this optimization 
and wrt this algo, even if we assumed the string concatenations weren't O(n), this is technically not O(n)
Why not
because of the str(ctr)?
The value or data part attached to a node could be null or any data type, sure, if you wanted it to have them. If you mean the nodes themselves a null/None node usually means it doesn't exist
it would be nice to have a proper optional type in python
actually, I guess it doesn't matter much because python is dynamically typed, I guess my complaint is more that T|None has horrible semantics
I want my None coalescing operators 
c = a if a is not None else b
c = a ?? b``` 
the one thing JS has on python 
Is this selection sort?
arr = [5,2,6,1,3]
for i in range(0, len(arr)-1):
minIndex = i
for j in range(i+1, len(arr)):
if arr[j] < arr[minIndex]:
minIndex = j
temp = arr[i]
arr[i] = arr[minIndex]
arr[minIndex] = temp
print(arr)
appears so
I ran the code with the node itself being a null/none and it worked :3
Hi,
Please correct my understanding regarding the BFS:
Let’s consider below graph.
||
Started with node “A”
||
It’s siblings are B,C ----- So, they should be covered next
||
Next; you should cover all the child’s of B,C ----- So, E,D &G should be covered next
||
Finally, F
traversal logic is right?
looks good
Ok. Thanks for verifying
But, most of sources say: below is the BFS pattern, which led to confusion.
Hmm, I find that diagram misleading, at least the "levels". In my mind the levels of a BFS match your first diagram. However in this example a BFS very well could follow the maroon path ABCDGEF (and does assuming you do things in a-z order when there's a choice)
Exactly.. The problem with 2nd diagram is; it forces to think like, After "node A", "node B" must be visited, as both are at the level 1
||
But, in reality it's not the case.
Right. Starting A then C is just as valid as a BFS as starting A then B
Because of this misleading diagram in udemy course, 1/2 day consumed to get clear on this confusion..
this thing is just wrong
unless you for some reason say both A and B are your starting nodes
which is something you can do, but it's not typical
Yeah this diagram is not very helpful.
@haughty mountain this works almost for all test but it takes 70s 😳
Queue: 5 , 6 , 4 , 3, 2, 1
Neighbours vertex 7: 5, 6 } this vertices have distance = splen - 1 (4) so we are pushing them to Queue
Neighbours vertex 5: 4, 7 } We are considering only 4 beacuse 7 has greater distance than splen - 2 (3)
-> Push 4 to Queue
Neighbours vertex 6: 4,7 } We are considering only 4 beacuse 7 has greater distance than splen - 2 (3)
-> 4 has been pushed to queue already so we are not pushing this vertex
-> The program can't return this vertex and his parent as a result beacuse 4 has more neighbours than 1 ( len(G[4]) - len(Queue) - 1 != 1 ) (2 != 1)
Neighbours vertex 4: 3,2 } Push both ( splen - 3 == 2 and their distances are 2 as well )
Neighbours vertex 3: 4, 1, 9 } Push only 1 because 4 and 9 have greater distance than ( splen -4 ) ( 1)
Neighbours vertex 2: 1 , 4} Only 1 has distance equal 1 ( splen - 4 )
-> 1 has been pushed already to queue and 1 has only 1 neighbour left
( len(G[1]) - len(Queue) - 1 == 1 )
RETURN parent[1], 1
And here is a code
from collections import deque
import queue
def longer(G, s, t):
V = len(G)
que = deque()
processed = []
que.append(s)
parents = [None for _ in range(V)]
distance = [0 for _ in range(V)]
pQue = queue.PriorityQueue()
# BFS
while len(que) > 0:
v = que.popleft()
processed.append(v)
for neighbour in G[v]:
if neighbour not in processed:
que.append(neighbour)
parents[neighbour] = v
distance[neighbour] = distance[v] + 1
processed.append(neighbour)
spLen = distance[t]
sameVertexQue = deque()
for nei in G[t]:
if distance[nei] == spLen - 1:
sameVertexQue.append(nei)
if len(sameVertexQue) == 1:
return t, sameVertexQue.popleft()
while spLen > 1:
el = sameVertexQue.popleft()
spLen = distance[el]
for nei in G[el]:
if distance[nei] > spLen: continue
print(nei, G[nei])
if nei in sameVertexQue and len(G[nei]) - len(sameVertexQue) - 1 == 1:
return parents[nei], nei
else:
if distance[nei] == spLen - 1 and nei not in sameVertexQue:
sameVertexQue.append(nei)
return None
G = [[1, 5, 7],
[0, 2, 4],
[1, 3],
[2, 4],
[1, 3, 5],
[0, 4, 6],
[5, 7, 8],
[0, 6, 8],
[6, 7]
]
s = 0
t = 2
G = [
[1, 8],
[0, 2, 3],
[1, 3, 4],
[1, 4, 9],
[2, 3, 5, 6],
[4, 7],
[4, 7],
[5, 6],
[0, 9],
[3, 8]
]
s = 0
t = 7
print(longer(G, s, t))
you're doing a in check in a list, that's super slow
make processed a set
why?
these are the requirements of the task to use only those structures
you could use a list with booleans, one per node
and then do
if processed[i]
```and
```py
processed[i] = True
I haven't read it closely, but the BFS part looks like expected
OMFG it sped up the algorithm by 69s
But i still have two tests with wrong answer so something is wrong with this approach
It's happening when the expected result is None
Can you see where the problem is in here?
What is the best data structure for storing classes, for example, a class that represents a person, and has their name, hair color, eye color, height, age.. etc...
^^ If any1 could tell me it would help so much
i should probably lurk here more often
are you looking to store info about a person, instances of a Person class, or a bunch of classes?
@shut breach a bunch of classes, i also want a way to search for stuff in them classes
do you know the difference between a class and instances of a class?
yes
so what stuff are you searching for?
Good evening, could someone help me with refactoring, I have the book to consult. But I wish I could find more content on the internet. The method I'm looking for is Replace Inline Code with Function Call, but I just can't find any repository, did you change the name? I'm usually finding method inline, but I don't know if it's correct. In case someone knows a repository to be able to consult it, it helps too
(was on a flight for the last 9ish hours)
so what I expected code-wise for the task is something like
path = shortest_path()
for i in range(len(path)):
p = shortest_path_banning_edge(path[i], path[i+1])
if len(p) > len(path):
return "found the edge!"
return "no such edge!"
Anyone can explain what a linked list in a very simple easy way to understand for a new person see this for the first time?🙂
I know but to be honst this approach is much slower than my current one
Your approach takes around 3/4s for all 11 test on my pc
My code does it in 0.06/ 0.08
If you want i can send you how the code looks like now
when you have an object with two "slots"
In this video you have everything that you should know about linked lists as If i remember correctly https://www.youtube.com/watch?v=WwfhLC16bis
Learn the basics of linked lists. Java & Python sample code below.
Check out Brilliant.org (https://brilliant.org/CSDojo/), a website for learning math and computer science concepts through solving problems. First 200 subscribers will get 20% off through the link above.
Special thanks to Brilliant for sponsoring this video.
Find sample code in...
one slot for anything you want, the value
the other for some other object of this type
Linked Lists explained: Dr Alex Pinkney returns to Computerphile.
Apologies for the traffic noise on this episode - we tried filming outside in London which it turns out didn't work that well for audio!
EXTRA BITS: https://youtu.be/jiHuPbUGlBE
http://www.facebook.com/computerphile
https://twitter.com/computer_phile
This video was filmed and...
Actually i watched this and understand everything
Thx anyway🌹
the important thing is linked list is not a type, it's a pattern, it just happens
only nodes are real
I mean, I don't exactly know what your code currently does
and does your code even work for all cases atm?
So i keeps doubling until it is greater than n. Say the number of iterations, aka the number of time i doubles is D. That means roughly 2^D = n. Rearrange that and you get D = log(n) (base 2 or e doesn't matter since those are a constant multiple apart). So the number of iterations is log(n).
(Strictly the 2^D = n doesn't make sense when both n and D are integers but 2^D can't go beyond 2*n, so still within a constant multiple.)
Hi,
Below is the BFS & DFS program & I am understanding it when analyzed individually. But, when I compare two at a time, seeing only the change of queue to stack is turning BFS to DFS, which is not clear. I mean, not getting big picture with confidence….
||
Can anyone pls tell the crux because of which BFS is changing to DFS, by just changing queue to stack….
from collections import deque
class Graph:
def __init__(self,dictionary):
self.custom_dict = dictionary
def bfs(self,vertex):
visited_vertices = [vertex]
queue_vertices = [vertex]
while queue_vertices:
dequed_vertex = queue_vertices.pop(0)
print(dequed_vertex)
for adj_vertex in self.custom_dict[dequed_vertex]:
if adj_vertex not in visited_vertices:
visited_vertices.append(adj_vertex)
queue_vertices.append(adj_vertex)
def dfs(self,vertex):
visited_vertices = [vertex]
stack_vertices = [vertex]
while stack_vertices:
popped_vertex = stack_vertices.pop()
print(popped_vertex)
for adj_vertex in self.custom_dict[popped_vertex]:
if adj_vertex not in visited_vertices:
visited_vertices.append(adj_vertex)
stack_vertices.append(adj_vertex)
custom_dict = {
"a" : ["b","c"],
"b" : ["a","d","e"],
"c" : ["a","e"],
"d" : ["b","e","f"],
"e" : ["c","d","f"],
"f" : ["d","e"]
}
graph_dict = Graph(custom_dict)
graph_dict.dfs("a")
may any one can help me with this
output=[]
for i in range(int(input(""))):
a,b,c,d=map(int,input("").split(" "))
if (a+b+c)<=d:
output.append(1)
elif (d*2)>=(a+b+c)>=d:
output.append(2)
else:
output.append(3)
for i in output:
print(i)
that's my program and code chef is not accepting it
With the stack, new unvisited nodes you come across are put on the top of the stack, so they will be the next ones popped. So it is always delving into the deepest part of the graph seen so far (hence dfs). With the queue, new unvisited nodes are put at then end of the queue, so it won't pop them until all the nodes already noticed are run through, so the fringe of the next to-visit nodes is always the breadth of the graph at the current state in the search (hence bfs).
Hope that makes sense. This is how I understand it 
Hi,
You have clearly explained the point. Thank you. I will just explain once again to you. If you feel, any correction needed, please tell me.
Let’s consider this graph
BFS ----- queue = [B,C] ----- Popped out elements are B & C
Note: I am not mentioned A here, because when we start with A, we will insert in into visited vertices directly, so, let’s not worry about it for understanding purpose.
DFS ----- stack
During 1st loop:
C
B
||
C pops out
During 2nd loop, we are inserting adjacent vertices of C into stack, so:
E
C
B
||
E pops out
Because of stack; we can clearly see that adjacent vertices are not popping out, but the distance one’s.
Well in dfs if C pops out then you'd insert (append) the vertices adjacent to C, so just E
So with dfs, stating at A (and appending things in A-Z order when there's a choice), the state of the stack changes like |A # start with A |BC # pop A, push B C |BE # pop C, push E |BDF # pop E, push D F |BD # pop F |B # pop D | # pop B leaving empty stack where | represents the base of the stack and the rightmost letter is the top
though you're right, the search travels far away from the A start pretty quickly (deeply you might say - depth first search)
so cool
For the bfs don't use a list as a queue, it's very slow. When you pop element 0 all other elements must move. Use collections.deque and use popleft and append
Yes it works for all cases. I created the own test like 0 -> 1, disconnected graphs, the tree with always two children etc. seems to work perfectly
How to recognise what type of problem it is? Either DP or greedy algorithm? I know that DP is based on sub problems that overlaps and are connected in some sense each other. But exists there any way to look at the problem and know for sure it's greedy or it's 100% DP problem?
ik this is stupid, but given a regular adjacency list of edges, how can i simply find the minimum amount of bridges needed to get from x to y
like no minimum cost or anything
just a path
Bfs starting at x, stopping when you find y
We've just gone over this, please just phrase your question
Idk how to phrase my question
Like I just get it wrong
It’s not a coding question where I can say got it wrong here
Idk what I’m doing wrong
Anyone? I have no idea I’ve watched khan academy videos tried mostly everything
Is 2^(n/4) in O(2^n) or is it its "own class"?
Technically yes, it is O(2^n) but maybe not in the way you mean. 2^(n/4) is the same as (2^(1/4))^n or about 1.19^n. but 2^n grows faster than 1.19^n so 1.19^n != θ(2^n), where θ (big theta) means bounded on both sides (above and below). So in a θ sense they are different classes.
But 1.19^n is O(2^n) because big O is just an upper bound. So in the same way n is O(2^n)
Okay, I think I got it, so basically θ(2^(n/4)) != θ(2^n), but θ(n/4) == θ(n), right?
Correct
You're given that T1 and T2 are conditionally independent given L. That means, if you know whether or not the person has the disease, then the results of the two tests are independent of each other. (If you don't know whether or not the person has the disease, then the two tests are not independent of each other, as they have a dependence through L.) A more formal way of putting this is: P(T1, T2 | L) = P(T1 | L) * P(T2 | L) and P(T1, T2 | ~L) = P(T1 | ~L) * P(T2 | ~L) You want to find P(L | T1, T2). You're given P(L) and, from the equations above, P(T1, T1 | L) and P(T1, T2 | ~L). Try applying Bayes' rule.
Hint: ||Treat the joint event (T1, T2) as if it were a single event A. Then the goal is to find P(L | A), given P(L), P(A | L), and P(A | ~L)||
Hope everyone’s had a good weekend. I was wondering if anyone has recommendations on resources for algorithms / data structures for general interview prep.
Reading a book rn / trying to mix in leetcode exercises here and there but I wanted to see if anyone had a website / YouTube channel / book / etc that they found helpful. Would be greatly appreciated.
Thanks