@@tompov227 no wonder you think python is the best, your brain is slow asf to think quantity = quality and cant handle anything besides that 0 structure, slow and dynamically typed language come back here when you know how to allocate and deallocate memory
Correction: windows is a special iterator which can be created over slices and similar types, its'a method on [T], map, rev, take, and sum are present in rust std::iter::Iterator trait, where as counts and sorted come from itertools package's itertools::Itertools trait. The reason it looks like they're the same is because of rust's traits which is basically Inheritance via Interfaces but flipped on it's head, leading to a much nicer system with higher composibility. They are technically, all over the place but, I understand the sentiment.
There are plenty of languages that do that. Many of them go under the umbrella "golfing languages", because they are made to solve common programming problems with as few symbols as possible. So basically any operation you can think of doing to a list has a single symbol. And the same for strings. And the same for numbers. And so on. You eventually have to get creative with which symbols you use.
Each time I try to comprehend languages like BQN, it looks like sorcery and magic spells. I can't even understand how the fancy math symbols and operators appear. Do you have a basic tutorial, by any chance?
btw theres a pretty good tutorial on bqn's page (if you want a beginner friendly apl-like language i recommend uiua tho since you dont need to remember the keyboard combinations)
We just released a video about BQN for a simple I/O command line program--not a sophisticated algorithm like this one--but it does somewhat introduce the language in terms of basic operations, evaluation order, syntax, etc., which you might find of some value: th-cam.com/video/LR26p05dLi4/w-d-xo.html
I wouldn't go so far as to say that "in rust everything exist in the same place", in fact that is one of the criticisms that rust gets depending on what you are working on. It just happens that iterators are a core feature for the language so you have access to these functions, but there are many other things that are only available through third party languages as well, one small example, Rust does not have regex support by default, which most languages do.
regex, log and a couple other crates are maintained by the rust project, they're just not in std because they don't need to be. Adding something to std is a guarantee its signature will _never_ change, so that you can always update the compiler. Iterator is used by for loops, Future is used by async fn, etc std is for actual language features which couldn't be easily imported from elsewhere.
I enjoy these videos but would really like to see an example of BQN (or another APL descendant) used for something a bit less contrived than LeetCode problems.
I never understood the purpose of BQN and other similar languages. Do they have the same capabilities as Rust or Python (web server, GUIs), or are they just constrained to array operations?
They are normally derived from research, and they are in general Turing complete, meaning you could in principle build the same kind of stuff as in other languages. The big difference is that in contrast to something like Python, you won’t even have the basic tooling for building a web server, which means you have a lot of stuff to implement before even starting your project.
For me, the usefulness comes not in any speed or performance as is typical in mainstream languages, but in the way it forces my mind to think about the problem differently. It is like turning an essay into a haiku: you are forced to condense the meaning somewhat, which leads to beauty
I like the concepts of array languages because working with sets of data is an important programming technique, and some elegant and interesting solutions come out of those ideas. I don't particularly agree with the idea that more terse is more better though.
You can use a key function to reverse the (k, v) item pair from Counter.items when sorting. You can use a lambda but I factored it out for clarity. You can then map math.prod across the top n. You may substitute sorted with heapq.nlargest if n is expected to be much smaller than k and k is large. from collections import Counter from heapq import nlargest from math import prod from more_itertools import sliding_window def find_x_sum(nums, k, n): def reverse(p): return p[::-1] return [ sum(map(prod, nlargest(n, Counter(window).items(), key=reverse))) for window in sliding_window(nums, k) ]
map+sum expresses your intent more clearly, in particular that the order of iteration doesn't matter. Here the optimizer should realize that anyway, but eg if your map function had side effects then fold would have to perform them in order, while map+sum is free to insert a .rev or whatever
This is too nice on Rust. You're using sorted from itertools while everything else is a builtin. The standard library only includes the methods that can be implemented without allocating.
Are there any similar languages to BQN et al. that work from left-to-right? After getting into FP, starting at the right and working backwards feels very... backwards. Just look at the Rust solution, doesn't that read so much better (and I'm not talking about words vs symbols)?
Which array language should us mere mortals go to if we can only choose one, my impression from your videos is BQN, but you also seem to like Uiua. Which one should we go for as our first array language?
BQN is my favorite by far. Amazing documentation and it is the best "APL" out there in my opinion. I like Uiua as well but it is a different flavored language - stack + array language.
@code_report I'm always amazed at how you swap between the two (BQN and Uiua), keeping both sets of symbols for the different methods unconfused. Is the Jelly series now finished, did you get all the things you wanted in it done. Kinda liked the fact it used names rather than symbols, thought maybe I could get to grips with array languages more easily using it.
I tried BQN, then uiua - went back to BQN and now sticking with it. Great documentation - just keep at it, learn small chunks at a time and really play around and start by tying to do simple things first.
What is the point of constanly having to compare rust to other languages? Can't it stand on its own legs and be a tool in the tool box as the other languages for us to pick up when we need exactly that ONE feature that attrackts you the most? Does it have to be just one swiss-army language in the tool-box? If so I prefer plain old ANSI-C (and java for OOP).
I actually don't know how to solve this in Uiua. Here is my attempt: uiua.org/pad?src=0_14_0-dev_1__IyBFeHBlcmltZW50YWwhCgojICAgICAgICAgICAgICBUaGUgMiBpcyBoYXJkIGNvZGVkIChub3Qgc3VyZSBob3cgdG8gZml4KQpGaW5kWFN1bSDihpAg4omhKC8r4omhL8OX4oaZMuKHjOKNhuKIteKKgsKw4pa94o2GKeKXqzoKCkZpbmRYU3VtIFsxIDEgMiAyIDMgNCAyIDNdIDYgIyAyCg==
I like how in js and rust you call the functions on the collection instead of the keyword in python. This is something I would love for python4, if they ever make one.
Okay, so your argument is that it's beautiful because each component part of the implementation of the algorithm is a possible function call and they all line up when you use them with method chaining? Personally, I don't think any of the three languages look good there. The Rust solution is far too verbose and I vehemently disagree with that syntax being beautiful. I don't like method chaining in general and BQN looks like line noise far more than Perl ever did. The Python solution is closest to looking good, but it's still garbage. I would show what a more straightforward solution would look like in C, and that would be beautiful, but TH-cam deletes more than half of my comments anyhow and especially those with code samples in them.
Solution in Haskell (definitely not optimal, but I understand this is not the objective here !) : import Data.List (sort, group) topOccurences = reverse . sort . map (\zs -> (length zs, head zs)) . group . sort xsum x = sum . map (\(k,y) -> k*y) . take x . topOccurences sliding k = takeWhile ((== k) . length) . map (take k) . tails findXSums ys k x = map (xsum x) . sliding k $ ys
sliding could be: sliding k = divvy k 1 using divvy from Data.List (hackage.haskell.org/package/split-0.2.5/docs/Data-List-Split.html#v:divvy) I also thought there was a function called "counts" in a library (similar to Rust) but it seems to have disappeared.
Mine is fairly similar (just went to post it and saw yours here). Indeed the biggest issue is no out-of-the-box window function, but various ways to make one of course. As ever, many things are a matter of taste, so not suggesting that everyone will like this, but it's pretty compact at least. import Control.Arrow import Data.List import Data.Ord findXSum :: [Int] -> Int -> Int -> [Int] findXSum nums k x = (sum . take x . map (uncurry (*)) . sortOn Down . map (length &&& head) . group . sort) windows where windows = map (take k) . takeWhile ((>= k) . length) . tails $ nums
@@code_report Indeed, divvy (and all of Data.List.Split) is cool. I did see that and avoided it only because it was yet another library to pull in, and not in one of the core packages either). One of the odd things about Haskell is that nobody (to my knowledge) has yet assembled a nice complete-ish set of combinators for all the basic stuff in one place (and given them a really nice self-consistent naming scheme that is both concise, evocative of function and as 'standard' as possible). Consequently there are a lot of things spread around with different contexts and local naming schemes. It's often easy to create the building blocks oneself of course, but at least some of the point of this video is how Rust was able to source so many of the pieces from one place.
@@LukeEvans0Only two methods (counts/sorted) are from itertools, windows/map/rev/take/sum/collect are in the std. You could even collect:: or something for sorted but I'd just accept the semicolon and use Vec::sort. counts is a couple more lines with fold.
@@asmodeuszdewa7194 I like well-designed and simple languages like Modula-3, Scheme and Forth. I know not many people use these but it is not a popularity contest. Sadly in the industry the worst languages are always more popular.
Extraterrestrial developer compares native language to both Earth's worst and finest languages ❤
"Earth's worst language" that happens to have an order or magnitude more people using it than Earth's "best language" lol
@@tompov227 that's pretty normal.
@@tompov227 no wonder you think python is the best, your brain is slow asf to think quantity = quality and cant handle anything besides that 0 structure, slow and dynamically typed language
come back here when you know how to allocate and deallocate memory
I was studying Egyptian Lettering. But now I decided, I must study BQN.
Unfortunately BQN wasn't on the Rosetta stone
@@BrianMelancon could be on Linear A, don't know yet
@@cryptonative I'm pretty sure that was Uiua. The Minoans were more of stack-based crowd.
@@batlin I don’t think so, they surely didn’t like their languages interpreted!
Correction: windows is a special iterator which can be created over slices and similar types, its'a method on [T], map, rev, take, and sum are present in rust std::iter::Iterator trait, where as counts and sorted come from itertools package's itertools::Itertools trait. The reason it looks like they're the same is because of rust's traits which is basically Inheritance via Interfaces but flipped on it's head, leading to a much nicer system with higher composibility. They are technically, all over the place but, I understand the sentiment.
Thanks! I didn't realize sorted was itertools and I forgot that windows was special.
So someone turned wingdings into a programming language? I've never been so intrigued by something I never want to learn
I was trying to process this video when your comment crystallized my thoughts instantly and perfectly. I can now move on.
There are plenty of languages that do that. Many of them go under the umbrella "golfing languages", because they are made to solve common programming problems with as few symbols as possible. So basically any operation you can think of doing to a list has a single symbol. And the same for strings. And the same for numbers. And so on. You eventually have to get creative with which symbols you use.
@@MasterHigure oh it looks cool as hell. I just prefer not to read hieroglyphics when I code lmao
Rust is just practical
You lost me when you pulled out the twitter operator 😂
Each time I try to comprehend languages like BQN, it looks like sorcery and magic spells. I can't even understand how the fancy math symbols and operators appear. Do you have a basic tutorial, by any chance?
No, that is a good video idea though.
@@code_report i will eat that video up omg
btw theres a pretty good tutorial on bqn's page
(if you want a beginner friendly apl-like language i recommend uiua tho since you dont need to remember the keyboard combinations)
We just released a video about BQN for a simple I/O command line program--not a sophisticated algorithm like this one--but it does somewhat introduce the language in terms of basic operations, evaluation order, syntax, etc., which you might find of some value: th-cam.com/video/LR26p05dLi4/w-d-xo.html
I agree with @@RedstonekPL, Uiua is super beginner friendly and has a great discord for asking questions
I wouldn't go so far as to say that "in rust everything exist in the same place", in fact that is one of the criticisms that rust gets depending on what you are working on. It just happens that iterators are a core feature for the language so you have access to these functions, but there are many other things that are only available through third party languages as well, one small example, Rust does not have regex support by default, which most languages do.
regex, log and a couple other crates are maintained by the rust project, they're just not in std because they don't need to be. Adding something to std is a guarantee its signature will _never_ change, so that you can always update the compiler. Iterator is used by for loops, Future is used by async fn, etc std is for actual language features which couldn't be easily imported from elsewhere.
Great video!
I enjoy these videos but would really like to see an example of BQN (or another APL descendant) used for something a bit less contrived than LeetCode problems.
Please keep reminding us of Rust’s beauty! ❤
Even though BQN fascinates me, I would dread having to maintain something written in it. Nevertheless, excellent video. Well done!
I never understood the purpose of BQN and other similar languages.
Do they have the same capabilities as Rust or Python (web server, GUIs), or are they just constrained to array operations?
They are normally derived from research, and they are in general Turing complete, meaning you could in principle build the same kind of stuff as in other languages.
The big difference is that in contrast to something like Python, you won’t even have the basic tooling for building a web server, which means you have a lot of stuff to implement before even starting your project.
I've been rewriting bash scripts in BQN, so it is quite useful as a general programming language.
For me, the usefulness comes not in any speed or performance as is typical in mainstream languages, but in the way it forces my mind to think about the problem differently. It is like turning an essay into a haiku: you are forced to condense the meaning somewhat, which leads to beauty
It is what you call a "Calculator language". Meant to be used from REPL to perform specific calculations, and then forget about it
@@theondono Turing completeness doesn't tell you if it has networking APIs lol
I like the concepts of array languages because working with sets of data is an important programming technique, and some elegant and interesting solutions come out of those ideas. I don't particularly agree with the idea that more terse is more better though.
You can use a key function to reverse the (k, v) item pair from Counter.items when sorting. You can use a lambda but I factored it out for clarity.
You can then map math.prod across the top n. You may substitute sorted with heapq.nlargest if n is expected to be much smaller than k and k is large.
from collections import Counter
from heapq import nlargest
from math import prod
from more_itertools import sliding_window
def find_x_sum(nums, k, n):
def reverse(p): return p[::-1]
return [
sum(map(prod, nlargest(n, Counter(window).items(), key=reverse)))
for window in sliding_window(nums, k)
]
uh, that python soln can be solved without any library lol, also leetcode doesn't even have much of these libraries
Perhaps a question of taste, the last map(..).sum() for the Rust solution could however have been replaced with a fold(..). Great video as usual!
map+sum expresses your intent more clearly, in particular that the order of iteration doesn't matter. Here the optimizer should realize that anyway, but eg if your map function had side effects then fold would have to perform them in order, while map+sum is free to insert a .rev or whatever
I would love to see you try raku
What is this enchantment table language 😂
Great video 👍🏻
Can you do a BQN video where you attempt to make a neural net
Probably needs more than a single video. Not BQN, but rather APL proper: th-cam.com/play/PLgTqamKi1MS3p-O0QAgjv5vt4NY5OgpiM.html
5:29 lol I love the animation
This is too nice on Rust. You're using sorted from itertools while everything else is a builtin. The standard library only includes the methods that can be implemented without allocating.
Are there any similar languages to BQN et al. that work from left-to-right? After getting into FP, starting at the right and working backwards feels very... backwards. Just look at the Rust solution, doesn't that read so much better (and I'm not talking about words vs symbols)?
Which array language should us mere mortals go to if we can only choose one, my impression from your videos is BQN, but you also seem to like Uiua.
Which one should we go for as our first array language?
BQN is my favorite by far. Amazing documentation and it is the best "APL" out there in my opinion. I like Uiua as well but it is a different flavored language - stack + array language.
@code_report I'm always amazed at how you swap between the two (BQN and Uiua), keeping both sets of symbols for the different methods unconfused.
Is the Jelly series now finished, did you get all the things you wanted in it done.
Kinda liked the fact it used names rather than symbols, thought maybe I could get to grips with array languages more easily using it.
I tried BQN, then uiua - went back to BQN and now sticking with it. Great documentation - just keep at it, learn small chunks at a time and really play around and start by tying to do simple things first.
What is the point of constanly having to compare rust to other languages? Can't it stand on its own legs and be a tool in the tool box as the other languages for us to pick up when we need exactly that ONE feature that attrackts you the most? Does it have to be just one swiss-army language in the tool-box? If so I prefer plain old ANSI-C (and java for OOP).
'beautiful' superquadratic solutions... it could be O(n)...
UIUA solution where?
I actually don't know how to solve this in Uiua. Here is my attempt: uiua.org/pad?src=0_14_0-dev_1__IyBFeHBlcmltZW50YWwhCgojICAgICAgICAgICAgICBUaGUgMiBpcyBoYXJkIGNvZGVkIChub3Qgc3VyZSBob3cgdG8gZml4KQpGaW5kWFN1bSDihpAg4omhKC8r4omhL8OX4oaZMuKHjOKNhuKIteKKgsKw4pa94o2GKeKXqzoKCkZpbmRYU3VtIFsxIDEgMiAyIDMgNCAyIDNdIDYgIyAyCg==
≡(/+××
I like how in js and rust you call the functions on the collection instead of the keyword in python. This is something I would love for python4, if they ever make one.
You mean UFCS? No need to wait for python4, check nim language.
Okay, so your argument is that it's beautiful because each component part of the implementation of the algorithm is a possible function call and they all line up when you use them with method chaining? Personally, I don't think any of the three languages look good there. The Rust solution is far too verbose and I vehemently disagree with that syntax being beautiful. I don't like method chaining in general and BQN looks like line noise far more than Perl ever did. The Python solution is closest to looking good, but it's still garbage. I would show what a more straightforward solution would look like in C, and that would be beautiful, but TH-cam deletes more than half of my comments anyhow and especially those with code samples in them.
Genuine question - is ban as fast as rust? I know python is out of question.
For performance: Rust > BQN > Python
@@code_report Isn't BQN also an interpreted language?
@WillJackDo yes
Ok(())
Solution in Haskell (definitely not optimal, but I understand this is not the objective here !) :
import Data.List (sort, group)
topOccurences = reverse . sort . map (\zs -> (length zs, head zs)) . group . sort
xsum x = sum . map (\(k,y) -> k*y) . take x . topOccurences
sliding k = takeWhile ((== k) . length) . map (take k) . tails
findXSums ys k x = map (xsum x) . sliding k $ ys
sliding could be:
sliding k = divvy k 1
using divvy from Data.List (hackage.haskell.org/package/split-0.2.5/docs/Data-List-Split.html#v:divvy)
I also thought there was a function called "counts" in a library (similar to Rust) but it seems to have disappeared.
Mine is fairly similar (just went to post it and saw yours here). Indeed the biggest issue is no out-of-the-box window function, but various ways to make one of course.
As ever, many things are a matter of taste, so not suggesting that everyone will like this, but it's pretty compact at least.
import Control.Arrow
import Data.List
import Data.Ord
findXSum :: [Int] -> Int -> Int -> [Int]
findXSum nums k x =
(sum . take x . map (uncurry (*)) . sortOn Down . map (length &&& head) . group . sort) windows
where
windows = map (take k) . takeWhile ((>= k) . length) . tails $ nums
@@code_report Indeed, divvy (and all of Data.List.Split) is cool. I did see that and avoided it only because it was yet another library to pull in, and not in one of the core packages either).
One of the odd things about Haskell is that nobody (to my knowledge) has yet assembled a nice complete-ish set of combinators for all the basic stuff in one place (and given them a really nice self-consistent naming scheme that is both concise, evocative of function and as 'standard' as possible). Consequently there are a lot of things spread around with different contexts and local naming schemes. It's often easy to create the building blocks oneself of course, but at least some of the point of this video is how Rust was able to source so many of the pieces from one place.
@@LukeEvans0Only two methods (counts/sorted) are from itertools, windows/map/rev/take/sum/collect are in the std. You could even collect:: or something for sorted but I'd just accept the semicolon and use Vec::sort. counts is a couple more lines with fold.
code in python is piece of s...
Nobody writes like that...
Better use elixir!!!!
Do a doubly linked list in Rust
Why? It's in std::collections::LinkedList already.
Had to look it up because I never use it for some reason... wonder why...
Rust, Python and JS are the worst languages ever lol.
Also happen to some of the most popular languages... So, how about that?
Lol. Rust has been the most loved language for the last couple of years bro 😂
I'm genuinely curious about what languages you like
@@WillJackDo It is not a popularity contest. For example Python and Go are only famous and used a lot because of Google.
@@asmodeuszdewa7194 I like well-designed and simple languages like Modula-3, Scheme and Forth. I know not many people use these but it is not a popularity contest. Sadly in the industry the worst languages are always more popular.
🤮 Please stop constantly reminding everyone of rusts "beauty" 🤮
Kotlin:
fun lc3318(d: List, k: Int, x: Int): List =
d.windowed(k).map{
it.sortedDescending()
.groupingBy{it}
.eachCount()
.toList()
.sortedByDescending{it.second}
.take(x)
.sumOf{it.first*it.second}
}