
'''simple docstring'''
import numpy as np







def 		A_(     A						:		str		,     A						:		Optional[Any]		,     A						:		Tuple		,     A						:		Optional[int]		,     A						:		str):
							UpperCamelCase   			=     int(np.ceil((x_end - xa) / h))
							UpperCamelCase   			=     np.zeros((n + 1,))
							UpperCamelCase   			=     ya
							UpperCamelCase   			=     xa

							for k in range(A):
														UpperCamelCase   			=     f(A		,     y[k])
														UpperCamelCase   			=     f(x + 0.5 * h		,     y[k] + 0.5 * h * ka)
														UpperCamelCase   			=     f(x + 0.5 * h		,     y[k] + 0.5 * h * ka)
														UpperCamelCase   			=     f(x + h		,     y[k] + h * ka)
														UpperCamelCase   			=     y[k] + (1 / 6) * h * (ka + 2 * ka + 2 * ka + ka)
														x += h

							return y


if __name__ == "__main__":
						import doctest

						doctest.testmod()






'''simple docstring'''
lowerCAmelCase					:    Optional[Any]           = {
    'A': ['B', 'C', 'E'],
    'B': ['A', 'D', 'E'],
    'C': ['A', 'F', 'G'],
    'D': ['B'],
    'E': ['A', 'B', 'D'],
    'F': ['C'],
    'G': ['C'],
}







def 		A_(     A						:		dict		,     A						:		str		,     A						:		Optional[Any]):
							UpperCamelCase   			=     set()
							# keep track of all the paths to be checked
							UpperCamelCase   			=     [[start]]

							# return path if start is goal
							if start == goal:
														return [start]

							# keeps looping until all possible paths have been checked
							while queue:
														# pop the first path from the queue
														UpperCamelCase   			=     queue.pop(0)
														# get the last node from the path
														UpperCamelCase   			=     path[-1]
														if node not in explored:
																					UpperCamelCase   			=     graph[node]
																					# go through all neighbour nodes, construct a new path and
																					# push it into the queue
																					for neighbour in neighbours:
																												UpperCamelCase   			=     list(A)
																												new_path.append(A)
																												queue.append(A)
																												# return path if neighbour is goal
																												if neighbour == goal:
																																			return new_path

            # mark node as explored
																					explored.add(A)

    # in case there's no path between the 2 nodes
							return []







def 		A_(     A						:		dict		,     A						:		str		,     A						:		Tuple):
							if not graph or start not in graph or target not in graph:
														return -1
							if start == target:
														return 0
							UpperCamelCase   			=     [start]
							UpperCamelCase   			=     set(A)
							# Keep tab on distances from `start` node.
							UpperCamelCase   			=     {start: 0, target: -1}
							while queue:
														UpperCamelCase   			=     queue.pop(0)
														if node == target:
																					UpperCamelCase   			=     (
																					    dist[node] if dist[target] == -1 else min(dist[target]		,     dist[node])
																					)
														for adjacent in graph[node]:
																					if adjacent not in visited:
																												visited.add(A)
																												queue.append(A)
																												UpperCamelCase   			=     dist[node] + 1
							return dist[target]


if __name__ == "__main__":
						print(bfs_shortest_path(demo_graph, 'G', 'D'))  # returns ['G', 'C', 'A', 'B', 'D']
						print(bfs_shortest_path_distance(demo_graph, 'G', 'D'))  # returns 4




