Skip to content

Instantly share code, notes, and snippets.

@suessflorian
Last active September 12, 2019 20:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save suessflorian/9221a9a6b20521d22ffa65615f11da4d to your computer and use it in GitHub Desktop.
Save suessflorian/9221a9a6b20521d22ffa65615f11da4d to your computer and use it in GitHub Desktop.
import string
CONDITIONS = input()
[N, U, L] = [int(x) for x in CONDITIONS.split(" ")]
K_TH = int(input())
# this conversion here is used for easy sorting, 1, 2, 3 = L, U, N
BIGGEST_PERMU = list('1' * L + '2' * U + '3' * N)
def find_kth(current, k):
if not current:
return []
# we begin by finding the significance of the leftest most digit
tail_numbers, tail_uppers, tail_lowers = current[1:].count('1'), current[1:].count('2'), current[1:].count('3')
digit_significance = 10**tail_numbers * 26**tail_uppers * 26**tail_lowers
# what base this digit has
i = 10 if current[0] == '1' else 26
success = False
while i > 0:
# in decremental order if a digit that fits
if i * digit_significance <= k:
success = True
break
i = i - 1
if success:
# if we manage to actually find such a digit
sub_k = k - i * digit_significance
next = current[1:]
next.sort()
# we build this digit and recursively call the remaining list
return [build_digit(current[0], i)] + find_kth(next, sub_k)
else:
# if we couldn't find such a digit, either we "shuffle" or "hit base"
if current[0] == '2': # U
next_number = current[1:].find('1') + 1 if '1' in current[1:] else 0
# if we can reduce the group somehow then shuffle down
if next_number:
return find_kth(swap(current, 0, next_number), k)
if current[0] == '3': # L
next_upper = current[1:].find('2') + 1 if '2' in current[1:] else 0
if next_upper:
return find_kth(swap(current, 0, next_upper), k)
next_number = current[1:].find('1') + 1 if '2' in current[1:] else 0
if next_number:
return find_kth(swap(current, 0, next_number), k)
# if we simply cannot shuffle down, then we "hit base"
next = current[1:]
next.sort()
# and we recursively call the remaining list
return [build_digit(current[0], i)] + find_kth(next, k)
def swap(l, x, y):
l[x], l[y] = l[y], l[x]
return l
def build_digit(type, index):
if type == '3':
return string.ascii_lowercase[index]
if type == '2':
return string.ascii_uppercase[index]
if type == '1':
return str(index)
print(find_kth(BIGGEST_PERMU, K_TH))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment