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)); |
|
}
|
|
|