Fermat's primality test and Carmichael number - java

I am playing with prime numbers and Fermat's Little Theorem. I read about Carmichael numbers and that they should pass the tests. The problem is, when I test it and use two different conditions it should end with the same result, but it isn't.
Code :
import java.math.BigInteger;
public class FermatTest {
public static boolean passesAllFermatTests(BigInteger n) {
BigInteger testValue = BigInteger.ONE;
while (testValue.compareTo(n) == -1) {
if (!passesFermatTest(n, testValue)) {
return false;
}
testValue = testValue.add(BigInteger.ONE);
}
return true;
}
public static boolean passesFermatTest(BigInteger n, BigInteger a) {
//if( !a.modPow(n.subtract(BigInteger.ONE), n).equals(BigInteger.ONE)) {
if(! a.modPow(n, n).equals(a)) {
return false;
}
return true;
}
public static void main(String[] args) {
System.out.println(passesAllFermatTests(BigInteger.valueOf((long) 561)));
}
}
When I run it with this condition, it returns true ( pass it ). If I run it with the commented condition, it returns false. It should be the same, isn't it? Is there an error in my code or I misunderstood something?

The problem is when a = 3, your commented condition return false, it is because 3 and 561 is not relatively prime! Carmichael number require gcd(a,n) = 1 (please refer to the wikipedia: https://en.wikipedia.org/wiki/Carmichael_number).
So in your program, you should first check "a" and "n" is relatively prime first before applying the commented condition.

Related

Check for Palidrome using Recursion and Char Array search

I'm currently trying to use a function that compares the left and right side character to return a true or false Boolean value as to whether the string entered by the user is a palindrome or not, but I get a vague error statement to do with line 44. Not sure how to proceed. I am a beginner-level Java programmer who is open-minded and willing to learn, so don't roast me to hard haha.
import java.util.Scanner;
/**
*
* #author owner
*/
public class Q2_RecursivePalidrome {
public static void main(String[] args) {
int leftSideCharacter = 0;
int rightSideCharacter = 0;
Scanner scan = new Scanner (System.in);
System.out.println("Enter word to check whether palidrome: ");
String userInput = scan.next();
char[] checkPalidrome = userInput.toCharArray(); // creates an array of characters
System.out.println(isPalidrome(checkPalidrome, leftSideCharacter, rightSideCharacter));
}
public static boolean isPalidrome(char[] checkPalidrome, int leftSideCharacter, int rightSideCharacter) {
leftSideCharacter = 0;
rightSideCharacter = checkPalidrome.length - 1; // java arrays start at 0, not 1.
if (rightSideCharacter > leftSideCharacter) { // check both ends of string character by character
// to be palidrome, both sides of string should be same
//
if (checkPalidrome[leftSideCharacter] == checkPalidrome[rightSideCharacter]) {
return (isPalidrome(checkPalidrome, leftSideCharacter + 1, rightSideCharacter - 1));
}
else {
return false;
}
}
return true;
}
}
There are a couple main issues here, but you have the right idea:
Your recursive function uses left and right indices to determine which characters to compare in the test string. However, these two pointers are immediately set to the left and right ends of the string when the function is called, so they never recursively move towards the middle. Since the base case where the indices are equal is unreachable, the stack overflows. Remember, these calls are identical all the way down the stack, but with different parameters, so one-time "set up" tasks like setting initial indices should be moved outside of the recursive function.
Your initial pointer indices are 0, 0. This is an inaccurate "set up" call to the recursive function--it should be 0, string.length - 1.
Here is code that fixes these problems and cleans up comments and variable names:
import java.util.*;
public class Q2_RecursivePalidrome {
public static void main(String[] args) {
String test = "racecar";
System.out.println(isPalidrome(test.toCharArray(), 0, test.length() - 1));
}
static boolean isPalidrome(char[] test, int l, int r) {
if (l < r) {
if (test[l] == test[r]) {
return isPalidrome(test, l + 1, r - 1);
}
else {
return false;
}
}
return true;
}
}
By the way, the important lesson to take from all this is how to debug your program. In this case, printing your indices (the arguments that change from one call to the next) at the top of your recursive function will clearly show that they aren't doing what you expect.

Issue with my string reverse program

newer programmer here, having trouble diagnosing the issue with my string reversal program. The program is supposed to compare two strings and find out if string x is the reversal of string y and if it is it returns true, if not it returns false.
public class Reverse
{
public static void main(String[] args)
{
System.out.println(isExactReverse("ba", "a"));
System.out.println(isExactReverse("desserts", "stressed"));
System.out.println(isExactReverse("apple", "apple"));
System.out.println(isExactReverse("regal", "lager"));
System.out.println(isExactReverse("war", "raw"));
System.out.println(isExactReverse("pal", "slap"));
}
public static boolean isExactReverse(String x, String y)
{
//To be completed
int counter = 0;
int temp = x.length() - 1;
boolean result = false;
for(int i = 0; i < y.length(); i++)
{
if(x.charAt(temp) == y.charAt(i))
{
counter++;
}
temp--;
}
if(counter == y.length())
{
result = true;
}
return result;
}
}
the output i get is not correct and I am getting a runtime error.
true
true
false
true
true
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.String.charAt(String.java:658)
at Reverse.isExactReverse(Reverse.java:24)
at Reverse.main(Reverse.java:11)
Expected output:
False
True
False
True
True
False
The problem in your code is that it assumes that x and y have the same length. When it is not so, the code either returns a false positive, as in case of "ba"-"a", or crashes, as in case of "pal"-"slap".
Fix this by adding this check at the top of your isExactReverse method:
if (x.length() != y.length()) {
return false;
}
Demo.
The code is certainly able to be compiled. It would be nice if you could specify the problem.
But I guess you got problems getting the correct result. First of all, I would recommend you simplified the code. There is a lot of lines, that don't have to be there.
Here is, what I would do.
public class Reverse
{
public static void main(String[] args)
{
System.out.println(isExactReverse("ba", "a"));
System.out.println(isExactReverse("desserts", "stressed"));
System.out.println(isExactReverse("apple", "apple"));
System.out.println(isExactReverse("regal", "lager"));
System.out.println(isExactReverse("war", "raw"));
System.out.println(isExactReverse("pal", "slap"));
}
public static boolean isExactReverse(String x, String y)
{
//To be completed
int temp = x.length() - 1;
boolean result = false;
for(int i = 0; i < y.length(); i++)
{
if(!x.charAt(temp).equals(y.charAt(i)))
{
return false;
}
temp--;
}
return true;
}
}
This should work. I don't really have an answer for your post, because I don't know you problem, but this is just some kind of help that maybe will resolve your problem.

Java: good programming approach?

I am being asked to learn Java very quickly and I am struggling with not only the verbose syntax but also the expected style and approach requirements.
Given a simple FizzBuzz challenge I produced the following code:
public class FizzBuzz {
public static void main(String[] args) {
boolean hit;
for (int n = 1; n <= 30; n++) {
hit = false;
if (n % 3 == 0) {
System.out.print("Fizz");
hit = true;
}
if (n % 5 == 0) {
System.out.print("Buzz");
hit = true;
}
if (hit != true) {
System.out.print(n);
}
System.out.println();
}
}
}
Asked to refactor this code by the lead programmer and to consider possible future requirements and code managability issues I gave it some thought and produced the following refactored code:
public class FizzBuzz {
public static void main(String[] args) {
boolean hit;
for (int n = 1; n < 30; n++) {
hit = false;
hit = (n % 3 == 0) ? writeAction("Fizz") : hit;
hit = (n % 5 == 0) ? writeAction("Buzz") : hit;
if ( ! hit)
System.out.print(n);
System.out.println();
}
}
private static boolean writeAction(String actionWord){
System.out.print(actionWord);
return true;
}
}
However, the guy who set this task has moved on quite quickly and I never got any feedback on this approach. Am I going in the right direction with this or have I regressed?. To me this should scale better and would be easier to modify. I have also considered that maybe he was expecting some sort of TDD approach? I am aware that I have no tests currently.
This site isn't for reviews, but in case your question gets moved, here is some feedback (from the "clean code" perspective):
your "main" code sits in a main() method. Makes re-using it very hard.
talking about re-use - various things in there prevent re-using it
you have some duplicated code in there
you are violating the single layer of abstraction principle
How I would write something along the lines of:
public class FizzBuzz {
private final OutputStream out;
public FizzBuzz(OutputStream out) {
this.out = out;
}
public void runFizzBuzzUpTo(int n) {
for (int i = 1; i < n; i++) {
if ( writeIfTrue(n % 3 == 0, "Fizz") ) {
continue;
}
if ( writeIfTrue(n % 5 == 0, "Buzz") ) {
continue;
}
out.println(n);
}
}
private boolean writeIfTrue(boolean toCheck, String word) {
if (toCheck) {
out.println(word);
}
return toCheck;
}
public static void main(String[] args) {
new FizzBuzz(System.out).runFizzBuzzUpto(30);
}
}
Things I changed:
made the output the "core" thing of a class
provided the possibility to run for arbitrary positive numbers
Stuff still missing:
"single layere of abstraction" is still not good
instead of fixing "30" in main() - one could check for exactly one argument passed to main() - which would then be used as parameter for runFizzBuzzUpTo()
Of course, the second code is more modular and easier to modify that way. I mostly don't prefer to write the if conditions in the short way...
The method writeAction could be void because you don't have to return anything.
But you have good ideas :)

