Тёмный

1 Problem, 24 Programming Languages 

code_report
Подписаться 60 тыс.
Просмотров 373 тыс.
50% 1

A video taking a look at 24 programming language solutions (C, Go, C++, Rust, D, Clojure, Ruby, Elixir, Haskell, Racket, Python, APL, J, BQN, PHP, Scala, Erlang, Typescript, Javascript, Java, Kotlin, Swift, Dart, C#) to one problem.
Solutions on GitHub: github.com/codereport/LeetCod...
ADSP Podcast: adspthepodcast.com/
Array Cast: www.arraycast.com/
Contest: 327
Problem Name: Maximum Count of Positive Integer and Negative Integer
Problem Link: leetcode.com/problems/maximum...
Problem Type: Greedy
Chapters:
0:00 Intro
0:31 Problem Description
1:14 Test Cases & Solution Explanation
1:55 Programming Language Solution Categories
2:59 C Solution
3:22 Go Solution
3:35 PHP Solution
4:09 Python Solution
4:25 Dart, Swift & Erlang Solutions
5:00 Javascript & Typescript Solutions
5:17 Clojure & Racket Solutions
5:56 C#, Elixir & Kotlin Solutions
6:20 Scala & Ruby Solutions
6:51 Java & D Solutions
7:14 Haskell Solution
8:15 C++ Solution 1
10:02 C++ Solution 2
10:24 C++ Solution 3
11:03 Rust Solution 1
11:40 Rust Solution 2
11:57 Rust Solution 3
12:19 J, APL & BQN Solutions
12:42 BQN Explanation
17:15 Best Solution Awards
18:15 Performance Comparison
19:05 Outro
Follow me on Github: github.com/codereport
Follow me on Twitter: / code_report
Follow me on LinkedIn: / codereport

Опубликовано:

 

31 май 2024

Поделиться:

Ссылка:

Скачать:

Готовим ссылку...

Добавить в:

Мой плейлист
Посмотреть позже
Комментарии : 554   
@blt_r
@blt_r Год назад
For your first rust solution you could have used `.iter()` instead of `.into_iter()` to not consume the vec, and not clone it. Like this: fn maximum_count(nums: Vec) -> i32 { std::cmp::max( nums.iter().filter(|&&n| n < 0).count(), nums.iter().filter(|&&n| n > 0).count(), ) as i32 } Also in idiomatic rust this function would have taken `&[i32]` and returned `usize`, but I guess there's nothing I can do about it :(
@Bo15307
@Bo15307 Год назад
Yes you should always use .iter() unless you need mutability and/or want to move the values somewhere else
@tamburine
@tamburine Год назад
I also thought that you can pass nums by reference (borrow it). Plus make it a slice instead of vector, so the solution become more general. fn maximum_count(nums: &[i32]) -> i32 { ...
@code_report
@code_report Год назад
Yea, this is way nicer! I tried using .iter() but clearly didn't set up the lambda correctly. Thanks : )
@albertz0
@albertz0 Год назад
So much more sexy
@Jplaysterraria
@Jplaysterraria Год назад
@@code_report The problem with iter is that you get an extra reference (Iterator), instead of into_iter (Iterator), then in filter you take &Item, which ends up being a double reference (&&T), then you have to either do (|&&n| n < 0) like @blyat did, or (the much uglier imo) (|n| **n < 0) or (|n| n < &&0), so the types match. You can mitigate this by doing .iter().copied() (or .cloned()) to remove the references from .iter(). I'd like to see a .filter() that takes Clone types by value, but I don't think that's allowed in the type system. and it could be a footgun if someone decides to make their 16kiB struct copy. (An example of a real 16kiB struct is the Asahi Linux M1 GPU driver structs, they literally overflow the kernel stack if you try to construct them normally)
@oj0024
@oj0024 Год назад
The performance difference between C++/C and Rust seems to be C++/C using gcc and rust using a llvm backend, if you use clang for C you get almost the same codegen as rust.
@adaskalov
@adaskalov Год назад
Perhaps, but then Swift should be near Rust performance, since it also uses llvm.
@matthewsanetra
@matthewsanetra Год назад
@@adaskalov No, because despite Swift also using LLVM the language still does other abstractions e.g. the ABI boxes
@keremardicli4013
@keremardicli4013 Год назад
Plus for loop is always faster than foreach. So PHP would run faster with a for loop. But it is already very fast thank to C interpreter
@GeorgeFosberry
@GeorgeFosberry Год назад
What about time spent on I/O? I'm not familiar with Leetcode, but assume that input is read from files, as usual. I suspect that the author of this video used for C++ solutions, which is notorious for being very slow by default.
@Klayperson
@Klayperson Год назад
On leetcode, your don't have to do i/o yourself, as the environment calls your function with all the test cases for you. The author of the video only had to include and
@interested_in_everything
@interested_in_everything Год назад
I really like the code transition effects. Very well produced video.
@oantolin
@oantolin Год назад
Conor made a video explaining how he makes these transitions, it's pretty cool: ru-vid.com/video/%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE-Vh3y1ela-_s.html
@raffimolero64
@raffimolero64 Год назад
My only complaint is the framerate. It's otherwise a really clear and beautiful explanation.
@puppergump4117
@puppergump4117 Год назад
Looks like it's all done by a library called Manim.
@h0rst
@h0rst Год назад
I would think the solution in C (and similar solutions with a single for loop) could be even faster once you take into account that the numbers are sorted. Start the loop and count the number of negatives. As soon as you encounter a number that is not negative, stop. We now have the number of negative elements. Next up, count the number of zeroes, and stop as soon as you encounter a positive element. The number of positive elements is now simply equal to the total size minus the number of negative elements minus the number of zeroes. So on average, you only have to loop through half of the input array. Optimized for speed, not for readability/maintainability.
@qqii
@qqii Год назад
You can replicate the C++ std::equal_range manually in C for the best time complexity. Instead of looping to count the number of negatives, you can binary search for the first element that is positive, then count down to the first element that is negative.
@add-iv
@add-iv Год назад
@@qqii counting down makes this worst case O(n) 😉
@qqii
@qqii Год назад
Your right! I translated the "count the number of zeros" from your solution, which is actually O(n) if it's all 0s. That makes the 1 binary search method O(log2(N) + N) So actually ideally you'd do two binary searches, the 2nd with the smaller range (essentially std::lower_bound and std::upper_bound) for O(2 * log2(N)) = O(log2(N)).
@MrAbrazildo
@MrAbrazildo Год назад
@@qqii Better would be to binary search for the 1st non negative, and then, starting by that position, search the first non zero.
@michelderosa2695
@michelderosa2695 Год назад
@h0rst That solution could still be a bit too slow, imagine the array being passed is made up of 3 negative numbers, 1000 0's and 2 positives, it'll still take awhile to go over the array. Instead peek at the values from both ends at once, say using index starting at 0, while barrier is size_of(array)-1, each pass you increment index and decrement barrier.. once index == barrier *or* (num[index] == 0) && (num[barrier] == 0) .. in this scenario you quit the loop after 3 peeks, for the array example I mentioned.
@programmingjobesch7291
@programmingjobesch7291 Год назад
C, PHP, JS, C#, Python, Kotlin and Dart are the best looking/most readable to me for sure.
@MegaEnpassant
@MegaEnpassant Год назад
Scala has prefix max function: Math.max Performant Scala code, similar to Rust: def maximumCount(nums: Array[Int]): Int = { def op(v: (Int, Int), e: Int) = (if (e > 0) v._1 + 1 else v._1, if (e < 0) v._2 + 1 else v._2) val (pos, neg) = nums.foldLeft((0, 0))(op) Math.max(pos, neg) }
@ubhelbr
@ubhelbr Год назад
In PHP you probably forgot to put an opening tag in the beginning so the syntax highlighting is correct and your program will simply output its contents :)
@jesusjar11
@jesusjar11 Год назад
The Kotlin solution could be "improved" by using the `it` keyword which is a implicit name for the parameter of a "single-parameter" lambda so { it < 0 } and { it > 0 } respectively o/
@PavitraGolchha
@PavitraGolchha Год назад
Kotlin looked too good and readable
@U20E0
@U20E0 Год назад
why in the world would they chose “it” of all things
@PavitraGolchha
@PavitraGolchha Год назад
it is because it is :)
@vardhanpatil5222
@vardhanpatil5222 Год назад
Yes, the function would end up as ``` fun maximumCount(nums: IntArray): Int { return maxOf( nums.count { it < 0 }, nums.count { it > 0 }, ) } ``` I just found out that youtube doesn't have a way to enter monospace text.
@U20E0
@U20E0 Год назад
@@vardhanpatil5222 Yep. Unicode has monospace version of the characters of the Latin alphabet and Arabic numerals ( although many fonts render them as something weird ), but not the rest of ASCII.
@vm-seventy
@vm-seventy Год назад
The array programming languages always fascinate me because of how informationally dense they are! They perform operations that other languages require like 5 lines to describe in just 1 line.
@kahnfatman
@kahnfatman 9 месяцев назад
@code_report Could you give me your insights on the trade off between: 1. Finding/Training developers to read/understand/maintain APL/BQN code vs FP vs imperative programming languages 2. Maintainability/Extensibility of the code base I have the feeling that BQNish code is awesome to certain extent but how can I sell this to my tech lead??
@soniablanche5672
@soniablanche5672 Год назад
You have to remember that Big O(n) complexity only matters if the N is big enough, maybe that's why the C++ solution wasn't the fastest, maybe if the array used is large enough you can see the difference.
@SiarheiSiamashka
@SiarheiSiamashka Год назад
As the others already noticed, the binary search C++ solution has O(N) time complexity because the vector is passed not by reference but by value. Creating a copy of the vector ruins performance.
@Adam_le_Zigoto
@Adam_le_Zigoto Год назад
@@SiarheiSiamashka that's why C++ with const correctness should be the fastest, or same to Rust
@kolyan199816
@kolyan199816 Год назад
Nope. The caller can put nums by rvalue: maximumCount(std::move(nums))
@khatdubell
@khatdubell Год назад
@@kolyan199816 "Can" doesn't guarantee "does". But even without that, I suspect the C++ solution would still be slow. This is a list of 2000 ints. 2k elements of 4 bytes. 8kb. Easily fits inside a l1 cache. The predictability of going linearly through the array is going to outperform the random access required to do a binary search on the array (which is what equal range does under the hood) This is why its important to know your data and your hardware to pick correct algorithms. Ofcourse the only way to know for sure is to measure both and see.
@puppergump4117
@puppergump4117 Год назад
@@khatdubell I feel like they butchered the c++ solutions. There's no need to try to use every single stl function for a single problem. The simpler your code is, like in the c solution, the better it can be optimized.
@FrankieTheKneeMan
@FrankieTheKneeMan 6 месяцев назад
Your comment about excessive duplication on the haskell solution got me thinking, and actually, you can reduce repitition a _lot_ in haskell with some creative use of partition (from Data.List), filter, and uncurry: maximumCount = uncurry (on max length) . partition (
@dashnone
@dashnone Год назад
with Python you need not put the comprehension into a list and pass it to `len`; you can just sum the comprehension: def maximumCount(self, nums: List[int]) -> int: return max(sum(x < 0 for x in nums), sum(x > 0 for x in nums))
@xslvrxslwt
@xslvrxslwt Год назад
yes, and that's why it's slower seventy five times than C.
@andyl.5998
@andyl.5998 Год назад
@@xslvrxslwt Yes, python is slower. But it's slower for other reasons, not because of the stylish preference of the commenter.
@noomade
@noomade Год назад
xslvrxslwt The style is not the issue, for example the haskell version provided can be written maximumCount = (on max length . filter (>0)) (filter (
@aragonnetje
@aragonnetje Год назад
personally i'd prefer keeping the iterators shorter, to save work on the sum, like this: def maximumCount(self, nums: List[int]) -> int: return max(sum(1 for x in nums if x < 0), sum(1 for x in nums if x > 0)) slight difference in preference, but adding up a list of zeroes at the end is something i don't like. not that the performance difference is likely to be noticable
@ihve
@ihve Год назад
@@aragonnetje your solution is equivalent to the other one, because the booleans will just be implicitly converted to integer when applying the sum function.
@rubenverg
@rubenverg Год назад
Scala: x.filter(_ != 0).groupBy(_.sign).values.map(_.size).max
@Jebusankel
@Jebusankel Год назад
When I started I thought groupMapReduce would do this more elegantly, but really it's more cryptic nums.groupMapReduce(_.sign)(_ => 1)(_ + _).values.max The docs say groupMapReduce is more efficient. I didn't know about _.sign. Thanks for that.
@rubenverg
@rubenverg Год назад
@@Jebusankel looks a bit better with a K combinator: nums.groupMapReduce(_.sign)(const(1))(_ + _).values.max
@rubenverg
@rubenverg Год назад
@@Jebusankel but yeah, it's slightly less clear in what it's doing, especially because gmr isn't really common either
@spencerwhite3400
@spencerwhite3400 Год назад
Hate to be that guy, but you don't need `.clone()` in the rust solution if you use `.iter()` (by reference) instead of `.into_iter()` (by value). Also, the std library provides a `.partition_point()` method on slices, so you could've done the solution in O(log n) just like the cpp solution. Also, you could've parallelized the solution because Rust™ guarantees™fearless concurrency™.
@gabrielcastilho4168
@gabrielcastilho4168 Год назад
That .clone() was so annoying to watch haha
@5FT6MAN
@5FT6MAN Год назад
Wouldnt this increase the space complexity tho brother?
@what42pizza
@what42pizza Год назад
I've got good news and bad news. The good news is that I've made a multithreaded version! The bad news is that it's terrible. (and I'm not sure if I'll be able to give a link)
@what42pizza
@what42pizza Год назад
The PB link id is XtSyyU53
@what42pizza
@what42pizza Год назад
Actually I was able to make a much better version using rayon (PB id 73k7yP4X)
@davidkatz1017
@davidkatz1017 Год назад
Hi Connor, great video as always. Just a note that in D you only need one cast (from result of `max`) because `max` is a template and will return the common type of its two arguments.
@terrydaniel9045
@terrydaniel9045 Год назад
Here is a fun Julia solution: If nums is the given vector then sol = max(sum(0 .nums))
@Player_X_YT2
@Player_X_YT2 Год назад
4:14 You're iterating twice through the array, you can do what you did in php or you can do this for a more efficient time: neg = 0 for i, n in enumerate(nums): if n0: return max(neg, len(nums)-i) return neg
@TerjeMathisen
@TerjeMathisen Год назад
BTW, you can also solve this with SIMD vector ops, processing 8 32-bit ints in each iteration (Just pad the array with enough zero values to make it a multiple of 8 in length!) load 8 ints, compare for greater with an an array of 8 zeroes, generating 0/-1 mask values, then do the same except for less than zero. Use two accumulator arrays, one for positive and one for negative values, just remember to subtract each new value. At the end we make horizontal sums across the pair of 8 individual accumulators and take the global max. This is just 5 AVX ops per 8 ints, so it will run in less than a clock cycle per entry.
@gshan994
@gshan994 Год назад
How to code it bdw
@TerjeMathisen
@TerjeMathisen Год назад
@@gshan994 Programming in the comment box will probably be buggy. :.(
@TerjeMathisen
@TerjeMathisen Год назад
The loop will look like this while (len >= 8) { _m256i curr = __mm256_lddqu_si256(*inp256++); _m256i posmask = _mm256_cmpgt_epi32(curr, zero256); _m256i negmask = _mm256_cmplt_epi32(*curr, zero256); posacc = _mm256_sub_epi32(posacc, posmask); negacc = _mm256_sub_epi32(negacc, negmask); len -= 8; } So one load from memory, two compares to generate the masks and two subs to update the accumulators!
@gshan994
@gshan994 Год назад
@@TerjeMathisen looks cool 😎
@tanveerhasan2382
@tanveerhasan2382 Год назад
Impressive, very nice
@alxjones
@alxjones Год назад
In Kotlin, lambdas with one parameter can use `it` as a default name. So instead of `e -> e < 0`, you can just do `it < 0`.
@awwastor
@awwastor Год назад
I assume they gave the JVM heat up time and didn’t measure it’s start up, in which case it makes sense that it’s quite fast, because it likely only used the allocation it made while starting up and acted basically as a bump allocator, never actually freeing memory or running the garbage collector (maybe a peek at the memory usage could reveal some stuff). I’m also willing to believe that whatever Java JIT was used outperformed the GCC optimisations, because Java compilers are extremely good nowadays. The difference between C/C++ and Rust is probably because if I recall correctly GCC is used for c and c++, while rust relies on LLVM which generally generates better machine code
@atiedebee1020
@atiedebee1020 6 месяцев назад
Clang has consistently been slower than GCC for me and leetcode timings are a joke
@halneufmille
@halneufmille Год назад
3 Julia solutions: max(sum(nums .> 0),sum(nums .< 0)) max(count((0), nums)) To avoid using 0, count or nums more than once: maximum((count(c(0), nums) for c ∈ ()))
@miguelraz4156
@miguelraz4156 Год назад
Oh, that's a sweet last solution!
@mjiii
@mjiii Год назад
Or, if you prefer the O(log n) way: function maximum_count(nums) zeros = searchsorted(nums, 0) negatives = firstindex(nums) : zeros.start - 1 positives = zeros.stop + 1 : lastindex(nums) maximum(length, (negatives, positives)) end
@Jebusankel
@Jebusankel Год назад
Java can be done with one pass over the data Collections.max(Arrays.stream(nums).boxed() .collect(Collectors.partitioningBy(n -> n > 0, Collectors.counting())).values()); Scala can take the same approach using groupMapReduce. group-by for Clojure.
@nERVEcenter117
@nERVEcenter117 Год назад
Sad for D right here, if we could see performance metrics it'd be right there with Java and Rust. I loved using it so much.
@user-hr1fr5xs4p
@user-hr1fr5xs4p 7 месяцев назад
Haskell analog for BQN program: f xs = on max g () where g p = length $ filter (p 0) xs
@japedr
@japedr Год назад
In the C solutions you can take advantage of the implicit cast to write: pos += (nums[i] > 0); neg += (nums[i] < 0); This is probably what you want to do in x86 assembly to avoid branches (but perhaps the compiler can come up with a crazy smarter solution).
@bigboysteen7638
@bigboysteen7638 Год назад
compilers already those obvious branchless optimisations by default, or use conditional operations (cmov, etc), readability > blind optimization
@user-gr5ec2tf5s
@user-gr5ec2tf5s Год назад
@@bigboysteen7638 Readability can be improved by comment section
@pdr.
@pdr. Год назад
Because it's pre-sorted, it's slightly faster in Haskell to use takeWhile, dropWhile and/or span: mc xs = (max `on` length) neg pos where (neg, nonneg) = span (
@chaddaifouche536
@chaddaifouche536 Год назад
Right, but I think the main improvement in your solution is to use `on` as infix, that just read much more naturally! ;-)
@qqii
@qqii Год назад
@@chaddaifouche536 Although it's elegant and probably doesn't make a difference for smaller and unsorted inputs, just like std::equal_range I find it quite elegant to actually use the sorted property of the list.
@unconv
@unconv Год назад
Had to stop the video and do the PHP version before you started to show the examples. I'm so happy that I figured out the same solution 😄(except I used type declarations, more verbose variable names and ended on a positive note instead of negative 😉) function max_count( array $numbers ): int { $negative_count = 0; $positive_count = 0; foreach( $numbers as $number ) { if( $number < 0 ) { $negative_count++; } elseif( $number > 0 ) { $positive_count++; } } return max( $negative_count, $positive_count ); }
@roerd
@roerd Год назад
A bit weird that there's just a single solution that takes advantage of the input data being sorted. All other solutions actually solve a more general problem than what was being described. binsearch solution in Python: from bisect import bisect_left, bisect_right def maximum_count(nums): a = bisect_left(nums, 0) b = bisect_right(nums, 0, a) return max(a, len(nums) - b)
@10e999
@10e999 Год назад
This video highlights perfectly why I like C: One of the best performance while being trivial to read. Nice video as always ! I hope to see zig as a contender in the future :)
@alexhiatt3374
@alexhiatt3374 Год назад
Yeah, I found the majority of these (except Rust, C#, and Kotlin) to be incredibly confusing. Whereas the C solution is simple, clear, and neck-and-neck with Rust.
@briannormant3622
@briannormant3622 Год назад
This is probably what i love the most about C: because the std is bare one you don't waste time using reduction lambda and whatnot. By design the language will make you implement the simplest and (most of the time) fastest solution. A of that while style being clear and readable (not like APL...). Only gripe about the syntax is function pointers, they look atrocious and need you to take a piece of paper to really understand what it actually mean. Would be simpler with a arrow notation.
@LambOfDemyelination
@LambOfDemyelination Год назад
8:05 I feel like (max `on` length . flip filter xs) (>0) (
@porlando12
@porlando12 Год назад
Amazing video! I'd love to see you include some more data science languages like R and Julia.
@MCRuCr
@MCRuCr 7 месяцев назад
julia> func(arr::Vector{ 0), sum(arr .< 0)) 10 μs with a 2000 element array amazing stuff
@cyclotron007
@cyclotron007 Год назад
Gave this problem to ChatGPT and asked it to solve it in APL. As usual (my experience with CGPT & programming), it got the overall concept right but almost every line contained a silly misstep. But it learnt from its mistakes, ultimately producing a conventionally structured, functional APL solution. I then gave it Hoekstra's APL solution, which it attempted to explain ... but it confused the Over operator with Each, so had to give it the formal definition of Over. Eventually it produced a passable explanation. Getting ChatGPT to explain APL expressions in plain English - therein lies an unexplored opportunity!
@shambhav9534
@shambhav9534 Год назад
I'm mostly fascinated at it's ability to learn on the spot.
@c4tubo
@c4tubo Год назад
Please show us what APL code ChatGPT came up with at each step.
@jomy10-games
@jomy10-games Год назад
For the first Rust solution, do you really need to clone if you would instead use iter instead of into_iter? (It’s been a while since I’ve written Rust though)
@cb6619
@cb6619 Год назад
I feel like I'm missing something here. It seems like you're optimizing for the least amount of redundancy and characters typed in the implementation and being as clever as possible. It would have been quicker, and significantly more readable and maintainable to just use a for loop. Someone who's never seen the piece of code before can look at it and instantly understand what's going on. With super clever solutions like the c++ or bqn one it's gonna take someone a second to understand what's going on. A plain, non exciting solution is going to be easier to write, debug, read, and maintain.
@gabrieldoon
@gabrieldoon Год назад
It seems (to me) like the entire point of the video is to be as clever as possible. It's essentially a showcase of the crazy things these languages can do once you get into the deeper stuff. I don't believe that the narrator would actually advocate for doing this in production code. Code golf is in a similar vein.
@seanthesheep
@seanthesheep 6 месяцев назад
Most of the examples in the video seem idiomatic and straightforward to me, especially for the languages that support functional style. I think you just think they're clever because you're not used to them. A for loop will seem like the solution to everything if you only use a language that forces you to use them
@aczajka74
@aczajka74 6 месяцев назад
Some of the languages don't even have for loops my guy
@ifstatementifstatement2704
@ifstatementifstatement2704 5 месяцев назад
Yeah I don’t get this insistance on using the most obscure implementation possible. We are programming, not writing math. So use the commands of the programming language.
@Axman6
@Axman6 Год назад
The Haskell solution using the foldl package is pretty nice: fold (max prefilter (0) length)
@flowname
@flowname 8 месяцев назад
What's the performance implications of this composed Foldl compared to the hand-written one below? There must be some difference. uncurry max $ foldl' (\acc x -> bimap (+ fromEnum (x > 0)) (+ fromEnum (x < 0)) acc) (0, 0) [-1,-2,-3, 0, 0, 1,2]
@Axman6
@Axman6 8 месяцев назад
@@flowname there’s definitely some overhead to the extra data types needed by , unless the compiler is smart enough to completely remove them. That would be faster but the code is less reusable
@flowname
@flowname 8 месяцев назад
@@Axman6 is it always guaranteed to be a single pass at all times though? Extra allocations are fine as long as it always converts to exactly one pass. I guess it's implied by the package when it mentions streaming in the README, but just in case :)
@Axman6
@Axman6 8 месяцев назад
@@flowname yep, the foldl package defines a type which basically matches the arguments you’d give to the foldl function, and takes care of passing each input to each sub-Fold, and aggregating their intermediate states, and also adding a projection function to get the final answer: data Fold a b = forall s. Fold (s -> a -> s) s (s -> b) (Fold function, initial/current state, projection to final type).
@Instinctive
@Instinctive Год назад
Only once through the list in Haskell: maxCount = uncurry (on max length) . span (
@MCRuCr
@MCRuCr 7 месяцев назад
julia> func(arr::Vector{ 0), sum(arr .< 0)) takes 10 μs with a 2000 element array
@pauhull
@pauhull Год назад
In kotlin instead of writing the lambda as { e -> e < 0 } you could have written it as { it < 0 }
@adambickford8720
@adambickford8720 Год назад
I think a lot of it depends on how you use the language in some cases. For example, I'd likely write it in kotlin to take 1 pass: ``` fun maxCount(nums: Iterable): Int = nums.fold(listOf(0, 0)) { counts, i -> when { i > 0 -> listOf(counts[0], counts[1] + 1) i < 0 -> listOf(counts[0] + 1, counts[1]) else -> counts } } .max() ``` It only takes an Iterable, which is a pretty strong hint to its performance.
@ihve
@ihve Год назад
It is worth mentioning, that in python you also have the option to use map function which you can directly substitute for the list comprehension and a filter function. However, to get the length of it, you need to convert it to a list, but I think it's zero-cost since filters are not copying data.
@BrianWoodruff-Jr
@BrianWoodruff-Jr Год назад
A faster Python solution would be: max(sum(x < 0 for x in nums), sum(x > 0 for x in nums))
@roietbd2992
@roietbd2992 Год назад
@@BrianWoodruff-Jr An even faster Python solution would be max(len([x for x in nums if x < 0]), len([x for x in nums if x > 0]))
@ChimeraGilbert
@ChimeraGilbert Год назад
@@BrianWoodruff-Jr your solution works significantly slower than the one in the video on my machine.
@BrianWoodruff-Jr
@BrianWoodruff-Jr Год назад
@@ChimeraGilbert Interesting. I tried RoieTBD's solution and it was slower on my machine. You are saying my solution is slower on yours. I wonder how much of that is due to what we set "nums" to, how much to which python version we're using (CPython, pypy, etc), and how much to our hardware.
@katrinabryce
@katrinabryce Год назад
Another option in Python is to use Numpy. In my experience, that can be several orders of magnitude faster than list comprehension. Eg on a list with 10 million items I worked on recently, execution time went down from 10 minutes to less than a second, not including io time to get the list into memory.
@11rchitwood
@11rchitwood Год назад
In R: max(sum(x > 0), sum(x < 0))
@RoyRope
@RoyRope 7 месяцев назад
Go recently added the min/max functions to the standard library too, this is now possible due to the recent introduction of generics. ☺ For how much I disliked Python initially, I really love the clean way of solving things like this now.
@georgehelyar
@georgehelyar Год назад
The performance numbers are all a bit meaningless because the solutions are generally optimised for readability instead of speed. For example the languages using max(count(), count()) would run faster if they were rewritten as a for loop, avoiding function calls, only iterating through the list once, etc. You could even sort the list and then use the indexes and the length.
@mhcbon4606
@mhcbon4606 Год назад
most meaningful comment, yet, no plus.... thanks, i could not have said it better. (Although, the list is already sorted, and there is no need to iterate any further than the first value of '1' found, as long as you know count of negative numbers, the count of zeros, it is just some simple math)
@igboman2860
@igboman2860 Год назад
A performant complier should be able to fold and inline these calls
@genejas
@genejas Год назад
what about some bit operations? given that the numbers are stored in 2s complement, you'd only need to check the first bit for the negative numbers. If you then check how many zeroes there are, you'll know how many numbers are positive by subtracting the current count from the total...
@HannesSchmiderer
@HannesSchmiderer Год назад
@@genejas My assembly knowledge is quite old but I don't think that a binary bit operation is much faster than a simple number comparison. The number comparison might actually be as fast as the logical bit operation on many processors. If you need the fastest implementation you probably should just implement binary search which special handling of zeroes in a decent language by yourself.
@genejas
@genejas Год назад
@@HannesSchmiderer fair point, i just assumed they were faster everywhere because they're faster on my most used platform
@captainaxlerod1297
@captainaxlerod1297 Год назад
Thanks for breaking it down and explaining it to us non-mathematically inclined individuals
@mjiii
@mjiii Год назад
Using list comprehension in Python is (memory) inefficient because it builds two new lists. I would write it using sum with generator expressions instead: max(sum(x < 0 for x in nums), sum(x > 0 for x in nums))
@aragonnetje
@aragonnetje Год назад
to prevent some counting up of zeroes in the binary mask, you could also do: max(sum(1 for x in nums if x < 0), sum(1 for x in nums if x > 0))
@flowname
@flowname 8 месяцев назад
@@aragonnetje it still scans twice, and if nums is a stream itself, you'll have to tee it with all the implications of tee
@futuza
@futuza Год назад
The 1st C++ solution can probably be improved if you pass the vector 'nums' by ref (&), instead of copying it. Operating on the vector directly should give a bit of a speed up. It's my 2nd favorite solution though, I just really like C's classical easy to read syntax. Lamda expressions, iterators, while all nice, sometimes make the code harder to read imo. Guess that's why I like C++, you can use whatever works/reads best, including classic C style, or do something more modern.
@kasdejong6425
@kasdejong6425 Год назад
the rust solution also uses clone though, since the value isn’t borrowed. So this would make the rust solution even faster right?
@khatdubell
@khatdubell Год назад
@@kasdejong6425 The rust compiler is exceedingly competent at optimizing code. I say this as someone who is not a fan of the language.
@razvbir
@razvbir Год назад
You can write functional code in php, too
@movax20h
@movax20h 7 месяцев назад
Nice and comprehensive. Nitpics: Erlang does have fold and other reductions primitives in lists module. Also in Python, instead of doing len([....]) with list comprehension, use list generator: len(...) (without square brackets). Result will be the same. Also Python 2 had reduce primitive, but it was removed from core language, but is as a function in itertools or functools package. Also in Erlang, D, and Python, you can easily do single pass over array using fold, and storing data in a tuples. Example in Erlang: Add = fun({A,B},{C,D}) -> {A+C,B+D} end. lists:max(tuple_to_list(lists:foldl(fun(E, Acc) -> Add(Acc, {if E < 0 -> 1; true -> 0 end, if E > 0 -> 1; true -> 0 end}) end, {0,0}, A))). Or if you want to be more fancy: GenericReduce = fun(Map, Agg, Init, List) -> lists:foldl(fun(E, Acc) -> Agg(Map(E), Acc) end, Init, List) end. lists:max(tuple_to_list(GenericReduce(fun(E) -> {if E < 0 -> 1; true -> 0 end, if E > 0 -> 1; true -> 0 end} end, fun({A,B},{C,D}) -> {A+C,B+D} end, {0,0}, A))).
@vikingthedude
@vikingthedude 7 месяцев назад
Can't we implement the "One Reduction" method in many of the languages of the "Two Reductions" section? Like in JS/TS, we could array.reduce() and accumulate the pair, just like in rust
@quelkun
@quelkun 4 месяца назад
Yes, in JS you could write this: Math.max(...nums.reduce(([pos, neg], n) => [pos + (n > 0), neg + (n < 0)], [0,0])) And it would iterate only once
@iCeManMeltingSC2
@iCeManMeltingSC2 Год назад
With clojure you can actually do it with a single reduce, which is actually faster than the solution presented. Like so: (defn maximum-count2 [nums] (apply max (reduce (fn [[neg pos] v] (if (pos? v) [neg (inc pos)] [(inc neg) pos])) [0 0] nums))) Not the most beautiful code, but it does it in a single pass. (bench (maximum-count v)) Evaluation count : 397260 in 60 samples of 6621 calls. Execution time mean : 153.486508 µs Execution time std-deviation : 1.470614 µs Execution time lower quantile : 151.619876 µs ( 2.5%) Execution time upper quantile : 156.210734 µs (97.5%) Overhead used : 2.367798 ns => nil (bench (maximum-count2 v)) Evaluation count : 971880 in 60 samples of 16198 calls. Execution time mean : 62.433205 µs Execution time std-deviation : 540.384065 ns Execution time lower quantile : 61.499199 µs ( 2.5%) Execution time upper quantile : 63.337031 µs (97.5%) Overhead used : 2.367798 ns
@tauraamui
@tauraamui Год назад
In the Go example you did not need the else blocks at all. You could have the two if statements, the first if block would just end with a continue, and the else if could just be a second if. The final else block could have been omitted entirely and just been a single return statement after the final if.
@willyhorizont8672
@willyhorizont8672 Год назад
Subscribed! I love the content!
@qqii
@qqii Год назад
I would have loved to see std::equal_range-equivalent solutions in other languages, as although the problem only states a small input size it would have been most interesting to see how other languages handle operations on sorted lists and taking advantage of the sorted list property.
@0LoneTech
@0LoneTech 5 месяцев назад
Here's one in BQN: (⌈´ 0⊸≍∘≠ |∘- ⍋⟜¯1‿0) For an array sorted in ascending order, find the last places that -1 and 0 would fit. Take the absolute difference from 0 and length of the array respectively, then maximum.
@modolief
@modolief Год назад
Phenomenal. Simply phenomenal.
@Alex-dn7jq
@Alex-dn7jq Год назад
In Rust you don't have to clone the vectors, instead you should use .iter() instead of .into_iter() so that the iteration doesn't consume the vector.
@DoraTheExploder
@DoraTheExploder Год назад
In order for VSCode to highlight PHP syntax you have to start the doc with the proper tag
@joro550
@joro550 Год назад
You probably all ready know that you didn't do the most performant solution in all languages but I found the c# one particularly egregious, with that code you would essentially be iteratring through the list twice (seeing as it's max 2k list then you have the potential of going through 4k items. I ran some benchmarks and your solution was 22,978 ns where as a solution that looks like: public int Span() { var (pos, neg) = (0, 0); var span = CollectionsMarshal.AsSpan(_numbers); for (var i = 0; i < span.Length; i++) { var item = span[i]; if (item > 0) pos++; if (item < 0) neg++; } return Math.Max(pos, neg); } would be 593 ns, which is a HUGE leap in performance
@secahl
@secahl 5 месяцев назад
Very clever RU-vidr. I like it. I Enjoy looking from different dimension, every RU-vidr should know psychology. Create conversations on everyone minds without 'em realising and this was a perfect content. Keep up 'em great work 🙏 Lastly.. keeping 'em rust close to c++ makes you a award winning perfect psychologist.
@user-rr6my1lo2k
@user-rr6my1lo2k Год назад
In julia, you can do one reduction as well: maximumcount(x) = reduce(((post, neg), v) -> (post + (v > 0), neg + (v < 0)), x; init = (0, 0)) |> maximum
@giorgiobarchiesi5003
@giorgiobarchiesi5003 4 месяца назад
Great video, thanks. It gives a limited but extremely significant idea of the different language coding styles. A bit less convincing to me is the performance part. for instance, have you tried to natively compile Dart and C# code? That way you can obtain machine-specific executable code, that I would expect to run much faster, compared to the results shown in the video.
@milesrout
@milesrout 9 месяцев назад
The best solution is the C version. I suspect the Rust version is being optimised out because you have made the input a compile-time constant.
@user-zu4ft8yw9e
@user-zu4ft8yw9e Месяц назад
The snippets do not provide a list of 24 programming languages used to solve problems in the previous context. However, based on the information provided, some common programming languages that are widely used for various purposes include Java, Python, C++, JavaScript, Ruby, PHP, Swift, and many more.
@neuraloutlet
@neuraloutlet Год назад
Python looking real lonely in the list comp section. Here is the similar set-builder solution from SETL, it makes use of the cardinality operator # which I quite enjoy: proc maximumCount(nums); return #[x in nums | x < 0] max #[y in nums | y > 0]; end proc;
@malstream
@malstream 7 месяцев назад
Milliseconds for an array of several elements did not bother the author and he compiled a performance comparison. One of the funniest coding videos in recent times, perhaps it deserves a good analysis.
@aboltus99
@aboltus99 5 месяцев назад
What made you laugh?
@PixelOutlaw
@PixelOutlaw Год назад
You can use the Clojure/Racket solution in Common Lisp but here's a little more flavorful option that only traverses the list once. Those two solutions probably have an implicit double iteration. (loop :for i :in list :when (plusp i) :count i :into e :when (minusp i) :count i :into o :finally (return (max e o)))
@user-zu4ft8yw9e
@user-zu4ft8yw9e Месяц назад
The purpose of the video showcasing 24 programming language solutions is to demonstrate how different programming languages can be used to solve various problems efficiently and effectively. It aims to showcase the versatility and capabilities of each language in solving programming challenges, highlighting the unique features and strengths of each language in the context of problem-solving.
@SiarheiSiamashka
@SiarheiSiamashka Год назад
In D language it's possible to have a single pass fold solution similar to Rust and also a binary search solution similar to C++: int maximum_count_single_pass_fold(const int[] nums) { return nums.fold!("a+(b>0)", "a+(b
@bowildmusic
@bowildmusic 6 месяцев назад
The C program is suboptimal. You can program the same loop without the if statements (either add the Boolean result or use it as an array index for the correct variable to add to). The if cases are slowing down the code.
@ahmadrezadorkhah9574
@ahmadrezadorkhah9574 Год назад
Thanks man, useful information, rust (my favorite language) rocks everywhere
@NikolajLepka
@NikolajLepka Год назад
Note that not all lisps use the question mark convention for predicates. Common Lisp uses the suffix p in Common Lisp, they'd be called plusp and minusp instead of pos? and neg?.
@AvrDusk
@AvrDusk Год назад
Can you do a video comparing the differences between APL and BQN?
@quelkun
@quelkun 4 месяца назад
I'd like to share some Ruby here. First, if you like short code the solution could be written like this: def maximum_count(nums) = [nums.count(&:positive?), nums.count(&:negative?)].max If you like the Kotlin version, you can do exactly the same in Ruby: def maximum_count(nums) = [nums.count{ |e| e < 0 }, nums.count{ |e| e > 0 }].max If you like clever solutions, this one only iterates once over the array: def maximum_count(nums) = nums.reduce([0, 0]) { |(pos, neg), n| [pos + n.clamp(0, 1), neg - n.clamp(-1, 0) ] }.max I chose to stick with the oneliner solution because youtube doesn't have syntax coloration but I would have used the other style in my code... Anyway that was my 2 cents!
@vectoralphaAI
@vectoralphaAI Год назад
Also the C solution is by far the easiest to understand as it's just checking every single value one by one and seeing if they are positive or negative and just counting them. Linear time O(n) runtime and yet still performs far faster 3rd place beyond all those other languages. Just shows how optemized and fast C is as a language for hardware speed.
@stepmi
@stepmi Год назад
Array is sorted, there's no need to check it all. For negatives you start from the beginning and look for first non-negative. Index of that first would be the count. For positives - same, but from the end, and search non-positive. Count would be distance from that to the end index.
@miguelraz4156
@miguelraz4156 Год назад
Another cool video Conor! The Julia solution for the 2 linear algorithms could look like max(count((0), xs)) Keep the videos coming, and hope to see more Julia in the future (or hear about it in the ArrayCast :D)
@code_report
@code_report Год назад
I actually coded Julia as the 25th language but decided 24 (4*6 grid) looked better. 😂 I can came up with: max(sum(xs .< 0), sum(xs .> 0))
@chrisjduplessis
@chrisjduplessis Год назад
For the O(log(n)) solution, you would get something not as pretty: function f(x::Vector{Int64})::Int64 s = searchsorted(x, 0) return max(s.start - 1, length(s) - s.stop) end Would be nice to see a solution that's not prone to an off by one error.
@spacelem
@spacelem Год назад
I tested that against my naive approach of count(xs .< 0), and there were 0 allocations and it took 0.3x as long, so that's a good spot!
@FreeStyleKid777
@FreeStyleKid777 Год назад
what are those hierogliphs at the end? I didn't even know I had those symbols on my keyboard. What am I watching?
@otter502
@otter502 Год назад
I had a cool possible solution (I am new to programming) Since the list is sorted you could use that to your advantage Count the positive values through the list until you reach the end of the list or a value that is ≤0, then count the number of zeros, Then do something like Max ( positive, length - positive - # of zeros) This only works if the list is sorted (If it is sorted in an ascending order then switch negatives with the # of positive values and switch ≤0 with ≥0)
@mikolajwojnicki2169
@mikolajwojnicki2169 Год назад
Hey, as you become more experienced you'll understand the tradeoff between code complexity and performance. Your code would work, but it would be much more complex while only increasing performance by about 0.5. Usually you want to keep the code simple so that others can follow it easily. If speed is very important there are much better algorithms like the binary search or equal_range mentioned in the video.
@del1an
@del1an Год назад
3:24 A trick I use in languages that don't have a ternary operator is: return pos > neg && pos || neg
@jackfitz8969
@jackfitz8969 Год назад
Interesting as always Conor! As a total k/q/shakti noob here's what I came up with: f:{./1#|^(#&x0)} I am almost certain it can be shortened significantly and that I did things a bit too "literally" but I was surprised at how quickly I arrived at a (seemingly) working solution. I think it would've taken me a minute to straighten out in any other language (maybe besides C). It's nice how intuitive k is for problems like this.
@fredesch3158
@fredesch3158 Год назад
Could you explain the bind operator in bqn? I could follow the logic until the bind thing, I just don't understand why you could remove the identity function from the fork after binding the zero.
@0LoneTech
@0LoneTech 5 месяцев назад
(0
@MrEo89
@MrEo89 Год назад
Couldn’t you do it in Julia? It’s popukarity is skyrocketing among all data-intensive fields/sectors. I’d greatly appreciate it if it were a “standing” example language.
@klopt305
@klopt305 Год назад
that bqn solution is gorgeous
@GreenThePear
@GreenThePear Год назад
please make another video like this, I started learning APL because of it
@codingzone4019
@codingzone4019 Год назад
your video is crazy, and I love it.
@s90210h
@s90210h Год назад
24 solutions in BQN and APL would have made me equally happy but this was interesting
@larakayaalp1676
@larakayaalp1676 Год назад
for rust you could do max(nums.iter().filter(i32::is_positive).count(), nums.iter().filter(i32::is_negative).count())
@MrSMGun
@MrSMGun Год назад
You can use lambdas in php so it can end up similar to c#
@alexshirley9531
@alexshirley9531 Год назад
You could've added the Bisect module for Python and done the Equivalent of std::upper/lower_bound
@keatonhatch6213
@keatonhatch6213 Год назад
Oh man that first Rust solution could’ve been so much cleaner. You don’t need into_iter() for this, just iter() so you don’t need to clone. std::cmp::max( nums.iter().filter(|e| **e > 0).count(), nums.iter().filter(|e| **e < 0).count() ) as i32
@drjd2
@drjd2 Год назад
I have many questions about how this tests are actually conducted. Is the input compiled into the same source as the function? If so, compiler optimizations influence the outcome heavily. Also which compile options are used for some of the languages, like c# (native compilation), c++, c, rust (compiler, optimizations), java (which runtime). Also how often where the tests running (to see impact of jit compilation on some languages). You can see at the difference between Java and Kotlin that probably the java compiler optimized most of the code out? Without further knowledge we can't say anything. It might even be that all calculation is already done at compile time by the optimizer (see input above) and the results are worthless for a real life scenerio.
@Johnnydhee
@Johnnydhee Год назад
With all the Scala code I’ve seen in production, 600ms to perform that operation is staggering…
@AntonioZL
@AntonioZL 5 месяцев назад
Python may have a lot of problems, but it's solution to this problem in particular is so freaking elegant.
@manemobiili
@manemobiili Год назад
You're a beast code_report! PS: Go Ruby!
Год назад
This is probably out of scope for this video, but being (sometimes) a performance jerk/nerd I would've placed a couple of edge cases return shortcuts at the beginning of the function. If either first number in the array is positive or the last one is negative we can safely assume the whole array is filled with all positive or negative numbers, then return the given array's length. If both and last numbers are zero, then there aren't any positive nor negative numbers and therefore return 0. If neither or the previous, proceed as usual. This would make a best case scenario O(1) and worst case scenario O(O' + 2) (O' stands for the complexity of the main algorithm in the rest of the function).
@FabrizioRomanogc
@FabrizioRomanogc Год назад
Maybe this has already been said, but you can have O(log(n)) solution in Python too. from bisect import bisect_left, bisect_right def maximumCount(nums): l, r = bisect_left(nums, 0), bisect_right(nums, 0) return max(l, len(nums) - r)
@roietbd2992
@roietbd2992 Год назад
Gold comment, I didn't know of bisect
@frogofwar26
@frogofwar26 Год назад
It sounds like only C++ and Python can have O(log(n)) solution, as if other languages weren't turning-complete. You can implement your own binary search function as long as you have indices and comparator. I actually don't get why only C++ used logarithmic solution...
@Hardcore_Remixer
@Hardcore_Remixer Год назад
The fastest solution was to find the position of first 0 with binary search and then the position of the last 0 with binary search between the first 0 and the end of the array. This way your solution would be in O(log(n)) instead of O(n). Edit: This solution is flawed when there is no 0 in the vector. Read the first 2 comments for the right solution with binary search.
@aintaintaword666
@aintaintaword666 6 месяцев назад
But what if there aren't any zeros at all
@Hardcore_Remixer
@Hardcore_Remixer 6 месяцев назад
@@aintaintaword666 You're right. We'd need to adapt binary search to find the position of the first of the positive number and the position of the last negative number from the vector. I typed a solution for the C variant: #include // The vector and the count of elements int *v, n; // Finds the position of the first positive from a given interval in v // Rerurns n if there is no positive number int binary_search_furst_pos(l, r) { // Non-existent interval if (l > r) return n; // One value interval if (l == r) if (v[l] > 0) return l; else return n; int m = (l + r) / 2; // If there is a positive on position m, then keep looking to the left for the first one if (v[m] > 0) { int aux = binary_search_first_pos(l, m - 1); // If there is no positive to the left, then return the one we found if (aux == n) return m; } // If there is a non-positive integer on position m, then we keep looking to the right else return binary_search_first_pos(m + 1, r); } // Finds the position of the last negative from a given interval in v // Rerurns -1 if there is no negative number int binary_search_last_neg(l, r) { // Non-existent interval if (l > r) return -1; // One value interval if (l == r) if (v[l] < 0) return l; else return -1; int m = (l + r) / 2; // If there is a negative on position m, then keep looking to the right for the last one if (v[m] < 0) { int aux = binary_search_last_neg(m + 1, r); // If there is no negative to the right, then return m if (aux == -1) return m; } // If there is a non-negative integer on position m, then we keep looking to the left else return binary_search_last_neg(l, m - 1); } int main() { { // initialize or read n and v // branches are not required ... } int last_neg = binary_search_last_neg(0, n - 1); int first_pos = binary_search_first_pos(0, n - 1); // Store the counts of negatives and positives int cnt_neg = last_neg + 1; int cnt_pos = n - first_pos; // Get the maximum of the 2 counts int max; if (cnt_pos < cnt_neg) max = cnt_neg; else max = cnt_pos; // Print the maxinum to the console printf("%d ", max); }
@0LoneTech
@0LoneTech 5 месяцев назад
The correct binary search solution is to branch out when finding a 0 to search for both lower and upper bound of the span of 0s, keeping the closest bounds known to be outside rather than restarting from either end. This is what C++ std::equal_range does.
@sophiacristina
@sophiacristina Год назад
Would be cool if you do one of these videos of the series "1 problem, n languages", but using old languages, like Fortran, Basic and etc...
@DerekRoss1958
@DerekRoss1958 Год назад
Here you go: QBASIC version... ------------------------ DEFINT A-Z REDIM A(1 TO 6) LET A(1) = -2: A(2) = -1: A(3) = -1: A(4) = 1: A(5) = 2: A(6) = 3 PRINT maxCount(A()) REDIM A(1 TO 7) LET A(1) = -3: A(2) = -2: A(3) = -1: A(4) = 0: A(5) = 0: A(6) = 1: A(7) = 2 PRINT maxCount(A()) REDIM A(1 TO 4) LET A(1) = 5: A(2) = 20: A(3) = 66: A(4) = 1314 PRINT maxCount(A()) END DEFINT A-Z FUNCTION maxCount (aVector()) DIM dCount(-1 TO 1) FOR J = LBOUND(aVector, 1) TO UBOUND(aVector, 1) LET S = SGN(aVector(J)) LET dCount(S) = dCount(S) + 1 NEXT LET maxCount = dCount(2 * ABS(dCount(-1) < dCount(1)) - 1) END FUNCTION ------------------------ I'll leave the benchmarking and video up to you. 😉
@sophiacristina
@sophiacristina Год назад
​@@DerekRoss1958 Haha, thanks!!! Now you have to record your voice commenting the code for our video! And we also need people to do the same in Cobol, Algol, Fortran, B and etc... :3 Let me guess, you are 40+ and had a Commodore or ZX Spec when kid?
@DerekRoss1958
@DerekRoss1958 Год назад
@@sophiacristina I wish! More like 60+ and I had kids who had a ZX Spec! My first language was actually FORTRAN IV on coding forms. And I have no idea what brand of computer my programs were run on. I sent off the coding forms and got the results back on green-and-white striped paper!
@sophiacristina
@sophiacristina Год назад
@@DerekRoss1958 That is pretty cool. :) I watch videos about old systems and i saw some stuffs around about FORTRAN, but i never messed up with it myself. Pretty interesting to know things were done this way back then. I never though about a programmer far from the computer. 😮 If there was an error or bug in your code, would you have to discover it only later? That looks cool, i hope one day i can touch older computer and see my modern days programming knowledge working on such systems and printing in paper, haha, i really enjoy this theme... :) I think i'm newer than your kids. I used to mess with computer in the mid 90's when i was kid. Using MS-DOS and Win95. I think if i had a ZX i would have at had more inspiration in programming at an early age. But MS-DOS also made me not lay about computer when i grew up. When i was nearly teen, i had heard about Pascal, C and C++, and one uncle i had used to program on C++.
@zappellin2398
@zappellin2398 Год назад
I was actually surprised on how fast PHP was but considering it's close to C I guess it make some sense
@esphilee
@esphilee Год назад
Amazing that you know some many programing language.
@JonRonnenberg
@JonRonnenberg Год назад
Was Haskell missing in the performance chart? And did you show the C# solution?
Далее
The purest coding style, where bugs are near impossible
10:25
Comparing C to machine language
10:02
Просмотров 5 млн
Naming Things in Code
7:25
Просмотров 1,9 млн
how Google writes gorgeous C++
7:40
Просмотров 759 тыс.
Every Programming Language Ever Explained in 15 Minutes
15:29
APL demonstration 1975
28:00
Просмотров 101 тыс.
The Uiua Programming Language Caught Me By Surprise
12:24
The Superpower of C++
7:27
Просмотров 34 тыс.
2D water magic
10:21
Просмотров 392 тыс.