Wasteful, equidigital and frugal numbers: Difference between revisions
Content added Content deleted
(add RPL) |
(New post.) |
||
Line 97: | Line 97: | ||
+/1e6>1+I. 1=b11 NB. frugal |
+/1e6>1+I. 1=b11 NB. frugal |
||
3428</syntaxhighlight> |
3428</syntaxhighlight> |
||
=={{header|Java}}== |
|||
<syntaxhighlight lang="java"> |
|||
import java.util.ArrayList; |
|||
import java.util.Arrays; |
|||
import java.util.HashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
import java.util.function.Function; |
|||
import java.util.stream.Collectors; |
|||
import java.util.stream.IntStream; |
|||
public final class WastefulEquidigitalAndFrugalNumbers { |
|||
public static void main(String[] args) { |
|||
createFactors(2_700_000); |
|||
final int tinyLimit = 50; |
|||
final int lowerLimit = 10_000; |
|||
final int upperLimit = 1_000_000; |
|||
for ( int base : List.of( 10, 11 ) ) { |
|||
Map<Category, Count> counts = Arrays.stream(Category.values()) |
|||
.collect(Collectors.toMap( Function.identity(), value -> new Count(0, 0) )); |
|||
Map<Category, List<Integer>> lists = Arrays.stream(Category.values()) |
|||
.collect(Collectors.toMap( Function.identity(), value -> new ArrayList<Integer>() )); |
|||
int number = 1; |
|||
System.out.println("FOR BASE " + base + ":" + System.lineSeparator()); |
|||
while ( counts.values().stream().anyMatch( count -> count.lowerCount < lowerLimit ) ) { |
|||
Category category = category(number, base); |
|||
Count count = counts.get(category); |
|||
if ( count.lowerCount < tinyLimit || count.lowerCount == lowerLimit - 1 ) { |
|||
lists.get(category).add(number); |
|||
} |
|||
count.lowerCount += 1; |
|||
if ( number < upperLimit ) { |
|||
count.upperCount += 1; |
|||
} |
|||
number += 1; |
|||
} |
|||
for ( Category category : Category.values() ) { |
|||
System.out.println("First " + tinyLimit + " " + category + " numbers:"); |
|||
for ( int i = 0; i < tinyLimit; i++ ) { |
|||
System.out.print(String.format("%4d%s", lists.get(category).get(i), (i % 10 == 9 ? "\n" : " "))); |
|||
} |
|||
System.out.println(); |
|||
System.out.println(lowerLimit + "th " + category + " number: " + lists.get(category).get(tinyLimit)); |
|||
System.out.println(); |
|||
} |
|||
System.out.println("For natural numbers less than " + upperLimit + ", the breakdown is as follows:"); |
|||
System.out.println(" Wasteful numbers : " + counts.get(Category.Wasteful).upperCount); |
|||
System.out.println(" Equidigital numbers : " + counts.get(Category.Equidigital).upperCount); |
|||
System.out.println(" Frugal numbers : " + counts.get(Category.Frugal).upperCount); |
|||
System.out.println(); |
|||
} |
|||
} |
|||
private enum Category { Wasteful, Equidigital, Frugal } |
|||
/** |
|||
* Factorise the numbers from 1 to limit, both inclusive |
|||
*/ |
|||
private static void createFactors(int limit) { |
|||
factors = IntStream.rangeClosed(0, limit).boxed() |
|||
.map( integer -> new HashMap<Integer, Integer>() ).collect(Collectors.toList()); |
|||
factors.get(1).merge(1, 1, Integer::sum); |
|||
for ( int n = 1; n < limit; n++ ) { |
|||
if ( factors.get(n).isEmpty() ) { |
|||
long nCopy = n; |
|||
while ( nCopy < limit ) { |
|||
for ( long i = nCopy; i < limit; i += nCopy ) { |
|||
factors.get((int) i).merge(n, 1, Integer::sum); |
|||
} |
|||
nCopy *= n; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
/** |
|||
* Return the number of digits in the given number written in the given base |
|||
*/ |
|||
private static int digitCount(int number, int base) { |
|||
int result = 0; |
|||
while ( number != 0 ) { |
|||
result += 1; |
|||
number /= base; |
|||
} |
|||
return result; |
|||
} |
|||
/** |
|||
* Return the total number of digits used in the prime factorisation |
|||
* of the given number written in the given base |
|||
*/ |
|||
private static int factorCount(int number, int base) { |
|||
int result = 0; |
|||
for ( Map.Entry<Integer, Integer> entry : factors.get(number).entrySet() ) { |
|||
result += digitCount(entry.getKey(), base); |
|||
if ( entry.getValue() > 1 ) { |
|||
result += digitCount(entry.getValue(), base); |
|||
} |
|||
} |
|||
return result; |
|||
} |
|||
/** |
|||
* Return the category of the given number written in the given base |
|||
*/ |
|||
private static Category category(int number, int base) { |
|||
final int digitCount = digitCount(number, base); |
|||
final int factorCount = factorCount(number, base); |
|||
return ( digitCount < factorCount ) ? Category.Wasteful : |
|||
( digitCount > factorCount ) ? Category.Frugal : Category.Equidigital; |
|||
} |
|||
private static class Count { |
|||
public Count(int aLowerCount, int aUpperCount) { |
|||
lowerCount = aLowerCount; upperCount = aUpperCount; |
|||
} |
|||
private int lowerCount, upperCount; |
|||
} |
|||
private static List<Map<Integer, Integer>> factors; |
|||
} |
|||
</syntaxhighlight> |
|||
{{ out }} |
|||
<pre> |
|||
FOR BASE 10: |
|||
First 50 Wasteful numbers: |
|||
4 6 8 9 12 18 20 22 24 26 |
|||
28 30 33 34 36 38 39 40 42 44 |
|||
45 46 48 50 51 52 54 55 56 57 |
|||
58 60 62 63 65 66 68 69 70 72 |
|||
74 75 76 77 78 80 82 84 85 86 |
|||
10000th Wasteful number: 14346 |
|||
First 50 Equidigital numbers: |
|||
1 2 3 5 7 10 11 13 14 15 |
|||
16 17 19 21 23 25 27 29 31 32 |
|||
35 37 41 43 47 49 53 59 61 64 |
|||
67 71 73 79 81 83 89 97 101 103 |
|||
105 106 107 109 111 112 113 115 118 119 |
|||
10000th Equidigital number: 33769 |
|||
First 50 Frugal numbers: |
|||
125 128 243 256 343 512 625 729 1024 1029 |
|||
1215 1250 1280 1331 1369 1458 1536 1681 1701 1715 |
|||
1792 1849 1875 2048 2187 2197 2209 2401 2560 2809 |
|||
3125 3481 3584 3645 3721 4096 4374 4375 4489 4802 |
|||
4913 5041 5103 5329 6241 6250 6561 6859 6889 7203 |
|||
10000th Frugal number: 1953125 |
|||
For natural numbers less than 1000000, the breakdown is as follows: |
|||
Wasteful numbers : 831231 |
|||
Equidigital numbers : 165645 |
|||
Frugal numbers : 3123 |
|||
FOR BASE 11: |
|||
First 50 Wasteful numbers: |
|||
4 6 8 9 10 12 18 20 22 24 |
|||
26 28 30 33 34 36 38 39 40 42 |
|||
44 45 46 48 50 51 52 54 55 56 |
|||
57 58 60 62 63 65 66 68 69 70 |
|||
72 74 75 76 77 78 80 82 84 85 |
|||
10000th Wasteful number: 12890 |
|||
First 50 Equidigital numbers: |
|||
1 2 3 5 7 11 13 14 15 16 |
|||
17 19 21 23 25 27 29 31 32 35 |
|||
37 41 43 47 49 53 59 61 64 67 |
|||
71 73 79 81 83 89 97 101 103 107 |
|||
109 113 121 122 123 127 129 131 133 134 |
|||
10000th Equidigital number: 33203 |
|||
First 50 Frugal numbers: |
|||
125 128 243 256 343 512 625 729 1024 1331 |
|||
1369 1458 1536 1681 1701 1715 1792 1849 1875 2048 |
|||
2187 2197 2209 2401 2560 2809 3072 3125 3481 3584 |
|||
3645 3721 4096 4374 4375 4489 4802 4913 5041 5103 |
|||
5120 5329 6241 6250 6561 6859 6889 7168 7203 7921 |
|||
10000th Frugal number: 2659171 |
|||
For natural numbers less than 1000000, the breakdown is as follows: |
|||
Wasteful numbers : 795861 |
|||
Equidigital numbers : 200710 |
|||
Frugal numbers : 3428 |
|||
</pre> |
|||
=={{header|Julia}}== |
=={{header|Julia}}== |