'hallway problem - is there a way to solve in python?

hallway problem picture

There is a some rooms and a hallway. Two of the rooms are connected to the hallway. Each of those rooms have one room connected to them. Those have no connections to the hallway. Much easier is you look at this to understand. Anyways.

I have this:

#
def possible_path(lst):
    d = {
        1 : [2],
        2 : [1,"H"],
        "H" : [2,4],
        4 : ["H", 3],
        3 : [4]
    }
    for i in range(len(lst)):
        ele1, ele2 = lst[i-1], lst[i]
        if not ele2 in d[ele1]:
            return False
    return True
#

but its giving me the wrong answer. (possible_path([1, 2, "H", 4, 3]) should output True, but my code outputs false. )

FAILED: False should equal True
ERROR: Traceback:
   in <module>
  File "./frameworks/python/cw-2.py", line 28, in assert_equals
    expect(actual == expected, message, allow_raise)
  File "./frameworks/python/cw-2.py", line 18, in expect
    raise AssertException(message)
cw-2.AssertException: False should equal True

By printing ele1 and ele2 its giving (3,1) when it should be (1,2). Here are all the tests for further verification.

(possible_path([1, 2, "H", 4, 3]), True)
(possible_path(["H", 1, 2]), False)
(possible_path([4, 3, 4, "H", 4, "H"]), True)
(possible_path(["H"]), True)
(possible_path([1]), True)
(possible_path([1, 2, 1]), True)
(possible_path(["H", 2, 1, "H", 2]), False)
(possible_path([3, "H", 2, 1]), False)
(possible_path(["H", 2, 3, "H"]), False)
(possible_path([1, 3, 4]), False)


Solution 1:[1]

You only need to change range(len(lst)) to range(1, len(lst)). This is because when i == 0, the if condition becomes if not lst[0] in d[-1], which you don't want.

def possible_path(lst):
    d = {1: [2], 2: [1,"H"], "H": [2,4], 4: ["H",3], 3: [4]}
    for i in range(1, len(lst)):
        ele1, ele2 = lst[i-1], lst[i]
        if not ele2 in d[ele1]:
            return False
    return True

def verify(a, b):
    print(a == b)

verify(possible_path([1, 2, "H", 4, 3]), True)
verify(possible_path(["H", 1, 2]), False)
verify(possible_path([4, 3, 4, "H", 4, "H"]), True)
verify(possible_path(["H"]), True)
verify(possible_path([1]), True)
verify(possible_path([1, 2, 1]), True)
verify(possible_path(["H", 2, 1, "H", 2]), False)
verify(possible_path([3, "H", 2, 1]), False)
verify(possible_path(["H", 2, 3, "H"]), False)
verify(possible_path([1, 3, 4]), False)

Or using zip (or you could use itertools.pairwise since python 3.10) and all:

def possible_path(lst):
    d = {1: [2], 2: [1,"H"], "H": [2,4], 4: ["H",3], 3: [4]}
    return all(y in d[x] for x, y in zip(lst, lst[1:]))

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 j1-lee