Esthetic numbers
You are encouraged to solve this task according to the task description, using any language you may know.
An esthetic number is a positive integer where every adjacent digit differs from its neighbour by 1.
- E.G.
- 12 is an esthetic number. One and two differ by 1.
- 5654 is an esthetic number. Each digit is exactly 1 away from its neighbour.
- 890 is not an esthetic number. Nine and zero differ by 9.
These examples are nominally in base 10 but the concept extends easily to numbers in other bases. Traditionally, single digit numbers are included in esthetic numbers; zero may or may not be. For our purposes, for this task, do not include zero (0) as an esthetic number. Do not include numbers with leading zeros.
Esthetic numbers are also sometimes referred to as stepping numbers.
- Task
- Write a routine (function, procedure, whatever) to find esthetic numbers in a given base.
- Use that routine to find esthetic numbers in bases 2 through 16 and display, here on this page, the esthectic numbers from index (base × 4) through index (base × 6), inclusive. (E.G. for base 2: 8th through 12th, for base 6: 24th through 36th, etc.)
- Find and display, here on this page, the base 10 esthetic numbers with a magnitude between 1000 and 9999.
- Stretch: Find and display, here on this page, the base 10 esthetic numbers with a magnitude between 1.0e8 and 1.3e8.
- Related task
- See also
11l
F isEsthetic(=n, b)
I n == 0 {R 0B}
V i = n % b
n I/= b
L n > 0
V j = n % b
I abs(i - j) != 1
R 0B
n I/= b
i = j
R 1B
F listEsths(Int64 n1, n2, m1, m2; perLine, all)
[Int64] esths
F dfs(Int64 n, m, i) -> Void
I i C n .. m
@esths.append(i)
I i == 0 | i > m {R}
V d = i % 10
V i1 = i * 10 + d - 1
V i2 = i1 + 2
I d == 0
@dfs(n, m, i2)
E I d == 9
@dfs(n, m, i1)
E
@dfs(n, m, i1)
@dfs(n, m, i2)
L(i) 10
dfs(n2, m2, i)
print(‘Base 10: ’esths.len‘ esthetic numbers between ’n1‘ and ’m1‘:’)
I all
L(esth) esths
print(esth, end' I (L.index + 1) % perLine == 0 {"\n"} E ‘ ’)
print()
E
L(i) 0 .< perLine
print(esths[i], end' ‘ ’)
print("\n............")
L(i) esths.len - perLine .< esths.len
print(esths[i], end' ‘ ’)
print()
print()
L(b) 2..16
print(‘Base ’b‘: ’(4 * b)‘th to ’(6 * b)‘th esthetic numbers:’)
V n = Int64(1)
V c = Int64(0)
L c < 6 * b
I isEsthetic(n, b)
c++
I c >= 4 * b
print(String(n, radix' b), end' ‘ ’)
n++
print("\n")
listEsths(1000, 1010, 9999, 9898, 16, 1B)
listEsths(100'000'000, 101'010'101, 130'000'000, 123'456'789, 9, 1B)
listEsths(100'000'000'000, 101'010'101'010, 130'000'000'000, 123'456'789'898, 7, 0B)
listEsths(100'000'000'000'000, 101'010'101'010'101, 130'000'000'000, 123'456'789'898'989, 5, 0B)
listEsths(100'000'000'000'000'000, 101'010'101'010'101'010, 130'000'000'000'000'000, 123'456'789'898'989'898, 4, 0B)
- Output:
Base 2: 8th to 12th esthetic numbers: 10101010 101010101 1010101010 10101010101 101010101010 Base 3: 12th to 18th esthetic numbers: 1210 1212 2101 2121 10101 10121 12101 Base 4: 16th to 24th esthetic numbers: 323 1010 1012 1210 1212 1232 2101 2121 2123 Base 5: 20th to 30th esthetic numbers: 323 343 432 434 1010 1012 1210 1212 1232 1234 2101 Base 6: 24th to 36th esthetic numbers: 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234 Base 7: 28th to 42th esthetic numbers: 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232 Base 8: 32th to 48th esthetic numbers: 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212 Base 9: 36th to 54th esthetic numbers: 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210 Base 10: 40th to 60th esthetic numbers: 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012 Base 11: 44th to 66th esthetic numbers: 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 A98 A9A 1010 Base 12: 48th to 72th esthetic numbers: 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA BA9 BAB Base 13: 52th to 78th esthetic numbers: 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB CBA Base 14: 56th to 84th esthetic numbers: 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC Base 15: 60th to 90th esthetic numbers: 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC CDE DCB DCD Base 16: 64th to 96th esthetic numbers: 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC CDE DCB DCD DED DEF EDC Base 10: 61 esthetic numbers between 1000 and 9999: 1010 1012 1210 1212 1232 1234 2101 2121 2123 2321 2323 2343 2345 3210 3212 3232 3234 3432 3434 3454 3456 4321 4323 4343 4345 4543 4545 4565 4567 5432 5434 5454 5456 5654 5656 5676 5678 6543 6545 6565 6567 6765 6767 6787 6789 7654 7656 7676 7678 7876 7878 7898 8765 8767 8787 8789 8987 8989 9876 9878 9898 Base 10: 126 esthetic numbers between 100000000 and 130000000: 101010101 101010121 101010123 101012101 101012121 101012123 101012321 101012323 101012343 101012345 101210101 101210121 101210123 101212101 101212121 101212123 101212321 101212323 101212343 101212345 101232101 101232121 101232123 101232321 101232323 101232343 101232345 101234321 101234323 101234343 101234345 101234543 101234545 101234565 101234567 121010101 121010121 121010123 121012101 121012121 121012123 121012321 121012323 121012343 121012345 121210101 121210121 121210123 121212101 121212121 121212123 121212321 121212323 121212343 121212345 121232101 121232121 121232123 121232321 121232323 121232343 121232345 121234321 121234323 121234343 121234345 121234543 121234545 121234565 121234567 123210101 123210121 123210123 123212101 123212121 123212123 123212321 123212323 123212343 123212345 123232101 123232121 123232123 123232321 123232323 123232343 123232345 123234321 123234323 123234343 123234345 123234543 123234545 123234565 123234567 123432101 123432121 123432123 123432321 123432323 123432343 123432345 123434321 123434323 123434343 123434345 123434543 123434545 123434565 123434567 123454321 123454323 123454343 123454345 123454543 123454545 123454565 123454567 123456543 123456545 123456565 123456567 123456765 123456767 123456787 123456789 Base 10: 911 esthetic numbers between 100000000000 and 130000000000: 101010101010 101010101012 101010101210 101010101212 101010101232 101010101234 101010121010 ............ 123456787678 123456787876 123456787878 123456787898 123456789876 123456789878 123456789898 Base 10: 6225 esthetic numbers between 100000000000000 and 130000000000: 101010101010101 101010101010121 101010101010123 101010101012101 101010101012121 ............ 123456789898767 123456789898787 123456789898789 123456789898987 123456789898989 Base 10: 44744 esthetic numbers between 100000000000000000 and 130000000000000000: 101010101010101010 101010101010101012 101010101010101210 101010101010101212 ............ 123456789898987898 123456789898989876 123456789898989878 123456789898989898
ALGOL 68
As with other solutions here, uses brute-force for the main task, generates the numbers for the stretch goal.
BEGIN # find some esthetic numbers: numbers whose successive digits differ by 1 #
# returns TRUE if n is esthetic in the specified base, FALSE otherwise #
PRIO ISESTHETIC = 1;
OP ISESTHETIC = ( INT n, base )BOOL:
BEGIN
INT v := ABS n;
BOOL is esthetic := TRUE;
INT prev digit := v MOD base;
v OVERAB base;
WHILE v > 0 AND is esthetic
DO
INT next digit := v MOD base;
is esthetic := ABS ( next digit - prev digit ) = 1;
prev digit := next digit;
v OVERAB base
OD;
is esthetic
END # ISESTHETIC # ;
# returns an array of the first n esthetic numbers in the specified base #
PRIO ESTHETIC = 1;
OP ESTHETIC = ( INT n, base )[]INT:
BEGIN
[ 1 : n ]INT result;
INT e count := 0;
FOR i WHILE e count < n DO
IF i ISESTHETIC base THEN result[ e count +:= 1 ] := i FI
OD;
result
END # ESTHETIC # ;
# returns a string erpresentation of n in the specified base, 2 <= base <= 16 must be TRUE #
PRIO TOBASESTRING = 1;
OP TOBASESTRING = ( INT n, base )STRING:
IF base < 2 OR base > 16
THEN # invalid vbase #
"?" + whole( n, 0 ) + ":" + whole( base, 0 ) + "?"
ELSE
INT v := ABS n;
STRING digits = "0123456789abcdef";
STRING result := digits[ ( v MOD base ) + 1 ];
WHILE ( v OVERAB base ) > 0 DO
digits[ ( v MOD base ) + 1 ] +=: result
OD;
IF n < 0 THEN "-" +=: result FI;
result
FI # TOBASESTRING # ;
# sets count to the number of esthetic numbers with length digits in base b less than max #
# also displays the esthetic numbers #
PROC show esthetic = ( INT number, base, length, max, REF INT count )VOID:
IF length = 1
THEN # number is esthetic #
IF number <= max THEN
# number is in the required range #
print( ( " ", whole( number, 0 ) ) );
IF ( count +:= 1 ) MOD 9 = 0 THEN print( ( newline ) ) FI
FI
ELSE
# find the esthetic numbers that start with number #
INT digit = number MOD base;
INT prefix = number * base;
IF digit > 0 THEN # can have a lower digit #
show esthetic( prefix + ( digit - 1 ), base, length - 1, max, count )
FI;
IF digit < base - 1 THEN # can have a higher digit #
show esthetic( prefix + ( digit + 1 ), base, length - 1, max, count )
FI
FI # show esthetic # ;
# task #
# esthetic numbers from base * 4 to base * 6 for bases 2 to 16 #
FOR base FROM 2 TO 16 DO
INT e from = base * 4;
INT e to = base * 6;
print( ( "Esthetic numbers ", whole( e from, 0 ), " to ", whole( e to, 0 ), " in base ", whole( base, 0 ), newline ) );
[]INT e numbers = e to ESTHETIC base;
print( ( " " ) );
FOR n FROM e from TO e to DO
print( ( " ", e numbers[ n ] TOBASESTRING base ) )
OD;
print( ( newline ) )
OD;
# esthetic base 10 numbers between 1000 and 9999 #
print( ( "Base 10 eshetic numbers between 1000 and 9999", newline ) );
INT e count := 0;
FOR i FROM 1000 TO 9999 DO
IF i ISESTHETIC 10 THEN
print( ( " ", whole( i, 0 ) ) );
IF ( e count +:= 1 ) MOD 16 = 0 THEN print( ( newline ) ) FI
FI
OD;
print( ( newline, newline ) );
print( ( "Esthetic numbers between 100 000 000 and 130 000 000:", newline ) );
e count := 0;
show esthetic( 1, 10, 9, 130 000 000, e count );
print( ( newline ) );
print( ( "Found ", whole( e count, 0 ), " esthetic numbers", newline ) )
END
- Output:
Esthetic numbers 8 to 12 in base 2 10101010 101010101 1010101010 10101010101 101010101010 Esthetic numbers 12 to 18 in base 3 1210 1212 2101 2121 10101 10121 12101 Esthetic numbers 16 to 24 in base 4 323 1010 1012 1210 1212 1232 2101 2121 2123 Esthetic numbers 20 to 30 in base 5 323 343 432 434 1010 1012 1210 1212 1232 1234 2101 Esthetic numbers 24 to 36 in base 6 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234 Esthetic numbers 28 to 42 in base 7 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232 Esthetic numbers 32 to 48 in base 8 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212 Esthetic numbers 36 to 54 in base 9 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210 Esthetic numbers 40 to 60 in base 10 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012 Esthetic numbers 44 to 66 in base 11 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 a98 a9a 1010 Esthetic numbers 48 to 72 in base 12 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba ba9 bab Esthetic numbers 52 to 78 in base 13 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb cba Esthetic numbers 56 to 84 in base 14 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc Esthetic numbers 60 to 90 in base 15 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd Esthetic numbers 64 to 96 in base 16 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd ded def edc Base 10 eshetic numbers between 1000 and 9999 1010 1012 1210 1212 1232 1234 2101 2121 2123 2321 2323 2343 2345 3210 3212 3232 3234 3432 3434 3454 3456 4321 4323 4343 4345 4543 4545 4565 4567 5432 5434 5454 5456 5654 5656 5676 5678 6543 6545 6565 6567 6765 6767 6787 6789 7654 7656 7676 7678 7876 7878 7898 8765 8767 8787 8789 8987 8989 9876 9878 9898 Esthetic numbers between 100 000 000 and 130 000 000: 101010101 101010121 101010123 101012101 101012121 101012123 101012321 101012323 101012343 101012345 101210101 101210121 101210123 101212101 101212121 101212123 101212321 101212323 101212343 101212345 101232101 101232121 101232123 101232321 101232323 101232343 101232345 101234321 101234323 101234343 101234345 101234543 101234545 101234565 101234567 121010101 121010121 121010123 121012101 121012121 121012123 121012321 121012323 121012343 121012345 121210101 121210121 121210123 121212101 121212121 121212123 121212321 121212323 121212343 121212345 121232101 121232121 121232123 121232321 121232323 121232343 121232345 121234321 121234323 121234343 121234345 121234543 121234545 121234565 121234567 123210101 123210121 123210123 123212101 123212121 123212123 123212321 123212323 123212343 123212345 123232101 123232121 123232123 123232321 123232323 123232343 123232345 123234321 123234323 123234343 123234345 123234543 123234545 123234565 123234567 123432101 123432121 123432123 123432321 123432323 123432343 123432345 123434321 123434323 123434343 123434345 123434543 123434545 123434565 123434567 123454321 123454323 123454343 123454345 123454543 123454545 123454565 123454567 123456543 123456545 123456565 123456567 123456765 123456767 123456787 123456789 Found 126 esthetic numbers
Arturo
esthetic?: function [n, b][
if n=0 -> return false
k: n % b
l: n / b
while [l>0][
j: l % b
if 1 <> abs k-j -> return false
l: l / b
k: j
]
return true
]
HEX: "0000000000ABCDEF"
getHex: function [ds][
map ds 'd [
(d < 10)? -> to :string d
-> to :string HEX\[d]
]
]
findEsthetics: function [base][
limDown: base * 4
limUp: base * 6
cnt: 0
i: 1
result: new []
while [cnt < limUp][
if esthetic? i base [
cnt: cnt + 1
if cnt >= limDown ->
'result ++ join getHex digits.base: base i
]
i: i + 1
]
print ["Base" base "->" (to :string limDown)++"th" "to" (to :string limUp)++"th" "esthetic numbers:"]
print result
print ""
]
loop 2..16 'bs ->
findEsthetics bs
print "Esthetic numbers between 1000 and 9999:"
loop split.every: 16 select 1000..9999 'num -> esthetic? num 10 'row [
print map to [:string] row 'item -> pad item 4
]
- Output:
Base 2 -> 8th to 12th esthetic numbers: 10101010 101010101 1010101010 10101010101 101010101010 Base 3 -> 12th to 18th esthetic numbers: 1210 1212 2101 2121 10101 10121 12101 Base 4 -> 16th to 24th esthetic numbers: 323 1010 1012 1210 1212 1232 2101 2121 2123 Base 5 -> 20th to 30th esthetic numbers: 323 343 432 434 1010 1012 1210 1212 1232 1234 2101 Base 6 -> 24th to 36th esthetic numbers: 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234 Base 7 -> 28th to 42th esthetic numbers: 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232 Base 8 -> 32th to 48th esthetic numbers: 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212 Base 9 -> 36th to 54th esthetic numbers: 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210 Base 10 -> 40th to 60th esthetic numbers: 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012 Base 11 -> 44th to 66th esthetic numbers: 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 A98 A9A 1010 Base 12 -> 48th to 72th esthetic numbers: 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA BA9 BAB Base 13 -> 52th to 78th esthetic numbers: 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB CBA Base 14 -> 56th to 84th esthetic numbers: 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC Base 15 -> 60th to 90th esthetic numbers: 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC CDE DCB DCD Base 16 -> 64th to 96th esthetic numbers: 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC CDE DCB DCD DED DEF EDC Esthetic numbers between 1000 and 9999: 1010 1012 1210 1212 1232 1234 2101 2121 2123 2321 2323 2343 2345 3210 3212 3232 3234 3432 3434 3454 3456 4321 4323 4343 4345 4543 4545 4565 4567 5432 5434 5454 5456 5654 5656 5676 5678 6543 6545 6565 6567 6765 6767 6787 6789 7654 7656 7676 7678 7876 7878 7898 8765 8767 8787 8789 8987 8989 9876 9878 9898
C
#include <stdio.h>
#include <string.h>
#include <locale.h>
typedef int bool;
typedef unsigned long long ull;
#define TRUE 1
#define FALSE 0
char as_digit(int d) {
return (d >= 0 && d <= 9) ? d + '0' : d - 10 + 'a';
}
void revstr(char *str) {
int i, len = strlen(str);
char t;
for (i = 0; i < len/2; ++i) {
t = str[i];
str[i] = str[len - i - 1];
str[len - i - 1] = t;
}
}
char* to_base(char s[], ull n, int b) {
int i = 0;
while (n) {
s[i++] = as_digit(n % b);
n /= b;
}
s[i] = '\0';
revstr(s);
return s;
}
ull uabs(ull a, ull b) {
return a > b ? a - b : b - a;
}
bool is_esthetic(ull n, int b) {
int i, j;
if (!n) return FALSE;
i = n % b;
n /= b;
while (n) {
j = n % b;
if (uabs(i, j) != 1) return FALSE;
n /= b;
i = j;
}
return TRUE;
}
ull esths[45000];
int le = 0;
void dfs(ull n, ull m, ull i) {
ull d, i1, i2;
if (i >= n && i <= m) esths[le++] = i;
if (i == 0 || i > m) return;
d = i % 10;
i1 = i * 10 + d - 1;
i2 = i1 + 2;
if (d == 0) {
dfs(n, m, i2);
} else if (d == 9) {
dfs(n, m, i1);
} else {
dfs(n, m, i1);
dfs(n, m, i2);
}
}
void list_esths(ull n, ull n2, ull m, ull m2, int per_line, bool all) {
int i;
le = 0;
for (i = 0; i < 10; ++i) {
dfs(n2, m2, i);
}
printf("Base 10: %'d esthetic numbers between %'llu and %'llu:\n", le, n, m);
if (all) {
for (i = 0; i < le; ++i) {
printf("%llu ", esths[i]);
if (!(i+1)%per_line) printf("\n");
}
} else {
for (i = 0; i < per_line; ++i) printf("%llu ", esths[i]);
printf("\n............\n");
for (i = le - per_line; i < le; ++i) printf("%llu ", esths[i]);
}
printf("\n\n");
}
int main() {
ull n;
int b, c;
char ch[15] = {0};
for (b = 2; b <= 16; ++b) {
printf("Base %d: %dth to %dth esthetic numbers:\n", b, 4*b, 6*b);
for (n = 1, c = 0; c < 6 * b; ++n) {
if (is_esthetic(n, b)) {
if (++c >= 4 * b) printf("%s ", to_base(ch, n, b));
}
}
printf("\n\n");
}
char *oldLocale = setlocale(LC_NUMERIC, NULL);
setlocale(LC_NUMERIC, "");
// the following all use the obvious range limitations for the numbers in question
list_esths(1000, 1010, 9999, 9898, 16, TRUE);
list_esths(1e8, 101010101, 13*1e7, 123456789, 9, TRUE);
list_esths(1e11, 101010101010, 13*1e10, 123456789898, 7, FALSE);
list_esths(1e14, 101010101010101, 13*1e13, 123456789898989, 5, FALSE);
list_esths(1e17, 101010101010101010, 13*1e16, 123456789898989898, 4, FALSE);
setlocale(LC_NUMERIC, oldLocale);
return 0;
}
- Output:
Same as Go entry.
C++
#include <functional>
#include <iostream>
#include <sstream>
#include <vector>
std::string to(int n, int b) {
static auto BASE = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
std::stringstream ss;
while (n > 0) {
auto rem = n % b;
n = n / b;
ss << BASE[rem];
}
auto fwd = ss.str();
return std::string(fwd.rbegin(), fwd.rend());
}
uint64_t uabs(uint64_t a, uint64_t b) {
if (a < b) {
return b - a;
}
return a - b;
}
bool isEsthetic(uint64_t n, uint64_t b) {
if (n == 0) {
return false;
}
auto i = n % b;
n /= b;
while (n > 0) {
auto j = n % b;
if (uabs(i, j) != 1) {
return false;
}
n /= b;
i = j;
}
return true;
}
void listEsths(uint64_t n, uint64_t n2, uint64_t m, uint64_t m2, int perLine, bool all) {
std::vector<uint64_t> esths;
const auto dfs = [&esths](uint64_t n, uint64_t m, uint64_t i) {
auto dfs_impl = [&esths](uint64_t n, uint64_t m, uint64_t i, auto &dfs_ref) {
if (i >= n && i <= m) {
esths.push_back(i);
}
if (i == 0 || i > m) {
return;
}
auto d = i % 10;
auto i1 = i * 10 + d - 1;
auto i2 = i1 + 2;
if (d == 0) {
dfs_ref(n, m, i2, dfs_ref);
} else if (d == 9) {
dfs_ref(n, m, i1, dfs_ref);
} else {
dfs_ref(n, m, i1, dfs_ref);
dfs_ref(n, m, i2, dfs_ref);
}
};
dfs_impl(n, m, i, dfs_impl);
};
for (int i = 0; i < 10; i++) {
dfs(n2, m2, i);
}
auto le = esths.size();
printf("Base 10: %d esthetic numbers between %llu and %llu:\n", le, n, m);
if (all) {
for (size_t c = 0; c < esths.size(); c++) {
auto esth = esths[c];
printf("%llu ", esth);
if ((c + 1) % perLine == 0) {
printf("\n");
}
}
printf("\n");
} else {
for (int c = 0; c < perLine; c++) {
auto esth = esths[c];
printf("%llu ", esth);
}
printf("\n............\n");
for (size_t i = le - perLine; i < le; i++) {
auto esth = esths[i];
printf("%llu ", esth);
}
printf("\n");
}
printf("\n");
}
int main() {
for (int b = 2; b <= 16; b++) {
printf("Base %d: %dth to %dth esthetic numbers:\n", b, 4 * b, 6 * b);
for (int n = 1, c = 0; c < 6 * b; n++) {
if (isEsthetic(n, b)) {
c++;
if (c >= 4 * b) {
std::cout << to(n, b) << ' ';
}
}
}
printf("\n");
}
printf("\n");
// the following all use the obvious range limitations for the numbers in question
listEsths(1000, 1010, 9999, 9898, 16, true);
listEsths((uint64_t)1e8, 101'010'101, 13 * (uint64_t)1e7, 123'456'789, 9, true);
listEsths((uint64_t)1e11, 101'010'101'010, 13 * (uint64_t)1e10, 123'456'789'898, 7, false);
listEsths((uint64_t)1e14, 101'010'101'010'101, 13 * (uint64_t)1e13, 123'456'789'898'989, 5, false);
listEsths((uint64_t)1e17, 101'010'101'010'101'010, 13 * (uint64_t)1e16, 123'456'789'898'989'898, 4, false);
return 0;
}
- Output:
Base 2: 8th to 12th esthetic numbers: 10101010 101010101 1010101010 10101010101 101010101010 Base 3: 12th to 18th esthetic numbers: 1210 1212 2101 2121 10101 10121 12101 Base 4: 16th to 24th esthetic numbers: 323 1010 1012 1210 1212 1232 2101 2121 2123 Base 5: 20th to 30th esthetic numbers: 323 343 432 434 1010 1012 1210 1212 1232 1234 2101 Base 6: 24th to 36th esthetic numbers: 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234 Base 7: 28th to 42th esthetic numbers: 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232 Base 8: 32th to 48th esthetic numbers: 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212 Base 9: 36th to 54th esthetic numbers: 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210 Base 10: 40th to 60th esthetic numbers: 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012 Base 11: 44th to 66th esthetic numbers: 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 A98 A9A 1010 Base 12: 48th to 72th esthetic numbers: 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA BA9 BAB Base 13: 52th to 78th esthetic numbers: 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB CBA Base 14: 56th to 84th esthetic numbers: 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC Base 15: 60th to 90th esthetic numbers: 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC CDE DCB DCD Base 16: 64th to 96th esthetic numbers: 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC CDE DCB DCD DED DEF EDC Base 10: 61 esthetic numbers between 1000 and 9999: 1010 1012 1210 1212 1232 1234 2101 2121 2123 2321 2323 2343 2345 3210 3212 3232 3234 3432 3434 3454 3456 4321 4323 4343 4345 4543 4545 4565 4567 5432 5434 5454 5456 5654 5656 5676 5678 6543 6545 6565 6567 6765 6767 6787 6789 7654 7656 7676 7678 7876 7878 7898 8765 8767 8787 8789 8987 8989 9876 9878 9898 Base 10: 126 esthetic numbers between 100000000 and 130000000: 101010101 101010121 101010123 101012101 101012121 101012123 101012321 101012323 101012343 101012345 101210101 101210121 101210123 101212101 101212121 101212123 101212321 101212323 101212343 101212345 101232101 101232121 101232123 101232321 101232323 101232343 101232345 101234321 101234323 101234343 101234345 101234543 101234545 101234565 101234567 121010101 121010121 121010123 121012101 121012121 121012123 121012321 121012323 121012343 121012345 121210101 121210121 121210123 121212101 121212121 121212123 121212321 121212323 121212343 121212345 121232101 121232121 121232123 121232321 121232323 121232343 121232345 121234321 121234323 121234343 121234345 121234543 121234545 121234565 121234567 123210101 123210121 123210123 123212101 123212121 123212123 123212321 123212323 123212343 123212345 123232101 123232121 123232123 123232321 123232323 123232343 123232345 123234321 123234323 123234343 123234345 123234543 123234545 123234565 123234567 123432101 123432121 123432123 123432321 123432323 123432343 123432345 123434321 123434323 123434343 123434345 123434543 123434545 123434565 123434567 123454321 123454323 123454343 123454345 123454543 123454545 123454565 123454567 123456543 123456545 123456565 123456567 123456765 123456767 123456787 123456789 Base 10: 911 esthetic numbers between 100000000000 and 130000000000: 101010101010 101010101012 101010101210 101010101212 101010101232 101010101234 101010121010 ............ 123456787678 123456787876 123456787878 123456787898 123456789876 123456789878 123456789898 Base 10: 6225 esthetic numbers between 100000000000000 and 130000000000000: 101010101010101 101010101010121 101010101010123 101010101012101 101010101012121 ............ 123456789898767 123456789898787 123456789898789 123456789898987 123456789898989 Base 10: 44744 esthetic numbers between 100000000000000000 and 130000000000000000: 101010101010101010 101010101010101012 101010101010101210 101010101010101212 ............ 123456789898987898 123456789898989876 123456789898989878 123456789898989898
D
import std.conv;
import std.stdio;
ulong uabs(ulong a, ulong b) {
if (a > b) {
return a - b;
}
return b - a;
}
bool isEsthetic(ulong n, ulong b) {
if (n == 0) {
return false;
}
auto i = n % b;
n /= b;
while (n > 0) {
auto j = n % b;
if (uabs(i, j) != 1) {
return false;
}
n /= b;
i = j;
}
return true;
}
ulong[] esths;
void dfs(ulong n, ulong m, ulong i) {
if (i >= n && i <= m) {
esths ~= i;
}
if (i == 0 || i > m) {
return;
}
auto d = i % 10;
auto i1 = i * 10 + d - 1;
auto i2 = i1 + 2;
if (d == 0) {
dfs(n, m, i2);
} else if (d == 9) {
dfs(n, m, i1);
} else {
dfs(n, m, i1);
dfs(n, m, i2);
}
}
void listEsths(ulong n, ulong n2, ulong m, long m2, int perLine, bool all) {
esths.length = 0;
for (auto i = 0; i < 10; i++) {
dfs(n2, m2, i);
}
auto le = esths.length;
writefln("Base 10: %s esthetic numbers between %s and %s:", le, n, m);
if (all) {
foreach (c, esth; esths) {
write(esth, ' ');
if ((c + 1) % perLine == 0) {
writeln;
}
}
writeln;
} else {
for (auto i = 0; i < perLine; i++) {
write(esths[i], ' ');
}
writeln("\n............");
for (auto i = le - perLine; i < le; i++) {
write(esths[i], ' ');
}
writeln;
}
writeln;
}
void main() {
for (auto b = 2; b <= 16; b++) {
writefln("Base %d: %dth to %dth esthetic numbers:", b, 4 * b, 6 * b);
for (auto n = 1, c = 0; c < 6 * b; n++) {
if (isEsthetic(n, b)) {
c++;
if (c >= 4 * b) {
write(to!string(n, b), ' ');
}
}
}
writeln;
}
writeln;
// the following all use the obvious range limitations for the numbers in question
listEsths(1000, 1010, 9999, 9898, 16, true);
listEsths(cast(ulong) 1e8, 101_010_101, 13*cast(ulong) 1e7, 123_456_789, 9, true);
listEsths(cast(ulong) 1e11, 101_010_101_010, 13*cast(ulong) 1e10, 123_456_789_898, 7, false);
listEsths(cast(ulong) 1e14, 101_010_101_010_101, 13*cast(ulong) 1e13, 123_456_789_898_989, 5, false);
listEsths(cast(ulong) 1e17, 101_010_101_010_101_010, 13*cast(ulong) 1e16, 123_456_789_898_989_898, 4, false);
}
- Output:
Base 2: 8th to 12th esthetic numbers: 10101010 101010101 1010101010 10101010101 101010101010 Base 3: 12th to 18th esthetic numbers: 1210 1212 2101 2121 10101 10121 12101 Base 4: 16th to 24th esthetic numbers: 323 1010 1012 1210 1212 1232 2101 2121 2123 Base 5: 20th to 30th esthetic numbers: 323 343 432 434 1010 1012 1210 1212 1232 1234 2101 Base 6: 24th to 36th esthetic numbers: 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234 Base 7: 28th to 42th esthetic numbers: 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232 Base 8: 32th to 48th esthetic numbers: 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212 Base 9: 36th to 54th esthetic numbers: 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210 Base 10: 40th to 60th esthetic numbers: 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012 Base 11: 44th to 66th esthetic numbers: 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 A98 A9A 1010 Base 12: 48th to 72th esthetic numbers: 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA BA9 BAB Base 13: 52th to 78th esthetic numbers: 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB CBA Base 14: 56th to 84th esthetic numbers: 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC Base 15: 60th to 90th esthetic numbers: 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC CDE DCB DCD Base 16: 64th to 96th esthetic numbers: 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC CDE DCB DCD DED DEF EDC Base 10: 61 esthetic numbers between 1000 and 9999: 1010 1012 1210 1212 1232 1234 2101 2121 2123 2321 2323 2343 2345 3210 3212 3232 3234 3432 3434 3454 3456 4321 4323 4343 4345 4543 4545 4565 4567 5432 5434 5454 5456 5654 5656 5676 5678 6543 6545 6565 6567 6765 6767 6787 6789 7654 7656 7676 7678 7876 7878 7898 8765 8767 8787 8789 8987 8989 9876 9878 9898 Base 10: 126 esthetic numbers between 100000000 and 130000000: 101010101 101010121 101010123 101012101 101012121 101012123 101012321 101012323 101012343 101012345 101210101 101210121 101210123 101212101 101212121 101212123 101212321 101212323 101212343 101212345 101232101 101232121 101232123 101232321 101232323 101232343 101232345 101234321 101234323 101234343 101234345 101234543 101234545 101234565 101234567 121010101 121010121 121010123 121012101 121012121 121012123 121012321 121012323 121012343 121012345 121210101 121210121 121210123 121212101 121212121 121212123 121212321 121212323 121212343 121212345 121232101 121232121 121232123 121232321 121232323 121232343 121232345 121234321 121234323 121234343 121234345 121234543 121234545 121234565 121234567 123210101 123210121 123210123 123212101 123212121 123212123 123212321 123212323 123212343 123212345 123232101 123232121 123232123 123232321 123232323 123232343 123232345 123234321 123234323 123234343 123234345 123234543 123234545 123234565 123234567 123432101 123432121 123432123 123432321 123432323 123432343 123432345 123434321 123434323 123434343 123434345 123434543 123434545 123434565 123434567 123454321 123454323 123454343 123454345 123454543 123454545 123454565 123454567 123456543 123456545 123456565 123456567 123456765 123456767 123456787 123456789 Base 10: 911 esthetic numbers between 100000000000 and 130000000000: 101010101010 101010101012 101010101210 101010101212 101010101232 101010101234 101010121010 ............ 123456787678 123456787876 123456787878 123456787898 123456789876 123456789878 123456789898 Base 10: 6225 esthetic numbers between 100000000000000 and 130000000000000: 101010101010101 101010101010121 101010101010123 101010101012101 101010101012121 ............ 123456789898767 123456789898787 123456789898789 123456789898987 123456789898989 Base 10: 44744 esthetic numbers between 100000000000000000 and 130000000000000000: 101010101010101010 101010101010101012 101010101010101210 101010101010101212 ............ 123456789898987898 123456789898989876 123456789898989878 123456789898989898
Delphi
type TIntArray = array of integer;
function GetRadixString(L: Integer; Radix: Byte): string;
{Converts integer a string of any radix}
const HexChars: array[0..15] Of char =
('0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F');
var I: integer;
var S: string;
var Sign: string[1];
begin
Result:='';
If (L < 0) then
begin
Sign:='-';
L:=Abs(L);
end
else Sign:='';
S:='';
repeat
begin
I:=L mod Radix;
S:=HexChars[I] + S;
L:=L div Radix;
end
until L = 0;
Result:=Sign + S;
end;
procedure StrToInts(S: string; var IA: TIntArray);
{Convert numerical string of any radix and convert to numbers}
var I: integer;
begin
for I:=1 to Length(S) do
begin
SetLength(IA,Length(IA)+1);
if S[I]<#$40 then IA[High(IA)]:=Byte(S[I])-$30
else IA[High(IA)]:=(Byte(S[I])-$41)+10;
end;
end;
function IsEsthetic(N: integer; Radix: byte): boolean;
{Check number to see if neighboring digits are no more than one differents.}
var I: integer;
var S: string;
var IA: TIntArray;
begin
Result:=False;
S:=GetRadixString(N,Radix);
StrToInts(S,IA);
for I:=0 to Length(IA)-2 do
if Abs(IA[I+1]-IA[I])<>1 then exit;
Result:=True;
end;
function GetEstheticRange(Memo: TMemo; Range1,Range2,Count1,Count2,Base: integer): integer;
{Find an Esthetic number in the domain of Range and Counts specified}
var I,Cnt: integer;
var S: string;
begin
Cnt:=0; Result:=0;
S:='';
for I:=Range1 to Range2 do
if IsEsthetic(I,Base) then
begin
Inc(Cnt);
if (Cnt>=Count1) and (Cnt<=Count2) then
begin
Inc(Result);
S:=S+' '+GetRadixString(I,Base);
if (Result mod 10)=0 then S:=S+#$0D#$0A;
end;
if Cnt>=Count2 then break;
end;
Memo.Lines.Add(S);
end;
procedure FindEstheticNumbers(Memo: TMemo);
{Find Esthetic numbers for Rosetta Code problem}
var Base,First,Last,Cnt: integer;
begin
for Base:=2 to 16 do
begin
First:=Base*4; Last:=Base*6;
Memo.Lines.Add(Format('Base %2d: %2dth to %2dth esthetic numbers:',[Base,First,Last]));
Cnt:=GetEstheticRange(Memo,0,High(Integer),First,Last,Base);
Memo.Lines.Add('Count: '+IntToStr(Cnt));
Memo.Lines.Add('');
end;
Memo.Lines.Add('Base 10: esthetic numbers between 1000,9999');
Cnt:=GetEstheticRange(Memo,1000,9999,0,High(Integer),10);
Memo.Lines.Add('Count: '+IntToStr(Cnt));
Memo.Lines.Add('');
Memo.Lines.Add('Base 10: esthetic numbers between 100000000,130000000');
Cnt:=GetEstheticRange(Memo,100000000,130000000,0,High(Integer),10);
Memo.Lines.Add('Count: '+IntToStr(Cnt));
Memo.Lines.Add('');
end;
- Output:
Base 2: 8th to 12th esthetic numbers: 1010101 10101010 101010101 1010101010 10101010101 Count: 5 Base 3: 12th to 18th esthetic numbers: 1012 1210 1212 2101 2121 10101 10121 Count: 7 Base 4: 16th to 24th esthetic numbers: 321 323 1010 1012 1210 1212 1232 2101 2121 Count: 9 Base 5: 20th to 30th esthetic numbers: 321 323 343 432 434 1010 1012 1210 1212 1232 1234 Count: 11 Base 6: 24th to 36th esthetic numbers: 323 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 Count: 13 Base 7: 28th to 42th esthetic numbers: 343 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 Count: 15 Base 8: 32th to 48th esthetic numbers: 345 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 Count: 17 Base 9: 36th to 54th esthetic numbers: 432 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 Count: 19 Base 10: 40th to 60th esthetic numbers: 434 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 Count: 21 Base 11: 44th to 66th esthetic numbers: 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 A98 A9A Count: 23 Base 12: 48th to 72th esthetic numbers: 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA BA9 Count: 25 Base 13: 52th to 78th esthetic numbers: 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB Count: 27 Base 14: 56th to 84th esthetic numbers: 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC Count: 29 Base 15: 60th to 90th esthetic numbers: 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC CDE DCB Count: 31 Base 16: 64th to 96th esthetic numbers: 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC CDE DCB DCD DED DEF Count: 33 Base 10: esthetic numbers between 1000,9999 1010 1012 1210 1212 1232 1234 2101 2121 2123 2321 2323 2343 2345 3210 3212 3232 3234 3432 3434 3454 3456 4321 4323 4343 4345 4543 4545 4565 4567 5432 5434 5454 5456 5654 5656 5676 5678 6543 6545 6565 6567 6765 6767 6787 6789 7654 7656 7676 7678 7876 7878 7898 8765 8767 8787 8789 8987 8989 9876 9878 9898 Count: 61 Base 10: esthetic numbers between 100000000,130000000 101010101 101010121 101010123 101012101 101012121 101012123 101012321 101012323 101012343 101012345 101210101 101210121 101210123 101212101 101212121 101212123 101212321 101212323 101212343 101212345 101232101 101232121 101232123 101232321 101232323 101232343 101232345 101234321 101234323 101234343 101234345 101234543 101234545 101234565 101234567 121010101 121010121 121010123 121012101 121012121 121012123 121012321 121012323 121012343 121012345 121210101 121210121 121210123 121212101 121212121 121212123 121212321 121212323 121212343 121212345 121232101 121232121 121232123 121232321 121232323 121232343 121232345 121234321 121234323 121234343 121234345 121234543 121234545 121234565 121234567 123210101 123210121 123210123 123212101 123212121 123212123 123212321 123212323 123212343 123212345 123232101 123232121 123232123 123232321 123232323 123232343 123232345 123234321 123234323 123234343 123234345 123234543 123234545 123234565 123234567 123432101 123432121 123432123 123432321 123432323 123432343 123432345 123434321 123434323 123434343 123434345 123434543 123434545 123434565 123434567 123454321 123454323 123454343 123454345 123454543 123454545 123454565 123454567 123456543 123456545 123456565 123456567 123456765 123456767 123456787 123456789 Count: 126
EasyLang
func$ to n b .
digs$ = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
if n = 0
return 0
.
s$ = ""
while n > 0
idx = n mod b + 1
n = n div b
s$ = substr digs$ idx 1 & s$
.
return s$
.
func uabs a b .
if a > b
return a - b
.
return b - a
.
func isEsthetic n b .
if n = 0
return 0
.
i = n mod b
n = n div b
while n > 0
j = n mod b
if uabs i j <> 1
return 0
.
n = n div b
i = j
.
return 1
.
for b = 2 to 16
print "Base " & b & ": " & 4 * b & "th to " & 6 * b & "th esthetic numbers:"
n = 1
c = 0
while c < 6 * b
if isEsthetic n b = 1
c += 1
if c >= 4 * b
write to n b & " "
.
.
n += 1
.
print ""
print ""
.
print "Base 10 esthetic numbers between 1000 and 9999:"
for i = 1000 to 9999
if isEsthetic i 10 = 1
write i & " "
.
.
F#
The functions
// Generate Esthetic Numbers. Nigel Galloway: March 21st., 2020
let rec fN Σ n g = match g with h::t -> match List.head h with
0 -> fN ((1::h)::Σ) n t
|g when g=n-1 -> fN ((g-1::h)::Σ) n t
|g -> fN ((g-1::h)::(g+1::h)::Σ) n t
|_ -> Σ
let Esthetic n = let Esthetic, g = fN [] n, [1..n-1] |> List.map(fun n->[n])
Seq.unfold(fun n->Some(n,Esthetic(List.rev n)))(g) |> Seq.concat
let EtoS n = let g = "0123456789abcdef".ToCharArray()
n |> List.map(fun n->g.[n]) |> List.rev |> Array.ofList |> System.String
The Tasks
- Esthetic numbers in bases 2 through 16
[2..16]|>List.iter(fun n->printfn "\nBase %d" n; Esthetic n|>Seq.skip(4*n-1)|>Seq.take((6-4)*n+1)|>Seq.iter(EtoS >> printfn "%s"))
- Output:
Base 2 10101010 101010101 1010101010 10101010101 101010101010 Base 3 1210 1212 2101 2121 10101 10121 12101 Base 4 323 1010 1012 1210 1212 1232 2101 2121 2123 Base 5 323 343 432 434 1010 1012 1210 1212 1232 1234 2101 Base 6 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234 Base 7 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232 Base 8 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212 Base 9 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210 Base 10 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012 Base 11 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 a98 a9a 1010 Base 12 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba ba9 bab Base 13 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb cba Base 14 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc Base 15 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd Base 16 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd ded def edc
- Base 10 esthetic numbers with a magnitude between 1000 and 9999
Esthetic 10|>Seq.map(EtoS>>int)|>Seq.skipWhile(fun n->n<1000)|>Seq.takeWhile(fun n->n<9999)|>Seq.iter(printfn "%d");;
- Output:
1010 1012 1210 1212 1232 1234 2101 2121 2123 2321 2323 2343 2345 3210 3212 3232 3234 3432 3434 3454 3456 4321 4323 4343 4345 4543 4545 4565 4567 5432 5434 5454 5456 5654 5656 5676 5678 6543 6545 6565 6567 6765 6767 6787 6789 7654 7656 7676 7678 7876 7878 7898 8765 8767 8787 8789 8987 8989 9876 9878 9898
- Base 10 esthetic numbers with a magnitude between 1.0e8 and 1.3e8
Esthetic 10|>Seq.map(EtoS>>int)|>Seq.skipWhile(fun n->n<100000000)|>Seq.takeWhile(fun n->n< 130000000)|>Seq.iter(printfn "%d")
- Output:
101010101 101010121 101010123 101012101 101012121 101012123 101012321 101012323 101012343 101012345 101210101 101210121 101210123 101212101 101212121 101212123 101212321 101212323 101212343 101212345 101232101 101232121 101232123 101232321 101232323 101232343 101232345 101234321 101234323 101234343 101234345 101234543 101234545 101234565 101234567 121010101 121010121 121010123 121012101 121012121 121012123 121012321 121012323 121012343 121012345 121210101 121210121 121210123 121212101 121212121 121212123 121212321 121212323 121212343 121212345 121232101 121232121 121232123 121232321 121232323 121232343 121232345 121234321 121234323 121234343 121234345 121234543 121234545 121234565 121234567 123210101 123210121 123210123 123212101 123212121 123212123 123212321 123212323 123212343 123212345 123232101 123232121 123232123 123232321 123232323 123232343 123232345 123234321 123234323 123234343 123234345 123234543 123234545 123234565 123234567 123432101 123432121 123432123 123432321 123432323 123432343 123432345 123434321 123434323 123434343 123434345 123434543 123434545 123434565 123434567 123454321 123454323 123454343 123454345 123454543 123454545 123454565 123454567 123456543 123456545 123456565 123456567 123456765 123456767 123456787 123456789
- Base 10 esthetic numbers with a magnitude between 1.0e11 and 1.3e11
Esthetic 10|>Seq.map(EtoS>>int64)|>Seq.skipWhile(fun n->n<100000000000L)|>Seq.takeWhile(fun n->n<130000000000L)|>Seq.iter(printfn "%d")
- Output:
101010101010 101010101012 101010101210 101010101212 101010101232 101010101234 101010121010 101010121012 101010121210 101010121212 101010121232 101010121234 101010123210 101010123212 101010123232 101010123234 101010123432 101010123434 101010123454 101010123456 101012101010 101012101012 101012101210 101012101212 101012101232 101012101234 101012121010 101012121012 101012121210 101012121212 101012121232 101012121234 101012123210 101012123212 101012123232 101012123234 101012123432 101012123434 101012123454 101012123456 101012321010 101012321012 101012321210 101012321212 101012321232 101012321234 101012323210 101012323212 101012323232 101012323234 101012323432 101012323434 101012323454 101012323456 101012343210 101012343212 101012343232 101012343234 101012343432 101012343434 101012343454 101012343456 101012345432 101012345434 101012345454 101012345456 101012345654 101012345656 101012345676 101012345678 101210101010 101210101012 101210101210 101210101212 101210101232 101210101234 101210121010 101210121012 101210121210 101210121212 101210121232 101210121234 101210123210 101210123212 101210123232 101210123234 101210123432 101210123434 101210123454 101210123456 101212101010 101212101012 101212101210 101212101212 101212101232 101212101234 101212121010 101212121012 101212121210 101212121212 101212121232 101212121234 101212123210 101212123212 101212123232 101212123234 101212123432 101212123434 101212123454 101212123456 101212321010 101212321012 101212321210 101212321212 101212321232 101212321234 101212323210 101212323212 101212323232 101212323234 101212323432 101212323434 101212323454 101212323456 101212343210 101212343212 101212343232 101212343234 101212343432 101212343434 101212343454 101212343456 101212345432 101212345434 101212345454 101212345456 101212345654 101212345656 101212345676 101212345678 101232101010 101232101012 101232101210 101232101212 101232101232 101232101234 101232121010 101232121012 101232121210 101232121212 101232121232 101232121234 101232123210 101232123212 101232123232 101232123234 101232123432 101232123434 101232123454 101232123456 101232321010 101232321012 101232321210 101232321212 101232321232 101232321234 101232323210 101232323212 101232323232 101232323234 101232323432 101232323434 101232323454 101232323456 101232343210 101232343212 101232343232 101232343234 101232343432 101232343434 101232343454 101232343456 101232345432 101232345434 101232345454 101232345456 101232345654 101232345656 101232345676 101232345678 101234321010 101234321012 101234321210 101234321212 101234321232 101234321234 101234323210 101234323212 101234323232 101234323234 101234323432 101234323434 101234323454 101234323456 101234343210 101234343212 101234343232 101234343234 101234343432 101234343434 101234343454 101234343456 101234345432 101234345434 101234345454 101234345456 101234345654 101234345656 101234345676 101234345678 101234543210 101234543212 101234543232 101234543234 101234543432 101234543434 101234543454 101234543456 101234545432 101234545434 101234545454 101234545456 101234545654 101234545656 101234545676 101234545678 101234565432 101234565434 101234565454 101234565456 101234565654 101234565656 101234565676 101234565678 101234567654 101234567656 101234567676 101234567678 101234567876 101234567878 101234567898 121010101010 121010101012 121010101210 121010101212 121010101232 121010101234 121010121010 121010121012 121010121210 121010121212 121010121232 121010121234 121010123210 121010123212 121010123232 121010123234 121010123432 121010123434 121010123454 121010123456 121012101010 121012101012 121012101210 121012101212 121012101232 121012101234 121012121010 121012121012 121012121210 121012121212 121012121232 121012121234 121012123210 121012123212 121012123232 121012123234 121012123432 121012123434 121012123454 121012123456 121012321010 121012321012 121012321210 121012321212 121012321232 121012321234 121012323210 121012323212 121012323232 121012323234 121012323432 121012323434 121012323454 121012323456 121012343210 121012343212 121012343232 121012343234 121012343432 121012343434 121012343454 121012343456 121012345432 121012345434 121012345454 121012345456 121012345654 121012345656 121012345676 121012345678 121210101010 121210101012 121210101210 121210101212 121210101232 121210101234 121210121010 121210121012 121210121210 121210121212 121210121232 121210121234 121210123210 121210123212 121210123232 121210123234 121210123432 121210123434 121210123454 121210123456 121212101010 121212101012 121212101210 121212101212 121212101232 121212101234 121212121010 121212121012 121212121210 121212121212 121212121232 121212121234 121212123210 121212123212 121212123232 121212123234 121212123432 121212123434 121212123454 121212123456 121212321010 121212321012 121212321210 121212321212 121212321232 121212321234 121212323210 121212323212 121212323232 121212323234 121212323432 121212323434 121212323454 121212323456 121212343210 121212343212 121212343232 121212343234 121212343432 121212343434 121212343454 121212343456 121212345432 121212345434 121212345454 121212345456 121212345654 121212345656 121212345676 121212345678 121232101010 121232101012 121232101210 121232101212 121232101232 121232101234 121232121010 121232121012 121232121210 121232121212 121232121232 121232121234 121232123210 121232123212 121232123232 121232123234 121232123432 121232123434 121232123454 121232123456 121232321010 121232321012 121232321210 121232321212 121232321232 121232321234 121232323210 121232323212 121232323232 121232323234 121232323432 121232323434 121232323454 121232323456 121232343210 121232343212 121232343232 121232343234 121232343432 121232343434 121232343454 121232343456 121232345432 121232345434 121232345454 121232345456 121232345654 121232345656 121232345676 121232345678 121234321010 121234321012 121234321210 121234321212 121234321232 121234321234 121234323210 121234323212 121234323232 121234323234 121234323432 121234323434 121234323454 121234323456 121234343210 121234343212 121234343232 121234343234 121234343432 121234343434 121234343454 121234343456 121234345432 121234345434 121234345454 121234345456 121234345654 121234345656 121234345676 121234345678 121234543210 121234543212 121234543232 121234543234 121234543432 121234543434 121234543454 121234543456 121234545432 121234545434 121234545454 121234545456 121234545654 121234545656 121234545676 121234545678 121234565432 121234565434 121234565454 121234565456 121234565654 121234565656 121234565676 121234565678 121234567654 121234567656 121234567676 121234567678 121234567876 121234567878 121234567898 123210101010 123210101012 123210101210 123210101212 123210101232 123210101234 123210121010 123210121012 123210121210 123210121212 123210121232 123210121234 123210123210 123210123212 123210123232 123210123234 123210123432 123210123434 123210123454 123210123456 123212101010 123212101012 123212101210 123212101212 123212101232 123212101234 123212121010 123212121012 123212121210 123212121212 123212121232 123212121234 123212123210 123212123212 123212123232 123212123234 123212123432 123212123434 123212123454 123212123456 123212321010 123212321012 123212321210 123212321212 123212321232 123212321234 123212323210 123212323212 123212323232 123212323234 123212323432 123212323434 123212323454 123212323456 123212343210 123212343212 123212343232 123212343234 123212343432 123212343434 123212343454 123212343456 123212345432 123212345434 123212345454 123212345456 123212345654 123212345656 123212345676 123212345678 123232101010 123232101012 123232101210 123232101212 123232101232 123232101234 123232121010 123232121012 123232121210 123232121212 123232121232 123232121234 123232123210 123232123212 123232123232 123232123234 123232123432 123232123434 123232123454 123232123456 123232321010 123232321012 123232321210 123232321212 123232321232 123232321234 123232323210 123232323212 123232323232 123232323234 123232323432 123232323434 123232323454 123232323456 123232343210 123232343212 123232343232 123232343234 123232343432 123232343434 123232343454 123232343456 123232345432 123232345434 123232345454 123232345456 123232345654 123232345656 123232345676 123232345678 123234321010 123234321012 123234321210 123234321212 123234321232 123234321234 123234323210 123234323212 123234323232 123234323234 123234323432 123234323434 123234323454 123234323456 123234343210 123234343212 123234343232 123234343234 123234343432 123234343434 123234343454 123234343456 123234345432 123234345434 123234345454 123234345456 123234345654 123234345656 123234345676 123234345678 123234543210 123234543212 123234543232 123234543234 123234543432 123234543434 123234543454 123234543456 123234545432 123234545434 123234545454 123234545456 123234545654 123234545656 123234545676 123234545678 123234565432 123234565434 123234565454 123234565456 123234565654 123234565656 123234565676 123234565678 123234567654 123234567656 123234567676 123234567678 123234567876 123234567878 123234567898 123432101010 123432101012 123432101210 123432101212 123432101232 123432101234 123432121010 123432121012 123432121210 123432121212 123432121232 123432121234 123432123210 123432123212 123432123232 123432123234 123432123432 123432123434 123432123454 123432123456 123432321010 123432321012 123432321210 123432321212 123432321232 123432321234 123432323210 123432323212 123432323232 123432323234 123432323432 123432323434 123432323454 123432323456 123432343210 123432343212 123432343232 123432343234 123432343432 123432343434 123432343454 123432343456 123432345432 123432345434 123432345454 123432345456 123432345654 123432345656 123432345676 123432345678 123434321010 123434321012 123434321210 123434321212 123434321232 123434321234 123434323210 123434323212 123434323232 123434323234 123434323432 123434323434 123434323454 123434323456 123434343210 123434343212 123434343232 123434343234 123434343432 123434343434 123434343454 123434343456 123434345432 123434345434 123434345454 123434345456 123434345654 123434345656 123434345676 123434345678 123434543210 123434543212 123434543232 123434543234 123434543432 123434543434 123434543454 123434543456 123434545432 123434545434 123434545454 123434545456 123434545654 123434545656 123434545676 123434545678 123434565432 123434565434 123434565454 123434565456 123434565654 123434565656 123434565676 123434565678 123434567654 123434567656 123434567676 123434567678 123434567876 123434567878 123434567898 123454321010 123454321012 123454321210 123454321212 123454321232 123454321234 123454323210 123454323212 123454323232 123454323234 123454323432 123454323434 123454323454 123454323456 123454343210 123454343212 123454343232 123454343234 123454343432 123454343434 123454343454 123454343456 123454345432 123454345434 123454345454 123454345456 123454345654 123454345656 123454345676 123454345678 123454543210 123454543212 123454543232 123454543234 123454543432 123454543434 123454543454 123454543456 123454545432 123454545434 123454545454 123454545456 123454545654 123454545656 123454545676 123454545678 123454565432 123454565434 123454565454 123454565456 123454565654 123454565656 123454565676 123454565678 123454567654 123454567656 123454567676 123454567678 123454567876 123454567878 123454567898 123456543210 123456543212 123456543232 123456543234 123456543432 123456543434 123456543454 123456543456 123456545432 123456545434 123456545454 123456545456 123456545654 123456545656 123456545676 123456545678 123456565432 123456565434 123456565454 123456565456 123456565654 123456565656 123456565676 123456565678 123456567654 123456567656 123456567676 123456567678 123456567876 123456567878 123456567898 123456765432 123456765434 123456765454 123456765456 123456765654 123456765656 123456765676 123456765678 123456767654 123456767656 123456767676 123456767678 123456767876 123456767878 123456767898 123456787654 123456787656 123456787676 123456787678 123456787876 123456787878 123456787898 123456789876 123456789878 123456789898 Real: 00:00:00.322, CPU: 00:00:00.093, GC gen0: 3, gen1: 2, gen2: 1
Factor
The bfs
word is an adaptation of the algorithm from the Geeks for Geeks reference. It has been changed to work with any base. In summary, this algorithm constructs esthetic numbers directly using a breadth first search. For example, we know the only two esthetic numbers that can be constructed from 23 are 232 and 234, or in other words, the last digit of 23 ± 1 appended to 23. This forms a tree for each digit in a given base where each node is an esthetic number and can have at most two children. This method is very fast and has been used to find the count of esthetic numbers in base 10 between zero and one quadrillion.
USING: combinators deques dlists formatting grouping io kernel
locals make math math.order math.parser math.ranges
math.text.english prettyprint sequences sorting strings ;
:: bfs ( from to num base -- )
DL{ } clone :> q
base 1 - :> ld
num q push-front
[ q deque-empty? ]
[
q pop-back :> step-num
step-num from to between? [ step-num , ] when
step-num zero? step-num to > or
[
step-num base mod :> last-digit
step-num base * last-digit 1 - + :> a
step-num base * last-digit 1 + + :> b
last-digit
{
{ 0 [ b q push-front ] }
{ ld [ a q push-front ] }
[ drop a q push-front b q push-front ]
} case
] unless
] until ;
:: esthetics ( from to base -- seq )
[ base <iota> [| num | from to num base bfs ] each ]
{ } make natural-sort ;
: .seq ( seq width -- )
group [ [ dup string? [ write ] [ pprint ] if bl ] each nl ]
each nl ;
:: show ( base -- )
base [ 4 * ] [ 6 * ] bi :> ( from to )
from to [ dup ordinal-suffix ] bi@ base
"%d%s through %d%s esthetic numbers in base %d\n" printf
from to 1 + 0 5000 ! enough for base 16
base esthetics subseq [ base >base ] map 17 .seq ;
2 16 [a,b] [ show ] each
"Base 10 numbers between 1,000 and 9,999:" print
1,000 9,999 10 esthetics 16 .seq
"Base 10 numbers between 100,000,000 and 130,000,000:" print
100,000,000 130,000,000 10 esthetics 9 .seq
"Count of base 10 esthetic numbers between zero and one quadrillion:"
print 0 1e15 10 esthetics length .
- Output:
8th through 12th esthetic numbers in base 2 10101010 101010101 1010101010 10101010101 101010101010 12th through 18th esthetic numbers in base 3 1210 1212 2101 2121 10101 10121 12101 16th through 24th esthetic numbers in base 4 323 1010 1012 1210 1212 1232 2101 2121 2123 20th through 30th esthetic numbers in base 5 323 343 432 434 1010 1012 1210 1212 1232 1234 2101 24th through 36th esthetic numbers in base 6 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234 28th through 42nd esthetic numbers in base 7 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232 32nd through 48th esthetic numbers in base 8 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212 36th through 54th esthetic numbers in base 9 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210 40th through 60th esthetic numbers in base 10 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012 44th through 66th esthetic numbers in base 11 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 a98 a9a 1010 48th through 72nd esthetic numbers in base 12 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba ba9 bab 52nd through 78th esthetic numbers in base 13 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb cba 56th through 84th esthetic numbers in base 14 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc 60th through 90th esthetic numbers in base 15 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd 64th through 96th esthetic numbers in base 16 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd ded def edc Base 10 numbers between 1,000 and 9,999: 1010 1012 1210 1212 1232 1234 2101 2121 2123 2321 2323 2343 2345 3210 3212 3232 3234 3432 3434 3454 3456 4321 4323 4343 4345 4543 4545 4565 4567 5432 5434 5454 5456 5654 5656 5676 5678 6543 6545 6565 6567 6765 6767 6787 6789 7654 7656 7676 7678 7876 7878 7898 8765 8767 8787 8789 8987 8989 9876 9878 9898 Base 10 numbers between 100,000,000 and 130,000,000: 101010101 101010121 101010123 101012101 101012121 101012123 101012321 101012323 101012343 101012345 101210101 101210121 101210123 101212101 101212121 101212123 101212321 101212323 101212343 101212345 101232101 101232121 101232123 101232321 101232323 101232343 101232345 101234321 101234323 101234343 101234345 101234543 101234545 101234565 101234567 121010101 121010121 121010123 121012101 121012121 121012123 121012321 121012323 121012343 121012345 121210101 121210121 121210123 121212101 121212121 121212123 121212321 121212323 121212343 121212345 121232101 121232121 121232123 121232321 121232323 121232343 121232345 121234321 121234323 121234343 121234345 121234543 121234545 121234565 121234567 123210101 123210121 123210123 123212101 123212121 123212123 123212321 123212323 123212343 123212345 123232101 123232121 123232123 123232321 123232323 123232343 123232345 123234321 123234323 123234343 123234345 123234543 123234545 123234565 123234567 123432101 123432121 123432123 123432321 123432323 123432343 123432345 123434321 123434323 123434343 123434345 123434543 123434545 123434565 123434567 123454321 123454323 123454343 123454345 123454543 123454545 123454565 123454567 123456543 123456545 123456565 123456567 123456765 123456767 123456787 123456789 Count of base 10 esthetic numbers between zero and one quadrillion: 161914
Forth
\ Returns the next esthetic number in the given base after n, where n is an
\ esthetic number in that base or one less than a power of base.
: next_esthetic_number { n base -- n }
n 1+ base < if n 1+ exit then
n base / dup base mod
dup n base mod 1+ = if dup 1+ base < if 2drop n 2 + exit then then
drop base recurse
dup base mod
dup 0= if 1+ else 1- then
swap base * + ;
: print_esthetic_numbers { min max per_line -- }
." Esthetic numbers in base 10 between " min 1 .r ." and " max 1 .r ." :" cr
0
min 1- 10 next_esthetic_number
begin
dup max <=
while
dup 4 .r
swap 1+ dup per_line mod 0= if cr else space then swap
10 next_esthetic_number
repeat
drop
cr ." count: " . cr ;
: main
17 2 do
i 4 * i 6 * { min max }
." Esthetic numbers in base " i 1 .r ." from index " min 1 .r ." through index " max 1 .r ." :" cr
0
max 1+ 1 do
j next_esthetic_number
i min >= if dup ['] . j base-execute then
loop
drop
cr cr
loop
1000 9999 16 print_esthetic_numbers cr
100000000 130000000 8 print_esthetic_numbers ;
main
bye
- Output:
Esthetic numbers in base 2 from index 8 through index 12: 10101010 101010101 1010101010 10101010101 101010101010 Esthetic numbers in base 3 from index 12 through index 18: 1210 1212 2101 2121 10101 10121 12101 Esthetic numbers in base 4 from index 16 through index 24: 323 1010 1012 1210 1212 1232 2101 2121 2123 Esthetic numbers in base 5 from index 20 through index 30: 323 343 432 434 1010 1012 1210 1212 1232 1234 2101 Esthetic numbers in base 6 from index 24 through index 36: 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234 Esthetic numbers in base 7 from index 28 through index 42: 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232 Esthetic numbers in base 8 from index 32 through index 48: 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212 Esthetic numbers in base 9 from index 36 through index 54: 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210 Esthetic numbers in base 10 from index 40 through index 60: 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012 Esthetic numbers in base 11 from index 44 through index 66: 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 A98 A9A 1010 Esthetic numbers in base 12 from index 48 through index 72: 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA BA9 BAB Esthetic numbers in base 13 from index 52 through index 78: 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB CBA Esthetic numbers in base 14 from index 56 through index 84: 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC Esthetic numbers in base 15 from index 60 through index 90: 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC CDE DCB DCD Esthetic numbers in base 16 from index 64 through index 96: 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC CDE DCB DCD DED DEF EDC Esthetic numbers in base 10 between 1000 and 9999: 1010 1012 1210 1212 1232 1234 2101 2121 2123 2321 2323 2343 2345 3210 3212 3232 3234 3432 3434 3454 3456 4321 4323 4343 4345 4543 4545 4565 4567 5432 5434 5454 5456 5654 5656 5676 5678 6543 6545 6565 6567 6765 6767 6787 6789 7654 7656 7676 7678 7876 7878 7898 8765 8767 8787 8789 8987 8989 9876 9878 9898 count: 61 Esthetic numbers in base 10 between 100000000 and 130000000: 101010101 101010121 101010123 101012101 101012121 101012123 101012321 101012323 101012343 101012345 101210101 101210121 101210123 101212101 101212121 101212123 101212321 101212323 101212343 101212345 101232101 101232121 101232123 101232321 101232323 101232343 101232345 101234321 101234323 101234343 101234345 101234543 101234545 101234565 101234567 121010101 121010121 121010123 121012101 121012121 121012123 121012321 121012323 121012343 121012345 121210101 121210121 121210123 121212101 121212121 121212123 121212321 121212323 121212343 121212345 121232101 121232121 121232123 121232321 121232323 121232343 121232345 121234321 121234323 121234343 121234345 121234543 121234545 121234565 121234567 123210101 123210121 123210123 123212101 123212121 123212123 123212321 123212323 123212343 123212345 123232101 123232121 123232123 123232321 123232323 123232343 123232345 123234321 123234323 123234343 123234345 123234543 123234545 123234565 123234567 123432101 123432121 123432123 123432321 123432323 123432343 123432345 123434321 123434323 123434343 123434345 123434543 123434545 123434565 123434567 123454321 123454323 123454343 123454345 123454543 123454545 123454565 123454567 123456543 123456545 123456565 123456567 123456765 123456767 123456787 123456789 count: 126
FreeBASIC
dim shared as string*16 digits = "0123456789ABCDEF"
function get_digit( n as uinteger ) as string
return mid(digits, n+1, 1)
end function
function find_digit( s as string ) as integer
for i as uinteger = 1 to len(digits)
if s = mid(digits, i, 1) then return i
next i
return -999
end function
sub make_base( byval n as uinteger, bse as uinteger, byref ret as string )
if n = 0 then ret = "0" else ret = ""
dim as uinteger m
while n > 0
m = n mod bse
ret = mid(digits, m+1, 1) + ret
n = (n - m)/bse
wend
end sub
function is_esthetic( number as string ) as boolean
if number = "0" then return false
if len(number) = 1 then return true
dim as integer curr = find_digit( left(number,1) ), last, i
for i = 2 to len(number)
last = curr
curr = find_digit( mid(number, i, 1) )
if abs( last - curr ) <> 1 then return false
next i
return true
end function
dim as uinteger b, c
dim as ulongint i
dim as string number
for b = 2 to 16
print "BASE ";b
i = 0 : c = 0
while c <= 6*b
i += 1
make_base i, b, number
if is_esthetic( number ) then
c += 1
if c >= 4*b then print number;" ";
end if
wend
print
next b
print "BASE TEN"
for i = 1000 to 9999
make_base i, 10, number
if is_esthetic(number) then print number;" ";
next i
print
print "STRETCH GOAL"
for i = 100000000 to 130000000
make_base i, 10, number
if is_esthetic(number) then print number;" ";
next i
- Output:
BASE 2 10101010 101010101 1010101010 10101010101 101010101010 1010101010101 BASE 3 1210 1212 2101 2121 10101 10121 12101 12121 BASE 4 323 1010 1012 1210 1212 1232 2101 2121 2123 2321 BASE 5 323 343 432 434 1010 1012 1210 1212 1232 1234 2101 2121 BASE 6 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234 2101 BASE 7 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232 1234 BASE 8 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212 1232 BASE 9 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210 1212 BASE 10 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012 1210 BASE 11 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 A98 A9A 1010 1012 BASE 12 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA BA9 BAB 1010 BASE 13 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB CBA CBC BASE 14 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC DCB BASE 15 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC CDE DCB DCD DED BASE 16 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC CDE DCB DCD DED DEF EDC EDE BASE TEN 1010 1012 1210 1212 1232 1234 2101 2121 2123 2321 2323 2343 2345 3210 3212 3232 3234 3432 3434 3454 3456 4321 4323 4343 4345 4543 4545 4565 4567 5432 5434 5454 5456 5654 5656 5676 5678 6543 6545 6565 6567 6765 6767 6787 6789 7654 7656 7676 7678 7876 7878 7898 8765 8767 8787 8789 8987 8989 9876 9878 9898 STRETCH GOAL 101010101 101010121 101010123 101012101 101012121 101012123 101012321 101012323 101012343 101012345 101210101 101210121 101210123 101212101 101212121 101212123 101212321 101212323 101212343 101212345 101232101 101232121 101232123 101232321 101232323 101232343 101232345 101234321 101234323 101234343 101234345 101234543 101234545 101234565 101234567 121010101 121010121 121010123 121012101 121012121 121012123 121012321 121012323 121012343 121012345 121210101 121210121 121210123 121212101 121212121 121212123 121212321 121212323 121212343 121212345 121232101 121232121 121232123 121232321 121232323 121232343 121232345 121234321 121234323 121234343 121234345 121234543 121234545 121234565 121234567 123210101 123210121 123210123 123212101 123212121 123212123 123212321 123212323 123212343 123212345 123232101 123232121 123232123 123232321 123232323 123232343 123232345 123234321 123234323 123234343 123234345 123234543 123234545 123234565 123234567 123432101 123432121 123432123 123432321 123432323 123432343 123432345 123434321 123434323 123434343 123434345 123434543 123434545 123434565 123434567 123454321 123454323 123454343 123454345 123454543 123454545 123454565 123454567 123456543 123456545 123456565 123456567 123456765 123456767 123456787 123456789
Go
A simple brute force approach suffices for the first and second parts of the task.
For the last two parts (stretched up to 1.0e17/1.3e17), a 'depth first search' approach is used with the obvious range limitations imposed for extra speed.
package main
import (
"fmt"
"strconv"
)
func uabs(a, b uint64) uint64 {
if a > b {
return a - b
}
return b - a
}
func isEsthetic(n, b uint64) bool {
if n == 0 {
return false
}
i := n % b
n /= b
for n > 0 {
j := n % b
if uabs(i, j) != 1 {
return false
}
n /= b
i = j
}
return true
}
var esths []uint64
func dfs(n, m, i uint64) {
if i >= n && i <= m {
esths = append(esths, i)
}
if i == 0 || i > m {
return
}
d := i % 10
i1 := i*10 + d - 1
i2 := i1 + 2
if d == 0 {
dfs(n, m, i2)
} else if d == 9 {
dfs(n, m, i1)
} else {
dfs(n, m, i1)
dfs(n, m, i2)
}
}
func listEsths(n, n2, m, m2 uint64, perLine int, all bool) {
esths = esths[:0]
for i := uint64(0); i < 10; i++ {
dfs(n2, m2, i)
}
le := len(esths)
fmt.Printf("Base 10: %s esthetic numbers between %s and %s:\n",
commatize(uint64(le)), commatize(n), commatize(m))
if all {
for c, esth := range esths {
fmt.Printf("%d ", esth)
if (c+1)%perLine == 0 {
fmt.Println()
}
}
} else {
for i := 0; i < perLine; i++ {
fmt.Printf("%d ", esths[i])
}
fmt.Println("\n............\n")
for i := le - perLine; i < le; i++ {
fmt.Printf("%d ", esths[i])
}
}
fmt.Println("\n")
}
func commatize(n uint64) string {
s := fmt.Sprintf("%d", n)
le := len(s)
for i := le - 3; i >= 1; i -= 3 {
s = s[0:i] + "," + s[i:]
}
return s
}
func main() {
for b := uint64(2); b <= 16; b++ {
fmt.Printf("Base %d: %dth to %dth esthetic numbers:\n", b, 4*b, 6*b)
for n, c := uint64(1), uint64(0); c < 6*b; n++ {
if isEsthetic(n, b) {
c++
if c >= 4*b {
fmt.Printf("%s ", strconv.FormatUint(n, int(b)))
}
}
}
fmt.Println("\n")
}
// the following all use the obvious range limitations for the numbers in question
listEsths(1000, 1010, 9999, 9898, 16, true)
listEsths(1e8, 101_010_101, 13*1e7, 123_456_789, 9, true)
listEsths(1e11, 101_010_101_010, 13*1e10, 123_456_789_898, 7, false)
listEsths(1e14, 101_010_101_010_101, 13*1e13, 123_456_789_898_989, 5, false)
listEsths(1e17, 101_010_101_010_101_010, 13*1e16, 123_456_789_898_989_898, 4, false)
}
- Output:
Base 2: 8th to 12th esthetic numbers: 10101010 101010101 1010101010 10101010101 101010101010 Base 3: 12th to 18th esthetic numbers: 1210 1212 2101 2121 10101 10121 12101 Base 4: 16th to 24th esthetic numbers: 323 1010 1012 1210 1212 1232 2101 2121 2123 Base 5: 20th to 30th esthetic numbers: 323 343 432 434 1010 1012 1210 1212 1232 1234 2101 Base 6: 24th to 36th esthetic numbers: 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234 Base 7: 28th to 42th esthetic numbers: 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232 Base 8: 32th to 48th esthetic numbers: 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212 Base 9: 36th to 54th esthetic numbers: 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210 Base 10: 40th to 60th esthetic numbers: 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012 Base 11: 44th to 66th esthetic numbers: 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 a98 a9a 1010 Base 12: 48th to 72th esthetic numbers: 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba ba9 bab Base 13: 52th to 78th esthetic numbers: 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb cba Base 14: 56th to 84th esthetic numbers: 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc Base 15: 60th to 90th esthetic numbers: 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd Base 16: 64th to 96th esthetic numbers: 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd ded def edc Base 10: 61 esthetic numbers between 1,000 and 9,999: 1010 1012 1210 1212 1232 1234 2101 2121 2123 2321 2323 2343 2345 3210 3212 3232 3234 3432 3434 3454 3456 4321 4323 4343 4345 4543 4545 4565 4567 5432 5434 5454 5456 5654 5656 5676 5678 6543 6545 6565 6567 6765 6767 6787 6789 7654 7656 7676 7678 7876 7878 7898 8765 8767 8787 8789 8987 8989 9876 9878 9898 Base 10: 126 esthetic numbers between 100,000,000 and 130,000,000: 101010101 101010121 101010123 101012101 101012121 101012123 101012321 101012323 101012343 101012345 101210101 101210121 101210123 101212101 101212121 101212123 101212321 101212323 101212343 101212345 101232101 101232121 101232123 101232321 101232323 101232343 101232345 101234321 101234323 101234343 101234345 101234543 101234545 101234565 101234567 121010101 121010121 121010123 121012101 121012121 121012123 121012321 121012323 121012343 121012345 121210101 121210121 121210123 121212101 121212121 121212123 121212321 121212323 121212343 121212345 121232101 121232121 121232123 121232321 121232323 121232343 121232345 121234321 121234323 121234343 121234345 121234543 121234545 121234565 121234567 123210101 123210121 123210123 123212101 123212121 123212123 123212321 123212323 123212343 123212345 123232101 123232121 123232123 123232321 123232323 123232343 123232345 123234321 123234323 123234343 123234345 123234543 123234545 123234565 123234567 123432101 123432121 123432123 123432321 123432323 123432343 123432345 123434321 123434323 123434343 123434345 123434543 123434545 123434565 123434567 123454321 123454323 123454343 123454345 123454543 123454545 123454565 123454567 123456543 123456545 123456565 123456567 123456765 123456767 123456787 123456789 Base 10: 911 esthetic numbers between 100,000,000,000 and 130,000,000,000: 101010101010 101010101012 101010101210 101010101212 101010101232 101010101234 101010121010 ............ 123456787678 123456787876 123456787878 123456787898 123456789876 123456789878 123456789898 Base 10: 6,225 esthetic numbers between 100,000,000,000,000 and 130,000,000,000,000: 101010101010101 101010101010121 101010101010123 101010101012101 101010101012121 ............ 123456789898767 123456789898787 123456789898789 123456789898987 123456789898989 Base 10: 44,744 esthetic numbers between 100,000,000,000,000,000 and 130,000,000,000,000,000: 101010101010101010 101010101010101012 101010101010101210 101010101010101212 ............ 123456789898987898 123456789898989876 123456789898989878 123456789898989898
Haskell
import Data.List (unfoldr, genericIndex)
import Control.Monad (replicateM, foldM, mzero)
-- a predicate for esthetic numbers
isEsthetic b = all ((== 1) . abs) . differences . toBase b
where
differences lst = zipWith (-) lst (tail lst)
-- Monadic solution, inefficient for small bases.
esthetics_m b =
do differences <- (\n -> replicateM n [-1, 1]) <$> [0..]
firstDigit <- [1..b-1]
differences >>= fromBase b <$> scanl (+) firstDigit
-- Much more efficient iterative solution (translation from Python).
-- Uses simple list as an ersatz queue.
esthetics b = tail $ fst <$> iterate step (undefined, q)
where
q = [(d, d) | d <- [1..b-1]]
step (_, queue) =
let (num, lsd) = head queue
new_lsds = [d | d <- [lsd-1, lsd+1], d < b, d >= 0]
in (num, tail queue ++ [(num*b + d, d) | d <- new_lsds])
-- representation of numbers as digits
fromBase b = foldM f 0
where f r d | d < 0 || d >= b = mzero
| otherwise = pure (r*b + d)
toBase b = reverse . unfoldr f
where
f 0 = Nothing
f n = let (q, r) = divMod n b in Just (r, q)
showInBase b = foldMap (pure . digit) . toBase b
where digit = genericIndex (['0'..'9'] <> ['a'..'z'])
Tasks implementation
λ> isEsthetic 10 1234567654321 True λ> isEsthetic 10 1234560654321 False λ> isEsthetic 2 <$> fromBase 2 [1,0,1,0,1,0] True λ> isEsthetic 2 <$> fromBase 2 [1,0,1,0,1,1] False λ> take 50 $ esthetics 10 [1,2,3,4,5,6,7,8,9,10,12,21,23,32,34,43,45,54,56,65,67,76,78,87,89,98,101,121,123,210,212,232,234,321,323,343,345,432,434, 454,456,543,545,565,567,654,656,676,678,765] λ> take 50 $ showInBase 3 <$> esthetics 3 ["1","2","10","12","21","101","121","210","212","1010","1012","1210","1212","2101","2121","10101","10121","12101","12121", "21010","21012","21210","21212","101010","101012","101210","101212","121010","121012","121210","121212","210101","210121", "212101","212121","1010101","1010121","1012101","1012121","1210101","1210121","1212101","1212121","2101010","2101012", "2101210","2101212","2121010","2121012","2121210"] λ> :{ *Main| examples b = do { *Main| putStrLn $ "Task for base " <> show b; *Main| putStrLn $ unwords $ showInBase b <$> (drop (b*4-1) . take (b*6) $ esthetics b)} *Main| :} λ> mapM_ examples [2..16] Task for base 2 10101010 101010101 1010101010 10101010101 101010101010 Task for base 3 1210 1212 2101 2121 10101 10121 12101 Task for base 4 323 1010 1012 1210 1212 1232 2101 2121 2123 Task for base 5 323 343 432 434 1010 1012 1210 1212 1232 1234 2101 Task for base 6 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234 Task for base 7 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232 Task for base 8 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212 Task for base 9 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210 Task for base 10 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012 Task for base 11 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 a98 a9a 1010 Task for base 12 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba ba9 bab Task for base 13 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb cba Task for base 14 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc Task for base 15 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd Task for base 16 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd ded def edc λ> let takeWithin a b = dropWhile (< a) . takeWhile (<= b) λ> takeWithin 1000 9999 $ esthetics 10 [1010,1012,1210,1212,1232,1234,2101,2121,2123,2321,2323,2343,2345,3210,3212,3232,3234,3432,3434,3454,3456,4321,4323,4343, 4345,4543,4545,4565,4567,5432,5434,5454,5456,5654,5656,5676,5678,6543,6545,6565,6567,6765,6767,6787,6789,7654,7656,7676, 7678,7876,7878,7898,8765,8767,8787,8789,8987,8989,9876,9878,9898] λ> takeWithin 100000000 130000000 $ esthetics 10 [101010101,101010121,101010123,101012101,101012121,101012123,101012321,101012323,101012343,101012345,101210101,101210121, 101210123,101212101,101212121,101212123,101212321,101212323,101212343,101212345,101232101,101232121,101232123,101232321, 101232323,101232343,101232345,101234321,101234323,101234343,101234345,101234543,101234545,101234565,101234567,121010101, 121010121,121010123,121012101,121012121,121012123,121012321,121012323,121012343,121012345,121210101,121210121,121210123, 121212101,121212121,121212123,121212321,121212323,121212343,121212345,121232101,121232121,121232123,121232321,121232323, 121232343,121232345,121234321,121234323,121234343,121234345,121234543,121234545,121234565,121234567,123210101,123210121, 123210123,123212101,123212121,123212123,123212321,123212323,123212343,123212345,123232101,123232121,123232123,123232321, 123232323,123232343,123232345,123234321,123234323,123234343,123234345,123234543,123234545,123234565,123234567,123432101, 123432121,123432123,123432321,123432323,123432343,123432345,123434321,123434323,123434343,123434345,123434543,123434545, 123434565,123434567,123454321,123454323,123454343,123454345,123454543,123454545,123454565,123454567,123456543,123456545, 123456565,123456567,123456765,123456767,123456787,123456789] λ> length it 126 λ> length $ takeWithin 100000000000000000 130000000000000000 $ esthetics 10 44744
J
Implementation (brute force):
isesthetic=: 10&$: :(1 */ .=2 |@-/\ #.inv)"0
gen=: {{r=.$k=.1 while.y>#r do. r=.r,k#~u k
k=.1+({:k)+i.2*#k end.y{.r}}
Task examples:
tobase=: (a.{~;48 97(+ i.)each 10 26) {~ #.inv
taskB=: {{;:inv y tobase&.> (<:4*y)}. y&isesthetic gen 6*y}}
taskB 2
10101010 101010101 1010101010 10101010101 101010101010
taskB 3
1210 1212 2101 2121 10101 10121 12101
taskB 4
323 1010 1012 1210 1212 1232 2101 2121 2123
taskB 5
323 343 432 434 1010 1012 1210 1212 1232 1234 2101
taskB 6
343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234
taskB 7
345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232
taskB 8
432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212
taskB 9
434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210
taskB 10
454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012
taskB 11
456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 a98 a9a 1010
taskB 12
543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba ba9 bab
taskB 13
545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb cba
taskB 14
565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc
taskB 15
567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd
taskB 16
654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd ded def edc
(#~ isesthetic) 1000+i.1000
1010 1012 1210 1212 1232 1234
Stretch goal (the slow way):
$e=: x: (#~ isesthetic) 1e8+i.1+3e7
126
q:126
2 3 3 7
(Result e not displayed here -- it's the same as next^:8]1 below.)
It's much more efficient to generate sequences of digits from a base digit, rather than generating sequential integers and discarding those which are not suitable.
For example, we can generate a directed graph, from one digit to the one or two viable adjacent digits, and then build up a result based on all viable values of the rightmost digit of the current list of partially built candidates:
graph=: </./|:0 1,10 10#:(#~ isesthetic)10+i.90
next=: [:; (0 10#.],.graph {::~10|])each
next^:3]1
1010 1012 1210 1212 1232 1234
$next^:8]1
126
14 9$next^:8]1
101010101 101010121 101010123 101012101 101012121 101012123 101012321 101012323 101012343
101012345 101210101 101210121 101210123 101212101 101212121 101212123 101212321 101212323
101212343 101212345 101232101 101232121 101232123 101232321 101232323 101232343 101232345
101234321 101234323 101234343 101234345 101234543 101234545 101234565 101234567 121010101
121010121 121010123 121012101 121012121 121012123 121012321 121012323 121012343 121012345
121210101 121210121 121210123 121212101 121212121 121212123 121212321 121212323 121212343
121212345 121232101 121232121 121232123 121232321 121232323 121232343 121232345 121234321
121234323 121234343 121234345 121234543 121234545 121234565 121234567 123210101 123210121
123210123 123212101 123212121 123212123 123212321 123212323 123212343 123212345 123232101
123232121 123232123 123232321 123232323 123232343 123232345 123234321 123234323 123234343
123234345 123234543 123234545 123234565 123234567 123432101 123432121 123432123 123432321
123432323 123432343 123432345 123434321 123434323 123434343 123434345 123434543 123434545
123434565 123434567 123454321 123454323 123454343 123454345 123454543 123454545 123454565
123454567 123456543 123456545 123456565 123456567 123456765 123456767 123456787 123456789
(We organize the 126 values of the stretch goal into 14 rows of 9 columns (126=14*9) using the expression 14 9 $ ...)
Java
import java.util.ArrayList;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
public class EstheticNumbers {
interface RecTriConsumer<A, B, C> {
void accept(RecTriConsumer<A, B, C> f, A a, B b, C c);
}
private static boolean isEsthetic(long n, long b) {
if (n == 0) {
return false;
}
var i = n % b;
var n2 = n / b;
while (n2 > 0) {
var j = n2 % b;
if (Math.abs(i - j) != 1) {
return false;
}
n2 /= b;
i = j;
}
return true;
}
private static void listEsths(long n, long n2, long m, long m2, int perLine, boolean all) {
var esths = new ArrayList<Long>();
var dfs = new RecTriConsumer<Long, Long, Long>() {
public void accept(Long n, Long m, Long i) {
accept(this, n, m, i);
}
@Override
public void accept(RecTriConsumer<Long, Long, Long> f, Long n, Long m, Long i) {
if (n <= i && i <= m) {
esths.add(i);
}
if (i == 0 || i > m) {
return;
}
var d = i % 10;
var i1 = i * 10 + d - 1;
var i2 = i1 + 2;
if (d == 0) {
f.accept(f, n, m, i2);
} else if (d == 9) {
f.accept(f, n, m, i1);
} else {
f.accept(f, n, m, i1);
f.accept(f, n, m, i2);
}
}
};
LongStream.range(0, 10).forEach(i -> dfs.accept(n2, m2, i));
var le = esths.size();
System.out.printf("Base 10: %d esthetic numbers between %d and %d:%n", le, n, m);
if (all) {
for (int i = 0; i < esths.size(); i++) {
System.out.printf("%d ", esths.get(i));
if ((i + 1) % perLine == 0) {
System.out.println();
}
}
} else {
for (int i = 0; i < perLine; i++) {
System.out.printf("%d ", esths.get(i));
}
System.out.println();
System.out.println("............");
for (int i = le - perLine; i < le; i++) {
System.out.printf("%d ", esths.get(i));
}
}
System.out.println();
System.out.println();
}
public static void main(String[] args) {
IntStream.rangeClosed(2, 16).forEach(b -> {
System.out.printf("Base %d: %dth to %dth esthetic numbers:%n", b, 4 * b, 6 * b);
var n = 1L;
var c = 0L;
while (c < 6 * b) {
if (isEsthetic(n, b)) {
c++;
if (c >= 4 * b) {
System.out.printf("%s ", Long.toString(n, b));
}
}
n++;
}
System.out.println();
});
System.out.println();
// the following all use the obvious range limitations for the numbers in question
listEsths(1000, 1010, 9999, 9898, 16, true);
listEsths((long) 1e8, 101_010_101, 13 * (long) 1e7, 123_456_789, 9, true);
listEsths((long) 1e11, 101_010_101_010L, 13 * (long) 1e10, 123_456_789_898L, 7, false);
listEsths((long) 1e14, 101_010_101_010_101L, 13 * (long) 1e13, 123_456_789_898_989L, 5, false);
listEsths((long) 1e17, 101_010_101_010_101_010L, 13 * (long) 1e16, 123_456_789_898_989_898L, 4, false);
}
}
- Output:
Base 2: 8th to 12th esthetic numbers: 10101010 101010101 1010101010 10101010101 101010101010 Base 3: 12th to 18th esthetic numbers: 1210 1212 2101 2121 10101 10121 12101 Base 4: 16th to 24th esthetic numbers: 323 1010 1012 1210 1212 1232 2101 2121 2123 Base 5: 20th to 30th esthetic numbers: 323 343 432 434 1010 1012 1210 1212 1232 1234 2101 Base 6: 24th to 36th esthetic numbers: 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234 Base 7: 28th to 42th esthetic numbers: 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232 Base 8: 32th to 48th esthetic numbers: 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212 Base 9: 36th to 54th esthetic numbers: 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210 Base 10: 40th to 60th esthetic numbers: 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012 Base 11: 44th to 66th esthetic numbers: 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 a98 a9a 1010 Base 12: 48th to 72th esthetic numbers: 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba ba9 bab Base 13: 52th to 78th esthetic numbers: 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb cba Base 14: 56th to 84th esthetic numbers: 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc Base 15: 60th to 90th esthetic numbers: 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd Base 16: 64th to 96th esthetic numbers: 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd ded def edc Base 10: 61 esthetic numbers between 1000 and 9999: 1010 1012 1210 1212 1232 1234 2101 2121 2123 2321 2323 2343 2345 3210 3212 3232 3234 3432 3434 3454 3456 4321 4323 4343 4345 4543 4545 4565 4567 5432 5434 5454 5456 5654 5656 5676 5678 6543 6545 6565 6567 6765 6767 6787 6789 7654 7656 7676 7678 7876 7878 7898 8765 8767 8787 8789 8987 8989 9876 9878 9898 Base 10: 126 esthetic numbers between 100000000 and 130000000: 101010101 101010121 101010123 101012101 101012121 101012123 101012321 101012323 101012343 101012345 101210101 101210121 101210123 101212101 101212121 101212123 101212321 101212323 101212343 101212345 101232101 101232121 101232123 101232321 101232323 101232343 101232345 101234321 101234323 101234343 101234345 101234543 101234545 101234565 101234567 121010101 121010121 121010123 121012101 121012121 121012123 121012321 121012323 121012343 121012345 121210101 121210121 121210123 121212101 121212121 121212123 121212321 121212323 121212343 121212345 121232101 121232121 121232123 121232321 121232323 121232343 121232345 121234321 121234323 121234343 121234345 121234543 121234545 121234565 121234567 123210101 123210121 123210123 123212101 123212121 123212123 123212321 123212323 123212343 123212345 123232101 123232121 123232123 123232321 123232323 123232343 123232345 123234321 123234323 123234343 123234345 123234543 123234545 123234565 123234567 123432101 123432121 123432123 123432321 123432323 123432343 123432345 123434321 123434323 123434343 123434345 123434543 123434545 123434565 123434567 123454321 123454323 123454343 123454345 123454543 123454545 123454565 123454567 123456543 123456545 123456565 123456567 123456765 123456767 123456787 123456789 Base 10: 911 esthetic numbers between 100000000000 and 130000000000: 101010101010 101010101012 101010101210 101010101212 101010101232 101010101234 101010121010 ............ 123456787678 123456787876 123456787878 123456787898 123456789876 123456789878 123456789898 Base 10: 6225 esthetic numbers between 100000000000000 and 130000000000000: 101010101010101 101010101010121 101010101010123 101010101012101 101010101012121 ............ 123456789898767 123456789898787 123456789898789 123456789898987 123456789898989 Base 10: 44744 esthetic numbers between 100000000000000000 and 130000000000000000: 101010101010101010 101010101010101012 101010101010101210 101010101010101212 ............ 123456789898987898 123456789898989876 123456789898989878 123456789898989898
JavaScript
JavaScript :: Procedural
function isEsthetic(inp, base = 10) {
let arr = inp.toString(base).split('');
if (arr.length == 1) return false;
for (let i = 0; i < arr.length; i++)
arr[i] = parseInt(arr[i], base);
for (i = 0; i < arr.length-1; i++)
if (Math.abs(arr[i]-arr[i+1]) !== 1) return false;
return true;
}
function collectEsthetics(base, range) {
let out = [], x;
if (range) {
for (x = range[0]; x < range[1]; x++)
if (isEsthetic(x)) out.push(x);
return out;
} else {
x = 1;
while (out.length < base*6) {
s = x.toString(base);
if (isEsthetic(s, base)) out.push(s.toUpperCase());
x++;
}
return out.slice(base*4);
}
}
// main
let d = new Date();
for (let x = 2; x <= 36; x++) { // we put b17 .. b36 on top, because we can
console.log(`${x}:`);
console.log( collectEsthetics(x),
(new Date() - d) / 1000 + ' s');
}
console.log( collectEsthetics(10, [1000, 9999]),
(new Date() - d) / 1000 + ' s' );
console.log( collectEsthetics(10, [1e8, 1.3e8]),
(new Date() - d) / 1000 + ' s' );
- Output:
2:> Array(4) [ "1010101010", "10101010101", "101010101010", "1010101010101" ] 0.009 s 3: > Array(6) [ "2121", "10101", "10121", "12101", "12121", "21010" ] 0.01 s 4: > Array(8) [ "1212", "1232", "2101", "2121", "2123", "2321", "2323", "3210" ] 0.011 s 5: > Array(10) [ "1012", "1210", "1212", "1232", "1234", "2101", "2121", "2123", "2321", "2323" ] 0.013 6: > Array(12) [ "545", "1010", "1012", "1210", "1212", "1232", "1234", "2101", "2121", "2123", … ] 0.015 s 7: > Array(14) [ "565", "654", "656", "1010", "1012", "1210", "1212", "1232", "1234", "2101", … ] 0.017 s 8: > Array(16) [ "654", "656", "676", "765", "767", "1010", "1012", "1210", "1212", "1232", … ] 0.018 s 9: > Array(18) [ "676", "678", "765", "767", "787", "876", "878", "1010", "1012", "1210", … ] 0.02 s 10: > Array(20) [ "765", "767", "787", "789", "876", "878", "898", "987", "989", "1010", … ] 0.021 s 11: > Array(22) [ "787", "789", "876", "878", "898", "89A", "987", "989", "9A9", "A98", … ] 0.023 s 12: > Array(24) [ "876", "878", "898", "89A", "987", "989", "9A9", "9AB", "A98", "A9A", … ] 0.026 s 13: > Array(26) [ "898", "89A", "987", "989", "9A9", "9AB", "A98", "A9A", "ABA", "ABC", … ] 0.028 s 14: > Array(28) [ "987", "989", "9A9", "9AB", "A98", "A9A", "ABA", "ABC", "BA9", "BAB", … ] 0.031 s 15: > Array(30) [ "9A9", "9AB", "A98", "A9A", "ABA", "ABC", "BA9", "BAB", "BCB", "BCD", … ] 0.035 s 16: > Array(32) [ "A98", "A9A", "ABA", "ABC", "BA9", "BAB", "BCB", "BCD", "CBA", "CBC", … ] 0.04 s 17: > Array(34) [ "ABA", "ABC", "BA9", "BAB", "BCB", "BCD", "CBA", "CBC", "CDC", "CDE", … ] 0.044 s 18: > Array(36) [ "BA9", "BAB", "BCB", "BCD", "CBA", "CBC", "CDC", "CDE", "DCB", "DCD", … ] 0.05 s 19: > Array(38) [ "BCB", "BCD", "CBA", "CBC", "CDC", "CDE", "DCB", "DCD", "DED", "DEF", … ] 0.056 s 20: > Array(40) [ "CBA", "CBC", "CDC", "CDE", "DCB", "DCD", "DED", "DEF", "EDC", "EDE", … ] 0.063 s 21: > Array(42) [ "CDC", "CDE", "DCB", "DCD", "DED", "DEF", "EDC", "EDE", "EFE", "EFG", … ] 0.072 s 22: > Array(44) [ "DCB", "DCD", "DED", "DEF", "EDC", "EDE", "EFE", "EFG", "FED", "FEF", … ] 0.081 s 23: > Array(46) [ "DED", "DEF", "EDC", "EDE", "EFE", "EFG", "FED", "FEF", "FGF", "FGH", … ] 0.092 s 24: > Array(48) [ "EDC", "EDE", "EFE", "EFG", "FED", "FEF", "FGF", "FGH", "GFE", "GFG", … ] 0.103 s 25: > Array(50) [ "EFE", "EFG", "FED", "FEF", "FGF", "FGH", "GFE", "GFG", "GHG", "GHI", … ] 0.116 s 26: > Array(52) [ "FED", "FEF", "FGF", "FGH", "GFE", "GFG", "GHG", "GHI", "HGF", "HGH", … ] 0.132 s 27: > Array(54) [ "FGF", "FGH", "GFE", "GFG", "GHG", "GHI", "HGF", "HGH", "HIH", "HIJ", … ] 0.147 s 28: > Array(56) [ "GFE", "GFG", "GHG", "GHI", "HGF", "HGH", "HIH", "HIJ", "IHG", "IHI", … ] 0.169 s 29: > Array(58) [ "GHG", "GHI", "HGF", "HGH", "HIH", "HIJ", "IHG", "IHI", "IJI", "IJK", … ] 0.191 s 30: > Array(60) [ "HGF", "HGH", "HIH", "HIJ", "IHG", "IHI", "IJI", "IJK", "JIH", "JIJ", … ] 0.224 s 31: > Array(62) [ "HIH", "HIJ", "IHG", "IHI", "IJI", "IJK", "JIH", "JIJ", "JKJ", "JKL", … ] 0.257 s 32: > Array(64) [ "IHG", "IHI", "IJI", "IJK", "JIH", "JIJ", "JKJ", "JKL", "KJI", "KJK", … ] 0.291 s 33: > Array(66) [ "IJI", "IJK", "JIH", "JIJ", "JKJ", "JKL", "KJI", "KJK", "KLK", "KLM", … ] 0.327 s 34: > Array(68) [ "JIH", "JIJ", "JKJ", "JKL", "KJI", "KJK", "KLK", "KLM", "LKJ", "LKL", … ] 0.373 s 35: > Array(70) [ "JKJ", "JKL", "KJI", "KJK", "KLK", "KLM", "LKJ", "LKL", "LML", "LMN", … ] 0.409 s 36: > Array(72) [ "KJI", "KJK", "KLK", "KLM", "LKJ", "LKL", "LML", "LMN", "MLK", "MLM", … ] 0.465 s > Array(61) [ 1010, 1012, 1210, 1212, 1232, 1234, 2101, 2121, 2123, 2321, … ] 0.47 s > Array(126) [ 101010101, 101010121, 101010123, 101012101, 101012121, 101012123, 101012321, 101012323, 101012343, 101012345, … ]
14.204 s
JavaScript :: Functional
Constrained generation – more efficient than a filter over a larger space.
(() => {
"use strict";
// -------- ESTHETIC NUMBERS IN A GIVEN BASE ---------
// estheticNumbersInBase :: Int -> [Int]
const estheticNumbersInBase = b =>
// An infinite sequence of numbers which
// are esthetic in the given base.
tail(fmapGen(x => x[0])(
iterate(([, queue]) => {
const [num, lsd] = queue[0];
const
newDigits = [lsd - 1, lsd + 1]
.flatMap(
d => (d < b && d >= 0) ? (
[d]
) : []
);
return Tuple(num)(
queue.slice(1).concat(
newDigits.flatMap(d => [
Tuple((num * b) + d)(d)
])
)
);
})(
Tuple()(
enumFromTo(1)(b - 1).flatMap(
d => [Tuple(d)(d)]
)
)
)
));
// ---------------------- TESTS ----------------------
const main = () => {
const samples = b => {
const
i = b * 4,
j = b * 6;
return unlines([
`Esthetics [${i}..${j}] for base ${b}:`,
...chunksOf(10)(
compose(drop(i - 1), take(j))(
estheticNumbersInBase(b)
).map(n => n.toString(b))
)
.map(unwords)
]);
};
const takeInRange = ([a, b]) =>
compose(
dropWhile(x => x < a),
takeWhileGen(x => x <= b)
);
return [
enumFromTo(2)(16)
.map(samples)
.join("\n\n"),
[
Tuple(1000)(9999),
Tuple(100000000)(130000000)
]
.map(
([lo, hi]) => unlines([
`Base 10 Esthetics in range [${lo}..${hi}]:`,
unlines(
chunksOf(6)(
takeInRange([lo, hi])(
estheticNumbersInBase(10)
)
)
.map(unwords)
)
])
).join("\n\n")
].join("\n\n");
};
// --------------------- GENERIC ---------------------
// Tuple (,) :: a -> b -> (a, b)
const Tuple = a =>
b => ({
type: "Tuple",
"0": a,
"1": b,
length: 2,
*[Symbol.iterator]() {
for (const k in this) {
if (!isNaN(k)) {
yield this[k];
}
}
}
});
// chunksOf :: Int -> [a] -> [[a]]
const chunksOf = n => {
// xs split into sublists of length n.
// The last sublist will be short if n
// does not evenly divide the length of xs .
const go = xs => {
const chunk = xs.slice(0, n);
return 0 < chunk.length ? (
[chunk].concat(
go(xs.slice(n))
)
) : [];
};
return go;
};
// compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
const compose = (...fs) =>
// A function defined by the right-to-left
// composition of all the functions in fs.
fs.reduce(
(f, g) => x => f(g(x)),
x => x
);
// drop :: Int -> [a] -> [a]
// drop :: Int -> Generator [a] -> Generator [a]
// drop :: Int -> String -> String
const drop = n =>
xs => Infinity > length(xs) ? (
xs.slice(n)
) : (take(n)(xs), xs);
// dropWhile :: (a -> Bool) -> [a] -> [a]
// dropWhile :: (Char -> Bool) -> String -> String
const dropWhile = p =>
// The suffix remaining after takeWhile p xs.
xs => {
const n = xs.length;
return xs.slice(
0 < n ? until(
i => n === i || !p(xs[i])
)(i => 1 + i)(0) : 0
);
};
// enumFromTo :: Int -> Int -> [Int]
const enumFromTo = m =>
n => Array.from({
length: 1 + n - m
}, (_, i) => m + i);
// fmapGen <$> :: (a -> b) -> Gen [a] -> Gen [b]
const fmapGen = f =>
// The map of f over a stream of generator values.
function* (gen) {
let v = gen.next();
while (!v.done) {
yield f(v.value);
v = gen.next();
}
};
// iterate :: (a -> a) -> a -> Gen [a]
const iterate = f =>
// An infinite list of repeated
// applications of f to x.
function* (x) {
let v = x;
while (true) {
yield v;
v = f(v);
}
};
// length :: [a] -> Int
const length = xs =>
// Returns Infinity over objects without finite
// length. This enables zip and zipWith to choose
// the shorter argument when one is non-finite,
// like cycle, repeat etc
"GeneratorFunction" !== xs.constructor
.constructor.name ? (
xs.length
) : Infinity;
// tail :: [a] -> [a]
const tail = xs =>
// A new list consisting of all
// items of xs except the first.
"GeneratorFunction" !== xs.constructor
.constructor.name ? (
(ys => 0 < ys.length ? ys.slice(1) : [])(
xs
)
) : (take(1)(xs), xs);
// take :: Int -> [a] -> [a]
// take :: Int -> String -> String
const take = n =>
// The first n elements of a list,
// string of characters, or stream.
xs => "GeneratorFunction" !== xs
.constructor.constructor.name ? (
xs.slice(0, n)
) : Array.from({
length: n
}, () => {
const x = xs.next();
return x.done ? [] : [x.value];
}).flat();
// takeWhileGen :: (a -> Bool) -> Gen [a] -> [a]
const takeWhileGen = p => xs => {
const ys = [];
let
nxt = xs.next(),
v = nxt.value;
while (!nxt.done && p(v)) {
ys.push(v);
nxt = xs.next();
v = nxt.value;
}
return ys;
};
// unlines :: [String] -> String
const unlines = xs =>
// A single string formed by the intercalation
// of a list of strings with the newline character.
xs.join("\n");
// until :: (a -> Bool) -> (a -> a) -> a -> a
const until = p =>
// The value resulting from repeated applications
// of f to the seed value x, terminating when
// that result returns true for the predicate p.
f => x => {
let v = x;
while (!p(v)) {
v = f(v);
}
return v;
};
// unwords :: [String] -> String
const unwords = xs =>
// A space-separated string derived
// from a list of words.
xs.join(" ");
// MAIN ---
return main();
})();
- Output:
Esthetics [8..12] for base 2: 10101010 101010101 1010101010 10101010101 101010101010 Esthetics [12..18] for base 3: 1210 1212 2101 2121 10101 10121 12101 Esthetics [16..24] for base 4: 323 1010 1012 1210 1212 1232 2101 2121 2123 Esthetics [20..30] for base 5: 323 343 432 434 1010 1012 1210 1212 1232 1234 2101 Esthetics [24..36] for base 6: 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234 Esthetics [28..42] for base 7: 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232 Esthetics [32..48] for base 8: 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212 Esthetics [36..54] for base 9: 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210 Esthetics [40..60] for base 10: 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012 Esthetics [44..66] for base 11: 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 a98 a9a 1010 Esthetics [48..72] for base 12: 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba ba9 bab Esthetics [52..78] for base 13: 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb cba Esthetics [56..84] for base 14: 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc Esthetics [60..90] for base 15: 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd Esthetics [64..96] for base 16: 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd ded def edc Base 10 Esthetics in range [1000..9999]: 1010 1012 1210 1212 1232 1234 2101 2121 2123 2321 2323 2343 2345 3210 3212 3232 3234 3432 3434 3454 3456 4321 4323 4343 4345 4543 4545 4565 4567 5432 5434 5454 5456 5654 5656 5676 5678 6543 6545 6565 6567 6765 6767 6787 6789 7654 7656 7676 7678 7876 7878 7898 8765 8767 8787 8789 8987 8989 9876 9878 9898 Base 10 Esthetics in range [100000000..130000000]: 101010101 101010121 101010123 101012101 101012121 101012123 101012321 101012323 101012343 101012345 101210101 101210121 101210123 101212101 101212121 101212123 101212321 101212323 101212343 101212345 101232101 101232121 101232123 101232321 101232323 101232343 101232345 101234321 101234323 101234343 101234345 101234543 101234545 101234565 101234567 121010101 121010121 121010123 121012101 121012121 121012123 121012321 121012323 121012343 121012345 121210101 121210121 121210123 121212101 121212121 121212123 121212321 121212323 121212343 121212345 121232101 121232121 121232123 121232321 121232323 121232343 121232345 121234321 121234323 121234343 121234345 121234543 121234545 121234565 121234567 123210101 123210121 123210123 123212101 123212121 123212123 123212321 123212323 123212343 123212345 123232101 123232121 123232123 123232321 123232323 123232343 123232345 123234321 123234323 123234343 123234345 123234543 123234545 123234565 123234567 123432101 123432121 123432123 123432321 123432323 123432343 123432345 123434321 123434323 123434343 123434345 123434543 123434545 123434565 123434567 123454321 123454323 123454343 123454345 123454543 123454545 123454565 123454567 123456543 123456545 123456565 123456567 123456765 123456767 123456787 123456789
jq
Adapted from Wren
Also works with gojq, the Go implementation of jq.
### Preliminaries
# _nwise/1 is included here for the sake of gojq:
def _nwise($n):
def n: if length <= $n then . else .[0:$n] , (.[$n:] | n) end;
n;
def tobase($b):
def digit: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[.:.+1];
def mod: . % $b;
def div: ((. - mod) / $b);
def digits: recurse( select(. > 0) | div) | mod ;
# For jq it would be wise to protect against `infinite` as input, but using `isinfinite` confuses gojq
select( (tostring|test("^[0-9]+$")) and 2 <= $b and $b <= 36)
| if . == 0 then "0"
else [digits | digit] | reverse[1:] | add
end;
### Esthetic Numbers
def isEsthetic($b):
if . == 0 then false
else {i: (. % $b), n: ((./$b)|floor) }
| until (.n <= 0;
(.n % $b) as $j
| if (.i - $j)|length != 1 # abs
then .n = -1 #flag
else .n |= ((./$b)|floor)
| .i = $j
end)
| .n != -1
end;
# depth-first search
# input: {esths}
def dfs($n; $m; $i):
if ($i >= $n and $i <= $m) then .esths += [$i] else . end
| if ($i == 0 or $i > $m) then .
else ($i % 10) as $d
| ($i*10 + $d - 1) as $i1
| ($i1 + 2) as $i2
| if $d == 0
then dfs($n; $m; $i2)
elif $d == 9
then dfs($n; $m; $i1)
else dfs($n; $m; $i1) | dfs($n; $m; $i2)
end
end;
### The tasks
def listEsths(n; n2; m; m2; $perLine; $all):
( {esths: []}
| reduce range(0;10) as $i (.; dfs(n2; m2; $i) )
| "Base 10: \(.esths|length) esthetic numbers between \(n) and \(m)",
if $all
then .esths | _nwise($perLine) | join(" ")
else
(.esths[:$perLine] | join(" ")),
"............",
(.esths[-$perLine:] | join(" "))
end ),
"";
def task($maxBase):
range (2; 1+$maxBase) as $b
| "Base \($b): \(4*$b)th to \(6*$b)th esthetic numbers:",
( [{ n: 1, c: 0 }
| while (.c <= 6*$b;
.emit = null
| if (.n|isEsthetic($b))
then .c += 1
| if .c >= 4*$b
then .emit = "\(.n | tobase($b))"
else .
end
else .
end
| .n += 1 )
| select(.emit).emit]
| _nwise(10) | join(" ") ),
"" ;
task(16),
# the following all use the obvious range limitations for the numbers in question
listEsths(1000; 1010; 9999; 9898; 16; true),
listEsths(1e8; 101010101; 13*1e7; 123456789; 9; true),
listEsths(1e11; 101010101010; 13*1e10; 123456789898; 7; false),
listEsths(1e14; 101010101010101; 13*1e13; 123456789898989; 5; false)
- Output:
(scrollable)
Base 2: 8th to 12th esthetic numbers: 10101010 101010101 1010101010 10101010101 101010101010 Base 3: 12th to 18th esthetic numbers: 1210 1212 2101 2121 10101 10121 12101 Base 4: 16th to 24th esthetic numbers: 323 1010 1012 1210 1212 1232 2101 2121 2123 Base 5: 20th to 30th esthetic numbers: 323 343 432 434 1010 1012 1210 1212 1232 1234 2101 Base 6: 24th to 36th esthetic numbers: 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234 Base 7: 28th to 42th esthetic numbers: 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232 Base 8: 32th to 48th esthetic numbers: 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212 Base 9: 36th to 54th esthetic numbers: 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210 Base 10: 40th to 60th esthetic numbers: 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012 Base 11: 44th to 66th esthetic numbers: 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 A98 A9A 1010 Base 12: 48th to 72th esthetic numbers: 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA BA9 BAB Base 13: 52th to 78th esthetic numbers: 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB CBA Base 14: 56th to 84th esthetic numbers: 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC Base 15: 60th to 90th esthetic numbers: 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC CDE DCB DCD Base 16: 64th to 96th esthetic numbers: 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC CDE DCB DCD DED DEF EDC Base 10: 61 esthetic numbers between 1000 and 9999 1010 1012 1210 1212 1232 1234 2101 2121 2123 2321 2323 2343 2345 3210 3212 3232 3234 3432 3434 3454 3456 4321 4323 4343 4345 4543 4545 4565 4567 5432 5434 5454 5456 5654 5656 5676 5678 6543 6545 6565 6567 6765 6767 6787 6789 7654 7656 7676 7678 7876 7878 7898 8765 8767 8787 8789 8987 8989 9876 9878 9898 Base 10: 126 esthetic numbers between 100000000 and 130000000 101010101 101010121 101010123 101012101 101012121 101012123 101012321 101012323 101012343 101012345 101210101 101210121 101210123 101212101 101212121 101212123 101212321 101212323 101212343 101212345 101232101 101232121 101232123 101232321 101232323 101232343 101232345 101234321 101234323 101234343 101234345 101234543 101234545 101234565 101234567 121010101 121010121 121010123 121012101 121012121 121012123 121012321 121012323 121012343 121012345 121210101 121210121 121210123 121212101 121212121 121212123 121212321 121212323 121212343 121212345 121232101 121232121 121232123 121232321 121232323 121232343 121232345 121234321 121234323 121234343 121234345 121234543 121234545 121234565 121234567 123210101 123210121 123210123 123212101 123212121 123212123 123212321 123212323 123212343 123212345 123232101 123232121 123232123 123232321 123232323 123232343 123232345 123234321 123234323 123234343 123234345 123234543 123234545 123234565 123234567 123432101 123432121 123432123 123432321 123432323 123432343 123432345 123434321 123434323 123434343 123434345 123434543 123434545 123434565 123434567 123454321 123454323 123454343 123454345 123454543 123454545 123454565 123454567 123456543 123456545 123456565 123456567 123456765 123456767 123456787 123456789 Base 10: 911 esthetic numbers between 100000000000 and 130000000000 101010101010 101010101012 101010101210 101010101212 101010101232 101010101234 101010121010 ............ 123456787678 123456787876 123456787878 123456787898 123456789876 123456789878 123456789898 Base 10: 6225 esthetic numbers between 100000000000000 and 130000000000000 101010101010101 101010101010121 101010101010123 101010101012101 101010101012121 ............ 123456789898767 123456789898787 123456789898789 123456789898987 123456789898989
Julia
Illustrates both brute force and iterative methods of generating numbers in the sequence.
using Formatting
import Base.iterate, Base.IteratorSize, Base.IteratorEltype
"""
struct Esthetic
Used for iteration of esthetic numbers
"""
struct Esthetic{T}
lowerlimit::T where T <: Integer
base::T
upperlimit::T
Esthetic{T}(n, bas, m=typemax(T)) where T = new{T}(nextesthetic(n, bas), bas, m)
end
Base.IteratorSize(n::Esthetic) = Base.IsInfinite()
Base.IteratorEltype(n::Esthetic) = Integer
function Base.iterate(es::Esthetic, state=typeof(es.lowerlimit)[])
state = isempty(state) ? digits(es.lowerlimit, base=es.base) : increment!(state, es.base, 1)
n = toInt(state, es.base)
return n <= es.upperlimit ? (n, state) : nothing
end
isesthetic(n, b) = (d = digits(n, base=b); all(i -> abs(d[i] - d[i + 1]) == 1, 1:length(d)-1))
toInt(dig, bas) = foldr((i, j) -> i + bas * j, dig)
nextesthetic(n, b) = for i in n:typemax(typeof(n)) if isesthetic(i, b) return i end; end
""" Fill the digits below pos in vector with the least esthetic number fitting there """
function filldecreasing!(vec, pos)
if pos > 1
n = vec[pos]
for i in pos-1:-1:1
n = (n == 0) ? 1 : n - 1
vec[i] = n
end
end
return vec
end
""" Get the next esthetic number's digits from the previous number's digits """
function increment!(vec, bas, startpos = 1)
len = length(vec)
if len == 1
if vec[1] < bas - 1
vec[1] += 1
else
vec[1] = 0
push!(vec, 1)
end
else
pos = findfirst(i -> vec[i] < vec[i + 1], startpos:len-1)
if pos == nothing
if vec[end] >= bas - 1
push!(vec, 1)
filldecreasing!(vec, len + 1)
else
vec[end] += 1
filldecreasing!(vec, len)
end
else
for i in pos:len
if i == len
if vec[i] < bas - 1
vec[i] += 1
filldecreasing!(vec, i)
else
push!(vec, 1)
filldecreasing!(vec, len + 1)
end
elseif vec[i] < vec[i + 1] && vec[i] < bas - 2
vec[i] += 2
filldecreasing!(vec, i)
break
end
end
end
end
return vec
end
for b in 2:16
println("For base $b, the esthetic numbers indexed from $(4b) to $(6b) are:")
printed = 0
for (i, n) in enumerate(Iterators.take(Esthetic{Int}(1, b), 6b))
if i >= 4b
printed += 1
print(string(n, base=b), printed % 21 == 20 ? "\n" : " ")
end
end
println("\n")
end
for (bottom, top, cols, T) in [[1000, 9999, 16, Int], [100_000_000, 130_000_000, 8, Int],
[101_010_000_000, 130_000_000_000, 6, Int], [101_010_101_010_000_000, 130_000_000_000_000_000, 4, Int],
[101_010_101_010_101_000_000, 130_000_000_000_000_000_000, 4, Int128]]
esth, count = Esthetic{T}(bottom, 10, top), 0
println("\nBase 10 esthetic numbers between $(format(bottom, commas=true)) and $(format(top, commas=true)):")
for n in esth
count += 1
if count == 64
println(" ...")
elseif count < 64
print(format(n, commas=true), count % cols == 0 ? "\n" : " ")
end
end
println("\nTotal esthetic numbers in interval: $count")
end
- Output:
For base 2, the esthetic numbers indexed from 8 to 12 are: 10101010 101010101 1010101010 10101010101 101010101010 For base 3, the esthetic numbers indexed from 12 to 18 are: 1210 1212 2101 2121 10101 10121 12101 For base 4, the esthetic numbers indexed from 16 to 24 are: 323 1010 1012 1210 1212 1232 2101 2121 2123 For base 5, the esthetic numbers indexed from 20 to 30 are: 323 343 432 434 1010 1012 1210 1212 1232 1234 2101 For base 6, the esthetic numbers indexed from 24 to 36 are: 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234 For base 7, the esthetic numbers indexed from 28 to 42 are: 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232 For base 8, the esthetic numbers indexed from 32 to 48 are: 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212 For base 9, the esthetic numbers indexed from 36 to 54 are: 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210 For base 10, the esthetic numbers indexed from 40 to 60 are: 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012 For base 11, the esthetic numbers indexed from 44 to 66 are: 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 a98 a9a 1010 For base 12, the esthetic numbers indexed from 48 to 72 are: 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba ba9 bab For base 13, the esthetic numbers indexed from 52 to 78 are: 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb cba For base 14, the esthetic numbers indexed from 56 to 84 are: 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc For base 15, the esthetic numbers indexed from 60 to 90 are: 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd For base 16, the esthetic numbers indexed from 64 to 96 are: 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd ded def edc Base 10 esthetic numbers between 1,000 and 9,999: 1,010 1,012 1,210 1,212 1,232 1,234 2,101 2,121 2,123 2,321 2,323 2,343 2,345 3,210 3,212 3,232 3,234 3,432 3,434 3,454 3,456 4,321 4,323 4,343 4,345 4,543 4,545 4,565 4,567 5,432 5,434 5,454 5,456 5,654 5,656 5,676 5,678 6,543 6,545 6,565 6,567 6,765 6,767 6,787 6,789 7,654 7,656 7,676 7,678 7,876 7,878 7,898 8,765 8,767 8,787 8,789 8,987 8,989 9,876 9,878 9,898 Total esthetic numbers in interval: 61 Base 10 esthetic numbers between 100,000,000 and 130,000,000: 101,010,101 101,010,121 101,010,123 101,012,101 101,012,121 101,012,123 101,012,321 101,012,323 101,012,343 101,012,345 101,210,101 101,210,121 101,210,123 101,212,101 101,212,121 101,212,123 101,212,321 101,212,323 101,212,343 101,212,345 101,232,101 101,232,121 101,232,123 101,232,321 101,232,323 101,232,343 101,232,345 101,234,321 101,234,323 101,234,343 101,234,345 101,234,543 101,234,545 101,234,565 101,234,567 121,010,101 121,010,121 121,010,123 121,012,101 121,012,121 121,012,123 121,012,321 121,012,323 121,012,343 121,012,345 121,210,101 121,210,121 121,210,123 121,212,101 121,212,121 121,212,123 121,212,321 121,212,323 121,212,343 121,212,345 121,232,101 121,232,121 121,232,123 121,232,321 121,232,323 121,232,343 121,232,345 121,234,321 ... Total esthetic numbers in interval: 126 Base 10 esthetic numbers between 101,010,000,000 and 130,000,000,000: 101,010,101,010 101,010,101,012 101,010,101,210 101,010,101,212 101,010,101,232 101,010,101,234 101,010,121,010 101,010,121,012 101,010,121,210 101,010,121,212 101,010,121,232 101,010,121,234 101,010,123,210 101,010,123,212 101,010,123,232 101,010,123,234 101,010,123,432 101,010,123,434 101,010,123,454 101,010,123,456 101,012,101,010 101,012,101,012 101,012,101,210 101,012,101,212 101,012,101,232 101,012,101,234 101,012,121,010 101,012,121,012 101,012,121,210 101,012,121,212 101,012,121,232 101,012,121,234 101,012,123,210 101,012,123,212 101,012,123,232 101,012,123,234 101,012,123,432 101,012,123,434 101,012,123,454 101,012,123,456 101,012,321,010 101,012,321,012 101,012,321,210 101,012,321,212 101,012,321,232 101,012,321,234 101,012,323,210 101,012,323,212 101,012,323,232 101,012,323,234 101,012,323,432 101,012,323,434 101,012,323,454 101,012,323,456 101,012,343,210 101,012,343,212 101,012,343,232 101,012,343,234 101,012,343,432 101,012,343,434 101,012,343,454 101,012,343,456 101,012,345,432 ... Total esthetic numbers in interval: 911 Base 10 esthetic numbers between 101,010,101,010,000,000 and 130,000,000,000,000,000: 101,010,101,010,101,010 101,010,101,010,101,012 101,010,101,010,101,210 101,010,101,010,101,212 101,010,101,010,101,232 101,010,101,010,101,234 101,010,101,010,121,010 101,010,101,010,121,012 101,010,101,010,121,210 101,010,101,010,121,212 101,010,101,010,121,232 101,010,101,010,121,234 101,010,101,010,123,210 101,010,101,010,123,212 101,010,101,010,123,232 101,010,101,010,123,234 101,010,101,010,123,432 101,010,101,010,123,434 101,010,101,010,123,454 101,010,101,010,123,456 101,010,101,012,101,010 101,010,101,012,101,012 101,010,101,012,101,210 101,010,101,012,101,212 101,010,101,012,101,232 101,010,101,012,101,234 101,010,101,012,121,010 101,010,101,012,121,012 101,010,101,012,121,210 101,010,101,012,121,212 101,010,101,012,121,232 101,010,101,012,121,234 101,010,101,012,123,210 101,010,101,012,123,212 101,010,101,012,123,232 101,010,101,012,123,234 101,010,101,012,123,432 101,010,101,012,123,434 101,010,101,012,123,454 101,010,101,012,123,456 101,010,101,012,321,010 101,010,101,012,321,012 101,010,101,012,321,210 101,010,101,012,321,212 101,010,101,012,321,232 101,010,101,012,321,234 101,010,101,012,323,210 101,010,101,012,323,212 101,010,101,012,323,232 101,010,101,012,323,234 101,010,101,012,323,432 101,010,101,012,323,434 101,010,101,012,323,454 101,010,101,012,323,456 101,010,101,012,343,210 101,010,101,012,343,212 101,010,101,012,343,232 101,010,101,012,343,234 101,010,101,012,343,432 101,010,101,012,343,434 101,010,101,012,343,454 101,010,101,012,343,456 101,010,101,012,345,432 ... Total esthetic numbers in interval: 44744 Base 10 esthetic numbers between 101,010,101,010,101,000,000 and 130,000,000,000,000,000,000: 101,010,101,010,101,010,101 101,010,101,010,101,010,121 101,010,101,010,101,010,123 101,010,101,010,101,012,101 101,010,101,010,101,012,121 101,010,101,010,101,012,123 101,010,101,010,101,012,321 101,010,101,010,101,012,323 101,010,101,010,101,012,343 101,010,101,010,101,012,345 101,010,101,010,101,210,101 101,010,101,010,101,210,121 101,010,101,010,101,210,123 101,010,101,010,101,212,101 101,010,101,010,101,212,121 101,010,101,010,101,212,123 101,010,101,010,101,212,321 101,010,101,010,101,212,323 101,010,101,010,101,212,343 101,010,101,010,101,212,345 101,010,101,010,101,232,101 101,010,101,010,101,232,121 101,010,101,010,101,232,123 101,010,101,010,101,232,321 101,010,101,010,101,232,323 101,010,101,010,101,232,343 101,010,101,010,101,232,345 101,010,101,010,101,234,321 101,010,101,010,101,234,323 101,010,101,010,101,234,343 101,010,101,010,101,234,345 101,010,101,010,101,234,543 101,010,101,010,101,234,545 101,010,101,010,101,234,565 101,010,101,010,101,234,567 101,010,101,010,121,010,101 101,010,101,010,121,010,121 101,010,101,010,121,010,123 101,010,101,010,121,012,101 101,010,101,010,121,012,121 101,010,101,010,121,012,123 101,010,101,010,121,012,321 101,010,101,010,121,012,323 101,010,101,010,121,012,343 101,010,101,010,121,012,345 101,010,101,010,121,210,101 101,010,101,010,121,210,121 101,010,101,010,121,210,123 101,010,101,010,121,212,101 101,010,101,010,121,212,121 101,010,101,010,121,212,123 101,010,101,010,121,212,321 101,010,101,010,121,212,323 101,010,101,010,121,212,343 101,010,101,010,121,212,345 101,010,101,010,121,232,101 101,010,101,010,121,232,121 101,010,101,010,121,232,123 101,010,101,010,121,232,321 101,010,101,010,121,232,323 101,010,101,010,121,232,343 101,010,101,010,121,232,345 101,010,101,010,121,234,321 ... Total esthetic numbers in interval: 312019
Kotlin
import kotlin.math.abs
fun isEsthetic(n: Long, b: Long): Boolean {
if (n == 0L) {
return false
}
var i = n % b
var n2 = n / b
while (n2 > 0) {
val j = n2 % b
if (abs(i - j) != 1L) {
return false
}
n2 /= b
i = j
}
return true
}
fun listEsths(n: Long, n2: Long, m: Long, m2: Long, perLine: Int, all: Boolean) {
val esths = mutableListOf<Long>()
fun dfs(n: Long, m: Long, i: Long) {
if (i in n..m) {
esths.add(i)
}
if (i == 0L || i > m) {
return
}
val d = i % 10
val i1 = i * 10 + d - 1
val i2 = i1 + 2
when (d) {
0L -> {
dfs(n, m, i2)
}
9L -> {
dfs(n, m, i1)
}
else -> {
dfs(n, m, i1)
dfs(n, m, i2)
}
}
}
for (i in 0L until 10L) {
dfs(n2, m2, i)
}
val le = esths.size
println("Base 10: $le esthetic numbers between $n and $m:")
if (all) {
for (c_esth in esths.withIndex()) {
print("${c_esth.value} ")
if ((c_esth.index + 1) % perLine == 0) {
println()
}
}
println()
} else {
for (i in 0 until perLine) {
print("${esths[i]} ")
}
println()
println("............")
for (i in le - perLine until le) {
print("${esths[i]} ")
}
println()
}
println()
}
fun main() {
for (b in 2..16) {
println("Base $b: ${4 * b}th to ${6 * b}th esthetic numbers:")
var n = 1L
var c = 0L
while (c < 6 * b) {
if (isEsthetic(n, b.toLong())) {
c++
if (c >= 4 * b) {
print("${n.toString(b)} ")
}
}
n++
}
println()
}
println()
// the following all use the obvious range limitations for the numbers in question
listEsths(1000, 1010, 9999, 9898, 16, true);
listEsths(1e8.toLong(), 101_010_101, 13 * 1e7.toLong(), 123_456_789, 9, true);
listEsths(1e11.toLong(), 101_010_101_010, 13 * 1e10.toLong(), 123_456_789_898, 7, false);
listEsths(1e14.toLong(), 101_010_101_010_101, 13 * 1e13.toLong(), 123_456_789_898_989, 5, false);
listEsths(1e17.toLong(), 101_010_101_010_101_010, 13 * 1e16.toLong(), 123_456_789_898_989_898, 4, false);
}
- Output:
Base 2: 8th to 12th esthetic numbers: 10101010 101010101 1010101010 10101010101 101010101010 Base 3: 12th to 18th esthetic numbers: 1210 1212 2101 2121 10101 10121 12101 Base 4: 16th to 24th esthetic numbers: 323 1010 1012 1210 1212 1232 2101 2121 2123 Base 5: 20th to 30th esthetic numbers: 323 343 432 434 1010 1012 1210 1212 1232 1234 2101 Base 6: 24th to 36th esthetic numbers: 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234 Base 7: 28th to 42th esthetic numbers: 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232 Base 8: 32th to 48th esthetic numbers: 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212 Base 9: 36th to 54th esthetic numbers: 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210 Base 10: 40th to 60th esthetic numbers: 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012 Base 11: 44th to 66th esthetic numbers: 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 a98 a9a 1010 Base 12: 48th to 72th esthetic numbers: 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba ba9 bab Base 13: 52th to 78th esthetic numbers: 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb cba Base 14: 56th to 84th esthetic numbers: 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc Base 15: 60th to 90th esthetic numbers: 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd Base 16: 64th to 96th esthetic numbers: 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd ded def edc Base 10: 61 esthetic numbers between 1000 and 9999: 1010 1012 1210 1212 1232 1234 2101 2121 2123 2321 2323 2343 2345 3210 3212 3232 3234 3432 3434 3454 3456 4321 4323 4343 4345 4543 4545 4565 4567 5432 5434 5454 5456 5654 5656 5676 5678 6543 6545 6565 6567 6765 6767 6787 6789 7654 7656 7676 7678 7876 7878 7898 8765 8767 8787 8789 8987 8989 9876 9878 9898 Base 10: 126 esthetic numbers between 100000000 and 130000000: 101010101 101010121 101010123 101012101 101012121 101012123 101012321 101012323 101012343 101012345 101210101 101210121 101210123 101212101 101212121 101212123 101212321 101212323 101212343 101212345 101232101 101232121 101232123 101232321 101232323 101232343 101232345 101234321 101234323 101234343 101234345 101234543 101234545 101234565 101234567 121010101 121010121 121010123 121012101 121012121 121012123 121012321 121012323 121012343 121012345 121210101 121210121 121210123 121212101 121212121 121212123 121212321 121212323 121212343 121212345 121232101 121232121 121232123 121232321 121232323 121232343 121232345 121234321 121234323 121234343 121234345 121234543 121234545 121234565 121234567 123210101 123210121 123210123 123212101 123212121 123212123 123212321 123212323 123212343 123212345 123232101 123232121 123232123 123232321 123232323 123232343 123232345 123234321 123234323 123234343 123234345 123234543 123234545 123234565 123234567 123432101 123432121 123432123 123432321 123432323 123432343 123432345 123434321 123434323 123434343 123434345 123434543 123434545 123434565 123434567 123454321 123454323 123454343 123454345 123454543 123454545 123454565 123454567 123456543 123456545 123456565 123456567 123456765 123456767 123456787 123456789 Base 10: 911 esthetic numbers between 100000000000 and 130000000000: 101010101010 101010101012 101010101210 101010101212 101010101232 101010101234 101010121010 ............ 123456787678 123456787876 123456787878 123456787898 123456789876 123456789878 123456789898 Base 10: 6225 esthetic numbers between 100000000000000 and 130000000000000: 101010101010101 101010101010121 101010101010123 101010101012101 101010101012121 ............ 123456789898767 123456789898787 123456789898789 123456789898987 123456789898989 Base 10: 44744 esthetic numbers between 100000000000000000 and 130000000000000000: 101010101010101010 101010101010101012 101010101010101210 101010101010101212 ............ 123456789898987898 123456789898989876 123456789898989878 123456789898989898
Lua
function to(n, b)
local BASE = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
if n == 0 then
return "0"
end
local ss = ""
while n > 0 do
local idx = (n % b) + 1
n = math.floor(n / b)
ss = ss .. BASE:sub(idx, idx)
end
return string.reverse(ss)
end
function isEsthetic(n, b)
function uabs(a, b)
if a < b then
return b - a
end
return a - b
end
if n == 0 then
return false
end
local i = n % b
n = math.floor(n / b)
while n > 0 do
local j = n % b
if uabs(i, j) ~= 1 then
return false
end
n = math.floor(n / b)
i = j
end
return true
end
function listEsths(n, n2, m, m2, perLine, all)
local esths = {}
function dfs(n, m, i)
if i >= n and i <= m then
table.insert(esths, i)
end
if i == 0 or i > m then
return
end
local d = i % 10
local i1 = 10 * i + d - 1
local i2 = i1 + 2
if d == 0 then
dfs(n, m, i2)
elseif d == 9 then
dfs(n, m, i1)
else
dfs(n, m, i1)
dfs(n, m, i2)
end
end
for i=0,9 do
dfs(n2, m2, i)
end
local le = #esths
print(string.format("Base 10: %s esthetic numbers between %s and %s:", le, math.floor(n), math.floor(m)))
if all then
for c,esth in pairs(esths) do
io.write(esth.." ")
if c % perLine == 0 then
print()
end
end
print()
else
for i=1,perLine do
io.write(esths[i] .. " ")
end
print("\n............")
for i = le - perLine + 1, le do
io.write(esths[i] .. " ")
end
print()
end
print()
end
for b=2,16 do
print(string.format("Base %d: %dth to %dth esthetic numbers:", b, 4 * b, 6 * b))
local n = 1
local c = 0
while c < 6 * b do
if isEsthetic(n, b) then
c = c + 1
if c >= 4 * b then
io.write(to(n, b).." ")
end
end
n = n + 1
end
print()
end
print()
-- the following all use the obvious range limitations for the numbers in question
listEsths(1000, 1010, 9999, 9898, 16, true)
listEsths(1e8, 101010101, 13 * 1e7, 123456789, 9, true)
listEsths(1e11, 101010101010, 13 * 1e10, 123456789898, 7, false)
listEsths(1e14, 101010101010101, 13 * 1e13, 123456789898989, 5, false)
listEsths(1e17, 101010101010101010, 13 * 1e16, 123456789898989898, 4, false)
- Output:
Base 2: 8th to 12th esthetic numbers: 10101010 101010101 1010101010 10101010101 101010101010 Base 3: 12th to 18th esthetic numbers: 1210 1212 2101 2121 10101 10121 12101 Base 4: 16th to 24th esthetic numbers: 323 1010 1012 1210 1212 1232 2101 2121 2123 Base 5: 20th to 30th esthetic numbers: 323 343 432 434 1010 1012 1210 1212 1232 1234 2101 Base 6: 24th to 36th esthetic numbers: 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234 Base 7: 28th to 42th esthetic numbers: 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232 Base 8: 32th to 48th esthetic numbers: 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212 Base 9: 36th to 54th esthetic numbers: 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210 Base 10: 40th to 60th esthetic numbers: 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012 Base 11: 44th to 66th esthetic numbers: 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 A98 A9A 1010 Base 12: 48th to 72th esthetic numbers: 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA BA9 BAB Base 13: 52th to 78th esthetic numbers: 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB CBA Base 14: 56th to 84th esthetic numbers: 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC Base 15: 60th to 90th esthetic numbers: 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC CDE DCB DCD Base 16: 64th to 96th esthetic numbers: 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC CDE DCB DCD DED DEF EDC Base 10: 61 esthetic numbers between 1000 and 9999: 1010 1012 1210 1212 1232 1234 2101 2121 2123 2321 2323 2343 2345 3210 3212 3232 3234 3432 3434 3454 3456 4321 4323 4343 4345 4543 4545 4565 4567 5432 5434 5454 5456 5654 5656 5676 5678 6543 6545 6565 6567 6765 6767 6787 6789 7654 7656 7676 7678 7876 7878 7898 8765 8767 8787 8789 8987 8989 9876 9878 9898 Base 10: 126 esthetic numbers between 100000000 and 130000000: 101010101 101010121 101010123 101012101 101012121 101012123 101012321 101012323 101012343 101012345 101210101 101210121 101210123 101212101 101212121 101212123 101212321 101212323 101212343 101212345 101232101 101232121 101232123 101232321 101232323 101232343 101232345 101234321 101234323 101234343 101234345 101234543 101234545 101234565 101234567 121010101 121010121 121010123 121012101 121012121 121012123 121012321 121012323 121012343 121012345 121210101 121210121 121210123 121212101 121212121 121212123 121212321 121212323 121212343 121212345 121232101 121232121 121232123 121232321 121232323 121232343 121232345 121234321 121234323 121234343 121234345 121234543 121234545 121234565 121234567 123210101 123210121 123210123 123212101 123212121 123212123 123212321 123212323 123212343 123212345 123232101 123232121 123232123 123232321 123232323 123232343 123232345 123234321 123234323 123234343 123234345 123234543 123234545 123234565 123234567 123432101 123432121 123432123 123432321 123432323 123432343 123432345 123434321 123434323 123434343 123434345 123434543 123434545 123434565 123434567 123454321 123454323 123454343 123454345 123454543 123454545 123454565 123454567 123456543 123456545 123456565 123456567 123456765 123456767 123456787 123456789 Base 10: 911 esthetic numbers between 100000000000 and 130000000000: 101010101010 101010101012 101010101210 101010101212 101010101232 101010101234 101010121010 ............ 123456787678 123456787876 123456787878 123456787898 123456789876 123456789878 123456789898 Base 10: 6225 esthetic numbers between 100000000000000 and 130000000000000: 101010101010101 101010101010121 101010101010123 101010101012101 101010101012121 ............ 123456789898767 123456789898787 123456789898789 123456789898987 123456789898989 Base 10: 44744 esthetic numbers between 100000000000000000 and 130000000000000000: 101010101010101010 101010101010101012 101010101010101210 101010101010101212 ............ 123456789898987898 123456789898989876 123456789898989878 123456789898989898
Mathematica /Wolfram Language
ClearAll[EstheticNumbersRangeHelper, EstheticNumbersRange]
EstheticNumbersRangeHelper[power_, mima : {mi_, max_}, b_ : 10] := Module[{steps, cands},
steps = Tuples[{-1, 1}, power - 1];
steps = Accumulate[Prepend[#, 0]] & /@ steps;
cands = Table[Select[# + ConstantArray[s, power] & /@ steps, AllTrue[Between[{0, b - 1}]]], {s, 1, b - 1}];
cands //= Catenate;
cands //= Map[FromDigits[#, b] &];
cands = Select[cands, Between[mima]];
BaseForm[#, b] & /@ cands
]
EstheticNumbersRange[{min_, max_}, b_ : 10] := Module[{mi, ma},
{mi, ma} = Log[b, {min, max}];
mi //= Ceiling;
ma //= Ceiling;
ma = Max[ma, 1];
mi = Max[mi, 1];
Catenate[EstheticNumbersRangeHelper[#, {min, max}, b] & /@ Range[mi, ma]]
]
Table[{b, EstheticNumbersRange[{1, If[b == 2, 100000, If[b == 3, 100000, b^4]]}, b][[4 b ;; 6 b]]}, {b, 2, 16}] // Grid
EstheticNumbersRange[{1000, 9999}]
EstheticNumbersRange[{10^8, 1.3 10^8}]
- Output:
2 {10101010,101010101,1010101010,10101010101,101010101010} 3 {1210,1212,2101,2121,10101,10121,12101} 4 {323,1010,1012,1210,1212,1232,2101,2121,2123} 5 {323,343,432,434,1010,1012,1210,1212,1232,1234,2101} 6 {343,345,432,434,454,543,545,1010,1012,1210,1212,1232,1234} 7 {345,432,434,454,456,543,545,565,654,656,1010,1012,1210,1212,1232} 8 {432,434,454,456,543,545,565,567,654,656,676,765,767,1010,1012,1210,1212} 9 {434,454,456,543,545,565,567,654,656,676,678,765,767,787,876,878,1010,1012,1210} 10 {454,456,543,545,565,567,654,656,676,678,765,767,787,789,876,878,898,987,989,1010,1012} 11 {456,543,545,565,567,654,656,676,678,765,767,787,789,876,878,898,89a,987,989,9a9,a98,a9a,1010} 12 {543,545,565,567,654,656,676,678,765,767,787,789,876,878,898,89a,987,989,9a9,9ab,a98,a9a,aba,ba9,bab} 13 {545,565,567,654,656,676,678,765,767,787,789,876,878,898,89a,987,989,9a9,9ab,a98,a9a,aba,abc,ba9,bab,bcb,cba} 14 {565,567,654,656,676,678,765,767,787,789,876,878,898,89a,987,989,9a9,9ab,a98,a9a,aba,abc,ba9,bab,bcb,bcd,cba,cbc,cdc} 15 {567,654,656,676,678,765,767,787,789,876,878,898,89a,987,989,9a9,9ab,a98,a9a,aba,abc,ba9,bab,bcb,bcd,cba,cbc,cdc,cde,dcb,dcd} 16 {654,656,676,678,765,767,787,789,876,878,898,89a,987,989,9a9,9ab,a98,a9a,aba,abc,ba9,bab,bcb,bcd,cba,cbc,cdc,cde,dcb,dcd,ded,def,edc} {1010,1012,1210,1212,1232,1234,2101,2121,2123,2321,2323,2343,2345,3210,3212,3232,3234,3432,3434,3454,3456,4321,4323,4343,4345,4543,4545,4565,4567,5432,5434,5454,5456,5654,5656,5676,5678,6543,6545,6565,6567,6765,6767,6787,6789,7654,7656,7676,7678,7876,7878,7898,8765,8767,8787,8789,8987,8989,9876,9878,9898} {101010101,101010121,101010123,101012101,101012121,101012123,101012321,101012323,101012343,101012345,101210101,101210121,101210123,101212101,101212121,101212123,101212321,101212323,101212343,101212345,101232101,101232121,101232123,101232321,101232323,101232343,101232345,101234321,101234323,101234343,101234345,101234543,101234545,101234565,101234567,121010101,121010121,121010123,121012101,121012121,121012123,121012321,121012323,121012343,121012345,121210101,121210121,121210123,121212101,121212121,121212123,121212321,121212323,121212343,121212345,121232101,121232121,121232123,121232321,121232323,121232343,121232345,121234321,121234323,121234343,121234345,121234543,121234545,121234565,121234567,123210101,123210121,123210123,123212101,123212121,123212123,123212321,123212323,123212343,123212345,123232101,123232121,123232123,123232321,123232323,123232343,123232345,123234321,123234323,123234343,123234345,123234543,123234545,123234565,123234567,123432101,123432121,123432123,123432321,123432323,123432343,123432345,123434321,123434323,123434343,123434345,123434543,123434545,123434565,123434567,123454321,123454323,123454343,123454345,123454543,123454545,123454565,123454567,123456543,123456545,123456565,123456567,123456765,123456767,123456787,123456789}
Nim
import strformat
func isEsthetic(n, b: int64): bool =
if n == 0: return false
var i = n mod b
var n = n div b
while n > 0:
let j = n mod b
if abs(i - j) != 1:
return false
n = n div b
i = j
result = true
proc listEsths(n1, n2, m1, m2: int64; perLine: int; all: bool) =
var esths: seq[int64]
func dfs(n, m, i: int64) =
if i in n..m: esths.add i
if i == 0 or i > m: return
let d = i mod 10
let i1 = i * 10 + d - 1
let i2 = i1 + 2
case d
of 0:
dfs(n, m, i2)
of 9:
dfs(n, m, i1)
else:
dfs(n, m, i1)
dfs(n, m, i2)
for i in 0..9:
dfs(n2, m2, i)
echo &"Base 10: {esths.len} esthetic numbers between {n1} and {m1}:"
if all:
for i, esth in esths:
stdout.write esth
stdout.write if (i + 1) mod perLine == 0: '\n' else: ' '
echo()
else:
for i in 0..<perLine:
stdout.write esths[i], ' '
echo "\n............"
for i in esths.len - perLine .. esths.high:
stdout.write esths[i], ' '
echo()
echo()
proc toBase(n, b: int64): string =
const Digits = ['0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f']
if n == 0: return "0"
var n = n
while n > 0:
result.add Digits[n mod b]
n = n div b
for i in 0..<(result.len div 2):
swap result[i], result[result.high - i]
for b in 2..16:
echo &"Base {b}: {4 * b}th to {6 * b}th esthetic numbers:"
var n = 1i64
var c = 0i64
while c < 6 * b:
if n.isEsthetic(b):
inc c
if c >= 4 * b: stdout.write n.toBase(b), ' '
inc n
echo '\n'
# The following all use the obvious range limitations for the numbers in question.
listEsths(1000, 1010, 9999, 9898, 16, true)
listEsths(100_000_000, 101_010_101, 130_000_000, 123_456_789, 9, true)
listEsths(100_000_000_000, 101_010_101_010, 130_000_000_000, 123_456_789_898, 7, false)
listEsths(100_000_000_000_000, 101_010_101_010_101, 130_000_000_000, 123_456_789_898_989, 5, false)
listEsths(100_000_000_000_000_000, 101_010_101_010_101_010, 130_000_000_000_000_000, 123_456_789_898_989_898, 4, false)
- Output:
Base 2: 8th to 12th esthetic numbers: 10101010 101010101 1010101010 10101010101 101010101010 Base 3: 12th to 18th esthetic numbers: 1210 1212 2101 2121 10101 10121 12101 Base 4: 16th to 24th esthetic numbers: 323 1010 1012 1210 1212 1232 2101 2121 2123 Base 5: 20th to 30th esthetic numbers: 323 343 432 434 1010 1012 1210 1212 1232 1234 2101 Base 6: 24th to 36th esthetic numbers: 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234 Base 7: 28th to 42th esthetic numbers: 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232 Base 8: 32th to 48th esthetic numbers: 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212 Base 9: 36th to 54th esthetic numbers: 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210 Base 10: 40th to 60th esthetic numbers: 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012 Base 11: 44th to 66th esthetic numbers: 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 a98 a9a 1010 Base 12: 48th to 72th esthetic numbers: 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba ba9 bab Base 13: 52th to 78th esthetic numbers: 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb cba Base 14: 56th to 84th esthetic numbers: 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc Base 15: 60th to 90th esthetic numbers: 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd Base 16: 64th to 96th esthetic numbers: 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd ded def edc Base 10: 61 esthetic numbers between 1000 and 9999: 1010 1012 1210 1212 1232 1234 2101 2121 2123 2321 2323 2343 2345 3210 3212 3232 3234 3432 3434 3454 3456 4321 4323 4343 4345 4543 4545 4565 4567 5432 5434 5454 5456 5654 5656 5676 5678 6543 6545 6565 6567 6765 6767 6787 6789 7654 7656 7676 7678 7876 7878 7898 8765 8767 8787 8789 8987 8989 9876 9878 9898 Base 10: 126 esthetic numbers between 100000000 and 130000000: 101010101 101010121 101010123 101012101 101012121 101012123 101012321 101012323 101012343 101012345 101210101 101210121 101210123 101212101 101212121 101212123 101212321 101212323 101212343 101212345 101232101 101232121 101232123 101232321 101232323 101232343 101232345 101234321 101234323 101234343 101234345 101234543 101234545 101234565 101234567 121010101 121010121 121010123 121012101 121012121 121012123 121012321 121012323 121012343 121012345 121210101 121210121 121210123 121212101 121212121 121212123 121212321 121212323 121212343 121212345 121232101 121232121 121232123 121232321 121232323 121232343 121232345 121234321 121234323 121234343 121234345 121234543 121234545 121234565 121234567 123210101 123210121 123210123 123212101 123212121 123212123 123212321 123212323 123212343 123212345 123232101 123232121 123232123 123232321 123232323 123232343 123232345 123234321 123234323 123234343 123234345 123234543 123234545 123234565 123234567 123432101 123432121 123432123 123432321 123432323 123432343 123432345 123434321 123434323 123434343 123434345 123434543 123434545 123434565 123434567 123454321 123454323 123454343 123454345 123454543 123454545 123454565 123454567 123456543 123456545 123456565 123456567 123456765 123456767 123456787 123456789 Base 10: 911 esthetic numbers between 100000000000 and 130000000000: 101010101010 101010101012 101010101210 101010101212 101010101232 101010101234 101010121010 ............ 123456787678 123456787876 123456787878 123456787898 123456789876 123456789878 123456789898 Base 10: 6225 esthetic numbers between 100000000000000 and 130000000000: 101010101010101 101010101010121 101010101010123 101010101012101 101010101012121 ............ 123456789898767 123456789898787 123456789898789 123456789898987 123456789898989 Base 10: 44744 esthetic numbers between 100000000000000000 and 130000000000000000: 101010101010101010 101010101010101012 101010101010101210 101010101010101212 ............ 123456789898987898 123456789898989876 123456789898989878 123456789898989898
Pascal
Simple brute force, but fast and simple counting for complete first digit ranges.
program Esthetic;
{$IFDEF FPC}
{$MODE DELPHI} {$OPTIMIZATION ON,ALL} {$codealign proc=16}
{$ELSE}
{$APPTYPE CONSOLE}
{$ENDIF}
uses
sysutils,//IntToStr
strutils;//Numb2USA aka commatize
const
ConvBase :array[0..15] of char= '0123456789ABCDEF';
maxBase = 16;
type
tErg = string[63];
tCnt = array[0..maxBase-1] of UInt64;
tDgtcnt = array[0..64] of tCnt;
//global
var
Dgtcnt :tDgtcnt;
procedure CalcDgtCnt(base:NativeInt;var Dgtcnt :tDgtcnt);
var
pCnt0,
pCnt1 : ^tCnt;
i,j,SumCarry: NativeUInt;
begin
fillchar(Dgtcnt,SizeOf(Dgtcnt),#0);
pCnt0 := @Dgtcnt[0];
//building count for every first digit of digitcount:
//example :count numbers starting "1" of lenght 13
For i := 0 to Base-1 do
pCnt0^[i] := 1;
For j := 1 to High(Dgtcnt) do
Begin
pCnt1 := @Dgtcnt[j];
//0 -> followed only by solutions of 1
pCnt1^[0] := pCnt0^[1];
//base-1 -> followed only by solutions of Base-2
pCnt1^[base-1] := pCnt0^[base-2];
//followed by solutions for i-1 and i+1
For i := 1 to base-2 do
pCnt1^[i]:= pCnt0^[i-1]+pCnt0^[i+1];
//next row aka digitcnt
pCnt0:= pCnt1;
end;
//converting to sum up each digit
//example :count numbers starting "1" of lenght 13
//-> count of all est. numbers from 1 to "1" with max lenght 13
//delete leading "0"
For j := 0 to High(Dgtcnt) do //High(Dgtcnt)
Dgtcnt[j,0] := 0;
SumCarry := Uint64(0);
For j := 0 to High(Dgtcnt) do
Begin
pCnt0 := @Dgtcnt[j];
For i := 0 to base-1 do
begin
SumCarry +=pCnt0^[i];
pCnt0^[i] :=SumCarry;
end;
end;
end;
function ConvToBaseStr(n,base:NativeUint):tErg;
var
idx,dgt,rst : Uint64;
Begin
IF n = 0 then
Begin
result := ConvBase[0];
EXIT;
end;
idx := High(result);
repeat
rst := n div base;
dgt := n-rst*base;
result[idx] := ConvBase[dgt];
dec(idx);
n := rst;
until n=0;
rst := High(result)-idx;
move(result[idx+1],result[1],rst);
setlength(result,rst);
end;
function isEsthetic(n,base:Uint64):boolean;
var
lastdgt,
dgt,
rst : Uint64;
Begin
result := true;
IF n >= Base then
Begin
rst := n div base;
Lastdgt := n-rst*base;
n := rst;
repeat
rst := n div base;
dgt := n-rst*base;
IF sqr(lastDgt-dgt)<> 1 then
Begin
result := false;
EXIT;
end;
lastDgt := dgt;
n := rst;
until n = 0;
end;
end;
procedure Task1;
var
i,base,cnt : NativeInt;
Begin
cnt := 0;
For base := 2 to 16 do
Begin
CalcDgtCnt(base,Dgtcnt);
writeln(4*base,'th through ',6*base,'th esthetic numbers in base ',base);
cnt := 0;
i := 0;
repeat
inc(i);
if isEsthetic(i,base) then
inc(cnt);
until cnt >= 4*base;
repeat
if isEsthetic(i,base) then
Begin
write(ConvToBaseStr(i,base),' ');
inc(cnt);
end;
inc(i);
until cnt > 6*base;
writeln;
end;
writeln;
end;
procedure Task2;
var
i : NativeInt;
begin
write(' There are ',Dgtcnt[4][0]-Dgtcnt[3][0],' esthetic numbers');
writeln(' between 1000 and 9999 ');
For i := 1000 to 9999 do
Begin
if isEsthetic(i,10) then
write(i:5);
end;
writeln;writeln;
end;
procedure Task3(Pot10: NativeInt);
//calculating esthetic numbers starting with "1" and Pot10+1 digits
var
i : NativeInt;
begin
write(' There are ',Numb2USA(IntToStr(Dgtcnt[Pot10][1]-Dgtcnt[Pot10][0])):26,' esthetic numbers');
writeln(' between 1e',Pot10,' and 1.3e',Pot10);
if Pot10 = 8 then
Begin
For i := 100*1000*1000 to 110*1000*1000-1 do
Begin
if isEsthetic(i,10) then
write(i:10);
end;
writeln;
//Jump over "11"
For i := 120*1000*1000 to 130*1000*1000-1 do
Begin
if isEsthetic(i,10) then
write(i:10);
end;
writeln;writeln;
end;
end;
var
i:NativeInt;
BEGIN
Task1;
//now only base 10 is used
CalcDgtCnt(10,Dgtcnt);
Task2;
For i := 2 to 20 do
Task3(3*i+2);
writeln;
write(' There are ',Numb2USA(IntToStr(Dgtcnt[64][0])),' esthetic numbers');
writeln(' with max 65 digits ');
writeln;
writeln(' The count of numbers with 64 digits like https://oeis.org/A090994');
writeln(Numb2USA(IntToStr(Dgtcnt[64][0]-Dgtcnt[63][0])):28);
end.
- Output:
8th through 12th esthetic numbers in base 2 10101010 101010101 1010101010 10101010101 101010101010 12th through 18th esthetic numbers in base 3 1210 1212 2101 2121 10101 10121 12101 16th through 24th esthetic numbers in base 4 323 1010 1012 1210 1212 1232 2101 2121 2123 20th through 30th esthetic numbers in base 5 323 343 432 434 1010 1012 1210 1212 1232 1234 2101 24th through 36th esthetic numbers in base 6 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234 28th through 42th esthetic numbers in base 7 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232 32th through 48th esthetic numbers in base 8 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212 36th through 54th esthetic numbers in base 9 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210 40th through 60th esthetic numbers in base 10 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012 44th through 66th esthetic numbers in base 11 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 A98 A9A 1010 48th through 72th esthetic numbers in base 12 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA BA9 BAB 52th through 78th esthetic numbers in base 13 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB CBA 56th through 84th esthetic numbers in base 14 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC 60th through 90th esthetic numbers in base 15 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC CDE DCB DCD 64th through 96th esthetic numbers in base 16 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC CDE DCB DCD DED DEF EDC There are 61 esthetic numbers between 1000 and 9999 1010 1012 1210 1212 1232 1234 2101 2121 2123 2321 2323 2343 2345 3210 3212 3232 3234 3432 3434 3454 3456 4321 4323 4343 4345 4543 4545 4565 4567 5432 5434 5454 5456 5654 5656 5676 5678 6543 6545 6565 6567 6765 6767 6787 6789 7654 7656 7676 7678 7876 7878 7898 8765 8767 8787 8789 8987 8989 9876 9878 9898 There are 126 esthetic numbers between 1e8 and 1.3e8 101010101 101010121 101010123 101012101 101012121 101012123 101012321 101012323 101012343 101012345 101210101 101210121 101210123 101212101 101212121 101212123 101212321 101212323 101212343 101212345 101232101 101232121 101232123 101232321 101232323 101232343 101232345 101234321 101234323 101234343 101234345 101234543 101234545 101234565 101234567 121010101 121010121 121010123 121012101 121012121 121012123 121012321 121012323 121012343 121012345 121210101 121210121 121210123 121212101 121212121 121212123 121212321 121212323 121212343 121212345 121232101 121232121 121232123 121232321 121232323 121232343 121232345 121234321 121234323 121234343 121234345 121234543 121234545 121234565 121234567 123210101 123210121 123210123 123212101 123212121 123212123 123212321 123212323 123212343 123212345 123232101 123232121 123232123 123232321 123232323 123232343 123232345 123234321 123234323 123234343 123234345 123234543 123234545 123234565 123234567 123432101 123432121 123432123 123432321 123432323 123432343 123432345 123434321 123434323 123434343 123434345 123434543 123434545 123434565 123434567 123454321 123454323 123454343 123454345 123454543 123454545 123454565 123454567 123456543 123456545 123456565 123456567 123456765 123456767 123456787 123456789
There are 911 esthetic numbers between 1e11 and 1.3e11 There are 6,225 esthetic numbers between 1e14 and 1.3e14 There are 44,744 esthetic numbers between 1e17 and 1.3e17 There are 312,019 esthetic numbers between 1e20 and 1.3e20 There are 2,223,504 esthetic numbers between 1e23 and 1.3e23 There are 15,621,426 esthetic numbers between 1e26 and 1.3e26 There are 110,820,165 esthetic numbers between 1e29 and 1.3e29 There are 781,074,572 esthetic numbers between 1e32 and 1.3e32 There are 5,529,362,694 esthetic numbers between 1e35 and 1.3e35 There are 39,027,676,220 esthetic numbers between 1e38 and 1.3e38 There are 276,017,648,570 esthetic numbers between 1e41 and 1.3e41 There are 1,949,472,483,601 esthetic numbers between 1e44 and 1.3e44 There are 13,781,324,308,298 esthetic numbers between 1e47 and 1.3e47 There are 97,364,252,272,077 esthetic numbers between 1e50 and 1.3e50 There are 688,156,000,065,766 esthetic numbers between 1e53 and 1.3e53 There are 4,862,434,535,536,899 esthetic numbers between 1e56 and 1.3e56 There are 34,363,852,859,396,807 esthetic numbers between 1e59 and 1.3e59 There are 242,826,004,764,166,201 esthetic numbers between 1e62 and 1.3e62 There are 12,010,980,988,448,085,902 esthetic numbers with max 65 digits The count of numbers with 64 digits like https://oeis.org/A090994 5,751,957,590,040,265,961
Perl
use 5.020;
use warnings;
use experimental qw(signatures);
use ntheory qw(fromdigits todigitstring);
sub generate_esthetic ($root, $upto, $callback, $base = 10) {
my $v = fromdigits($root, $base);
return if ($v > $upto);
$callback->($v);
my $t = $root->[-1];
__SUB__->([@$root, $t + 1], $upto, $callback, $base) if ($t + 1 < $base);
__SUB__->([@$root, $t - 1], $upto, $callback, $base) if ($t - 1 >= 0);
}
sub between_esthetic ($from, $upto, $base = 10) {
my @list;
foreach my $k (1 .. $base - 1) {
generate_esthetic([$k], $upto,
sub($n) { push(@list, $n) if ($n >= $from) }, $base);
}
sort { $a <=> $b } @list;
}
sub first_n_esthetic ($n, $base = 10) {
for (my $m = $n * $n ; 1 ; $m *= $base) {
my @list = between_esthetic(1, $m, $base);
return @list[0 .. $n - 1] if @list >= $n;
}
}
foreach my $base (2 .. 16) {
say "\n$base-esthetic numbers at indices ${\(4*$base)}..${\(6*$base)}:";
my @list = first_n_esthetic(6 * $base, $base);
say join(' ', map { todigitstring($_, $base) } @list[4*$base-1 .. $#list]);
}
say "\nBase 10 esthetic numbers between 1,000 and 9,999:";
for (my @list = between_esthetic(1e3, 1e4) ; @list ;) {
say join(' ', splice(@list, 0, 20));
}
say "\nBase 10 esthetic numbers between 100,000,000 and 130,000,000:";
for (my @list = between_esthetic(1e8, 1.3e8) ; @list ;) {
say join(' ', splice(@list, 0, 9));
}
- Output:
2-esthetic numbers at indices 8..12: 10101010 101010101 1010101010 10101010101 101010101010 3-esthetic numbers at indices 12..18: 1210 1212 2101 2121 10101 10121 12101 4-esthetic numbers at indices 16..24: 323 1010 1012 1210 1212 1232 2101 2121 2123 5-esthetic numbers at indices 20..30: 323 343 432 434 1010 1012 1210 1212 1232 1234 2101 6-esthetic numbers at indices 24..36: 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234 7-esthetic numbers at indices 28..42: 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232 8-esthetic numbers at indices 32..48: 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212 9-esthetic numbers at indices 36..54: 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210 10-esthetic numbers at indices 40..60: 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012 11-esthetic numbers at indices 44..66: 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 a98 a9a 1010 12-esthetic numbers at indices 48..72: 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba ba9 bab 13-esthetic numbers at indices 52..78: 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb cba 14-esthetic numbers at indices 56..84: 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc 15-esthetic numbers at indices 60..90: 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd 16-esthetic numbers at indices 64..96: 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd ded def edc Base 10 esthetic numbers between 1,000 and 9,999: 1010 1012 1210 1212 1232 1234 2101 2121 2123 2321 2323 2343 2345 3210 3212 3232 3234 3432 3434 3454 3456 4321 4323 4343 4345 4543 4545 4565 4567 5432 5434 5454 5456 5654 5656 5676 5678 6543 6545 6565 6567 6765 6767 6787 6789 7654 7656 7676 7678 7876 7878 7898 8765 8767 8787 8789 8987 8989 9876 9878 9898 Base 10 esthetic numbers between 100,000,000 and 130,000,000: 101010101 101010121 101010123 101012101 101012121 101012123 101012321 101012323 101012343 101012345 101210101 101210121 101210123 101212101 101212121 101212123 101212321 101212323 101212343 101212345 101232101 101232121 101232123 101232321 101232323 101232343 101232345 101234321 101234323 101234343 101234345 101234543 101234545 101234565 101234567 121010101 121010121 121010123 121012101 121012121 121012123 121012321 121012323 121012343 121012345 121210101 121210121 121210123 121212101 121212121 121212123 121212321 121212323 121212343 121212345 121232101 121232121 121232123 121232321 121232323 121232343 121232345 121234321 121234323 121234343 121234345 121234543 121234545 121234565 121234567 123210101 123210121 123210123 123212101 123212121 123212123 123212321 123212323 123212343 123212345 123232101 123232121 123232123 123232321 123232323 123232343 123232345 123234321 123234323 123234343 123234345 123234543 123234545 123234565 123234567 123432101 123432121 123432123 123432321 123432323 123432343 123432345 123434321 123434323 123434343 123434345 123434543 123434545 123434565 123434567 123454321 123454323 123454343 123454345 123454543 123454545 123454565 123454567 123456543 123456545 123456565 123456567 123456765 123456767 123456787 123456789
Phix
Simple string based approach, very fast, manages stretch goal and much further in the blink of an eye.
constant aleph = "0123456789ABCDEF" function efill(string s, integer ch, i) -- min-fill, like 10101 or 54321 or 32101 s[i] = ch for j=i+1 to length(s) do ch = iff(ch>='1'?iff(ch='A'?'9':ch-1):'1') s[j] = ch end for return s end function function esthetic(string s, integer base = 10) -- generate the next esthetic number after s -- (nb unpredictable results if s is not esthetic, or "") for i=length(s) to 1 by -1 do integer ch = s[i], cp = iff(i>1?s[i-1]:'0') if ch<cp and cp<aleph[base] then return efill(s,aleph[find(ch,aleph)+2],i) elsif i=1 and ch<aleph[base] then return efill(s,iff(ch='9'?'A':ch+1),i) end if end for return efill("1"&s,'1',1) end function string s sequence res for base=2 to 16 do integer hi = base*6, lo = base*4 {s,res} = {"",{}} for i=1 to hi do s = esthetic(s, base) if i>=lo then res = append(res,s) end if end for res = join(shorten(res,"numbers",4)) printf(1,"Base %d esthetic numbers[%d..%d]: %s\n",{base,lo,hi,res}) end for {s,res} = {efill("1000",'1',1),{}} while length(s)=4 do res = append(res,s) s = esthetic(s) end while res = {join(shorten(res,"numbers",5))} printf(1,"\nBase 10 esthetic numbers between 1,000 and 9,999: %s\n\n",res) function comma(string s) for i=length(s)-2 to 2 by -3 do s[i..i-1] = "," end for return s end function for k=7 to 19 by 3 do string f = "10"&repeat('0',k), t = "13"&repeat('0',k) {s,res} = {efill(f,'1',1),{}} while s<t do res = append(res,s) s = esthetic(s) end while res = join(shorten(res,"numbers",1)) printf(1,"Base 10 esthetic numbers between %s and %s: %s\n", {comma(f),comma(t),res}) end for
- Output:
Base 2 esthetic numbers[8..12]: 10101010 101010101 1010101010 10101010101 101010101010 Base 3 esthetic numbers[12..18]: 1210 1212 2101 2121 10101 10121 12101 Base 4 esthetic numbers[16..24]: 323 1010 1012 1210 1212 1232 2101 2121 2123 Base 5 esthetic numbers[20..30]: 323 343 432 434 ... 1212 1232 1234 2101 (11 numbers) Base 6 esthetic numbers[24..36]: 343 345 432 434 ... 1210 1212 1232 1234 (13 numbers) Base 7 esthetic numbers[28..42]: 345 432 434 454 ... 1012 1210 1212 1232 (15 numbers) Base 8 esthetic numbers[32..48]: 432 434 454 456 ... 1010 1012 1210 1212 (17 numbers) Base 9 esthetic numbers[36..54]: 434 454 456 543 ... 878 1010 1012 1210 (19 numbers) Base 10 esthetic numbers[40..60]: 454 456 543 545 ... 987 989 1010 1012 (21 numbers) Base 11 esthetic numbers[44..66]: 456 543 545 565 ... 9A9 A98 A9A 1010 (23 numbers) Base 12 esthetic numbers[48..72]: 543 545 565 567 ... A9A ABA BA9 BAB (25 numbers) Base 13 esthetic numbers[52..78]: 545 565 567 654 ... BA9 BAB BCB CBA (27 numbers) Base 14 esthetic numbers[56..84]: 565 567 654 656 ... BCD CBA CBC CDC (29 numbers) Base 15 esthetic numbers[60..90]: 567 654 656 676 ... CDC CDE DCB DCD (31 numbers) Base 16 esthetic numbers[64..96]: 654 656 676 678 ... DCD DED DEF EDC (33 numbers) Base 10 esthetic numbers between 1,000 and 9,999: 1010 1012 1210 1212 1232 ... 8987 8989 9876 9878 9898 (61 numbers) Base 10 esthetic numbers between 100,000,000 and 130,000,000: 101010101 ... 123456789 (126 numbers) Base 10 esthetic numbers between 100,000,000,000 and 130,000,000,000: 101010101010 ... 123456789898 (911 numbers) Base 10 esthetic numbers between 100,000,000,000,000 and 130,000,000,000,000: 101010101010101 ... 123456789898989 (6,225 numbers) Base 10 esthetic numbers between 100,000,000,000,000,000 and 130,000,000,000,000,000: 101010101010101010 ... 123456789898989898 (44,744 numbers) Base 10 esthetic numbers between 100,000,000,000,000,000,000 and 130,000,000,000,000,000,000: 101010101010101010101 ... 123456789898989898989 (312,019 numbers)
counting
Of course (for instance) the number of 62-digit esthetic numbers beginning with 5 is just the sum of the number of 61-digit esthetic numbers beginning with 4 plus the number of 61-digit esthetic numbers beginning with 6. Those in turn can be calculated from 60-digit numbers beginning 3+5 and 5+7, and at most 10 sums per digit. In other words we can count the total number of 62-digit esthetic numbers with at most 574 additions from a table of at most 610 entries, in practice obviously just do all 610.
function count_esthetic(integer len, start=0) -- a start digit of 0 means sum all 1..9 sequence dc = repeat(repeat(1,10),len) -- nb 0..9 logically for i=2 to len do for d=0 to 9 do dc[i][d+1] = iff(d=0?0:dc[i-1][d]) + iff(d=9?0:dc[i-1][d+2]) end for end for if start=0 then return sum(dc[len][1..9]) end if -- (see note) return dc[len][start+1] end function sequence t = tagset(iff(machine_bits()=64?63:57),9,3), r = columnize({apply(true,count_esthetic,{t,1}),t}) papply(true,printf,{1,{"There are %,26d %2d-digit esthetic numbers beginning with 1\n"},r}) if machine_bits()=64 then printf(1,"There are %,26d 64-digit esthetic numbers\n",{count_esthetic(64)}) printf(1,"There are %,26d esthetic numbers with max 65 digits\n",{sum(apply(tagset(64),count_esthetic))}) end if
(It turns out that [1..9] is the same as [2..10] anyway, by symmetry, but technically the latter would be the more correct expression for digits 1..9)
- Output:
Matches Pascal output. Obviously on 32-bit/js you don't get the last four lines, if you did they'd be slightly wrong due to the 53-bit accuracy limit.
There are 126 9-digit esthetic numbers beginning with 1 There are 911 12-digit esthetic numbers beginning with 1 There are 6,225 15-digit esthetic numbers beginning with 1 There are 44,744 18-digit esthetic numbers beginning with 1 There are 312,019 21-digit esthetic numbers beginning with 1 There are 2,223,504 24-digit esthetic numbers beginning with 1 There are 15,621,426 27-digit esthetic numbers beginning with 1 There are 110,820,165 30-digit esthetic numbers beginning with 1 There are 781,074,572 33-digit esthetic numbers beginning with 1 There are 5,529,362,694 36-digit esthetic numbers beginning with 1 There are 39,027,676,220 39-digit esthetic numbers beginning with 1 There are 276,017,648,570 42-digit esthetic numbers beginning with 1 There are 1,949,472,483,601 45-digit esthetic numbers beginning with 1 There are 13,781,324,308,298 48-digit esthetic numbers beginning with 1 There are 97,364,252,272,077 51-digit esthetic numbers beginning with 1 There are 688,156,000,065,766 54-digit esthetic numbers beginning with 1 There are 4,862,434,535,536,899 57-digit esthetic numbers beginning with 1 There are 34,363,852,859,396,807 60-digit esthetic numbers beginning with 1 There are 242,826,004,764,166,201 63-digit esthetic numbers beginning with 1 There are 5,751,957,590,040,265,961 64-digit esthetic numbers There are 12,010,980,988,448,085,902 esthetic numbers with max 65 digits
PicoLisp
(de esthetic (N Base)
(let Lst
(make
(loop
(yoke (% N Base))
(T (=0 (setq N (/ N Base)))) ) )
(and
(fully
=1
(make
(for (L Lst (cdr L) (cdr L))
(link (abs (- (car L) (cadr L)))) ) ) )
(pack
(mapcar
'((C)
(and (> C 9) (inc 'C 39))
(char (+ C 48)) )
Lst ) ) ) ) )
(de genCount (Num Base)
(let (C 0 N 0)
(tail
(inc (* 2 Base))
(make
(while (>= Num C)
(when (esthetic N Base) (link @) (inc 'C))
(inc 'N) ) ) ) ) )
(de genRange (A B Base)
(make
(while (>= B A)
(when (esthetic A Base) (link @))
(inc 'A) ) ) )
(for (N 2 (>= 16 N) (inc N))
(prin "Base " N ": ")
(mapc '((L) (prin L " ")) (genCount (* 6 N) N))
(prinl) )
(prinl)
(prinl "Base 10: 61 esthetic numbers between 1000 and 9999:")
(let L (genRange 1000 9999 10)
(while (cut 16 'L)
(mapc '((L) (prin L " ")) @)
(prinl) ) )
(prinl)
(prinl "Base 10: 126 esthetic numbers between 100000000 and 130000000:")
(let L (genRange 100000000 130000000 10)
(while (cut 9 'L)
(mapc '((L) (prin L " ")) @)
(prinl) ) )
- Output:
Base 2: 10101010 101010101 1010101010 10101010101 101010101010 Base 3: 1210 1212 2101 2121 10101 10121 12101 Base 4: 323 1010 1012 1210 1212 1232 2101 2121 2123 Base 5: 323 343 432 434 1010 1012 1210 1212 1232 1234 2101 Base 6: 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234 Base 7: 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232 Base 8: 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212 Base 9: 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210 Base 10: 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012 Base 11: 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 a98 a9a 1010 Base 12: 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba ba9 bab Base 13: 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb cba Base 14: 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc Base 15: 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd Base 16: 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd ded def edc Base 10: 61 esthetic numbers between 1000 and 9999: 1010 1012 1210 1212 1232 1234 2101 2121 2123 2321 2323 2343 2345 3210 3212 3232 3234 3432 3434 3454 3456 4321 4323 4343 4345 4543 4545 4565 4567 5432 5434 5454 5456 5654 5656 5676 5678 6543 6545 6565 6567 6765 6767 6787 6789 7654 7656 7676 7678 7876 7878 7898 8765 8767 8787 8789 8987 8989 9876 9878 9898 Base 10: 126 esthetic numbers between 100000000 and 130000000: 101010101 101010121 101010123 101012101 101012121 101012123 101012321 101012323 101012343 101012345 101210101 101210121 101210123 101212101 101212121 101212123 101212321 101212323 101212343 101212345 101232101 101232121 101232123 101232321 101232323 101232343 101232345 101234321 101234323 101234343 101234345 101234543 101234545 101234565 101234567 121010101 121010121 121010123 121012101 121012121 121012123 121012321 121012323 121012343 121012345 121210101 121210121 121210123 121212101 121212121 121212123 121212321 121212323 121212343 121212345 121232101 121232121 121232123 121232321 121232323 121232343 121232345 121234321 121234323 121234343 121234345 121234543 121234545 121234565 121234567 123210101 123210121 123210123 123212101 123212121 123212123 123212321 123212323 123212343 123212345 123232101 123232121 123232123 123232321 123232323 123232343 123232345 123234321 123234323 123234343 123234345 123234543 123234545 123234565 123234567 123432101 123432121 123432123 123432321 123432323 123432343 123432345 123434321 123434323 123434343 123434345 123434543 123434545 123434565 123434567 123454321 123454323 123454343 123454345 123454543 123454545 123454565 123454567 123456543 123456545 123456565 123456567 123456765 123456767 123456787 123456789
Prolog
main:-
forall(between(2, 16, Base),
(Min_index is Base * 4, Max_index is Base * 6,
print_esthetic_numbers1(Base, Min_index, Max_index))),
print_esthetic_numbers2(1000, 9999, 16),
nl,
print_esthetic_numbers2(100000000, 130000000, 8).
print_esthetic_numbers1(Base, Min_index, Max_index):-
swritef(Format, '~%tr ', [Base]),
writef('Esthetic numbers in base %t from index %t through index %t:\n',
[Base, Min_index, Max_index]),
print_esthetic_numbers1(Base, Format, Min_index, Max_index, 0, 1).
print_esthetic_numbers1(Base, Format, Min_index, Max_index, M, I):-
I =< Max_index,
!,
next_esthetic_number(Base, M, N),
(I >= Min_index -> format(Format, [N]) ; true),
J is I + 1,
print_esthetic_numbers1(Base, Format, Min_index, Max_index, N, J).
print_esthetic_numbers1(_, _, _, _, _, _):-
write('\n\n').
print_esthetic_numbers2(Min, Max, Per_line):-
writef('Esthetic numbers in base 10 between %t and %t:\n', [Min, Max]),
M is Min - 1,
print_esthetic_numbers2(Max, Per_line, M, 0).
print_esthetic_numbers2(Max, Per_line, M, Count):-
next_esthetic_number(10, M, N),
N =< Max,
!,
write(N),
Count1 is Count + 1,
(0 is Count1 mod Per_line -> nl ; write(' ')),
print_esthetic_numbers2(Max, Per_line, N, Count1).
print_esthetic_numbers2(_, _, _, Count):-
writef('\nCount: %t\n', [Count]).
next_esthetic_number(Base, M, N):-
N is M + 1,
N < Base,
!.
next_esthetic_number(Base, M, N):-
A is M // Base,
B is A mod Base,
(B is M mod Base + 1, B + 1 < Base ->
N is M + 2
;
next_esthetic_number(Base, A, C),
D is C mod Base,
(D == 0 -> E = 1 ; E is D - 1),
N is C * Base + E).
- Output:
Esthetic numbers in base 2 from index 8 through index 12: 10101010 101010101 1010101010 10101010101 101010101010 Esthetic numbers in base 3 from index 12 through index 18: 1210 1212 2101 2121 10101 10121 12101 Esthetic numbers in base 4 from index 16 through index 24: 323 1010 1012 1210 1212 1232 2101 2121 2123 Esthetic numbers in base 5 from index 20 through index 30: 323 343 432 434 1010 1012 1210 1212 1232 1234 2101 Esthetic numbers in base 6 from index 24 through index 36: 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234 Esthetic numbers in base 7 from index 28 through index 42: 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232 Esthetic numbers in base 8 from index 32 through index 48: 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212 Esthetic numbers in base 9 from index 36 through index 54: 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210 Esthetic numbers in base 10 from index 40 through index 60: 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012 Esthetic numbers in base 11 from index 44 through index 66: 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 a98 a9a 1010 Esthetic numbers in base 12 from index 48 through index 72: 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba ba9 bab Esthetic numbers in base 13 from index 52 through index 78: 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb cba Esthetic numbers in base 14 from index 56 through index 84: 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc Esthetic numbers in base 15 from index 60 through index 90: 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd Esthetic numbers in base 16 from index 64 through index 96: 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd ded def edc Esthetic numbers in base 10 between 1000 and 9999: 1010 1012 1210 1212 1232 1234 2101 2121 2123 2321 2323 2343 2345 3210 3212 3232 3234 3432 3434 3454 3456 4321 4323 4343 4345 4543 4545 4565 4567 5432 5434 5454 5456 5654 5656 5676 5678 6543 6545 6565 6567 6765 6767 6787 6789 7654 7656 7676 7678 7876 7878 7898 8765 8767 8787 8789 8987 8989 9876 9878 9898 Count: 61 Esthetic numbers in base 10 between 100000000 and 130000000: 101010101 101010121 101010123 101012101 101012121 101012123 101012321 101012323 101012343 101012345 101210101 101210121 101210123 101212101 101212121 101212123 101212321 101212323 101212343 101212345 101232101 101232121 101232123 101232321 101232323 101232343 101232345 101234321 101234323 101234343 101234345 101234543 101234545 101234565 101234567 121010101 121010121 121010123 121012101 121012121 121012123 121012321 121012323 121012343 121012345 121210101 121210121 121210123 121212101 121212121 121212123 121212321 121212323 121212343 121212345 121232101 121232121 121232123 121232321 121232323 121232343 121232345 121234321 121234323 121234343 121234345 121234543 121234545 121234565 121234567 123210101 123210121 123210123 123212101 123212121 123212123 123212321 123212323 123212343 123212345 123232101 123232121 123232123 123232321 123232323 123232343 123232345 123234321 123234323 123234343 123234345 123234543 123234545 123234565 123234567 123432101 123432121 123432123 123432321 123432323 123432343 123432345 123434321 123434323 123434343 123434345 123434543 123434545 123434565 123434567 123454321 123454323 123454343 123454345 123454543 123454545 123454565 123454567 123456543 123456545 123456565 123456567 123456765 123456767 123456787 123456789 Count: 126
Python
Python :: Procedural
from collections import deque
from itertools import dropwhile, islice, takewhile
from textwrap import wrap
from typing import Iterable, Iterator
Digits = str # Alias for the return type of to_digits()
def esthetic_nums(base: int) -> Iterator[int]:
"""Generate the esthetic number sequence for a given base
>>> list(islice(esthetic_nums(base=10), 20))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 21, 23, 32, 34, 43, 45, 54, 56, 65]
"""
queue: deque[tuple[int, int]] = deque()
queue.extendleft((d, d) for d in range(1, base))
while True:
num, lsd = queue.pop()
yield num
new_lsds = (d for d in (lsd - 1, lsd + 1) if 0 <= d < base)
num *= base # Shift num left one digit
queue.extendleft((num + d, d) for d in new_lsds)
def to_digits(num: int, base: int) -> Digits:
"""Return a representation of an integer as digits in a given base
>>> to_digits(0x3def84f0ce, base=16)
'3def84f0ce'
"""
digits: list[str] = []
while num:
num, d = divmod(num, base)
digits.append("0123456789abcdef"[d])
return "".join(reversed(digits)) if digits else "0"
def pprint_it(it: Iterable[str], indent: int = 4, width: int = 80) -> None:
"""Pretty print an iterable which returns strings
>>> pprint_it(map(str, range(20)), indent=0, width=40)
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19
<BLANKLINE>
"""
joined = ", ".join(it)
lines = wrap(joined, width=width - indent)
for line in lines:
print(f"{indent*' '}{line}")
print()
def task_2() -> None:
nums: Iterator[int]
for base in range(2, 16 + 1):
start, stop = 4 * base, 6 * base
nums = esthetic_nums(base)
nums = islice(nums, start - 1, stop) # start and stop are 1-based indices
print(
f"Base-{base} esthetic numbers from "
f"index {start} through index {stop} inclusive:\n"
)
pprint_it(to_digits(num, base) for num in nums)
def task_3(lower: int, upper: int, base: int = 10) -> None:
nums: Iterator[int] = esthetic_nums(base)
nums = dropwhile(lambda num: num < lower, nums)
nums = takewhile(lambda num: num <= upper, nums)
print(
f"Base-{base} esthetic numbers with "
f"magnitude between {lower:,} and {upper:,}:\n"
)
pprint_it(to_digits(num, base) for num in nums)
if __name__ == "__main__":
print("======\nTask 2\n======\n")
task_2()
print("======\nTask 3\n======\n")
task_3(1_000, 9_999)
print("======\nTask 4\n======\n")
task_3(100_000_000, 130_000_000)
- Output:
====== Task 2 ====== Base-2 esthetic numbers from index 8 through index 12 inclusive: 10101010, 101010101, 1010101010, 10101010101, 101010101010 Base-3 esthetic numbers from index 12 through index 18 inclusive: 1210, 1212, 2101, 2121, 10101, 10121, 12101 Base-4 esthetic numbers from index 16 through index 24 inclusive: 323, 1010, 1012, 1210, 1212, 1232, 2101, 2121, 2123 Base-5 esthetic numbers from index 20 through index 30 inclusive: 323, 343, 432, 434, 1010, 1012, 1210, 1212, 1232, 1234, 2101 Base-6 esthetic numbers from index 24 through index 36 inclusive: 343, 345, 432, 434, 454, 543, 545, 1010, 1012, 1210, 1212, 1232, 1234 Base-7 esthetic numbers from index 28 through index 42 inclusive: 345, 432, 434, 454, 456, 543, 545, 565, 654, 656, 1010, 1012, 1210, 1212, 1232 Base-8 esthetic numbers from index 32 through index 48 inclusive: 432, 434, 454, 456, 543, 545, 565, 567, 654, 656, 676, 765, 767, 1010, 1012, 1210, 1212 Base-9 esthetic numbers from index 36 through index 54 inclusive: 434, 454, 456, 543, 545, 565, 567, 654, 656, 676, 678, 765, 767, 787, 876, 878, 1010, 1012, 1210 Base-10 esthetic numbers from index 40 through index 60 inclusive: 454, 456, 543, 545, 565, 567, 654, 656, 676, 678, 765, 767, 787, 789, 876, 878, 898, 987, 989, 1010, 1012 Base-11 esthetic numbers from index 44 through index 66 inclusive: 456, 543, 545, 565, 567, 654, 656, 676, 678, 765, 767, 787, 789, 876, 878, 898, 89a, 987, 989, 9a9, a98, a9a, 1010 Base-12 esthetic numbers from index 48 through index 72 inclusive: 543, 545, 565, 567, 654, 656, 676, 678, 765, 767, 787, 789, 876, 878, 898, 89a, 987, 989, 9a9, 9ab, a98, a9a, aba, ba9, bab Base-13 esthetic numbers from index 52 through index 78 inclusive: 545, 565, 567, 654, 656, 676, 678, 765, 767, 787, 789, 876, 878, 898, 89a, 987, 989, 9a9, 9ab, a98, a9a, aba, abc, ba9, bab, bcb, cba Base-14 esthetic numbers from index 56 through index 84 inclusive: 565, 567, 654, 656, 676, 678, 765, 767, 787, 789, 876, 878, 898, 89a, 987, 989, 9a9, 9ab, a98, a9a, aba, abc, ba9, bab, bcb, bcd, cba, cbc, cdc Base-15 esthetic numbers from index 60 through index 90 inclusive: 567, 654, 656, 676, 678, 765, 767, 787, 789, 876, 878, 898, 89a, 987, 989, 9a9, 9ab, a98, a9a, aba, abc, ba9, bab, bcb, bcd, cba, cbc, cdc, cde, dcb, dcd Base-16 esthetic numbers from index 64 through index 96 inclusive: 654, 656, 676, 678, 765, 767, 787, 789, 876, 878, 898, 89a, 987, 989, 9a9, 9ab, a98, a9a, aba, abc, ba9, bab, bcb, bcd, cba, cbc, cdc, cde, dcb, dcd, ded, def, edc ====== Task 3 ====== Base-10 esthetic numbers with magnitude between 1,000 and 9,999: 1010, 1012, 1210, 1212, 1232, 1234, 2101, 2121, 2123, 2321, 2323, 2343, 2345, 3210, 3212, 3232, 3234, 3432, 3434, 3454, 3456, 4321, 4323, 4343, 4345, 4543, 4545, 4565, 4567, 5432, 5434, 5454, 5456, 5654, 5656, 5676, 5678, 6543, 6545, 6565, 6567, 6765, 6767, 6787, 6789, 7654, 7656, 7676, 7678, 7876, 7878, 7898, 8765, 8767, 8787, 8789, 8987, 8989, 9876, 9878, 9898 ====== Task 4 ====== Base-10 esthetic numbers with magnitude between 100,000,000 and 130,000,000: 101010101, 101010121, 101010123, 101012101, 101012121, 101012123, 101012321, 101012323, 101012343, 101012345, 101210101, 101210121, 101210123, 101212101, 101212121, 101212123, 101212321, 101212323, 101212343, 101212345, 101232101, 101232121, 101232123, 101232321, 101232323, 101232343, 101232345, 101234321, 101234323, 101234343, 101234345, 101234543, 101234545, 101234565, 101234567, 121010101, 121010121, 121010123, 121012101, 121012121, 121012123, 121012321, 121012323, 121012343, 121012345, 121210101, 121210121, 121210123, 121212101, 121212121, 121212123, 121212321, 121212323, 121212343, 121212345, 121232101, 121232121, 121232123, 121232321, 121232323, 121232343, 121232345, 121234321, 121234323, 121234343, 121234345, 121234543, 121234545, 121234565, 121234567, 123210101, 123210121, 123210123, 123212101, 123212121, 123212123, 123212321, 123212323, 123212343, 123212345, 123232101, 123232121, 123232123, 123232321, 123232323, 123232343, 123232345, 123234321, 123234323, 123234343, 123234345, 123234543, 123234545, 123234565, 123234567, 123432101, 123432121, 123432123, 123432321, 123432323, 123432343, 123432345, 123434321, 123434323, 123434343, 123434345, 123434543, 123434545, 123434565, 123434567, 123454321, 123454323, 123454343, 123454345, 123454543, 123454545, 123454565, 123454567, 123456543, 123456545, 123456565, 123456567, 123456765, 123456767, 123456787, 123456789
Python :: Functional
'''Esthetic numbers'''
from functools import reduce
from itertools import (
accumulate, chain, count, dropwhile,
islice, product, takewhile
)
from operator import add
from string import digits, ascii_lowercase
from textwrap import wrap
# estheticNumbersInBase :: Int -> [Int]
def estheticNumbersInBase(b):
'''Infinite stream of numbers which are
esthetic in a given base.
'''
return concatMap(
compose(
lambda deltas: concatMap(
lambda headDigit: concatMap(
compose(
fromBaseDigits(b),
scanl(add)(headDigit)
)
)(deltas)
)(range(1, b)),
replicateList([-1, 1])
)
)(count(0))
# ------------------------ TESTS -------------------------
def main():
'''Specified tests'''
def samples(b):
i, j = b * 4, b * 6
return '\n'.join([
f'Esthetics [{i}..{j}] for base {b}:',
unlines(wrap(
unwords([
showInBase(b)(n) for n in compose(
drop(i - 1), take(j)
)(
estheticNumbersInBase(b)
)
]), 60
))
])
def takeInRange(a, b):
return compose(
dropWhile(lambda x: x < a),
takeWhile(lambda x: x <= b)
)
print(
'\n\n'.join([
samples(b) for b in range(2, 1 + 16)
])
)
for (lo, hi) in [(1000, 9999), (100_000_000, 130_000_000)]:
print(f'\nBase 10 Esthetics in range [{lo}..{hi}]:')
print(
unlines(wrap(
unwords(
str(x) for x in takeInRange(lo, hi)(
estheticNumbersInBase(10)
)
), 60
))
)
# ------------------- BASES AND DIGITS -------------------
# fromBaseDigits :: Int -> [Int] -> [Int]
def fromBaseDigits(b):
'''An empty list if any digits are out of range for
the base. Otherwise a list containing an integer.
'''
def go(digitList):
maybeNum = reduce(
lambda r, d: None if r is None or (
0 > d or d >= b
) else r * b + d,
digitList, 0
)
return [] if None is maybeNum else [maybeNum]
return go
# toBaseDigits :: Int -> Int -> [Int]
def toBaseDigits(b):
'''A list of the digits of n in base b.
'''
def f(x):
return None if 0 == x else (
divmod(x, b)[::-1]
)
return lambda n: list(reversed(unfoldr(f)(n)))
# showInBase :: Int -> Int -> String
def showInBase(b):
'''String representation of n in base b.
'''
charSet = digits + ascii_lowercase
return lambda n: ''.join([
charSet[i] for i in toBaseDigits(b)(n)
])
# ----------------------- GENERIC ------------------------
# compose :: ((a -> a), ...) -> (a -> a)
def compose(*fs):
'''Composition, from right to left,
of a series of functions.
'''
def go(f, g):
def fg(x):
return f(g(x))
return fg
return reduce(go, fs, lambda x: x)
# concatMap :: (a -> [b]) -> [a] -> [b]
def concatMap(f):
'''A concatenated list over which a function has been
mapped.
The list monad can be derived by using a function f
which wraps its output in a list, (using an empty
list to represent computational failure).
'''
def go(xs):
return chain.from_iterable(map(f, xs))
return go
# drop :: Int -> [a] -> [a]
# drop :: Int -> String -> String
def drop(n):
'''The sublist of xs beginning at
(zero-based) index n.
'''
def go(xs):
if isinstance(xs, (list, tuple, str)):
return xs[n:]
else:
take(n)(xs)
return xs
return go
# dropWhile :: (a -> Bool) -> [a] -> [a]
# dropWhile :: (Char -> Bool) -> String -> String
def dropWhile(p):
'''The suffix remainining after takeWhile p xs.
'''
return lambda xs: list(
dropwhile(p, xs)
)
# replicateList :: [a] -> Int -> [[a]]
def replicateList(xs):
'''All distinct lists of length n that
consist of elements drawn from xs.
'''
def rep(n):
def go(x):
return [[]] if 1 > x else [
([a] + b) for (a, b) in product(
xs, go(x - 1)
)
]
return go(n)
return rep
# scanl :: (b -> a -> b) -> b -> [a] -> [b]
def scanl(f):
'''scanl is like reduce, but defines a succession of
intermediate values, building from the left.
'''
def go(a):
def g(xs):
return accumulate(chain([a], xs), f)
return g
return go
# take :: Int -> [a] -> [a]
# take :: Int -> String -> String
def take(n):
'''The prefix of xs of length n,
or xs itself if n > length xs.
'''
def go(xs):
return list(islice(xs, n))
return go
# takeWhile :: (a -> Bool) -> [a] -> [a]
# takeWhile :: (Char -> Bool) -> String -> String
def takeWhile(p):
'''The longest (possibly empty) prefix of xs
in which all elements satisfy p.
'''
return lambda xs: list(
takewhile(p, xs)
)
# unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
def unfoldr(f):
'''Dual to reduce or foldr.
Where catamorphism reduces a list to a summary value,
the anamorphic unfoldr builds a list from a seed value.
As long as f returns (a, b) a is prepended to the list,
and the residual b is used as the argument for the next
application of f.
When f returns None, the completed list is returned.
'''
def go(v):
xr = v, v
xs = []
while True:
xr = f(xr[1])
if None is not xr:
xs.append(xr[0])
else:
return xs
return go
# unlines :: [String] -> String
def unlines(xs):
'''A single string formed by the intercalation
of a list of strings with the newline character.
'''
return '\n'.join(xs)
# unwords :: [String] -> String
def unwords(xs):
'''A space-separated string derived
from a list of words.
'''
return ' '.join(xs)
# MAIN ---
if __name__ == '__main__':
main()
- Output:
Esthetics [8..12] for base 2: 10101010 101010101 1010101010 10101010101 101010101010 Esthetics [12..18] for base 3: 1210 1212 2101 2121 10101 10121 12101 Esthetics [16..24] for base 4: 323 1010 1012 1210 1212 1232 2101 2121 2123 Esthetics [20..30] for base 5: 323 343 432 434 1010 1012 1210 1212 1232 1234 2101 Esthetics [24..36] for base 6: 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234 Esthetics [28..42] for base 7: 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232 Esthetics [32..48] for base 8: 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212 Esthetics [36..54] for base 9: 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210 Esthetics [40..60] for base 10: 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012 Esthetics [44..66] for base 11: 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 a98 a9a 1010 Esthetics [48..72] for base 12: 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba ba9 bab Esthetics [52..78] for base 13: 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb cba Esthetics [56..84] for base 14: 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc Esthetics [60..90] for base 15: 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd Esthetics [64..96] for base 16: 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd ded def edc Base 10 Esthetics in range [1000..9999]: 1010 1012 1210 1212 1232 1234 2101 2121 2123 2321 2323 2343 2345 3210 3212 3232 3234 3432 3434 3454 3456 4321 4323 4343 4345 4543 4545 4565 4567 5432 5434 5454 5456 5654 5656 5676 5678 6543 6545 6565 6567 6765 6767 6787 6789 7654 7656 7676 7678 7876 7878 7898 8765 8767 8787 8789 8987 8989 9876 9878 9898 Base 10 Esthetics in range [100000000..130000000]: 101010101 101010121 101010123 101012101 101012121 101012123 101012321 101012323 101012343 101012345 101210101 101210121 101210123 101212101 101212121 101212123 101212321 101212323 101212343 101212345 101232101 101232121 101232123 101232321 101232323 101232343 101232345 101234321 101234323 101234343 101234345 101234543 101234545 101234565 101234567 121010101 121010121 121010123 121012101 121012121 121012123 121012321 121012323 121012343 121012345 121210101 121210121 121210123 121212101 121212121 121212123 121212321 121212323 121212343 121212345 121232101 121232121 121232123 121232321 121232323 121232343 121232345 121234321 121234323 121234343 121234345 121234543 121234545 121234565 121234567 123210101 123210121 123210123 123212101 123212121 123212123 123212321 123212323 123212343 123212345 123232101 123232121 123232123 123232321 123232323 123232343 123232345 123234321 123234323 123234343 123234345 123234543 123234545 123234565 123234567 123432101 123432121 123432123 123432321 123432323 123432343 123432345 123434321 123434323 123434343 123434345 123434543 123434545 123434565 123434567 123454321 123454323 123454343 123454345 123454543 123454545 123454565 123454567 123456543 123456545 123456565 123456567 123456765 123456767 123456787 123456789
Quackery
[ [] swap
[ base share /mod
rot join swap
dup 0 = until ]
drop ] is digits ( n --> [ )
[ dup 0 = iff
[ drop false ]
done
digits
true swap
behead swap
witheach
[ tuck - abs 1 != if
[ dip not conclude ] ]
drop ] is esthetic ( n --> b )
15 times
[ i^ 2 +
say "Base " dup echo cr
base put
[] 0
[ 1+
dup esthetic if
[ tuck join swap ]
over size
base share 6 * = until ]
drop
base share 4 * 1 - split nip
echo cr cr
base release ]
say "Decimal between 1000 and 9999: "
cr
0 temp put
9000 times
[ i^ 1000 + dup
esthetic iff
[ echo
1 temp tally
temp share
10 mod iff
sp else cr ]
else drop ]
temp release
- Output:
Base 2 [ 10101010 101010101 1010101010 10101010101 101010101010 ] Base 3 [ 1210 1212 2101 2121 10101 10121 12101 ] Base 4 [ 323 1010 1012 1210 1212 1232 2101 2121 2123 ] Base 5 [ 323 343 432 434 1010 1012 1210 1212 1232 1234 2101 ] Base 6 [ 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234 ] Base 7 [ 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232 ] Base 8 [ 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212 ] Base 9 [ 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210 ] Base 10 [ 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012 ] Base 11 [ 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 A98 A9A 1010 ] Base 12 [ 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA BA9 BAB ] Base 13 [ 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB CBA ] Base 14 [ 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC ] Base 15 [ 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC CDE DCB DCD ] Base 16 [ 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC CDE DCB DCD DED DEF EDC ] Decimal between 1000 and 9999: 1010 1012 1210 1212 1232 1234 2101 2121 2123 2321 2323 2343 2345 3210 3212 3232 3234 3432 3434 3454 3456 4321 4323 4343 4345 4543 4545 4565 4567 5432 5434 5454 5456 5654 5656 5676 5678 6543 6545 6565 6567 6765 6767 6787 6789 7654 7656 7676 7678 7876 7878 7898 8765 8767 8787 8789 8987 8989 9876 9878 9898
Raku
use Lingua::EN::Numbers;
sub esthetic($base = 10) {
my @s = ^$base .map: -> \s {
((s - 1).base($base) if s > 0), ((s + 1).base($base) if s < $base - 1)
}
flat [ (1 .. $base - 1)».base($base) ],
{ [ flat .map: { $_ xx * Z~ flat @s[.comb.tail.parse-base($base)] } ] } … *
}
for 2 .. 16 -> $b {
put "\n{(4 × $b).&ordinal-digit} through {(6 × $b).&ordinal-digit} esthetic numbers in base $b";
put esthetic($b)[(4 × $b - 1) .. (6 × $b - 1)]».fmt('%3s').batch(16).join: "\n"
}
my @e10 = esthetic;
put "\nBase 10 esthetic numbers between 1,000 and 9,999:";
put @e10.&between(1000, 9999).batch(20).join: "\n";
put "\nBase 10 esthetic numbers between {1e8.Int.&comma} and {1.3e8.Int.&comma}:";
put @e10.&between(1e8.Int, 1.3e8.Int).batch(9).join: "\n";
sub between (@array, Int $lo, Int $hi) {
my $top = @array.first: * > $hi, :k;
@array[^$top].grep: * > $lo
}
- Output:
8th through 12th esthetic numbers in base 2 10101010 101010101 1010101010 10101010101 101010101010 12th through 18th esthetic numbers in base 3 1210 1212 2101 2121 10101 10121 12101 16th through 24th esthetic numbers in base 4 323 1010 1012 1210 1212 1232 2101 2121 2123 20th through 30th esthetic numbers in base 5 323 343 432 434 1010 1012 1210 1212 1232 1234 2101 24th through 36th esthetic numbers in base 6 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234 28th through 42nd esthetic numbers in base 7 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232 32nd through 48th esthetic numbers in base 8 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212 36th through 54th esthetic numbers in base 9 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210 40th through 60th esthetic numbers in base 10 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012 44th through 66th esthetic numbers in base 11 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 A98 A9A 1010 48th through 72nd esthetic numbers in base 12 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA BA9 BAB 52nd through 78th esthetic numbers in base 13 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB CBA 56th through 84th esthetic numbers in base 14 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC 60th through 90th esthetic numbers in base 15 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC CDE DCB DCD 64th through 96th esthetic numbers in base 16 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC CDE DCB DCD DED DEF EDC Base 10 esthetic numbers between 1,000 and 9,999: 1010 1012 1210 1212 1232 1234 2101 2121 2123 2321 2323 2343 2345 3210 3212 3232 3234 3432 3434 3454 3456 4321 4323 4343 4345 4543 4545 4565 4567 5432 5434 5454 5456 5654 5656 5676 5678 6543 6545 6565 6567 6765 6767 6787 6789 7654 7656 7676 7678 7876 7878 7898 8765 8767 8787 8789 8987 8989 9876 9878 9898 Base 10 esthetic numbers between 100,000,000 and 130,000,000: 101010101 101010121 101010123 101012101 101012121 101012123 101012321 101012323 101012343 101012345 101210101 101210121 101210123 101212101 101212121 101212123 101212321 101212323 101212343 101212345 101232101 101232121 101232123 101232321 101232323 101232343 101232345 101234321 101234323 101234343 101234345 101234543 101234545 101234565 101234567 121010101 121010121 121010123 121012101 121012121 121012123 121012321 121012323 121012343 121012345 121210101 121210121 121210123 121212101 121212121 121212123 121212321 121212323 121212343 121212345 121232101 121232121 121232123 121232321 121232323 121232343 121232345 121234321 121234323 121234343 121234345 121234543 121234545 121234565 121234567 123210101 123210121 123210123 123212101 123212121 123212123 123212321 123212323 123212343 123212345 123232101 123232121 123232123 123232321 123232323 123232343 123232345 123234321 123234323 123234343 123234345 123234543 123234545 123234565 123234567 123432101 123432121 123432123 123432321 123432323 123432343 123432345 123434321 123434323 123434343 123434345 123434543 123434545 123434565 123434567 123454321 123454323 123454343 123454345 123454543 123454545 123454565 123454567 123456543 123456545 123456565 123456567 123456765 123456767 123456787 123456789
REXX
/*REXX pgm lists a bunch of esthetic numbers in bases 2 ──► 16, & base 10 in two ranges.*/
parse arg baseL baseH range /*obtain optional arguments from the CL*/
if baseL=='' | baseL=="," then baseL= 2 /*Not specified? Then use the default.*/
if baseH=='' | baseH=="," then baseH=16 /* " " " " " " */
if range=='' | range=="," then range=1000..9999 /* " " " " " " */
do radix=baseL to baseH; #= 0; if radix<2 then iterate /*process the bases. */
start= radix * 4; stop = radix * 6
$=; do i=1 until #==stop; y= base(i, radix) /*convert I to base Y*/
if \esthetic(y, radix) then iterate /*not esthetic? Skip*/
#= # + 1; if #<start then iterate /*is # below range?*/
$= $ y /*append # to $ list.*/
end /*i*/
say
say center(' base ' radix", the" th(start) '──►' th(stop) ,
"esthetic numbers ", max(80, length($) - 1), '─')
say strip($)
end /*radix*/
say; g= 25
parse var range start '..' stop
say center(' base 10 esthetic numbers between' start "and" stop '(inclusive) ', g*5-1,"─")
#= 0; $=
do k=start to stop; if \esthetic(k, 10) then iterate; #= # + 1; $= $ k
if #//g==0 then do; say strip($); $=; end
end /*k*/
say strip($); say; say # ' esthetic numbers listed.'
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
PorA: _= pos(z, @u); p= substr(@u, _-1, 1); a= substr(@u, _+1, 1); return
th: parse arg th; return th || word('th st nd rd', 1+(th//10)*(th//100%10\==1)*(th//10<4))
vv: parse arg v,_; vr= x2d(v) + _; if vr==-1 then vr= r; return d2x(vr)
/*──────────────────────────────────────────────────────────────────────────────────────*/
base: procedure expose @u; arg x 1 #,toB,inB,,y /*Y is assigned a "null" value. */
if tob=='' then tob= 10 /*maybe assign a default for TObase. */
if inb=='' then inb= 10 /* " " " " " INbase. */
@l= '0123456789abcdef'; @u= @l; upper @u /*two versions of hexadecimal digits. */
if inB\==10 then do; #= 0 /*only convert if not base 10. */
do j=1 for length(x) /*convert X: base inB ──► base 10. */
#= # * inB + pos(substr(x, j, 1), @u) -1 /*build new number.*/
end /*j*/ /* [↑] this also verifies digits. */
end
if toB==10 then return # /*if TOB is ten, then simply return #.*/
do while # >= toB /*convert #: base 10 ──► base toB.*/
y= substr(@l, (# // toB) + 1, 1)y /*construct the output number. */
#= # % toB /* ··· and whittle # down also. */
end /*while*/ /* [↑] algorithm may leave a residual.*/
return substr(@l, # + 1, 1)y /*prepend the residual, if any. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
esthetic: procedure expose @u; arg x,r; L= length(x); if L==1 then return 1
if x<2 then return 0
do d=0 to r-1; _= d2x(d); if pos(_ || _, x)\==0 then return 0
end /*d*/ /* [↑] check for a duplicated digits. */
do j=1 for L; @.j= substr(x, j, 1) /*assign (base) digits to stemmed array*/
end /*j*/
if L==2 then do; z= @.1; call PorA; if @.2==p | @.2==a then nop
else return 0
end
do e=2 to L-1; z= @.e; pe= e - 1; ae= e + 1
if (z==vv(@.pe,-1)|z==vv(@.pe,1))&(z==vv(@.ae,-1)|z==vv(@.ae,1)) then iterate
return 0
end /*e*/; return 1
- output when using the default inputs:
───────────────── base 2, the 8th ──► 12th esthetic numbers ────────────────── 10101010 101010101 1010101010 10101010101 101010101010 ───────────────── base 3, the 12th ──► 18th esthetic numbers ───────────────── 1210 1212 2101 2121 10101 10121 12101 ───────────────── base 4, the 16th ──► 24th esthetic numbers ───────────────── 323 1010 1012 1210 1212 1232 2101 2121 2123 ───────────────── base 5, the 20th ──► 30th esthetic numbers ───────────────── 323 343 432 434 1010 1012 1210 1212 1232 1234 2101 ───────────────── base 6, the 24th ──► 36th esthetic numbers ───────────────── 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234 ───────────────── base 7, the 28th ──► 42nd esthetic numbers ───────────────── 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232 ───────────────── base 8, the 32nd ──► 48th esthetic numbers ───────────────── 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212 ───────────────── base 9, the 36th ──► 54th esthetic numbers ───────────────── 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210 ─────────────────── base 10, the 40th ──► 60th esthetic numbers ─────────────────── 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012 ────────────────────── base 11, the 44th ──► 66th esthetic numbers ─────────────────────── 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 a98 a9a 1010 ────────────────────────── base 12, the 48th ──► 72nd esthetic numbers ────────────────────────── 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba ba9 bab ────────────────────────────── base 13, the 52nd ──► 78th esthetic numbers ────────────────────────────── 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb cba ────────────────────────────────── base 14, the 56th ──► 84th esthetic numbers ────────────────────────────────── 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc ────────────────────────────────────── base 15, the 60th ──► 90th esthetic numbers ────────────────────────────────────── 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd ────────────────────────────────────────── base 16, the 64th ──► 96th esthetic numbers ────────────────────────────────────────── 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd ded def edc ──────────────────────────────── base 10 esthetic numbers between 1000 and 9999 (inclusive) ──────────────────────────────── 1010 1012 1210 1212 1232 1234 2101 2121 2123 2321 2323 2343 2345 3210 3212 3232 3234 3432 3434 3454 3456 4321 4323 4343 4345 4543 4545 4565 4567 5432 5434 5454 5456 5654 5656 5676 5678 6543 6545 6565 6567 6765 6767 6787 6789 7654 7656 7676 7678 7876 7878 7898 8765 8767 8787 8789 8987 8989 9876 9878 9898 61 esthetic numbers listed.
Ring
basePlus = []
decList = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
baseList = ["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"]
for base = 2 to 16
see "Base " + base + ": " + (base*4) + "th to " + (base*6) + "th esthetic numbers:" + nl
res = 0
binList = []
for n = 1 to 10000
str = decimaltobase(n,base)
limit1 = base*4
limit2 = base*6
ln = len(str)
flag = 0
for m = 1 to ln-1
nr1 = str[m]
ind1 = find(baseList,nr1)
num1 = decList[ind1]
nr2 = str[m+1]
ind2 = find(baseList,nr2)
num2 = decList[ind2]
num = num1-num2
if num = 1 or num = -1
flag = flag + 1
ok
next
if flag = ln - 1
res = res + 1
if res > (limit1 - 1) and res < (limit2 + 1)
see " " + str
ok
if base = 10 and number(str) > 1000 and number(str) < 9999
add(basePlus,str)
ok
ok
next
see nl + nl
next
see "Base 10: " + len(basePlus) +" esthetic numbers between 1000 and 9999:"
for row = 1 to len(basePlus)
if (row-1) % 16 = 0
see nl
else
see " " + basePlus[row]
ok
next
func decimaltobase(nr,base)
binList = []
binary = 0
remainder = 1
while(nr != 0)
remainder = nr % base
ind = find(decList,remainder)
rem = baseList[ind]
add(binList,rem)
nr = floor(nr/base)
end
binlist = reverse(binList)
binList = list2str(binList)
binList = substr(binList,nl,"")
return binList
- Output:
Base 2: 8th to 12th esthetic numbers: 10101010 101010101 1010101010 10101010101 101010101010 Base 3: 12th to 18th esthetic numbers: 1210 1212 2101 2121 10101 10121 12101 Base 4: 16th to 24th esthetic numbers: 323 1010 1012 1210 1212 1232 2101 2121 2123 Base 5: 20th to 30th esthetic numbers: 323 343 432 434 1010 1012 1210 1212 1232 1234 2101 Base 6: 24th to 36th esthetic numbers: 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234 Base 7: 28th to 42th esthetic numbers: 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232 Base 8: 32th to 48th esthetic numbers: 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212 Base 9: 36th to 54th esthetic numbers: 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210 Base 10: 40th to 60th esthetic numbers: 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012 Base 11: 44th to 66th esthetic numbers: 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 A98 A9A 1010 Base 12: 48th to 72th esthetic numbers: 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA BA9 BAB Base 13: 52th to 78th esthetic numbers: 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB CBA Base 14: 56th to 84th esthetic numbers: 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC Base 15: 60th to 90th esthetic numbers: 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC CDE DCB DCD Base 16: 64th to 96th esthetic numbers: 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC CDE DCB DCD DED DEF EDC Base 10: 61 esthetic numbers between 1000 and 9999: 1012 1210 1212 1232 1234 2101 2121 2123 2321 2323 2343 2345 3210 3212 3232 3432 3434 3454 3456 4321 4323 4343 4345 4543 4545 4565 4567 5432 5434 5454 5654 5656 5676 5678 6543 6545 6565 6567 6765 6767 6787 6789 7654 7656 7676 7876 7878 7898 8765 8767 8787 8789 8987 8989 9876 9878 9898
RPL
No brute force here, but a step-by-step generation, starting from a seed made up of the list of the digits of the base.
Task is accomplished in 999 seconds - precisely - on a basic HP-28S (4-bit CPU, 32 Mb RAM), but just in a few seconds on an iOS-based emulator.
≪ "0123456789ABCDEF" 1 3 PICK SUB → deb fin base digits ≪ { } 2 base FOR j digits j DUP SUB + NEXT 1 DO DUP2 GET digits OVER DUP SIZE DUP SUB POS → idx nbr pos ≪ IF pos 1 ≠ THEN nbr digits pos 1 - DUP SUB + + END IF pos base ≠ THEN nbr digits pos 1 + DUP SUB + + END idx ≫ 1 + UNTIL DUP fin ≥ END DROP deb fin SUB ≫ ≫ 'ESTIC' STO ≪ 2 16 FOR b b 4 * b 6 * b ESTIC NEXT 59 119 10 ESTIC ≫ 'TASK' STO
- Output:
16: { "10101010" "101010101" "1010101010" "10101010101" "101010101010" } 15: { "1210" "1212" "2101" "2121" "10101" "10121" "12101" } 14: { "323" "1010" "1012" "1210" "1212" "1232" "2101" "2121" "2123" } 13: { "323" "343" "432" "434" "1010" "1012" "1210" "1212" "1232" "1234" "2101" } 12: { "343" "345" "432" "434" "454" "543" "545" "1010" "1012" "1210" "1212" "1232" "1234" } 11: { "345" "432" "434" "454" "456" "543" "545" "565" "654" "656" "1010" "1012" "1210" "1212" "1232" } 10: { "432" "434" "454" "456" "543" "545" "565" "567" "654" "656" "676" "765" "767" "1010" "1012" "1210" "1212" } 9: { "434" "454" "456" "543" "545" "565" "567" "654" "656" "676" "678" "765" "767" "787" "876" "878" "1010" "1012" "1210" } 8: { "454" "456" "543" "545" "565" "567" "654" "656" "676" "678" "765" "767" "787" "789" "876" "878" "898" "987" "989" "1010" "1012" } 7: { "456" "543" "545" "565" "567" "654" "656" "676" "678" "765" "767" "787" "789" "876" "878" "898" "89A" "987" "989" "9A9" "A98" "A9A" "1010" } 6: { "543" "545" "565" "567" "654" "656" "676" "678" "765" "767" "787" "789" "876" "878" "898" "89A" "987" "989" "9A9" "9AB" "A98" "A9A" "ABA" "BA9" "BAB" } 5: { "545" "565" "567" "654" "656" "676" "678" "765" "767" "787" "789" "876" "878" "898" "89A" "987" "989" "9A9" "9AB" "A98" "A9A" "ABA" "ABC" "BA9" "BAB" "BCB" "CBA" } 4: { "565" "567" "654" "656" "676" "678" "765" "767" "787" "789" "876" "878" "898" "89A" "987" "989" "9A9" "9AB" "A98" "A9A" "ABA" "ABC" "BA9" "BAB" "BCB" "BCD" "CBA" "CBC" "CDC" } 3: { "567" "654" "656" "676" "678" "765" "767" "787" "789" "876" "878" "898" "89A" "987" "989" "9A9" "9AB" "A98" "A9A" "ABA" "ABC" "BA9" "BAB" "BCB" "BCD" "CBA" "CBC" "CDC" "CDE" "DCB" "DCD" } 2: { "654" "656" "676" "678" "765" "767" "787" "789" "876" "878" "898" "89A" "987" "989" "9A9" "9AB" "A98" "A9A" "ABA" "ABC" "BA9" "BAB" "BCB" "BCD" "CBA" "CBC" "CDC" "CDE" "DCB" "DCD" "DED" "DEF" "EDC" } 1: { "1010" "1012" "1210" "1212" "1232" "1234" "2101" "2121" "2123" "2321" "2323" "2343" "2345" "3210" "3212" "3232" "3234" "3432" "3434" "3454" "3456" "4321" "4323" "4343" "4345" "4543" "4545" "4565" "4567" "5432" "5434" "5454" "5456" "5654" "5656" "5676" "5678" "6543" "6545" "6565" "6567" "6765" "6767" "6787" "6789" "7654" "7656" "7676" "7678" "7876" "7878" "7898" "8765" "8767" "8787" "8789" "8987" "8989" "9876" "9878" "9898" }
Ruby
def isEsthetic(n, b)
if n == 0 then
return false
end
i = n % b
n2 = (n / b).floor
while n2 > 0
j = n2 % b
if (i - j).abs != 1 then
return false
end
n2 = n2 / b
i = j
end
return true
end
def listEsths(n, n2, m, m2, perLine, all)
esths = Array.new
dfs = lambda {|n, m, i|
if n <= i and i <= m then
esths << i
end
if i == 0 or i > m then
return
end
d = i % 10
i1 = i * 10 + d - 1
i2 = i1 + 2
if d == 0 then
dfs[n, m, i2]
elsif d == 9 then
dfs[n, m, i1]
else
dfs[n, m, i1]
dfs[n, m, i2]
end
}
for i in 0..9
dfs[n2, m2, i]
end
le = esths.length
print "Base 10: %d esthetic numbers between %d and %d:\n" % [le, n, m]
if all then
esths.each_with_index { |esth, idx|
print "%d " % [esth]
if (idx + 1) % perLine == 0 then
print "\n"
end
}
print "\n"
else
for i in 0 .. perLine - 1
print "%d " % [esths[i]]
end
print "\n............\n"
for i in le - perLine .. le - 1
print "%d " % [esths[i]]
end
print "\n"
end
print "\n"
end
def main
for b in 2..16
print "Base %d: %dth to %dth esthetic numbers:\n" % [b, 4 * b, 6 * b]
n = 1
c = 0
while c < 6 * b
if isEsthetic(n, b) then
c = c + 1
if c >= 4 * b then
print "%s " % [n.to_s(b)]
end
end
n = n + 1
end
print "\n"
end
print "\n"
listEsths(1000, 1010, 9999, 9898, 16, true)
listEsths(1e8, 101010101, 13 * 1e7, 123456789, 9, true)
listEsths(1e11, 101010101010, 13 * 1e10, 123456789898, 7, false)
listEsths(1e14, 101010101010101, 13 * 1e13, 123456789898989, 5, false)
listEsths(1e17, 101010101010101010, 13 * 1e16, 123456789898989898, 4, false)
end
main()
- Output:
Base 2: 8th to 12th esthetic numbers: 10101010 101010101 1010101010 10101010101 101010101010 Base 3: 12th to 18th esthetic numbers: 1210 1212 2101 2121 10101 10121 12101 Base 4: 16th to 24th esthetic numbers: 323 1010 1012 1210 1212 1232 2101 2121 2123 Base 5: 20th to 30th esthetic numbers: 323 343 432 434 1010 1012 1210 1212 1232 1234 2101 Base 6: 24th to 36th esthetic numbers: 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234 Base 7: 28th to 42th esthetic numbers: 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232 Base 8: 32th to 48th esthetic numbers: 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212 Base 9: 36th to 54th esthetic numbers: 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210 Base 10: 40th to 60th esthetic numbers: 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012 Base 11: 44th to 66th esthetic numbers: 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 a98 a9a 1010 Base 12: 48th to 72th esthetic numbers: 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba ba9 bab Base 13: 52th to 78th esthetic numbers: 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb cba Base 14: 56th to 84th esthetic numbers: 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc Base 15: 60th to 90th esthetic numbers: 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd Base 16: 64th to 96th esthetic numbers: 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd ded def edc Base 10: 61 esthetic numbers between 1000 and 9999: 1010 1012 1210 1212 1232 1234 2101 2121 2123 2321 2323 2343 2345 3210 3212 3232 3234 3432 3434 3454 3456 4321 4323 4343 4345 4543 4545 4565 4567 5432 5434 5454 5456 5654 5656 5676 5678 6543 6545 6565 6567 6765 6767 6787 6789 7654 7656 7676 7678 7876 7878 7898 8765 8767 8787 8789 8987 8989 9876 9878 9898 Base 10: 126 esthetic numbers between 100000000 and 130000000: 101010101 101010121 101010123 101012101 101012121 101012123 101012321 101012323 101012343 101012345 101210101 101210121 101210123 101212101 101212121 101212123 101212321 101212323 101212343 101212345 101232101 101232121 101232123 101232321 101232323 101232343 101232345 101234321 101234323 101234343 101234345 101234543 101234545 101234565 101234567 121010101 121010121 121010123 121012101 121012121 121012123 121012321 121012323 121012343 121012345 121210101 121210121 121210123 121212101 121212121 121212123 121212321 121212323 121212343 121212345 121232101 121232121 121232123 121232321 121232323 121232343 121232345 121234321 121234323 121234343 121234345 121234543 121234545 121234565 121234567 123210101 123210121 123210123 123212101 123212121 123212123 123212321 123212323 123212343 123212345 123232101 123232121 123232123 123232321 123232323 123232343 123232345 123234321 123234323 123234343 123234345 123234543 123234545 123234565 123234567 123432101 123432121 123432123 123432321 123432323 123432343 123432345 123434321 123434323 123434343 123434345 123434543 123434545 123434565 123434567 123454321 123454323 123454343 123454345 123454543 123454545 123454565 123454567 123456543 123456545 123456565 123456567 123456765 123456767 123456787 123456789 Base 10: 911 esthetic numbers between 100000000000 and 130000000000: 101010101010 101010101012 101010101210 101010101212 101010101232 101010101234 101010121010 ............ 123456787678 123456787876 123456787878 123456787898 123456789876 123456789878 123456789898 Base 10: 6225 esthetic numbers between 100000000000000 and 130000000000000: 101010101010101 101010101010121 101010101010123 101010101012101 101010101012121 ............ 123456789898767 123456789898787 123456789898789 123456789898987 123456789898989 Base 10: 44744 esthetic numbers between 100000000000000000 and 130000000000000000: 101010101010101010 101010101010101012 101010101010101210 101010101010101212 ............ 123456789898987898 123456789898989876 123456789898989878 123456789898989898
Rust
// [dependencies]
// radix_fmt = "1.0"
// Returns the next esthetic number in the given base after n, where n is an
// esthetic number in that base or one less than a power of base.
fn next_esthetic_number(base: u64, n: u64) -> u64 {
if n + 1 < base {
return n + 1;
}
let mut a = n / base;
let mut b = a % base;
if n % base + 1 == b && b + 1 < base {
return n + 2;
}
a = next_esthetic_number(base, a);
b = a % base;
a * base + if b == 0 { 1 } else { b - 1 }
}
fn print_esthetic_numbers(min: u64, max: u64, numbers_per_line: usize) {
let mut numbers = Vec::new();
let mut n = next_esthetic_number(10, min - 1);
while n <= max {
numbers.push(n);
n = next_esthetic_number(10, n);
}
let count = numbers.len();
println!(
"Esthetic numbers in base 10 between {} and {} ({}):",
min, max, count
);
if count > 200 {
for i in 0..numbers_per_line {
if i != 0 {
print!(" ");
}
print!("{}", numbers[i]);
}
println!("\n............\n");
for i in 0..numbers_per_line {
if i != 0 {
print!(" ");
}
print!("{}", numbers[count - numbers_per_line + i]);
}
println!();
} else {
for i in 0..count {
print!("{}", numbers[i]);
if (i + 1) % numbers_per_line == 0 {
println!();
} else {
print!(" ");
}
}
if count % numbers_per_line != 0 {
println!();
}
}
}
fn main() {
for base in 2..=16 {
let min = base * 4;
let max = base * 6;
println!(
"Esthetic numbers in base {} from index {} through index {}:",
base, min, max
);
let mut n = 0;
for index in 1..=max {
n = next_esthetic_number(base, n);
if index >= min {
print!("{} ", radix_fmt::radix(n, base as u8));
}
}
println!("\n");
}
let mut min = 1000;
let mut max = 9999;
print_esthetic_numbers(min, max, 16);
println!();
min = 100000000;
max = 130000000;
print_esthetic_numbers(min, max, 8);
println!();
for i in 0..3 {
min *= 1000;
max *= 1000;
let numbers_per_line = match i {
0 => 7,
1 => 5,
_ => 4,
};
print_esthetic_numbers(min, max, numbers_per_line);
println!();
}
}
- Output:
Esthetic numbers in base 2 from index 8 through index 12: 10101010 101010101 1010101010 10101010101 101010101010 Esthetic numbers in base 3 from index 12 through index 18: 1210 1212 2101 2121 10101 10121 12101 Esthetic numbers in base 4 from index 16 through index 24: 323 1010 1012 1210 1212 1232 2101 2121 2123 Esthetic numbers in base 5 from index 20 through index 30: 323 343 432 434 1010 1012 1210 1212 1232 1234 2101 Esthetic numbers in base 6 from index 24 through index 36: 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234 Esthetic numbers in base 7 from index 28 through index 42: 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232 Esthetic numbers in base 8 from index 32 through index 48: 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212 Esthetic numbers in base 9 from index 36 through index 54: 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210 Esthetic numbers in base 10 from index 40 through index 60: 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012 Esthetic numbers in base 11 from index 44 through index 66: 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 a98 a9a 1010 Esthetic numbers in base 12 from index 48 through index 72: 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba ba9 bab Esthetic numbers in base 13 from index 52 through index 78: 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb cba Esthetic numbers in base 14 from index 56 through index 84: 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc Esthetic numbers in base 15 from index 60 through index 90: 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd Esthetic numbers in base 16 from index 64 through index 96: 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd ded def edc Esthetic numbers in base 10 between 1000 and 9999 (61): 1010 1012 1210 1212 1232 1234 2101 2121 2123 2321 2323 2343 2345 3210 3212 3232 3234 3432 3434 3454 3456 4321 4323 4343 4345 4543 4545 4565 4567 5432 5434 5454 5456 5654 5656 5676 5678 6543 6545 6565 6567 6765 6767 6787 6789 7654 7656 7676 7678 7876 7878 7898 8765 8767 8787 8789 8987 8989 9876 9878 9898 Esthetic numbers in base 10 between 100000000 and 130000000 (126): 101010101 101010121 101010123 101012101 101012121 101012123 101012321 101012323 101012343 101012345 101210101 101210121 101210123 101212101 101212121 101212123 101212321 101212323 101212343 101212345 101232101 101232121 101232123 101232321 101232323 101232343 101232345 101234321 101234323 101234343 101234345 101234543 101234545 101234565 101234567 121010101 121010121 121010123 121012101 121012121 121012123 121012321 121012323 121012343 121012345 121210101 121210121 121210123 121212101 121212121 121212123 121212321 121212323 121212343 121212345 121232101 121232121 121232123 121232321 121232323 121232343 121232345 121234321 121234323 121234343 121234345 121234543 121234545 121234565 121234567 123210101 123210121 123210123 123212101 123212121 123212123 123212321 123212323 123212343 123212345 123232101 123232121 123232123 123232321 123232323 123232343 123232345 123234321 123234323 123234343 123234345 123234543 123234545 123234565 123234567 123432101 123432121 123432123 123432321 123432323 123432343 123432345 123434321 123434323 123434343 123434345 123434543 123434545 123434565 123434567 123454321 123454323 123454343 123454345 123454543 123454545 123454565 123454567 123456543 123456545 123456565 123456567 123456765 123456767 123456787 123456789 Esthetic numbers in base 10 between 100000000000 and 130000000000 (911): 101010101010 101010101012 101010101210 101010101212 101010101232 101010101234 101010121010 ............ 123456787678 123456787876 123456787878 123456787898 123456789876 123456789878 123456789898 Esthetic numbers in base 10 between 100000000000000 and 130000000000000 (6225): 101010101010101 101010101010121 101010101010123 101010101012101 101010101012121 ............ 123456789898767 123456789898787 123456789898789 123456789898987 123456789898989 Esthetic numbers in base 10 between 100000000000000000 and 130000000000000000 (44744): 101010101010101010 101010101010101012 101010101010101210 101010101010101212 ............ 123456789898987898 123456789898989876 123456789898989878 123456789898989898
Sidef
func generate_esthetic(root, upto, callback, b=10) {
var v = root.digits2num(b)
return nil if (v > upto)
callback(v)
var t = root.head
__FUNC__([t+1, root...], upto, callback, b) if (t+1 < b)
__FUNC__([t-1, root...], upto, callback, b) if (t-1 >= 0)
}
func between_esthetic(from, upto, b=10) {
gather {
for k in (1..^b) {
generate_esthetic([k], upto, { take(_) if (_ >= from) }, b)
}
}.sort
}
func first_n_esthetic(n, b=10) {
for (var m = n**2; true ; m *= b) {
var list = between_esthetic(1, m, b)
return list.first(n) if (list.len >= n)
}
}
for b in (2..16) {
say "\n#{b}-esthetic numbers with indices #{4*b}..#{6*b}: "
say first_n_esthetic(6*b, b).last(6*b - 4*b + 1).map{.base(b)}.join(' ')
}
say "\nBase 10 esthetic numbers between 1,000 and 9,999:"
between_esthetic(1e3, 1e4).slices(20).each { .join(' ').say }
say "\nBase 10 esthetic numbers between 100,000,000 and 130,000,000:"
between_esthetic(1e8, 13e7).slices(9).each { .join(' ').say }
- Output:
2-esthetic numbers with indices 8..12: 10101010 101010101 1010101010 10101010101 101010101010 3-esthetic numbers with indices 12..18: 1210 1212 2101 2121 10101 10121 12101 4-esthetic numbers with indices 16..24: 323 1010 1012 1210 1212 1232 2101 2121 2123 5-esthetic numbers with indices 20..30: 323 343 432 434 1010 1012 1210 1212 1232 1234 2101 6-esthetic numbers with indices 24..36: 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234 7-esthetic numbers with indices 28..42: 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232 8-esthetic numbers with indices 32..48: 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212 9-esthetic numbers with indices 36..54: 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210 10-esthetic numbers with indices 40..60: 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012 11-esthetic numbers with indices 44..66: 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 a98 a9a 1010 12-esthetic numbers with indices 48..72: 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba ba9 bab 13-esthetic numbers with indices 52..78: 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb cba 14-esthetic numbers with indices 56..84: 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc 15-esthetic numbers with indices 60..90: 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd 16-esthetic numbers with indices 64..96: 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd ded def edc Base 10 esthetic numbers between 1,000 and 9,999: 1010 1012 1210 1212 1232 1234 2101 2121 2123 2321 2323 2343 2345 3210 3212 3232 3234 3432 3434 3454 3456 4321 4323 4343 4345 4543 4545 4565 4567 5432 5434 5454 5456 5654 5656 5676 5678 6543 6545 6565 6567 6765 6767 6787 6789 7654 7656 7676 7678 7876 7878 7898 8765 8767 8787 8789 8987 8989 9876 9878 9898 Base 10 esthetic numbers between 100,000,000 and 130,000,000: 101010101 101010121 101010123 101012101 101012121 101012123 101012321 101012323 101012343 101012345 101210101 101210121 101210123 101212101 101212121 101212123 101212321 101212323 101212343 101212345 101232101 101232121 101232123 101232321 101232323 101232343 101232345 101234321 101234323 101234343 101234345 101234543 101234545 101234565 101234567 121010101 121010121 121010123 121012101 121012121 121012123 121012321 121012323 121012343 121012345 121210101 121210121 121210123 121212101 121212121 121212123 121212321 121212323 121212343 121212345 121232101 121232121 121232123 121232321 121232323 121232343 121232345 121234321 121234323 121234343 121234345 121234543 121234545 121234565 121234567 123210101 123210121 123210123 123212101 123212121 123212123 123212321 123212323 123212343 123212345 123232101 123232121 123232123 123232321 123232323 123232343 123232345 123234321 123234323 123234343 123234345 123234543 123234545 123234565 123234567 123432101 123432121 123432123 123432321 123432323 123432343 123432345 123434321 123434323 123434343 123434345 123434543 123434545 123434565 123434567 123454321 123454323 123454343 123454345 123454543 123454545 123454565 123454567 123456543 123456545 123456565 123456567 123456765 123456767 123456787 123456789
Swift
extension Sequence {
func take(_ n: Int) -> [Element] {
var res = [Element]()
for el in self {
guard res.count != n else {
return res
}
res.append(el)
}
return res
}
}
extension String {
func isEsthetic(base: Int = 10) -> Bool {
zip(dropFirst(0), dropFirst())
.lazy
.allSatisfy({ abs(Int(String($0.0), radix: base)! - Int(String($0.1), radix: base)!) == 1 })
}
}
func getEsthetics(from: Int, to: Int, base: Int = 10) -> [String] {
guard base >= 2, to >= from else {
return []
}
var start = ""
var end = ""
repeat {
if start.count & 1 == 1 {
start += "0"
} else {
start += "1"
}
} while Int(start, radix: base)! < from
let digiMax = String(base - 1, radix: base)
let lessThanDigiMax = String(base - 2, radix: base)
var count = 0
repeat {
if count != base - 1 {
end += String(count + 1, radix: base)
count += 1
} else {
if String(end.last!) == digiMax {
end += lessThanDigiMax
} else {
end += digiMax
}
}
} while Int(end, radix: base)! < to
if Int(start, radix: base)! >= Int(end, radix: base)! {
return []
}
var esthetics = [Int]()
func shimmer(_ n: Int, _ m: Int, _ i: Int) {
if (n...m).contains(i) {
esthetics.append(i)
} else if i == 0 || i > m {
return
}
let d = i % base
let i1 = i &* base &+ d &- 1
let i2 = i1 &+ 2
if (i1 < i || i2 < i) {
// overflow
return
}
switch d {
case 0: shimmer(n, m, i2)
case base-1: shimmer(n, m, i1)
case _:
shimmer(n, m, i1)
shimmer(n, m, i2)
}
}
for digit in 0..<base {
shimmer(Int(start, radix: base)!, Int(end, radix: base)!, digit)
}
return esthetics.filter({ $0 <= to }).map({ String($0, radix: base) })
}
for base in 2...16 {
let esthetics = (0...)
.lazy
.map({ String($0, radix: base) })
.filter({ $0.isEsthetic(base: base) })
.dropFirst(base * 4)
.take((base * 6) - (base * 4) + 1)
print("Base \(base) esthetics from \(base * 4) to \(base * 6)")
print(esthetics)
print()
}
let base10Esthetics = (1000...9999).filter({ String($0).isEsthetic() })
print("\(base10Esthetics.count) esthetics between 1000 and 9999:")
print(base10Esthetics)
print()
func printSlice(of array: [String]) {
print(array.take(5))
print("...")
print(Array(array.lazy.reversed().take(5).reversed()))
print("\(array.count) total\n")
}
print("Esthetics between \(Int(1e8)) and \(13 * Int(1e7)):")
printSlice(of: getEsthetics(from: Int(1e8), to: 13 * Int(1e7)))
print("Esthetics between \(Int(1e11)) and \(13 * Int(1e10))")
printSlice(of: getEsthetics(from: Int(1e11), to: 13 * Int(1e10)))
print("Esthetics between \(Int(1e14)) and \(13 * Int(1e13)):")
printSlice(of: getEsthetics(from: Int(1e14), to: 13 * Int(1e13)))
print("Esthetics between \(Int(1e17)) and \(13 * Int(1e16)):")
printSlice(of: getEsthetics(from: Int(1e17), to: 13 * Int(1e16)))
- Output:
Base 2 esthetics from 8 to 12 ["10101010", "101010101", "1010101010", "10101010101", "101010101010"] Base 3 esthetics from 12 to 18 ["1210", "1212", "2101", "2121", "10101", "10121", "12101"] Base 4 esthetics from 16 to 24 ["323", "1010", "1012", "1210", "1212", "1232", "2101", "2121", "2123"] Base 5 esthetics from 20 to 30 ["323", "343", "432", "434", "1010", "1012", "1210", "1212", "1232", "1234", "2101"] Base 6 esthetics from 24 to 36 ["343", "345", "432", "434", "454", "543", "545", "1010", "1012", "1210", "1212", "1232", "1234"] Base 7 esthetics from 28 to 42 ["345", "432", "434", "454", "456", "543", "545", "565", "654", "656", "1010", "1012", "1210", "1212", "1232"] Base 8 esthetics from 32 to 48 ["432", "434", "454", "456", "543", "545", "565", "567", "654", "656", "676", "765", "767", "1010", "1012", "1210", "1212"] Base 9 esthetics from 36 to 54 ["434", "454", "456", "543", "545", "565", "567", "654", "656", "676", "678", "765", "767", "787", "876", "878", "1010", "1012", "1210"] Base 10 esthetics from 40 to 60 ["454", "456", "543", "545", "565", "567", "654", "656", "676", "678", "765", "767", "787", "789", "876", "878", "898", "987", "989", "1010", "1012"] Base 11 esthetics from 44 to 66 ["456", "543", "545", "565", "567", "654", "656", "676", "678", "765", "767", "787", "789", "876", "878", "898", "89a", "987", "989", "9a9", "a98", "a9a", "1010"] Base 12 esthetics from 48 to 72 ["543", "545", "565", "567", "654", "656", "676", "678", "765", "767", "787", "789", "876", "878", "898", "89a", "987", "989", "9a9", "9ab", "a98", "a9a", "aba", "ba9", "bab"] Base 13 esthetics from 52 to 78 ["545", "565", "567", "654", "656", "676", "678", "765", "767", "787", "789", "876", "878", "898", "89a", "987", "989", "9a9", "9ab", "a98", "a9a", "aba", "abc", "ba9", "bab", "bcb", "cba"] Base 14 esthetics from 56 to 84 ["565", "567", "654", "656", "676", "678", "765", "767", "787", "789", "876", "878", "898", "89a", "987", "989", "9a9", "9ab", "a98", "a9a", "aba", "abc", "ba9", "bab", "bcb", "bcd", "cba", "cbc", "cdc"] Base 15 esthetics from 60 to 90 ["567", "654", "656", "676", "678", "765", "767", "787", "789", "876", "878", "898", "89a", "987", "989", "9a9", "9ab", "a98", "a9a", "aba", "abc", "ba9", "bab", "bcb", "bcd", "cba", "cbc", "cdc", "cde", "dcb", "dcd"] Base 16 esthetics from 64 to 96 ["654", "656", "676", "678", "765", "767", "787", "789", "876", "878", "898", "89a", "987", "989", "9a9", "9ab", "a98", "a9a", "aba", "abc", "ba9", "bab", "bcb", "bcd", "cba", "cbc", "cdc", "cde", "dcb", "dcd", "ded", "def", "edc"] 61 esthetics between 1000 and 9999: [1010, 1012, 1210, 1212, 1232, 1234, 2101, 2121, 2123, 2321, 2323, 2343, 2345, 3210, 3212, 3232, 3234, 3432, 3434, 3454, 3456, 4321, 4323, 4343, 4345, 4543, 4545, 4565, 4567, 5432, 5434, 5454, 5456, 5654, 5656, 5676, 5678, 6543, 6545, 6565, 6567, 6765, 6767, 6787, 6789, 7654, 7656, 7676, 7678, 7876, 7878, 7898, 8765, 8767, 8787, 8789, 8987, 8989, 9876, 9878, 9898] Esthetics between 100000000 and 130000000: ["101010101", "101010121", "101010123", "101012101", "101012121"] ... ["123456567", "123456765", "123456767", "123456787", "123456789"] 126 total Esthetics between 100000000000 and 130000000000 ["101010101010", "101010101012", "101010101210", "101010101212", "101010101232"] ... ["123456787878", "123456787898", "123456789876", "123456789878", "123456789898"] 911 total Esthetics between 100000000000000 and 130000000000000: ["101010101010101", "101010101010121", "101010101010123", "101010101012101", "101010101012121"] ... ["123456789898767", "123456789898787", "123456789898789", "123456789898987", "123456789898989"] 6225 total Esthetics between 100000000000000000 and 130000000000000000: ["101010101010101010", "101010101010101012", "101010101010101210", "101010101010101212", "101010101010101232"] ... ["123456789898987878", "123456789898987898", "123456789898989876", "123456789898989878", "123456789898989898"] 44744 total
Wren
import "./fmt" for Conv, Fmt
var isEsthetic = Fn.new { |n, b|
if (n == 0) return false
var i = n % b
n = (n/b).floor
while (n > 0) {
var j = n % b
if ((i - j).abs != 1) return false
n = (n/b).floor
i = j
}
return true
}
var esths = []
var dfs // recursive function
dfs = Fn.new { |n, m, i|
if (i >= n && i <= m) esths.add(i)
if (i == 0 || i > m) return
var d = i % 10
var i1 = i*10 + d - 1
var i2 = i1 + 2
if (d == 0) {
dfs.call(n, m, i2)
} else if (d == 9) {
dfs.call(n, m, i1)
} else {
dfs.call(n, m, i1)
dfs.call(n, m, i2)
}
}
var listEsths = Fn.new { |n, n2, m, m2, perLine, all|
esths.clear()
for (i in 0..9) dfs.call(n2, m2, i)
var le = esths.count
Fmt.print("Base 10: $,d esthetic numbers between $,d and $,d", le, n, m)
if (all) {
var c = 0
for (esth in esths) {
System.write("%(esth) ")
if ((c+1)%perLine == 0) System.print()
c = c + 1
}
} else {
for (i in 0...perLine) System.write("%(Conv.dec(esths[i])) ")
System.print("\n............\n")
for (i in le-perLine...le) System.write("%(Conv.dec(esths[i])) ")
}
System.print("\n")
}
for (b in 2..16) {
System.print("Base %(b): %(4*b)th to %(6*b)th esthetic numbers:")
var n = 1
var c = 0
while (c < 6*b) {
if (isEsthetic.call(n, b)) {
c = c + 1
if (c >= 4*b) System.write("%(Conv.itoa(n, b)) ")
}
n = n + 1
}
System.print("\n")
}
// the following all use the obvious range limitations for the numbers in question
listEsths.call(1000, 1010, 9999, 9898, 16, true)
listEsths.call(1e8, 101010101, 13*1e7, 123456789, 9, true)
listEsths.call(1e11, 101010101010, 13*1e10, 123456789898, 7, false)
listEsths.call(1e14, 101010101010101, 13*1e13, 123456789898989, 5, false)
- Output:
Base 2: 8th to 12th esthetic numbers: 10101010 101010101 1010101010 10101010101 101010101010 Base 3: 12th to 18th esthetic numbers: 1210 1212 2101 2121 10101 10121 12101 Base 4: 16th to 24th esthetic numbers: 323 1010 1012 1210 1212 1232 2101 2121 2123 Base 5: 20th to 30th esthetic numbers: 323 343 432 434 1010 1012 1210 1212 1232 1234 2101 Base 6: 24th to 36th esthetic numbers: 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234 Base 7: 28th to 42th esthetic numbers: 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232 Base 8: 32th to 48th esthetic numbers: 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212 Base 9: 36th to 54th esthetic numbers: 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210 Base 10: 40th to 60th esthetic numbers: 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012 Base 11: 44th to 66th esthetic numbers: 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 a98 a9a 1010 Base 12: 48th to 72th esthetic numbers: 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba ba9 bab Base 13: 52th to 78th esthetic numbers: 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb cba Base 14: 56th to 84th esthetic numbers: 565 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc Base 15: 60th to 90th esthetic numbers: 567 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd Base 16: 64th to 96th esthetic numbers: 654 656 676 678 765 767 787 789 876 878 898 89a 987 989 9a9 9ab a98 a9a aba abc ba9 bab bcb bcd cba cbc cdc cde dcb dcd ded def edc Base 10: 61 esthetic numbers between 1,000 and 9,999 1010 1012 1210 1212 1232 1234 2101 2121 2123 2321 2323 2343 2345 3210 3212 3232 3234 3432 3434 3454 3456 4321 4323 4343 4345 4543 4545 4565 4567 5432 5434 5454 5456 5654 5656 5676 5678 6543 6545 6565 6567 6765 6767 6787 6789 7654 7656 7676 7678 7876 7878 7898 8765 8767 8787 8789 8987 8989 9876 9878 9898 Base 10: 126 esthetic numbers between 100,000,000 and 130,000,000 101010101 101010121 101010123 101012101 101012121 101012123 101012321 101012323 101012343 101012345 101210101 101210121 101210123 101212101 101212121 101212123 101212321 101212323 101212343 101212345 101232101 101232121 101232123 101232321 101232323 101232343 101232345 101234321 101234323 101234343 101234345 101234543 101234545 101234565 101234567 121010101 121010121 121010123 121012101 121012121 121012123 121012321 121012323 121012343 121012345 121210101 121210121 121210123 121212101 121212121 121212123 121212321 121212323 121212343 121212345 121232101 121232121 121232123 121232321 121232323 121232343 121232345 121234321 121234323 121234343 121234345 121234543 121234545 121234565 121234567 123210101 123210121 123210123 123212101 123212121 123212123 123212321 123212323 123212343 123212345 123232101 123232121 123232123 123232321 123232323 123232343 123232345 123234321 123234323 123234343 123234345 123234543 123234545 123234565 123234567 123432101 123432121 123432123 123432321 123432323 123432343 123432345 123434321 123434323 123434343 123434345 123434543 123434545 123434565 123434567 123454321 123454323 123454343 123454345 123454543 123454545 123454565 123454567 123456543 123456545 123456565 123456567 123456765 123456767 123456787 123456789 Base 10: 911 esthetic numbers between 100,000,000,000 and 130,000,000,000 101010101010 101010101012 101010101210 101010101212 101010101232 101010101234 101010121010 ............ 123456787678 123456787876 123456787878 123456787898 123456789876 123456789878 123456789898 Base 10: 6,225 esthetic numbers between 100,000,000,000,000 and 130,000,000,000,000 101010101010101 101010101010121 101010101010123 101010101012101 101010101012121 ............ 123456789898767 123456789898787 123456789898789 123456789898987 123456789898989
XPL0
proc NumOut(N); \Display N in the current Base
int N, R;
[N:= N/Base;
R:= rem(0);
if N # 0 then NumOut(N);
if Base <= 10 then
ChOut(0, R+^0)
else
ChOut(0, if R < 10 then R+^0 else R-10+^A);
];
func Esthetic(N); \Return 'true' if adjacent digits differ by 1
int N, D, D0;
[N:= N/Base;
D0:= rem(0);
while N # 0 do
[N:= N/Base;
D:= rem(0);
if D = D0 then return false;
if abs(D-D0) > 1 then return false;
D0:= D;
];
return true;
];
int Count, N;
[for Base:= 2 to 16 do
[Text(0, "Base "); IntOut(0, Base); Text(0, ": ");
Count:= 0; N:= 1;
loop [if Esthetic(N) then
[Count:= Count+1;
if Count >= Base*4 then
[NumOut(N); ChOut(0, ^ )];
if Count >= Base*6 then quit;
];
N:= N+1;
];
CrLf(0);
];
Base:= 10;
Text(0, "Base 10 numbers between 1000 and 9999:^m^j");
Count:= 0;
for N:= 1000 to 9999 do
[if Esthetic(N) then
[Count:= Count+1;
NumOut(N); ChOut(0, ^ );
if rem(Count/16) = 0 then CrLf(0);
];
];
CrLf(0);
Text(0, "Base 10 numbers between 1.0e8 and 1.3e8:^m^j");
Count:= 0;
for N:= 100_000_000 to 130_000_000 do
[if Esthetic(N) then
[Count:= Count+1;
NumOut(N); ChOut(0, ^ );
if rem(Count/9) = 0 then CrLf(0);
];
];
]
- Output:
Base 2: 10101010 101010101 1010101010 10101010101 101010101010 Base 3: 1210 1212 2101 2121 10101 10121 12101 Base 4: 323 1010 1012 1210 1212 1232 2101 2121 2123 Base 5: 323 343 432 434 1010 1012 1210 1212 1232 1234 2101 Base 6: 343 345 432 434 454 543 545 1010 1012 1210 1212 1232 1234 Base 7: 345 432 434 454 456 543 545 565 654 656 1010 1012 1210 1212 1232 Base 8: 432 434 454 456 543 545 565 567 654 656 676 765 767 1010 1012 1210 1212 Base 9: 434 454 456 543 545 565 567 654 656 676 678 765 767 787 876 878 1010 1012 1210 Base 10: 454 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 987 989 1010 1012 Base 11: 456 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 A98 A9A 1010 Base 12: 543 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA BA9 BAB Base 13: 545 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB CBA Base 14: 565 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC Base 15: 567 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC CDE DCB DCD Base 16: 654 656 676 678 765 767 787 789 876 878 898 89A 987 989 9A9 9AB A98 A9A ABA ABC BA9 BAB BCB BCD CBA CBC CDC CDE DCB DCD DED DEF EDC Base 10 numbers between 1000 and 9999: 1010 1012 1210 1212 1232 1234 2101 2121 2123 2321 2323 2343 2345 3210 3212 3232 3234 3432 3434 3454 3456 4321 4323 4343 4345 4543 4545 4565 4567 5432 5434 5454 5456 5654 5656 5676 5678 6543 6545 6565 6567 6765 6767 6787 6789 7654 7656 7676 7678 7876 7878 7898 8765 8767 8787 8789 8987 8989 9876 9878 9898 Base 10 numbers between 1.0e8 and 1.3e8: 101010101 101010121 101010123 101012101 101012121 101012123 101012321 101012323 101012343 101012345 101210101 101210121 101210123 101212101 101212121 101212123 101212321 101212323 101212343 101212345 101232101 101232121 101232123 101232321 101232323 101232343 101232345 101234321 101234323 101234343 101234345 101234543 101234545 101234565 101234567 121010101 121010121 121010123 121012101 121012121 121012123 121012321 121012323 121012343 121012345 121210101 121210121 121210123 121212101 121212121 121212123 121212321 121212323 121212343 121212345 121232101 121232121 121232123 121232321 121232323 121232343 121232345 121234321 121234323 121234343 121234345 121234543 121234545 121234565 121234567 123210101 123210121 123210123 123212101 123212121 123212123 123212321 123212323 123212343 123212345 123232101 123232121 123232123 123232321 123232323 123232343 123232345 123234321 123234323 123234343 123234345 123234543 123234545 123234565 123234567 123432101 123432121 123432123 123432321 123432323 123432343 123432345 123434321 123434323 123434343 123434345 123434543 123434545 123434565 123434567 123454321 123454323 123454343 123454345 123454543 123454545 123454565 123454567 123456543 123456545 123456565 123456567 123456765 123456767 123456787 123456789