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

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