#algos-and-data-structs
1 messages · Page 160 of 1
No sense in thinking about that anyway. Reality is that interviewers ask this so you need to know it to get through
elif price - min_price > max_profit:
this part for example in my code above
should probably be cleaned up a bit more
its not obvious why we are taking price - min_price
you know?
that could be put into a function
is_profit_gained()
would be nicer i think
I disagree. It would be too much abstraction for a simple problem.
# Check if the current profit is the new maximum.
current_profit = price - min_price
if current_profit > max_profit:
...
is better
yeah i thought aabout that as well
class Solution {
public:
int maxProfit(vector<int>& prices) {
int max_profit=0,min_profit;
for(int i=0;i<prices.size();i++)
{
min_profit = min(min_profit, prices[i]);
max_profit = max(max_profit, prices[i]-min_profit);
}
return max_profit;
}
};
I don't like how you wrote the two integers in one line like that
and there's no spacing in your for loop
or your min/max functions
You should clean that up
Also, why not replace the for loop with ranged-based for loop?
class Solution {
public:
int maxProfit(vector<int>& prices) {
int max_profit=0
int lowest_price;
for(auto i : prices)
{
lowest_price = min(lowest_price, i);
max_profit = max(max_profit, i - lowest_price);
}
return max_profit;
}
};
for (int price : prices)```
min_profit is a misnomer. It's not storing a profit. It's just a single price.
yeah thats much cleaner lol
int max_profit=0,min_profit;
replace this with this
nvm u got it lol
lol
I'm doing a review basically what my boss would do to me 😄
hahaha
I also believe that like 90% of these people making coding algorithms are doing it wrong
Like why use C++?
C++ is so verbose
Python/Ruby is what you should be using
Disagree
Use what you're most familiar with
You don't want to waste time looking up how to do basic things
i guarantee you that you will spend more time doing c++
than if u knew python/ruby
yes, you will take longer to "learn" a new language, but if you took the time to learn that language, long term, you would be more productive
C++ suits me personally better to learn fundamental CS concepts. In addition to that, the industry I'm trying to get in uses C++ as it has the highest performance.
C++ is not good for being productive
Depends on what your goal is, no? As long as you don't have to look up syntax bs all the time as @half lotus said
I mean being an efficient and productive programmer is important to getting promotions at your job
As you move up past senior, it becomes less about "what you do" and more about "how you unblocked and helped your team do things easier"
You do know that there are industries where python is just not sufficient due to lack of performance?
Financial industry, specifically in the trading space uses primarily C++ and q/kdb
I work in gaming. We use C++, Rust, C#, and Python.
C++ and Python are both good for being productive, and you can combine them.
Python is heavily used
I think Rust is a superior language to C++/C
There's almost no reason to use C++ anymore
It's 30 years old
Rust can do everything C++ can do
And Rust even outperforms C
In many algorithm tests
There are certain cases where you need something faster than Python or Rust
Rust is faster than C/C++
No, otherwise the UHFT (ultra high frequency trading firms) would use it
They don't, they use C++. Because it is faster
That's just because their code is probably old as shit lol
nope
Rust allows reaching a higher-level performance in comparison to C++ because of its better safety standards that decrease the development process cost. For example, to ensure faster operation, C++ does not have automatic garbage collection tools, which might contribute to multiple runtime errors.Jun 9, 2021
literally just google it bro lol
Rust is faster in 4 of the benchmarks, C++ is faster in 3 of them, and they're basically identical in 3 of them.
Performance of rust is either superior, or equal to C/C++
in almost every benchmark
Rust achieves the same speed while guaranteeing memory safety and thread safety, doesn’t need error handling, doesn’t need null checks...being easier to debug, maintain, etc. The only thing it actually loses at (by a long shot) is compile time.
Brother I respect your opinion and even agree that you can use Python or Rust for the vast majority of cases (and performance is equal while having easier to read code). But the only reason these firms use C++ is because it is literally faster. They optimize it in ways we don't even know
It's a fact that they can use it in a way that is faster than Rust
its not an opinion
its fact
Rust beats C/C++ in almost every benchmark
This isn't really up for discussion
almost
it does
You should learn Rust
don't fight it lol
its a great language
and you will love it
I'm willing to and will probably
But first C++ because it is widely used in high frequency trading (because it's faster)
They optimize it in various ways like running it solely on hardware and other stuff.
Don't you think they'd use Rust if Rust was faster?
No
Companies use whatever their engineers know
And Rust is still a new language
Companies take a long time to change their habits
lol
Lmao they'd use Rust immediately if it was faster
Takes like 10-20 years
No they wouldn't.
You don't know what you're talking about
It takes time to train people, hire them, and learn best practices
Give me a second to explain, you don't know what I'm referrring to
Look
In high frequency trading literal micro to even nanoseconds decide whether you get the trade or not
Companies spend hundreds of MILLIONS of dollars in order to reduce latency
I don't think you know what you're talking about
If they're able to send a order to the exchange a couple microseconds faster, then they'll outcompete their rivals and literally gain millions from it
If Rust was faster in this circumstance, they would use it immediately. Some of the smartest people in the world work for such UHFT firms or market makers.
You think they wouldn't figure it out?
are we still on the topic of algos and data structs?
In this specific use case C++ is superior, that is a fact.
no, probably shouldnt talk about this anymore lol
sorry
def coinChange(self, coins: List[int], amount: int) -> int:
dp = [amount + 1] * (amount + 1)
dp[0] = 0
for amount in range(1, amount + 1):
for coin in coins:
if amount - coin >= 0:
dp[amount] = min(dp[amount], 1 + dp[amount - coin])
return dp[amount] if dp[amount] != amount + 1 else -1```
Found this solution online
Anyone know how to write this so it's more intuitive to understand?
How about this ```py
def coinChange(self, coins: List[int], amount: int) -> int:
# The index is the amount.
# The value is the smallest number of coins needed for that amount.
coins_per_amount = [amount + 1] * (amount + 1)
# As a base case, an amount of 0 trivially requires 0 coins.
coins_per_amount[0] = 0
# Determine the fewest coins needed to reach each amount, starting at the smallest amount.
for amount in range(1, amount + 1):
for coin in coins:
deficit = amount - coin
# If the deficit is negative, then the current coin can't be used;
# it would go over the current amount needed.
if deficit >= 0:
# Does using the current coin result in fewer coins used than the previously known
# minimum for this amount?
coins_per_amount[amount] = min(coins_per_amount[amount], 1 + coins_per_amount[deficit])
if coins_per_amount[amount] == amount + 1:
# The number of coins for the target amount is still at its default value.
# Thus, it's impossible to reach with any combination of coins.
return -1
else:
return coins_per_amount[amount]
I like that
At what level were you after several months? Have you been able to solve mediums consistently?
where did u find ur study bro
I don't remember by now. That was almost two years ago. I think it was a 3 month span during fall 2020. Doing 2-3 problems 5 days a week.
I doubt I was able to consistently solve mediums.
Maybe like 60%-75% success
If I dont' get promoted in the next year, I'm going to start looking for a new job.
So I would like to get a study buddy
lol
I want to get up to making 300k+ salary
my total compensation is like 115k righbt now
which is tooo low
I started practicing again last month and I definitely forgot things. Revisited problems I did 2 years ago and couldn't remember the approach.
Nothing I'm looking for a job right now 😄
Thats very good. I think FAANG is possible with such a quota(maybe with luck? but thats always needed). From what I've heard they ask easy-mediums.
FAANG pays less than the gaming industry
Believe it or not lol
You hear all this bad stuff about gaming paying low, it does pay low... At the junior/entry level positions.
Well this is more of a #career-advice topic
But when you get to senior+ its actually more, or equal
Wow for real? I have never heard about that
And the graduate pay is so low because too many applicants?
Last thing I'll say, it's basically higher at the more senior level because we get royalties + stocks + base salary
Most FAANG companies don't give royalties
They just give salary + rsu's
On reddit. They were the ones looking actually, not me. I just figured it'd be a good opportunity for me to practice too.
'lists' is bunch of linked lists in an array like this
[
ListNode{val: 1, next: ListNode{val: 4, next: ListNode{val: 5, next: None}}}
ListNode{val: 1, next: ListNode{val: 3, next: ListNode{val: 4, next: None}}}
]
anyone know why this doesn't work
for l in lists :
heapq.heappush(heap, (l.val, l) )
but why this work ?
NODE = ListNode(0)
for l in lists :
heapq.heappush(heap, (l.val, NODE) )
the error
TypeError: '<' not supported between instances of 'ListNode' and 'ListNode'
tuples are compared elementwise, so if there's a tie on the l.val, it then tries to compare the second elements
make senses ... i will look into this, ty
but why wait would NODE = ListNode(0) works ?
difference = lambda x: abs(x - mean)
res = min(x, key=difference)
can anyone tell me how this code works
x is an iterable here and mean is the mean of the elements in x
you could make it even cleaner using max and min rather than the if statement
max_profit = max(max_profit, price - min_price)
min_price = min(min_price, price)
the section this is from has almost nothing to do with runtime performance
and the reddit post this is from doesn't support your point either, if you actually read more than the first line
Rust is faster in 4 of the benchmarks, C++ is faster in 3 of them, and they're basically identical in 3 of them.
While strictly mathematically, Rust wins in more of them (4 out of 10 vs 3 out of 10), this is not that strong of a proof of anything. If you count the C implementation of regex-redux as achievable by C++, it makes it even. Both languages have their merits, but basing any blanket statements about performance on microoptimized code filled with non-standard language extensions (omp and other libraries in the C++ code) can lead you to false conclusions.
The reasonable answer would be - profile the code from both languages, find where their bottlenecks are and determine whether it's reasonably fixable in the given language. Rust can have some interesting guarantees via borrow checker, C++ has stronger compile-time programming capabilities (AFAIK) so it depends on which attribute has a bigger impact.
It would be more interesting to compare how equivalent solutions, both written with idiomatic usage of the language, compares
e.g. no manual simd, avoid unsafe rust
from my experience writing both they are comparable in runtime performance
Guys is there any material which will help for understanding and implementing ADTs
?!
hey yo I just wanted to say i found a fix for that situation https://leetcode.com/problems/merge-k-sorted-lists/discuss/465094/Problems-with-Python3-and-Multiple-Solutions
at line "Here are the two ways"
👍
👌
💯
Problem is that it's idiomatic in C and C++ to end up with something more low level / complex for speed. Idiomatic is often taken as "leaving it at the bad solution", which kind of defeats the purpose of both C++ and Rust, in that you can make it as fast as it possibly could be (since you can even do inline assembly), while in other higher level languages you can't, not without switching to C/C++/Rust (e.g. Python calling into a C library / its own implementation like CPython). So it depends on what you consider "idiomatic" and how fair that really is (is it throwing away the languages' possibilities / purpose?).
(It's more about what you CAN do (with reasonable effort), when arguing for using a lower level language)
Could anyone recommend some reading for time and space complexity analysis? Pretty easy to figure out linear, quadratic, etc complexity but when there is an inherent tree or graph structure I sometimes make mistakes.
(Although the answer for C vs Python is BOTH (need consider if you can just call into a lower level language / where you draw the line))
I wouldn't say that's idiomatic at all, you can write fast simple code, and if you really need it you can get your hands dirty
But getting your hands dirty should be the exception, not the rule
Yea the simple solution can be orders of magnitude faster depending on language. But when it comes to something like C++ vs Rust, that does not really happen like the way it does for C vs Ruby. So it's more about the details at that point.
They are too close.
That's kind of my point
They are both good performance languages when writing simple idiomatic code
Oh, ok, because that was what the quote said already, was not sure. I thought they were doing the standard "idiomatic" code tests.
Anyhow, for C/C++/Rust and pretty much any compiled non-GC language that has pointers / references and is not doing really crazy stuff it will be pretty much the same except for the difference of years of compiler optimizations, although those kind of optimizations that compilers are good for are more like general project-wide optimization for optimizations that are really tedious for humans to do / not feasible on such a large scale.
Oh, I don't disagree with the thing I quoted in full. I disagree with claims of rust being just faster than C++, and pointed out that the sources originally quoted doesn't even support that
(Unless the compilers are bugged, which is unfortunately common)
(I remember seeing a Haskell project that actually runs just fine, but GHC was so buggy that they had to switch)
And yeah, the tests mentioned are actually really bad for comparison. A lot of code on benchmarksgame are very hand optimized and non-idiomatic.
(Or GCC defragmenting the hard drive on a simple 30 line program)
compiler bugs are a thing yeah, but they tend to be ironed out pretty quickly
I can't speak for ghc :P
(MSVC with its decade old bugs (what is Microsoft doing?))
Yeah, which is also kind of the point of both languages, they both can be as fast as can be, it's why they are chosen, which makes the whole speed comparison thing hard / very dependent on rules chosen.
If I see rust code that is majority unsafe I think that's kinda bypassing a bunch of the niceness of rust
(We can just assume / guess that C++ is faster due to being older, but that is not very convincing to those that need convincing)
similarly for stupidly optimized C++
Yea like when C++ compilers use UB to do optimizations that change behavior potentially.
I mean, clang and rust both are on top of llvm, no?
(Writing non-UB code in C++ is a nightmare)
(So is it idiomatic if nobody does it? (even though it's considered officially the "correct" thing))
UB code should never be considered officially correct
LLVM is a nightmare to use and so even though multiple languages use it their results vary a lot.
(Depends on what you feed to LLVM and which specific version)
what would you rather use? or do you think everything is pain in compiler space? 
The thing is that UB is often "machine defined" in practice and a lot of code relies on that, even for correctness. If writing non-UB code were way more feasible I could see it.
LLVM is kind of a "have to use for now until I can replace it with my own back-end". It gets lots of projects up and running.
Making your own backend is a lifetime effort though
Actually it's not as bad as it seems. The optimizations can just keep being added over time. But to get to a really usable / fast level is not too hard. And you don't need to support everything right away, even just x86 is fine to start.
and you'll more than likely end up with something that optimizes way worse
Odin for example or Zig, use LLVM but have their own backends too. You can select which.
LLVM causes them too many pains for maintenance so they want to phase it out eventually.
llvm has the nice idea of having multiple frontends and 1 common representation for the compiler, which solves a ton of platform issues
Yeah, it's unfortunate that the code for LLVM is a huge overly complex template mess in C++.
you don't need to write code gen for N target platforms
And they constantly break API with versions.
Lack of documentation, etc.
It's not developer friendly.
Ideally there is a project like it, but not as much a mess and with documentation. Nobody should have to write the Nth backend.
I suspect it's less of a mess than gcc
Oh yeah, GCC wew.
It has the Stallman complexity touch.
(see emacs)
(generally a bad state of affairs for compilers (also why they are so slow), but that leaves opportunity for improvement and I suspect it will involve either Rust, Odin, D, or Zig)
(decades of hindsight can be applied (hopefully they do))
Does anyone have any good resources for learning data structures and algorithms?
See the pins.
ah I forgot to look, thank you
Hello, can anyone help me with this task
So we have the josephus problem (https://en.wikipedia.org/wiki/Josephus_problem) but a variation of it, i need to find the list of executed individuals. Now I have seen the solution I just don't understand it
reapeat x*a+b while n>0
n is the number of alive people in each round (so for eight it would be :8, 4, 2, 1)
x is the iterator, a is equal to the round to the power of two (so, 2, 4, 8, 16...) and b is equal to b+a (from last round) if n is odd and b-a if n is even
we use a and b to compensate for the space we have to skip
Now I understand a, but I don't understand why is " b is equal to b+a(from last round) if n is odd and b-a if n is even"
Create a new algorithm to make the calculation of Fibonacci numbers more efficient. Include calculation counter variable in your implementation
how do i do this
well, what's your current algorithm?
i was able to do it
i use a list
to keep track of the two numbers
it was recursive before
Prove Prim’s Algorithm using the Loop Invariant technique.
whats the simplest way to explain this
something like this but for prim
I'm trying to make a python script that runs daily automatically (basically a schedule run) but I'm not sure whats the best way to set up a schedule
for the time being I'm planning to just run an infinite loop checking if its a new day (maybe using time) but I'm quite concerned about it crashing in the future so just wondering if there are proper method out there.
what is your operating system ?
windows 10/11
kinda heard about task scheduling tho
yes use that
what property does prim maintain between iterations?
try out celery
hi all, quick and straightforward question:
in CLRS they commonly write in their pseudocode something like: for j=p to r-1: do something
of course, in python one cannot declare a variable in a loop header. so when implementing this, can one simply move that statement to a line above it, eg j = p and then have something like: j = p for j to r-1 ...
or would that change the performance of the function / algorithm?
does it depend on the program/algo in usage or is it a generalized safe conversion to make when implementing pseudocode to python
range(p, r)
so just choose some arbitrary new variable, like for x in range (p,r)?
also see my question regarding if this is a safe conversion to make generally or if it depends on the given situation
j = p
for j in r-1
``` Is not valid Python.
for j in range(p, r): is valid Python.
Whatever pseudo-code is given you need to convert to Python and it's up to you to know if your Python mimics the pseudo-code or not. There is no "safe" conversion if you don't know how Python works or what the pseudo-code's intent is. No simple rules (that cover all cases) can be given as the pseudo-code is not well defined and there would be too many rules.
Stick to "for variable in something" (tuple, list, set, dict, range, etc) and if you can't make that fit, then go with "while condition".
The "variable" part may sometimes be multiple parts / variables separated by commas depending on what comes after the "in".
ok. maybe it'd be more helpful if next time i provide a specific example and can thus learn from that
help
Anyone familiar with few-shot/one shot algo used in Cryo EM? I want to study a github algorithm but having hard time understanding.
Hi Guys, I have little problem with understanding DSA sometimes. Would you like to suggest a good YouTube channel that teach DSA with C++ so I can practice and learn it both way at the same time to improve my coding skill. Thanks.
anyone want to do mock interview leetcode ?
@tacit nova count me in, assuming it is about solving a set of leetcode problems.
hi all,
trying to understand the for loop at line 2 and what is meant by the C[A[j]] statements in line 5
oh it seems as if the for loop in line 2 is simply setting all the values in the new array C to zero?
yeah
same as it would in python C[A[j]] is the element in C at index A[j]
you would write that increment more nicely as C[A[j]] += 1 in python
right right. and i think line 10 could be replaced with for i in range (a.length),1,-1))
still not getting the "the element in C at index A[j]" thing
A[j] is some integer
you can index array C with it
for a in A:
C[a] += 1
```if that helps
ok let me write an example to be sure i understand:
A = [0, 1, 2]
C = [4, 5, 6]
j = 2
then
C[A[j]] = 6
```?
you don't want strings
similarly C[A[j]] = 4 when j=0?
oh thats just improper syntax, nvm that
im just thinking about what it means
C[A[2]] = C[2] = 6 yes
do note that python uses 0 indexing like here, the book does 1 indexing
correct
yes
what about what i said here: #algos-and-data-structs message
.. is that correct?
kinda, for 0 indexing it's range(len(A)-1, -1, -1) which is painful to write
nicer: reversed(range(len(A)))
ok
hmm counting sort is giving me trouble. the other algos have been pretty straightforward
lines 1-6 should be straightforward
i was gonna skip but i need to understand it to understand radixsort
I wouldn't write a counting sort for integers like they do it here though on 7-12
did i tell you one of the problems in the course im auditing is implementing a DTM.. woof
do you understand what lines 1-6 does?
lms
like, the idea of counting sort is very simple, e.g.
[3, 1, 4, 1]
I have 0 zeroes, 2 ones, 0 twos, 1 three and 1 four, so
[1, 1, 3, 4]
ahh i think i see it. they are just binning the number of elements of value x, and saying essentially "i have x index i's"
they are counting the number of occurences, yes
at least, i can read it that way when analyzing their figure
lines 7 onwards does some extra complications so they in the end can copy elements from A to the output
for integers this is pretty overkill
the output in this case is array B
they use 3 arrays, A B and C
C is the temporary working array
an array of counts, yes
ok i see it now
i also recently learned some graph theory and the graph coloring problem and that is super interesting
the number of different problems you can solve with that as a model
if you don't care about copying from A you could write line 7 onward as just
res = []
for i, c in enumerate(C):
for _ in range(c):
res.append(i)
```or even
```py
res = []
for i, c in enumerate(C):
res += [i]*c
what they to is to compute where each group of integers start by doing a cumulative sum
e.g.
[3, 2, 1, 2]
C = [0, 1, 2, 1]
cumulative sum of C to get
[1, 1, 2, 4, 5]
[1, 2, 2, 3]
^ ^ ^ ^
1 2 4 5
the start of every group (except the last element which is the index just outside the array)
that info can then be used to copy elements over from A
which lines do the computation you mention
but it's kinda awkward
line 7-9 is the cumulative sum, though I see now they do a slightly different cumulative sum
they don't make it one larger
so ignore the first number in my 5 element array
actually, them not using zero indexing is pretty awkward here
right bc in the figure i posted they use 0 indexing for 1 array and not the other (where they use 1 indexing)
they compute cumulative sum [0, 1, 3, 4] in my case, which makes a lot of sense if you zero index
that part doesn't matter that much
it's just that cumulative counts translate to 0 indexing
wait...
oh, they think of it as the ends of each group
not the start
so it makes sense with 1 indexing
so...this
[1, 2, 2, 3]
^ ^ ^ ^
0 1 3 4
index 1 is the last 1
index 3 is the last 2
index 4 is the last 3
then they go backwards through A and copy values over into the groups, starting from the end of each group
i'm trying to trace lines 10-12 given the figure and i can't see how it works from the end
a.length = 8
A[8] = 3
C[3] = 7
B[7] = A[8] = 3 i see it
man is that involved jeez
so thats line 11
lms if i can do 12
the copying process goes backwards in A and backwards in each group of digits
[3, 2, 1, 2] [-, -, -, -]
[3, 2, 1, -] [-, -, 2, -]
[3, 2, -, -] [1, -, 2, -]
[3, -, -, -] [1, 2, 2, -]
[-, -, -, -] [1, 2, 2, 3]
```like this, if this makes sense
no i don't see how line 12 runs
🤔
line 10 starts with j = 8
so line 11 makes sense
but 12??
C kinda marks the end of the groups
[-, -, -, -]
^ ^ ^
1s 2s 3s
it picks the last element of A, which is a 2 in my example, and puts it at the 2s marker
(that's line 11)
[-, -, 2, -]
^ ^ ^
1s 2s 3s
it then moves the marker back 1
(that's line 12)
ok, how does 0 get placed in output array B in figure (d)
[-, -, 2, -]
^ ^ ^
1s 2s 3s
its no longer enumerating instances of a given value its now placing them into output array B in sorted order
in their example a 0s marker would be at index 2
insert a zero there
move marker back one step
so that it now points at index 1
(where the other zero will later go)
like according to C in (c)?
oh no
thats a 4 at index 2
the C you have in figure (b) onward
this is all so that you can copy elements over
if you just deal with integers this is overkill
as I mentioned earlier
how do you mean
a 2 is as good as any other 2, right? the process here makes sure it's the same 2 that gets moved over
it makes sense if what you deal with is actually objects that has some integer value attached
in that case you really want to copy/move objects over
yeah this is one thing i've been wondering about, like in all these algos we learn they essentially all just sort integers, but like in real world applications you'd be sorting records of some sort or metadata or customer logins or whatever so how does the implementation change
also when would you actually need to sort giant datasets of just integers
if it's just looking up a customer record (by number) it shouldn't matter if its sorted? or it does to be able to find it?
for counting sort and radix sort and similar you need to be able to translate your object into some integer for sorting
for an integer it's just itself
for a Person class it might have some property like age you want to sort by
it's the latter case where you have to be careful and copy stuff over like in the code here
because people with the same age isn't just interchangable, they have other stuff attached
integers on the other hand are interchangable, this 2 is as good as the other 2
but this code handles the more general case where stuff isn't just interchangable
as for comparison based sorting, there it doesn't really matter if you work with integers or not, you just need to be able to check if one element is less than another, so those generalize easily
so but things must be sorted in order to find a search value in an array, otherwise no search algo can function efficiently*, because its searching for an integer indexed record (or integer record) given an integer input
and if the data isn't sorted, it'll take worst case runtime, having to check each element in the array with the search term
which would happen every time that the search term isn't actually in the dataset
is that right? so in essence there is a lot of time spent sorting so that searches can be efficient
i'm answering the sort of basic theory question like "why do we care about sorting so much"
in part because searching yes
sort once search a bunch
there are also applications where doing things in sorted order is important
because doing things in that orders can give some guarantees
e.g. minimum spanning tree algorithms like Kruskal's algorithm
i understand that heaps can be used to create priority queues
yeah, yet another case where sorted order is important
Anyone here use AlgoExpert or Leetcode? If so if say the name of teh question talks about a data structure like BST I haven't looked at in a while, would it be "cheating" to review it prior to solving the problem? Or is the question looks like it needs an algorithm I forgot about so I review prior to tackling the problem? Just want to mitigate time wasters.
Hello, can anyone here help me with LaPlace method for calculating the determinant of a matrix?
i can help
when you get a matrix which order is 5 or more, it gets a huge ramification of cofactors and stuff, right?
yes, expansion is pretty large, but you can use a recursive function
because you will eliminate the line and column from each number of the chosen line/column and a matrix of order 1 number smaller would remain for calculating cofactors
yeah, but I don't know how to do that
i would start with a minor function that gives you the matrix with row i, column j removed
can you generalize it for any matrix?
Solving reversing a String using recursion where is my code going wrong:
class Solution:
def recursive_swap(string, left, right):
if right < left:
return string
string[left], string[right] = string[right], string[left]
self.recursive_swap(string, left + 1, right - 1)
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
left = 0
right = len(s) -1
recursive_swap(s, left, right)
matrix have to be square and numbers integers
yes, but can your minor function take any size matrix
don't know if I got your question. One function is for matrix of size 3x3 and the other for 4x4
yes, i'm saying make a function for any size matrix
that's what I have to do now and don't know how
you can't even do a function that creates a minor from a given i, j ?
I've thought about making a variable number of for loops
you only need two loops
sorry, what do you mean by "minor"?
really?
the minor (i, j) of a matrix, is the matrix with the ith row and jth column removed
once you have a function that creates a minor, you can start to piece together a determinant function
oh, sorry, I was referring to it as "cofactor", I didn't know it was called minor
makes sense
it's not a cofactor --- cofactor is +/- the determinant of a minor
but we need the minor first
if it's easy for you, I'd like to see
def minor(matrix, i, j):
return [
[_ for _, _ in enumerate(_) if _ != j]
for _, _ in enumerate(_) if _ != i
]
we just need to fill in the blanks here
this assumes you've seen list comprehensions and enumerate, if not i can rewrite this as a normal loop
and change j and i for sliced lists, right?
no, i and j are just integers
yep
but we are going to use only the ones from the chosen line/column, right?
yep
but we don't worry about that yet, we just make a general minor function that works for everything
ok
once you've written this function, you can create a sort-of one-line function for cofactor and determinant
the cofactor and determinant functions will refer to each other, but are basically just the math definitions put into python
then we would be breaking the problem into smaller things, that's nice
because I haven't defined functions for determinant, cofactors and minors
I'm just kinda confused on filling the blanks in minor function
ok, we first want to loop over the rows of the matrix -- this is the outer-loop, i'll fill this one in:
def minor(matrix, i, j):
return [
[_ for _, _ in enumerate(_) if _ != j]
for n, row in enumerate(matrix) if _ != i
]
so we want to include every row except the ith row --- do you see how to fill in the conditional at the bottom?
that's gonna be for each entry in the row -- the inner loop is over items in the row
you can test your function in the interpreter and make sure it works:
In [2]: my_matrix = [
...: [1, 2, 3],
...: [4, 5, 6],
...: [7, 8, 9],
...: ]
In [3]: minor(my_matrix, 0, 0)
Out[3]: [[5, 6], [8, 9]]
In [4]: minor(my_matrix, 0, 1)
Out[4]: [[4, 6], [7, 9]]
so it's returning each line of the minor
the way I was doing was an entire list with the elements
like: M = [1, 2, 3, 4, 5, 6, 7, 8, 9] for a 3x3 matrix
i see, i'm using a list of lists
!e also makes indexing the matrix more convenient:
my_matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]
print(my_matrix[0][0], my_matrix[1][1])
@stable pecan :white_check_mark: Your eval job has completed with return code 0.
1 5
I see
makes sense
def fourth_order(lst):
if len(lst) == 16:
n_order_matrix = list(lst)
#cofactors
results = dict()
for i, ele in enumerate(n_order_matrix[:4]):
del (n_order_matrix[i::4])
a_set = set(n_order_matrix)
n_order_matrix = list(lst)
del (n_order_matrix[:4])
b_set = set(n_order_matrix)
n_order_matrix = list(lst)
results[ele] = -1 ** (i + 2) * third_order(list(a_set.intersection(b_set)))
#determinant
determinant = 0
for key, value in results.items():
determinant += key * value
return determinant
else:
raise ValueError
now I see how easier it would be if I had done your way
you often don't want to modify arguments you pass into functions, better to create new lists
I thought I had copied lst that way
but if you break everything down into minors, cofactors, and finally determinants, you'll have about as much code as you wrote above, but it will handle arbitrary sized matrices
oh, you did, i didn't see
that's right
do you think I can keep these two functions (3x3 and 4x4) I've already written for making the process a bit faster when the passed matrix is already 3x3 or 4x4?
you could keep them, but the more general function will probably be just as fast if not faster
np
What is considered the standard way to overload functions in Python? I know it used to not be a thing but is doable now
I'm seeing all sorts of different implementations, such as:
- the naïve method of doing
if type(x) == stror the like for each argument - Using the
functools.singledispatchmodule and registering alternative versions of a given function based on argument type (but this is limited to single argument functions) - using
metaclass=OverloadMetain your class declaration, but this only applies to classes AFAIK - Using 3rd party packages like
overloadto handle this for you
But I'm not sure if there's a proper standard library way of doing this
I would go for "don't do it" but that's just me
overload sets that do significantly different stuff per type seems like a bad idea
Does anyone know a python solution for this task https://cses.fi/problemset/task/2163 ? If so can they explain it to me?
Im new to data structs. In a hash table how can I avoid collisions
you can't
there are mitigation strategies, though, like chaining or open addressing
So thereis not a way, only ways to make it less likely to happen
Thx, ill do some research and learn bout them
they're already highly unlikely with a proper hash algorithm. chaining and open addressing are for when collisions do happen
Yeah. I imagine a way would be to create a list for each index and store collided pairs in this list
yep, that is indeed a way. it's called "chaining"
Alright. Thank you
I was more so thinking that it would reduce the number of if type(arg) is X calls within a function, and it would let you annotate argument types for each of the different overloaded function definitions
why not just write different function if you're doing different things with it?
also this isn't an algorithms question, but feel free to ask about it in #python-discussion or open a help channel in #❓|how-to-get-help
hi all. the photo shows the runtime of bucketsort. the theta(n) term is given but the runtime of the bucketsort lines of the program, which contains an insertionsort algo within it, given by the next term. it is a summation because they are indicating the enumeration of the number of calls the algorithm must make to insertion sort, which runs in O of quadratic time (n^2). just making sure i'm reading and understanding this correctly.
Is there an itertoolsy way to turn some iterable (A, B, C, ...) into (A, A, A, B, B, B, C, C, C, ...), i.e. each element is repeated over k times (k = 3 in example)
cc @median dawn 
(x for x in i for _ in range(k))
there's no itertoolsy way
!e
from itertools import *
i= [1,2,3]
print(*chain.from_iterable(zip(*[i]*3)))
print(*(x for x in i for _ in range(3)))```
@runic tinsel :white_check_mark: Your eval job has completed with return code 0.
001 | 1 1 1 2 2 2 3 3 3
002 | 1 1 1 2 2 2 3 3 3
double for comprehension strikes again 
there's itertools.repeat
You could do
sum(map(lambda x: tuple(itertools.repeat(x, 3)), range(10)), start=())
or something
bRuh
just (repeat(i, n) for i in my_iterable)
But that's a generator expression
chain from it
chain.from_iterable(repeat(i, n) for i in my_iterable)
yes
the bucketsort they have is to put ranges in different buckets and then sorting each bucket with insert sort, so you get many smaller quadratic costs, note that it's not O(n²) but O(n_i²), so the size of the ith bucket squared
This is cool though
tuple(itertools.chain.from_iterable(map(lambda x: itertools.repeat(x, 3), range(10))))
itertools.chain.from_iterable is like using sum except it's less hacky and better in every other way
at what point do you just give up write the neat readable generator expression?
Idk I was just trying to find a solution
In [1]: from itertools import chain, repeat
In [2]: my_list = [1, 2, 3, 4, 5]
In [3]: def repeater(iterable, n):
...: return chain.from_iterable(repeat(i, n) for i in iterable)
In [4]: list(repeater(my_list, 3))
Out[4]: [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5]
!d itertools.starmap is a cool idea
itertools.starmap(function, iterable)```
Make an iterator that computes the function using arguments obtained from the iterable. Used instead of [`map()`](https://docs.python.org/3/library/functions.html#map "map") when argument parameters are already grouped in tuples from a single iterable (the data has been “pre-zipped”). The difference between [`map()`](https://docs.python.org/3/library/functions.html#map "map") and [`starmap()`](https://docs.python.org/3/library/itertools.html#itertools.starmap "itertools.starmap") parallels the distinction between `function(a,b)` and `function(*c)`. Roughly equivalent to:
```py
def starmap(function, iterable):
# starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000
for args in iterable:
yield function(*args)
other fun options
def my_repeat(it, k):
for x in it:
yield from [x]*k
but that's less fun :(
(lst[i//k] for i in range(k*len(lst)))
so many silly ways
(x for x in iterable for _ in range(k))
yeah, that's the sensible way that was mentioned a while back
Ye
I just remembered Kronecker nonsense exists
In [1]: import numpy as np
In [2]: np.kron([3, 1, 4, 2], [1] * 3)
Out[2]: array([3, 3, 3, 1, 1, 1, 4, 4, 4, 2, 2, 2])
reminds me of my matlab days
apparently numpy has this function anyway
In [12]: np.repeat([3, 1, 4, 2], 3)
Out[12]: array([3, 3, 3, 1, 1, 1, 4, 4, 4, 2, 2, 2])
Is salt-die online? don't want to ping him but I need his help
i'll ask
!e ```py
def minor(lst, i, j):
return [
[num for pos, num in enumerate(row) if pos != i] for n, row in enumerate(lst) if n != j
]
my_matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
print(minor(my_matrix, 0, 0))
@undone stream :white_check_mark: Your eval job has completed with return code 0.
[[5, 6], [8, 9]]
looks right
I don't know if it's working correctly, since I had trouble completing that
actually, I don't know if the names for the variables are correct. If not, it may confuse me in the future
because I changed a bit that template you did for me yesterday
def minor(matrix, i, j):
return [
[e for m, e in enumerate(row) if m != j]
for n, row in enumerate(matrix) if n != i
]
i use this as my variable names, the names in the inner loop are mostly arbitrary --- i used e for entry
!e you can test it real quick:
def minor(matrix, i, j):
return [
[e for m, e in enumerate(row) if m != j]
for n, row in enumerate(matrix) if n != i
]
my_matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]
for i in range(3):
for j in range(3):
print(minor(my_matrix, i, j))
@stable pecan :white_check_mark: Your eval job has completed with return code 0.
001 | [[5, 6], [8, 9]]
002 | [[4, 6], [7, 9]]
003 | [[4, 5], [7, 8]]
004 | [[2, 3], [8, 9]]
005 | [[1, 3], [7, 9]]
006 | [[1, 2], [7, 8]]
007 | [[2, 3], [5, 6]]
008 | [[1, 3], [4, 6]]
009 | [[1, 2], [4, 5]]
I'd better invert that again I suppose
since it works correctly only when j and i are equal
did you write a cofactor function?
not yet
after our talk yesterday I came back to this project now
I'll start it now
@undone stream :white_check_mark: Your eval job has completed with return code 0.
[[], [], []]
for a cofactor function I'll need a determinant one first, right?
def cofactors(lst):
return [
-1 ** (2 + pos) * minor(lst, 0, pos)
for pos, n in enumerate(lst[0])
]
I did this using minor instead of determinant 😐
will I need a closure with determinant and cofactors functions?
the cofactor and the determinant will both refer to each other, so they'll be mutually recursive, but this isn't exactly right
try something like this:
def cofactor(matrix, i, j):
return <sign of cofactor> * <determinant of some minor>
the determinant function doesn't have to be defined, we'll define it next -- but you can use it as if it was already defined
I used -1 ** (2 + pos) for defining the sign of cofactor. Shouldn't I change only the minor(lst, 0, pos) for the determinant?
like this? ```py
def determinant(mino):
pass
def cofactors(lst):
return [
-1 ** (2 + pos) * determinant(minor(lst))
for pos, n in enumerate(lst[0])
]```
kind of, but try to keep the same function signature -- you shouldn't need a comprehension for this function
ok
def determinant(mino):
pass
def cofactors(lst):
for pos, n in enumerate(lst[0]):
return -1 ** (2 + pos) * determinant(minor(lst))
I didn't get the signature thing
this is closer, but you don't need a loop --- signature means the functions arguments:
note that minor 's arguments are matrix, i, j but you're only passing one argument -- similarly my example cofactor function also has 3 arguments matrix, i, j
you just need to implement this definition
hmm now I see
you're very close though
but that worked as well, doesn't it?
the loop will be in the determinant function
when we get there
cofactor has a simpler definition
right
I got to go now. I'll come back tomorrow and probably will ask for your help again 😅
you can ping me in here if you want
np
Can someone explain to me this solution for this task (here https://cses.fi/problemset/task/2163)
Solution
from collections import deque
from itertools import cycle
SPLIT_SIZE = 1000
n, k = map(int, input().split())
numbers = range(1, n + 1)
splits = cycle(list(numbers[i:i+SPLIT_SIZE]) for i in range(0, n, SPLIT_SIZE))
i = 0
split = next(splits)
res = []
while n:
i = (i + k) % n
while i >= len(split):
i -= len(split)
split = next(splits)
res.append(split.pop(i))
n -= 1
print(' '.join(map(str, res)))```
it makes a sort of circular list, but each node has many people in an array
so large steps are cheap
i don't know if this is better than just using deque as is
it seems that it's worse
from collections import deque
n, k = map(int, input().split())
numbers = deque(range(1, n + 1))
res = []
while n:
numbers.rotate(-k-1)
res.append(numbers.pop())
n -= 1
``` like this seems to run faster
@dark aurora got it?
it avoids using deque, implements an alternative manually, and gets half the speed
so, it makes a circular list and then he can remove any number because it will be the end of a list(?) which makes the pop much faster?
sorry, i have never used deque (so am a bit confused here)
oh, actually not using anything is faster
n = 181923, k = 18900000
"splits" : ~8s
deque: 2.9s
list: 1.6s
that's strange
it will be at the end in the sense that it will be at most 1000 from the end
and if you don't do anything and just pop, that's the fastest way
numbers = list(range(1, n + 1))
i = 0
res = []
while n:
i = (i + k) % n
res.append(numbers.pop(i))
n -= 1
like this
i didn't expect deque to make it worse but i also don't know how it really works
yeah, I mean the solution should be much faster than just a list
???
this is the simple solution
I will look into his solution a bit more, and see what I find
so the splits pass?
but list doesn't
that's what you;re saying?
yes, i can see that
if i run in pypy
the splits benefit the most for some reason
so it's like, splits are better, but the overhead is not worth it (for these constraints or always?), but pypy removes it completely
strange but ok
@dark aurora so it's a circular list of small python lists
" A lot of it is using copypasta SortedList (list-of-lists decomposed over some loading threshold) to account for the lack of stuff like std::map built-in" this is what i found about the solution though I don't understand it maybe you do
maybe that's referring to another problem from this site
no, it is reffering to this specific problem
can you explain why he does this
does what
Il send it
while i >= len(split):
i -= len(split)
split = next(splits)
this is going through the circular list
he makes k steps
by subtracting length of the sublist, and going to the next sublist
why not just if i>=len(split), split = splits[it+i//len(split)] (it = index of curent split)
same man
no ok, that makes sense, i is like "increment", not "index"
i is how many steps you need to make
your splits get shorter, you can't just do arithmetics to figure out the correct split
like
[1,2,3] [4,5,6] [7,8,9]
[1,2,3] [4,5,6] [7,9]
[1,3] [4,5,6] [7,9]
[1,3] [4,5,6] [9]
[1,3] [4,5] [9]
it's really just popping from a list, except you make each pop cost 1000 at most
and you have to do this loop to navigate
and it's worth it somehow
i'm still confused about this (i+k) % n
I don't quite understand that, can you elaborate
it should give you index, not increment 🤔
isn't that pretty straigthforward it just gives you the index of the next step
it's neither
wait il go eat for a few mins
when you do this, your i is an offset into the current slice
it's always the increment
i get it
hard to visualize
so yeah it's index into how your current list looks like
like this
[1,2,3] [4,5,6] [7,8,9] new i; i = 4 (so number 5)
[4,5,6] [7,8,9][1,2,3]; i = 1
[4,6] [7,8,9][1,2,3] (pop) new i; i = 1
[4] [7,8,9][1,2,3] (pop) new i ; i = 4
[7,8,9][1,2,3][4]; i=3
[1,2,3][4] [7,8,9]; i=0
[2,3][4] [7,8,9] (pop)
...
what is an offset?
how did you get i=4 on the fourth one?
I don't understand this sequence really?
@dark aurorawhen it says new i, it comes from nowhere
it's (i + k) % n, unpredictable
i didn;t have a k in mind
aaah I see, i though these sequences were connected
but how does that make the code that much faster?
when it doesn;t say new i, we cycle once and decrease i by the length we just cycled
i don't know why it works, it just looks to me like a middle ground between n one element lists and 1 list length n
whether it's predictably better than both, or it's just somehow optimal on real hardware in pypy, no clue
I see what you mean, do you think we could get similiar results with hashmaps?
is it even possible?
don't know sorry
there's a possibility that it's just how you make a deque, beczuse i tried the built in deque version in pypy and it completely freaks out
like there's an insane slowdown
deque in python is basically a linked list, so yeah it will be super slow
I can imagine a solution using something like a segment tree (or fenwick tree) to keep track of "how many elements are to the left of index i. Then you can ignore removing elements from the list and instead do a range update in the tree
The tree can then be searched to find the index with the kth element
You can get that down to O(n log n)
will try that out , thanks
it's probably a lot more involved than what's necessary, but in my head it should work
ah, some solutions I see around use trees where you can get order statistics
which is what the thing I described basically is, just hackier
V * W * 8 + Y - Z
= (((((V * W) * 8) + Y) - Z))
= ((-(+( * (* V W) 8) Y) Z))
= - + * * V W 8 Y Z
is this the correct way to convert from an infix to prefix?
depends on the precedence of the infixes
hi all i'm reading about 'dynamic sets' in CLRS, how would a dynamic set be implemented in python, like what DS
oh
"the best way to implement a dynamic set depends upon the operations that must be supported."
nvm
how important is to know a binary search tree and what use can I give to it in the day to day?
hey guys pretty new to dsa here: why does this not append to alist
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
empty = []
def rev():
empty.append(head.next)
head = head.next
rev(head)
return empty[0]```
.append(name_of_list)
oh
try that
or maybe head.next is nothing
so it appends nothing
try printing head next
it is something surelyt
they given me head
1 is head
i was under the impression i could .append nodes to a list and use that as the answer but it turns out you cant
I thought head.next gives you 1
this not how append works
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
empty = []
def rev(head):
empty = empty.append(head.next)
head = head.next
rev(head)
return empty
why does this return an empty list?
iunstead ofa list of nodes
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
empty = []
def rev(head):
empty = empty.append(head.next)
head = head.next
rev(head)
return empty
the inner function you defined is never called
so you're defining an empty list, defining a function, and then returning the empty list
ahhhh ok
thanks alot
but by inner do u mean first one?
u cant call rev inside itself right
I think it expects me to return as a liunked list not as a list of nodes
it's pretty rare to use a bst, but you don't want to not know about it when you need to
Variants of the idea are often used. But it depends on what your "day to day" is. For some they can't go a day without running into some kind of tree.
If you are a systems programmer you have probably needed one or more of them at some point: https://en.wikipedia.org/wiki/Completely_Fair_Scheduler
The Completely Fair Scheduler (CFS) is a process scheduler that was merged into the 2.6.23 (October 2007) release of the Linux kernel and is the default scheduler of the tasks of the SCHED_NORMAL class (i.e., tasks that have no real-time execution constraints). It handles CPU resource allocation for executing processes, and aims to maximize over...
It also shows up as part of other data structures.
gemeric bst is rare, bbst is actually useful
This is a sliding window problem, Best Time to Buy and Sell Stock
https://leetcode.com/problems/best-time-to-buy-and-sell-stock
The brute force solution is
class Solution:
def maxProfit(self, prices: List[int]) -> int:
max_profit = 0
for i in range(len(prices) - 1):
for j in range(i + 1, len(prices)):
profit = prices[j] - prices[i]
if profit > max_profit:
max_profit = profit
return max_profit
The loop runs n(n - 1) / 2 times.
How do we get that?
there are 2 loops there
Yep. I know it generalizes to O(N^2). But how do we get the exact total sum?
you said "the loop," runs in.. which loop in the above are you referring to
I believe it means the number of operations
Like if we had 7 elements in the array, we would run operations (7 * 6)/2 times
it can also be solved with Dynamic Programming (State Machine pattern)
i do too much leetcode now i feel 🤢
look at the loops. there's no early exit, so we just need to care about the start and ends of each loop. the outer loop runs len(prices) - 1 times. the inner loop runs len(prices) - i + 1) times, where i is 0, 1, 2, 3, ... len(prices - 1). then just multiply the two
yeah, they're definitely useful, but i think they're still pretty rare to actually need
hello @stable pecan
This is how I left yesterday```py
def determinant(mino):
pass
def cofactors(lst, i, j):
return -1 ** (i + j) * determinant(minor(lst, i, j))
I think cofactor function is all right, now I need to develop determinant() for looping over the matrix, right?
yep, looks correct
Thanks, but I don't think that answers my question on how the number of operations simplifies to n(n - 1) / 2
The outer loop runs n times and the inner loop runs (n - 1) + (n - 2) + (n - 3) ... 1 times. So it should be n(n - 1) + n(n - 2) + n(n - 3) + ... 1
I'm guessing there's a series summation thing that says that simplifies to n(n- 1) / 2
you don't multiply, you just have the inner loop running 0 + 1 + 2 + 3 + ... len(prices - 1) times
for the determinant, there's a base case i'll give you --- without the base case function will error when it tries to take cofactors of a 1x1 matrix:
def determinant(matrix):
if len(matrix) == 1:
return matrix[0][0]
return <laplace expansion>
so that's just an error handling?
for recursive functions, you usually need a way to stop the recursion at some point --- usually with a base case
oh, I see
for 1x1 matrixes we know the determinant is just the element in the matrix, so that can be our base case
no, for 2x2 matrices it will be split into smaller cases!
the minors will be 1x1
yeah
I think I got into the same problem as in the old way I was trying to do before your help: I think I need a variable number of nested loops according to matrix's length, but if it's correct, I don't know exactly how to do it
someone recommended me using itertools lib for that
you only need a single loop, do you have the definition of laplace expansion on hand?
found this
it's like e * [e], right? the sum of each element times its cofactor
so we have (-1)**(i + j) * M_i,j is our cofactor
so we should have something like:
sum( something * cofactor for loop_variables in what_we_loop_over)
we only have to loop over a single row to get our expansion though
i also just realized there's a typo in the cofactor function
def cofactors(lst, i, j):
return (-1) ** (i + j) * determinant(minor(lst, i, j))
put parens around this -1 otherwise it will raise 1 to that power and then negate it
right
i've made this mistake lots of times
sorry, I haven't got how it could work. I think I'm kinda fixed in that lots of loops thought
and what is B_i,j supposed to be?
ok, i'm going to paste the example from wikipedia and we can work it out in python:
so in this case they decided to loop along the first row --- each entry in the first row was multiplied by the cofactor of that entry
in python:
sum(entry * cofactor(entry) for entry in first_row)
so we just have to fix these variables
like I said here, I think. But those -1 and -2 entries don't make sense. Shouldn't they be positive?
B_ij is just the ith, jth entry in B
they took the signs from their cofactors
oh, I see
ok
correct me please: for each entry from the first row, cofactor and determinant functions will refer to each other until it's "not possible"
yep
ooh, that makes a lot of sense now
determinant will call cofactor, cofactor will call determinant, but on smaller determinants
that's incredible
until it reaches the base case
yeah
then I think determinant() is ok now: ```py
def determinant(lst):
if len(lst) == 1:
return lst[0][0]
return sum(entry * cofactor(entry) for entry in lst[0])
not actually
ok, now we just need to fix the arguments to cofactor
the row
thats right
i'll change
return sum(entry * cofactor(entry, 0, pos) for pos, entry in enumerate(lst[0]))
I think this line is conflicting with ```py
if len(lst) == 1:
return lst[0][0]
looks like first argument of cofactor is wrong
(entry is actually given by i,j in our function) but we need to pass the matrix
like this?```py
return sum(entry * cofactor(cofactor(entry, i, j), 0, pos) for pos, entry in enumerate(lst[0]))
return sum(entry * cofactor(lst, 0, pos) for pos, entry in enumerate(lst[0]))
hmm
the 0, pos arguments give the entry pos
i just put cofactor(entry) clues above to not give too much away
I think it's working now
to see if it's correct we can check with a matrix of consecutive numbers, its det will always be 0
!e
def determinant(matrix):
if len(matrix) == 1:
return matrix[0][0]
return sum(e * cofactor(matrix, 0, j) for j, e in enumerate(matrix[0]))
def cofactor(matrix, i, j):
return (-1)**(i + j) * determinant(minor(matrix, i, j))
def minor(matrix, i, j):
return [[e for m, e in enumerate(row) if m != j] for n, row in enumerate(matrix) if n != i]
matrices = (
[
[4, 6],
[3, 8],
],
[
[6, 1, 1],
[4, -2, 5],
[2, 8, 7],
],
)
for matrix in matrices:
print(determinant(matrix))
@stable pecan :white_check_mark: Your eval job has completed with return code 0.
001 | 14
002 | -306
ez pz
it's so nice
this explodes for huge matrices though and will take forever to compute
even though you did most of the job, the point of this project for me was to learn, and I learned so much with your help. That's what matters
but it's still super elegant
I appreciate your patience. Thanks a lot
the super take away is we can almost copy the math definitions verbatim and everything just works!
yeah
the only nuance being the base case
this was very nice
Hey, not sure it this is the best place to ask. I'm following the websockets tutorial bulding a connect 4 game. They have a code snippet to determine if there's a winner on the board, and I'm having very hard time understanding it
@property
def last_player_won(self):
"""
Whether the last move is winning.
"""
b = sum(1 << (8 * column + row) for _, column, row in self.moves[::-2])
return any(b & b >> v & b >> 2 * v & b >> 3 * v for v in [1, 7, 8, 9])
https://websockets.readthedocs.io/en/stable/intro/tutorial1.html#connect4.Connect4.winner
In this tutorial, you’re going to build a web-based Connect Four game. The web removes the constraint of being in the same room for playing a game. Two players can connect over of the Internet, reg...
!e
code
this is pretty esoteric, but they're mapping the location of all checkers in the grid to a 54-bit number -- here's the number when every spot in the grid is filled:
In [28]: from itertools import product
In [29]: moves = product(range(7), range(6))
In [30]: bin(sum(1 << (8 * col + row) for col, row in moves))
Out[30]: '0b111111001111110011111100111111001111110011111100111111'
here's how some other combinations of moves fill out the number:
In [31]: moves = [(6, 5), (6, 4), (6, 3), (6, 2)] # column connect4
In [32]: bin(sum(1 << (8 * col + row) for col, row in moves))
Out[32]: '0b111100000000000000000000000000000000000000000000000000'
In [33]: moves = [(6, 5), (5, 5), (4, 5), (3, 5)] # row connect4
In [34]: bin(sum(1 << (8 * col + row) for col, row in moves))
Out[34]: '0b100000001000000010000000100000000000000000000000000000'
In [35]: moves = [(6, 5), (5, 4), (4, 3), (3, 2)] # diagonal connect4
In [36]: bin(sum(1 << (8 * col + row) for col, row in moves))
Out[36]: '0b100000000100000000100000000100000000000000000000000000'
In [37]: moves = [(0, 5), (1, 4), (2, 3), (3, 2)] # diagonal connect4
In [38]: bin(sum(1 << (8 * col + row) for col, row in moves))
Out[38]: '0b100000010000001000000100000'
so this final line any(b & b >> v & b >> 2 * v & b >> 3 * v for v in [1, 7, 8, 9])
is checking if there's a column connect4 (v = 1), a row connect4 (v = 8), or one of the diagonal connect4's (v = 7 or v = 9)
the >> is shifting this (binary) number that many digits to the left and the & is a bitwise-and
Can you elaborate
I tried using segment trees and dictionaries but my solution got really complicated so I gave up
To explain the basic idea, imagine you have a second array with 0s and 1s depending on if the number is still there in the original array. I start with all ones, and when I remove an element I just turn that 1 to a 0. You can then count how many ones there are to find the kth unset item
In practice we don't want a 0/1 array because counting ones is slow
That's where something like Fenwick trees or segment trees (range query trees) come in. With such trees you can easily compute sums of subarrays
You could also do something similar with range updates and seeing the value at a single point, which is what I wad thinking earlier. Put updating a single element and querying ranges is probably the more straightforward thing
How do I use sums of subarrays to find the kth item
I think i get it, so if we have a num at position n i calculate the range sum from (0, n) which is it's index if we were popping them, because each num not popped has value one
to find the index of the kth item you want the first index i such that the sum up until i is k
naively you could binary search for that i, but that would be O(log(n)²) because each prefix sum costs O(log(n))
you can be a bit more clever and find it by walking down the tree from the root in O(log(n))
but probably correctness is the more important part in the beginning
that should still be enough
I was able to solve it, thanks so much
Why are they checking the heap size in lines 3 and 6
to detect if there is no such child
i.e. if the computed index > heap_size then the index is outside the heap
what's equation 7.5
Thank you so much .. I'll spend more time trying to comprehend! This is pretty hard for me 😰
the one shown right above it in b
ok, it looks scary but it's actually quite straightforward
i definitely can read b and understand what its claiming mathematically
i'm reading in CLRS that hashtables where collisions are resolved by chaining with doubly linked lists can be searched successfully for a search term in theta(1+alpha) where alpha is the load factor, that is, the average number of elements in each linked list.
given the assumption of simple uniform hashing. but i don't see how that could be, i think at least half of all the elements in all the linked lists would have to be searched on average..
is there something im misunderstanding
if you assume simple uniform hashing, each spot is equally likely, so on average, you would need to search the load factor + 1 items, because each spot has load factor items on average
you're forgetting that you only need to search the items in one index of the table
because.. given the search term x its location within the table will be computed by the hash function h(x)?
yes
yes that's what i was missing
now if i could just understand it in the following terms:
which part are you having trouble with?
the entire thing but maybe once i look back at lemma 5.1 and learn the linearity of expectation and look at equation A.1 i can put it all together
linearity of expectation is very simple, it's basically just: "the expected value of the sum of random variables is equal to the sum of the expected values of the random variables"
basically, you transpose the E and the sum
i wonder if they have a definition for the expectation in this book anywhere
i would assume in chapter 5
they do but its not well defined in that it isn't clear how its different than the probability
ah, nevermind, it's in the appendix, C.20
they have the def of expected value of an indicator random variable on pages 118-119
the expected value is basically the "weighted average" of the values the random variable can have
this is different from probability
that's a wide screenshot
clicking open original and then zooming in helps
Value, not probability.
3.5
Yes. To understand that value, roll a die that always lands on six. What is the expected value. Don't even need math for this one, just the natural answer to that.
*Which value do you expect to show up / what do you predict.
so i just made a hypothetical example in which value 1 has probability 0.1, val 2 has prob 0.2, val 3 prob 0.5, val 4 prob 0.1, and val 5 has prob 0.1
that adds up to more than 1 probability
The probabilities of all the possible outcomes need to add up to one, because when you roll the die, it has to be one of the values.
One of the possible outcomes.
nvm the die example, i'll tweak mine to add to 1
so the expected value in my example is 2.9
i'll do it again
no i'm getting 2.9
just the v1p1 + v2p2... + v5*p5
oops, you're right lol
I got 2.9.
ok great thanks
well that's easy for a random variable. in the book they expand on the concept to indicator random variables, expected value of binomial distribution, and geometric distributions
this is important for me to know
in the future i'll be dreaming up ways of how to normalize the expected value of transcripts of gene A in tissue B during condition C
an indicator random variable is just 1 if some event happens, and 0 otherwise
yeah thats where the book misleads you as they define the expected value of an indicator random variable in a very circular way using the probability of some event
pg 119
how is that circular? the expected value of an indicator random variable is very closely tied to the probability of the event happening
Create an indicator variable for rolling a six.
perhaps it isn't what i mean to say is that when learning the expected value, seeing it explained in this manner first doesn't do well to differentiate the concept from probability in the eyes of a beginner (me)
i can see where you'd be confused, considering they're numerically equal
so in the hash table search analysis using doubly linked lists as chains to avoid collision, they let the indicator random variable be the probability that your search term is equal to k_j, what is k_j?
they define it in the paragraph, it's a key
it simply says for keys k_i and k_j
its abundantly clear what k_i is, k_j not so much
welcome
you need two keys for a hash collision, k_j is the other key
is the syllabus still compatible with python now after the updates?
not sure what you mean
are you in a specific course right now?
no, im running a coding and robotics club with my friend for extracurriculars.
he asked me to cofound because i write good emails
also power points
so.. you want to learn python?
this is the algorithms and data structures specific channel, you may want to learn the basics before trying to implement specific algorithms
sorry i didnt sleep well so my english isnt good
ah ok
i thought this was like general lol
I don't feel like reposting the question so imagine I just posted #help-cake message here
do you actually have issues with that case?
yes
I'm working with opencv contours and I have a vertex on the polygon like every pixel pretty much, and I'm running into issues because of that
why would it not hit both segments? 
the vertex is in both segments
yeah
but the issue is that if it hits two like that then it'll always be counted as outside even if it's inside
lin any case, you could rewrite things with dot products if you want to, which might behave better
how would that work
compute the perpendicular pointing into the polygon the for all segments, if the point is on the correct side of all sides it's inside
I think that would only work for convex shapes right?
though I think this only works properly for convex polygons, yeah
yeah that's why I asked about converting to triangles or convex polygons
if it's only the perimeter that's annoying you could handle that as a special case
e.g. if it's within ε of the perimeter it's inside
hm
actually since my fake infinity is so far away I could just offset the y of the endpoint by 1
so that it won't hit any vertices
since all of this is on a pixel grid and is an integer
so binary tree 'depth' is counting from 0 as top to bottom, and 'height' is counting from 0 as bottom to top
i think left-right-root traversal is better for counting the 'height' of a node right ?
and root-left-right traversal is better for 'depth' right ?
Does anyone have a good introductory tutorial for someone that doesn't know anything about dsa/time complexity?
And what math do I need to know beforehand?
for depth you want push an incrementing counter down the tree
for height you want to increment the return value of nodes (and a max over nodes)
so probably what you said, just phrased differently
yes sir, you put it more elegantly, also 'incrementing counter' sounds great for depth
something like this dfs(node.left, depth+1)
what does this mean in python, when you have two variable assignments in a single line:
def add_node(self, value):
if self.head is None:
self.tail = self.head = Node(value)
https://paste.pythondiscord.com/dinomelize
How should i go about adding multiple objectives to a bin packing problem with or tools?
I have a list of items each with a weight, volume, vendor, customer and port. I am easily able to constrain the bins on weight and volume but i want to alter the objective from least ammount of bins to least ammount of cost. Cost for a bin with 1 vendor and 1 customer is lower then a bin with 3 vendors, 3 ports and 3 customers for example.
the rightmost thing is assigned to everything on the left
basically, a = b = c is the same as b=c; a=b
I was thinking to create a model which generates the cost for bins and the objective is minimize cost. But i didnt know if there was a standard way of doing it
wouldn't it be b=c; a=c
thats how i interpret your statement at least
given by "the rightmost thing..."
no since c could be something like [], and both variables get the same reference
yeah, that explanation could be better
ok thanks
can anyone walk me thru a traversal to find deepest leaves sum
its hard to grasp at first
how to make the queue?
Does anyone have a good introductory tutorial for someone that doesn't know anything about dsa/time complexity?
And what math do I need to know beforehand?
I would generally avoid this kind of multi-assignment because it's kind of confusing (I don't want to have to look up more language rules), with not much gain (just 1 less line).
I agree
can you do something funky there through overloading? 
I'm guessing no
actually, I seems like the assignment order is actually
a = c
b = c
though idk if you can detect that in any simple way
other than looking at the bytecode
ok, you can totally detect it
In [10]: a = [1, 2] In [11]: a = a[1] = [42] --------------------------------------------------------------------------- IndexError Traceback (most recent call last) Input In [11], in <module> ----> 1 a = a[1] = [42] IndexError: list assignment index out of range In [12]: a Out[12]: [42]
hey y'all,
i'm sort of struggling to implement functions where they take the array length input as arguments.. wouldn't it have to be precomputed? or how would you write from pseudocode that says something like:
def somefunction(A, p, r):
do function stuff
return A.modified
where r is taken to mean the length of the array
i think we were talking about this before
i'll try A.length as an argument
eh, i can just use it as is until i need to call it recursively
wdym precomputed?
p and r are the beginning and end of the array A
i think to call this you'd have to compute the length of the array beforehand
bc the argument to a function len(array) when you're just passing it the same array as input won't work
in the case of something like binary search the first call would just be smth like
bs(A, 0, len(A))
i think what they're calling for from the pseudocode is assigning the length of the array to a new variable r
idk i'm sort of struggling with how to structure the function definition when the input is the array, the beginning of the array, the end all in the def statement
def somefunction(A, startindex, endindex): like you have is fine 