#algos-and-data-structs
1 messages · Page 64 of 1
I guess, most DSA classes teach the same topics. Binary search, etc.
The planting problem above strikes me as a DP problem: it's not going to lend itself to some convenient solution other than brute force with optimization.
DP prolly the way to go
i.e. let ||dp[i][c] := min if you planted flower type c at i||
ok, will check.
Also, DSA is just one piece of learning software engineering. Make sure to do real projects... not just practice DSA.
also, i forgot to ask.
any source suggestion for system design ?
To get good at system design? Just building projects.
Maybe also read/study real-world systems. I see this MIT OCW course too... never looked at it, but I like the syllabus: https://ocw.mit.edu/courses/2-882-system-design-and-analysis-based-on-ad-and-complexity-theories-spring-2005/pages/syllabus/ (might be lecture notes only tho)
But besides that, take any popular web-scale company: there's many articles that'll talk about their architecture and evolution and design decisions. Reddit, Twitter, Facebook, Amazon, Google Search, etc have fascinating histories
this seems like kinda textbook dp
let dp[i][j] be the smallest cost to plant the first i flowers, where the last planted flower was of type j
and you can express dp[i+1] in terms of dp[i]
the formula would be (in not quite python)
||dp[i+1][j] = min(dp[i][k] for k != j)||
Yes, that is even better.
I’m allowed to send in images right?
Yeah.
So let’s say this is our simple Binary tree
I want to insert 5
Each left child node must be less than the parent
While each right child must be greater than the parent
This is where the “binary search” of the binary search tree comes into play
Now to insert 5, we need to compare 5 with each node until we get to a leaf. If it’s less than the current node, it goes left, if it’s greater than the current node we go right
When we finally get to an leaf we append 5
Ok, what are the fundamental building blocks here? That is the first part to convert to code. Identify the objects involved in this process, they will need a representation in code.
You can highlight them in your English sentences.
(For more simple algorithms, it often revolves around one object)
Ok
The first value, the one you want to insert is 5
The second value is the node you are comparing 5 to
Ok, so two keywords there, value and node.
These things are fundamental objects present in the problem, that we will need to operate on.
Hmmm
So keep a list of the objects, and mark them as needing some representation in code, there are multiple options for this, but they both need some implementation.
I could write the possible sudocode here
Yeah, but before that I just want to list things at an even more high level.
Oh, ok
So we know what must show up in the code somewhere.
Mhm
Now a little asterisk on that, sometimes some things are reperesented implicitly, so no directly in code, but either way make that list.
Ok, so next, make a list of actions that are taken, these will often show up as procedures / functions, etc in the code. They operate on/with the objects, and are transitions between states of the algorithm. They will often show up as verbs / near them. Can you spot them here?
To insert 5, compare node, go left if lesser, go right if greater, run until leaf node
So we can "go left" and "go right" (based on some conditions).
And those transition us from the current state to the next state (which is now the new current state).
So If/else statement?
Yes, branches.
Kk
So how is the "current state" represented? Which objects are used and how many? (from the list)
(Some objects are part of another)
The current state being the current place the algorithm is in / at at each step.
As in "state of being."
“Current state” would be the first value of the comparable range of the branch to it’s leaf
Maybe this is what you meant, but let give another example. Say I have a house with 3 rooms, A, B, and C, and A <-> B <-> C is the layout, with "<->" meaning there is a door between them. If I start at A, and want to go to C, I can give a step by step instruction of start at A, go to B, go to C. My start state is "A," and I can represent my current state with just a single letter (the room name).
If I had in my object list "room," then each current state would be represented by one "room."
The important thing here is to think through time, where we have transitions between states through time, as the algorithm runs, and what is needed at each point in time.
And after I compare the next value would be the new “current node”
Ah, alright
Like moving from one room to another, the "current room" is updated to be what the "next room" was.
An algorithm runs through time, and so if we find out what is needed at each point in time to represent that point in time in code, and then what the transitions are (in the case of the binary tree, go left, and go right), and then when to do those transitions (the conditions), then we more or less have the solved problem.
The object list are the individual components, the binary tree is technically also in that list as it's the whole thing, but I meant from your English sentence describing the solution earlier, there were two other keywords, and they are what the binary tree is made of.
The object i'm seeing here is "node."
And also there is "value."
Oh
The tree is made of nodes, which hold values.
So for object list: tree node value
They can be found in your own English description, so if you are unsure about how to code it, start by highlighting these.
Next, you can write down the relationship between these.
"A tree is made of nodes that hold values."
Still just writing English, not code yet.
Gotcha!
So next, we have the object and their relationships, what are the actions / transitions between states?
(Not conditions, just the actions themselves)
Greater than or less than?
That would be conditions.
Oh
You wrote them before, "go left," "go right."
Left or right
Ok, so now we have ```
Objects:
tree
node
value
Tree is made of nodes which hold values.
Transitions/actions/operations:
Go left.
Go right.
We are missing a bit on the actions.
When we get to the end, we need to actually insert the value.
The final action.
Mhm
If you have a "final" or "unique" action or object, mark it as such.
Using your wording from before "append the node."
To "go left," "go right," "append node." (final action).
Next, identify the conditions under which the actions happens.
So now greater than or less than?
Yes.
Kk
And try using the word "if."
So still in English, can you describe it?
And the previous list of objects and actions.
Try to use all of them.
If the value 5 is greater than the value of node then go right
If the value 5 is less than value of the node then how left
If there are no more nodes append 5
Ok, so this is already more refined the the original, getting closer to code too.
So now lets refine it more.
What exactly does it mean to "go right?"
And to answer this you can partially get there by asking the question how "node" should be represented to make that as easy as possible to implement.
The value 5 compares itself to the right child node
What information do you need at each point in time to make the decisions?
And where does it come from?
Where is it stored?
Ok, so how do we get the right child node? What would be a convenient way to have that available?
Given our current description, where do we pull that from? Which objects have it?
The objects hold all our data, so we know it has to be in one of them.
(Or multiple)
The only object being referenced here is "node."
And also "value."
Nodes hold values, so we know we are getting value from node.
So if you could define what is "inside" node, what would you like to be there?
We know value is in there.
Basically we need some way to fetch or compute the left and right children.
And so they need to be referenced somewhere in some way.
We can't pull them out of nothing.
Right now in the English description we are, because we have not given that detail yet, we just assume we have it somehow. Now we want to know how / where.
How do we do that?
So there are multiple options, but the key thing here is that for every object involved, we need to be able have a reference to it somehow.
There are multiple ways to do this in code and I will give just one.
Are you fimiliar with classes in Python?
Yes
Ok, what they let us do at the most basic level (and most important part) is bundle things together, this makes things concise and convenient as many variables are often used together in the same context.
(Passed around together, they are related)
Variables are a form of reference to an object / entity.
Yep
So we know we need at least three references for our description. The value, the left child, and the right child. WIthout these we can't use our description.
We need them all at the same time.
When you need a bunch of things all the same time/place, a class can be a good tool to solve it.
Can you make a class with those three variables? What is the class name?
I have to make one full class, right?
Yes.
That would contain everything. Think about one point in time what you need. The description you gave before.
You need the value, the left child, and the right child.
And node.
Value which is 5
So without a class, you could just have ```
value = 5
node = ???
left_child = ???
right_child = ???
You need all 4 at that point in time.
Ok, but how do we "fetch" these?
They are stored somewhere in some way.
For the value it's simple, we are given it and can just set it once.
But at each step, we need to retrieve node, left child, and right child, and this depends on how/where we stores the nodes.
This is the datastructure part of data structures and algorithms.
We know that we want to store them in a binary tree structure, but how?
Node.left_child and node.right_child???
Yes, but why?
Or how do we get there?
The key is taking the objects the structure (tree) is made of (nodes), and their relationships and encoding that in code.
How though?
So see how in your diagram you have nodes pointing to other points?
In other words you can get from one to another.
So if I have a node, I have a reference / way to compute a reference to the children.
The key here is "references."
Variables are references.
So node.left_child would be the value of the left child?
And so if I have a reference to node, I would like to have a reference to left and right nodes.
And also I would like a referenece to the value of that node.
In other words, node contains references to value, left node, right node.
Data structures is all about how you can get one thing to another via references.
And then setup in a clever way to make it efficient.
How could I translate it into python though?
So we have nodes, and they have those things in them.
When you have a container, you can use a class.
class Node:
def __init__(self, value, left_node, right_node):
self.value = value
self.left_node = left_node
self.right_node = right_node
Now I can make Nodes.
And I can build a tree by setting up the references between them.
# This is just the 25, no children yet.
root = Node(25, None, None)
# Add the children by making them and setting up the references, this is now a tree structure.
root.left_node = Node(15, None, None)
root.right_node = Node(30, None, None)
I think I get what you’re saying
It's a tree because I can follow the references from the top node down to whatever child.
The structure is the reference scheme.
You can think of the 1D version with the rooms, each would have a reference to the next and previous room, forming a chain of rooms that I can traverse.
The varaibles link them together.
Variables can directly references simple values, like 5, but they can also reference something that references other things.
Mhm
Using the method I gave, build the entire tree in your image manually like I was.
Yes, so, when you are given such a programming problem, they will often have built the tree for you.
But to make sure you get the structure first, try making the tree manually.
Thanks for your help Squiggle!
Hello team, I was wondering if you have any useful rules of thumb when using recursion in typical recursion, backtracking and dynamic programming problems. Thank you in advance:)
get the base case right first ig 🙂
Writing recursion is a lot like mathematical induction:
- You make it work for the base case.
- You assume that your function works for the recursive call, and with its result you show how you build the answer for the current call. For example, if you have a function f(n) which calls f(n-1), you write it by assuming f(n-1) works, and from its return value you create the return value for your current f(n).
Another rule of thumb is that at least in Python, everything you can solve with recursion you can also solve without recursion, and it's usually easier without. It's a nice exercise at least
not always easier
but avoiding recursion in python for performance reasons if often a good idea
Didn't say always
Something good to know about is that there is a trick to quickly convert a recursive DP solution to iterative ("bottom-up").
Say for example that you've coded this recursive solution for computing fibonacci numbers (mod 10^9 + 7 to keep them small).
import functools
MOD = 10**9 + 7
@functools.cache
def fibonacci(n):
if n <= 1:
return n
return (fibonacci(n - 1) + fibonacci(n - 2)) % MOD
n = 10**5
print(n)
You can convert this to bottom-up DP simply by
!e
import functools
MOD = 10**9 + 7
@functools.cache
def fibonacci(n):
if n <= 1:
return n
return (fibonacci(n - 1) + fibonacci(n - 2)) % MOD
n = 10**5
for i in range(n):
fibonacci(i)
print(fibonacci(n))
:white_check_mark: Your 3.12 eval job has completed with return code 0.
911435502
I would definitely recommend to start out with a recursive solution, and then use the trick ^ to make it bottom up if recursion is too slow/you are hitting the recursion limit.
in an http request , why is http requesting things from me?
#algos-and-data-structs is not the right channel for this
I am currently practicing for coding interviews in Python, while I do find the iterative solutions more intuitive I am doing my best to learn recursion in case it is asked from the interviewer. Would you consider solving everything iteratively a viable approach?
From a theoretical standpoint, recursive is by far the most preferred option.
Only when you are thinking about implementing it is the iterative approach considered
Best idea is to just ask which one the interviewer prefers.
what does -> mean
for example data ->
that is an arrow
Return value annotations
Hi,
any good course for system design?
the pin in #software-architecture might be useful
Because sometimes you have so much data that it doesn’t fit in the ram
Also the ram is reset when your computer reboots so you need to go through the hard drive eventually anyway
@fallow agate
currently i am learning system design.
what i am thinking is to start the ball rolling with implementing a server using flask framework.
& then whatever the concept i am going to read, suppose caching, i will integrate a simple nosql database named TinyDB into my project(i will make my application use this nosql data base for caching).
Next, suppose i read the concept of load balancing, then i create 2 more flask servers & will write small code in python to route the requests to different servers one after the other, using round robin algo.
this way, i not only learn theory but also practice practically.
Once i covered all system components like this one by one, finally i will start practising questions like how to design Instagram & how to design what's app etc.
Any corrections to my strategy/suggestions?
Does this help me to answer system interview questions?
graphql Vs Realm which one you choosing and why?
(I know that there is better solution but I am interested to know what is wront with my code)
I am trying to solve this problem https://neetcode.io/problems/lru-cache
This is my code: https://pastecode.io/s/0h8m4saq
I do not understand how as a result I get [null,null,10,null,null,-1,10] instead of [null,null,10,null,null,20,-1]?
A better way to prepare for coding interviews.
What did you get while debugging it?
In the end I solved problem
looking for a hacker
hi
This style of coding is very common in china for some reason
My guess is that the original code even had scanf/printf, which was changed to cin/cout to be more readable
Note that there is no cin.tie or sync_with_stdio
They also use the wonderful #define int long long
can anyone point me to a python markov chain implementation i could look at in on github
bruh, who writes like this?
(ans *= a) %= mod;
(a *= a) %= mod;
I kinda like it
anyone got a heuristic for multiple knapsack problem?
or some python code that i can look at
hi
^_^
I just don’t understand like where the Normal Bible sort would stop if it isn’t normally stopping when no swaps are made
after n-1 passes you know it's sorted
each pass "bubbles" one number to the end/top
so after n-1 passes n-1 highest numbers are sorted at the end, that also means that the lowest number is at the beginning, so everything is sorted
the datastructures course from opencourseware has too much pre req in math
i cant find a good datastructures course work. i really want to get a solid understanding of DSA. i already know a rough overview of the whole area as i had a whole subject on it in the last semester but i feel like i still don't have a solid understanding on the topic than being familiar to some algorithms and topics.
how do i get good at DSA
@floral nebula if youre looking for a course, im currently doing stiver's dsa sheet, high recommend it
Why? What's your goal here and where are you in your educational joirney? Real question: answer depends on where you're at.
Which course? If intro to Algs yeah it has a heavy math pre-req
i have already covered some topics and data structures like stacks queues linked list dll but feels like all i done is just learn those algorithms just to forget it after a month
my goal is to actually understand data structures in detail
that is because you're only watching videos/courses and solving easy puzzles
you could use https://cses.fi/problemset/ and work by topic, you can't learn 5 topics in a month, but you can learn a lot about one single topic in a month, depending on how much effort do you put on it,
the datastructures course from opencourseware has too much pre req in math
I dont know why you dislike this, basically dsa is worse than maths, if you dont like math dont even try dsa
basically dsa/cp is for people than like to break their heads trying to solve something with a crazy solution
if you think you are that type of person, then keep it up
i am not good either, but i like it, if you want we can practice together and share solutions for diff problems
yeah that can be a problem. its not that i hate math i am willing to learn the topics in math but too much is going on now along with uni exams
yea sure are u working out leetcode problems?
Im working on leetcode
We can practice together
yea but i havent started with leetcode yet i been doing exercism.org python track thought i would go to leetcode after i completed that. but due to college exams dont get much time to code
sure man, ill send you the fr
Ez.
How can I connect my custom Python algorithmic trading bot to the MT5 platform via TeamViewer?
I doubt you'll find anyone on this server, at least this channel, who'd know much about MT5 here. I'm familiar with it but don't use it Maybe open a help thread and hope someone knows? #❓|how-to-get-help
Guys i have question and i dont know where to ask, my question is can phyton work with realtime database?
Yes. #python-discussion or #databases is a better channel to ask
hello 👋
I implemented a Markov algorithms interpreter in python
pseudocode of it: #esoteric-python message
it works fine, but it is slow
I'm curious what data structures exist to solve this problem
most time is spent on iterating over rules and checking if they match or not
another point of concern is reallocating the entire string at each step even if only the small part of it has changed
I think the Rope DS can partially solve this problem [but it would mean that the built-in str in str would no longer be available]
all kinds of ideas (crazy or not) are welcome
do you care about the order of replacements?
AC Automaton?
Should bump 1 iteration from O(len(rules)*len(before)*len(string)) down to O(len(before) + len(string)) but is complicated
yeah aho corasick feels relevant
if replacement order doesn't matter it feels tempting to try to iterate over the string and shove stuff onto a stack, when a match is found you pop it and push the replacement
you might need some undo-ability in the string searching to make it really efficient though
yes
only thet first matched rule must be applied, and only in the first occurrence
after that you have to start from the first rule again
in my head, there's also a possibility to have a rolling hash on the string and a range-update-point-query datastructure to reduce the if before in string from O(len(before) * len(string)) to O(len(string))
but len(before) isn't that big anyway as you said, dunno how much this affects things
since most time is spend on checking if rule match or not, it can be made faster by splitting work on several threads and then applying first found matched rule
but with gil it won't be faster
I think I have a working implementation on my laptop if you want to see it
I actually was thinking about something like this
as usual, some smart guys already invented it long before 🙂
would be nice
trying to get rid of the linear cost string replacement is probably a good idea
btw naive string search algorithm is O(len(string)*len(before)), but with Z-function or other smart algorithms it can become O(len(string)+len(before))
I'm pretty sure cpython implementation uses one of such algorithms
here
was used to solve AoC2023 Day 1
and I didn't write helpful comments soo uh...
python string searching probably uses boyer moore or something
aho corasick on a day 1 problem? 🥴
well I solved it with a more brute force thing first
then saw the opportunity to actually learn ACA
(which I definitely forgot by now)
I had a groovy time
def magic(s) {
def digits = s.findAll(/\d/)
digits[0].toInteger()*10 + digits[-1].toInteger()
}
def part1(lines) {
lines.sum { magic(it) }
}
def part2(lines) {
lines.collect{
it.replace("one", "o1e")
.replace("two", "t2o")
.replace("three", "t3e")
.replace("four", "4")
.replace("five", "5e")
.replace("six", "6")
.replace("seven", "7n")
.replace("eight", "e8t")
.replace("nine", "n9e")
}.sum{ magic(it) }
}
def br = new BufferedReader(new InputStreamReader(System.in))
def lines = br.readLines()
println "Part 1: ${part1 lines}"
println "Part 2: ${part2 lines}"
Objects/stringlib/fastsearch.h lines 5 to 8
/* fast search/count implementation, based on a mix between boyer-
moore and horspool, with a few more bells and whistles on the top.
for some more background, see:
https://web.archive.org/web/20201107074620/http://effbot.org/zone/stringlib.htm */```
`Objects/stringlib/stringlib_find_two_way_notes.txt` lines 19 to 22
```txt
The algorithm runs in O(len(needle) + len(haystack)) time and with
O(1) space. However, since there is a larger preprocessing cost than
simpler algorithms, this Two-Way algorithm is to be used only when the
needle and haystack lengths meet certain thresholds.```
I was half correct
do you have some decent test case?
oh god
no :)
working on it...
what is happening
gives me flashbacks of
https://www.youtube.com/watch?v=8_npHZbe3qM
This lecture is an addendum to my video about Anagraphs, which you should watch first (or only). I do two proofs by reduction: One that the "generalized kerning" problem is undecidable, and one that the "generalized anagraphing" problem is decidable. The first proof uses turing machines, and the second a fragment of linear logic. I try to explai...
that is how brainfuck is interpreted in markov algorithms :)
there are two "tapes": code and memory
to perform bf + operation you move a thingy from code tape to memory tape, and then perform increment there
i think i have seen this video before
all I see is something that'd appear in a hacker's screen in a movie /s
here is a cute rule set
rules = [
('0>0', '10>'),
('0>$', '<1$'),
('1<1', '<10'),
('^<1', '^0>'),
]
string = '^0>00000000$'
results
^0>00000000$
^10>0000000$
^110>000000$
^1110>00000$
^11110>0000$
^111110>000$
^1111110>00$
^11111110>0$
^111111110>$
^11111111<1$
^1111111<10$
^111111<100$
^11111<1000$
^1111<10000$
^111<100000$
^11<1000000$
^1<10000000$
^<100000000$
^0>00000000$
...
it's similar to what you're doing, but the question is instead:
given some replacement rules, can I turn string s into string t with some application of the rules?
so not the same replacement scheme you have
the proof in the video is a reduction from turing machines, i.e. basically implement turing machines with this rule replacement problem
!e another rule set and string
rules = [
('0|$', '1|$'),
('1|$', '|0$'),
('0|', '1>'),
('1|', '|0'),
('>0', '0>'),
('>1', '1>'),
('>$', '|$'),
]
string = '00000000|$'
for i in range(100):
if string.endswith('|$'):
print(string)
for before, after in rules:
if before in string: # profiling says that 99% of time is spent on this line
string = string.replace(before, after, 1)
break
else:
break
:white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | 00000000|$
002 | 00000001|$
003 | 00000010|$
004 | 00000011|$
005 | 00000100|$
006 | 00000101|$
007 | 00000110|$
008 | 00000111|$
009 | 00001000|$
010 | 00001001|$
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/ZWLVJEDKSLWC7TLAJZKVWPHCP4
rules = [
('| ', ' |'),
('w ', ' w'),
('h ', ' h'),
('e ', ' e'),
('> ', ' > '),
]
string = "|wheee> "
|wheee>
|wheee >
|whee e>
|whe ee>
|wh eee>
|w heee>
| wheee>
|wheee>
|wheee >
|whee e>
|whe ee>
|wh eee>
|w heee>
| wheee>
|wheee>
|wheee >
|whee e>
|whe ee>
|wh eee>
|w heee>
| wheee>
|wheee>
sorting a string of a and b can be done in just one rule: ba -> ab
Rules:
0: ba -> ab
before: [6] >bababa<
after: [6] >abbaba<
rule: 0: ba -> ab
before: [6] >abbaba<
after: [6] >ababba<
rule: 0: ba -> ab
before: [6] >ababba<
after: [6] >aabbba<
rule: 0: ba -> ab
before: [6] >aabbba<
after: [6] >aabbab<
rule: 0: ba -> ab
before: [6] >aabbab<
after: [6] >aababb<
rule: 0: ba -> ab
before: [6] >aababb<
after: [6] >aaabbb<
rule: 0: ba -> ab
terminated: no matching rule
here is a challenge for you:
you are given a string of a and b
your goal is to reverse it:
aabb --> bbaa
abab --> baba
aaa --> aaa
etc
some other ideas if you are interested:
- make a copy of a string
- split a string into two strings of even and odd indices (
s[::2]ands[1::2]) - compute length of a string into unary system
- compute length of a string into binary system
- compute number of
aandbseparately
this is a cool interpreter with GUI: https://yad-studio.github.io/
this is a binary counter:
s = State(
'>0<',
[
Rule('0+', '1'),
Rule('1+', '+0'),
Rule('>+', '>1'),
Rule('<', '+<'),
],
)
while True:
s.step()
input(s.string)
``` ```py
>0<
>0+<
>1<
>1+<
>+0<
>10<
>10+<
>11<
>11+<
>1+0<
>+00<
>100<
>100+<
>101<
>101+<
>10+0<
>110<
>110+<
>111<
>111+<
>11+0<
>1+00<
>+000<
>1000<
>1000+<
>1001<
...
what are the requirements of the input string? am I allowed to decorate it to make things doable?
I can do a cheaty version which upper cases as well
rules = [
('aA', 'Aa'),
('bA', 'Ab'),
('bB', 'Bb'),
('aB', 'Ba'),
('a<', 'A<'),
('b<', 'B<'),
]
string = ">ababbaaa<"
decorating is actually not necessary
to make > you can use the rule "" -> ">", and to put < at the end you can spawn a runner that will go to the end
there are actually two kinds of rules which were not refrected in my pseudocode: regular and terminating
if a terminating rule is matched, it halts the program completely, and the string you have is a result of your algorithm
ah, termination was kinda my bigger concern
but if you can have terminating states that simplifies stuff
string = '...' # current state, might be long (100+ or 1000+ chars), changes at each step
rules: list[tuple[str, str, bool]] = [...] # a couple hundred rules (both left and right side are pretty short - usually less than 10 chars), doesn't change
while True:
for before, after, terminating in rules:
if before in string: # profiling says that 99% of time is spent on this line
string = string.replace(before, after, 1)
if terminating:
break@while # break 2 loops at once
break # end the rule search, start again
else:
break # no rule matched - halt
print(string)
something like this
that gives you a possibility to give a result of bba for input abb
without terminating rules it would be switching between abb and bba forever
yeah
sometimes terminating rules are denoted as foo ->. bar (note the point in ->.)
hi
a deque is just a queue with insert at front and delete at last and only difference in algorithm is decrement of rear and head in those new operations??
Hi, why it give syntax error when I declare an empty 2d array? data = [num_of_algs][] ^ SyntaxError: invalid syntax
because that's not the right syntax
are you trying to make num_of_algs rows of empty lists?
I recall previously I've been using this pretty often ...
do you want the result to be like this?
[
[],
[],
[],
... # num_of_algs many
]
yes the size of the first layer of the array
yes
exactly
l = [ [] for _ in range(num_of_algs) ]
i recall I was using "array = [][]", and it was kinda working?
[[]] * num_of_algs does not work the way you want it to if that's what you're thinking of
!e
l = [[]] * 5
print(l)
l[0].append(1)
print(l)
:white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | [[], [], [], [], []]
002 | [[1], [1], [1], [1], [1]]
Thank you. I was having impression that python array declaration was prettry straight forward, but it turns out I've been using wrong way for long time...
I recall previously I've been using this pretty often ...
in a different language, perhaps?
maybe... but couldn't come up with what that was rn... is there other language supporting such way of using? the " array = [][] "
Or, maybe I've beening useing "array = []" so I just took it for granted I could simply expand it to 2d array....
in C/Java/etc the syntax would be along the lines of int data[10] (to declare a 10-element array data), and similarly data[10][20] for a 2d array.
in python, well, there's no arrays and no special syntax for them. there's just lists which behave like all other objects.
for C there the bracket usually cannot be empty, as to Java I'm not that sure...
can't you do this?
int a[] = {1, 2, 3};
```or is this c++ only
yes, btw can the compiler do c++ code in this channel?
C allows this too
iirc in C you also can do int a[N][M] = {{1,2,3}, {4,5,6}, {7,8,9}};
and maybe int a[][] = {{1,2,3}, {4,5,6}, {7,8,9}};
I think only 1 of (the last?) dimension can be left empty
just checked: x[][5] works but x[5][] does not
N and M all constant here?
yes
if they're variable (like inputs) then you should use a vector
if programmer wanna represent tranditional POSIX file system which has files, folders and also possible symbolic links then which data structure should use? Graph or Tree ? I think without symbolic links Tree can be used because every file has only 1 unique path which prevents loops. When symbolic links involves i do not know i need to change tree based representation to graph or not
reservoir sampling on wikipedia: https://en.wikipedia.org/wiki/Reservoir_sampling
Reservoir sampling is a family of randomized algorithms for choosing a simple random sample, without replacement, of k items from a population of unknown size n in a single pass over the items. The size of the population n is not known to the algorithm and is typically too large for all n items to fit into main memory. The population is revealed to the algorithm over time, and the algorithm cannot look back at previous items. At any point, the current state of the algorithm must permit extraction of a simple random sample without replacement of size k over the part of the population seen so far.
Why does it say that the population n is not known to the algorithm, but hten in the source code it is known?
(* S has items to sample, R will contain the result *)
ReservoirSample(S[1..n], R[1..k])
// fill the reservoir array
for i := 1 to k
R[i] := S[i]
end
// replace elements with gradually decreasing probability
for i := k+1 to n
(* randomInteger(a, b) generates a uniform integer from the inclusive range {a, ..., b} *)
j := randomInteger(1, i)
if j <= k
R[j] := S[i]
end
end
end
the pseudocode notation just sucks here, they mean
i = k + 1
for s in S:
j = randomInteger(1, i)
if j <= k:
R[j] = s
i += 1
That looks incorrect, I think the correct python translation should be
R = S[:k]
for i in range(k, len(S)):
j = random.randint(0, i)
if j < k:
R[j] = S[i]
the whole point is that you can't know len(S).
I preserved the 1 indexing
still the first k elements of S should be stored in R
The point is that, if you want to add one more element to S (i.e. adding one more sample) you can easily do that (without having to recompute everything)
Here is how I would describe the algorithm
num_samples_seen = 0
k = 100
R = []
def add_sample(s):
global num_samples_seen
num_samples_seen += 1
if len(R) < k:
R.append(s)
else:
j = random.randint(0, num_samples_seen - 1)
if j < k:
R[j] = s
!e
import random
num_samples_seen = 0
k = 10
R = []
def add_sample(s):
global num_samples_seen
num_samples_seen += 1
if len(R) < k:
R.append(s)
else:
j = random.randint(0, num_samples_seen - 1)
if j < k:
R[j] = s
n = 10**4
for _ in range(n):
s = random.randint(1, 10**9)
add_sample(s)
print(R)
:white_check_mark: Your 3.12 eval job has completed with return code 0.
[856959814, 627914769, 105585371, 374199574, 333850095, 704136957, 237044355, 128028442, 325962198, 385723663]
Note how the algorithm has no knowledge of n (the number of samples it will be given)
add_sample simply just works with one sample at a time
It does however keep track of how many samples it has seen
print("Hello, world")
For this problem https://leetcode.com/problems/find-all-numbers-disappeared-in-an-array/description/
is this solution
class Solution:
def findDisappearedNumbers(self, nums):
ans, seen = [], [False]*(len(nums)+1)
for c in nums: seen[c] = True
for i in range(1, len(nums)+1):
if not seen[i]:
ans.append(i)
return ans
optimized version of this solution
class Solution:
def findDisappearedNumbers(self, nums):
s = set(nums)
return [i for i in range(1, len(nums)+1) if i not in s]
because the boolean solution is only storing 1 byte of information while the hashset is storing 4 bytes?
where do those amounts of bytes come from
Idk, that's what one dude mentioned when he asked that same question
3 things
- a boolean in python does not store 1 byte, it stores at least 12 or 24 bytes depending on the system
- first solution has a redundant operation
- "letting python do the work" is how things are mostly optimized, which happens in the 2nd solution
in conclusion the second one is theoretically faster
but it does seem like over large inputs the 2nd one gets slower
so it basically just depends on how large your input is
Guys I am solving coding problems Can anybody help me here ?
Which operation is redundant in first solution?
~~```py
seen = [False]*(len(nums)+1)
for c in nums: seen[c] = True
ah i see
nvm
Hii
I need code for breadth search function
My professor asked for it and idk wut exactly he need
from collections import deque
class Node:
def __init__(self, state, parent=None):
self.state = state
self.parent = parent
self.children = []
if parent:
parent.children.append(self)
def find(node, target_state):
queue = deque([node])
while queue:
current_node = queue.popleft()
if current_node.state == target_state:
return current_node
for child in current_node.children:
queue.append(child)
return None
root_node = Node("A")
B = Node("B", root_node)
C = Node("C", root_node)
D = Node("D", C)
result = find(root_node, "D")
if result:
print(f"Node with state '{result.state}' found.")
else:
print("Node not found.")```
Is this code explain breadth search correctly?
I could totally see the first one being faster since it doesn't use any hash maps
especially if someone gives it an evil designed sequence that makes set run in n^2
Its not about 1 byte vs 4 bytes
It is about using hash table vs not using hash table
working on genetic algorithm to create timetable? Anyone willing to help
Yeah but why, if it is really that true, first one solution is better than second? It's because for hash tables there is need to calculate hash value?
Hash tables are kind of complicated
There is a lot more going on than what you might expect
While a boolean list is about as basic as it gets.
Hi! could someone help me at #1307340581009096736 ? its a time limit issue
This is a perfect scenario for a bitset.
!cban 1276028320688898108 troll
:incoming_envelope: :ok_hand: applied ban to @rain copper permanently.
Hello 👋 I am solving some past advent of code problems. For one of the problems, I need to count the number of literal characters in a string (I am not sure if the term "literal characters" is correct).
i.e. "\x27" -> 4 (\, x, 2 & 7)
Python processes this as "'" (apostrophe). Any ideas ?
do you mean you get \x27 as input?
Yes
I'm not sure what you mean exactly, cause if you use input() then it works perfectly?
>>> input()
\x27
'\\x27'
>>> len(input())
\x27
4
>>>
if you're storing \x27 as a string directly, you can add a r prefix so it doesn't turn into '
>>> '\x27'
"'"
>>> r'\x27'
'\\x27'
Apologies, when I said input, I did not mean via input().
Thanks. This works I believe. I forgot about r""
guys how do i make the comparation of the in t hing
i wanna compare it with strings
like a in "thing1, thing2, thing3"
guys, why my code is skipping lines?
it wasn't suppose to print stuff skipping lines
Why do i have this error ???
what version of Python are you using
Yeah i don't have swichs
match case isn't switch case FWIW
What is it then ?
pattern matching
Just like a switch
no, it's more powerful, it looks for patterns, if you want something like switch case you'd want a dict in python
Whats the difference ?
https://peps.python.org/pep-0636/
give this a read
Ok thanks
this disjoint data struct just ate away my brain wtf 
which one
disjoint set union?
saw a tutorial in which guy explained union by rank first
istg i was about to fall asleep
then looked at union by size, its somewhat understandable now
both just say it's better to merge smaller groups into bigger ones, rather than the other way around
the really hard part comes if you try to prove the complexity
pretty much
it's called the inverse ackermann
where the ackermann is a really fast growing function (so the inverse grows very slow)
i still havent done kruskal's yet, my brain cannot handle this much info for a day, so i have no idea how its gonna work with graphs
yeah looked into that just rn, thanks for telling tho
it's more that kruskal's needs to quickly check if 2 nodes are connected already
and you can think of nodes that are connected being part of the same group and vice versa
so check if nodes are connected => check if nodes are in the same group => fast with DSU
oh alr so basically we introduce disjoint to check for that, at first i thought wouldnt it change the graph itself? now i got it thanks
you don't need a DSU for kruskal, but it drastically improves the time
pseudo code:
def kruskal(edges):
edges = sorted(edges) # sort by weight
mst_edges = []
for edge in edges:
if is_same_group(edge.source, edge.destination):
continue
mst_edges.append(edge)
join_group(edge.source, edge.destination)
return mst_edges
```and with a DSU, `is_same_group` and `join_group` is faast
oh now i see, thanks a lot for explaining
I made an insertion sort algorithm and tested its performance and notice that everytime I ran the tests 2000 and 3000 elements were faster than 1000 elements. 1000 elements took 12 ms when 2000 took 4 ms and 3000 took 8ms. Why is that?
I used randomly generated array.
Run each of your algorithms 500 times and make an average for each array size
Or use the Python timeit module
One bug I've seen in sort benchmarks is that you accidently benchmark on already sorted data
Basically, the first time you call sort, you do it on random data
which sorts the data used to benchmark
Then the rest of the benchmarks (after the first one) look weirdly fast
Given a list of lines which form a race track how would I color the inside of the track different from the outside of the track.
You're gonna have to be more clear about what you're doing
The colliders for a 2d race track are a list of lines. I want to know how i can color the outside of the track.
different from the inside
i guess i could make a 2d concave polygon from the lines and split that into a bunch of triangles then render thoes triangles as a track
so what are your inputs and expected outputs
like do you have a list of numbers? An image?
the way you're describing it still doesn't make it clear
then what do these lines look like, how are they given to you, and wdym by color them
i don't want to color the lines i want to color the inside of the track.
the lines are just two points start and end
i know how to do it nevermind i asked
Triangle decomposition is what i needed
Can you explain?
Instead of doing [False]*len(nums), you'd much rather pack it bit by bit. This can be done by using a single int, and bit shifting. For example, to say that that 40 is found, you'd do
seen |= 1 << 40, and to check whether 25 has been found, you'd do
seen & (1 << 25)
granted, idk how efficient using ints for this in python is
memory efficient yes
but toggling a bit might end up expensive for large bitsets, while with a proper bitset it's just O(1)
is 1 << n O(n/30) because base 2^30 digits?
the masking itself is equally as expensive
something like that
Other than maybe being more memory efficient, people usually don't bother with that.
I doubt it is faster
it is faster if it's a proper bitset, but yea, python ints don't work too well for this usecase
In Python u could store 63 bits in an int, and get true O(1) performance
Actually in C++, using vector<char> is usually faster than using bitset
The computer is kind of bad dealing with single bits in an efficient way
So for performance, counterintuitively 1 byte per bool is usually preferred
This is yet another reason for why c++ decision to make vector<bool> a bitset is stupid.
I am not able to identify error and even Google is not able see
num=[]
while True:
input=input("enter number and 0 to exit")
if input ==0:
break
num.append(int(input))
ordered=sorted(num)
ls=len(num) //2
median=ordered[ls]
print("gratest number is",max(num))
print("median is",{median})
```
What is error?
Ph error is variable sorry 😅
Don't use input as variable name
Does anyone know how I can turn these two arrays to a 3D array similar to the array at the bottom:
xe1 = np.array([["H", "F"], ["D", "F"], ["J", "I"]])
# [[[1,2], ["H", "F"]], [[3,4], [D", "F"]],[[5,6], ["J","I"]]] ```
well first of all the numbers would become strings to keep it homogeneous
second,
>>> np.stack((ex1, xe1), axis=1)
array([[['1', '2'],
['H', 'F']],
[['3', '4'],
['D', 'F']],
[['5', '6'],
['J', 'I']]], dtype='<U11')
Using input as a variable name is bad.
Another issue is that input always returns a string, so you need to check == "0" instead of == 0
num = []
while True:
x = int(input("enter number, 0 to exit"))
if x == 0:
break
num.append(x)
num.sort()
ls = len(num)//2
median = ordered[ls]
print("greatest number is", num[-1])
print("median is", median)
does anyone know how i can implement a shortest path algo for a directed graph (like in the picture, but with self-arrows) with the following constraints:
- without using a stack/queue/linked list
- only with the option of using static arrays (implementing this in Java, couldnt find help online)
- TC needs to be less than exponential TC
Sounds like a DP question. Are you familiar with dynamic programming?
not really, i think it's just breaking down big problems into smaller and solvable ones?
like in recursion
which is what im trying to do rn
With recursion, you'd need some memory structure to avoid infinite loops (ie; 3-4-3-4-3-4-...)?
And your problem statement says no stack/queue/list
A static array can be used as the storage for stack, queue, linked list
But really, this sounds like they want you to use Floyd warshall
yeah thats what im trying to do with it rn
idk who that is, this is our 2nd cs course so idk how to make < exponential
last semester i had i think the same problem and only managed to make it n^2 or something but with hash maps
or even n! cause idk if i managed
n! is better than exponential
It is a very standard alg that compute all pairwise shortest path in n^3 time
https://en.wikipedia.org/wiki/Bellman–Ford_algorithm if you just need one vertex to every other vertex/specific vertex, this algo is a move. A bad move, but a move nevertheless.
also O(|V||E|) <= O(|V|^3)
ill look at it after ill finish my current try, ty
Floyd is just 3 nested for loops, using a n x n matrix
I really think that is what they are trying to hint when they say you cannot use a stack/queue/linked list
yea, it does look likely
This is the entire algorithm
for (int k = 0; k < n; ++k) {
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
}
}
}
The goal of this project is to translate the wonderful resource http://e-maxx.ru/algo which provides descriptions of many algorithms and data structures especially popular in field of competitive programming. Moreover we want to improve the collected knowledge by extending the articles and adding new articles to the collection.
gave me a serious headache such that i had to take break from it
?
well, you'd need to modify it a bit to get actual paths rather than just distances
https://github.com/cheran-senthil/PyRival/blob/master/pyrival/graphs/floyd_warshall.py here is a version that does that
⚡ Competitive Programming Library. Contribute to cheran-senthil/PyRival development by creating an account on GitHub.
it's not
Stirling's approximation says hi
floyd-warshall just keeps asking
is it better to go A->B directly, or introduce some midpoint C and go A->C->B
repeat enough times
and for reference n^n = e^(n log n)
so it's worse than exponential
oh wait yea ,I misremembered
very relaxing
it's better than n^n
n! = 1 * 2 * ... * k * (k+1) * (k+2) * ...
if you select any exponential k^n, n! starts growing faster and faster after n == k
yeah i get that but for me the implementation got way confusing
cause we introduce 2 matrices one to keep record of paths, iirc
and other for shortest distance
I'm just not sure they'd ask a student to implement this given those instructions. But, I dunno.
Hey guys, I've a list A of n natural numbers, and a K number, natural also
I want to return B, where B has n * k numbers, and it has to have all elements of A, multiplied by j, 1 <= j <= k
So something like this:
A = [2, 4, 6, 8]
k = 3
B = [
2, 4, 6, // For 2
4, 8, 12, // For 4
6, 12, 18, // For 6
8, 16, 24 // For 8
]
and B needs to be in order
I need to give a solution in O(nk log n), what I thought was, first creating a B' like this:
A = [2, 4, 6, 8]
k = 3
B = [
[2, 4, 6], // For 2
[4, 8, 12], // For 4
[6, 12, 18], // For 6
[8, 16, 24] // For 8
]
I know I've n lists of k elements in B, where each list is in order. Getting here costs n * k
I thought I could take advantage of knowing all these lists are in order, to do a Merge Sort, but I'm not sure if I'm in the complexity range
Btw, this isnt a python problem, it's more a theoretical problem, from a uni excercise.
If no constraints on spce i think you can use min heap
You take extra o(n) spce for heap
And to get B
while min_heap: i = heapq.heappop(min_heap) B.append(i)
Or rather you can use binary search on the go?
hmm BST.inorder is O(1) and inserting in the binary tree is log n, right?
so I get nk log n?
oh that makes sense
nk log(nk)
Merge sort is nlogn
So it will be nk + nklog(n k)
It still be ny log(nk)
Cause total numbers will be n * k, i dont think you can escape that
can k > n?
if k ≤ n then log(n k) = O(log n)
there are also approaches that are O(max(n k, max_value)) but that use O(max_value) memory
yup
RIP
my exam is this friday, and I'm cooked 😄
I also need to study for my calc exam
isn't O(n k log n) easy with a min-heap?
you only ever need to keep n values in the heap
the smallest value from each group
wdym?
this makes it log n
not in the heap at any one time
you know that the minimum is one of the values among the smallest values in each group
so you can make use of things being sorted
I dont understand
Like, what you are trying to say 
I need to return B, which has to have n * k elements
if I use a heap to order, then I need a heap of n * k elements
you don't
if you have n lists of length k that you know are sorted, how many elements could possibly be the smallest?
I've n lists of lenght k that are sorted, but I might have repeated lists for example?
also, A isnt in order
and I dont need to return the smallest number, I need to return the FULL list, in order
so? say you wanted to find the smallest element, how many elements would you need to look at?
ty, i managed to implement it using it
but the explanations i found are so bad
like they shouldve given simple code, simple execution and simple examples
n
but I dont have to return the smallest number
cool, now remove that element and replace it with the next one in the same list
how many elements can now be the 2nd smallest?
it's again n
n-1
you can do these operation on a heap in O(heap size)
the heap has size ≤n at all times
i.e. at most n elements could be the minimum at any point, those are the ones you need to consider when finding the minimum
Sorry I just dont get how you can return a list of lenght k * n without adding k * n elements to the heap. I'll continue with the next excercise.
Thanks btw
you can put k*n references to the same object into a list
all n*k elements will be at the heap at some point
but not at the same time
@thorn oriole sketch of how it would work
n=2, k=3
a = [4, 8, 12]
b = [3, 6, 9]
result = []
heap = [3, 4]
a = [4, 8, 12]
b = [3, 6, 9]
result = [3]
heap = [4, 6]
a = [4, 8, 12]
b = [6, 9]
result = [3, 4]
heap = [6, 8]
a = [8, 12]
b = [6, 9]
result = [3, 4, 6]
heap = [8, 9]
a = [8, 12]
b = [9]
...
How to do method overloading ?
https://wiki.python.org/moin/TimeComplexity
What's the difference between pop intermediate and delete in that table for Python lists
Did they make two entries because pop returns the element and delete calls the garbage collector?
Pop removes the last element, delete is for any position in the list
Oh pop intermediate
Probably list.pop(i) vs del list[i]
No functional difference
That table is just very funky in general
Some of these tables look wrong in general
if n = 2 then you should get same time complexity on both rows
But you dont
Something I'm more facinated by is that pop isnt marked as a [1]. [1] means it is making use of amortization.
I would assume that just like append, pop also has to deal with amortization
Unless you never want the memory usage of a list to shrink
I guess someone mixed up max and min
it should be min in both I think
can't in python
you just have *args and **kwargs, then in the 1 function, choose which impl to use by parsing them
No, it should be a generalisation of the first worst case (which is comparing all elements)
So it hould say something like O((n - 1) * l^2)
Hello chat
Im just about to start training my transformer based model, any useful tips before i run this nonstop for a while?
oh, I was comparing the top left and bottom right for whatever reason
I think average case is (n-1) O(min(lens))
also "average"
maybe average on random input
That assumes the programmer put the smallest set first
Someone should probably just remove that multiple intersection row from the table
yeah
It tricks you into thinking that python has some special optimization for multiple intersections
While in fact it just runs pairwise intersection over and over
Does it? I’m not even sure it does
Like you can free the memory without having to copy your array somewhere else?
But when you append, if the memory you’re « requesting » when it grows is not free, then you have to copy everything
I think you can't really free part of some allocated memory
Ah I guess, this is beyond what I know
Isn’t that like the official Python doc lol
official wiki of sorts
but I'm not surprised there are errors
I would assume they would do a realloc to shrink memory
which more than likely just keeps the same pointer
probably better asked in #data-science-and-ml
sry
For this question:
You've decided to take the ultimate course: MATH131. However, that course has some requirements - you have to take MATH120, MATH121, and MATH122 first! But each of those have their own requirements:
MATH131 requires MATH120, MATH121, MATH122
MATH122 requires MATH111, MATH112
MATH121 requires MATH111
MATH120 requires MATH110, MATH111
MATH112 requires MATH110
MATH111 requires MATH110
MATH110 has no requirements
What order should you take these courses in?
How would you guys go about it?
This was my code, and let me know where I can improve it.
https://mystb.in/14eabcb146f111696d
Output = ['MATH110', 'MATH112', 'MATH111', 'MATH122', 'MATH121', 'MATH120', 'MATH131']
#The order matters
!docs graphlib.TopologicalSorter That's a topological sorting task, isn't it? Python has a builtin for it. (for some reason)
class graphlib.TopologicalSorter(graph=None)```
Provides functionality to topologically sort a graph of [hashable](https://docs.python.org/3/glossary.html#term-hashable) nodes.
A topological order is a linear ordering of the vertices in a graph such that for every directed edge u \-\> v from vertex u to vertex v, vertex u comes before vertex v in the ordering. For instance, the vertices of the graph may represent tasks to be performed, and the edges may represent constraints that one task must be performed before another; in this example, a topological ordering is just a valid sequence for the tasks. A complete topological ordering is possible if and only if the graph has no directed cycles, that is, if it is a directed acyclic graph.
and again for some reason this stdlib exists solely for this class
and honestly a topo sort isn't hard to implement anyways
class Solution:
def takeCharacters(self, s: str, k: int) -> int:
freqs = [0] * 3
n = len(s)
for c in s:
freqs[ord(c) - ord('a')] += 1
i = 0
j = 0
if freqs[0] < k or freqs[1] < k or freqs[2] < k:
return -1
for j in range(n):
freqs[ord(s[j]) - ord('a')] -= 1
if freqs[0] < k or freqs[1] < k or freqs[2] < k:
freqs[ord(s[i]) - ord('a')] += 1
i += 1
return n - (j - i + 1)```
Input: s = "aabaaaacaabc", k = 2
Output: 8```
can anyone explain how it works?
is j==n? use for loop here for j in range(n): working of j here?
range(n) is 0,1,..., n-1
n is not included
oh yeah so j has no role? Return i
so how i works here? How i is the soln like valid
How to send formatted code in this chat?
Could someone explain me the code implemented here..
Background : Its a code for finding the longest length of a sub-array in which its values sum to value k below is the code
def longest_subarray_with_sum_k(array, array_length, target_sum):
# Dictionary to store prefix sums and their first occurrences
prefix_sum_indices = {}
# Initialize variables
prefix_sum = 0
longest_subarray_length = 0
for index in range(array_length):
# Update the prefix sum
prefix_sum += array[index]
# If the prefix sum itself equals the target, update the length
if prefix_sum == target_sum:
longest_subarray_length = max(longest_subarray_length, index + 1)
# Check if the difference (prefix_sum - target_sum) exists in the hashmap
difference = prefix_sum - target_sum
if difference in prefix_sum_indices:
# Calculate the subarray length
subarray_length = index - prefix_sum_indices[difference]
longest_subarray_length = max(longest_subarray_length, subarray_length)
# Store the first occurrence of the prefix sum in the hashmap
if prefix_sum not in prefix_sum_indices:
prefix_sum_indices[prefix_sum] = index
return longest_subarray_length
# Example usage
n = 7
k = 3
a = [1, 2, 3, 1, 1, 1, 1]
result = longest_subarray_with_sum_k(a, n, k)
print("Length of the longest subarray with sum =", k, "is", result)```
Thank you so much.. much better 🙂
Here are my question... I am getting fuzzy in these two sections specially...
# Check if the difference (prefix_sum - target_sum) exists in the hashmap
difference = prefix_sum - target_sum
if difference in prefix_sum_indices:
# Calculate the subarray length
subarray_length = index - prefix_sum_indices[difference]
longest_subarray_length = max(longest_subarray_length, subarray_length)
# Store the first occurrence of the prefix sum in the hashmap
if prefix_sum not in prefix_sum_indices:
prefix_sum_indices[prefix_sum] = index
do u know hindi check codestorywithmik
I dont know Hindi..
Do you anyone around here who knows Tamil?
Its another south indian language
i dont know but wait so many xpert peeps here
The code looks buggy to me. j will always be n - 1 after the for loop. (Unless n=0, and in that case j=0.)
Technically it is return i - int(n<=0)
Hi ! I have a question regarding the del method.
I've stumble onto a bug (sys.meta_path is None, Python is likely shutting down) and a bit of reading convinced me that I had the wrong understanding of how it works. It appears not to act as a destructor, or mainly that it may be called after the environment starts to tear down and that's what causes my issue, and it's globally a bad idea to use them.
However, I do need some of my objects to act when destroyed, how can I do that please ? 😄
Looks like a good question for the people at #esoteric-python
Okay, thanks 😄
code works well
I have a numpy array like this: np.array(["1546", "234", "123414", "342", "9120831"]), and I want a new array instead with each strings lenght as a value. To this instead: np.array([4, 3, 6, 3, 7])
np.array(["1546", "234", "123414", "342", "9120831"]) # To this -> np.array([4, 3, 6, 3, 7]) Which is a new array of each strings length instead.
apparently np.char.str_len(arr) exists
!rule 9
!d numpy.char.str_len
char.str_len(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature]) = <ufunc 'str_len'>```
Returns the length of each element. For byte strings, this is the number of bytes, while, for Unicode strings, it is the number of Unicode code points.
guys one question
in bfs, you always have to have a initial node
and an reach node, or this last is not necessary
not necessary
just keep bfs-ing until the queue becomes empty
but it always has to have like an initial node right?
yes
or initial nodes
depends on what you're doing
uh, can you explain?
do you know how to fix
File "<console>", line 1
import os
^
SyntaxError: multiple statements found while compiling a single statement
File "<console>", line 1
import os
^
SyntaxError: multiple statements found while compiling a single statement
what do numbers have to do with json files though
Numeric values that cannot be represented in the grammar below (such
as Infinity and NaN) are not permitted.
JavaScript Object Notation (JSON) is a lightweight, text-based, language-independent data interchange format. It was derived from the ECMAScript Programming Language Standard. JSON defines a small set of formatting rules for the portable representation of structured data. This document removes inconsistencies with other specifications of JSON, r...
but the python json does have some special functions to read them anyways
Looking for buddies for daily learning or connecting..
Ok
is there a fast, branchless way of getting any 3d vector non-collinear to the given non-zero vector?
@raven dagger https://paste.pythondiscord.com/77YA
my parser broke
- Custom Sorting Algorithm
● Objective: Write a program to sort a list of integers using a custom sorting algorithm,
such as bubble sort or selection sort.
● Requirements:
○ Accept a list of integers from the user and provide options to sort it in ascending
or descending order.
○ Implement the sorting algorithm manually (no built-in sort() function).
○ Display the sorted list along with the number of comparisons or swaps made
during the sorting process.
○ Bonus: Implement both bubble sort and selection sort, allowing the user to
choose the algorithm they want to use.
● Skills Practiced: Loops, conditionals, algorithm design, and understanding of sorting
mechanics.
someone can help to create it? and can tell what this assignment exactly need?
what is bubble sort or selecion sort i mean?
a sorting algorithm takes a list of numbers and compares them to eachother so that the output contains all the numbers in ascending order
bubble sort and selection sort are algorithms that achieve this
take a random unit vector
Maybe something like (a,b,c) -> (b,c,2*a)
doesn't work for (1, 2^(1/3), 2^(2/3))
pretty sure it can't be continious in general because something-something hairy ball theorem
The hairy ball theorem of algebraic topology (sometimes called the hedgehog theorem in Europe) states that there is no nonvanishing continuous tangent vector field on even-dimensional n-spheres. For the ordinary sphere, or 2‑sphere, if f is a continuous function that assigns a vector in ℝ3 to every point p on a sphere such that f(p) is always ta...
u = v/abs(v); out = (u == i^)*j^ + (u != i^)*i^?
that works ig but you might as well have an if at that point. It's not pretty, but this is even worse, especially considering that by u == i^ here you actually mean something like abs(u.x) - 1 > -eps.
It would be nice if there was just a weird function which would do that.
agreed
but that's not an integer solution
can't you just add something perpendicular to the vector to get something that's guaranteed to be not colinear?
actually, can't you just pick some perpendicular vector 
e.g. (y - z, z - x, x - y)
doesn't work for (1, 1, 1)
In general, to find the perpendicular vector you take the cross product of your vector with any non-collinear vector and... well guess what
what's the context here?
in c++ for example if iirc, simple ternaries might get converted to branchless by the compiler
shaders
well, ok, now it's curiosity more than anything
because as it has already been said, just take a random unit vector
slightly funny that a matrix mult that does that exists in 2d and even 4d but not 3d
I think (1, y + floor(abs(x)), z) works for normalized vectors because when abs(x) != 1 it's (1, y, z) which is not collinear, and if abs(x) = 1 it's (1, y + 1, z) which is (1, 1, 0) and it's collinear to (+-1, 0, 0)
although (1, y + floor(abs(x + x)), z) should have better floating point robustness if my math in correct
why didnt they just add that legals is of max length 8? it's very misleading
they shouldve added ? to the other areas
it doesn't need to be
it can be whatever length (≤ len(V))
practice
it is that length of the other 2 arrays, so calling it an array at first and then calling it a stack is blatantly misleading
how is this O(n) and not O(n^2)?
inserting to an array should be O(1) since we keep track of the array's length (not the max array capacity)
so inserting to arr of size n should be n+1 operations to build and fill the new arr
oh i understand
so calling it an array at first and then calling it a stack is blatantly misleading
what?
all the others were plain arrays, and they only in the next slide changed the narrative that legals is a stack
where did anything say legals is a stack?
it's a separate slide with a completely separate example
the next slide, and same example
it's not?
what is misleading?
btw, have u used CLRS?
for my own learning no
calling an array an array, drawing only 2 out of 8 elements in memory of it (other arrays were drawn with the entirety of their elements in the example), and then the next slide saying that small array is a stack
of size 8
it did not say that
or you haven't shared whatever slide says that
okay forget it, look at this:
the length of that array doesn't need to be 8
i think there's a mistake here, because the $a_{i+1}$ Node might not exist (=be equal to null), so in the 2nd line: A.next<-A.next.next would be like doing A.next<-null.next, which is undefined, since null doesnt have any fields like next stored in memory
it's the same length asthe other arrays exactly
it doesn't need to be
theyre allocated and vacant "?"
thoughts?
also why it is an array thats also a stack of the same size as the others
oh, they do use a stack, but I don't get your complaint
the stack ADT is not a fixed size thing
u didnt understand that either
it is fixed maxlen in our implemention
but thats okay
i wanna know if u also think there's an edge case that needs to be account for here
this one
it's assuming you're not at the end, yes
depending on how the function is used it might be a fine function
what am i not understanding? why is amort(Pop) both 1 time units, and 0 time units (not possible)
I'm guessing the point is that you don't need to care about pop taking time
since before any pop comes a push
So "amortized" you could say pop has 0 cost by doubling the cost of push
return sum(1 for passenger in details if int(passenger[11:13]) > 60)
i feel like this probably isn't a great way of doing this
is the sum(1) thing idiomatic for python?
Its not uncommon to see the sum(1 for ...) in Python. The alternative in your case is to sum the Boolean condition without any ifs.
If you want your code to be easier to understand, a good alternative might be to create a list and do len on it.
what are cut vertices or articulation points?
How can I find them?
ty, but it seems incorrect to say it (as in u can only say armortized of both is 2 and none can be 0)
@regal spoke have u uses clrs book and how good it is? I wonder if their explanations would be better than our lecture slides
The slides are very informal
But they are not incorrect
Think of it more like this: for the time complexity analysis, it doesn't matter if you assume pop takes time or not
Since the time of doing pops will always be dominated by the time it takes to do the pushes
I have no clue
that's true, I understand now, ty
Does learning DSA in python is beneficial or not
https://cses.fi/problemset/task/1694/
Any idea how to make Edmonds-Karp pass in Python? I've tried to make it as fast as possible but I still get TLE on one test case
Here is my code: https://pastebin.com/uy7fg0uy
(I followed the pseudo code here: https://en.wikipedia.org/wiki/Edmonds–Karp_algorithm except I made two adjacency dicts, one for the curr flow between edges and one for the capacities)
Worth noting I also get TLE in C++ so it's probably that we can't use Edmonds-Karp for that problem?
Ah so, using a stack instead of a queue (so not using edmonds-karp) works
even though it's supposedly O(Ef) which is a lot worse than O(E²V)
Is it possible to make an example that's actually attaining this runtime? The wikipedia example here https://en.wikipedia.org/wiki/Ford–Fulkerson_algorithm (Integer flow example) is kind of bs imo (like in practice, a dfs wouldn't change randomly from one iteration to the other)
Don't trust wiki. Also never use dictinaries unless absolutely required.
The trick is to keep track of a forward capacity and a backwards capacity for each edge
When you push x flow through an edge, you decrease the forward capacity by x and increase the backwards capacity by x
About the time complexity. Flow algorithms almost always run magnitudes faster than what you'd expect from looking at their time complexity
However, on websites that allow users to add hacks, probably someone has submitted a worst case for all of the popular flow algorithms
Your BFS is kind of bugged. You will try to go back to the source node since its parent is -1
Yeah that I understand
Could you suggest a way to make the dfs version go slow?
If I understand correctly it is O(E*max_flow)
But I really don’t like the example of that worst case scenario / hack on Wikipedia
I don’t know if I’m clear
Codeforces comments are usually the best way to find stuff like this
Ah yes that’s smart, thank you
I see yeah
Just to make sure
On this page, the integer flow example
The Ford–Fulkerson method or Ford–Fulkerson algorithm (FFA) is a greedy algorithm that computes the maximum flow in a flow network. It is sometimes called a "method" instead of an "algorithm" as the approach to finding augmenting paths in a residual graph is not fully specified or it is specified in several implementations with different running...
Says it would take 2000 steps
To finish with dfs
Am I correct in saying that would never happen if you were to code it?
Or am I just misunderstanding something?
They claim you do ABCD (which is fair)
Then augmenting path ACBD
but like you’d go for ABD
Because no way the iterable neighbours(A) changed its order
A's adjecency list is [B,C]
I think you arent understanding my comment
here
What edges the graph contains dont change depending on the capacities
At this point ^ A,C,B,D is an augmenting path
Yes that I understand
However I don’t understand why in the first iteration the first path we found with our dfs was ABCD
so clearly in the second iteration the first augmenting path should be ABD?
But I’m not sure I understand your adjacency lists
This I understand, but why would there ever be D in A’s adjacency list
oh ops
Since initially there is no way to push flow from A to D « directly » nor is there a way to push flow from D to A
A and D arent connected
Hmm yes
If we use dfs the first augmenting path we find will be A C B D and the second one will be A C D
Maybe this isn't a good example
like there is no way
We alternate
A B and then A C
I know Wikipedia is usually not the greatest place for those examples but they seemed very convinced of their counter example
I think that "worst case" on wiki doesn't work for a fixed adjecency list
Is it worst case if we take a random neighbor
And we are really really really unlucky
Which I guess from a theoretical point of view is enough to say that’s the worst case
You know, just do dinics if you want to avoid this kind of worst case
But like if I were tasked to hack someone’s solution with a fixed adjacency list I really don’t see how I can attain this O(E*max_flow)
Thats fair but im really annoyed because I can’t reach that worst case
It’s probably not useful to try and build that counter example but still it bothers me
I think the point of the wiki article is just that if a bad actor could chose what dfs you do
Then the algorithm could become crazily slow
And so my question is can your algo become crazily slow if the bad actor can just craft a shitty output
Basically like a Codeforces hack
But it might not be that easy to build
In the case of a BFS, the answer is no
Oh yes I was talking about a DFS
In the case of a DFS, I'm not sure
I read the proof that BFS is VE^2 (Edmonds Karp thing)
There probably is some killer out there
And then I saw dinic but didn’t look at it yet
Dinics is basically same as edmonds karp
But it is able to reuse the BFS to find multiple augmenting paths
Anecdotally, on the cses I think they expected dinics because I copy pasted a template to try it and it passed
And the Edmonds Karp one didn’t pass (fair enough seeing the constraints)
But the dfs did which seems crazy to me (and currently the fastest Python solution uses it)
What about this example
Ah
The idea is that the dfs is tricked into going into the loop before trying C
Yes
That would definitely break it
I guess you would have to call B C
Coz the dfs goes to C first
You should definitely propose this as a hack on cses
It would break so many solutions
Actually can you go back to A after going to B?
Since A was marked as visited?
That depends on how you DFS
^
BFS != DFS
Yes I know I know but
In my DFS
I could very well say
Im adding to the stack only
If parent[neighbour] != -1
To avoid that loop
This blog mentions a hack to the normal dfs ford fulkerson but I’m a bit confused
So I tried to brute force it to find something bad
https://pastebin.com/ijUZDn3G
that failed miserably
Just do dinica
I'm not trying to pass the cses problem
Its easy and runs reasonably fast
I'm trying to hack my solution that passed despite it being O(E*f)
Btw all of these flow algorithms are technically O(E * f)
I'm pretty sure Edmonds-Karp can actually be bound by E²V
There's a formal proof here: https://enos.itcollege.ee/~japoia/algorithms/GT/Introduction_to_algorithms-3rd Edition.pdf
You can prove that the augmenting paths become longer and longer
That's the case with both dinics and Edmonds-karp
But the E*f bound still holds
They prove this first
and then they prove this claim (and I went through it and was convinced)
Thing is, all of the ford-fulkerson like algorithms obviously can be bounded by O(E * f)
This O(VE²) is just a better bound if f is big is what I meant.
And in the case of Edmonds-Karp they prove there are at most E*V/2 augmentations.
Since an augmentation costs O(E) time, and there can be at most f augmentations
Edmonds-karp use of BFS also makes it so there is an order to which it finds its augmenting paths
This lets you show another bound on the number of augmentations that it will do
And that bound is (worst-case) better when f is really big, right? I thought that was the whole point
It is more the case when the capacities are big
Well yes f being the max flow if f is big I meant the capacities will necessarily be big (since V and E are quite small in the problem)
Yes but they derive the other bound without assuming the capacities are all 1
if I'm not mistaken
yes
So there has to be an example where (for small V and E, and big capacities) BFS works and DFS times out crazy
and this would definitely hack my cses solution since I use the DFS which is not bound by VE² but only bound by E*f and the capacities can go up to 10^9
I really expected creating billions of random small graphs with big capacities would allow me to find that counter example but no 😦
hmm... we talking about cses download speed?
cause my ff definitely didn't pass (timed out on test 20)
blank
Looks blank to me too
Flow algorithms are super tricky to benchmark since their worst case almost never occur.
Yeeah I'm now realizing
maybe it's due to you doing dfs with a stack and thus have a different order
I did dfs with recursion
You know, max flow can be solved in O(n log ^ 10 n) (not sure of the exact number of logs, its something like 10 logs).
I think of it like max flow algorithms are usually really fast, but there are tricky edge cases where they run slow.
The people that did the O(n log ^ 10 n) algorithm was able to rule out all of those edge cases.
Those are the crazy edge cases I was looking for 😭
There has to be someone that hacked ff before
I'll probably just ask if they remember on a blog on codeforces
I initially thought it would be easy to come up with
how mistaken was i
I copied that sentence on the blog because you explained it well and succintely, I hope you don't mind
Actually I have an idea
Maybe you can show that the DFS version isn't really O(E * f)
My idea is to duplicate the edges enough times
To where a BFS would take the same path as a DFS
We know that the BFS doesn't take O(E * f)
So maybe the DFS also cannot take O(E * f)
There could still be some case where the DFS is horribly slow, but at least it will be polynomial in the number of edges
I feel like if you managed to prove that you could almost publish it, all sources I've seen so far all say FF with DFS is O(Ef) and that's why we like BFS in max flow because we have a bound that doesn't depend on the capacities (or at least that's how it was presented to me when I was in uni)
I asked some other people about this on another server
None of them have a clue about how to construct an E * f worst case in the DFS one
@stiff quartz Update.
This is a recursive construction that adds two new nodes every time
It takes O(2^n) time
basically said its near to constant time