<isene>
ox1eef_: It's for this use case: An XRPN program is running - then the gem is updated - and the program or user input tells the program to leverage the new functionality in the base - without having to restart the program.
mjacob has quit [Ping timeout: 260 seconds]
mjacob has joined #ruby
caedmon has joined #ruby
markong has quit [Ping timeout: 256 seconds]
FullMetalStacker has quit [Remote host closed the connection]
<weaksauc_>
I do wonder if he's alright. that tweet was three days ago
<bougyman>
1080 is right, 3690 is wrong. It shouldn't matter!
<bougyman>
I mean, it should work for any value passed to #find_start
<weaksauc_>
i don't think your logic is right
<bougyman>
why would it work with 4, then?
<bougyman>
4 chars in seen, break and return count (-1, since it added +1)
<weaksauc_>
beats me? luck?
<bougyman>
No way.
sagax has joined #ruby
<bougyman>
What do you think is wrong with the logic. Mind you I tried this a few different ways (inject, maps, indexes, etc). They all give the same result. 1080 for '4', and 3690 for '14'
<bougyman>
Even did a "get all sequences of long strings, take the first one that's 14"
<bougyman>
hrm wait. Maybe there's a trick and it has to be exactly 14? Like, if it's 15 that's invalid?
<weaksauc_>
ah i see what you are doing now
<weaksauc_>
wouldn't this be much easier using something like each_cons
<bougyman>
Yeah, did that too.
<bougyman>
There's a lot of easier ways. This is the "long form" way.
caedmon has quit [Ping timeout: 252 seconds]
<weaksauc_>
i didn't do this day yet but what is part 2?
<bougyman>
Part 2 is "the character number of the first character after a sequence of 14 different characters"
<bougyman>
They didn't say "exactly 14", but I think that may be what they mean.
caedmon has joined #ruby
aeris has quit [Remote host closed the connection]
caedmon has quit [Ping timeout: 265 seconds]
<weaksauc_>
i just did it real quick and got the right answer
<hays>
is there a ruby equivalent of python -m venv .venv ?
grokify has quit [Remote host closed the connection]
<hays>
goal is to contain gems to $HOME
<adam12>
hays: `bundle install --path` can work if you're installing from a Gemfile. If you're not, there's a --user-install option for `gem install` I believe.
cartdrige has quit [Read error: Connection reset by peer]
cartdrige has joined #ruby
crax23 has joined #ruby
Y05hito__ has joined #ruby
cartdrige has quit [Ping timeout: 260 seconds]
crax23 has quit [Ping timeout: 255 seconds]
teclator has joined #ruby
teclator has quit [Client Quit]
<havenwood>
adam12: This is such very sad news. I'm devastated. :(
_aeris_ is now known as aeris
crax23 has joined #ruby
<ox1eef_>
What sad news?
<ox1eef_>
O wow. May he rest in peace.
Y05hito__ has quit [Ping timeout: 268 seconds]
<ox1eef_>
isene: Okay, in that case you can use: Dir.glob(File.join(Gem.loaded_specs.find { _2.name == "xrpn"}.last.gem_dir, "**/*.rb")) { load(_1) } - or something close to it.
<adam12>
havenwood: I can't believe it :\ It feels very surreal.
<ox1eef_>
Untimely deaths that occur unexpectedly often do. I feel sorry for his family most of all.
crax23 has quit [Read error: Connection reset by peer]
<rapha>
i know there's a way when you have [["15", "Peter"], ["20", "Peter"], [["12", "Mike"]] to turn that into [[35, "Peter"], [12, "Mike"]] in a oneliner. can somebody help me get in the mindset of how to have the right thoughts to be able to pull that off?
<rapha>
my brain is going like "something something .inject something something :+ something" but it's not locking on properly :/
some14u has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<ox1eef_>
With the assumption that arr is: [["15", "Peter"], ["20", "Peter"], ["12", "Mike"]]
<rapha>
ok let me try to pick that apart
<rapha>
so the group_by
<rapha>
that's already wow. no |...|
<ox1eef_>
yeah it is using numbered parameters because those are handy for quick prototyping.
<ox1eef_>
_1 is first block arg, _2 is second block arg, and so on.
<rapha>
ok, equivalent to |x| x[1] then
<ox1eef_>
Yep
cryptkeeper has joined #ruby
<rapha>
ok then the map at the end, that's just handling the names differently from the numbers, totally by hand. looks a little complicated but isn't, actually.
<rapha>
and inside the .sum you would probably have liked to use numbered params again but i'm guessing they don't nest.
<ox1eef_>
That's correct, you can't nest them due to Ruby throwing an error.
<rapha>
yeah i just found out :P
<rapha>
hmm
<rapha>
amazed that it's such a long line
<rapha>
also to get back to my original question: bummed out since you didn't use any method that was new to me. the key was obviously #group_by and the technique of combining it with #values. i've used both in the past, but my brain didn't come up with this idea. but there's probably no "trick" here except for "enough coffee".
idkwtf has joined #ruby
<ox1eef_>
There could be other ways, and most people approach problems in a unique way based on a bunch of factors.
<ox1eef_>
My tip would be make the most of IRB, it can show you when you're getting close and give you immediate feedback that solving it in your mind alone can't.
<rapha>
ah i'm practically living in pry
<rapha>
used to be irb but now the new autocomplete is getting on my nerves
grokify has quit [Remote host closed the connection]
Y05hito__ has joined #ruby
crax23 has quit [Ping timeout: 256 seconds]
Y05hito__ has quit [Ping timeout: 260 seconds]
<weaksauc_>
dammit that's terrible news
<sam113101>
how old was he?
balo_ has quit [Quit: leaving]
balo has joined #ruby
<weaksauc_>
looked to be late 30s or 40s
Inoperable has quit [Ping timeout: 268 seconds]
_ht has joined #ruby
Linux_Kerio has quit [Ping timeout: 246 seconds]
Inoperable has joined #ruby
Doc_X has joined #ruby
<FullMetalStacker>
Heyho guys! I have a challenge to solve which is easy to do but it also includes an performance issue which I have no idea how to do.
<FullMetalStacker>
The task is simple:
<FullMetalStacker>
There is an array with some numbers. All numbers are equal except for one. Try to find it!
<FullMetalStacker>
my current solution is not done but already takes care of the standard case which is that the first 2 numbers in the array are identical, and this already solves almost all test. only 3 test are remaining which I do not pass, which is the case that the outlier number is within the first 2 indexes of the array. and the third is: the performance test with a huge array of thousands of numbers. this one i fail due to timeout. so
<FullMetalStacker>
part of the assignment is to do it in a smart i.e. performant way that does not time out.
<FullMetalStacker>
i have tried out so far
<FullMetalStacker>
arr.delete(arr[0]) if arr[0] == arr[1]
<FullMetalStacker>
arr.join.to_f
<FullMetalStacker>
as well as
<FullMetalStacker>
arr.uniq[1] if arr[0] == arr[1]
<FullMetalStacker>
but both time out. any suggestions/ hints on how to do it in a more performant way?
<FullMetalStacker>
I know how to take care off the case of having the outlier within the first 2 indexes of the array, but i have no idea about how to increase performance.
<FullMetalStacker>
any inspiration / explanation much appreciated, guys!
<leftylink>
well you have a good idea with the first two elements of the array
<leftylink>
either they're the same, in which case the different one is whatever one isn't those, or they're different, in which case it's easy to tell which of the two it is
<FullMetalStacker>
exactly
<FullMetalStacker>
but this approach of mine does not pass the performance test with the huge array. it times out.
<leftylink>
one thing I think it's necessar yto think about is do you think you are looking for a better time with the same asymptotic complexity, or are you looking for something with a better asymptotic complexity. so, you ahve uniq, that's O(n). would it at all be possible to do something in better than O(n)? this would imply looking at not all elements of the array
<FullMetalStacker>
O(n)?
<FullMetalStacker>
can you please elaborate further?
<caleb>
it's big O notation for time complexity
<leftylink>
so I agree with that, but explain about why it has to be O(n)
<leftylink>
if you didn't look at all elements of the array, what could happen?
<FullMetalStacker>
studying the link to wikipedia 0%###_________100%
<Doc_X>
I'm using ruby 3.1 and trying to write a method that takes a sub-command and a variable number of arguments/parameters and runs Open3.popen() based on that. I'm running into an issue with figuring out how to handle the parameters. The method definition is `def runKC(subCmd: nil, interactive: false, params: [])`. If I do a `params.join(' ')`, it treats it as one long string (which, frankly, I kind of
<Doc_X>
expected). Open3.popen2 complains when I pass it ("command", subCmd, params) . . . again, understandably since it's an array of strings, not a string.
<Doc_X>
Looking around, I haven't found a way to turn an array of strings into a sequence of strings that I could use as an argument.... I figure there's gotta be something simple I'm missing. Does anyone know of a good example of this sort of thing they could point me at?
<ox1eef_>
Doc_X: Try call the method with '*params'.
<neshpion>
what if you pass ("command", subCmd, *params)? it unrolls the array but i forget the formal name for that operator
_ht has quit [Quit: _ht]
<ox1eef_>
The splat operator.
<Doc_X>
Thanks, oxleef_ and nesphion... results look promising so far!
<Doc_X>
er... neshpion... doh!
* neshpion
facesplats
Inoperable has quit [Ping timeout: 256 seconds]
grokify has joined #ruby
<ox1eef_>
FullMetalStacker: If you have to iterate the whole array, and don't have any other options, then I would suggest you break the array up into slices, and perform the logic to determine the unique element on a thread for each slice. For example: huge_array.each_slice(10_000) { |slice| { Thread.new { slice.each { .. } } } - you might need a queue to communicate the results, there's the Queue class for
<ox1eef_>
that.
<ox1eef_>
Given that methods written in C (eg uniq) don't perform particularly well in this case, that might be the best option.
<weaksauc_>
FullMetalStacker what's the leetcode thing you are doing?
<FullMetalStacker>
@leftylink @caleb:
<FullMetalStacker>
Ok guys, I got the following so far (or at least: that is what I THINK I understood *LOL*):
<FullMetalStacker>
using uniq or delete span over the entire array and this is something that has O(n) which means: f grows linear with the growth of the array. and now you guys want me to find an alternative approach which is belof O(n) by doing it differently, i.e. by looking only at parts of the array, correct?
<FullMetalStacker>
So far the only idea I have is to iterate through the array and compare 2 neighbors until I find the outlier. But would this improve anything or be a good idea at all? Or is there something different that I could think off?
<ox1eef_>
And keep in mind that Ruby will only run one thread at a time for CPU intensive tasks, and this task sounds purely CPU-bound, so for true parallelism you might want to use fork, and maybe a unix socket to communicate the results.
<weaksauc_>
if it's sorted you can look at first and last element + one more
<weaksauc_>
if it's not sorted you can look at the first element save it and then iterate the list until you've found the outlier
<ox1eef_>
I don't think you can solve this problem without looking at the whole array.
<weaksauc_>
you do have to keep in mind the outlier could be the first element
<ox1eef_>
Not reliably at least.
<leftylink>
if you didn't look at all the elements, the answer could be one of the elements you arne't looking for, so you absolutely must look at all the elements
<leftylink>
so you should not look for solutions better than O(n) and instead find an O(n) solution that does better than uniq. What is wrong with uniq? it creates an extra array. that takes time. don't.
<leftylink>
though thinking about it that extra array only has two elements anyway but I guess the act of doing so was unnecessary work anyway
<FullMetalStacker>
so would e.g sorting the array be performing better?
<leftylink>
sorting is O(n log n) so no
<FullMetalStacker>
then i could sort and do the idea of weaksauc_
<ox1eef_>
Can you provide us the sample data you're using in a gist or something?
<weaksauc_>
no sorting is way too slow for this
<weaksauc_>
if it were pre-sorted from them yeah it's O(1)
<weaksauc_>
but not sorted on an arbitrary data is fundamentally O(n logn)
<weaksauc_>
*to sort
<FullMetalStacker>
oxieef_ it's an array of 1,5 MiB of number "24" and one number which is different
<caleb>
we're just looking for the one number that's different than the others right?
<caleb>
why not a binary search?
<leftylink>
binary searches need sorted input.
<leftylink>
so no
<weaksauc_>
FullMetalStacker share a gist to your code
<FullMetalStacker>
no sorry. the 1,5 MB is the size of the buffer that the app uses at max
otisolsen70 has quit [Quit: Leaving]
<neshpion>
binary search wouldn't help for this because there's no ordering of elements (other than the unique one) to go by
<FullMetalStacker>
is there any place i can look up the methods and their corresponding O notation?
<weaksauc_>
there is no way to do it less than O(n)
<ox1eef_>
I don't have good data to work with, but it should give you an idea.
<FullMetalStacker>
caleb: exactly. i get thrown arrays on me of different sizes with 2 different numbers. one only once, the other multiple times
<ox1eef_>
The missing part is communicating the result back to the parent, you can use a unix socket for that, or a lib I wrote that's easier to use: https://github.com/0x1eef/xchan.rb
grokify has quit [Remote host closed the connection]
<weaksauc_>
FullMetalStacker share your code and maybe someone can improve it
<leftylink>
as you can see, uniq takes time proportional to the input array size, regardless of the fact that the resulting array has only one elemtn
<leftylink>
it stands to reason that it's therefore inappropriate to use uniq for this problem
<ox1eef_>
This is the last I will say on this, but you won't find better performance without reaching for parallelism. You have to iterate the whole array to find the single element that's unique, and with parallelism you don't even need the solution to be performant.
<ox1eef_>
And in case it's not clear, .each_slice() is lazy, you are off loadding the heavy work to another process, or whatever is available for concurrency.
<leftylink>
oh wait, my demonstration wasn't the point I wanted to make... of course uniq is O(n
<leftylink>
apologies
<leftylink>
the demonstration I would have wanted to make is that uniq does unnecessary extra work, despite the fact that the result is only two elements. let's see how I would show that fact
<leftylink>
pandabot rb a = (1..10).to_a * 10000; b = (1..10000).to_a * 10; [a, b].map { |tgt| t = Time.now; 100.times { tgt.uniq }; Time.now - t }
<ox1eef_>
I think the point that's being missed is that given a large enough array, any solution that runs on a single thread is going to take a while, especially if the array is 100_000 and up. No algorithm that doesn't distribute the work will work around that. Find the fastest solution for a single thread, and then deploy it across many threads, or processes.
<leftylink>
it sounds like a necessary subskill of this task is "find the fastest solution for a single thread" then
havenwood has joined #ruby
<FullMetalStacker>
The skill level of this channel is insane. I am really admiring you guys!!! I am learning so much in so many levels.
<leftylink>
so we had better think about this in addition
<ox1eef_>
Yeah, that's fair but for 1.5MB of data it will still be relatively slow.
teclator has joined #ruby
<FullMetalStacker>
ox1eef_ thank you so much for your gist with the code! I am currently working on understanding it since it includes so many things that I am not familiar with yet.
<ox1eef_>
No worries. Back later.
<FullMetalStacker>
leftylink: yes, this is explicitly mentioned in the assignment statement in the last sentence: "The tests contain some very huge arrays, so think about performance."
grokify has quit [Remote host closed the connection]
<weaksauce>
i'd just iterate it once personally. uniq does some housekeeping to make it that way and is going to be considerably slower than just manually doing it
<ox1eef_>
I agree. The fastest solution will probably be using .each to iterate the array, and a hash that keeps track of the occurrences within that array.
<weaksauce>
and you could test each vs just doing it with an index variable
<weaksauce>
and a few tracking variables
<weaksauce>
it's 6kyu which i gather is on the easier side of codewars so it's not looking for anything tricky
<weaksauce>
you can also try it on mri 3 and see if there is enough of a speedup there
<FullMetalStacker>
mri 3?
<weaksauce>
ruby 3 dropdown
<FullMetalStacker>
ok got it!
<FullMetalStacker>
disabled for this kata :-D
<ox1eef_>
h = Hash.new(0); arr.each.max { |el| h[el] += 1 } - this might be fast enough.
<ox1eef_>
sorry, should 'min', not max.
<weaksauce>
ok i just did it manually and it passed in < 1 sec
<weaksauce>
so it's quite possible FullMetalStacker
<weaksauce>
ox1eef_ that code doesn't pass
<ox1eef_>
Pass in what sense? it works for me when the arr is [1,2,2,3,3,4,4]
<weaksauce>
anyway the while loop one is probably faster because of the closure thing
<FullMetalStacker>
this is crazy i just run it again a second and now it passed it :-)
<FullMetalStacker>
maybe the random tests are very much on the edge and depend on the random result
<weaksauce>
what's the time it takes on yours?
<FullMetalStacker>
thank you very much!! i will now study your solution and also the one of ox1eef_ to pick up as much knowledge from this as i can. and also that time measurements of leftylink .. so cool everything
<FullMetalStacker>
Completed in 1479ms
<FullMetalStacker>
Completed in 1018ms
<FullMetalStacker>
Completed in 1368ms
<FullMetalStacker>
maybe i was just unlucky with the server load at that time, as i am on the free plan
<FullMetalStacker>
GUYS THANK YOU ALL!!!
<FullMetalStacker>
Much appreciated!!!
<weaksauce>
yeah i don't have an account so who knows. could be that they expect the tests to pass < 2 seconds
<FullMetalStacker>
looking at tally, very interesting, but does not run on my irb
<FullMetalStacker>
ox1eef_ beautiful solution! thank you very much!!
grokify has joined #ruby
grokify has quit [Ping timeout: 246 seconds]
grokify has joined #ruby
<ox1eef_>
Welcome
grokify has quit [Remote host closed the connection]
<FullMetalStacker>
learned a ton today. first time ever for me on my learning journey to come in touch with performance considerations and you guys were a huge help for me to get this intro!!
<ox1eef_>
Always good to learn, that's what life is all about.
<FullMetalStacker>
one last question on this: you guys seem all to be super aware of the various Os of every method. Is there some kind of list I can look such things up or do you "just know" it because you have fully understood all the methods, and the mathematical side of them?
<FullMetalStacker>
"sorting is O(n log n)" etc.
<bougyman>
There's lists and charts and such.
<neshpion>
i usually just throw out my best guess and try to sound as sure as possible
<FullMetalStacker>
neshpion LOL :-)
<neshpion>
if asked for an explanation, "because of the way it is" works 80% of the time
<FullMetalStacker>
bougyman could you point me in some direction or maybe even have some links at hand for me?
grokify has joined #ruby
grokify has quit [Remote host closed the connection]