Last active
September 12, 2019 20:45
-
-
Save suessflorian/9221a9a6b20521d22ffa65615f11da4d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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