import pprint import itertools import fileinput nodes = [] edges = [] for raw in fileinput.input(): line = raw.strip() if line == '': continue [a,b] = line.split('-') nodes += [a, b] edges.append((a, b)) nodes = list(set(nodes)) nodes.sort() graph = [[0 for j in range(len(nodes))] for i in range(len(nodes))] #pprint.pprint(graph) for (a,b) in edges: i, j = nodes.index(a), nodes.index(b) graph[i][j] = 1 graph[j][i] = 1 visit_only_once = [e for e in nodes if e.lower() == e and e != 'start' and e != 'end'] start_index = nodes.index('start') end_index = nodes.index('end') nodes_d = [(i,e) for i,e in enumerate(nodes)] print(f'{nodes_d=}') print(f'{visit_only_once=}') visit_only_once_index = [nodes.index(e) for e in visit_only_once]+[start_index, end_index] def explore_path(stack, level, locked, s, did_visit_twice): edges = [i for i,e in enumerate(graph[s]) if e] if s == end_index: return [s] + [stack] paths = [] for edge in edges: if edge == start_index: continue if edge in visit_only_once_index: if edge in locked: if not did_visit_twice and edge != start_index and edge != end_index: did_visit_twice = True else: continue locked.add(edge) #print(f'{level=} , {nodes[edge]=}, {new_locked=}, {at_most=} ') paths += explore_path([s]+stack, level+1, locked.copy(), edge, did_visit_twice) return paths print('start exploring...') paths = explore_path([], 0, set(), start_index, False) all_paths = [ ''.join(map(str, p)) for p in paths ] res = list(set(all_paths)) for p in res: new_p = list(map(int, list(p))) #print([ nodes[i] for i in list(reversed(new_p))]) #print(res) print(f'There are {len(res)} paths')