5 kyu
Master your primes: sieve with memoization
73 of 176GiacomoSorbi
Loading description...
Memoization
Algorithms
Tutorials
View
This comment has been reported as {{ abuseKindText }}.
Show
This comment has been hidden. You can view it now .
This comment can not be viewed.
- |
- Reply
- Edit
- View Solution
- Expand 1 Reply Expand {{ comments?.length }} replies
- Collapse
- Spoiler
- Remove
- Remove comment & replies
- Report
{{ fetchSolutionsError }}
-
-
Your rendered github-flavored markdown will appear here.
-
Label this discussion...
-
No Label
Keep the comment unlabeled if none of the below applies.
-
Issue
Use the issue label when reporting problems with the kata.
Be sure to explain the problem clearly and include the steps to reproduce. -
Suggestion
Use the suggestion label if you have feedback on how this kata can be improved.
-
Question
Use the question label if you have questions and/or need help solving the kata.
Don't forget to mention the language you're using, and mark as having spoiler if you include your solution.
-
No Label
- Cancel
Commenting is not allowed on this discussion
You cannot view this solution
There is no solution to show
Please sign in or sign up to leave a comment.
Is this meant to come with some code pre-written? Some languages have significant partial implementations, whereas other languages only have the bare-bones you usually see with kata.
Languages with boilerplate only: Crystal, Python, Ruby
Languages with solution partially implemented: C#, JavaScript
Great kata of the series on primes to learn more about dynamic programming and algorithms efficency.
Pretty sure that the JS random tests are not correct..
In some cases it expects true for non-prime numbers (for example 992237) and the oposite as well (for example 373)
what is kyu
It is your rank. The smaller - the better. The highest kyu is 1.
.
umm, what? (python)
isn't 653 prime?
whats up with abs(len(primes)-9)<3 ? why at the same time kata is asking to update the primes array and not update??
Wow I definitely can't get how you can check number 8855 with only first 22 prime numbers (the 22nd is number 79). Isn't the point of the kata to add the prime number only if it is not present in the list and it is not the divisor of the N?
"Testing primes length after check for 8855 It should work with random inputs too: expected a result close to 22, instead got 525: False should equal True"
The funny thing is that a lot of tests print the same error (doesn't matter if it's a large or small number):
"Testing primes length after check for 119873 It should work with random inputs too: expected a result close to 22, instead got 525: False should equal True"
"Testing primes length after check for 1025 It should work with random inputs too: expected a result close to 22, instead got 525: False should equal True"
Okay I've tried this kata again with the solutions from the Solutions section. And these solutions also don't pass the tests. I am wondering how in the world can one solve this task...
This is completely incoherent.
I really don't understand what this wants me to do. I get the idea of not doing more work than you need to, but I'm apparently failing for not doing ENOUGH work, even though I'm doing exactly the right amount.
Take this example; this test fails where the previous primes length test succeeded.
Testing primes length after check for 74706941 It should work with random inputs too: expected a result close to 65, instead got 60: False should equal True
The prime factor that establishes that 74706941 is not prime is 281. 281 is the 60th prime number, so I did exactly as much work as I needed to answer the question. Why should I have to have done more work than that?
Which language? This kata is weird, seems easy but I could not figure out very well what it does, what it checks and what's the point of that... I solved it in Python but I could not in other languages. See the satisfaction rate is not very high...
Sorry, forgot to mention, it's Python.
No problem. Well, revising my code, I understand (or I believe so) that you must not add the last prime you computed to the memo if it allows you to determine that the parameter is not prime. You must return False immediately. Does not make much sense... Hope this helps.
I gave up, thanks anyway.
Why is the preloaded code for C# riddled with errors?
The base method the tests call is
IsPrime
but in the preloaded code it is calledisPrime
. The propertyPrimes
is aList<long>
but the method body triese to accessPrimes.length
(both a typo, it should beLength
, but also incorrect becauseList
s don't have aLength
property, they haveCount
). Finally it tries to call some mysteriousExpandPrimes
method which is not defined anywhere. Why is that there? Is the purpose of this kata to implement this method? If so, the description doesn't mention that. In fact, the entire description is an oddly rambling mess, to be quite frank.I changed it around and made the ExpandPrimes implimentation with the prelim tests all passing but the attempted test gets timed out.
Go translation available.
Could someone please just explain what this kata really wants, regarding prime list length? I'm completely lost, reading description and discourse only adds more confusion...
Ok, so we're checking if n is prime.
Looping through what? From a to b? primes?
When is that? If we find that it's prime? Do we expand if we found it's not prime? How far should we expand - up to n? Just adding n?
threshold? What threshold?? I don't see it described anywhere.
Are we checking for n's primality or are we checking for some potential primes? I don't get it.
If someone could explain exactly what primes should be present for this test, and why, it would be much appreciated.
It is trying to enforce the 'optimal' algorithm, ie. never do more work than you have to.
In the sample tests (The author should really explain this himself) the prime length checking is seeing whether you did more work than you had to. For example,
143
is divisible by 11, so your list of primes should not go any higher than that at that point. (that would be extra work). Later, you check if529
is prime, but it is divisible by23
, so the list of primes should not go above23
(Or stay the same length if it was already above).I don't mind a kata trying to teach me something, but adding confusing extra checks without explaining their purpose just makes the whole experience frustrating. (IMO)
Thanks for your explanation. It's starting to make some sense, I think. I'll give it another go later today... and probably come back with more questions x)
Ruby 3.0 should be enabled.
Done
This comment has been hidden.
Is it possible to have more infos when a test fail in Crystal for
test_len()
?It just says:
It's a bit hard to guess what it expects
I noticed a couple of errors. Using Python 3.6
Testing for 72857 It should work with random inputs too: False should equal True This one is 41 x 1777 so not a prime
Testing for 30053 It should work with random inputs too: False should equal True This one is 41 x 733 so not a prime
Testing for 76938497 It should work with random inputs too: False should equal True This one is 31 x 2481887 so not a prime
This kata is poorly written, poorly described.
Log 98033 It should work with random inputs too: False should equal True The tests expect this number to be a prime! but it is not a prime.Language is python.
duplicated issue. Closing
Big problem in Python 2 and 3, the primality check is completely wrong. It even said 41 is not a prime number. I tried to submit for 5 min but coulnd't get below 2 wrong checks.
duplicated issue, closing.
In javaScript version given: var primes = [2, 3, 5, 7]; // length 4
and: Test.describe("Basic tests",_=>{ Test.assertEquals(isPrime(1),false); Test.assertEquals(isPrime(2),true); Test.assertEquals(isPrime(5),true); Test.assertEquals(isPrime(143),false); Test.assertEquals(Math.abs(primes.length-5)<3,true); Test.assertEquals(isPrime(-1),false); Test.assertEquals(isPrime(29),true); //add here Test.assertEquals(isPrime(53),true); //add here Test.assertEquals(isPrime(529),false); Test.assertEquals(Math.abs(primes.length-9)<3,true); })
primes.length === 6
Last test cannot be passed: Math.abs(6-9) < 3;
Also later i'm failing tests for primes.length;
Python 2.7.6
Testing for 76009410593 It should work with random inputs too: True should equal False
https://www.wolframalpha.com/input/?i=76009410593+ 76009410593 is a prime number.
Same for other 9 fails in my random tests.
additional info: same with python 2 & 3
Testing for 683 It should work with random inputs too - Expected: false, instead got: true
Not sure how it expects 683 not to be a prime while it is a prime. Many such failures.
Language?
Ruby.
I tested the code and
683
is correctly marked as prime.You should probably disable
require
in ruby, otherwise it's (a bit) easier than expected. I thinkrequire = nil
in the preloaded section is enough.Good idea; fixed :+1:
C# Translation added.Please review and approve~
PS.fixed the markdown.
This comment has been hidden.
Thanks for your feedback :)
Gia :
This generator :
Produces wild swings in the test output so your own solution won't always pass and times out.
Not sure how that is possible, as in order to publish a kata or a translation it runs a conspicuous number of tests; well, whatever: range reduced - I guess there is still a luck factor, but should be not so crushing now.
The primality check test passes but the length check test fails with below error. Is this a problem with the kata or should I continue to work on a more optimal solution which works with only 9 primes for checking primality of 15725?
ERROR: Testing primes length after check for 15725 It should work with random inputs too: expected a result close to 9, instead got 30 - Expected: true, instead got: false
Language is Ruby
Looks like it is a problem in your code: is it an isolated case or are you failing multiple times?
Similar errors are seen everytime I Attempt. There might be an issue with my solution but I think there might also be some issue with the tests. See below errors. It is expecting the length to be close to 10 for checking primality of -1. Also, can you confirm that 182 is not the expected length for checking primality of 1181705? This confirmation will help me to continue to work on my solution knowing that I am not wasting my time on unresolved Test issues. Thanks in advance!
Testing for 1181705 Testing primes length after check for 1181705 It should work with random inputs too: expected a result close to 10, instead got 182 - Expected: true, instead got: false
Testing for -1 Testing primes length after check for -1 It should work with random inputs too: expected a result close to 10, instead got 182 - Expected: true, instead got: false
Do you expand
primes
up to the square ofn
, by any chance?This comment has been hidden.
Can you please confirm that 182 is not the expected length for checking primality of 1181705?
Considering you should stop at
5
, I would say so, yes...The kata expects
true
for input75647596379
, but75647596379 / 19 = 3981452441
. ScreenshotLanguage?
JavaScript
Mh, cannot reproduce - I assume now it is fixed, but so many thank to who downvoted me :D
I don't know who downvoted you, but here's an upvote to balance it out.
Thanks <3, reciprocated.
Hello, interestring kata for applying memoziation :) I have one question on the Python version : why testing with booleans ? Like : Test.assert_equals(abs(len(primes)-5)<3,True) Test.assert_equals(abs(len(primes)-9)<3, True)
At first i used the global primes list that would fail on the first of the abose test, re declaring it in the function (so keeping the global one unchanged) made the fisrt of the above test succeed, but it's not a clean solution - and you loose previous computations. Such function may raise a TypeError for boolean inputs.
Eventually printing n did not seem to work for boolean input, nothing to do with your kata but still annoying when debuging.
Thanks for your feed :)
Any idea on how to test if
primes
is in a given range otherwise?Found those in the random tests:
Seems I find a "more efficient" (or at least, a "stop faster") version than yours, but that makes fail the tests. Not fair! But in addition, I get sometimes a time out anyway... (might be server issues...)
To me, your kata still lacks some additionnal explainations about what we should do or not. Here, it seems more about guessing what you did exactly on your side.
That's interesting: not sure how you could be more efficient in terms of range, but are you sure you do not reset
primes
at each run, which might explain both issues?Errrr... Actually, I just realized I was lacking some in my list... ;-s Still timing out troubles to address, now...
This comment has been hidden.
Run it a number of times and never got above 5 seconds: are you sure you cannot make it without the set and/or there are no further improvements? Afterall it is meant to be an optimization kata, so not sure how I could improve things further without spoiling it, mh...
Hi,
Yeah right! ;) I believe I had my mind a bit clouded at this time. Failure again and again... not good to keep a clear mind (But still... Tried the code above again and never got anything else than a timeout, today... :o That's really weird... Nevermind... ;) )
EDIT : btw, "carrying capacity" is on its way? ;)
I start to wonder if CW changed something in their backend, as it used to be more stable before; either that or when you try to edit/create a kata it makes calls to some more dedicated resource, mh...
did you try in a fork of a solution, to go around that possibility?
EDIT: I just tried that for another purpose: same perf, apparently...
This comment has been hidden.
Language? And are you sure it is testing if
15371
is a prime, and not just how long is yourprimes
list?I'm also a little lost. I don't understand the description. Test.assert_equals(is_prime(1),False) -- don't add Test.assert_equals(is_prime(2),True) -- don't duplicate Test.assert_equals(is_prime(5),True) -- don't duplicate Test.assert_equals(is_prime(143),False) -- don't add, not prime Test.assert_equals(abs(len(primes)-5)<3,True) -- list has 2,3,5,7, so abs(4-5) < 3. True Test.assert_equals(is_prime(-1),False) -- don't add Test.assert_equals(is_prime(29),True) -- add. list len is now 5 Test.assert_equals(is_prime(53),True) -- add. list len is now 6 Test.assert_equals(is_prime(529),False) -- don't add Test.assert_equals(abs(len(primes)-9)<3,True). abs(6 - 9) == 3, not <3. What I'm I missing?
Do you had only
29
and53
? Consider how a sieve works and that you should add all the primes up to those numbers, before adding them :+1:@GiacomoSorbi, the trick should not be in us struggling to understand the Kata. Look at your response to my last question: ".....you should add all the primes up to those numberse, before adding them". What does this mean??
Please take some time to give a simple numeric example of how this should work and the expected result.
Thanks for bashing my English instead of suggesting some rewording <3, but let me try to reword: you should populate
primes
with all the primes you indeed need to run the sieve to verify each parameter given to you.@GiacomoSorbi I am sure 15371 was tested during random tests. I have had some other errors (during random testing), but I did not store them. Try to review code and test these area and I am sure you will find a bug.
I use Python.
Alternatively, can you post your code here with spoilers? :)
This comment has been hidden.
Thanks @GiacomoSorbi. Wasn't bashing your English. Your additional explanation helps.
No worries, but take into account that any suggestion on improving the descriptions I might write is always welcome, otherwise there is little I can do to improve that aspect.
@miecio, did you bother reading the link I put into said description and would you try to optimize in that sense?
yes, i did, and for sure i will optimize the code, but it is jsut temporary solution (to make sure that I understood Kata correctly)
This comment has been hidden.
Pardon for the lag, no notifications on CW for a few days, it would seem: if you keep proceeding by 2, I would invite you to reconsider the article I put at the bottom of the description and instead proveed by
6k+/-1
:)Furthermore, if you repost and format your code with gitflavored markdown, I might be able to read it better.
Oh, I had no clue we can do that. Thank you for advice and you should be able to see it now
Definitely better: you expand your
primes
list too much: do it only on a one-by-one basis :+1:This comment has been hidden.
Lovely reading <3, thanks :+1:
This comment has been hidden.
okay, so now I've read all the discussions here, have read the ecolbans comments, know what to do and going further with the Kata seems probable - instead of completely failing the tests, I now have too big discrepency between the number of primes in the list (i.e. 168 where there should be 152). Anyway, I think I'll manage, and actually I've learned so much even before completing the Kata.
The only concern I now have is the difficulty level of this Kata. It's marked as 5, its harder than those of Kyu3 which I have managed to pass, its definitely closer to kyu3 than to kyu5.
I concur on the difficulty being well above a 5kyu kata [yellow still meaning "novice], but ranking is out of my hands and often this kind of katas get ranked by power-users who have their own idea (for good or for bad, not telling I am the perfect assesser) of what is tough or not.
Your code, anyway, is far from being efficient, storing and testing each number up to
n
(even including numbers divisible by2
and3
, read the link in the description on why to proceed with6k+/-1
numbers), while you should just test until you prove a number is not prime.Hope this helps, cheers :)
I ranked this kata according to the average rank rating.
It's still possible to change the ranking after approving though. It's not set in stone :P
@GiacomoSorbi: Thanks for the input, you know, from the perspective of beginner programmer, a program which finds first 1000 prime numbers in 0.5 seconds seems efficient. Now I understand why it is not, and have gone much further in the Kata - to the point that I never get any errors from failed test cases. Unfortunately, there is still room for optimization, as I exceed the 12s threshold on checking whether numbers of size unknown to me are prime. For bilions it works fine. Could I please ask for the biggest possible value available in the Kata test cases, so I could analyse the performance on my local environment?
@Volie: Since the Kata itself is not really about checking if number is a prime or not, but about optimization of the process, it seems reasonable to rank it past the threshold of "able to get it done", and put it in "able to get it done quickly" basket. Anyway, CodeWars have tied in my personal ranking of best websites ever, and I thought that Quora is unmatched when it comes to getting rid of your own ignorance. It's not the first time you're responding on my concerns in the discussions, thank you for caring for this environment!
@imprezobus, not knowing your code, I would enquire if you did what I suggested above and checked if you were keeping things simple enough while grinding primes to check.
As for doing the above, indeed I did, as for keeping this simple, well, my sight is far from being perfect, but I'd probably see room for improvements in that matter even if I were semi-blind ;)
I'll be honest, the big challenge in solving this kata (Python version at least) was to figure out what the author intended to have for the length of primes[]. I happen to know a few things about primes, but this kata got me confused. I don't even know why I passed, and I won't try to figure it out.
and still, after a while I decided to check the test cases... hmmmm.... I wonder what is wrong with this statement: Test.assert_equals(abs(len(primes)-len(sol_primes)<3),True)? Maybe the fact that it returns the absolute value of ( len(primes) - len(sol_primes) < 3 ) :))
Fixed, thanks!
OK, I'm afraid I don't understand what this kata wants, although I solved a few hundred here already... It seems to be clear, though:
So, the initial list is
[2, 3, 5, 7]
and we start the tests:Please explain. I'm either stupid, or tired. Or the description is not clear.
Now I get:
72251 IS a prime, right?
...and this:
I feel like crying...
Screw memoization -- admire my solution :-)
p.s. the description is NOT clear
Care to suggest how to improve it?
Yes, sorry, been it a bit cynical yesterday.
I simply suggest to remove this part, because it's slightly misleading (it implies that you have to search for primes until you find one bigger than
n
-- but you don't). Plus, emphasize that you should keep your list as short as possible.Oh, and I suggest to add a heading for the second part of the description: "Memoization"
Cheers
No worries, I am a big fan of cynicism myself; changes made, feel free to give a feed now and thanks for your courtesy so far :)
"as short as possible" -> length 0 is as short as possible :s
Description is a bit broken:
Remove the backticks around 'n' or remove the bolding.
Cheers
Fixed
Approved
Vielen Dank, mein Freund :)
Oh, worst chicking ever. What i supposed to do with this error:
It should work with random inputs too - Expected: true, instead got: false
That is really anoying :~(
P.S It passes
22
tests and fails2
checks. Only2(two)
, not more. Theay are in the middle when it trying to check value 715 for primness(if it is prime) P.P.S After submiting again(without any changes) getting next stats:32
tests are passed and14
checks are failed :C P.P.P.S Now constantly50
passed /40
failed :S P.P.P.P.S Lol, it passed after 100th click on submit :~) P.P.P.P.P.S But you should do something with it... pleaseAnyway, nice optiomization problem =)
I think it tells what it is checking in the message above, plus you are not apparently optimizing the algorithm enough, it is not something I can fix with my (already quite lenient) testing routine.
Sry, cant edit anymore. I mean it fails 'Array size test' after checking numbers. Idk what i should do there
Error messages changed, then: try now :)
The messages are much better, but I think something else might be broken now:(My solution wouldn't have passed anyway, but still)Edit: This was a misunderstanding, Giacomo cleared it up for me in the chat. :)
The message text is out of my hands for the second part, but I could just turn it into a
Test.expect
call, mh...I think that this is related to the existing threads. I have tweaked my code so that I extend
primes
exactly as the tests expect it to be extended. Nevertheless, on input 4300816577, I get the error that myprimes
is only 6550 long, whereas 6551 is expected. The last prime in myprimes
is 65581, whose square is 4300867561, which is greater than 4300816577. Could you explain why you expect a longer sieve?Works now after GiacomoSorbi's last edits.
Sorry for the inconvenience, apparently CW was not saving my fixes.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden. ;-)
Fuck, right: let me unhide it for now, tell me when you are done ;)
P.S.: I am trying to update the description, but apparently even that is too much for the server...
I think that it's not so
less efficient
Perhaps the length check should be more intelligent or simply cancel it ;-)
EDIT:Sometimes their difference is 2 elements:
No no... nothing to cancel... it's a kata only for really really clever guys:-P...
Really and really? OK, Let me Zzz.. first ;-) Good night!
I am trying to fix that, but CW refuses to save my changes <_<...
Good night;-)!
And finally it should work again; if you want to point out some error or anything else that you saw, be my guest; have a nice sleep!
Sorry, it still can not pass the tests, perhaps I'm not a clever guy ;-)
You definitely are, but what happens now?
All things same as yesterday, has nothing new ;-)
There are two ways of solving this problem. Take
n = 12791
. We know that ifn
is composite, at least one factor must be less than or equal ton
's square root. Since this factor is anint
, it must be less than or equal toint(n ** 0.5)
, in this case113
. So we only need to check divisbility by the prime numbers up to and including113
, and if none of them dividesn
, we can conclude thatn
is prime. There are30
primes less than or equal to113
, so the length ofprimes
should be30
. Likewise, ifn == 67
, we only need to check divisibility by primes that are less than or equal to 8, which are the primes[2, 3, 5, 7]
. But how do we know that7
is the largest prime less than or equal to 8? One way is by finding the next prime and verifying that it is indeed greater than 8, but by the time we have done that, our list of primes has become[2, 3, 5, 7, 11]
. We could, alternatively, just abort the search for the next prime after reaching8
, in which case the greatest number in the list of primes is7
.Alternatively, we can compute all primes up to and including the first prime that is strictly greater than the square root of
n
. The next prime after113
is127
. When reaching127
after verifying that none of the primes before dividen
, we can conclude thatn
is a prime without verifying that127
dividesn
, since127
is strictly greater than the square root ofn
. With this method, we end up with the length ofprimes
equal to31
. We are computing more than necessary, since we need to compute the31
st prime (127
), and we still need to check divisibility with all the primes up to and including113
, so we are not gaining anything. Therefore, in my opinion, the first solution is the better one, but the tests fail for that solution. To accommodate both solutions, I suggest that the test put an upper (and lower) bound on the length ofprimes
and not require equality.I know I can modify my code to fit the author's test. But I don't want to do this because obviously the author's results are not optimal.
Let me know what you would specifically change, then: to me it is still better to stop once you get a prime larger then the square root of
n
, as it is most likely you will need it later and checking for each potential prime can be even more wasteful, particularly as numbers become larger and thus actual primes much rarer.I like ecolban idea, instead, and might implement it: how much of a margin would you put around the length of
primes
? I would say no more than2
, but you tell me.By the way i had the same problems yesterday;-)... But i always try to keep the author happy (on my sometimes special way:-))... Hey... seems to me it's at least a 2kyu kata;-)
... deleted (cw error)
I would be glad to have it ranked as a kyu kata also for the kind of users (and feed) it could gather; for now I am happy enough to have educated and smart people giving me good feed and not telling me it is a duplicate :p
FYI, tests all changed with more tolerance for the length of the primes array: let me know if all works well, now :)
Submitted and passed. Thanks ;-) Also voted and ranked ;-)
Awesome, thanks :)
And nice solution indeed!
This comment has been hidden.
Hi myjinxin and honoured to have you interested in my humble kata :)
Sorry for the first error, I was experimenting and forgot to restore the initial array of primes in the template, now fixed.
As far as the rest goes, for example
331755733
is definitely divisible by227
which happens to be the 49th prime; or am I missing something?Ah, OK. I think I know your point now. I will improve my code later..
Let me know if you think I could improve the description, cheers!