|
- #!/usr/bin/env python3
- import itertools
- import sys
-
-
- def decimal_to_alphabet(n: int, alphabet: str) -> str:
- if n == 0:
- return alphabet[0]
- base = len(alphabet)
- digits = []
- while n:
- digits.append(alphabet[n % base])
- n //= base
- return ''.join(digits[::-1])
-
-
- def alphabet_to_decimal(s: str, alphabet: str) -> int:
- base = len(alphabet)
- l = len(s)
- return sum(alphabet.index(s[l - 1 - i]) * base ** i for i in range(l))
-
-
- def test():
- assert alphabet_to_decimal('ff', '0123456789abcdef') == 255
- assert alphabet_to_decimal('100', '0123456789abcdef') == 256
- assert decimal_to_alphabet(255, '0123456789abcdef') == 'ff'
- assert decimal_to_alphabet(256, '0123456789abcdef') == '100'
- assert decimal_to_alphabet(0, '0123456789') == '0'
-
-
- def convert_start_stop(s, alphabet):
- if ':' in s:
- valalphabet, value = s.split(':')
- if not valalphabet:
- valalphabet = alphabet
- else:
- valalphabet, value = '0123456789', s
- return alphabet_to_decimal(value, valalphabet)
-
-
- if __name__ == '__main__':
- if len(sys.argv) == 2 and sys.argv[1] == '--test':
- test()
- elif len(sys.argv) in (3, 4):
- if len(sys.argv) == 3:
- sys.argv.append(sys.argv[-1])
- alphabet = sys.argv[1]
- start, stop = map(lambda x: convert_start_stop(x, alphabet), sys.argv[2:])
- for i in range(start, stop + 1):
- try:
- sys.stdout.write(decimal_to_alphabet(i, alphabet) + '\n')
- except (BrokenPipeError, IOError):
- try:
- sys.stdout.close()
- except IOError:
- pass
- break
- else:
- print('Usage: alphabetseq ALPHABET START [STOP]', file = sys.stderr)
- print('Generates the sequence from START to STOP (inclusive) using ALPHABET', file = sys.stderr)
- print('If STOP is omitted, it defaults to START, effectively making this a simple base transformation', file = sys.stderr)
- print('START and STOP have values of the form [[VALALPHABET]:]VALUE.', file = sys.stderr)
- print(' In the [VALALPHABET]:VALUE form, VALUE is expressed in terms of VALALPHABET, which defaults to ALPHABET if omitted.', file = sys.stderr)
- print(' In the VALUE form, it is treated as a decimal number.', file = sys.stderr)
- sys.exit(1)
|