Skip to content

Instantly share code, notes, and snippets.

@blizzy78
Created January 5, 2016 17:25
Show Gist options
  • Select an option

  • Save blizzy78/22f12c2ae2dcacbda3b2 to your computer and use it in GitHub Desktop.

Select an option

Save blizzy78/22f12c2ae2dcacbda3b2 to your computer and use it in GitHub Desktop.
Maths Puzzle: The self descriptive number
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Supplier;
import java.util.stream.Stream;
/*
Maths Puzzle: The self descriptive number
https://www.youtube.com/watch?v=K6Qc4oK_HqY
4: 1210
4: 2020
5: 21200
7: 3211000
8: 42101000
9: 521001000
10: 6210001000
*/
public class SelfRef {
public static class Ints implements Supplier<Integer> {
private final AtomicInteger CURRENT = new AtomicInteger();
private Ints(int start) {
CURRENT.set(start);
}
@Override
public Integer get() {
return CURRENT.getAndIncrement();
}
}
public static class Longs implements Supplier<Long> {
private final AtomicLong CURRENT = new AtomicLong();
@Override
public Long get() {
return CURRENT.getAndIncrement();
}
}
private static final long[] POW = new long[11];
static {
for (int i = 0; i <= 10; i++) {
POW[i] = (long) Math.pow(10, i);
}
}
public static void main(String... args) {
for (int numDigits = 1; numDigits <= 10; numDigits++) {
int myNumDigits = numDigits;
long max = tenPow(myNumDigits) - 1L;
Stream.generate(new Longs()).parallel()
.limit(max)
.filter(number -> isValidNumber(number, myNumDigits))
.forEach(number -> print(myNumDigits, number));
}
}
private static synchronized void print(int numDigits, long number) {
System.out.printf("%d: %d", numDigits, number).println();
}
private static boolean isValidNumber(long number, int numDigits) {
if (crossSum(number, numDigits) != numDigits) {
return false;
}
for (int idx = 0; idx < numDigits; idx++) {
if (count(number, idx, numDigits) != getDigit(number, idx, numDigits)) {
return false;
}
}
return true;
}
private static int crossSum(long number, int numDigits) {
int result = 0;
for (int idx = 0; idx < numDigits; idx++) {
result += getDigit(number, idx, numDigits);
}
return result;
}
private static int count(long number, int searchFor, int numDigits) {
int result = 0;
for (int idx = 0; idx < numDigits; idx++) {
if (getDigit(number, idx, numDigits) == searchFor) {
result++;
}
}
return result;
}
private static int getDigit(long number, int digitIndex, int numDigits) {
return (int) ((number / tenPow(numDigits - 1 - digitIndex)) % 10);
}
private static long tenPow(int x) {
return POW[x];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment