Skip to content

Instantly share code, notes, and snippets.

@nipafx
Last active February 2, 2016 07:11
Show Gist options
  • Save nipafx/3e8492f7fb3afe6c1712 to your computer and use it in GitHub Desktop.
Save nipafx/3e8492f7fb3afe6c1712 to your computer and use it in GitHub Desktop.
Computing factors with Java 8 streams - see https://bit.ly/1VF85Fa 17:28
package org.codefx.lab.aliquot;
import com.google.common.collect.ImmutableSetMultimap;
import org.junit.Test;
import java.util.Collection;
import java.util.List;
import java.util.stream.IntStream;
import static java.lang.Math.sqrt;
import static java.util.stream.Collectors.toList;
import static java.util.stream.IntStream.of;
import static java.util.stream.IntStream.range;
import static java.util.stream.IntStream.rangeClosed;
import static org.assertj.core.api.Assertions.assertThat;
public class Aliquot {
interface Factorization {
IntStream factorsOf(int number);
}
static class NealFordFactorization implements Factorization {
@Override
public IntStream factorsOf(int number) {
List<Integer> factors = range(1, (int) (sqrt(number) + 1))
.filter(potential -> number % potential == 0)
.boxed()
.collect(toList());
List<Integer> factorsAboveSqrt = factors
.stream()
.map(e -> number / e)
.collect(toList());
factors.addAll(factorsAboveSqrt);
return factors.stream().mapToInt(i -> i).distinct();
}
}
static class NiPaFactorization implements Factorization {
@Override
public IntStream factorsOf(int number) {
return rangeClosed(1, number)
.limit((int) sqrt(number))
.filter(potential -> number % potential == 0)
.flatMap(smallFactor -> of(smallFactor, number / smallFactor).distinct());
}
}
private static final ImmutableSetMultimap<Integer, Integer> FACTORS =
ImmutableSetMultimap.<Integer, Integer>builder()
// number, factor_1, factor_2, ...
.putAll(1, 1)
.putAll(2, 1, 2)
.putAll(3, 1, 3)
.putAll(4, 1, 2, 4)
.putAll(5, 1, 5)
.putAll(6, 1, 2, 3, 6)
.putAll(7, 1, 7)
.putAll(8, 1, 2, 4, 8)
.putAll(9, 1, 3, 9)
.putAll(10, 1, 2, 5, 10)
.build();
private static final Factorization NEAL_FORD = new NealFordFactorization();
private static final Factorization NIPA = new NiPaFactorization();
@Test
public void factorsOf() {
factorsOf_with(NEAL_FORD);
factorsOf_with(NIPA);
}
public void factorsOf_with(Factorization f) {
FACTORS.asMap().entrySet().forEach(numbersWithFactors -> {
Integer number = numbersWithFactors.getKey();
Collection<Integer> factors = numbersWithFactors.getValue();
assertThat(f.factorsOf(number).boxed())
.as("Factorize %d, which should result in %s.", number, factors)
.containsOnlyElementsOf(factors);
}
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment