tidied up the algorithm a bit