I didn't store the step number, so rather than recode to do so, I added a method to my Memory() class to cycle on from the current value until it saw that hash again. This works because the internal state of my machine is already in a value in the cycle when the part 1 code finishes.
I also added an automated test for the new method.
I then spent an age trying to work out why my cycle_length() method wasn't terminating on the test data, only to realise that in my test I had failed to do the "setup" step of solving Part 1 in the test object instance first, so it was waiting for the memory banks to return to the test case initial value, which isn't in the cycle so it never will