In Java, how do I test whether a list of `Double` contains a particular value

Background: Floating point numbers have rounding issues, so they should never be compared with "==".
Question: In Java, how do I test whether a list of Double contains a particular value. I am aware of various workarounds, but I am looking for the most elegant solution, presumably the ones that make use of Java or 3rd party library features.
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
// should be 1.38, but end up with 1.3800000000000001
Double d1 = new Double(1.37 + 0.01);
System.out.println("d1=" + d1);
// won't be able to test the element for containment
List<Double> list = new ArrayList<Double>();
list.add(d1);
System.out.println(list.contains(1.38));
}
}
Output is:
d1=1.3800000000000001
false
Thank you.
The general solution would be to write a utility method that loops through the list and checks if each element is within a certain a threshold of the target value. We can do slightly better in Java 8, though, using Stream#anyMatch():
list.stream().anyMatch(d -> (Math.abs(d/d1 - 1) < threshold))
Note that I am using the equality test suggested here.
If you're not using Java 8, I would write a simple utility method along the lines of this:
public static boolean contains(Collection<Double> collection, double key) {
for (double d : collection) {
if (Math.abs(d/key - 1) < threshold)
return true;
}
return false;
}
Note that you might need to add a special case to both of these approaches to check if the list contains 0 (or use the abs(x - y) < eps approach). That would just consist of adding || (abs(x) < eps && abs(y) < eps) to the end of the equality conditions.
Comparing bits wasn't a good idea. Similar to another post, but deals with NaN and Infinities.
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
// should be 1.38, but end up with 1.3800000000000001
Double d1 = 1.37d + 0.01d;
System.out.println("d1=" + d1);
// won't be able to test the element for containment
List<Double> list = new ArrayList<>();
list.add(d1);
System.out.println(list.contains(1.38));
System.out.println(contains(list, 1.38d, 0.00000001d));
}
public static boolean contains(List<Double> list, double value, double precision) {
for (int i = 0, sz = list.size(); i < sz; i++) {
double d = list.get(i);
if (d == value || Math.abs(d - value) < precision) {
return true;
}
}
return false;
}
}
You could wrap the Double in another class that provides a 'close enough' aspect to its equals method.
package com.michaelt.so.doub;
import java.util.HashSet;
import java.util.Set;
public class CloseEnough {
private Double d;
protected long masked;
protected Set<Long> similar;
public CloseEnough(Double d) {
this.d = d;
long bits = Double.doubleToLongBits(d);
similar = new HashSet<Long>();
masked = bits & 0xFFFFFFFFFFFFFFF8L; // 111...1000
similar.add(bits);
similar.add(bits + 1);
similar.add(bits - 1);
}
Double getD() {
return d;
}
#Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof CloseEnough)) {
return false;
}
CloseEnough that = (CloseEnough) o;
for(Long bits : this.similar) {
if(that.similar.contains(bits)) { return true; }
}
return false;
}
#Override
public int hashCode() {
return (int) (masked ^ (masked >>> 32));
}
}
And then some code to demonstrate it:
package com.michaelt.so.doub;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<CloseEnough> foo = new ArrayList<CloseEnough>();
foo.add(new CloseEnough(1.38));
foo.add(new CloseEnough(0.02));
foo.add(new CloseEnough(1.40));
foo.add(new CloseEnough(0.20));
System.out.println(foo.contains(new CloseEnough(0.0)));
System.out.println(foo.contains(new CloseEnough(1.37 + 0.01)));
System.out.println(foo.contains(new CloseEnough(0.01 + 0.01)));
System.out.println(foo.contains(new CloseEnough(1.39 + 0.01)));
System.out.println(foo.contains(new CloseEnough(0.19 + 0.01)));
}
}
The output of this code is:
false
true
true
true
true
(that first false is the compare with 0, just to show that it isn't finding things that aren't there)
CloseEnough is just a simple wrapper around the double that masks the lowest three bits for the hash code (enough that and also stores the valid set of similar numbers in a set. When doing an equals comparison, it uses the sets. Two numbers are equal if they contain a common element in their sets.
That said, I am fairly certain that there are some values that would be problematic with a.equals(b) being true and a.hashCode() == b.hashCode() being false that may still occur at edge conditions for the proper bit patterns - this would make some things (like HashSet and HashMap) 'unhappy' (and would likely make a good question somewhere.
Probably a better approach to this would instead be to extend ArrayList so that the indexOf method handles the similarity between the numbers:
package com.michaelt.so.doub;
import java.util.ArrayList;
public class SimilarList extends ArrayList<Double> {
#Override
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < this.size(); i++) {
if (get(i) == null) {
return i;
}
}
} else {
for (int i = 0; i < this.size(); i++) {
if (almostEquals((Double)o, this.get(i))) {
return i;
}
}
}
return -1;
}
private boolean almostEquals(Double a, Double b) {
long abits = Double.doubleToLongBits(a);
long bbits = Double.doubleToLongBits(b);
// Handle +0 == -0
if((abits >> 63) != (bbits >> 63)) {
return a.equals(b);
}
long diff = Math.abs(abits - bbits);
if(diff <= 1) {
return true;
}
return false;
}
}
Working with this code becomes a bit easier (pun not intended):
package com.michaelt.so.doub;
import java.util.ArrayList;
public class ListTest {
public static void main(String[] args) {
ArrayList foo = new SimilarList();
foo.add(1.38);
foo.add(1.40);
foo.add(0.02);
foo.add(0.20);
System.out.println(foo.contains(0.0));
System.out.println(foo.contains(1.37 + 0.01));
System.out.println(foo.contains(1.39 + 0.01));
System.out.println(foo.contains(0.19 + 0.01));
System.out.println(foo.contains(0.01 + 0.01));
}
}
The output of this code is:
false
true
true
true
true
In this case, the bit fiddling is done in the SimilarList based on the code HasMinimalDifference. Again, the numbers are converted into bits, but this time the math is done in the comparison rather than trying to work with the equality and hash code of a wrapper object.
Background: Floating point numbers have rounding issues, so they should never be compared with "==".
This is false. You do need to be awake when writing floating-point code, but reasoning about the errors that are possible in your program is in many cases straightforward. If you cannot do this, it behooves you to at least get an empirical estimate of how wrong your computed values are and think about whether the errors you're seeing are acceptably small.
What this means is that you cannot avoid getting your hands dirty and thinking about what your program is doing. If you're going to work with approximate comparisons, you need to have some idea of what differences mean that two values really are different and what differences mean that two quantities might be the same.
// should be 1.38, but end up with 1.3800000000000001
This is also false. Notice that the closest double to 1.37 is 0x1.5eb851eb851ecp+0 and the closest double to 0.01 is 0x1.47ae147ae147bp-7. When you add these, you get 0x1.6147ae147ae14f6p+0, which rounds to 0x1.6147ae147ae15p+0. The closest double to 1.38 is 0x1.6147ae147ae14p+0.
There are several reasons why two slightly different doubles do not compare ==. Here are two:
If they did so, that would break transitivity. (There would be a, b, and c such that a == b and b == c but !(a == c).
If they did so, carefully-written numerical code would stop working.
The real issue with trying to find a double in a list is that NaN does not compare == to itself. You may try using a loop that checks needle == haystack[i] || needle != needle && haystack[i] != haystack[i].

Java / JUnit - AssertionError testing a pre-defined polynomial

I have a Term class to define a polynomial:
public class Term
{
final private int coef;
final private int expo;
private static Term zero, unit;
static
{
try
{
zero = new Term(0, 0); // the number zero
unit = new Term(1, 0); // the number one
}
catch (Exception e)
{
// constructor will not throw an exception here anyway
}
}
/**
*
* #param c
* The coefficient of the new term
* #param e
* The exponent of the new term (must be non-negative)
* #throws NegativeExponent
*/
public Term(int c, int e) throws NegativeExponent
{
if (e < 0)
throw new NegativeExponent();
coef = c;
expo = (coef == 0) ? 1 : e;
}
final public static Term Zero = zero;
final public static Term Unit = unit;
public boolean isConstant()
{
boolean isConst = false;
if (this.expo == 0)
{
isConst = true;
}
return isConst;
}
}
And I have the JUnit test as follows:
/*
* const1 isConstant(zero) => true (0,0)
* const2 isConstant(unit) => true (1,0)
* const3 isConstant(0,5) => true
* const4 isConstant(5,1) => false
*/
#Test
public void const1() throws TError { assertTrue(Term.Zero.isConstant()); }
#Test
public void const2() throws TError { assertTrue(Term.Unit.isConstant()); }
#Test
public void const3() throws TError { assertTrue(new Term(0,5).isConstant()); }
#Test
public void const4() throws TError { assertFalse(new Term(5,1).isConstant()); }
Tests 2 and 4 pass as they should, but Tests 1 and 3 come up as failures and I cannot work out why, "Zero" is defining the polynomial as (0,0) and the other is defining it as (0,5). So by my thinking, the 1st one should give a green tick and the 3rd test should give a red cross as it has 5 as the exponent.
Any ideas?
Please review your constructor:
public Term(int c, int e) throws NegativeExponent{
if (e < 0) throw new NegativeExponent();
coef = c;
expo = (coef == 0) ? 1 : e;
}
When coef == 0, then exp is assigned with 1.
This makes zero as (0,1) not (0,0). this is the reason for test outcome as below:
const1 -> false as expo = 1-->failure as expecting true
const2 -> true as expo = 0 -->success as expecting true
const3 -> false as expo = 5.-->failure as expecting true
const4 -> false as expo = 1.-->success as expecting false
EDIT: To reverse fix your code to make the test cases pass, I think you may update your constructor as below:
public Term(int c, int e) throws NegativeExponent{
if (e < 0) throw new NegativeExponent();
coef = c;
expo = (c == 0 && e != 0) ? 0 : e;
}
Here, I have updated the constructor to set expo as 0, if coef is 0 as any expo for coef 0 is immaterial.
Yogendra covered why your first test fails. Your const3() fails (for me at least) because new Term(0, 5) has a expo of 5, which gets replaced with 1 b/c of the coef, but 1 is still not 0 so new Term(0, 5) is NOT constant.
Not that you asked, but I'll also give you some general Java pointers for the future...
1) Use all caps for static constants
public static final Term ZERO = new Term(0, 0);
public static final Term UNIT = new Term(1, 0);
this is just a convention that the Java community expects.
2) Give your test cases meaningful names. One powerful use of test cases is that they can double as documentation of your assumptions at the time. Rather than const1() which tells a fellow developer nothing, use a descriptive name like zeroShouldBeAConstant(). This tells the next person who looks at your code that Zero should be considered a constant in this system.
3) Whenever you are returning a boolean variable, consider just returning the statement. Compare the function below to yours and tell me which one is more readable:
public boolean isConstant()
{
return expo == 0;
}
It is less code and hopefully easier to read.
Good luck!

Categories

Resources