def reachable(stepFunction, start, destinations, _alreadyseen=None):
 if ((len(start) == 0) or (len(destinations) == 0)):
  return {}
 if (_alreadyseen is None):
  _alreadyseen = []
 _alreadyseen.extend(start)
 res = {}
 for s in start:
  if (s in destinations):
   res[s] = 0
   start.remove(s)
 new = set()
 for s in start:
  new.update(stepFunction(s))
 new.difference_update(_alreadyseen)
 ndestinations = list(destinations)
 for s in list(new):
  if (s in destinations):
   res[s] = 1
   new.remove(s)
   ndestinations.remove(s)
   _alreadyseen.append(s)
 deeper = reachable(stepFunction, new, ndestinations, _alreadyseen)
 for (k, val) in list(deeper.items()):
  res[k] = (val + 1)
 return res

def reachable ( stepFunction , start , destinations , _alreadyseen = None ) : if ( ( len ( start ) == 0 ) or ( len ( destinations ) == 0 ) ) : return { } if ( _alreadyseen is None ) : _alreadyseen = [ ] _alreadyseen . extend ( start ) res = { } for s in start : if ( s in destinations ) : res [ s ] = 0 start . remove ( s ) new = set ( ) for s in start : new . update ( stepFunction ( s ) ) new . difference_update ( _alreadyseen ) ndestinations = list ( destinations ) for s in list ( new ) : if ( s in destinations ) : res [ s ] = 1 new . remove ( s ) ndestinations . remove ( s ) _alreadyseen . append ( s ) deeper = reachable ( stepFunction , new , ndestinations , _alreadyseen ) for ( k , val ) in list ( deeper . items ( ) ) : res [ k ] = ( val + 1 ) return res
determines the subset of destinations that can be reached from a set of starting positions .