Created
January 5, 2016 17:25
-
-
Save blizzy78/22f12c2ae2dcacbda3b2 to your computer and use it in GitHub Desktop.
Maths Puzzle: The self descriptive number
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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