Test spec failing with my prime number checker - ruby

I am doing some coding challenges at code wars and ran into this one asking me to make a method that takes a number and determines if it is a prime number or not. If it is prime the method should return "true" if the number is not prime it should return "false".
The method passes every introductory test and each number I can think to throw at it but continually kicks back two tests as incorrect. At this point I'm curious if I am not understanding something about the testing process?
This is my code:
def isPrime(num)
counter=2 #is incremented with every time until loop loops
until counter>999999999999999 do
if num.abs <2
return false
elsif num.abs % counter == 0 && num.abs!=counter
return false
else
return true
end#if
counter+=1
end#
end```
and this is the feed back that code wars is sending back to me
isPrime
Should have isPrime defined.
Test Passed
Should return false for numbers less than 2.
Test Passed: Value == false
Test Passed: Value == false
Test Passed: Value == false
Should return false for non-prime numbers.
Test Passed: Value == false
Test Passed: Value == false
Expected: false, instead got: true # THESE ARE THE TESTS THAT FAIL
Expected: false, instead got: true # THESE ARE THE TESTS THAT FAIL
Should return true for prime numbers.
Test Passed: Value == true
Test Passed: Value == true
Test Passed: Value == true
Test Passed: Value == true
Test Passed: Value == true
Also I checked here page for help on the algorithm.
Any help is greatly appreciated.

There are a number of issues here. The biggest is with the if statement you have inside the loop.
if num.abs <2
return false
elsif num.abs % counter == 0 && num.abs!=counter
return false
else
return true
end
There is no condition under which this if statement will not terminate the loop and return either true or false in the first iteration. This will prevent counter from ever being incremented.
The next issue is in your loop control. You have
until counter>999999999999999 do
...
counter+=1
end
In this case it would be better to stop at the sqrt(num) rather than some large number. For better performance you probably should instead use as the loop control something like
until counter*counter > num do
This will avoid multiple sqrt calculations. You could precompute the sqrt instead, something like
sqrt_num = num.sqrt
until counter > sqrt_num do
(I don't know Ruby so I may have the syntax wrong, but I think you get the point). If you do this, though, be sure num is not negative before hand.
If you exit from the loop never having found a factor for num you know the number is prime.

There are 2 problems in your code
Why are you taking the num.abs? If the tester provides negative numbers, it doesn't fail. By formal definition negative numbers aren't prime.
The program can stop at Math.sqrt(n) https://stackoverflow.com/a/5811176/3804420

Related

Python: For loops breaking issue

I'm using a for loop, and inside the for loop are two if-statements that are both being checked for each iteration of the for loop. My issue is that once one of the if-statements = True, then I want the True if-statement to stop being checked, and only check the second if-statement. Or vice versa.
print("Guess the numbers it is! Your goal is to guess a two digit number from 00-99. The two digits may be the same.")
numGuessesN = int(input("How many guesses would you like? (2, 3, or 4) "))
for numGuessesN in range (firstGuess, numGuessesN + 1) :
print("Guess number", numGuessesN)
userGuessN = int(input("What is your guess? "))
if (userGuessN == randomNum1) :
print("You've guessed the first number!")
break
else :
print("The first number is not", userGuessN)
if (userGuessN == randomNum2) :
print("You've guessed the second number!")
break
else :
print("The second number is not", userGuessN)
I know the breaks in the if-statements will completely exit the for loop, and that's not what I want. But somehow I need the for loop to "break" for only each individual statement if it turns out the statement is true, and keep checking the remaining statement until it's true, or the loop runs out of iterations.
Thanks guys! I'm new to all of this, so I'm sorry if I'm not really clear haha.
either you use nested if-statements, or (in case you have a lot, so you would have a lot of repeated code) you set a variable
first_wrong=False
if bla:
pass
else:
first_wrong=True
if bla2 and not first_wrong:
pass
if bla3 and not first_wrong:
pass

how to create conditional loop for Luhn object to check if index[0] is not 0

I am using a Luhn lib from Github.
Luhn class has more methods but I am intersted in only "generate" and "valid?" methods.
m = Luhn.generate(9) # generates a random number like [123456789] or [098765432]
Luhn.valid?(m) # returns true or false based on Luhn checksum passing
But I don't want the generated number starts with "0".
so how do I put in my ruby script:
Discard the generated number that starts with "0".
Generate another number and check again until m[0] is non-zero.
run valid?() on generated number: if false, generate another non-zero number until true.
return the valid 9 digits number to the caller code
Will this work for you? (Very basic recursion)
require 'luhn'
def generate_non_zero_luhn(size=9)
m = Luhn.generate(size)
m[0] != "0" && Luhn.valid?(m) ? m : generate_non_zero_luhn(size)
end
Example Outputs
10.times.map { generate_non_zero_luhn }
#=> ["582428355", "353646136", "821379013", "818135220", "696652767",
"934766437", "885229401", "226319044", "682121645", "688197078"]
Although I think the validity check is not needed because Luhn is generating the number so it will always be valid. e.g.
1_000_000.times.map { Luhn.valid?(Luhn.generate(9))}.any?{|val| !val}
#=> false
So then the method can become
def generate_non_zero_luhn(size=9)
m = Luhn.generate(size)
m[0] != "0" ? m : generate_non_zero_luhn(size)
end

I am attempting to create a method which generates a true or false return value for a Fibonacci detection method in Ruby

I am attempting to create a method which generates a true or false return value when a number is given as its argument to detect if the number is a Fibonacci sequence, although I have never encountered a number like so:
2.073668380220713e+21 .
Forgive my ignorance but is there a way to deal with this type of value in ruby to make it work in the method below?
def is_fibonacci?(num)
high_square = Math.sqrt((5 * num) * num + 4)
low_square = Math.sqrt((5 * num) * num - 4)
# If high_square or low_square are perfect squares, return true, else false.
high_square == high_square.round || low_square == low_square.round ? true : false
end
puts is_fibonacci?(927372692193078999171) # Trying to return false, but returns true. The sqrt of this number is 2.073668380220713e+21.
puts is_fibonacci?(987) # Returns true as expected.
I believe because it's such a large number it's being displayed as scientific notation by Ruby and not able to work in your is_fibonacci? method with the basic Math library.
You might want to look into using the BigMath library for Ruby http://ruby-doc.org/stdlib-1.9.3/libdoc/bigdecimal/rdoc/BigMath.html
Edit As Niel pointed out, it's a Ruby float and has therefore lost precision. Big Math should still do the trick for you.

Determine if two tables have the same set of keys

I'm using Lua tables as sets by placing the value of the set in the table key and 1 as the table value, e.g.
function addToSet(s,...) for _,e in ipairs{...} do s[e]=1 end end
function removeFromSet(s,...) for _,e in ipairs{...} do s[e]=nil end end
local logics = {}
addToSet(logics,true,false,"maybe")
To test if two sets are equal I need to ensure that they have exactly the same keys. What's an efficient way to do this?
Since you asked about efficiency, I'll provide an alternative implementation. Depending on your expected input tables, you might want to avoid the second loop's lookups. It is more efficient if the tables are expected to be the same, it is less efficient if there are differences.
function sameKeys(t1,t2)
local count=0
for k,_ in pairs(t1) do
if t2[k]==nil then return false end
count = count + 1
end
for _ in pairs(t2) do
count = count - 1
end
return count == 0
end
Another version avoids lookups unless they are necessary. This might perform faster in yet another set of use-cases.
function sameKeys(t1,t2)
local count=0
for _ in pairs(t1) do count = count + 1 end
for _ in pairs(t2) do count = count - 1 end
if count ~= 0 then return false end
for k,_ in pairs(t1) do if t2[k]==nil then return false end end
return true
end
EDIT: After some more research and testing, I came to the conclusion that you need to distinguish between Lua and LuaJIT. With Lua, the performance characteristics are dominated by Lua's Parser and therefore by the number of source code tokens. For Lua, this means that Phrogz's version is most likely the faster alternative. For LuaJIT, the picture changes dramatically, as the parser is no longer an issue. For almost all cases the first version I showed is an improvement, the second version is probably best when the tables are very big. I would advise everyone to run their own benchmarks and check which version works best in their environment.
Loop through both tables and make sure that the key has a value in the other. Fail as soon as you find a mismatch, return true if you got through both. For sets of size M and N this is O(M+N) complexity.
function sameKeys(t1,t2)
for k,_ in pairs(t1) do if t2[k]==nil then return false end end
for k,_ in pairs(t2) do if t1[k]==nil then return false end end
return true
end
Seen in action:
local a,b,c,d = {},{},{},{}
addToSet(a,1,2,3)
addToSet(b,3,1,2,3,3,1)
addToSet(c,1,2)
addToSet(d,2,1)
print(sameKeys(a,b)) --> true
print(sameKeys(a,c)) --> false
print(sameKeys(d,c)) --> true
Note testing for t[k]==nil is better than just not t[k] to handle the (unlikely) case that you have set a value of false for the table entry and you want the key to be present in the set.

Pythonic ways to use 'else' in a for loop [duplicate]

This question already has answers here:
Why does python use 'else' after for and while loops?
(24 answers)
Closed 7 months ago.
I have hardly ever noticed a python program that uses else in a for loop.
I recently used it to perform an action based on the loop variable condition while exiting; as it is in the scope.
What is the pythonic way to use an else in a for loop? Are there any notable use cases?
And, yea. I dislike using break statement. I'd rather set the looping condition complex. Would I be able to get any benefit out of it, if I don't like to use break statement anyway.
Worth noting that for loop has an else since the language inception, the first ever version.
What could be more pythonic than PyPy?
Look at what I discovered starting at line 284 in ctypes_configure/configure.py:
for i in range(0, info['size'] - csize + 1, info['align']):
if layout[i:i+csize] == [None] * csize:
layout_addfield(layout, i, ctype, '_alignment')
break
else:
raise AssertionError("unenforceable alignment %d" % (
info['align'],))
And here, from line 425 in pypy/annotation/annrpython.py (clicky)
if cell.is_constant():
return Constant(cell.const)
else:
for v in known_variables:
if self.bindings[v] is cell:
return v
else:
raise CannotSimplify
In pypy/annotation/binaryop.py, starting at line 751:
def is_((pbc1, pbc2)):
thistype = pairtype(SomePBC, SomePBC)
s = super(thistype, pair(pbc1, pbc2)).is_()
if not s.is_constant():
if not pbc1.can_be_None or not pbc2.can_be_None:
for desc in pbc1.descriptions:
if desc in pbc2.descriptions:
break
else:
s.const = False # no common desc in the two sets
return s
A non-one-liner in pypy/annotation/classdef.py, starting at line 176:
def add_source_for_attribute(self, attr, source):
"""Adds information about a constant source for an attribute.
"""
for cdef in self.getmro():
if attr in cdef.attrs:
# the Attribute() exists already for this class (or a parent)
attrdef = cdef.attrs[attr]
s_prev_value = attrdef.s_value
attrdef.add_constant_source(self, source)
# we should reflow from all the reader's position,
# but as an optimization we try to see if the attribute
# has really been generalized
if attrdef.s_value != s_prev_value:
attrdef.mutated(cdef) # reflow from all read positions
return
else:
# remember the source in self.attr_sources
sources = self.attr_sources.setdefault(attr, [])
sources.append(source)
# register the source in any Attribute found in subclasses,
# to restore invariant (III)
# NB. add_constant_source() may discover new subdefs but the
# right thing will happen to them because self.attr_sources
# was already updated
if not source.instance_level:
for subdef in self.getallsubdefs():
if attr in subdef.attrs:
attrdef = subdef.attrs[attr]
s_prev_value = attrdef.s_value
attrdef.add_constant_source(self, source)
if attrdef.s_value != s_prev_value:
attrdef.mutated(subdef) # reflow from all read positions
Later in the same file, starting at line 307, an example with an illuminating comment:
def generalize_attr(self, attr, s_value=None):
# if the attribute exists in a superclass, generalize there,
# as imposed by invariant (I)
for clsdef in self.getmro():
if attr in clsdef.attrs:
clsdef._generalize_attr(attr, s_value)
break
else:
self._generalize_attr(attr, s_value)
If you have a for loop you don't really have any condition statement. So break is your choice if you like to abort and then else can serve perfectly to handle the case where you were not happy.
for fruit in basket:
if fruit.kind in ['Orange', 'Apple']:
fruit.eat()
break
else:
print 'The basket contains no desirable fruit'
Basically, it simplifies any loop that uses a boolean flag like this:
found = False # <-- initialize boolean
for divisor in range(2, n):
if n % divisor == 0:
found = True # <-- update boolean
break # optional, but continuing would be a waste of time
if found: # <-- check boolean
print n, "is composite"
else:
print n, "is prime"
and allows you to skip the management of the flag:
for divisor in range(2, n):
if n % divisor == 0:
print n, "is composite"
break
else:
print n, "is prime"
Note that there is already a natural place for code to execute when you do find a divisor - right before the break. The only new feature here is a place for code to execute when you tried all divisor and did not find any.
This helps only in conjuction with break. You still need booleans if you can't break (e.g. because you looking for the last match, or have to track several conditions in parallel).
Oh, and BTW, this works for while loops just as well.
any/all
Nowdays, if the only purpose of the loop is a yes-or-no answer, you might be able to write it much shorter with the any()/all() functions with a generator or generator expression that yields booleans:
if any(n % divisor == 0
for divisor in range(2, n)):
print n, "is composite"
else:
print n, "is prime"
Note the elegancy! The code is 1:1 what you want to say!
[This is as effecient as a loop with a break, because the any() function is short-circuiting, only running the generator expression until it yeilds True. In fact it's usually even faster than a loop. Simpler Python code tends to have less overhear.]
This is less workable if you have other side effects - for example if you want to find the divisor. You can still do it (ab)using the fact that non-0 value are true in Python:
divisor = any(d for d in range(2, n) if n % d == 0)
if divisor:
print n, "is divisible by", divisor
else:
print n, "is prime"
but as you see this is getting shaky - wouldn't work if 0 was a possible divisor value...
Without using break, else blocks have no benefit for for and while statements. The following two examples are equivalent:
for x in range(10):
pass
else:
print "else"
for x in range(10):
pass
print "else"
The only reason for using else with for or while is to do something after the loop if it terminated normally, meaning without an explicit break.
After a lot of thinking, I can finally come up with a case where this might be useful:
def commit_changes(directory):
for file in directory:
if file_is_modified(file):
break
else:
# No changes
return False
# Something has been changed
send_directory_to_server()
return True
Perhaps the best answer comes from the official Python tutorial:
break and continue Statements, and else Clauses on Loops:
Loop statements may have an else
clause; it is executed when the loop
terminates through exhaustion of the
list (with for) or when the condition
becomes false (with while), but not
when the loop is terminated by a break
statement
I was introduced to a wonderful idiom in which you can use a for/break/else scheme with an iterator to save both time and LOC. The example at hand was searching for the candidate for an incompletely qualified path. If you care to see the original context, please see the original question.
def match(path, actual):
path = path.strip('/').split('/')
actual = iter(actual.strip('/').split('/'))
for pathitem in path:
for item in actual:
if pathitem == item:
break
else:
return False
return True
What makes the use of for/else so great here is the elegance of avoiding juggling a confusing boolean around. Without else, but hoping to achieve the same amount of short-circuiting, it might be written like so:
def match(path, actual):
path = path.strip('/').split('/')
actual = iter(actual.strip('/').split('/'))
failed = True
for pathitem in path:
failed = True
for item in actual:
if pathitem == item:
failed = False
break
if failed:
break
return not failed
I think the use of else makes it more elegant and more obvious.
A use case of the else clause of loops is breaking out of nested loops:
while True:
for item in iterable:
if condition:
break
suite
else:
continue
break
It avoids repeating conditions:
while not condition:
for item in iterable:
if condition:
break
suite
Here you go:
a = ('y','a','y')
for x in a:
print x,
else:
print '!'
It's for the caboose.
edit:
# What happens if we add the ! to a list?
def side_effect(your_list):
your_list.extend('!')
for x in your_list:
print x,
claimant = ['A',' ','g','u','r','u']
side_effect(claimant)
print claimant[-1]
# oh no, claimant now ends with a '!'
edit:
a = (("this","is"),("a","contrived","example"),("of","the","caboose","idiom"))
for b in a:
for c in b:
print c,
if "is" == c:
break
else:
print

Resources