# Tutorial 11 — DP state design# Python 3, standard library only. No installation beyond Python is needed.# Q01, Q05 and Q09 are written questions on the webpage.# Complete one function, then run: python3 dp_states.py 2# Q07/Q08 depend on Q06. Q11/Q15 depend on Q10.# The default command checks the nine core coding/debugging questions.def stairs_memo(n): # Q02: create memo once, outside the recursive helper. # Cache by remaining steps; return the helper's result. raise NotImplementedError("Q02")def stairs_table(n): # Q03: initialize the base case, then fill in dependency order. raise NotImplementedError("Q03")def stairs_blocked(n, blocked): # Q04: this code is wrong. Repair its base cases and blocked states. table = [1] * (n + 1) for k in range(2, n + 1): if k not in blocked: table[k] = table[k - 1] + table[k - 2] return table[n]def lis_ending(values): # Q06: one state per endpoint; compare all valid earlier endpoints. raise NotImplementedError("Q06")def lis_sequence(values): # Q07: recover a path through the endpoint states. raise NotImplementedError("Q07")def lis_length(values): dp = lis_ending(values) # Q08: this return is wrong. return dp[-1]def lcs_table(a, b): # Q10: base row/column = 0; then match or skip one ending character. raise NotImplementedError("Q10")def lcs_sequence(a, b): # Q11: walk backward; reverse the collected characters at the end. raise NotImplementedError("Q11")def lcs_memo(a, b): memo = {} def solve(i, j): if i == 0 or j == 0: return 0 # Q12: the cache key below is incomplete. if i not in memo: if a[i - 1] == b[j - 1]: memo[i] = 1 + solve(i - 1, j - 1) else: memo[i] = max(solve(i - 1, j), solve(i, j - 1)) return memo[i] return solve(len(a), len(b))def lis_count(values): # Q13: a better length replaces the count; an equal length adds to it. raise NotImplementedError("Q13")def max_sum_increasing(values): # Q14: still end at i, but store sum rather than length. raise NotImplementedError("Q14")def deletions_to_match(a, b): # Q15: first find the longest sequence both strings can keep. raise NotImplementedError("Q15")def lcs_length_small_space(a, b): # Q16: use the shorter string for columns; rebuild the current row. raise NotImplementedError("Q16")# Checks — keep below your functions.def check_q02(): assert [stairs_memo(n) for n in range(8)] == [1, 1, 2, 3, 5, 8, 13, 21] assert stairs_memo(30) == 1346269 assert stairs_memo(3) == 3def check_q03(): assert stairs_table(0) == [1] assert stairs_table(1) == [1, 1] assert stairs_table(6) == [1, 1, 2, 3, 5, 8, 13]def check_q04(): assert stairs_blocked(0, set()) == 1 assert stairs_blocked(1, {1}) == 0 assert stairs_blocked(2, {1}) == 1 assert stairs_blocked(4, {2}) == 1 assert stairs_blocked(5, {3}) == 2 assert stairs_blocked(3, {3}) == 0def check_q06(): assert lis_ending([]) == [] assert lis_ending([2, 2, 2]) == [1, 1, 1] assert lis_ending([9, 7, 5]) == [1, 1, 1] assert lis_ending([1, 2, 3, 0]) == [1, 2, 3, 1] values = [3, 1, 2, 5, 4, 6] original = values[:] assert lis_ending(values) == [1, 1, 2, 3, 3, 4] assert values == originaldef check_q07(): for values, length in [([], 0), ([2,2,2], 1), ([1,2,3,0], 3), ([3,1,2,5,4,6], 4)]: original = values[:] answer = lis_sequence(values) assert len(answer) == length assert all(x < y for x, y in zip(answer, answer[1:])) stream = iter(values) assert all(any(v == x for v in stream) for x in answer) assert values == originaldef check_q08(): assert lis_length([]) == 0 assert lis_length([1,2,3,0]) == 3 assert lis_length([4,3,2]) == 1 assert lis_length([2,2,2]) == 1def check_q10(): assert lcs_table('', '') == [[0]] assert lcs_table('AB', '') == [[0], [0], [0]] assert lcs_table('ABC', 'AC') == [[0,0,0],[0,1,1],[0,1,1],[0,1,2]] assert lcs_table('AB', 'BA')[-1][-1] == 1 assert lcs_table('ABCBDAB', 'BDCABA')[-1][-1] == 4 table = lcs_table('AA', 'A') assert table[0] is not table[1]def check_q11(): for a, b, length in [('', 'ABC', 0), ('ABC','AC',2), ('AB','BA',1), ('ABCBDAB','BDCABA',4)]: answer = lcs_sequence(a, b) assert isinstance(answer, str) and len(answer) == length for source in (a, b): stream = iter(source) assert all(any(c == x for c in stream) for x in answer)def check_q12(): for a, b, expected in [('', '', 0), ('AB','CD',0), ('ABC','AC',2), ('ABCBDAB','BDCABA',4), ('ABBA','BAAB',2)]: assert lcs_memo(a, b) == expected, (a, b) assert lcs_memo('AAAA', 'AA') == 2 assert lcs_memo('X', 'Y') == 0def check_q13(): assert lis_count([]) == 0 assert lis_count([2,2,2]) == 3 assert lis_count([1,3,5,4,7]) == 2 assert lis_count([1,2,3]) == 1 assert lis_count([1,2,1,2]) == 3def check_q14(): assert max_sum_increasing([]) == 0 assert max_sum_increasing([4,1,2,6]) == 10 assert max_sum_increasing([-3,-1]) == -1 assert max_sum_increasing([2,2]) == 2def check_q15(): assert deletions_to_match('sea', 'eat') == 2 assert deletions_to_match('', 'ABC') == 3 assert deletions_to_match('same', 'same') == 0 assert deletions_to_match('AB', 'CD') == 4def check_q16(): assert lcs_length_small_space('', 'ABC') == 0 assert lcs_length_small_space('ABC', '') == 0 assert lcs_length_small_space('AA', 'A') == 1 assert lcs_length_small_space('ABCBDAB', 'BDCABA') == 4 assert lcs_length_small_space('ABCDE', 'ACE') == 3import sysCHECKS = {2: check_q02, 3: check_q03, 4: check_q04, 6: check_q06, 7: check_q07, 8: check_q08, 10: check_q10, 11: check_q11, 12: check_q12, 13: check_q13, 14: check_q14, 15: check_q15, 16: check_q16}GROUPS = { "memo": [2, 3, 4], "lis": [6, 7, 8], "lcs": [10, 11, 12], "extra": [13, 14, 15, 16], "core": [2, 3, 4, 6, 7, 8, 10, 11, 12], "all": sorted(CHECKS),}if __name__ == "__main__": stage = sys.argv[1] if len(sys.argv) > 1 else "core" if stage.isdigit() and int(stage) in CHECKS: selected = [int(stage)] elif stage in GROUPS: selected = GROUPS[stage] else: print("Choose memo, lis, lcs, extra, core, all, or a coding question number.") sys.exit(2) for number in selected: try: CHECKS[number]() except Exception as error: print(f"Q{number:02d} failed: {type(error).__name__}: {error}") print("Check this question and its listed dependencies, then try again.") sys.exit(1) print(f"Q{number:02d} passed.") print(f"{stage}: {len(selected)}/{len(selected)} checks passed.")