diff --git a/README.md b/README.md
index 51abd25..1fa14b5 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,22 @@
-# javascript-subway-final
\ No newline at end of file
+# ๐ ์งํ์ฒ ๋
ธ์ ๋ ๊ฒฝ๋ก ์กฐํ ๋ฏธ์
+- ๋ฑ๋ก๋ ์งํ์ฒ ๋
ธ์ ๋์์ ๊ฒฝ๋ก๋ฅผ ์กฐํํ๋ ๊ธฐ๋ฅ์ ๊ตฌํํ๋ค.
+
+## ๐ ๊ตฌํ ๊ธฐ๋ฅ๋ชฉ๋ก
+
+### ์ด๊ธฐ ์ค์
+- ํ๋ก๊ทธ๋จ ์์ ์ ์ญ, ๋
ธ์ , ๊ตฌ๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ด๊ธฐ ์ค์ ํ๋ค.
+ - ๊ฑฐ๋ฆฌ์ ์์ ์๊ฐ์ ์์ ์ ์์ด๋ฉฐ ๋จ์๋ km์ ๋ถ์ ์๋ฏธํ๋ค.
+
+### ๊ฒฝ๋ก ์กฐํ ๊ธฐ๋ฅ
+- ์ถ๋ฐ์ญ๊ณผ ๋์ฐฉ์ญ์ ์
๋ ฅ๋ฐ์ ์
๋ ฅ๊ฐ๋ค์ ์ฒ๋ฆฌํ๋ค.
+ - ๊ธธ์ฐพ๊ธฐ๋ฒํผ ํด๋ฆญ ์ ํด๋น ๊ธฐ๋ฅ์ด ์คํ๋๋ค.
+ - ์ถ๋ฐ์ญ๊ณผ ๋์ฐฉ์ญ์ 2๊ธ์ ์ด์์ด์ด์ผ ํ๋ค.
+ - ์กด์ฌํ์ง ์๋ ์ญ์ ์
๋ ฅ๋ฐ์์ ๊ฒฝ์ฐ alert์ฐฝ์ ๋์ด๋ค.
+ - ์ถ๋ฐ์ญ๊ณผ ๋์ฐฉ์ญ์ ๋ค๋ฅด๊ฒ ์
๋ ฅํด์ผ ํ๋ค.
+ - ์
๋ ฅ๊ฐ์ด ์์ ๊ฒฝ์ฐ alert์ฐฝ์ ๋์ ๋ค์ ์
๋ ฅํ๋๋ก ํ๋ค.
+ - ์
๋ ฅ๊ฐ๋ค์ ๊ณต๋ฐฑ์ ์ ๊ฑฐํ๋ค.
+- ์
๋ ฅ๋ ์ถ๋ฐ์ญ๊ณผ ๋์ฐฉ์ญ์ ๋ฐํ์ผ๋ก ๊ฒฝ๋ก๋ฅผ ์กฐํํ๋ค.
+ - ์ด ๊ฑฐ๋ฆฌ, ์ด ์์ ์๊ฐ์ ํ
์ด๋ธ์ ๋ด์ ์ถ๋ ฅํ๋ค.
+ - ์ถ๋ฐ์ญ๊ณผ ๋์ฐฉ์ญ์ด ์ฐ๊ฒฐ๋์ด ์์ง ์์ผ๋ฉด ๊ฒฝ๋ก๋ฅผ ์กฐํํ ์ ์๋ค.
+ - ๊ฒฝ๋ก ์กฐํ ์ ์ต๋จ๊ฑฐ๋ฆฌ ๋๋ ์ต์ ์๊ฐ ์ต์
์ ์ ํํ ์ ์๋ค.
+ - ๊ธฐ๋ณธ๊ฐ์ ์ต๋จ๊ฑฐ๋ฆฌ์ด๋ค.
\ No newline at end of file
diff --git a/images/dijkstra_example.png b/images/dijkstra_example.png
new file mode 100644
index 0000000..7c75197
Binary files /dev/null and b/images/dijkstra_example.png differ
diff --git a/images/path_result.gif b/images/path_result.gif
new file mode 100644
index 0000000..ee394bd
Binary files /dev/null and b/images/path_result.gif differ
diff --git a/images/path_result.jpg b/images/path_result.jpg
new file mode 100644
index 0000000..40a4bed
Binary files /dev/null and b/images/path_result.jpg differ
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..2b80a95
--- /dev/null
+++ b/index.html
@@ -0,0 +1,25 @@
+
+
+
+
+
+ ๐์งํ์ฒ ๊ธธ์ฐพ๊ธฐ
+
+
+
+
๐์งํ์ฒ ๊ธธ์ฐพ๊ธฐ
+ ์ถ๋ฐ์ญ
+
+
+
๋์ฐฉ์ญ
+
+
+
์ต๋จ๊ฑฐ๋ฆฌ
+
์ต์์๊ฐ
+
+
+
๐๊ฒฐ๊ณผ
+
+
+
+
diff --git a/src/index.js b/src/index.js
new file mode 100644
index 0000000..7863b52
--- /dev/null
+++ b/src/index.js
@@ -0,0 +1,34 @@
+import processStationNames from "./process-station-names.js?ver=31";
+import processSubwayDirection from "./process-subway-direction.js?ver=51";
+
+export default class Index {
+ constructor() {
+ this.processStationNames = new processStationNames();
+ this.processSubwayDirection = new processSubwayDirection();
+ this.searchButton = document.getElementById("search-button");
+ this.searchButton.addEventListener("click", () => {this.printResult()});
+ }
+
+ checkRadioButton() {
+ const radioButton = document.getElementsByName("search-type");
+ let radioValue;
+ radioButton.forEach(button => {
+ if(button.checked == true) {
+ radioValue = button.value;
+ }
+ });
+ return radioValue;
+ }
+
+ printResult() {
+ const stationNames = this.processStationNames.getStationNames();
+ const radioValue = this.checkRadioButton();
+ let result;
+ if(stationNames !== []) {
+ result = radioValue === "distance" ? this.processSubwayDirection.getMinDistance(stationNames) : this.processSubwayDirection.getMinTime(stationNames);
+ }
+ console.log(result);
+ }
+}
+
+new Index();
\ No newline at end of file
diff --git a/src/process-station-names.js b/src/process-station-names.js
new file mode 100644
index 0000000..8ee58e2
--- /dev/null
+++ b/src/process-station-names.js
@@ -0,0 +1,64 @@
+import {stations} from "./utils/data.js?ver=30";
+import {
+ removeWhiteSpaceValue,
+ isEmpty,
+ isRightLength
+} from "./utils/common.js?ver=30";
+
+export default class processStationNames {
+ constructor() {
+ this.stations = stations;
+ }
+
+ checkStationInData(name) {
+ return this.stations.findIndex(station => station.name === name);
+ }
+
+ getAlertText(stationName, stationType) {
+ let text = "";
+ if(isEmpty(stationName)) {
+ text = `${stationType}์ญ์ ์
๋ ฅํด์ฃผ์ธ์`;
+ }
+ else if(!isRightLength(stationName)) {
+ text = `${stationType}์ญ์ ๋๊ธ์ ์ด์ ์
๋ ฅํด์ฃผ์ธ์`;
+ }
+ else if(this.checkStationInData(stationName) === -1){
+ text = `${stationName}์ญ์ ๋ฑ๋ก๋์ง ์์ ์ญ์
๋๋ค`;
+ }
+ return text;
+ }
+
+ setAlert(departureText, arrivalText, departureStationName, arrivalStationName) {
+ let isCorrect = false;
+ if(departureText !== "") {
+ alert(departureText);
+ }
+ else if(arrivalText !== "") {
+ alert(arrivalText);
+ }
+ else if(departureStationName === arrivalStationName){
+ alert("์ถ๋ฐ์ญ๊ณผ ๋์ฐฉ์ญ์ ๋ค๋ฅด๊ฒ ์
๋ ฅํด์ฃผ์ธ์");
+ }
+ else {
+ isCorrect = true;
+ }
+ return isCorrect;
+ }
+
+ checkStationNames(departureStationName, arrivalStationName) {
+ const departureText = this.getAlertText(departureStationName, "์ถ๋ฐ");
+ const arrivalText = this.getAlertText(arrivalStationName, "๋์ฐฉ");
+ return this.setAlert(departureText, arrivalText, departureStationName, arrivalStationName);
+ }
+
+ getStationNames() {
+ const departureStationName = removeWhiteSpaceValue(document.getElementById("departure-station-name-input").value);
+ const arrivalStationName = removeWhiteSpaceValue(document.getElementById("arrival-station-name-input").value);
+ const isCorrect = this.checkStationNames(departureStationName, arrivalStationName);
+ let stationNames = [];
+ if(isCorrect) {
+ stationNames = [departureStationName, arrivalStationName];
+ }
+ return stationNames;
+ }
+}
\ No newline at end of file
diff --git a/src/process-subway-direction.js b/src/process-subway-direction.js
new file mode 100644
index 0000000..6cf3c82
--- /dev/null
+++ b/src/process-subway-direction.js
@@ -0,0 +1,46 @@
+import {lines} from "./utils/data.js?ver=30";
+
+export default class processSubwayDirection {
+ constructor() {
+ this.lines = lines;
+ this.directions = [];
+ }
+
+ getLinesInStation(stationName) {
+ const linesInStation = this.lines.filter(line => line.station.includes(stationName));
+ return linesInStation;
+ }
+
+ checkNextStation(station, index) {
+ return station.length - 1 ? null : station[index + 1];
+ }
+
+ recordDirection(stationList) {
+ const lineList = this.getLinesInStation(stationList[-1]);
+ lineList.forEach(line => {
+ const station = line.station;
+ this.checkNextStation(station, station.indexOf(stationList[-1]));
+ })
+ }
+
+ getDirection(startLine, stationName) {
+ const startStation = startLine.station;
+ const startIndex = startStation.indexOf(stationName);
+ const nextStation = this.checkNextStation(startStation, startIndex);
+ if(nextStation !== null) {
+ this.recordDirection([startStation, nextStation]);
+ }
+ }
+
+ getMinDistance(stationNames) {
+ const startLineList = this.getLinesInStation(stationNames[0]);
+ startLineList.forEach(line => {
+ this.getDirection(line, stationNames[0]);
+ })
+
+ }
+
+ getMinTime(stationNames) {
+
+ }
+}
\ No newline at end of file
diff --git a/src/style.css b/src/style.css
new file mode 100644
index 0000000..63f96de
--- /dev/null
+++ b/src/style.css
@@ -0,0 +1,4 @@
+h3 {
+ display: inline;
+}
+
diff --git a/src/utils/Dijkstra.js b/src/utils/Dijkstra.js
new file mode 100644
index 0000000..7c6cfd5
--- /dev/null
+++ b/src/utils/Dijkstra.js
@@ -0,0 +1,220 @@
+export default function Dijkstra() {
+ const Node = {
+ init: function (val, priority) {
+ this.val = val;
+ this.priority = priority;
+ },
+ };
+
+ const PriorityQueue = {
+ init: function () {
+ this.values = [];
+ },
+ enqueue: function (val, priority) {
+ const newNode = Object.create(Node);
+ newNode.init(val, priority);
+
+ this.values.push(newNode);
+
+ let idxOfNewNode = this.values.length - 1;
+
+ while (idxOfNewNode > 0) {
+ const idxOfParentNode = Math.floor((idxOfNewNode - 1) / 2);
+
+ const parentNode = this.values[idxOfParentNode];
+
+ if (priority < parentNode.priority) {
+ this.values[idxOfParentNode] = newNode;
+ this.values[idxOfNewNode] = parentNode;
+ idxOfNewNode = idxOfParentNode;
+ continue;
+ }
+ break;
+ }
+ return this.values;
+ },
+ dequeue: function () {
+ if (this.values.length == 0) {
+ return;
+ }
+ const dequeued = this.values.shift();
+ const lastItem = this.values.pop();
+ if (!lastItem) {
+ return dequeued;
+ }
+ this.values.unshift(lastItem);
+
+ let idxOfTarget = 0;
+
+ while (true) {
+ let idxOfLeftChild = idxOfTarget * 2 + 1;
+ let idxOfRightChild = idxOfTarget * 2 + 2;
+ let leftChild = this.values[idxOfLeftChild];
+ let rightChild = this.values[idxOfRightChild];
+
+ function swap(direction) {
+ const idxOfChild =
+ direction == "left" ? idxOfLeftChild : idxOfRightChild;
+ const child = direction == "left" ? leftChild : rightChild;
+ this.values[idxOfChild] = this.values[idxOfTarget];
+ this.values[idxOfTarget] = child;
+ idxOfTarget = idxOfChild;
+ }
+
+ if (!leftChild) {
+ return dequeued;
+ }
+
+ if (!rightChild) {
+ if (leftChild.priority < lastItem.priority) {
+ swap.call(this, "left");
+ continue;
+ }
+ return dequeued;
+ }
+
+ if (leftChild.priority == rightChild.priority) {
+ swap.call(this, "left");
+ continue;
+ }
+
+ if (
+ leftChild.priority < rightChild.priority &&
+ leftChild.priority < lastItem.priority
+ ) {
+ swap.call(this, "left");
+ continue;
+ }
+
+ if (
+ rightChild.priority < leftChild.priority &&
+ rightChild.priority < lastItem.priority
+ ) {
+ swap.call(this, "right");
+ continue;
+ }
+ }
+ },
+ };
+
+ const WeightedGraph = {
+ init: function () {
+ this.adjacencyList = {};
+ this.length = 0;
+ },
+ addVertex: function (vertex) {
+ if (!this.adjacencyList.hasOwnProperty(vertex)) {
+ this.adjacencyList[vertex] = {};
+ this.length++;
+ }
+ },
+ addEdge: function (vertex1, vertex2, weight) {
+ this.addVertex(vertex1);
+ this.addVertex(vertex2);
+ this.adjacencyList[vertex1][vertex2] = weight;
+ this.adjacencyList[vertex2][vertex1] = weight;
+ return this.adjacencyList;
+ },
+ removeEdge: function (vertex1, vertex2) {
+ if (!this.adjacencyList.hasOwnProperty(vertex1)) {
+ return `There's no ${vertex1}`;
+ }
+ if (!this.adjacencyList.hasOwnProperty(vertex2)) {
+ return `There's no ${vertex2}`;
+ }
+
+ function removeHelper(v1, v2) {
+ if (!this.adjacencyList.hasOwnProperty(v1)) {
+ return `There's no edge between ${v1} and ${v2}`;
+ }
+ delete this.adjacencyList[v1][v2];
+ if (Object.keys(this.adjacencyList[v1]).length == 0) {
+ delete this.adjacencyList[v1];
+ }
+ }
+
+ removeHelper.call(this, vertex1, vertex2);
+ removeHelper.call(this, vertex2, vertex1);
+
+ return this.adjacencyList;
+ },
+ removeVertex: function (vertex) {
+ if (!this.adjacencyList.hasOwnProperty(vertex)) {
+ return `There's no ${vertex}`;
+ }
+ const edges = this.adjacencyList[vertex];
+ for (const key in edges) {
+ this.removeEdge(key, vertex);
+ }
+ return this.adjacencyList;
+ },
+ findShortestRoute: function (start, end) {
+ if (!start || !end) {
+ throw Error("์ถ๋ฐ์ง์ ๋์ฐฉ์ง๋ฅผ ๋ชจ๋ ์
๋ ฅํด์ผ ํฉ๋๋ค.");
+ }
+ const distance = {};
+ const previous = {};
+ const pq = Object.create(PriorityQueue);
+ pq.init();
+ pq.enqueue(start, 0);
+ const visited = {};
+
+ const hashOfVertex = this.adjacencyList;
+ for (const vertexName in hashOfVertex) {
+ const priority = vertexName == start ? 0 : Infinity;
+ distance[vertexName] = priority;
+ previous[vertexName] = null;
+ }
+
+ while (true) {
+ let current = pq.dequeue();
+ if (!current?.val) {
+ return;
+ }
+ current = current.val;
+ if (current == end) {
+ break;
+ }
+ const neighbors = hashOfVertex[current];
+
+ for (const vertexName in neighbors) {
+ if (visited.hasOwnProperty(vertexName)) {
+ continue;
+ }
+ const distFromStart = distance[current] + neighbors[vertexName];
+
+ if (distFromStart < distance[vertexName]) {
+ pq.enqueue(vertexName, distFromStart);
+ distance[vertexName] = distFromStart;
+ previous[vertexName] = current;
+ }
+ }
+ visited[current] = true;
+ }
+
+ let node = end;
+
+ const route = [];
+ while (node) {
+ route.unshift(node);
+ node = previous[node];
+ }
+
+ return route;
+ },
+ };
+
+ this.addEdge = (source, target, weight) => {
+ WeightedGraph.addEdge(source, target, weight);
+ };
+
+ this.findShortestPath = (source, target) => {
+ return WeightedGraph.findShortestRoute(source, target);
+ };
+
+ this.addVertex = (vertex) => {
+ WeightedGraph.addVertex(vertex);
+ };
+
+ WeightedGraph.init();
+}
diff --git a/src/utils/common.js b/src/utils/common.js
new file mode 100644
index 0000000..ac293d1
--- /dev/null
+++ b/src/utils/common.js
@@ -0,0 +1,12 @@
+export function removeWhiteSpaceValue(value) {
+ return value.replace(/^\s+|\s+$/gm, '');
+}
+
+export function isEmpty(value) {
+ return (value === "" || value === null || value === undefined || (value !== null
+ && typeof value === "object" && !Object.keys(value).length));
+}
+
+export function isRightLength(value) {
+ return value.length >= 2;
+}
\ No newline at end of file
diff --git a/src/utils/data.js b/src/utils/data.js
new file mode 100644
index 0000000..9d72b50
--- /dev/null
+++ b/src/utils/data.js
@@ -0,0 +1,44 @@
+export const stations = [
+ {
+ name: "๊ต๋"
+ },
+ {
+ name: "๊ฐ๋จ"
+ },
+ {
+ name: "์ญ์ผ"
+ },
+ {
+ name: "๋จ๋ถํฐ๋ฏธ๋"
+ },
+ {
+ name: "์์ฌ"
+ },
+ {
+ name: "์์ฌ์๋ฏผ์์ฒ"
+ },
+ {
+ name: "๋งค๋ด"
+ }
+]
+
+export const lines = [
+ {
+ name: "2ํธ์ ",
+ station: ["๊ต๋", "๊ฐ๋จ", "์ญ์ผ"],
+ distance: [2, 2, 0],
+ time: [3, 3, 0]
+ },
+ {
+ name: "3ํธ์ ",
+ station: ["๊ต๋", "๋จ๋ถํฐ๋ฏธ๋", "์์ฌ", "๋งค๋ด"],
+ distance: [3, 6, 1, 0],
+ time: [2, 5, 1, 0]
+ },
+ {
+ name: "์ ๋ถ๋น์ ",
+ station: ["๊ฐ๋จ", "์์ฌ", "์์ฌ์๋ฏผ์์ฒ"],
+ distance: [2, 10, 0],
+ time: [8, 3, 0]
+ }
+]
\ No newline at end of file