Jump to content

Esthetic numbers: Difference between revisions

no edit summary
(Added Algol 68)
No edit summary
Line 4,387:
123434565 123434567 123454321 123454323 123454343 123454345 123454543 123454545 123454565
123454567 123456543 123456545 123456565 123456567 123456765 123456767 123456787 123456789
</pre>
 
=={{header|Python}}==
 
{{works with|Python|3.9.5}}
<lang python>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():
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):
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)
 
</lang>
 
{{out}}
<pre>
======
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
</pre>
 
2

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.