I'm trying to write a basic function to take an integer and evaluate to a bool that will check whether the integer is a prime or not.
I've used an auxiliary function to keep track of the current divisor I'm testing, like so:
fun is_divisible(n : int, currentDivisor : int) =
if currentDivisor <= n - 1 then
n mod currentDivisor = 0 orelse is_divisible(n, currentDivisor + 1)
else
true;
fun is_prime(n : int) : bool =
if n = 2 then
true
else
not(is_divisible(n, 2));
It looks right to me but I test it on 9 and get false and then on 11 and get false as well.
Sorry for all the questions today and thanks!
The problem is that if your is_divisible reaches the last case it should return false because it means that all the iterated divisors have resulted in a remainder larger than zero except for the last one which is the number it self. So you should rename is_divisible and return false instead of true
Related
I am trying to create a code which identifies if the elements in an array are monotonic or not.
I wrote the below code and got the error -
function isMonotonic(array)
if length(array) <= 2
return true
end
check_up = []
check_down = []
for i in range(2, length(array))
if array[i] <= array[i-1]
append!(check_up, 1)
end
if array[i] >= array[i - 1]
append!(check_down, 1)
end
end
if sum(check_up) == length(array) - 1 || sum(check_down) == length(array) - 1
return true
else
return false
end
end
isMonotonic([1, 2, 3, 4, 5, 6 , 7])
I am getting the below error
Error: Methoderror: no method matching zero(::Type{Any})
I think it is because I am trying to sum up the empth array, I want to understand how to overcome this problem in general, I have a solution for the above code, but in genral I want to know the reason and how to use it. I do not want to first check if the array is empty or not and then do the sum.
If you wanted to save yourself lots of effort, the simplest solution would just be:
my_ismonotonic(x) = issorted(x) || issorted(x ; rev=true)
This will return true if x is sorted either forwards, or in reverse, and false otherwise.
We could maybe make it a little more efficient using a check so we only need a single call to issorted.
function my_ismonotonic(x)
length(x) <= 2 && return true
for n = 2:length(x)
if x[n] > x[1]
return issorted(x)
elseif x[n] < x[1]
return issorted(x ; rev=true)
end
end
return true
end
# Alternatively, a neater version using findfirst
function my_ismonotonic(x)
length(x) <= 2 && return true
ii = findfirst(a -> a != x[1], x)
isnothing(ii) && return true # All elements in x are equal
if x[ii] > x[1]
return issorted(x)
else
return issorted(x ; rev=true)
end
end
The loop detects the first occurrence of an element greater than or less than the first element and then calls the appropriate issorted as soon as this occurs. If all elements in the array are equal then the loop runs over the whole array and returns true.
There are a few problems of efficiency in your approach, but the reason you are getting an actual error message is because given the input, either this expression sum(check_up) or this expression sum(check_down) will effectively result in the following call:
sum(Any[])
There is no obvious return value for this since the array could have any type, so instead you get an error. If you had used the following earlier in your function:
check_up = Int[]
check_down = Int[]
then you shouldn't have the same problem, because:
julia> sum(Int[])
0
Note also that append! is usually for appending a vector to a vector. If you just want to add a single element to a vector use push!.
I am solving this homework of clean programming language;
The problem is we have a number of five digits and we want to check whether it's an odd palindrome or not.
I am stuck at the stage of dividing the number to five separate digits and perform a comparison with the original number, for the palindrome check. With Clean I can't loop over the number and check if it remains the same from the both sides, so I am looking for an alternative solution (Some mathematical operations).
Code block:
isOddPalindrome :: Int -> Bool
isOddPalindrome a
| isFive a <> 5 = abort("The number should be exactly five digits...")
| (/*==> Here should be the palindrome check <==*/) && (a rem 2 <> 0) = True
| otherwise = False
isFive :: Int -> Int
isFive n
| n / 10 == 0 = 1
= 1 + isFive(n / 10)
My idea is to take the number, append it's digits one by one to an empty list, then perform the reverse method on the list and check if it's the same number or not (Palindrome)
Your answer above doesn't have a stopping condition so it will result in stack overflow.
You could try this
numToList :: Int -> [Int]
numToList n
| n < 10 = [n]
= numToList (n/10) ++ [n rem 10]
Start = numToList 12345
and then like you mentioned in the answer, you can reverse it with the 'reverse' function and check if they are equal.
After hours of trying to figure out how to recursively add the digits of our number to an empty list, I did the following:
sepDigits :: Int [Int] -> [Int]
sepDigits n x = sepDigits (n/10) [n rem 10 : x]
Now I can easily check whether the reverse is equal to the initial list :) then the number is palindrome.
I need to write a recursive function that returns the remainder of two numbers. Here's what I wrote:
def remainder(a,b):
if a==b:
return 0
else:
k=a-b
return a-b + remainder(b,a-k)
If we test remainder(5,3) the function will return 2 and it's correct but if we test remainder(15,3),
we'll get 12 and its false. I just don't know how to debug it.
You are missing a case: (when a < b)
def remainder(a,b):
if a<b: #trivial: remainder = a - b*0 = a
return a
else: #reduce the problem to a simple one
return remainder(a-b, b)
Test:
print remainder(15,3)
Output:
0
Here if you are lazy and don't want to write more than 2 lines:
def remainder(a,b):
return a if a < b else remainder(a-b, b)
It should be something like this :
def remainder(a,b):
if a<b:
return a
else:
return remainder(a-b,b)
You can do:
def remainder(a, b):
if a < b:
return a
return remainder(a - b, b)
Examples:
>>> remainder(15, 3)
0
>>> remainder(14, 3)
2
>>> remainder(13, 3)
1
If a < b then it means we're done: we know the result of the computation and we can return a. Otherwise we need to subtract b from a and we call remainder again recursively. This can then repeatedly continue until a is smaller than b. Once that happens the recursion stops (i.e., it won't call remainder again) but we're able to return the result.
I'm stuck in an infinite loop in this function:
let rec showGoatDoorSupport(userChoice, otherGuess, aGame) =
if( (userChoice != otherGuess) && (List.nth aGame otherGuess == "goat") ) then otherGuess
else showGoatDoorSupport(userChoice, (Random.int 3), aGame);;
And here's how I'm calling the function:
showGoatDoorSupport(1, 2, ["goat"; "goat"; "car"]);
In the first condition in the function, I compare the first 2 input parameters (1 and 2) if the are different, and if the item in the list at index "otherGuess" is not equal to "goat", I want to return that otherGuess.
Otherwise, I want to run the function again with a random number between 0-2 as the second input parameter.
The point is to keep trying to run the function until the second parameter doesnt equal the first, and that slot in the List isn't "goat", then return that slot number.
Don't use ==, it checks for physical equality. Use =. Two different strings will never be physically equal, even if they contain the same sequence of characters. (This is necessary, because strings are mutable in OCaml.)
$ ocaml
OCaml version 4.00.0
# "abc" == "abc";;
- : bool = false
# "abc" = "abc";;
- : bool = true
Another to do that is to use the String.compare. An example:
if String.compare str1 str2 = 0 then (* case equal *)
else (* case not equal *)
In the below snippet, please explain starting with the first "for" loop what is happening and why. Why is 0 added, why is 1 added in the second loop. What is going on in the "if" statement under bigi. Finally explain the modPow method. Thank you in advance for meaningful replies.
public static boolean isPrimitive(BigInteger m, BigInteger n) {
BigInteger bigi, vectorint;
Vector<BigInteger> v = new Vector<BigInteger>(m.intValue());
int i;
for (i=0;i<m.intValue();i++)
v.add(new BigInteger("0"));
for (i=1;i<m.intValue();i++)
{
bigi = new BigInteger("" + i);
if (m.gcd(bigi).intValue() == 1)
v.setElementAt(new BigInteger("1"), n.modPow(bigi,m).intValue());
}
for (i=0;i<m.intValue();i++)
{
bigi = new BigInteger("" + i);
if (m.gcd(bigi).intValue() == 1)
{
vectorint = v.elementAt(bigi.intValue());
if ( vectorint.intValue() == 0)
i = m.intValue() + 1;
}
}
if (i == m.intValue() + 2)
return false;
else
return true;
}
Treat the vector as a list of booleans, with one boolean for each number 0 to m. When you view it that way, it becomes obvious that each value is set to 0 to initialize it to false, and then set to 1 later to set it to true.
The last for loop is testing all the booleans. If any of them are 0 (indicating false), then the function returns false. If all are true, then the function returns true.
Explaining the if statement you asked about would require explaining what a primitive root mod n is, which is the whole point of the function. I think if your goal is to understand this program, you should first understand what it implements. If you read Wikipedia's article on it, you'll see this in the first paragraph:
In modular arithmetic, a branch of
number theory, a primitive root modulo
n is any number g with the property
that any number coprime to n is
congruent to a power of g (mod n).
That is, if g is a primitive root (mod
n), then for every integer a that has
gcd(a, n) = 1, there is an integer k
such that gk ≡ a (mod n). k is called
the index of a. That is, g is a
generator of the multiplicative group
of integers modulo n.
The function modPow implements modular exponentiation. Once you understand how to find a primitive root mod n, you'll understand it.
Perhaps the final piece of the puzzle for you is to know that two numbers are coprime if their greatest common divisor is 1. And so you see these checks in the algorithm you pasted.
Bonus link: This paper has some nice background, including how to test for primitive roots near the end.