/**
This class generates all the factors of a number.
*/
public class FactorGenerator
{
private boolean answer;
private int factor, number;
/**
Creates a FactorGenerator object used to determine the factor of
an input value.
@param aNum is the input value
*/
public FactorGenerator(int aNum)
{
number = aNum;
factor = 2;
}
/**
Determine whether or not there are more factors.
@return true there are more factors
*/
public boolean hasMoreFactors()
{
answer = true;
while(number % factor != 0 && answer == true)
{
if (factor >= number)
{
answer = false;
}
factor++;
}
return answer;
}
/**
Calculate the next factor of a value.
@return factor the next factor
*/
public int nextFactor()
{
while(factor < number)
{
if(number%factor == 0)
{
number/= factor;
break;
}
else
factor++;
}
return factor;
}
}
Refactorings
No refactoring yet !
Eineki
November 26, 2008, November 26, 2008 23:24, permalink
The two functions, nextFactor and has nextFactor shared the common pattern I refactored into the findNextFactor() private method.
You have obfuscated the while conditions a bit but I'm sure you can see that the loop laying after the two sligthy different syntax are the same.
Once you get this, the two method get straight simple.
I added a runtime exception to cover the case of a call of nextFactor method without a previous check of hasNextFactor
I hope you can get through my english to the explanation :)
// line 44 while condition have to change to or you don't apply the last division //(but return the last factor everytime) => number don't become 1 => hasnextfactor misbehave. while (factor <= number)
public class factorGenerator
{
private int number;
private int factor;
/**
* Creates a FactorGenerator object used to determine the factor of an input value.
* @param aNum is the input value
**/
public factorGenerator(int aNum)
{
number = aNum;
factor = 2;
}
/**
* Find the next factor of a value.
* @return factor the next factor
**/
private int findNextFactor()
{
while((factor < number) && ((number%factor)!=0)) factor++;
return factor;
}
/**
* Apply the next factor of a value.
* @return factor the next factor
**/
public int nextFactor() throws RuntimeException
{
int result = findNextFactor();
if (result <= number) {
number/= result;
return result;
} else
throw new RuntimeException();
}
/**
Determine whether or not there are more factors.
@return true there are more factors
*/
public boolean hasMoreFactors()
{
return (findNextFactor()<=number);
}
}
Uday
January 13, 2009, January 13, 2009 04:21, permalink
Same as Eineki But a little smaller...
/**
* This class generates all the factors of a number.
*/
public class FactorGenerator {
private int factor, number;
/**
* Creates a FactorGenerator object used to determine the factor of
* an input value.
*
* @param aNum is the input value
*/
public FactorGenerator(int aNum) {
number = aNum;
factor = 2;
}
/**
* Determine whether or not there are more factors.
*
* @return true there are more factors
*/
public boolean hasMoreFactors() {
while (factor <= number) {
if (number % factor == 0)
return true;
else
factor++;
}
return false;
}
/**
* Calculate the next factor of a value.
*
* @return factor the next factor
*/
public int nextFactor() {
if(hasMoreFactors()){
number /= factor;
return factor;
}
else
throw new RuntimeException("There are no more factors");
}
}
DojoCoders
January 15, 2009, January 15, 2009 19:49, permalink
This is the first pass at refactoring from our coding dojo.
We've implemented a new List method, to abstract the implementation details (as we expect that most client code would look like the implementation of getFactors anyway)
We've also included our test suite.
We'll be looking at it again next week.
import static java.util.Arrays.asList;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import java.util.List;
import org.junit.Test;
public class FactoringIntegersTest {
@Test
public void shouldReturnCorrectFactorsForValueOf60() throws Exception {
// Given
FactoringIntegers factoriser = new FactoringIntegers(60);
assertThat(factoriser.nextFactor(), is(2));
assertThat(factoriser.hasMoreFactors(), is(true));
assertThat(factoriser.nextFactor(), is(2));
assertThat(factoriser.hasMoreFactors(), is(true));
assertThat(factoriser.nextFactor(), is(3));
assertThat(factoriser.hasMoreFactors(), is(true));
assertThat(factoriser.nextFactor(), is(5));
assertThat(factoriser.hasMoreFactors(), is(false));
}
@Test
public void shouldReturnCorrectFactorsForValueOf82() throws Exception {
//Given
FactoringIntegers factoriser = new FactoringIntegers(82);
assertThat(factoriser.nextFactor(), is(2));
assertThat(factoriser.hasMoreFactors(), is(true));
assertThat(factoriser.nextFactor(), is(41));
assertThat(factoriser.hasMoreFactors(), is(false));
}
@Test
public void shouldReturnAListForValueOf90() throws Exception {
//Given
FactoringIntegers factoriser = new FactoringIntegers(90);
//When
List<Integer> result = factoriser.getFactors();
//Then
assertThat(result.size(), is(4));
assertThat(productOf(result), is (90));
assertThat(result, is(equalTo(asList(2,3,3,5))));
}
private Integer productOf(List<Integer> listOfIntegers) {
Integer result=1;
for(Integer factor : listOfIntegers) {
result *= factor;
}
return result;
}
}
import java.util.ArrayList;
import java.util.List;
import static java.util.Collections.unmodifiableList;
/**
* This class generates all the factors of a number.
* http://refactormycode.com/codes/625-factoring-integers
*/
public class FactoringIntegers {
private boolean answer;
private int factor, number;
/**
* Creates a FactorGenerator object used to determine the factor of an input
* value.
*
* @param aNum
* is the input value
*/
public FactoringIntegers(int aNum) {
number = aNum;
factor = 2;
}
/**
* Determine whether or not there are more factors.
*
* @return true there are more factors
*/
public boolean hasMoreFactors() {
answer = true;
while (number % factor != 0 && answer == true) {
if (factor >= number) {
answer = false;
}
factor++;
}
return answer;
}
/**
* Calculate the next factor of a value.
*
* @return factor the next factor
*/
public int nextFactor() {
while (factor <= number) {
if (number % factor == 0) {
number /= factor;
break;
} else
factor++;
}
return factor;
}
public List<Integer> getFactors() {
List<Integer> result = new ArrayList<Integer>();
while (hasMoreFactors()) {
result.add(nextFactor());
}
return unmodifiableList(result);
}
}
tetrojensen
August 17, 2009, August 17, 2009 05:14, permalink
How do I do this.....
/**
* a. Instead of "foo", "biz" or "baz", the factors of the number should be shown after it if the
* number is not a prime number. Otherwise, the sentence "The number is prime." is shown
* after the number.
* b. Appropriate comments should be included in the source code.
**/
public class FooBizBaz {
public static void main(String[]args){
int num;
for (num=1; num<=50; num+=1){
System.out.print(num+" ");
if (num%3==0)
System.out.print("foo"+" ");
if (num%5==0)
System.out.print("biz"+" ");
if (num%7==0)
System.out.print("baz"+" ");
System.out.println();
}
System.exit(0);
}//end of main
}//end of class
yma
January 19, 2010, January 19, 2010 11:44, permalink
If i call hasMoreFactors() again and again, it will finally say 'No', even i never call nextFactor()...
hasMoreFactors shouldn't use the variable factor but a copy of it.
After taking all the factors of 60 (2, 2, 3, 5), when I invoke hasMoreFactors(), it should return false, cause there are no other factors beyond that 5, yet I can only get it to return true. Any ideas?