I'm currently practicing for the british informatics olympiad by doing past papers.
I was doing question 3 of the 2019 paper:
A set of children’s blocks, each illustrated with a single different letter, have been chained together in a line. They have been arranged so that it is not possible to find three (not necessarily adjacent) letters,from left to right, that are in alphabetical order.
Write a program that enumerates block-chains. Your program should input a single integer l (1 ≤ l ≤ 19) indicating that the blocks are illustrated with the first l letters of the alphabet, followed by a word p of between 1 and l uppercase letters indicating (in order) the leftmost letters of the block chain. p will only contain letters take from the first l letters of the alphabet and will not contain any duplicates. You should output a single integer giving the number of possible block-chains that begin with p.
I wrote this code for the question:
from itertools import permutations
from string import ascii_uppercase
def has_alphabetical_substring(s):
for i in range(len(s)):
for j in range(i + 1, len(s)):
if ascii_uppercase.index(s[i]) > ascii_uppercase.index(s[j]):
continue
for k in range(j + 1, len(s)):
if ascii_uppercase.index(s[j]) <= ascii_uppercase.index(s[k]):
return True
return False
def find_legal_block_chains(l, p):
combinations = list(permutations(ascii_uppercase[:l], l))
combinations = [combination for combination in combinations if all(combination[i] == p[i] for i in range(len(p)))]
combinations = [combination for combination in combinations if not has_alphabetical_substring(combination)]
return combinations
l, p = input().split()
print(len(find_legal_block_chains(int(l), p.upper())))
For example, if I input 4 CB
, it prints 2
. More tests which are required to pass can be found on the relevant marks page.
I have tested it against the test cases in the run scheme, and it works, but it's slow and inefficient.
I would be grateful to know any improvements that I could make to this program.
4 PORK
and8 DEADBEEF
run without errors, but return0
without printing. It does work for the sample run provided in the paper (4 CB
returns2
), but a single test-case is quite limited for something like this. Writing a review would be easier with a bigger set of inputs to test on. \$\endgroup\$