diff --git a/README.md b/README.md index bb0c84ebb..3e1fea825 100644 --- a/README.md +++ b/README.md @@ -3,251 +3,47 @@
-## ๐Ÿš€ ๊ธฐ๋Šฅ ์š”๊ตฌ์‚ฌํ•ญ - -> ํ”„๋ฆฌ์ฝ”์Šค 3์ฃผ์ฐจ ๋ฏธ์…˜์—์„œ ์‚ฌ์šฉํ•œ ์ฝ”๋“œ๋ฅผ ์ฐธ๊ณ ํ•ด๋„ ๋ฌด๊ด€ํ•˜๋‹ค. - -### ์ดˆ๊ธฐ ์„ค์ • -- ํ”„๋กœ๊ทธ๋žจ ์‹œ์ž‘ ์‹œ ์—ญ, ๋…ธ์„ , ๊ตฌ๊ฐ„ ์ •๋ณด๋ฅผ ์ดˆ๊ธฐ ์„ค์ • ํ•ด์•ผ ํ•œ๋‹ค. -- ๊ฑฐ๋ฆฌ์™€ ์†Œ์š” ์‹œ๊ฐ„์€ ์–‘์˜ ์ •์ˆ˜์ด๋ฉฐ ๋‹จ์œ„๋Š” km์™€ ๋ถ„์„ ์˜๋ฏธํ•œ๋‹ค. -- ์•„๋ž˜์˜ ์‚ฌ์ „ ๋“ฑ๋ก ์ •๋ณด๋กœ ๋ฐ˜๋“œ์‹œ ์ดˆ๊ธฐ ์„ค์ •์„ ํ•œ๋‹ค. - -``` - 1. ์ง€ํ•˜์ฒ ์—ญ์œผ๋กœ ๊ต๋Œ€์—ญ, ๊ฐ•๋‚จ์—ญ, ์—ญ์‚ผ์—ญ, ๋‚จ๋ถ€ํ„ฐ๋ฏธ๋„์—ญ, ์–‘์žฌ์—ญ, ์–‘์žฌ์‹œ๋ฏผ์˜์ˆฒ์—ญ, ๋งค๋ด‰์—ญ์ด ๋“ฑ๋ก๋˜์–ด ์žˆ๋‹ค. - 2. ์ง€ํ•˜์ฒ  ๋…ธ์„ ์œผ๋กœ 2ํ˜ธ์„ , 3ํ˜ธ์„ , ์‹ ๋ถ„๋‹น์„ ์ด ๋“ฑ๋ก๋˜์–ด ์žˆ๋‹ค. - 3. ๋…ธ์„ ์— ์—ญ์ด ์•„๋ž˜์™€ ๊ฐ™์ด ๋“ฑ๋ก๋˜์–ด ์žˆ๋‹ค.(์™ผ์ชฝ ๋์ด ์ƒํ–‰ ์ข…์ ) - - 2ํ˜ธ์„ : ๊ต๋Œ€์—ญ - ( 2km / 3๋ถ„ ) - ๊ฐ•๋‚จ์—ญ - ( 2km / 3๋ถ„ ) - ์—ญ์‚ผ์—ญ - - 3ํ˜ธ์„ : ๊ต๋Œ€์—ญ - ( 3km / 2๋ถ„ ) - ๋‚จ๋ถ€ํ„ฐ๋ฏธ๋„์—ญ - ( 6km / 5๋ถ„ ) - ์–‘์žฌ์—ญ - ( 1km / 1๋ถ„ ) - ๋งค๋ด‰์—ญ - - ์‹ ๋ถ„๋‹น์„ : ๊ฐ•๋‚จ์—ญ - ( 2km / 8๋ถ„ ) - ์–‘์žฌ์—ญ - ( 10km / 3๋ถ„ ) - ์–‘์žฌ์‹œ๋ฏผ์˜์ˆฒ์—ญ - ``` - -### ๊ฒฝ๋กœ ์กฐํšŒ ๊ธฐ๋Šฅ -- ์ถœ๋ฐœ์—ญ๊ณผ ๋„์ฐฉ์—ญ์„ ์ž…๋ ฅ๋ฐ›์•„ ๊ฒฝ๋กœ๋ฅผ ์กฐํšŒํ•œ๋‹ค. -- ๊ฒฝ๋กœ ์กฐํšŒ ์‹œ ์ด ๊ฑฐ๋ฆฌ, ์ด ์†Œ์š” ์‹œ๊ฐ„๋„ ํ•จ๊ป˜ ์ถœ๋ ฅํ•œ๋‹ค. -- ๊ฒฝ๋กœ ์กฐํšŒ ๊ธฐ์ค€์€ `์ตœ๋‹จ ๊ฑฐ๋ฆฌ` `์ตœ์†Œ ์‹œ๊ฐ„`์ด ์žˆ๋‹ค. - -### ์˜ˆ์™ธ ์ฒ˜๋ฆฌ -- ๊ฒฝ๋กœ ์กฐํšŒ ์‹œ ์ถœ๋ฐœ์—ญ๊ณผ ๋„์ฐฉ์—ญ์ด ๊ฐ™์œผ๋ฉด ์—๋Ÿฌ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. -- ๊ฒฝ๋กœ ์กฐํšŒ ์‹œ ์ถœ๋ฐœ์—ญ๊ณผ ๋„์ฐฉ์—ญ์ด ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์ง€ ์•Š์œผ๋ฉด ์—๋Ÿฌ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. -- ๊ทธ ์™ธ ์ •์ƒ์ ์œผ๋กœ ํ”„๋กœ๊ทธ๋žจ์ด ์ˆ˜ํ–‰๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ์—๋Ÿฌ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. - -
- -## โœ๐Ÿป ์ž…์ถœ๋ ฅ ์š”๊ตฌ์‚ฌํ•ญ -- `ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์‹คํ–‰ ๊ฒฐ๊ณผ ์˜ˆ์‹œ`์™€ ๋™์ผํ•˜๊ฒŒ ์ž…์ถœ๋ ฅ์„ ๊ตฌํ˜„ํ•œ๋‹ค. -- ๊ธฐ๋Œ€ํ•˜๋Š” ์ถœ๋ ฅ ๊ฒฐ๊ณผ๋Š” `[INFO]`๋ฅผ ๋ถ™์—ฌ์„œ ์ถœ๋ ฅํ•œ๋‹ค. ์ถœ๋ ฅ๊ฐ’์˜ ํ˜•์‹์€ ์˜ˆ์‹œ์™€ ๋™์ผํ•˜๊ฒŒ ํ•œ๋‹ค. -- ์—๋Ÿฌ ๋ฐœ์ƒ ์‹œ `[ERROR]`๋ฅผ ๋ถ™์—ฌ์„œ ์ถœ๋ ฅํ•œ๋‹ค. ์—๋Ÿฌ์˜ ๋ฌธ๊ตฌ๋Š” ์ž์œ ๋กญ๊ฒŒ ์ž‘์„ฑํ•œ๋‹ค. - -### ๐Ÿ’ป ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์‹คํ–‰ ๊ฒฐ๊ณผ ์˜ˆ์‹œ -#### ๊ฒฝ๋กœ ์กฐํšŒ -``` -## ๋ฉ”์ธ ํ™”๋ฉด -1. ๊ฒฝ๋กœ ์กฐํšŒ -Q. ์ข…๋ฃŒ - -## ์›ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์„ ํƒํ•˜์„ธ์š”. -1 - -## ๊ฒฝ๋กœ ๊ธฐ์ค€ -1. ์ตœ๋‹จ ๊ฑฐ๋ฆฌ -2. ์ตœ์†Œ ์‹œ๊ฐ„ -B. ๋Œ์•„๊ฐ€๊ธฐ - -## ์›ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์„ ํƒํ•˜์„ธ์š”. -1 - -## ์ถœ๋ฐœ์—ญ์„ ์ž…๋ ฅํ•˜์„ธ์š”. -๊ต๋Œ€์—ญ - -## ๋„์ฐฉ์—ญ์„ ์ž…๋ ฅํ•˜์„ธ์š”. -์–‘์žฌ์—ญ - -## ์กฐํšŒ ๊ฒฐ๊ณผ -[INFO] --- -[INFO] ์ด ๊ฑฐ๋ฆฌ: 4km -[INFO] ์ด ์†Œ์š” ์‹œ๊ฐ„: 11๋ถ„ -[INFO] --- -[INFO] ๊ต๋Œ€์—ญ -[INFO] ๊ฐ•๋‚จ์—ญ -[INFO] ์–‘์žฌ์—ญ - -## ๋ฉ”์ธ ํ™”๋ฉด -1. ๊ฒฝ๋กœ ์กฐํšŒ -Q. ์ข…๋ฃŒ - -... -``` - -#### ์—๋Ÿฌ ์ถœ๋ ฅ ์˜ˆ์‹œ - -``` -## ๋ฉ”์ธ ํ™”๋ฉด -1. ๊ฒฝ๋กœ ์กฐํšŒ -Q. ์ข…๋ฃŒ - -## ์›ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์„ ํƒํ•˜์„ธ์š”. -1 - -## ๊ฒฝ๋กœ ๊ธฐ์ค€ -1. ์ตœ๋‹จ ๊ฑฐ๋ฆฌ -2. ์ตœ์†Œ ์‹œ๊ฐ„ -B. ๋Œ์•„๊ฐ€๊ธฐ - -## ์›ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์„ ํƒํ•˜์„ธ์š”. -1 - -## ์ถœ๋ฐœ์—ญ์„ ์ž…๋ ฅํ•˜์„ธ์š”. -๊ฐ•๋‚จ์—ญ - -## ๋„์ฐฉ์—ญ์„ ์ž…๋ ฅํ•˜์„ธ์š”. -๊ฐ•๋‚จ์—ญ - -[ERROR] ์ถœ๋ฐœ์—ญ๊ณผ ๋„์ฐฉ์—ญ์ด ๋™์ผํ•ฉ๋‹ˆ๋‹ค. - -## ๊ฒฝ๋กœ ๊ธฐ์ค€ -1. ์ตœ๋‹จ ๊ฑฐ๋ฆฌ -2. ์ตœ์†Œ ์‹œ๊ฐ„ -B. ๋Œ์•„๊ฐ€๊ธฐ - -## ์›ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์„ ํƒํ•˜์„ธ์š”. - -... - -``` - -
- -## ๐ŸŽฑ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ์‚ฌํ•ญ -- ์ž๋ฐ” ์ฝ”๋“œ ์ปจ๋ฒค์…˜์„ ์ง€ํ‚ค๋ฉด์„œ ํ”„๋กœ๊ทธ๋ž˜๋ฐํ•œ๋‹ค. - - ๊ธฐ๋ณธ์ ์œผ๋กœ [Google Java Style Guide](https://google.github.io/styleguide/javaguide.html)์„ ์›์น™์œผ๋กœ ํ•œ๋‹ค. - - ๋‹จ, ๋“ค์—ฌ์“ฐ๊ธฐ๋Š” '2 spaces'๊ฐ€ ์•„๋‹Œ '4 spaces'๋กœ ํ•œ๋‹ค. -- indent(์ธ๋ดํŠธ, ๋“ค์—ฌ์“ฐ๊ธฐ) depth๋ฅผ 3์ด ๋„˜์ง€ ์•Š๋„๋ก ๊ตฌํ˜„ํ•œ๋‹ค. 2๊นŒ์ง€๋งŒ ํ—ˆ์šฉํ•œ๋‹ค. - - ์˜ˆ๋ฅผ ๋“ค์–ด while๋ฌธ ์•ˆ์— if๋ฌธ์ด ์žˆ์œผ๋ฉด ๋“ค์—ฌ์“ฐ๊ธฐ๋Š” 2์ด๋‹ค. - - ํžŒํŠธ: indent(์ธ๋ดํŠธ, ๋“ค์—ฌ์“ฐ๊ธฐ) depth๋ฅผ ์ค„์ด๋Š” ์ข‹์€ ๋ฐฉ๋ฒ•์€ ํ•จ์ˆ˜(๋˜๋Š” ๋ฉ”์†Œ๋“œ)๋ฅผ ๋ถ„๋ฆฌํ•˜๋ฉด ๋œ๋‹ค. -- 3ํ•ญ ์—ฐ์‚ฐ์ž๋ฅผ ์“ฐ์ง€ ์•Š๋Š”๋‹ค. -- ํ•จ์ˆ˜(๋˜๋Š” ๋ฉ”์†Œ๋“œ)์˜ ๊ธธ์ด๊ฐ€ 15๋ผ์ธ์„ ๋„˜์–ด๊ฐ€์ง€ ์•Š๋„๋ก ๊ตฌํ˜„ํ•œ๋‹ค. - - ํ•จ์ˆ˜(๋˜๋Š” ๋ฉ”์†Œ๋“œ)๊ฐ€ ํ•œ ๊ฐ€์ง€ ์ผ๋งŒ ์ž˜ ํ•˜๋„๋ก ๊ตฌํ˜„ํ•œ๋‹ค. -- else ์˜ˆ์•ฝ์–ด๋ฅผ ์“ฐ์ง€ ์•Š๋Š”๋‹ค. - - ํžŒํŠธ: if ์กฐ๊ฑด์ ˆ์—์„œ ๊ฐ’์„ returnํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•˜๋ฉด else๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค. - - else๋ฅผ ์“ฐ์ง€ ๋ง๋ผ๊ณ  ํ•˜๋‹ˆ switch/case๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋Š”๋ฐ switch/case๋„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค. -- ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ์‚ฌํ•ญ์—์„œ ๋ณ„๋„๋กœ ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€ ์•ˆ๋‚ด๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ ํŒŒ์ผ ์ˆ˜์ •๊ณผ ํŒจํ‚ค์ง€ ์ด๋™์„ ์ž์œ ๋กญ๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค. -- ์˜ˆ์™ธ ์ƒํ™ฉ ์‹œ ์—๋Ÿฌ ๋ฌธ๊ตฌ๋ฅผ ์ถœ๋ ฅํ•ด์•ผ ํ•œ๋‹ค. ๋‹จ, ์—๋Ÿฌ ๋ฌธ๊ตฌ๋Š” `[ERROR]` ๋กœ ์‹œ์ž‘ํ•ด์•ผ ํ•œ๋‹ค. - -### ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ์‚ฌํ•ญ - Application -- Application ํด๋ž˜์Šค๋ฅผ ํ™œ์šฉํ•ด ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค. -- Application์˜ ํŒจํ‚ค์ง€ ๊ตฌ์กฐ๋Š” ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๋Š”๋‹ค. -- Application ํด๋ž˜์Šค์— ์žˆ๋Š” Scanner๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ๋ณ„๋„์˜ Scanner ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค. -```java -public class Application { - public static void main(String[] args) { - final Scanner scanner = new Scanner(System.in); - ... - } -} -``` - -### ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ์‚ฌํ•ญ - Station, Line -- Station, Line ํด๋ž˜์Šค๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์ง€ํ•˜์ฒ ์—ญ๊ณผ ๋…ธ์„ ์„ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค. -- ์ œ๊ณตํ•˜๋Š” ๊ฐ ํด๋ž˜์Šค์˜ ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์—†๋‹ค. -- ํ•„๋“œ(์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜)์ธ name์˜ ์ ‘๊ทผ ์ œ์–ด์ž private์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋‹ค. -- ๊ฐ€๋Šฅํ•˜๋ฉด setter ๋ฉ”์†Œ๋“œ(ex. setXXX)๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š๊ณ  ๊ตฌํ˜„ํ•œ๋‹ค. - -```java -public class Station { - private String name; - - public Station(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - // ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ๊ตฌํ˜„ -} - -``` - -### ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ์‚ฌํ•ญ - StationRepository, LineRepository -- Station๊ณผ Line์˜ ์ƒํƒœ๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š” StationRepository, LineRepository๋ฅผ ์ œ๊ณตํ•œ๋‹ค. -- ํ•„์š” ์‹œ StationRepository, LineRepository ์ด ์™ธ ์ถ”๊ฐ€๋กœ Repository๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. -- ์ถ”๊ฐ€๋กœ ์ƒ์„ฑ๋˜๋Š” ๊ฐ์ฒด์— ๋Œ€ํ•ด์„œ XXXRepository ๋„ค์ด๋ฐ์œผ๋กœ ์ €์žฅ ํด๋ž˜์Šค๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค. -- ๊ฐ์ฒด๋“ค์˜ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด์„œ XXXRepository ํด๋ž˜์Šค๋ฅผ ํ™œ์šฉํ•ด ์ €์žฅ ๋กœ์ง์„ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค. -- ์ž‘์„ฑ๋œ ๋ฉ”์„œ๋“œ๋Š” ์ˆ˜์ •ํ•  ์ˆ˜ ์—†๊ณ , ํ•„์š”์— ๋”ฐ๋ผ ๋ฉ”์„œ๋“œ๋ฅผ ์ž์œ ๋กญ๊ฒŒ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค. - -```java -public class StationRepository { - private static final List stations = new ArrayList<>(); - - public static List stations() { - return Collections.unmodifiableList(stations); - } - - public static void addStation(Station station) { - stations.add(station); - } - - public static boolean deleteStation(String name) { - return stations.removeIf(station -> Objects.equals(station.getName(), name)); - } - - public static void deleteAll() { - stations.clear(); - } -} -``` - -
- -## โ—๏ธํžŒํŠธ -### ์ตœ๋‹จ ๊ฒฝ๋กœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ -- jgrapht ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ™œ์šฉํ•˜๋ฉด ๊ฐ„ํŽธํ•˜๊ฒŒ ์ตœ๋‹จ๊ฑฐ๋ฆฌ๋ฅผ ์กฐํšŒํ•  ์ˆ˜ ์žˆ์Œ -- Dijkstra ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๋ฐ˜๋“œ์‹œ ์ดํ•ดํ•  ํ•„์š”๋Š” ์—†๊ณ  ๋ฏธ์…˜์— ์ ์šฉํ•  ์ •๋„๋กœ๋งŒ ์ดํ•ดํ•˜๋ฉด ๋จ -- JGraphtTest ํด๋ž˜์Šค์˜ ํ…Œ์ŠคํŠธ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ฏธ์…˜์— ํ•„์š”ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๊ธฐ๋Šฅ์„ ํ•™์Šตํ•  ์ˆ˜ ์žˆ์Œ -- ์ •์ (vertex)๊ณผ ๊ฐ„์„ (edge), ๊ทธ๋ฆฌ๊ณ  ๊ฐ€์ค‘์น˜ ๊ฐœ๋…์„ ์ด์šฉ - - ์ •์ : ์ง€ํ•˜์ฒ ์—ญ - - ๊ฐ„์„ : ์ง€ํ•˜์ฒ ์—ญ ์—ฐ๊ฒฐ์ •๋ณด - - ๊ฐ€์ค‘์น˜: ๊ฑฐ๋ฆฌ or ์†Œ์š” ์‹œ๊ฐ„ -- ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ๊ธฐ์ค€ ์กฐํšŒ ์‹œ ๊ฐ€์ค‘์น˜๋ฅผ ๊ฑฐ๋ฆฌ๋กœ ์„ค์ • - -```java -@Test -public void getDijkstraShortestPath() { - WeightedMultigraph graph - = new WeightedMultigraph(DefaultWeightedEdge.class); - graph.addVertex("v1"); - graph.addVertex("v2"); - graph.addVertex("v3"); - graph.setEdgeWeight(graph.addEdge("v1", "v2"), 2); - graph.setEdgeWeight(graph.addEdge("v2", "v3"), 2); - graph.setEdgeWeight(graph.addEdge("v1", "v3"), 100); - - DijkstraShortestPath dijkstraShortestPath = new DijkstraShortestPath(graph); - List shortestPath = dijkstraShortestPath.getPath("v3", "v1").getVertexList(); - - assertThat(shortestPath.size()).isEqualTo(3); -} -``` - -#### ํ…Œ์ŠคํŠธ ์„ค๋ช… - - - -- ์—ญ ์‚ฌ์ด์˜ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ ๋ คํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ V1->V3 ๊ฒฝ๋กœ๊ฐ€ ์ตœ๋‹จ ๊ฒฝ๋กœ -- ์—ญ ์‚ฌ์ด์˜ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ ๋ คํ•  ๊ฒฝ์šฐ V1->V3 ๊ฒฝ๋กœ์˜ ๊ฑฐ๋ฆฌ๋Š” 100km, V1->V2->V3 ๊ฒฝ๋กœ์˜ ๊ฑฐ๋ฆฌ๋Š” 4km์ด๋ฏ€๋กœ ์ตœ๋‹จ ๊ฒฝ๋กœ๋Š” V1->V2->V3 - -
- -## ๐Ÿ“ˆ ์ง„ํ–‰ ์š”๊ตฌ์‚ฌํ•ญ -- ๋ฏธ์…˜์€ [java-subway-path-precourse ์ €์žฅ์†Œ](https://github.com/woowacourse/java-subway-path-precourse) ๋ฅผ fork/cloneํ•ด ์‹œ์ž‘ํ•œ๋‹ค. -- ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์ „์— java-subway-path-precourse/docs/README.md ํŒŒ์ผ์— ๊ตฌํ˜„ํ•  ๊ธฐ๋Šฅ ๋ชฉ๋ก์„ ์ •๋ฆฌํ•ด ์ถ”๊ฐ€ํ•œ๋‹ค. -- git์˜ commit ๋‹จ์œ„๋Š” ์•ž ๋‹จ๊ณ„์—์„œ README.md ํŒŒ์ผ์— ์ •๋ฆฌํ•œ ๊ธฐ๋Šฅ ๋ชฉ๋ก ๋‹จ์œ„๋กœ ์ถ”๊ฐ€ํ•œ๋‹ค. - - [AngularJS Commit Message Conventions](https://gist.github.com/stephenparish/9941e89d80e2bc58a153) ์ฐธ๊ณ ํ•ด commit log๋ฅผ ๋‚จ๊ธด๋‹ค. -- [ํ”„๋ฆฌ์ฝ”์Šค ๊ณผ์ œ ์ œ์ถœ ๋ฌธ์„œ](https://github.com/woowacourse/woowacourse-docs/tree/master/precourse) ์ ˆ์ฐจ๋ฅผ ๋”ฐ๋ผ ๋ฏธ์…˜์„ ์ œ์ถœํ•œ๋‹ค. - - [ํ”„๋ฆฌ์ฝ”์Šค ๊ณผ์ œ FAQ](https://github.com/woowacourse/woowacourse-docs/tree/master/precourse/faq) ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค. -
- -## ๐Ÿ“ License - -This project is [MIT](https://github.com/woowacourse/java-subway-path-precourse/blob/master/LICENSE.md) licensed. +## ๊ธฐ๋ณธ ์„ค์ • +- ์—ญ, ๋…ธ์„ , ๊ตฌ๊ฐ„์ •๋ณด๋ฅผ ์ดˆ๊ธฐ์„ค์ •ํ•œ๋‹ค. +- ๊ตฌ๊ฐ„์€ `๋…ธ์„ `, `์ƒํ–‰์ชฝ์—ญ`, `ํ•˜ํ–‰์ชฝ์—ญ`, `๊ฑฐ๋ฆฌ`, `์‹œ๊ฐ„` ์œผ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๋‹ค. +``` +1. ์ง€ํ•˜์ฒ ์—ญ์œผ๋กœ ๊ต๋Œ€์—ญ, ๊ฐ•๋‚จ์—ญ, ์—ญ์‚ผ์—ญ, ๋‚จ๋ถ€ํ„ฐ๋ฏธ๋„์—ญ, ์–‘์žฌ์—ญ, ์–‘์žฌ์‹œ๋ฏผ์˜์ˆฒ์—ญ, ๋งค๋ด‰์—ญ์ด ๋“ฑ๋ก๋˜์–ด ์žˆ๋‹ค. +2. ์ง€ํ•˜์ฒ  ๋…ธ์„ ์œผ๋กœ 2ํ˜ธ์„ , 3ํ˜ธ์„ , ์‹ ๋ถ„๋‹น์„ ์ด ๋“ฑ๋ก๋˜์–ด ์žˆ๋‹ค. +3. ๋…ธ์„ ์— ์—ญ์ด ์•„๋ž˜์™€ ๊ฐ™์ด ๋“ฑ๋ก๋˜์–ด ์žˆ๋‹ค.(์™ผ์ชฝ ๋์ด ์ƒํ–‰ ์ข…์ ) + - 2ํ˜ธ์„ : ๊ต๋Œ€์—ญ - ( 2km / 3๋ถ„ ) - ๊ฐ•๋‚จ์—ญ - ( 2km / 3๋ถ„ ) - ์—ญ์‚ผ์—ญ + - 3ํ˜ธ์„ : ๊ต๋Œ€์—ญ - ( 3km / 2๋ถ„ ) - ๋‚จ๋ถ€ํ„ฐ๋ฏธ๋„์—ญ - ( 6km / 5๋ถ„ ) - ์–‘์žฌ์—ญ - ( 1km / 1๋ถ„ ) - ๋งค๋ด‰์—ญ + - ์‹ ๋ถ„๋‹น์„ : ๊ฐ•๋‚จ์—ญ - ( 2km / 8๋ถ„ ) - ์–‘์žฌ์—ญ - ( 10km / 3๋ถ„ ) - ์–‘์žฌ์‹œ๋ฏผ์˜์ˆฒ์—ญ +``` + +## ๊ตฌํ˜„ ๊ธฐ๋Šฅ ๋ชฉ๋ก +- ์ดˆ๊ธฐ ์„ค์ •์„ ์œ„ํ•ด ์—ญ, ๋…ธ์„ , ๊ตฌ๊ฐ„ ์ •๋ณด๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค. +- ๋ฉ”์ธ ํ™”๋ฉด์—์„œ ๋ฉ”๋‰ด๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. +- ๋ฉ”์ธ ํ™”๋ฉด์—์„œ ๊ฒฝ๋กœ ์กฐํšŒ์™€ ์ข…๋ฃŒ์ค‘ ์ž…๋ ฅ์„ ๋ฐ›๋Š”๋‹ค. (1: ๊ฒฝ๋กœ์กฐํšŒ, Q: ์ข…๋ฃŒ) +- ๊ฒฝ๋กœ ๊ธฐ์ค€ ํ™”๋ฉด์—์„œ ๋ฉ”๋‰ด๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. +- ๊ฒฝ๋กœ ๊ธฐ์ค€์„ ์ž…๋ ฅ๋ฐ›๋Š”๋‹ค. (1: ์ตœ๋‹จ๊ฑฐ๋ฆฌ, 2: ์ตœ์†Œ์‹œ๊ฐ„) +- ๊ฒฝ๋กœ๋ฅผ ์กฐํšŒํ•œ๋‹ค. + - ์ถœ๋ฐœ์—ญ์„ ์ž…๋ ฅ๋ฐ›๋Š”๋‹ค. + - ๋„์ฐฉ์—ญ์„ ์ž…๋ ฅ๋ฐ›๋Š”๋‹ค. + - (๊ฒฝ๋กœ ๊ธฐ์ค€) ์ถœ๋ฐœ์—ญ์—์„œ ๋„์ฐฉ์—ญ๊นŒ์ง€์˜ ๊ฐˆ ์ˆ˜ ์žˆ๋Š” ์ตœ๋‹จ ๊ฑฐ๋ฆฌ์ธ ๊ฒฝ๋กœ๋ฅผ ๊ณ„์‚ฐํ•œ๋‹ค. + - (์‹œ๊ฐ„ ๊ธฐ์ค€) ์ถœ๋ฐœ์—ญ์—์„œ ๋„์ฐฉ์—ญ๊นŒ์ง€์˜ ์ด ์†Œ์š”์‹œ๊ฐ„์ด ๊ฐ€์žฅ ์งง์€ ๊ฒฝ๋กœ๋ฅผ ๊ณ„์‚ฐํ•œ๋‹ค. + - ์ฐพ์•„๋‚ธ ๊ฒฝ๋กœ์˜ ๊ฑฐ๋ฆฌ์™€ ์†Œ์š”์‹œ๊ฐ„์„ ์ถœ๋ ฅํ•œ๋‹ค. +- ์ข…๋ฃŒํ•œ๋‹ค. + +`์˜ˆ์™ธ์ฒ˜๋ฆฌ` +- ๋ฉ”์ธํ™”๋ฉด๊ณผ ๊ฒฝ๋กœ๊ธฐ์ค€ ์ž…๋ ฅํ™”๋ฉด์—์„œ ์ •ํ•ด์ง„ ํ‚ค์›Œ๋“œ๊ฐ€ ์•„๋‹Œ ์ž…๋ ฅ์€ ๋ชจ๋‘ ์˜ˆ์™ธ์ฒ˜๋ฆฌ +- ๊ฒฝ๋กœ์กฐํšŒ์‹œ ์ถœ๋ฐœ์—ญ๊ณผ ๋„์ฐฉ์—ญ์ด ๊ฐ™์€ ๊ฒฝ์šฐ +- ์ถœ๋ฐœ์—ญ๊ณผ ๋„์ฐฉ์—ญ์ด ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์ง€ ์•Š์€ ๊ฒฝ์šฐ + +## ๊ฐ์ฒด +- ํ™”๋ฉด ๊ด€๋ฆฌ ๊ฐ์ฒด +- ๋ฉ”์ธ ํ™”๋ฉด +- ๊ฒฝ๋กœ ๊ธฐ์ค€ ์„ ํƒ ํ™”๋ฉด +- ๊ธฐ๋Šฅ ํ™”๋ฉด +- ์ถœ๋ ฅ +- ์ž…๋ ฅ +- ์—ญ +- ์—ญ ๋ ˆํฌ์ง€ํ† ๋ฆฌ +- ๋…ธ์„  +- ๋…ธ์„  ๋ ˆํฌ์ง€ํ† ๋ฆฌ +- ๊ตฌ๊ฐ„ +- ๊ตฌ๊ฐ„ ๋ ˆํฌ์ง€ํ† ๋ฆฌ diff --git a/gradlew b/gradlew index 2fe81a7d9..9b9244cd2 100755 --- a/gradlew +++ b/gradlew @@ -34,7 +34,7 @@ while [ -h "$PRG" ] ; do else PRG=`dirname "$PRG"`"/$link" fi -done +GO_BACK SAVED="`pwd`" cd "`dirname \"$PRG\"`/" >/dev/null APP_HOME="`pwd -P`" @@ -137,7 +137,7 @@ if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then for dir in $ROOTDIRSRAW ; do ROOTDIRS="$ROOTDIRS$SEP$dir" SEP="|" - done + GO_BACK OURCYGPATTERN="(^($ROOTDIRS))" # Add a user-defined pattern to the cygpath arguments if [ "$GRADLE_CYGPATTERN" != "" ] ; then @@ -155,7 +155,7 @@ if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then eval `echo args$i`="\"$arg\"" fi i=`expr $i + 1` - done + GO_BACK case $i in 0) set -- ;; 1) set -- "$args0" ;; @@ -172,7 +172,7 @@ fi # Escape application args save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; GO_BACK echo " " } APP_ARGS=`save "$@"` diff --git a/src/main/java/subway/Application.java b/src/main/java/subway/Application.java index 0bcf786cc..4a06e12fb 100644 --- a/src/main/java/subway/Application.java +++ b/src/main/java/subway/Application.java @@ -1,10 +1,54 @@ package subway; +import subway.domain.*; +import subway.screen.MainScreen; +import subway.screen.ScreenManager; +import subway.screen.ScreenModel; + +import java.util.Arrays; +import java.util.List; import java.util.Scanner; public class Application { public static void main(String[] args) { final Scanner scanner = new Scanner(System.in); - // TODO: ํ”„๋กœ๊ทธ๋žจ ๊ตฌํ˜„ + initialize(); + ScreenManager.addNextMenuScreen(new MainScreen(scanner)); + + while (!ScreenManager.isEmpty()) { + try { + ScreenModel nextScreen = ScreenManager.pop(); + ScreenManager.show(nextScreen); + } catch (IllegalArgumentException e) { + System.out.println(e.getMessage()); + ScreenManager.addNextMenuScreen(new MainScreen(scanner)); + } + } + } + + private static void initialize() { + List stations = Arrays.asList(new Station("๊ต๋Œ€์—ญ"), new Station("๊ฐ•๋‚จ์—ญ") + , new Station("์—ญ์‚ผ์—ญ"), new Station("๋‚จ๋ถ€ํ„ฐ๋ฏธ๋„์—ญ"), new Station("์–‘์žฌ์—ญ") + , new Station("์–‘์žฌ์‹œ๋ฏผ์˜์ˆฒ์—ญ"), new Station("๋งค๋ด‰์—ญ")); + stations.stream().forEach(station -> StationRepository.addStation(station)); + + List lines = Arrays.asList(new Line("2ํ˜ธ์„ ").addTerminus("๊ต๋Œ€์—ญ", "์—ญ์‚ผ์—ญ") + , new Line("3ํ˜ธ์„ ").addTerminus("๊ต๋Œ€์—ญ", "๋งค๋ด‰์—ญ") + , new Line("์‹ ๋ถ„๋‹น์„ ").addTerminus("๊ฐ•๋‚จ์—ญ", "์–‘์žฌ์‹œ๋ฏผ์˜์ˆฒ์—ญ")); + lines.stream().forEach(line -> LineRepository.addLine(line)); + + SectionRepository.addSection("2ํ˜ธ์„ ", "๊ฐ•๋‚จ์—ญ", 1); + SectionRepository.addSection("3ํ˜ธ์„ ", "๋‚จ๋ถ€ํ„ฐ๋ฏธ๋„์—ญ", 1); + SectionRepository.addSection("3ํ˜ธ์„ ", "์–‘์žฌ์—ญ", 2); + SectionRepository.addSection("์‹ ๋ถ„๋‹น์„ ", "์–‘์žฌ์—ญ", 1); + + SectionRepository.addSectinonDistanceAndTime("๊ต๋Œ€์—ญ", "๊ฐ•๋‚จ์—ญ", 2, 3); + SectionRepository.addSectinonDistanceAndTime("๊ฐ•๋‚จ์—ญ", "์—ญ์‚ผ์—ญ", 2, 3); + SectionRepository.addSectinonDistanceAndTime("๊ต๋Œ€์—ญ", "๋‚จ๋ถ€ํ„ฐ๋ฏธ๋„์—ญ", 3, 2); + SectionRepository.addSectinonDistanceAndTime("๋‚จ๋ถ€ํ„ฐ๋ฏธ๋„์—ญ", "์–‘์žฌ์—ญ", 6, 5); + SectionRepository.addSectinonDistanceAndTime("์–‘์žฌ์—ญ", "๋งค๋ด‰์—ญ", 1, 1); + SectionRepository.addSectinonDistanceAndTime("๊ฐ•๋‚จ์—ญ", "์–‘์žฌ์—ญ", 2, 8); + SectionRepository.addSectinonDistanceAndTime("์–‘์žฌ์—ญ", "์–‘์žฌ์‹œ๋ฏผ์˜์ˆฒ์—ญ", 10, 3); + } } diff --git a/src/main/java/subway/Menu/Menu.java b/src/main/java/subway/Menu/Menu.java new file mode 100644 index 000000000..05467cdbc --- /dev/null +++ b/src/main/java/subway/Menu/Menu.java @@ -0,0 +1,46 @@ +package subway.Menu; + +public class Menu { + public enum Main { + ROUTE_INQUIRY("1", "๊ฒฝ๋กœ์กฐํšŒ"), + QUIT("Q", "์ข…๋ฃŒ"); + + private String code; + private String korean; + + Main(String code, String korean) { + this.code = code; + this.korean = korean; + } + + public String getCode() { + return code; + } + + public String getKorean() { + return korean; + } + } + + public enum ROUTE_CRITERIA { + SHORTEST_DISTANCE("1", "์ตœ๋‹จ ๊ฑฐ๋ฆฌ"), + SHORTEST_TIME("2", "์ตœ์†Œ ์‹œ๊ฐ„"), + BACK("B", "๋Œ์•„๊ฐ€๊ธฐ"); + + private String code; + private String korean; + + ROUTE_CRITERIA(String code, String korean) { + this.code = code; + this.korean = korean; + } + + public String getCode() { + return code; + } + + public String getKorean() { + return korean; + } + } +} diff --git a/src/main/java/subway/PathResult.java b/src/main/java/subway/PathResult.java new file mode 100644 index 000000000..fa40092b0 --- /dev/null +++ b/src/main/java/subway/PathResult.java @@ -0,0 +1,27 @@ +package subway; + +import java.util.List; + +public class PathResult { + List shortestPath; + int distance; + int requiredTime; + + public PathResult(List shortestPath, int distance, int requiredTime) { + this.shortestPath = shortestPath; + this.distance = distance; + this.requiredTime = requiredTime; + } + + public List getShortestPath() { + return shortestPath; + } + + public int getDistance() { + return distance; + } + + public int getRequiredTime() { + return requiredTime; + } +} diff --git a/src/main/java/subway/domain/Line.java b/src/main/java/subway/domain/Line.java index f4d738d5a..3c2ef9771 100644 --- a/src/main/java/subway/domain/Line.java +++ b/src/main/java/subway/domain/Line.java @@ -1,6 +1,9 @@ package subway.domain; +import java.util.LinkedList; + public class Line { + private static LinkedList line = new LinkedList<>(); private String name; public Line(String name) { @@ -11,5 +14,13 @@ public String getName() { return name; } - // ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ๊ตฌํ˜„ + public void addSection(int sequence, Station station) { + line.add(sequence, station); + } + + public Line addTerminus(String upBoundTerminus, String downBoundTerminus) { + line.addFirst(StationRepository.findStation(upBoundTerminus)); + line.addLast(StationRepository.findStation(downBoundTerminus)); + return this; + } } diff --git a/src/main/java/subway/domain/LineRepository.java b/src/main/java/subway/domain/LineRepository.java index 2c4a723c9..69bfd17cc 100644 --- a/src/main/java/subway/domain/LineRepository.java +++ b/src/main/java/subway/domain/LineRepository.java @@ -23,4 +23,10 @@ public static boolean deleteLineByName(String name) { public static void deleteAll() { lines.clear(); } + + public static Line findLine(String name) { + return lines.stream() + .filter(line -> line.getName().equals(name)) + .findFirst().orElseThrow(() -> new IllegalArgumentException("[ERROR] ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๋…ธ์„ ")); + } } diff --git a/src/main/java/subway/domain/Section.java b/src/main/java/subway/domain/Section.java new file mode 100644 index 000000000..aed82e2f8 --- /dev/null +++ b/src/main/java/subway/domain/Section.java @@ -0,0 +1,40 @@ +package subway.domain; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class Section { + + private Set stations = new HashSet<>(); + private int distance; + private int requiredTime; + + public Section(String station1, String station2, int distance, int requiredTime) { + stations.add(station1); + stations.add(station2); + this.distance = distance; + this.requiredTime = requiredTime; + } + + public boolean isInShortestPath(List shortestPath) { + for(int i=0; i getStations() { + return stations; + } + + public int getDistance() { + return distance; + } + + public int getRequiredTime() { + return requiredTime; + } +} diff --git a/src/main/java/subway/domain/SectionRepository.java b/src/main/java/subway/domain/SectionRepository.java new file mode 100644 index 000000000..0417a1d08 --- /dev/null +++ b/src/main/java/subway/domain/SectionRepository.java @@ -0,0 +1,94 @@ +package subway.domain; + +import org.jgrapht.GraphPath; +import org.jgrapht.alg.shortestpath.DijkstraShortestPath; +import org.jgrapht.graph.DefaultWeightedEdge; +import org.jgrapht.graph.WeightedMultigraph; +import subway.Menu.Menu; +import subway.PathResult; + +import java.util.ArrayList; +import java.util.List; + +public class SectionRepository { + + static WeightedMultigraph graphByDistance = new WeightedMultigraph(DefaultWeightedEdge.class); + static WeightedMultigraph graphByCost = new WeightedMultigraph(DefaultWeightedEdge.class); + static List
sections = new ArrayList<>(); + + public static void addSection(String lineName, String stationName, int sequence) { + Line line = LineRepository.findLine(lineName); + Station station = StationRepository.findStation(stationName); + line.addSection(sequence, station); + } + + public static void addSectinonDistanceAndTime(String station1, String station2, int distance, int requiredTime) { + addVertex(station1, station2); + setEdgeWeight(station1, station2, distance, requiredTime); + sections.add(new Section(station1, station2, distance, requiredTime)); + } + + private static void setEdgeWeight(String station1, String station2, int distance, int requiredTime) { + graphByDistance.setEdgeWeight(graphByDistance.addEdge(station1, station2), distance); + graphByCost.setEdgeWeight(graphByCost.addEdge(station1, station2), requiredTime); + } + + public static PathResult findshortestPath(String input, String departure, String destination) { + validateDepartureAndDestination(departure, destination); + + WeightedMultigraph graph = null; + if (input.equals(Menu.ROUTE_CRITERIA.SHORTEST_DISTANCE.getCode())) { + graph = graphByDistance; + } + if (input.equals(Menu.ROUTE_CRITERIA.SHORTEST_TIME.getCode())) { + graph = graphByCost; + } + List shortestPath = getShortestPath(graph, departure, destination); + + return new PathResult(shortestPath, calculateDistance(shortestPath), calculateRequiredTime(shortestPath)); + } + + public static List getShortestPath(WeightedMultigraph graph, String departure, String destination) { + DijkstraShortestPath dijkstraShortestPath = new DijkstraShortestPath(graph); + GraphPath graphPath = dijkstraShortestPath.getPath(departure, destination); + return graphPath.getVertexList(); + + } + + private static void validateDepartureAndDestination(String departure, String destination) { + StationRepository.findStation(departure); + StationRepository.deleteStation(destination); + if (departure.equals(destination)) { + throw new IllegalArgumentException("[ERROR] ์ถœ๋ฐœ์—ญ๊ณผ ๋„์ฐฉ์—ญ์ด ๊ฐ™์Šต๋‹ˆ๋‹ค."); + } + } + + private static int calculateRequiredTime(List shortestPath) { + return sections.stream() + .filter(section -> section.isInShortestPath(shortestPath)) + .mapToInt(Section::getRequiredTime) + .sum(); + } + + private static int calculateDistance(List shortestPath) { + return sections.stream() + .filter(section -> section.isInShortestPath(shortestPath)) + .mapToInt(Section::getDistance) + .sum(); + } + + private static void addVertex(String station1, String station2) { + if (!graphByDistance.containsVertex(station1)) { + graphByDistance.addVertex(station1); + } + if (!graphByDistance.containsVertex(station2)) { + graphByDistance.addVertex(station2); + } + if (!graphByCost.containsVertex(station1)) { + graphByCost.addVertex(station1); + } + if (!graphByCost.containsVertex(station2)) { + graphByCost.addVertex(station2); + } + } +} diff --git a/src/main/java/subway/domain/StationRepository.java b/src/main/java/subway/domain/StationRepository.java index 8ed9d103f..a475e9e85 100644 --- a/src/main/java/subway/domain/StationRepository.java +++ b/src/main/java/subway/domain/StationRepository.java @@ -23,4 +23,10 @@ public static boolean deleteStation(String name) { public static void deleteAll() { stations.clear(); } + + public static Station findStation(String name) { + return stations.stream() + .filter(station -> station.getName().equals(name)) + .findFirst().orElseThrow(() -> new IllegalArgumentException(("[ERROR] ์กด์žฌํ•˜์ง€ ์•Š๋Š” ์—ญ"))); + } } diff --git a/src/main/java/subway/screen/FeatureScreen.java b/src/main/java/subway/screen/FeatureScreen.java new file mode 100644 index 000000000..fc003f153 --- /dev/null +++ b/src/main/java/subway/screen/FeatureScreen.java @@ -0,0 +1,38 @@ +package subway.screen; + +import subway.PathResult; +import subway.view.InputView; +import subway.view.OutputView; + +import java.util.Scanner; + +import static subway.domain.SectionRepository.*; + +public class FeatureScreen implements ScreenModel { + + private final Scanner scanner; + private final String input; + + public FeatureScreen(Scanner scanner, String input) { + this.scanner = scanner; + this.input = input; + } + + @Override + public String showScreen() { + InputView inputView = new InputView(scanner); + String departure = inputView.enterDeparture(); + String destination = inputView.enterDestination(); + PathResult pathResult = findshortestPath(input, departure, destination); + OutputView.printRouteResult(pathResult); + + + + return GO_MAIN; + } + + @Override + public ScreenModel getNextScreen(String input) { + return new MainScreen(scanner); + } +} diff --git a/src/main/java/subway/screen/MainScreen.java b/src/main/java/subway/screen/MainScreen.java new file mode 100644 index 000000000..fb7e25466 --- /dev/null +++ b/src/main/java/subway/screen/MainScreen.java @@ -0,0 +1,40 @@ +package subway.screen; + +import subway.Menu.Menu; +import subway.view.InputView; +import subway.view.OutputView; + +import java.util.Arrays; +import java.util.Scanner; + +public class MainScreen implements ScreenModel { + + private final Scanner scanner; + + public MainScreen(Scanner scanner) { + this.scanner = scanner; + } + + @Override + public String showScreen() { + InputView inputView = new InputView(scanner); + + OutputView.printMainMenu(); + return inputView.enterFeature(); + } + + @Override + public ScreenModel getNextScreen(String input) { + if (anyMatchToMenu(input)){ + return new SelectCriteriaScreen(scanner); + } + throw new IllegalArgumentException("[ERROR] ์ž˜๋ชป๋œ ์ž…๋ ฅ์ž…๋‹ˆ๋‹ค.\n"); + } + + @Override + public boolean anyMatchToMenu(String input) { + return Arrays.stream(Menu.Main.values()) + .anyMatch(menu -> menu.getCode().equals(input)); + } + +} diff --git a/src/main/java/subway/screen/ScreenManager.java b/src/main/java/subway/screen/ScreenManager.java new file mode 100644 index 000000000..b7ce74e1a --- /dev/null +++ b/src/main/java/subway/screen/ScreenManager.java @@ -0,0 +1,34 @@ +package subway.screen; + +import java.util.Objects; +import java.util.Stack; + +public class ScreenManager { + private static Stack screens = new Stack<>(); + + public static boolean isEmpty() { + if (screens.isEmpty()) { + return true; + } + return false; + } + + public static void show(ScreenModel screen) { + String result = screen.showScreen(); + if (result == ScreenModel.GO_BACK) { + return; + } + addNextMenuScreen(screen.getNextScreen(result)); + + } + + public static void addNextMenuScreen(ScreenModel nextScreen) { + if (!Objects.isNull(nextScreen)) { + screens.push(nextScreen); + } + } + + public static ScreenModel pop() { + return screens.pop(); + } +} diff --git a/src/main/java/subway/screen/ScreenModel.java b/src/main/java/subway/screen/ScreenModel.java new file mode 100644 index 000000000..45a0d35d0 --- /dev/null +++ b/src/main/java/subway/screen/ScreenModel.java @@ -0,0 +1,23 @@ +package subway.screen; + +import subway.Menu.Menu; + +import java.util.Arrays; + +public interface ScreenModel { + public static final String GO_MAIN = "0"; + public static final String GO_BACK = "-1"; + public static final ScreenModel NOTHING = null; + + public default String showScreen() { + return GO_BACK; + } + + public default ScreenModel getNextScreen(String input) { + return NOTHING; + } + + public default boolean anyMatchToMenu(String input) { + return false; + } +} diff --git a/src/main/java/subway/screen/SelectCriteriaScreen.java b/src/main/java/subway/screen/SelectCriteriaScreen.java new file mode 100644 index 000000000..11fe93e36 --- /dev/null +++ b/src/main/java/subway/screen/SelectCriteriaScreen.java @@ -0,0 +1,44 @@ +package subway.screen; + +import subway.Menu.Menu; +import subway.view.InputView; +import subway.view.OutputView; + +import java.util.Arrays; +import java.util.Scanner; + +public class SelectCriteriaScreen implements ScreenModel { + + private final Scanner scanner; + + public SelectCriteriaScreen(Scanner scanner) { + this.scanner = scanner; + } + + @Override + public String showScreen() { + InputView inputView = new InputView(scanner); + + OutputView.printCriteriaMenu(); + String input = inputView.enterFeature(); + if (input.equals(Menu.Main.QUIT)) { + return GO_BACK; + } + return input; + } + + @Override + public ScreenModel getNextScreen(String input) { + if (anyMatchToMenu(input)) { + return new FeatureScreen(scanner, input); + } + throw new IllegalArgumentException("[ERROR] ์ž˜๋ชป๋œ ์ž…๋ ฅ์ž…๋‹ˆ๋‹ค.\n"); + } + + @Override + public boolean anyMatchToMenu(String input) { + return Arrays.stream(Menu.ROUTE_CRITERIA.values()) + .anyMatch(menu -> menu.getCode().equals(input)); + } + +} diff --git a/src/main/java/subway/view/InputView.java b/src/main/java/subway/view/InputView.java new file mode 100644 index 000000000..0ca9b7d96 --- /dev/null +++ b/src/main/java/subway/view/InputView.java @@ -0,0 +1,29 @@ +package subway.view; + +import java.util.Scanner; + +public class InputView { + + private final Scanner scanner; + + public InputView(Scanner scanner) { + this.scanner = scanner; + } + + public String enterFeature() { + System.out.println("## ์›ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์„ ํƒํ•˜์„ธ์š”."); + return scanner.nextLine(); + } + + public String enterDeparture() { + System.out.println(); + System.out.println("## ์ถœ๋ฐœ์—ญ์„ ์ž…๋ ฅํ•˜์„ธ์š”."); + return scanner.nextLine(); + } + + public String enterDestination() { + System.out.println(); + System.out.println("## ๋„์ฐฉ์—ญ์„ ์ž…๋ ฅํ•˜์„ธ์š”."); + return scanner.nextLine(); + } +} diff --git a/src/main/java/subway/view/OutputView.java b/src/main/java/subway/view/OutputView.java new file mode 100644 index 000000000..05167b51a --- /dev/null +++ b/src/main/java/subway/view/OutputView.java @@ -0,0 +1,43 @@ +package subway.view; + +import subway.Menu.Menu; +import subway.PathResult; + +import java.util.List; + +public class OutputView { + + private static final String newLine = "\n"; + + public static void printMainMenu() { + String message = "## ๋ฉ”์ธ ํ™”๋ฉด" + newLine; + for (Menu.Main menu : Menu.Main.values()) { + message += String.format("%s. %s" + newLine, menu.getCode(), menu.getKorean()); + } + System.out.println(message); + } + + public static void printCriteriaMenu() { + String message = "## ๊ฒฝ๋กœ ๊ธฐ์ค€" + newLine; + for (Menu.ROUTE_CRITERIA menu : Menu.ROUTE_CRITERIA.values()) { + message += String.format("%s. %s" + newLine, menu.getCode(), menu.getKorean()); + } + System.out.println(message); + } + + public static void printRouteResult(PathResult pathResult) { + List shortestPath = pathResult.getShortestPath(); + int shortestPathDistance = pathResult.getDistance(); + int requiredTime = pathResult.getRequiredTime(); + + System.out.println(); + System.out.println("## ์กฐํšŒ ๊ฒฐ๊ณผ"); + System.out.println("[INFO] ---"); + System.out.println(String.format("[INFO] ์ด ๊ฑฐ๋ฆฌ: %dkm", shortestPathDistance)); + System.out.println(String.format("[INFO] ์ด ์†Œ์š”์‹œ๊ฐ„: %d๋ถ„", requiredTime)); + System.out.println("[INFO] ---"); + shortestPath.stream() + .forEach(station -> System.out.println("[INFO] " + station)); + System.out.println(); + } +}