diff --git a/labs/lab15/desc.json b/labs/lab15/desc.json index 0562948..3e83999 100644 --- a/labs/lab15/desc.json +++ b/labs/lab15/desc.json @@ -1,14 +1,28 @@ { "number": 15, - "task": "", + "task": "Лягушка хочет перепрыгнуть реку, но она не может сделать это одним прыжком. При этом, в реке имеется n камней. Лягушка может прыгать с ближайшего берега на камень 1 и с камня n на дальний берег. Она также может прыгать с камня на камень, вперед и назад. Однако на каждом камне написано число j, и она должна перепрыгнуть ровно на j камней назад или вперед. Найдите минимальное количество прыжков для перехода через реку (включая прыжки с первого камня и с последнего камня (или любого другого камня, если возможно) на дальний берег) или определите отсутствие шансов, если невозможно перепрыгнуть реку. Лягушка может также добраться до дальнего берега от камня, отличного от n, если на нем написано достаточно большое число. n >= 2.", "vars": [ [ { - "name": "", - "desc": "", + "name": "arr", + "desc": "Массив надписей на камнях", "data": "" } + ], + [ + { + "name": "arr", + "desc": "Массив надписей на камнях", + "data": "1 3 5 3 2 2 1 0" + } + ], + [ + { + "name": "arr", + "desc": "Массив надписей на камнях", + "data": "1 3 5 3 2 3 1 0" + } ] ], - "complete": false + "complete": true } \ No newline at end of file diff --git a/labs/lab15/main.js b/labs/lab15/main.js index 466be91..2d206bf 100644 --- a/labs/lab15/main.js +++ b/labs/lab15/main.js @@ -3,5 +3,98 @@ function main(formName) { let result = document.getElementById("result"); - result.textContent = "Результат: неопределенно"; + 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)); }