You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							100 lines
						
					
					
						
							2.1 KiB
						
					
					
				
			
		
		
	
	
							100 lines
						
					
					
						
							2.1 KiB
						
					
					
				| "use strict"; | |
|  | |
| function main(formName) { | |
| 	let result = document.getElementById("result"); | |
| 	 | |
| 	let arr = document.forms[formName].elements[0].value; | |
| 	arr = arr.trim().split(" "); | |
| 	let checkResult = arr.some( elem => isNotNumber(elem) ); | |
| 	if (checkResult) { | |
| 		result.textContent = "Ошибка: arr должен содержать только целые числа, разделенные пробелом!"; | |
| 		return; | |
| 	} else { | |
| 		arr = arr.map( elem => Number(elem) ); | |
| 	} | |
|  | |
| 	let graph = createGraph(arr); | |
| 	let path = findPath(graph); | |
| 	 | |
| 	if (path == undefined) { | |
| 		result.textContent = "Результат: путь не найден"; | |
| 		return; | |
| 	} | |
| 	 | |
| 	path[0] = "Start"; | |
| 	path[path.length - 1] = "End"; | |
| 	result.textContent = "Результат: " + path.join(" > ") + ". Длина пути: " + path.length; | |
| } | |
|  | |
| function createGraph(arr) { | |
| 	let result = []; | |
| 	 | |
| 	// Добавляем узлы берегов | |
| 	arr.unshift(1); | |
| 	arr.push(0); | |
|  | |
| 	length = arr.length; | |
| 	arr.forEach( (elem, index) => { | |
| 			result[index] = { | |
| 				prev: undefined, | |
| 				dist: Number.POSITIVE_INFINITY, | |
| 				visited: false, | |
| 				childs: [] | |
| 			}; | |
|  | |
| 			if (elem <= index) { | |
| 				result[index].childs.push(index - elem); | |
| 			} | |
|  | |
| 			let forwardIndex = elem >= (length - index) ? length - 1 : index + elem; | |
| 			result[index].childs.push(forwardIndex); | |
| 		} | |
| 	); | |
|  | |
| 	return result; | |
| } | |
|  | |
| function findPath(graph) { | |
| 	 | |
| 	let queue = []; | |
| 	 | |
| 	queue.push(0); | |
| 	graph[0].dist = 0; | |
|  | |
| 	mainLoop: while(queue.length > 0) { | |
| 		let v = queue.shift() | |
| 		for (let child of graph[v].childs) { | |
| 			if (!graph[child].visited) { | |
| 				queue.push(child) | |
| 				graph[v].visited = true; | |
| 				 | |
| 				let dist = graph[v].dist + 1; | |
| 				if ( dist < graph[child].dist ) { | |
| 					graph[child].prev = v; | |
| 					graph[child].dist = dist; | |
| 				} | |
|  | |
| 				if (child == graph.length - 1) { | |
| 					break mainLoop; | |
| 				} | |
| 			} | |
| 		}  | |
| 	} | |
| 	 | |
| 	if (graph[graph.length - 1].dist == Number.POSITIVE_INFINITY) { | |
| 		return undefined; | |
| 	} | |
|  | |
| 	let path = []; | |
| 	let index = graph.length - 1; | |
| 	while (index >= 0) { | |
| 		path.push(index); | |
| 		index = graph[index].prev; | |
| 	} | |
|  | |
| 	return path.reverse(); | |
| } | |
|  | |
| function isNotNumber(val) { | |
| 	return val.replace(/\s/g, '').length === 0 || isNaN(val) || !Number.isInteger(Number(val)); | |
| }
 | |
| 
 |