oh-my-oop 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (660) hide show
  1. package/MCP_STRUCTURE.md +301 -0
  2. package/README.md +167 -0
  3. package/SCOPE.md +27 -0
  4. package/dist/application/discovery.d.ts +133 -0
  5. package/dist/application/discovery.js +62 -0
  6. package/dist/application/discovery.js.map +1 -0
  7. package/dist/cli.d.ts +2 -0
  8. package/dist/cli.js +80 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/config.d.ts +16 -0
  11. package/dist/config.js +32 -0
  12. package/dist/config.js.map +1 -0
  13. package/dist/domain/collaborators.d.ts +2 -0
  14. package/dist/domain/collaborators.js +26 -0
  15. package/dist/domain/collaborators.js.map +1 -0
  16. package/dist/domain/ids.d.ts +4 -0
  17. package/dist/domain/ids.js +23 -0
  18. package/dist/domain/ids.js.map +1 -0
  19. package/dist/domain/model.d.ts +71 -0
  20. package/dist/domain/model.js +2 -0
  21. package/dist/domain/model.js.map +1 -0
  22. package/dist/domain/schemas.d.ts +213 -0
  23. package/dist/domain/schemas.js +79 -0
  24. package/dist/domain/schemas.js.map +1 -0
  25. package/dist/domain/stereotypes.d.ts +7 -0
  26. package/dist/domain/stereotypes.js +65 -0
  27. package/dist/domain/stereotypes.js.map +1 -0
  28. package/dist/index.d.ts +2 -0
  29. package/dist/index.js +21 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/io/classStore.d.ts +9 -0
  32. package/dist/io/classStore.js +39 -0
  33. package/dist/io/classStore.js.map +1 -0
  34. package/dist/io/collaborationStore.d.ts +7 -0
  35. package/dist/io/collaborationStore.js +32 -0
  36. package/dist/io/collaborationStore.js.map +1 -0
  37. package/dist/io/design.d.ts +3 -0
  38. package/dist/io/design.js +22 -0
  39. package/dist/io/design.js.map +1 -0
  40. package/dist/io/designIndex.d.ts +6 -0
  41. package/dist/io/designIndex.js +49 -0
  42. package/dist/io/designIndex.js.map +1 -0
  43. package/dist/io/frontmatter.d.ts +8 -0
  44. package/dist/io/frontmatter.js +31 -0
  45. package/dist/io/frontmatter.js.map +1 -0
  46. package/dist/io/history.d.ts +10 -0
  47. package/dist/io/history.js +38 -0
  48. package/dist/io/history.js.map +1 -0
  49. package/dist/io/useCaseStore.d.ts +8 -0
  50. package/dist/io/useCaseStore.js +36 -0
  51. package/dist/io/useCaseStore.js.map +1 -0
  52. package/dist/io/workspace.d.ts +14 -0
  53. package/dist/io/workspace.js +82 -0
  54. package/dist/io/workspace.js.map +1 -0
  55. package/dist/oop/commands.d.ts +446 -0
  56. package/dist/oop/commands.js +319 -0
  57. package/dist/oop/commands.js.map +1 -0
  58. package/dist/oop/conformance.d.ts +16 -0
  59. package/dist/oop/conformance.js +30 -0
  60. package/dist/oop/conformance.js.map +1 -0
  61. package/dist/prompts/discovery.d.ts +2 -0
  62. package/dist/prompts/discovery.js +41 -0
  63. package/dist/prompts/discovery.js.map +1 -0
  64. package/dist/prompts/imagineWithoutController.d.ts +2 -0
  65. package/dist/prompts/imagineWithoutController.js +75 -0
  66. package/dist/prompts/imagineWithoutController.js.map +1 -0
  67. package/dist/prompts/index.d.ts +2 -0
  68. package/dist/prompts/index.js +17 -0
  69. package/dist/prompts/index.js.map +1 -0
  70. package/dist/prompts/phasePressureTest.d.ts +2 -0
  71. package/dist/prompts/phasePressureTest.js +69 -0
  72. package/dist/prompts/phasePressureTest.js.map +1 -0
  73. package/dist/prompts/rddIntro.d.ts +2 -0
  74. package/dist/prompts/rddIntro.js +53 -0
  75. package/dist/prompts/rddIntro.js.map +1 -0
  76. package/dist/prompts/review.d.ts +2 -0
  77. package/dist/prompts/review.js +45 -0
  78. package/dist/prompts/review.js.map +1 -0
  79. package/dist/prompts/stateMachineIntrospect.d.ts +2 -0
  80. package/dist/prompts/stateMachineIntrospect.js +80 -0
  81. package/dist/prompts/stateMachineIntrospect.js.map +1 -0
  82. package/dist/prompts/tellDontAskRephrase.d.ts +2 -0
  83. package/dist/prompts/tellDontAskRephrase.js +66 -0
  84. package/dist/prompts/tellDontAskRephrase.js.map +1 -0
  85. package/dist/render/diff.d.ts +21 -0
  86. package/dist/render/diff.js +84 -0
  87. package/dist/render/diff.js.map +1 -0
  88. package/dist/render/mermaid.d.ts +24 -0
  89. package/dist/render/mermaid.js +53 -0
  90. package/dist/render/mermaid.js.map +1 -0
  91. package/dist/render/sideBySide.d.ts +14 -0
  92. package/dist/render/sideBySide.js +91 -0
  93. package/dist/render/sideBySide.js.map +1 -0
  94. package/dist/resources/index.d.ts +2 -0
  95. package/dist/resources/index.js +349 -0
  96. package/dist/resources/index.js.map +1 -0
  97. package/dist/server.d.ts +2 -0
  98. package/dist/server.js +22 -0
  99. package/dist/server.js.map +1 -0
  100. package/dist/tools/alternatives.d.ts +2 -0
  101. package/dist/tools/alternatives.js +9 -0
  102. package/dist/tools/alternatives.js.map +1 -0
  103. package/dist/tools/classes.d.ts +2 -0
  104. package/dist/tools/classes.js +13 -0
  105. package/dist/tools/classes.js.map +1 -0
  106. package/dist/tools/collaborations.d.ts +2 -0
  107. package/dist/tools/collaborations.js +8 -0
  108. package/dist/tools/collaborations.js.map +1 -0
  109. package/dist/tools/compare.d.ts +2 -0
  110. package/dist/tools/compare.js +9 -0
  111. package/dist/tools/compare.js.map +1 -0
  112. package/dist/tools/conformance.d.ts +3 -0
  113. package/dist/tools/conformance.js +11 -0
  114. package/dist/tools/conformance.js.map +1 -0
  115. package/dist/tools/diagram.d.ts +2 -0
  116. package/dist/tools/diagram.js +9 -0
  117. package/dist/tools/diagram.js.map +1 -0
  118. package/dist/tools/discovery.d.ts +2 -0
  119. package/dist/tools/discovery.js +23 -0
  120. package/dist/tools/discovery.js.map +1 -0
  121. package/dist/tools/index.d.ts +2 -0
  122. package/dist/tools/index.js +27 -0
  123. package/dist/tools/index.js.map +1 -0
  124. package/dist/tools/init.d.ts +2 -0
  125. package/dist/tools/init.js +9 -0
  126. package/dist/tools/init.js.map +1 -0
  127. package/dist/tools/oop.d.ts +9 -0
  128. package/dist/tools/oop.js +26 -0
  129. package/dist/tools/oop.js.map +1 -0
  130. package/dist/tools/responsibilities.d.ts +2 -0
  131. package/dist/tools/responsibilities.js +13 -0
  132. package/dist/tools/responsibilities.js.map +1 -0
  133. package/dist/tools/state.d.ts +2 -0
  134. package/dist/tools/state.js +8 -0
  135. package/dist/tools/state.js.map +1 -0
  136. package/dist/tools/useCases.d.ts +2 -0
  137. package/dist/tools/useCases.js +18 -0
  138. package/dist/tools/useCases.js.map +1 -0
  139. package/dist/tools/validate.d.ts +2 -0
  140. package/dist/tools/validate.js +9 -0
  141. package/dist/tools/validate.js.map +1 -0
  142. package/dist/tradeoff/engine.d.ts +61 -0
  143. package/dist/tradeoff/engine.js +171 -0
  144. package/dist/tradeoff/engine.js.map +1 -0
  145. package/dist/tradeoff/heuristics/classSplit.d.ts +3 -0
  146. package/dist/tradeoff/heuristics/classSplit.js +94 -0
  147. package/dist/tradeoff/heuristics/classSplit.js.map +1 -0
  148. package/dist/tradeoff/heuristics/collaborationShape.d.ts +2 -0
  149. package/dist/tradeoff/heuristics/collaborationShape.js +82 -0
  150. package/dist/tradeoff/heuristics/collaborationShape.js.map +1 -0
  151. package/dist/tradeoff/heuristics/collectionShape.d.ts +2 -0
  152. package/dist/tradeoff/heuristics/collectionShape.js +113 -0
  153. package/dist/tradeoff/heuristics/collectionShape.js.map +1 -0
  154. package/dist/tradeoff/heuristics/dualSubjectComparison.d.ts +2 -0
  155. package/dist/tradeoff/heuristics/dualSubjectComparison.js +114 -0
  156. package/dist/tradeoff/heuristics/dualSubjectComparison.js.map +1 -0
  157. package/dist/tradeoff/heuristics/errorHandling.d.ts +2 -0
  158. package/dist/tradeoff/heuristics/errorHandling.js +110 -0
  159. package/dist/tradeoff/heuristics/errorHandling.js.map +1 -0
  160. package/dist/tradeoff/heuristics/responsibilitySplit.d.ts +23 -0
  161. package/dist/tradeoff/heuristics/responsibilitySplit.js +183 -0
  162. package/dist/tradeoff/heuristics/responsibilitySplit.js.map +1 -0
  163. package/dist/tradeoff/heuristics/stereotypeChoice.d.ts +2 -0
  164. package/dist/tradeoff/heuristics/stereotypeChoice.js +23 -0
  165. package/dist/tradeoff/heuristics/stereotypeChoice.js.map +1 -0
  166. package/dist/tradeoff/heuristics/strategyOrPolicy.d.ts +2 -0
  167. package/dist/tradeoff/heuristics/strategyOrPolicy.js +110 -0
  168. package/dist/tradeoff/heuristics/strategyOrPolicy.js.map +1 -0
  169. package/dist/tradeoff/heuristics/valueObjectShape.d.ts +2 -0
  170. package/dist/tradeoff/heuristics/valueObjectShape.js +111 -0
  171. package/dist/tradeoff/heuristics/valueObjectShape.js.map +1 -0
  172. package/dist/tradeoff/templates.d.ts +2 -0
  173. package/dist/tradeoff/templates.js +33 -0
  174. package/dist/tradeoff/templates.js.map +1 -0
  175. package/dist/util/log.d.ts +1 -0
  176. package/dist/util/log.js +7 -0
  177. package/dist/util/log.js.map +1 -0
  178. package/dist/util/mcp.d.ts +4 -0
  179. package/dist/util/mcp.js +18 -0
  180. package/dist/util/mcp.js.map +1 -0
  181. package/dist/validate/cohesion.d.ts +3 -0
  182. package/dist/validate/cohesion.js +88 -0
  183. package/dist/validate/cohesion.js.map +1 -0
  184. package/dist/validate/collectionWrapper.d.ts +3 -0
  185. package/dist/validate/collectionWrapper.js +131 -0
  186. package/dist/validate/collectionWrapper.js.map +1 -0
  187. package/dist/validate/coupling.d.ts +3 -0
  188. package/dist/validate/coupling.js +47 -0
  189. package/dist/validate/coupling.js.map +1 -0
  190. package/dist/validate/cycle.d.ts +3 -0
  191. package/dist/validate/cycle.js +101 -0
  192. package/dist/validate/cycle.js.map +1 -0
  193. package/dist/validate/dataDuplication.d.ts +3 -0
  194. package/dist/validate/dataDuplication.js +150 -0
  195. package/dist/validate/dataDuplication.js.map +1 -0
  196. package/dist/validate/dependencyDirection.d.ts +3 -0
  197. package/dist/validate/dependencyDirection.js +106 -0
  198. package/dist/validate/dependencyDirection.js.map +1 -0
  199. package/dist/validate/dualUseKnowing.d.ts +3 -0
  200. package/dist/validate/dualUseKnowing.js +137 -0
  201. package/dist/validate/dualUseKnowing.js.map +1 -0
  202. package/dist/validate/emptyObjectFill.d.ts +3 -0
  203. package/dist/validate/emptyObjectFill.js +119 -0
  204. package/dist/validate/emptyObjectFill.js.map +1 -0
  205. package/dist/validate/findings.d.ts +22 -0
  206. package/dist/validate/findings.js +12 -0
  207. package/dist/validate/findings.js.map +1 -0
  208. package/dist/validate/functionDecompositionExcess.d.ts +3 -0
  209. package/dist/validate/functionDecompositionExcess.js +120 -0
  210. package/dist/validate/functionDecompositionExcess.js.map +1 -0
  211. package/dist/validate/functionNotObject.d.ts +3 -0
  212. package/dist/validate/functionNotObject.js +80 -0
  213. package/dist/validate/functionNotObject.js.map +1 -0
  214. package/dist/validate/godObject.d.ts +6 -0
  215. package/dist/validate/godObject.js +76 -0
  216. package/dist/validate/godObject.js.map +1 -0
  217. package/dist/validate/presentationInDomain.d.ts +3 -0
  218. package/dist/validate/presentationInDomain.js +57 -0
  219. package/dist/validate/presentationInDomain.js.map +1 -0
  220. package/dist/validate/primitiveWrapper.d.ts +3 -0
  221. package/dist/validate/primitiveWrapper.js +106 -0
  222. package/dist/validate/primitiveWrapper.js.map +1 -0
  223. package/dist/validate/rules.d.ts +24 -0
  224. package/dist/validate/rules.js +269 -0
  225. package/dist/validate/rules.js.map +1 -0
  226. package/dist/validate/singletonStatefulHolder.d.ts +3 -0
  227. package/dist/validate/singletonStatefulHolder.js +128 -0
  228. package/dist/validate/singletonStatefulHolder.js.map +1 -0
  229. package/dist/validate/strategyAsymmetry.d.ts +3 -0
  230. package/dist/validate/strategyAsymmetry.js +131 -0
  231. package/dist/validate/strategyAsymmetry.js.map +1 -0
  232. package/dist/validate/testability.d.ts +5 -0
  233. package/dist/validate/testability.js +157 -0
  234. package/dist/validate/testability.js.map +1 -0
  235. package/dist/validate/vagueName.d.ts +3 -0
  236. package/dist/validate/vagueName.js +136 -0
  237. package/dist/validate/vagueName.js.map +1 -0
  238. package/dist/validate/validationLocation.d.ts +3 -0
  239. package/dist/validate/validationLocation.js +120 -0
  240. package/dist/validate/validationLocation.js.map +1 -0
  241. package/lessons/STYLE_GUIDE.md +304 -0
  242. package/lessons/woowacourse-kotlin-blackjack/2chang5/33-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +293 -0
  243. package/lessons/woowacourse-kotlin-blackjack/Choisehyeon/52-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +106 -0
  244. package/lessons/woowacourse-kotlin-blackjack/Choisehyeon/9-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +282 -0
  245. package/lessons/woowacourse-kotlin-blackjack/DYGames/14-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +182 -0
  246. package/lessons/woowacourse-kotlin-blackjack/DYGames/37-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +122 -0
  247. package/lessons/woowacourse-kotlin-blackjack/EmilyCh0/12-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +117 -0
  248. package/lessons/woowacourse-kotlin-blackjack/EmilyCh0/38-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +291 -0
  249. package/lessons/woowacourse-kotlin-blackjack/HANDOVER.md +1475 -0
  250. package/lessons/woowacourse-kotlin-blackjack/HamBeomJoon/119-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +251 -0
  251. package/lessons/woowacourse-kotlin-blackjack/HamBeomJoon/137-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +459 -0
  252. package/lessons/woowacourse-kotlin-blackjack/Hevton/100-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +282 -0
  253. package/lessons/woowacourse-kotlin-blackjack/Hevton/82-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +303 -0
  254. package/lessons/woowacourse-kotlin-blackjack/Hogu59/71-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +134 -0
  255. package/lessons/woowacourse-kotlin-blackjack/Hogu59/96-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +323 -0
  256. package/lessons/woowacourse-kotlin-blackjack/JoYehyun99/66-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +210 -0
  257. package/lessons/woowacourse-kotlin-blackjack/Junyoung-WON/101-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +191 -0
  258. package/lessons/woowacourse-kotlin-blackjack/Junyoung-WON/80-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +253 -0
  259. package/lessons/woowacourse-kotlin-blackjack/Leeyerin0210/108-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +516 -0
  260. package/lessons/woowacourse-kotlin-blackjack/Leeyerin0210/133-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +541 -0
  261. package/lessons/woowacourse-kotlin-blackjack/RightHennessy/22-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +278 -0
  262. package/lessons/woowacourse-kotlin-blackjack/RightHennessy/48-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +188 -0
  263. package/lessons/woowacourse-kotlin-blackjack/SeongHoonC/16-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +228 -0
  264. package/lessons/woowacourse-kotlin-blackjack/SeongHoonC/54-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +227 -0
  265. package/lessons/woowacourse-kotlin-blackjack/Yunseok-Nam/76-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +279 -0
  266. package/lessons/woowacourse-kotlin-blackjack/Yunseok-Nam/86-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +203 -0
  267. package/lessons/woowacourse-kotlin-blackjack/aprilgom/105-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +162 -0
  268. package/lessons/woowacourse-kotlin-blackjack/aprilgom/64-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +279 -0
  269. package/lessons/woowacourse-kotlin-blackjack/boogi-woogi/18-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +188 -0
  270. package/lessons/woowacourse-kotlin-blackjack/boogi-woogi/36-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +769 -0
  271. package/lessons/woowacourse-kotlin-blackjack/briandr97/19-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +226 -0
  272. package/lessons/woowacourse-kotlin-blackjack/briandr97/59-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +193 -0
  273. package/lessons/woowacourse-kotlin-blackjack/chaehyuns/70-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +175 -0
  274. package/lessons/woowacourse-kotlin-blackjack/chaehyuns/98-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +206 -0
  275. package/lessons/woowacourse-kotlin-blackjack/chanho0908/123-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +277 -0
  276. package/lessons/woowacourse-kotlin-blackjack/chanho0908/150-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +219 -0
  277. package/lessons/woowacourse-kotlin-blackjack/chws0508/26-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +259 -0
  278. package/lessons/woowacourse-kotlin-blackjack/chws0508/43-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +189 -0
  279. package/lessons/woowacourse-kotlin-blackjack/cucumber99/109-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +351 -0
  280. package/lessons/woowacourse-kotlin-blackjack/cucumber99/149-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +147 -0
  281. package/lessons/woowacourse-kotlin-blackjack/devfeijoa/121-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +168 -0
  282. package/lessons/woowacourse-kotlin-blackjack/devfeijoa/153-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +116 -0
  283. package/lessons/woowacourse-kotlin-blackjack/doabletuple/126-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +680 -0
  284. package/lessons/woowacourse-kotlin-blackjack/doabletuple/142-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +739 -0
  285. package/lessons/woowacourse-kotlin-blackjack/donghyun81/116-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +297 -0
  286. package/lessons/woowacourse-kotlin-blackjack/donghyun81/147-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +244 -0
  287. package/lessons/woowacourse-kotlin-blackjack/dpcks0509/78-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +232 -0
  288. package/lessons/woowacourse-kotlin-blackjack/dpcks0509/88-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +137 -0
  289. package/lessons/woowacourse-kotlin-blackjack/etama123/112-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +269 -0
  290. package/lessons/woowacourse-kotlin-blackjack/etama123/148-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +240 -0
  291. package/lessons/woowacourse-kotlin-blackjack/gaeun5744/102-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +146 -0
  292. package/lessons/woowacourse-kotlin-blackjack/gaeun5744/69-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +224 -0
  293. package/lessons/woowacourse-kotlin-blackjack/gahyunkim/118-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +397 -0
  294. package/lessons/woowacourse-kotlin-blackjack/gahyunkim/141-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +215 -0
  295. package/lessons/woowacourse-kotlin-blackjack/giovannijunseokim/106-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +395 -0
  296. package/lessons/woowacourse-kotlin-blackjack/giovannijunseokim/134-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +219 -0
  297. package/lessons/woowacourse-kotlin-blackjack/haeum808/62-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +230 -0
  298. package/lessons/woowacourse-kotlin-blackjack/haeum808/89-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +169 -0
  299. package/lessons/woowacourse-kotlin-blackjack/hwannow/110-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +221 -0
  300. package/lessons/woowacourse-kotlin-blackjack/hwannow/132-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +573 -0
  301. package/lessons/woowacourse-kotlin-blackjack/hxeyexn/103-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +188 -0
  302. package/lessons/woowacourse-kotlin-blackjack/hxeyexn/81-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +301 -0
  303. package/lessons/woowacourse-kotlin-blackjack/hyemdooly/21-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +613 -0
  304. package/lessons/woowacourse-kotlin-blackjack/hyemdooly/35-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +691 -0
  305. package/lessons/woowacourse-kotlin-blackjack/hyunji1203/13-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +206 -0
  306. package/lessons/woowacourse-kotlin-blackjack/ii2001/79-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +153 -0
  307. package/lessons/woowacourse-kotlin-blackjack/ii2001/85-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +318 -0
  308. package/lessons/woowacourse-kotlin-blackjack/ijh1298/128-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +250 -0
  309. package/lessons/woowacourse-kotlin-blackjack/ijh1298/135-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +269 -0
  310. package/lessons/woowacourse-kotlin-blackjack/inseonyun/28-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +346 -0
  311. package/lessons/woowacourse-kotlin-blackjack/inseonyun/49-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +360 -0
  312. package/lessons/woowacourse-kotlin-blackjack/ippnsj/30-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +152 -0
  313. package/lessons/woowacourse-kotlin-blackjack/ippnsj/42-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +213 -0
  314. package/lessons/woowacourse-kotlin-blackjack/jaeyeongjo/73-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +247 -0
  315. package/lessons/woowacourse-kotlin-blackjack/jaeyeongjo/87-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +900 -0
  316. package/lessons/woowacourse-kotlin-blackjack/jerry8282/125-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +248 -0
  317. package/lessons/woowacourse-kotlin-blackjack/jerry8282/151-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +243 -0
  318. package/lessons/woowacourse-kotlin-blackjack/jinuemong/63-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +281 -0
  319. package/lessons/woowacourse-kotlin-blackjack/jinuemong/92-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +283 -0
  320. package/lessons/woowacourse-kotlin-blackjack/jiyuneel/113-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +348 -0
  321. package/lessons/woowacourse-kotlin-blackjack/jiyuneel/140-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +265 -0
  322. package/lessons/woowacourse-kotlin-blackjack/junjange/61-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +270 -0
  323. package/lessons/woowacourse-kotlin-blackjack/junjange/93-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +465 -0
  324. package/lessons/woowacourse-kotlin-blackjack/junseo511/107-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +296 -0
  325. package/lessons/woowacourse-kotlin-blackjack/junseo511/145-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +316 -0
  326. package/lessons/woowacourse-kotlin-blackjack/ki960213/11-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +175 -0
  327. package/lessons/woowacourse-kotlin-blackjack/kimhm0728/72-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +458 -0
  328. package/lessons/woowacourse-kotlin-blackjack/kimhm0728/97-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +225 -0
  329. package/lessons/woowacourse-kotlin-blackjack/kkosang/68-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +221 -0
  330. package/lessons/woowacourse-kotlin-blackjack/kkosang/94-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +158 -0
  331. package/lessons/woowacourse-kotlin-blackjack/kmkim2689/65-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +252 -0
  332. package/lessons/woowacourse-kotlin-blackjack/kmkim2689/90-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +460 -0
  333. package/lessons/woowacourse-kotlin-blackjack/krrong/32-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +216 -0
  334. package/lessons/woowacourse-kotlin-blackjack/krrong/46-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +285 -0
  335. package/lessons/woowacourse-kotlin-blackjack/m6z1/122-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +177 -0
  336. package/lessons/woowacourse-kotlin-blackjack/m6z1/144-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +155 -0
  337. package/lessons/woowacourse-kotlin-blackjack/medAndro/130-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +683 -0
  338. package/lessons/woowacourse-kotlin-blackjack/medAndro/143-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +678 -0
  339. package/lessons/woowacourse-kotlin-blackjack/moondev03/114-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +262 -0
  340. package/lessons/woowacourse-kotlin-blackjack/moondev03/131-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +498 -0
  341. package/lessons/woowacourse-kotlin-blackjack/murjune/77-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +287 -0
  342. package/lessons/woowacourse-kotlin-blackjack/murjune/91-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +280 -0
  343. package/lessons/woowacourse-kotlin-blackjack/no1msh/31-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +250 -0
  344. package/lessons/woowacourse-kotlin-blackjack/otter66/24-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +302 -0
  345. package/lessons/woowacourse-kotlin-blackjack/otter66/58-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +391 -0
  346. package/lessons/woowacourse-kotlin-blackjack/oungsi2000/111-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +253 -0
  347. package/lessons/woowacourse-kotlin-blackjack/oungsi2000/136-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +540 -0
  348. package/lessons/woowacourse-kotlin-blackjack/parkjiminnnn/117-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +819 -0
  349. package/lessons/woowacourse-kotlin-blackjack/parkjiminnnn/139-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +683 -0
  350. package/lessons/woowacourse-kotlin-blackjack/pingu244/20-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +258 -0
  351. package/lessons/woowacourse-kotlin-blackjack/pingu244/41-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +171 -0
  352. package/lessons/woowacourse-kotlin-blackjack/re4rk/34-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +289 -0
  353. package/lessons/woowacourse-kotlin-blackjack/re4rk/8-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +297 -0
  354. package/lessons/woowacourse-kotlin-blackjack/rhkrwngud445/17-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +279 -0
  355. package/lessons/woowacourse-kotlin-blackjack/rhkrwngud445/50-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +145 -0
  356. package/lessons/woowacourse-kotlin-blackjack/rhthrhrl0/23-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +253 -0
  357. package/lessons/woowacourse-kotlin-blackjack/rhthrhrl0/39-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +238 -0
  358. package/lessons/woowacourse-kotlin-blackjack/rosemin928/129-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +726 -0
  359. package/lessons/woowacourse-kotlin-blackjack/rosemin928/138-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +845 -0
  360. package/lessons/woowacourse-kotlin-blackjack/s6m1n/67-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +220 -0
  361. package/lessons/woowacourse-kotlin-blackjack/s6m1n/99-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +229 -0
  362. package/lessons/woowacourse-kotlin-blackjack/s9hn/10-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +284 -0
  363. package/lessons/woowacourse-kotlin-blackjack/sh1mj1/75-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +224 -0
  364. package/lessons/woowacourse-kotlin-blackjack/songpink/74-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +238 -0
  365. package/lessons/woowacourse-kotlin-blackjack/songpink/95-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +216 -0
  366. package/lessons/woowacourse-kotlin-blackjack/sujin9/15-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +132 -0
  367. package/lessons/woowacourse-kotlin-blackjack/sujin9/47-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +265 -0
  368. package/lessons/woowacourse-kotlin-blackjack/tmdgh1592/29-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +305 -0
  369. package/lessons/woowacourse-kotlin-blackjack/tmdgh1592/51-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +278 -0
  370. package/lessons/woowacourse-kotlin-blackjack/tobae-time/115-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +305 -0
  371. package/lessons/woowacourse-kotlin-blackjack/tobae-time/154-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +298 -0
  372. package/lessons/woowacourse-kotlin-blackjack/whk06061/25-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +235 -0
  373. package/lessons/woowacourse-kotlin-blackjack/whk06061/53-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +130 -0
  374. package/lessons/woowacourse-kotlin-blackjack/wondroid-world/124-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +486 -0
  375. package/lessons/woowacourse-kotlin-blackjack/wondroid-world/152-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +482 -0
  376. package/lessons/woowacourse-kotlin-blackjack/yrsel/120-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +194 -0
  377. package/lessons/woowacourse-kotlin-blackjack/yrsel/146-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +444 -0
  378. package/lessons/woowacourse-kotlin-lotto/2chang5/27-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +155 -0
  379. package/lessons/woowacourse-kotlin-lotto/2chang5/52-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +187 -0
  380. package/lessons/woowacourse-kotlin-lotto/Choisehyeon/14-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +206 -0
  381. package/lessons/woowacourse-kotlin-lotto/Choisehyeon/47-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +119 -0
  382. package/lessons/woowacourse-kotlin-lotto/DYGames/2-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +83 -0
  383. package/lessons/woowacourse-kotlin-lotto/DYGames/34-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +88 -0
  384. package/lessons/woowacourse-kotlin-lotto/EmilyCh0/12-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +107 -0
  385. package/lessons/woowacourse-kotlin-lotto/EmilyCh0/40-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +135 -0
  386. package/lessons/woowacourse-kotlin-lotto/HANDOVER.md +217 -0
  387. package/lessons/woowacourse-kotlin-lotto/HamBeomJoon/121-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +66 -0
  388. package/lessons/woowacourse-kotlin-lotto/HamBeomJoon/139-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +75 -0
  389. package/lessons/woowacourse-kotlin-lotto/Hevton/76-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +21 -0
  390. package/lessons/woowacourse-kotlin-lotto/Hevton/92-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +122 -0
  391. package/lessons/woowacourse-kotlin-lotto/Hogu59/100-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +110 -0
  392. package/lessons/woowacourse-kotlin-lotto/Hogu59/68-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +84 -0
  393. package/lessons/woowacourse-kotlin-lotto/JoYehyun99/60-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +176 -0
  394. package/lessons/woowacourse-kotlin-lotto/JoYehyun99/96-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +71 -0
  395. package/lessons/woowacourse-kotlin-lotto/Junyoung-WON/61-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +143 -0
  396. package/lessons/woowacourse-kotlin-lotto/Junyoung-WON/93-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +16 -0
  397. package/lessons/woowacourse-kotlin-lotto/Leeyerin0210/109-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +57 -0
  398. package/lessons/woowacourse-kotlin-lotto/Leeyerin0210/135-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +115 -0
  399. package/lessons/woowacourse-kotlin-lotto/PROGRESS.md +160 -0
  400. package/lessons/woowacourse-kotlin-lotto/README.md +77 -0
  401. package/lessons/woowacourse-kotlin-lotto/RightHennessy/32-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +178 -0
  402. package/lessons/woowacourse-kotlin-lotto/RightHennessy/5-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +149 -0
  403. package/lessons/woowacourse-kotlin-lotto/SUMMARY.md +369 -0
  404. package/lessons/woowacourse-kotlin-lotto/SeongHoonC/25-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +129 -0
  405. package/lessons/woowacourse-kotlin-lotto/SeongHoonC/37-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +27 -0
  406. package/lessons/woowacourse-kotlin-lotto/Yunseok-Nam/72-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +137 -0
  407. package/lessons/woowacourse-kotlin-lotto/Yunseok-Nam/86-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +17 -0
  408. package/lessons/woowacourse-kotlin-lotto/aprilgom/102-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +62 -0
  409. package/lessons/woowacourse-kotlin-lotto/aprilgom/64-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +146 -0
  410. package/lessons/woowacourse-kotlin-lotto/boogi-woogi/11-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +26 -0
  411. package/lessons/woowacourse-kotlin-lotto/boogi-woogi/29-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +26 -0
  412. package/lessons/woowacourse-kotlin-lotto/briandr97/26-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +52 -0
  413. package/lessons/woowacourse-kotlin-lotto/briandr97/51-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +123 -0
  414. package/lessons/woowacourse-kotlin-lotto/chaehyuns/71-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +115 -0
  415. package/lessons/woowacourse-kotlin-lotto/chaehyuns/97-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +107 -0
  416. package/lessons/woowacourse-kotlin-lotto/chanho0908/124-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +51 -0
  417. package/lessons/woowacourse-kotlin-lotto/chanho0908/129-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +149 -0
  418. package/lessons/woowacourse-kotlin-lotto/chws0508/24-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +117 -0
  419. package/lessons/woowacourse-kotlin-lotto/chws0508/50-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +167 -0
  420. package/lessons/woowacourse-kotlin-lotto/cucumber99/116-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +155 -0
  421. package/lessons/woowacourse-kotlin-lotto/cucumber99/147-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +223 -0
  422. package/lessons/woowacourse-kotlin-lotto/devfeijoa/125-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +68 -0
  423. package/lessons/woowacourse-kotlin-lotto/devfeijoa/153-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +107 -0
  424. package/lessons/woowacourse-kotlin-lotto/doabletuple/119-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +157 -0
  425. package/lessons/woowacourse-kotlin-lotto/doabletuple/138-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +77 -0
  426. package/lessons/woowacourse-kotlin-lotto/donghyun81/111-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +67 -0
  427. package/lessons/woowacourse-kotlin-lotto/donghyun81/152-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +124 -0
  428. package/lessons/woowacourse-kotlin-lotto/dpcks0509/80-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +141 -0
  429. package/lessons/woowacourse-kotlin-lotto/dpcks0509/87-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +134 -0
  430. package/lessons/woowacourse-kotlin-lotto/etama123/112-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +170 -0
  431. package/lessons/woowacourse-kotlin-lotto/etama123/148-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +183 -0
  432. package/lessons/woowacourse-kotlin-lotto/gaeun5744/101-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +21 -0
  433. package/lessons/woowacourse-kotlin-lotto/gaeun5744/78-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +158 -0
  434. package/lessons/woowacourse-kotlin-lotto/gahyunkim/107-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +83 -0
  435. package/lessons/woowacourse-kotlin-lotto/gahyunkim/136-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +51 -0
  436. package/lessons/woowacourse-kotlin-lotto/giovannijunseokim/106-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +171 -0
  437. package/lessons/woowacourse-kotlin-lotto/giovannijunseokim/137-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +111 -0
  438. package/lessons/woowacourse-kotlin-lotto/haeum808/67-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +52 -0
  439. package/lessons/woowacourse-kotlin-lotto/haeum808/95-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +97 -0
  440. package/lessons/woowacourse-kotlin-lotto/hwannow/113-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +235 -0
  441. package/lessons/woowacourse-kotlin-lotto/hwannow/132-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +149 -0
  442. package/lessons/woowacourse-kotlin-lotto/hxeyexn/77-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +141 -0
  443. package/lessons/woowacourse-kotlin-lotto/hxeyexn/98-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +162 -0
  444. package/lessons/woowacourse-kotlin-lotto/hyemdooly/17-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +19 -0
  445. package/lessons/woowacourse-kotlin-lotto/hyemdooly/28-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +23 -0
  446. package/lessons/woowacourse-kotlin-lotto/hyunji1203/15-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +171 -0
  447. package/lessons/woowacourse-kotlin-lotto/hyunji1203/48-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +150 -0
  448. package/lessons/woowacourse-kotlin-lotto/ii2001/62-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +104 -0
  449. package/lessons/woowacourse-kotlin-lotto/ii2001/88-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +20 -0
  450. package/lessons/woowacourse-kotlin-lotto/ijh1298/122-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +179 -0
  451. package/lessons/woowacourse-kotlin-lotto/ijh1298/133-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +153 -0
  452. package/lessons/woowacourse-kotlin-lotto/inseonyun/3-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +222 -0
  453. package/lessons/woowacourse-kotlin-lotto/inseonyun/49-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +166 -0
  454. package/lessons/woowacourse-kotlin-lotto/ippnsj/16-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +154 -0
  455. package/lessons/woowacourse-kotlin-lotto/ippnsj/55-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +145 -0
  456. package/lessons/woowacourse-kotlin-lotto/jaeyeongjo/59-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +68 -0
  457. package/lessons/woowacourse-kotlin-lotto/jaeyeongjo/83-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +53 -0
  458. package/lessons/woowacourse-kotlin-lotto/jerry8282/115-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +97 -0
  459. package/lessons/woowacourse-kotlin-lotto/jerry8282/134-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +145 -0
  460. package/lessons/woowacourse-kotlin-lotto/jinuemong/63-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +144 -0
  461. package/lessons/woowacourse-kotlin-lotto/jinuemong/89-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +148 -0
  462. package/lessons/woowacourse-kotlin-lotto/jiyuneel/128-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +52 -0
  463. package/lessons/woowacourse-kotlin-lotto/jiyuneel/144-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +149 -0
  464. package/lessons/woowacourse-kotlin-lotto/junjange/58-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +148 -0
  465. package/lessons/woowacourse-kotlin-lotto/junjange/81-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +178 -0
  466. package/lessons/woowacourse-kotlin-lotto/junseo511/120-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +153 -0
  467. package/lessons/woowacourse-kotlin-lotto/junseo511/131-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +188 -0
  468. package/lessons/woowacourse-kotlin-lotto/ki960213/43-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +24 -0
  469. package/lessons/woowacourse-kotlin-lotto/ki960213/8-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +159 -0
  470. package/lessons/woowacourse-kotlin-lotto/kimhm0728/74-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +50 -0
  471. package/lessons/woowacourse-kotlin-lotto/kimhm0728/94-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +176 -0
  472. package/lessons/woowacourse-kotlin-lotto/kkosang/85-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +145 -0
  473. package/lessons/woowacourse-kotlin-lotto/kmkim2689/70-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +97 -0
  474. package/lessons/woowacourse-kotlin-lotto/kmkim2689/82-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +157 -0
  475. package/lessons/woowacourse-kotlin-lotto/krrong/19-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +161 -0
  476. package/lessons/woowacourse-kotlin-lotto/krrong/41-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +73 -0
  477. package/lessons/woowacourse-kotlin-lotto/m6z1/105-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +67 -0
  478. package/lessons/woowacourse-kotlin-lotto/m6z1/151-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +104 -0
  479. package/lessons/woowacourse-kotlin-lotto/medAndro/127-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +186 -0
  480. package/lessons/woowacourse-kotlin-lotto/medAndro/130-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +132 -0
  481. package/lessons/woowacourse-kotlin-lotto/moondev03/110-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +66 -0
  482. package/lessons/woowacourse-kotlin-lotto/moondev03/141-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +155 -0
  483. package/lessons/woowacourse-kotlin-lotto/murjune/69-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +143 -0
  484. package/lessons/woowacourse-kotlin-lotto/murjune/90-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +177 -0
  485. package/lessons/woowacourse-kotlin-lotto/no1msh/20-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +69 -0
  486. package/lessons/woowacourse-kotlin-lotto/no1msh/46-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +143 -0
  487. package/lessons/woowacourse-kotlin-lotto/otter66/13-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +178 -0
  488. package/lessons/woowacourse-kotlin-lotto/otter66/53-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +160 -0
  489. package/lessons/woowacourse-kotlin-lotto/oungsi2000/126-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +71 -0
  490. package/lessons/woowacourse-kotlin-lotto/oungsi2000/149-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +56 -0
  491. package/lessons/woowacourse-kotlin-lotto/parkjiminnnn/117-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +129 -0
  492. package/lessons/woowacourse-kotlin-lotto/parkjiminnnn/146-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +173 -0
  493. package/lessons/woowacourse-kotlin-lotto/pingu244/33-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +21 -0
  494. package/lessons/woowacourse-kotlin-lotto/pingu244/54-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +30 -0
  495. package/lessons/woowacourse-kotlin-lotto/pingu244/7-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +19 -0
  496. package/lessons/woowacourse-kotlin-lotto/re4rk/31-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +143 -0
  497. package/lessons/woowacourse-kotlin-lotto/re4rk/4-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +66 -0
  498. package/lessons/woowacourse-kotlin-lotto/rhkrwngud445/23-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +26 -0
  499. package/lessons/woowacourse-kotlin-lotto/rhkrwngud445/38-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +129 -0
  500. package/lessons/woowacourse-kotlin-lotto/rhthrhrl0/21-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +146 -0
  501. package/lessons/woowacourse-kotlin-lotto/rhthrhrl0/36-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +150 -0
  502. package/lessons/woowacourse-kotlin-lotto/rosemin928/123-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +179 -0
  503. package/lessons/woowacourse-kotlin-lotto/rosemin928/140-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +126 -0
  504. package/lessons/woowacourse-kotlin-lotto/s6m1n/103-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +119 -0
  505. package/lessons/woowacourse-kotlin-lotto/s6m1n/66-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +118 -0
  506. package/lessons/woowacourse-kotlin-lotto/s9hn/18-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +112 -0
  507. package/lessons/woowacourse-kotlin-lotto/sh1mj1/75-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +104 -0
  508. package/lessons/woowacourse-kotlin-lotto/sh1mj1/91-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +140 -0
  509. package/lessons/woowacourse-kotlin-lotto/songpink/65-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +96 -0
  510. package/lessons/woowacourse-kotlin-lotto/songpink/99-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +64 -0
  511. package/lessons/woowacourse-kotlin-lotto/sujin9/10-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +20 -0
  512. package/lessons/woowacourse-kotlin-lotto/sujin9/35-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +124 -0
  513. package/lessons/woowacourse-kotlin-lotto/tmdgh1592/22-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +30 -0
  514. package/lessons/woowacourse-kotlin-lotto/tmdgh1592/30-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +20 -0
  515. package/lessons/woowacourse-kotlin-lotto/tobae-time/114-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +158 -0
  516. package/lessons/woowacourse-kotlin-lotto/tobae-time/145-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +120 -0
  517. package/lessons/woowacourse-kotlin-lotto/whk06061/42-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +21 -0
  518. package/lessons/woowacourse-kotlin-lotto/whk06061/9-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +89 -0
  519. package/lessons/woowacourse-kotlin-lotto/wondroid-world/118-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +100 -0
  520. package/lessons/woowacourse-kotlin-lotto/wondroid-world/150-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +142 -0
  521. package/lessons/woowacourse-kotlin-lotto/yrsel/108-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +124 -0
  522. package/lessons/woowacourse-kotlin-lotto/yrsel/143-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +108 -0
  523. package/lessons/woowacourse-racingcar/2chang5/33-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +56 -0
  524. package/lessons/woowacourse-racingcar/2chang5/75-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  525. package/lessons/woowacourse-racingcar/CFalws/85-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +56 -0
  526. package/lessons/woowacourse-racingcar/Choisehyeon/46-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +61 -0
  527. package/lessons/woowacourse-racingcar/DYGames/49-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +62 -0
  528. package/lessons/woowacourse-racingcar/EmilyCh0/40-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +64 -0
  529. package/lessons/woowacourse-racingcar/EmilyCh0/57-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  530. package/lessons/woowacourse-racingcar/HamBeomJoon/137-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  531. package/lessons/woowacourse-racingcar/HamBeomJoon/170-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
  532. package/lessons/woowacourse-racingcar/Hevton/106-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  533. package/lessons/woowacourse-racingcar/Hevton/118-/353/246/254/355/214/251/355/204/260/353/247/201.md +51 -0
  534. package/lessons/woowacourse-racingcar/Hogu59/108-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +56 -0
  535. package/lessons/woowacourse-racingcar/Hogu59/125-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +59 -0
  536. package/lessons/woowacourse-racingcar/JoYehyun99/111-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
  537. package/lessons/woowacourse-racingcar/JoYehyun99/88-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +45 -0
  538. package/lessons/woowacourse-racingcar/Junyoung-WON/127-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
  539. package/lessons/woowacourse-racingcar/Junyoung-WON/90-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
  540. package/lessons/woowacourse-racingcar/Leeyerin0210/133-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
  541. package/lessons/woowacourse-racingcar/Leeyerin0210/159-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  542. package/lessons/woowacourse-racingcar/PROGRESS.md +94 -0
  543. package/lessons/woowacourse-racingcar/README.md +69 -0
  544. package/lessons/woowacourse-racingcar/RightHennessy/51-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  545. package/lessons/woowacourse-racingcar/RightHennessy/58-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
  546. package/lessons/woowacourse-racingcar/RunaNam/81-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +44 -0
  547. package/lessons/woowacourse-racingcar/SUMMARY.md +339 -0
  548. package/lessons/woowacourse-racingcar/SeongHoonC/37-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
  549. package/lessons/woowacourse-racingcar/SeongHoonC/66-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +48 -0
  550. package/lessons/woowacourse-racingcar/Songusika/84-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +60 -0
  551. package/lessons/woowacourse-racingcar/Yunseok-Nam/114-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +43 -0
  552. package/lessons/woowacourse-racingcar/Yunseok-Nam/96-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  553. package/lessons/woowacourse-racingcar/aprilgom/130-/353/246/254/355/214/251/355/204/260/353/247/201.md +52 -0
  554. package/lessons/woowacourse-racingcar/aprilgom/97-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
  555. package/lessons/woowacourse-racingcar/awesomeo184/23-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +48 -0
  556. package/lessons/woowacourse-racingcar/boogi-woogi/35-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +62 -0
  557. package/lessons/woowacourse-racingcar/boogi-woogi/59-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  558. package/lessons/woowacourse-racingcar/briandr97/54-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
  559. package/lessons/woowacourse-racingcar/chaehyuns/131-/353/246/254/355/214/251/355/204/260/353/247/201.md +49 -0
  560. package/lessons/woowacourse-racingcar/chaehyuns/99-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +52 -0
  561. package/lessons/woowacourse-racingcar/chanho0908/147-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  562. package/lessons/woowacourse-racingcar/chanho0908/160-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
  563. package/lessons/woowacourse-racingcar/chws0508/45-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +61 -0
  564. package/lessons/woowacourse-racingcar/chws0508/73-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +46 -0
  565. package/lessons/woowacourse-racingcar/cucumber99/132-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  566. package/lessons/woowacourse-racingcar/cucumber99/177-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  567. package/lessons/woowacourse-racingcar/devfeijoa/146-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
  568. package/lessons/woowacourse-racingcar/doabletuple/149-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  569. package/lessons/woowacourse-racingcar/doabletuple/175-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  570. package/lessons/woowacourse-racingcar/donghyun81/154-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +58 -0
  571. package/lessons/woowacourse-racingcar/dpcks0509/103-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +48 -0
  572. package/lessons/woowacourse-racingcar/dpcks0509/112-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +48 -0
  573. package/lessons/woowacourse-racingcar/drunkenhw/82-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +60 -0
  574. package/lessons/woowacourse-racingcar/etama123/145-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +59 -0
  575. package/lessons/woowacourse-racingcar/gaeun5744/124-/353/246/254/355/214/251/355/204/260/353/247/201.md +53 -0
  576. package/lessons/woowacourse-racingcar/gaeun5744/93-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +60 -0
  577. package/lessons/woowacourse-racingcar/gahyunkim/134-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  578. package/lessons/woowacourse-racingcar/gahyunkim/164-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  579. package/lessons/woowacourse-racingcar/giovannijunseokim/140-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  580. package/lessons/woowacourse-racingcar/haeum808/101-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  581. package/lessons/woowacourse-racingcar/haeum808/129-/353/246/254/355/214/251/355/204/260/353/247/201.md +46 -0
  582. package/lessons/woowacourse-racingcar/hwannow/141-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +56 -0
  583. package/lessons/woowacourse-racingcar/hwannow/157-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +45 -0
  584. package/lessons/woowacourse-racingcar/hxeyexn/109-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +61 -0
  585. package/lessons/woowacourse-racingcar/hxeyexn/128-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +59 -0
  586. package/lessons/woowacourse-racingcar/hyemdooly/50-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +48 -0
  587. package/lessons/woowacourse-racingcar/hyemdooly/68-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  588. package/lessons/woowacourse-racingcar/hyunji1203/29-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  589. package/lessons/woowacourse-racingcar/hyunji1203/60-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
  590. package/lessons/woowacourse-racingcar/ii2001/102-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +42 -0
  591. package/lessons/woowacourse-racingcar/ii2001/122-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
  592. package/lessons/woowacourse-racingcar/ijh1298/144-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
  593. package/lessons/woowacourse-racingcar/injoon2019/24-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +58 -0
  594. package/lessons/woowacourse-racingcar/inseonyun/44-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +60 -0
  595. package/lessons/woowacourse-racingcar/inseonyun/76-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  596. package/lessons/woowacourse-racingcar/ippnsj/36-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  597. package/lessons/woowacourse-racingcar/ippnsj/67-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
  598. package/lessons/woowacourse-racingcar/jaeyeongjo/110-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +39 -0
  599. package/lessons/woowacourse-racingcar/jaeyeongjo/89-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +46 -0
  600. package/lessons/woowacourse-racingcar/jinuemong/104-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
  601. package/lessons/woowacourse-racingcar/jinuemong/117-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +42 -0
  602. package/lessons/woowacourse-racingcar/jiyuneel/142-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +59 -0
  603. package/lessons/woowacourse-racingcar/junjange/113-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +41 -0
  604. package/lessons/woowacourse-racingcar/junjange/87-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +39 -0
  605. package/lessons/woowacourse-racingcar/junseo511/148-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +52 -0
  606. package/lessons/woowacourse-racingcar/junseo511/165-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +51 -0
  607. package/lessons/woowacourse-racingcar/ki960213/32-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  608. package/lessons/woowacourse-racingcar/ki960213/63-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +51 -0
  609. package/lessons/woowacourse-racingcar/kimhm0728/100-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +52 -0
  610. package/lessons/woowacourse-racingcar/kimhm0728/116-/353/246/254/355/214/251/355/204/260/353/247/201.md +54 -0
  611. package/lessons/woowacourse-racingcar/kkosang/105-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  612. package/lessons/woowacourse-racingcar/kkosang/126-/353/246/254/355/214/251/355/204/260/353/247/201.md +53 -0
  613. package/lessons/woowacourse-racingcar/kmkim2689/123-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
  614. package/lessons/woowacourse-racingcar/kmkim2689/92-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  615. package/lessons/woowacourse-racingcar/krrong/34-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +63 -0
  616. package/lessons/woowacourse-racingcar/m6z1/150-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  617. package/lessons/woowacourse-racingcar/m6z1/156-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +40 -0
  618. package/lessons/woowacourse-racingcar/medAndro/153-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  619. package/lessons/woowacourse-racingcar/moondev03/135-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
  620. package/lessons/woowacourse-racingcar/moondev03/161-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +52 -0
  621. package/lessons/woowacourse-racingcar/murjune/121-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
  622. package/lessons/woowacourse-racingcar/murjune/95-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  623. package/lessons/woowacourse-racingcar/no1msh/43-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  624. package/lessons/woowacourse-racingcar/no1msh/69-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +60 -0
  625. package/lessons/woowacourse-racingcar/otter66/48-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  626. package/lessons/woowacourse-racingcar/otter66/77-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +52 -0
  627. package/lessons/woowacourse-racingcar/oungsi2000/152-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +56 -0
  628. package/lessons/woowacourse-racingcar/oungsi2000/187-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  629. package/lessons/woowacourse-racingcar/parkjiminnnn/143-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +58 -0
  630. package/lessons/woowacourse-racingcar/parkjiminnnn/158-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  631. package/lessons/woowacourse-racingcar/pingu244/38-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +58 -0
  632. package/lessons/woowacourse-racingcar/pingu244/62-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +59 -0
  633. package/lessons/woowacourse-racingcar/re4rk/28-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +60 -0
  634. package/lessons/woowacourse-racingcar/re4rk/55-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  635. package/lessons/woowacourse-racingcar/rhkrwngud445/42-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  636. package/lessons/woowacourse-racingcar/rhkrwngud445/74-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +47 -0
  637. package/lessons/woowacourse-racingcar/rhthrhrl0/31-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +43 -0
  638. package/lessons/woowacourse-racingcar/rosemin928/138-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  639. package/lessons/woowacourse-racingcar/rosemin928/171-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +38 -0
  640. package/lessons/woowacourse-racingcar/s6m1n/120-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  641. package/lessons/woowacourse-racingcar/s6m1n/91-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +62 -0
  642. package/lessons/woowacourse-racingcar/s9hn/53-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +44 -0
  643. package/lessons/woowacourse-racingcar/s9hn/78-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +43 -0
  644. package/lessons/woowacourse-racingcar/sh1mj1/107-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  645. package/lessons/woowacourse-racingcar/sh1mj1/115-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +61 -0
  646. package/lessons/woowacourse-racingcar/songpink/119-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +51 -0
  647. package/lessons/woowacourse-racingcar/songpink/98-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  648. package/lessons/woowacourse-racingcar/sujin9/52-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +48 -0
  649. package/lessons/woowacourse-racingcar/sujin9/61-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +47 -0
  650. package/lessons/woowacourse-racingcar/tmdgh1592/47-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
  651. package/lessons/woowacourse-racingcar/tmdgh1592/64-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  652. package/lessons/woowacourse-racingcar/tobae-time/151-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +51 -0
  653. package/lessons/woowacourse-racingcar/tobae-time/167-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +43 -0
  654. package/lessons/woowacourse-racingcar/whk06061/41-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +58 -0
  655. package/lessons/woowacourse-racingcar/wondroid-world/136-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
  656. package/lessons/woowacourse-racingcar/wondroid-world/166-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
  657. package/lessons/woowacourse-racingcar/yrsel/139-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  658. package/lessons/woowacourse-racingcar/yujamint/83-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +59 -0
  659. package/package.json +46 -0
  660. package/skills/oh-my-oop/SKILL.md +39 -0
@@ -0,0 +1,149 @@
1
+ # PR #144 — [포르] 2단계 로또
2
+
3
+ - **Reviewee:** [@jiyuneel](https://github.com/jiyuneel)
4
+ - **PR:** https://github.com/woowacourse/kotlin-lotto/pull/144
5
+ - **단계:** 2단계 (수동 로또)
6
+ - **리뷰어:** @krrong
7
+ - **라인 코멘트:** 16
8
+
9
+ ## 잘한 점 (설계 관점)
10
+
11
+ - **`LottoNumber.getAll()` 메시지화** — 학생 직접: "*객체에게 메시지를 던지는 연습을 꾸준히 해야 할 것 같네요..!* 🙂".
12
+ - **`WinningLotto.getLottoResult(lottos)`** — *Tell, Don't Ask*. 리뷰어 칭찬: "*WinningLotto가 스스로 일을 할 수 있도록 만들었네요* 👏".
13
+ - **`LottoCount` value class** — 리뷰어 칭찬: "*로또 개수 포장* 👏".
14
+ - **`Lotto.of` (수동) vs `Lotto.create` (자동) 팩토리 분리** — 후속 라운드에서 의도 명확화.
15
+ - **`LottoMachine` 인터페이스 + `ManualLottoMachine`/`AutomaticLottoMachine`** — Strategy. 리뷰어 칭찬: "*공통 로직을 인터페이스로 추상화* 💯".
16
+ - **학생이 *시도 후 폐기*도 PR에 명시** — 일급 컬렉션 만들어 봤다가 *역할 없어 폐기*.
17
+
18
+ ## 못한 점 (설계 관점)
19
+
20
+ ### 1. `Lotto.create()` — *자동 발매기 책임을 Lotto가 가져감*
21
+
22
+ ```kotlin
23
+ companion object {
24
+ fun create(): Lotto {
25
+ val lottoNumbers =
26
+ LottoNumber.NUMBERS.values
27
+ .shuffled()
28
+ .take(NUMBER_OF_LOTTO_NUMBERS)
29
+ return Lotto(lottoNumbers)
30
+ }
31
+ }
32
+ ```
33
+
34
+ 리뷰어 (1차): "로또가 *스스로를 반환*한다? 저는 *조금 어색하게 느껴*지기도 해요! Lotto가 직접 Lotto를 만들어 반환하도록 만든 *이유는 무엇*인가요? 🤔" 학생 (1차): "*create 함수가 팩토리 함수로써 Lotto 인스턴스를 생성하는 역할*을 하도록 했습니다! private constructor를 사용하여." 리뷰어 (2차): "아하! 제가 코드를 잘못 이해했었던 것 같군요 🙇‍♂️ — *랜덤으로 6개의 번호를 선택해서 로또를 반환하는 일은 로또의 책임일까요*? *AutomaticLottoMachine이 할 일을 로또가 가져가버린 것처럼* 보여요! 🤔" — *팩토리의 자기 책임 검증*: *어떤 생성 정책*인가에 따라 *책임 위치 다름*. *랜덤 선택*은 발매기 책임.
35
+
36
+ ### 2. `LottoMachine.generate(lottoNumbers: List<List<Int>>? = null)` — *nullable 분기*
37
+
38
+ ```kotlin
39
+ interface LottoMachine {
40
+ fun generate(
41
+ lottoCount: LottoCount,
42
+ lottoNumbers: List<List<Int>>? = null, // ⚠ nullable 인터페이스
43
+ ): List<Lotto>
44
+ }
45
+ ```
46
+
47
+ 학생 자가 의문: "*자동 발매기는 로또 개수만 필요하고, 수동 발매기는 로또 번호도 필요로 한다는 점*에서 *설계가 복잡*해진 것 같습니다. 결국 *lottoNumbers를 nullable로 선언*하고, *자동 발매기의 경우에는 lottoNumbers가 null*로 오도록 했습니다." 리뷰어: "*과연 로또 번호를 함수로만 넘길 수 있는 것일까*?에 대해 고민해 보면 답을 찾을 수 있을 것 같아요 🤠 *혼자 고민하는데 너무 많은 시간을 쏟지 마시고 어려우면 dm 남겨* 주셔도 됩니다요 😊" 학생: "로또 번호를 *수동 발매기의 생성자를 통해 넘겨주는 방식*으로 리팩터링해 봤습니다! 🤩"
48
+ ```kotlin
49
+ class ManualLottoMachine(private val lottoNumbers: List<List<Int>>) : LottoMachine {
50
+ override fun generate(lottoCount: LottoCount): List<Lotto> {. }
51
+ }
52
+ ```
53
+ — *공통 인터페이스 = 공통 시그니처*. *분기 인자*는 *생성자로*.
54
+
55
+ ### 3. 인터페이스 추가 *협력 끌어올림* — 함수 주입
56
+
57
+ 리뷰어 후속 제안:
58
+ ```kotlin
59
+ interface LottoMachine {
60
+ fun generate(count: LottoCount): List<Lotto>
61
+ }
62
+
63
+ class ManualLottoMachine(
64
+ private val getLottoNumbers: (List<Int>) -> Unit // ⚠ 함수 주입
65
+ ): LottoMachine {
66
+ override fun generate(count: Int): List<Lotto> {
67
+ return List(count) { Lotto(getLottoNumbers()) }
68
+ }
69
+ }
70
+ ```
71
+
72
+ "*나중에 협력 관계를 끌어올린다면 다음처럼 작성*할 수도 있어요." — *함수형 인터페이스*로 *지연 입력*. 매번 *번호 입력*을 함수로.
73
+
74
+ ### 4. `List<Lotto>` *일급 컬렉션* 없음
75
+
76
+ 학생 자가 답변: "로또 리스트를 감싸는 *일급 컬렉션을 만드는 방법을 생각하고, 실제로 그렇게 구현도 해 봤었*습니다. 하지만 구현을 하고 나니, 해당 클래스가 *List<Lotto>를 감싸는 것 외에는 아무런 역할이나 책임이 없어서 결국 List를 사용*하게 되었습니다! 제가 *고려하지 못한 부분*이 있을까요..?!" 리뷰어 (균형 잡힌 답변):
77
+ > List<Lotto>를 감싸면 간단하게만 생각해 봐도 아래와 같은 장점을 얻을 수 있을 거에요.
78
+ > 1. *도메인 의미를 명확하게 전달*할 수 있다. (클래스명을 잘 지어야 하겠지만요 😅)
79
+ > 2. 컬렉션에 대한 *불변성을 보장*한다. (개발자가 실수로 `MutableList<Lotto>`의 형태로 넘겨도 불변성을 보장)
80
+ > 3. *확장성을 가질 수 있다*. (로또 묶음이 하는 일이 생겼을 때 일급 컬렉션에 로직만 추가하면 되니 변경이 좀 더 자유로움)
81
+ >
82
+ > *하지만 언급한 것처럼 역할과 책임이 없기에 만들지 않는 것도 좋은 근거와 방법*이라고 생각해요 👏
83
+
84
+ — *언제 일급 컬렉션을 만들지*는 *현재 행동* + *예상 확장*의 트레이드오프.
85
+
86
+ ### 5. `Lotto.lottoNumbers` *public 노출*
87
+
88
+ ```kotlin
89
+ class Lotto(val lottoNumbers: List<LottoNumber>) {. }
90
+ ```
91
+
92
+ 리뷰어: "`LottoNumber`가 가지고 있는 값을 사용 사용하도록 잘 변경해 주었네요 👏 *너가 가진 번호 다 내놔라고 LottoNumber에게 메시지를 던져* 볼까요?" 학생: "*LottoNumber가 가지고 있는 로또 번호를 반환하는 getAll 함수*를 통해 값을 사용할 수 있도록 수정했습니다! *객체에게 메시지를 던지는 연습을 꾸준히 해야 할 것 같네요..!*" — *getter 호출* → *메시지*.
93
+
94
+ ### 6. `LottoStore.publish` — 네이밍
95
+
96
+ ```kotlin
97
+ class LottoStore {
98
+ fun publish(.) // ⚠ 발행
99
+ }
100
+ ```
101
+
102
+ 리뷰어: "nit: *상점에서 판매한다 → sell*은 어떤가요? 🤔" 학생: "*sell이 판매한다는 의미를 나타내는 더 명확한 네이밍*인 것 같아서 변경했습니다!" — *현실 메타포 일치* (kiosk).
103
+
104
+ ### 7. 테스트 *assertj static import* 권장
105
+
106
+ ```kotlin
107
+ Assertions.assertThat(lottos.size).isEqualTo(5)
108
+ ```
109
+
110
+ 리뷰어:
111
+ ```kotlin
112
+ import org.assertj.core.api.Assertions.assertThat
113
+ assertThat(lottos.size).isEqualTo(5)
114
+ ```
115
+
116
+ ## 리뷰어 의견 요지
117
+
118
+ - **`Lotto.create()` = *발매기 책임을 도메인이 가져간 안티***. *랜덤 선택*은 *AutomaticLottoMachine*.
119
+ - **인터페이스 인자는 *공통*만** — *분기 인자*는 *생성자*.
120
+ - **함수 주입으로 *협력 끌어올림*** — Functional Interface.
121
+ - **일급 컬렉션 = *트레이드오프*** — *현재 행동 없음 ↔ 미래 확장*.
122
+ - **`.lottoNumbers` 노출 → *메시지*** — `lotto.contains(.)`.
123
+ - **네이밍 = *현실 메타포***. `publish` → `sell`.
124
+ - **assertj static import**.
125
+
126
+ - **대표 인용:**
127
+ > 랜덤으로 6개의 번호를 선택해서 로또를 반환하는 일은 *로또의 책임일까요*? *AutomaticLottoMachine이 할 일을 로또가 가져가버린 것처럼* 보여요!
128
+ > — @krrong on `src/main/kotlin/lotto/domain/model/Lotto.kt`
129
+
130
+ > 자동 발매기는 로또 개수만 필요하고, 수동 발매기는 로또 번호도 필요로 한다는 점에서 설계가 복잡해진 것 같습니다. 결국 lottoNumbers를 nullable로 선언하고.
131
+ > — @jiyuneel on `src/main/kotlin/lotto/domain/service/LottoMachine.kt`
132
+
133
+ > 과연 *로또 번호를 함수로만 넘길 수 있는 것일까*?에 대해 고민해 보면 답을 찾을 수 있을 것 같아요 🤠
134
+ > — @krrong on `src/main/kotlin/lotto/domain/service/LottoMachine.kt`
135
+
136
+ > 하지만 언급한 것처럼 *역할과 책임이 없기에 만들지 않는 것도 좋은 근거와 방법*이라고 생각해요 👏
137
+ > — @krrong on `src/main/kotlin/lotto/controller/LottoController.kt`
138
+
139
+ ## 얻은 교훈
140
+
141
+ - **`Lotto.create()`는 *책임 침범*** — *랜덤 6개 선택*은 *발매기*. *수동 입력 검증*만 `Lotto` 책임.
142
+ - **공통 인터페이스 = 공통 시그니처** — *수동만 필요한 번호*를 *nullable*로 인터페이스에 넣으면 *자동도 신경 써야*. *생성자 차이*로 해결.
143
+ - **함수 주입으로 협력 끌어올림** — `(Int) -> List<Int>` 같은 *지연 입력*은 *순서 의존*을 *호출 컨텍스트*에서 해결.
144
+ - **일급 컬렉션 = *트레이드오프*** — *역할 없으면 List 사용*도 합리. 단 *불변성/확장성*은 일급 컬렉션 장점.
145
+ - **`.numbers` 노출 → 메시지** — `lotto.numbers.contains(x)` → `lotto.contains(x)`.
146
+ - **네이밍은 *현실 메타포*** — `publish` vs `sell`. *키오스크*에서 *판매*하는 게 자연.
147
+ - **assertj `import static`** — `assertThat(x).isEqualTo(y)`가 *코드 시그널*.
148
+ - **리뷰어의 *DM 제안*은 좋은 신호** — *왕복 4회 이상* 되면 *비동기 한계*. *동기 채널*로 이동.
149
+ - **이미지 첨부/커밋 링크 활용** — 학생이 *5e0de6b 커밋 링크*를 댓글에 첨부.
@@ -0,0 +1,148 @@
1
+ # PR #58 — [에디] 1단계 로또
2
+
3
+ - **Reviewee:** [@junjange](https://github.com/junjange)
4
+ - **PR:** https://github.com/woowacourse/kotlin-lotto/pull/58
5
+ - **단계:** 1단계
6
+ - **리뷰어:** @vagabond95
7
+ - **라인 코멘트:** 31
8
+
9
+ ## 잘한 점 (설계 관점)
10
+
11
+ - **`Lotto` 중복/크기 검증** — `require`로 도메인 invariant 강제.
12
+ - **`enum class Rank(countOfMatch, winningMoney)`** — 등수+상금 한 곳.
13
+ - **`Range` 재활용** — `LOTTO_NUMBER_RANGE: IntRange = 1..45`.
14
+ - **`Rank.valueOf(countOfMatch, matchBonus)` factory** — 매칭 → Rank 변환 캡슐화.
15
+ - **리뷰 반영을 커밋 해시로 명시** — 변경 추적 용이.
16
+
17
+ ## 못한 점 (설계 관점)
18
+
19
+ ### 1. Controller가 `","`로 split — View 책임 침범
20
+
21
+ ```kotlin
22
+ private fun lottoDraw(): DrawResult {
23
+ val winningNumber = InputView.readWinningNumbers()
24
+ val winningLotto = Lotto((winningNumber.split(",").map { LottoNumber(it.trim()) }))
25
+ .
26
+ }
27
+ ```
28
+
29
+ 리뷰어: "`,`로 split된다는 내용은 view의 요구사항인데요. view의 요구사항이 바뀔 때 controller에 변경이 발생하는 것을 지양해야 할 것 같습니다!" — 입력 형식은 View 내부에서 *완성된 데이터*로 변환되어야 함.
30
+
31
+ ### 2. `LottoMachine(private val price: String)` — 도메인이 String 받음
32
+
33
+ ```kotlin
34
+ class LottoMachine(private val price: String) {
35
+ init { require(price.toIntOrNull()?.let { it >= MIN_PRICE } == true) }
36
+ }
37
+ ```
38
+
39
+ 리뷰어: "LottoNumber, LottoMachine 모두 String으로 넘겨주고 내부적으로 숫자로 타입 변환 및 검증을 처리하고 있는데요. price가 숫자 타입으로 '입력' 되었는지는 View에서 검증하는 것이 좀 더 적절하지 않을까요?" 학생 반박: "View는 입력만, 유효성 검사는 LottoMachine." → 후속 논의에서 *형식 검증 = View*, *비즈니스 검증 = Domain*으로 합의.
40
+
41
+ ### 3. `LottoResult.static` — Kotlin 예약어와 혼동되는 명명
42
+
43
+ ```kotlin
44
+ class LottoResult(val static: Map<Rank, Int>) {. }
45
+ ```
46
+
47
+ 리뷰어: "kotlin이긴 하지만 static은 기본적으로 '정적 상태'를 의미하는 예약어로 많이 쓰이기 때문에 조금 혼동이 올 수 있을 것 같아요. 좀 더 적절한 네이밍으로 바꿔봐도 좋겠습니다." — `statistic`/`countByRank`.
48
+
49
+ ### 4. `LottoTicket` vs `Lotto` — 명명 혼동
50
+
51
+ ```kotlin
52
+ fun getLottoTicket(): Int = price.toInt() / MIN_PRICE // ⚠ 수량 반환인데 Ticket
53
+ ```
54
+
55
+ 리뷰어: "LottoTicket과 Lotto가 네이밍으로 봤을 때, 큰 차이를 알지 못할 것 같아요. 좀 더 적절한 이름은 없을까요~?" — 함수가 *수량*을 반환하면 `getLottoCount`.
56
+
57
+ ### 5. `OutputView`가 Rank 순회로 출력
58
+
59
+ ```kotlin
60
+ fun printResult(lottoResult: LottoResult) {
61
+ println("당첨 통계"); println("---------")
62
+ Rank.entries.reversed().forEach { rank ->. } // ⚠ Model 구조 가정
63
+ }
64
+ ```
65
+
66
+ 리뷰어: "Rank를 순회하면서 출력하기보다, lottoResult의 결과를 바로 출력하는 것은 어떨까요? 현재 요구사항에서는 rank를 순회하면서 출력을 해도 차이가 없습니다. 다만, 이것은 View가 'LottoResult에는 모든 등수의 결과가 들어있다.'라는 model의 내부 구현을 암묵적으로 알고 있기 때문에 가능한 것으로 보여요. 만약 LottoResult 내부에 변경사항이 발생하면, View에도 변경사항이 발생할 텐데 이러한 의존관계는 줄여 보면 어떨까요?" → 학생 해결: `LottoResult.toString()`을 커스텀해 View는 *출력만*.
67
+
68
+ ### 6. `Lotto`가 `List<LottoNumber>` — Set이 더 적합
69
+
70
+ ```kotlin
71
+ class Lotto(val lottoNumbers: List<LottoNumber>) {
72
+ init { require(lottoNumbers.distinct().size == LOTTO_SIZE) }
73
+ }
74
+ ```
75
+
76
+ 리뷰어: "이미 중복 검증을 잘해 주셨는데, 추가적으로 같이 생각해 보면 좋을 부분이라 코멘트 남깁니다. lottoNumbers의 자료구조는 List인데, Set으로 바꾼다면 기본적으로 '중복을 허용하지 않는 자료구조'이므로 도메인의 의미상 좀 더 적절한 자료구조가 될 수 있습니다." — 자료구조가 *invariant 표현*.
77
+
78
+ ### 7. `LottoAnalyzer` class vs object
79
+
80
+ ```kotlin
81
+ class LottoAnalyzer(private val lottos: List<Lotto>, private val drawResult: DrawResult) {. }
82
+ ```
83
+
84
+ 리뷰어: "class와 object를 사용하시는 기준이 있으실까요? 해당 클래스를 object로 전환하는 것이 적절할까요? 적절하다면 (혹은 그렇지 않다면) 이유는 무엇일까요?" 학생: "class의 생성자를 메서드의 파라미터로만 사용하고 있어 상태를 가지지 않고, 해당 class는 랭크를 통계 내는 기능만 하므로 object로 바꾸는 것이 더 적절." → `object`로 변환 + `calculateResult` 사용처 객체로 이동.
85
+
86
+ ### 8. `LottoMachine` class — 학생도 동일 결론
87
+
88
+ 학생: "LottoMachine을 object로 선언했을 때, 하나의 인스턴스만 생성되므로 메모리 측면에서 장점이 있을 것 같습니다. … LottoMachine은 price를 의존하고 있지만, price는 getNumberOfLottoTickets() 메서드에서만 사용되고 있고 LottoMachine이 price의 상태를 가지고 있을 필요가 없기 때문에 object로 바꾸는 게 더 적합." — *상태 없음*이 명확하면 `object`.
89
+
90
+ ### 9. `Rank.valueOf` 매번 분기
91
+
92
+ ```kotlin
93
+ fun valueOf(countOfMatch: Int, matchBonus: Boolean): Rank {
94
+ if (countOfMatch == THIRD.countOfMatch && !matchBonus) return THIRD
95
+ return entries.find { it.countOfMatch == countOfMatch } ?: MISS
96
+ }
97
+ ```
98
+
99
+ 리뷰어: "현재는 보너스 번호 때문에 Rank, LottoResult 등의 클래스에서 매번 분기 처리가 필요한 상황인데요. 앞으로도 보너스 번호와 관련된 클래스는 모두 이러한 분기 처리가 들어가야 하고, 이는 추후에 변경사항이 발생할 경우 리소스가 많이 드는 작업이 될 수 있을 것 같아요. 분기 처리 없이 등수를 구하도록 리팩토링 해 볼 수 있을까요?" 학생: "RankState라는 enum class에서 일반 당첨, 보너스 당첨, 미당첨을 구분." 리뷰어 후속: "Rank와 RankState는 잘 보면 유사한 점이 많습니다. matchBonus를 Rank에서 다룬다면 두 클래스를 잘 병합해 볼 수도 있지 않을까요?" — *분기 → 별도 enum* → *두 enum 병합*의 의사결정 흐름.
100
+
101
+ ### 10. `Rank` 테스트 일부만
102
+
103
+ ```kotlin
104
+ class RankTest {
105
+ @Test fun `5개 일치 + 보너스 → 2등`() {. }
106
+ @Test fun `5개 일치 → 3등`() {. }
107
+ // 1, 4, 5등, MISS 누락
108
+ }
109
+ ```
110
+
111
+ 리뷰어: "나머지 등수는 테스트하지 않으신 이유가 있을까요?" 학생: "3등을 구하는 로직이 어려울 수 있다고 판단하여 3등과 그 외 다른 2개의 테스트 코드를 작성." → 학생 보강 (1등~MISS 모두).
112
+
113
+ ### 11. 일급 컬렉션 `Lottos` 부재
114
+
115
+ 리뷰어: "요구사항 중 하나인 일급 컬렉션을 Lotto 리스트에 적용해 볼 수 있을 것 같아요~!" — `List<Lotto>` 자체를 `Lottos`로 감싸면 *발행물의 집합*이 자기 행위를 가질 수 있음.
116
+
117
+ ## 리뷰어 의견 요지
118
+
119
+ 1. **View 요구사항(`,` split, 형식 변환)이 Controller로 누수되지 말 것** — 입력 형식 변경이 *Controller*까지 영향 가면 책임 경계 깨짐.
120
+ 2. **자료구조 = invariant 표현** — `Set`이 도메인 의미를 더 잘 담을 수 있다면 `List` 대신.
121
+ 3. **`object` vs `class`** — *상태 없음*이 확실하면 `object`. 메모리 절약은 부차적.
122
+ 4. **분기 처리 흩어짐 = 새 enum 등장 신호** — `Rank.SECOND`/`THIRD` 분기가 여러 곳에 나타나면 `RankState` 같은 *새 분류*가 필요.
123
+ 5. **결과 객체의 *자기 출력 표현*** — `LottoResult.toString()`을 정의해 View가 *순회 책임*에서 자유로워짐.
124
+ 6. **명명은 *도메인 예약어*와 겹치지 않게** — `static`은 Kotlin/Java 키워드 인식.
125
+
126
+ - **대표 인용:**
127
+ > `,`로 split된다는 내용은 view의 요구사항인데요. view의 요구사항이 바뀔 때 controller에 변경이 발생하는 것을 지양해야 할 것 같습니다!
128
+ > — @vagabond95 on `src/main/kotlin/lotto/controller/LottoGameController.kt`
129
+
130
+ > 이것은 View가 'LottoResult에는 모든 등수의 결과가 들어있다.'라는 model의 내부 구현을 암묵적으로 알고 있기 때문에 가능한 것으로 보여요.
131
+ > — @vagabond95 on `src/main/kotlin/lotto/view/OutputView.kt`
132
+
133
+ > 분기 처리 없이 등수를 구하도록 리팩토링 해 볼 수 있을까요?
134
+ > — @vagabond95 on `src/main/kotlin/lotto/model/Rank.kt`
135
+
136
+ > Set으로 바꾼다면 기본적으로 '중복을 허용하지 않는 자료구조'이므로 도메인의 의미상 좀 더 적절한 자료구조가 될 수 있습니다.
137
+ > — @vagabond95 on `src/main/kotlin/lotto/model/Lotto.kt`
138
+
139
+ ## 얻은 교훈
140
+
141
+ - **View 형식(`,` split, String→Int)은 Controller로 누수 X**. 입력 *형식 변경*이 도메인 변경으로 이어지면 책임 경계 미설계 신호.
142
+ - **자료구조가 *invariant*를 표현** — `Set<LottoNumber>`이면 *중복 불가*가 타입에 명시. 외부에서 *불필요한 중복 검사*가 사라짐.
143
+ - **`object` = *상태 없음 + 단일성* 단언**. 메모리 절약이 아니라 *의미*가 1차 동기.
144
+ - ***분기가 여러 곳에 흩어지면 새 enum 등장 신호*** — `Rank`에 매번 `if (bonus)`가 붙으면 `RankState`/`BonusMatched` 같은 *새 분류*가 떠오름. 그 후 *원래 enum과 병합*도 검토.
145
+ - **결과 객체의 *자기 표현*** — `toString()` 커스텀으로 View 책임 줄이기. 단, 출력 형식이 자주 바뀌면 *별도 Formatter*가 더 자유로움.
146
+ - **자료구조 선택은 *컬렉션 무조건 List*가 아님** — Set/Map/List의 도메인 의미를 의식.
147
+ - **이름이 Kotlin/Java *예약어와 닮음*** — 의도 전달에 마찰. `static`은 *정적*을 떠올리게 함.
148
+ - **테스트는 *모든 분기*를 명세서로** — *어려운 경우만* 테스트 작성하면 *남은 분기*는 미보장.
@@ -0,0 +1,178 @@
1
+ # PR #81 — [로또] 에디 2단계 미션
2
+
3
+ - **Reviewee:** [@junjange](https://github.com/junjange)
4
+ - **PR:** https://github.com/woowacourse/kotlin-lotto/pull/81
5
+ - **단계:** 2단계 (수동 로또 추가)
6
+ - **리뷰어:** @vagabond95
7
+ - **라인 코멘트:** 32
8
+
9
+ ## 잘한 점 (설계 관점)
10
+
11
+ - **`sealed class GameState`** — 게임 흐름을 상태 패턴으로 표현.
12
+ - **`ErrorCode` enum + `ExceptionsHandler`** — 검증 로직 공통화 시도.
13
+ - **`LottoBundle.append(other)`** — 자동/수동 로또를 *컬렉션*이 직접 합치는 행위.
14
+ - **`LottoMachine`을 `object`로 복귀** — 상태 없음에 맞는 선택.
15
+ - **`Kiosk + Deposit + Record`로 리팩토링** — 사용자 흐름(잔액 + 거래 기록)을 한 객체로 통합.
16
+ - **`MatchResult` = wrapping → 행위 보유 객체로 진화** — 리뷰어 칭찬.
17
+
18
+ ## 못한 점 (설계 관점)
19
+
20
+ ### 1. 함수명에 `And` — 두 책임 신호
21
+
22
+ ```kotlin
23
+ private fun getLottoBundleAndDrawResult(): Result<LottoResponse> =.
24
+ ```
25
+
26
+ 리뷰어: "네이밍에 And가 들어간다는 것은 해당 함수가 2가지 이상의 역할을 수행한다는 신호인데요. 함수당 한 가지 역할만 수행하도록 개선 가능할까요?"
27
+
28
+ ### 2. `LottoManualPurchase` vs `LottoManualPurchaseCount`
29
+
30
+ ```kotlin
31
+ data class LottoManualPurchase(val count: Int) {. }
32
+ ```
33
+
34
+ 리뷰어: "`LottoManualPurchaseCount(val count: Int)`에 더 가까울 것 같습니다!" — 클래스명에 *count*가 빠지면 *수동 구매 자체*인지 *수동 구매 수*인지 모름.
35
+
36
+ ### 3. 상수 중복 — `LottoMachine`/`Lotto`/`LottoNumber`
37
+
38
+ ```kotlin
39
+ class LottoMachine(.) {
40
+ companion object {
41
+ private const val LOTTO_SIZE = 6 // ⚠ Lotto가 이미 보유
42
+ private val LOTTO_NUMBER_RANGE: IntRange = 1..45 // ⚠ LottoNumber가 이미 보유
43
+ }
44
+ }
45
+ ```
46
+
47
+ 리뷰어: "해당 상수들은 이미 다른 모델에서 선언되어 있는 상수로 보여요. 상수 선언의 중복을 제거해 볼 수 있을까요?" — *상수의 소유*는 한 곳, 다른 곳은 import.
48
+
49
+ ### 4. `createLottoBundle(lottoManualPurchaseNumbers: List<List<String>>,.)` — 이중 컬렉션
50
+
51
+ ```kotlin
52
+ fun createLottoBundle(
53
+ lottoManualPurchaseNumbers: List<List<String>>,
54
+ lottoPurchaseCount: LottoManualPurchase,
55
+ ): LottoBundle {. }
56
+ ```
57
+
58
+ 리뷰어: "이중 컬렉션은 쉽게 타입을 유추하기 어렵게 만드는데요. 일급 컬렉션으로 한번 감싸주는 것은 어떨까요?" — `ManualPurchaseLottos` 같은 일급 컬렉션으로.
59
+
60
+ ### 5. 같은 의미 상태가 두 인자로 분리됨
61
+
62
+ ```kotlin
63
+ fun createLottoBundle(manualPurchaseLottos: ManualPurchaseLottos, lottoManualPurchaseCount: LottoManualPurchaseCount): LottoBundle
64
+ ```
65
+
66
+ 리뷰어: "manualPurchaseLottos에서 lottoManualPurchaseCount 값을 추출해 낼 수 있지 않을까요? 같은 의미를 가지는 상태는 최대한 재사용해 보면 좋을 것 같아요!" — `manualPurchaseLottos.size`로 충분.
67
+
68
+ ### 6. `LottoMachine.getRandomLottoCount` 호출 무제한 + `price` 불변
69
+
70
+ ```kotlin
71
+ class LottoMachine(private val price: Price) {
72
+ fun getRandomLottoCount(.): Int {
73
+ val randomLottoCount = price.getNumberOfLottoTickets() - lottoPurchaseCount.count
74
+ .
75
+ }
76
+ }
77
+ ```
78
+
79
+ 리뷰어: "getRandomLottoCount의 호출에는 제한이 없는데, price는 생성 시에만 주입을 받으므로 로또를 구매했을 때 price 값도 차감되어야 논리적으로 맞지 않을까요~? 추후에 수동으로 로또를 언제든지 구매할 수 있는 요구사항이 추가될 경우 버그가 발생할 수 있는 부분일 것 같아요." — Kiosk 패턴(잔액 추적)으로 발전.
80
+
81
+ ### 7. `LottoAnalyzer.calculateResult` — `MatchResultResponse`의 책임
82
+
83
+ ```kotlin
84
+ object LottoAnalyzer {
85
+ fun calculateResult(matchResultResponse: MatchResultResponse): LottoResult {. }
86
+ }
87
+ ```
88
+
89
+ 리뷰어: "calculateResult 내에서 진행되는 로직은 MatchResultResponse 클래스가 '스스로' 수행할 수 있는 동작 아닐까요~? MatchResultResponse 클래스의 역할이 파편화되었다고 볼 수도 있을 것 같아요!" — *Analyzer*는 *대상 객체에 행위*가 있을 때 잉여.
90
+
91
+ ### 8. `Price.plusPrice(strMoney: String)` — 시그니처 불일치
92
+
93
+ ```kotlin
94
+ data class Price(val money: Int = DEFAULT_MONEY) {
95
+ fun plusPrice(strMoney: String): Price {. } // ⚠ String
96
+ fun minusPrice(): Price {. } // ⚠ 인자 없음
97
+ }
98
+ ```
99
+
100
+ 리뷰어 ①: "생성자에서는 Int를 전달받고 있는데, plus에서는 String 타입을 받는 구조가 일관성이 없어 보여요." ② "plusPrice가 실제로 더해지고자 하는 값을 받는다면, minusPrice도 동일한 규칙으로 빼고자 하는 값을 인자로 받는 것이 일관성이 있을 것 같아요." ③ "kotlin에서는 `operator` 라는 키워드를 이용하여 산술 연산자 오버라이딩이 가능하므로 이번 기회에 활용해 봐도 좋을 것 같아요." → `operator fun plus(other: Int)`.
101
+
102
+ ### 9. `Price`가 `Lotto`에 의존 (`getRandomLottoCount`/`getNumberOfLottoTickets`)
103
+
104
+ ```kotlin
105
+ data class Price(val money: Int) {
106
+ fun minusPrice(): Price = copy(money = money - getNumberOfLottoTickets() * MIN_PRICE)
107
+ }
108
+ ```
109
+
110
+ 리뷰어: "이러한 구조가 가능한 이유는 Price가 `getRandomLottoCount`, `getNumberOfLottoTickets`와 같이 Lotto에 대한 의존성을 가지고 있기 때문이에요. 그런데, 잘 생각해 보면 '가격'과 '로또' 중에 어느 것이 더 상위 개념일까요? 다르게 얘기하면 로또가 가격에 대한 정보를 알고 있는 것과 가격이 로또에 대한 정보를 알고 있는 것 중 어느 것이 더 자연스러울까요?" — *상위 개념(가격)*이 *하위 개념(로또)*을 알지 말 것.
111
+
112
+ ### 10. `Deposit.minus`가 음수 검증 누락
113
+
114
+ ```kotlin
115
+ operator fun minus(other: Int): Deposit = copy(money = Money(money.value - other))
116
+ ```
117
+
118
+ 리뷰어: "예치금의 개념이라면 빼고자 하는 값이 현재 남은 금액보다 큰 경우 즉, 마이너스가 되는 상황이 발생할 때의 예외처리가 필요하지 않을까요~?" — 도메인 invariant 누락.
119
+
120
+ ### 11. `addDeposit + recordPurchase`가 *외부에서 강제됨*
121
+
122
+ ```kotlin
123
+ kiosk.addDeposit(money)
124
+ kiosk.recordPurchase(money)
125
+ ```
126
+
127
+ 리뷰어: "이 과정이 항상 같이 수행되어야 한다면, kiosk 내부에서 한번에 처리해 주는 것은 어떨까요? 개별 스탭을 외부에서 처리해야 할 경우 이러한 사항을 놓칠 수 있고 또 구현상으로도 강제하기 어려워 의도하지 않은 동작을 유발시키기 쉬울 것 같아요." — *호출 순서 강제*는 *외부 컨벤션*이 아니라 *내부 캡슐화*.
128
+
129
+ ### 12. 중앙 `ErrorCode` enum
130
+
131
+ ```kotlin
132
+ enum class ErrorCode(val status: Int, val reason: String) {. }
133
+ ```
134
+
135
+ 리뷰어: "에러코드 정리 👍. 그런데, 서비스가 커질수록 모든 에러코드를 한 곳에서 관리했을 때 생길 수 있는 단점도 추후에는 같이 고려가 되면 좋을 것 같아요!" — 중앙 enum이 *god-folder*가 될 위험.
136
+
137
+ ### 13. `sealed class GameState` 선택 — Enum/Sealed Interface와의 비교
138
+
139
+ 리뷰어: "Enum, Sealed Interface를 활용해도 동일한 목적으로 활용이 가능한데요, 각각 선택하는 기준에 대해 생각해 보면 좋을 것 같습니다." — 학습 방향 제시.
140
+
141
+ ## 리뷰어 의견 요지
142
+
143
+ 1. **함수명에 `And` = 두 책임 신호** — 분리.
144
+ 2. **상수 중복 = 소유권 모호** — Lotto 정체성은 Lotto, LottoNumber 정체성은 LottoNumber.
145
+ 3. **이중 컬렉션은 일급 컬렉션으로 감싸기** — 의도 명시.
146
+ 4. **시간에 따라 변하는 상태 = 객체 생성자에 박아두지 말 것** — Kiosk/Deposit 패턴으로 잔액 추적.
147
+ 5. **연산 인터페이스 *일관성*** — `plus(Int)` + `minus(Int)` + `operator`.
148
+ 6. **상위 개념이 하위 개념을 모르게** — Price가 Lotto를 알면 의존 방향 역전.
149
+ 7. ***항상 같이 수행*되는 절차는 *외부에서 강제하지 말 것*** — 내부 캡슐화로 호출자 부담 제거.
150
+ 8. **중앙 enum = god-folder 위험** — 도메인별 분리 검토.
151
+ 9. **단순 wrapping → 행위 보유로 진화** — `MatchResult` 칭찬.
152
+
153
+ - **대표 인용:**
154
+ > 네이밍에 And가 들어간다는 것은 해당 함수가 2가지 이상의 역할을 수행한다는 신호인데요.
155
+ > — @vagabond95 on `src/main/kotlin/lotto/controller/LottoGameController.kt`
156
+
157
+ > 잘 생각해 보면 '가격'과 '로또' 중에 어느 것이 더 상위 개념일까요? 다르게 얘기하면 로또가 가격에 대한 정보를 알고 있는 것과 가격이 로또에 대한 정보를 알고 있는 것 중 어느 것이 더 자연스러울까요?
158
+ > — @vagabond95 on `src/main/kotlin/lotto/model/Price.kt`
159
+
160
+ > 이 과정이 항상 같이 수행되어야 한다면, kiosk 내부에서 한번에 처리해 주는 것은 어떨까요? 개별 스탭을 외부에서 처리해야 할 경우 이러한 사항을 놓칠 수 있고…
161
+ > — @vagabond95 on `src/main/kotlin/lotto/controller/LottoGameController.kt`
162
+
163
+ > calculateResult 내에서 진행되는 로직은 MatchResultResponse 클래스가 '스스로' 수행할 수 있는 동작 아닐까요? MatchResultResponse 클래스의 역할이 파편화되었다고 볼 수도 있을 것 같아요!
164
+ > — @vagabond95 on `src/main/kotlin/lotto/model/LottoAnalyzer.kt`
165
+
166
+ ## 얻은 교훈
167
+
168
+ - **함수명에 `And`/`Or`는 *2개 이상 책임* 신호**. 분리하거나 *목적*을 새 명사로.
169
+ - **상수의 *소유권*은 한 곳**. 중복 선언은 *변경 시 양쪽 모두 잊을 위험*.
170
+ - **이중 컬렉션 = 의도 모호** — 일급 컬렉션으로 *무엇의 모음인지* 명시.
171
+ - ***같은 의미의 상태*는 *하나의 인자*** — `manualPurchaseLottos`가 이미 count를 안다면 따로 받지 말 것.
172
+ - **시간에 따라 변하는 상태는 *객체 생성자*에 박지 말 것**. Price가 *최초 입력값*만 알고 있다면 잔액 추적 불가 → Kiosk/Deposit으로 *시간 흐름* 표현.
173
+ - **연산자 시그니처 *일관성*** — `plus(Int)` + `minus(Int)` + `operator`. 한쪽만 인자 없으면 *외부에서 빼는 값을 알 수 없음*.
174
+ - **상위 개념이 하위 개념을 알지 말 것**. *가격*이 *로또*를 알면 의존 방향 역전 — 로또가 가격을 알아야 자연.
175
+ - **항상 같이 수행되는 절차는 *내부 캡슐화*** — 호출자가 *두 번 호출*해야 한다면 빠뜨릴 위험.
176
+ - **중앙 enum은 god-folder 위험** — 도메인별 sealed/예외 분리도 옵션.
177
+ - **단순 wrapping → 행위 보유 객체로 진화**. wrapping만 하던 객체가 행위를 갖기 시작하면 *진짜 객체*가 됨.
178
+ - ***Enum vs Sealed class vs Sealed interface*** — 학습 시드. *상태가 데이터를 보유* 하면 sealed, *순수 분류*면 enum.
@@ -0,0 +1,153 @@
1
+ # PR #120 — [로또 1단계] 공백 미션 제출합니다
2
+
3
+ - **Reviewee:** [@junseo511](https://github.com/junseo511)
4
+ - **PR:** https://github.com/woowacourse/kotlin-lotto/pull/120
5
+ - **단계:** 1단계
6
+ - **리뷰어:** @krrong
7
+ - **라인 코멘트:** 71
8
+
9
+ ## 잘한 점 (설계 관점)
10
+
11
+ - **`Rank` enum + `matchBonus: Boolean = false` 기본값** — 2등에만 보너스 필드 적용 시도.
12
+ - **PR 본문에 명확한 자가 의문 다수** — TDD 커밋 단위, LottoNumber 필요성, `matchBonus` 기본값 처리 등.
13
+ - **README 체크박스 활용** — 진행 상태 시각화.
14
+
15
+ ## 못한 점 (설계 관점)
16
+
17
+ ### 1. `Lotto`가 너무 많은 일
18
+
19
+ ```kotlin
20
+ class Lotto(val numbers: List<Int>) {
21
+ init {
22
+ validateLottoNumbersCount(numbers)
23
+ validateLottoNumbersRange(numbers)
24
+ validateLottoNumbersDuplicate(numbers)
25
+ }
26
+
27
+ private fun validateLottoNumbersCount(numbers: List<Int>) {
28
+ require(numbers.size == LOTTO_NUMBER_SIZE) {. }
29
+ }
30
+
31
+ private fun validateLottoNumbersRange(numbers: List<Int>) {
32
+ require(numbers.all { it in 1..45 }) {. }
33
+ }
34
+ // + 중복 검증
35
+ // + 등수 계산
36
+ // + 보너스 비교
37
+ }
38
+ ```
39
+
40
+ 학생 의견:
41
+
42
+ > LottoNumber class를 따로 만들어서 번호에 대한 검증을 진행하더라구요?! 저는 근데 가지고 있는 로또 번호들을 Lotto에서 검증해도 괜찮다고 생각합니다. 오히려 너무 class를 보기 위해 가는 길이 가독성을 떨어지게 만드는 느낌이더라구요.
43
+
44
+ 리뷰어 답변:
45
+
46
+ > 하지만 `Lotto`클래스가 하는 일이 많아지지 않을까요?
47
+ >. 로또에서 사용하는 숫자는 Int 타입인데요. 외부에서 가져온 이 숫자들이 로또 번호라는 것을 어떻게 알 수 있을까요?
48
+ > ```kotlin
49
+ > val lotto = Lotto(.)
50
+ > val number = lotto.numbers.first()
51
+ > foo(number)
52
+ >
53
+ > fun foo(number: Int) {
54
+ > // number가 로또 번호가 맞나? 검증을 해야할까?
55
+ > }
56
+ > ```
57
+
58
+ → 가독성과 타입 안전성의 trade-off — Lotto 외부로 *Int를 노출*하면 호출자가 매번 "이게 로또 번호인가?" 의심.
59
+
60
+ ### 2. `Rank`의 `matchBonus` 처리 — 5개 일치 SECOND에만 적용
61
+
62
+ ```kotlin
63
+ enum class Rank(
64
+ val countOfMatch: Int,
65
+ val winningMoney: Int,
66
+ val matchBonus: Boolean = false,
67
+ ) {
68
+ MISS(0, 0),
69
+ FIFTH(3, 5_000),
70
+ FOURTH(4, 50_000),
71
+ THIRD(5, 1_500_000),
72
+ SECOND(5, 30_000_000, true), // ⚠ 5개 일치 둘 중 보너스 일치만 SECOND
73
+ FIRST(6, 2_000_000_000),
74
+ ;
75
+
76
+ companion object {
77
+ fun fromMatchResult(countOfMatch: Int, matchBonus: Boolean): Rank {
78
+ // 복잡한 분기 로직.
79
+ throw IllegalArgumentException(.)
80
+ }
81
+ }
82
+ }
83
+ ```
84
+
85
+ 학생 의문:
86
+
87
+ > Rank를 반환하는 과정에서 SECOND일 때 boolean값을 기본으로 가지게 했습니다. 근데 6개 중에서 SECOND만 예외를 둬야 하는 로직 말고도 더 괜찮은 방법이 있을까요?
88
+
89
+ 리뷰어 답:
90
+
91
+ > `Rank`는 정말 `matchBonus`가 필요할까요?
92
+
93
+ → **답:** 보너스 일치 정보는 Rank의 *속성*보다 Rank를 *찾는 데 쓰는 입력*. `Rank.matchBonus` 필드 자체가 어색.
94
+
95
+ 리뷰어가 준 힌트:
96
+
97
+ ```kotlin
98
+ return entries.find { it.countOfMatch == countOfMatch && it.matchBonus == matchBonus } ?: MISS
99
+ ```
100
+
101
+ → `IllegalArgumentException` 없이 MISS로 fallback.
102
+
103
+ ### 3. 테스트 assertion 길게
104
+
105
+ ```kotlin
106
+ import org.junit.jupiter.api.Assertions
107
+ Assertions.assertEquals(5, lottoQuantity) // ⚠ 길게
108
+ ```
109
+
110
+ → `import..assertEquals` 후 `assertEquals(5, lottoQuantity)`.
111
+
112
+ ### 4. PR 본문의 TDD 커밋 의문
113
+
114
+ 학생:
115
+
116
+ > feat부터 커밋을 날려야 하는가? -> 진행한건 test부터 작성했는데 왜 feat부터 만들어야 하지?
117
+ > test부터 커밋을 날려야 하는가? -> test부터 날린 상태로 빌드를 돌리면 컴파일 에러가 발생할 텐데 왜 test부터 날리는거지?
118
+
119
+ 리뷰어 답:
120
+
121
+ > 저의 선호도는 **세 번째**(feat과 test를 함께 커밋한다)인데요.
122
+ > 100개의 기능을 TDD로 구현할 때 200개의 커밋 vs 100개의 커밋, 리뷰어가 어떤 PR이 리뷰하기 편할까요?
123
+
124
+ → TDD = *테스트 주도 사고*. 커밋은 *완결된 단위*.
125
+
126
+ ## 리뷰어 의견 요지
127
+
128
+ 리뷰어 @krrong (racingcar에서도 reviewee였던 사람이 lotto에서 reviewer로!):
129
+
130
+ 1. **`LottoNumber` 도메인 추출 — 가독성 vs 타입 안전성**. 가독성 떨어진다는 학생 의견에 *호출처 의심 비용*으로 반박.
131
+
132
+ 2. **`Rank.matchBonus` 필드의 어색함** — Rank의 *속성*인지 *찾기 입력*인지 구분.
133
+
134
+ 3. **TDD 커밋 단위 = 완결된 기능 단위** — test/feat 분리는 *과정 기록*이지 *리뷰 단위*가 아님.
135
+
136
+ 4. **`Rank` 검색에서 예외 던지지 말고 MISS fallback**.
137
+
138
+ - **대표 인용:**
139
+ > 하지만 `Lotto`클래스가 하는 일이 많아지지 않을까요? 로또 번호인지 검증도 해야하고, 몇 등인지 계산도 해야하고.
140
+ >
141
+ > — @krrong on `src/main/kotlin/lotto/model/Lotto.kt`
142
+
143
+ > `Rank`는 정말 `matchBonus`가 필요할까요?
144
+ >
145
+ > — @krrong on `src/main/kotlin/lotto/model/Rank.kt`
146
+
147
+ ## 얻은 교훈
148
+
149
+ - **LottoNumber 추출의 진짜 가치 = *호출처가 의심하지 않게***. 외부에 `Int` 노출 = 매번 "이게 로또 번호 맞나?" 의심. 타입이 정답.
150
+ - **enum 필드의 분류 — *속성* vs *검색 키***. `matchBonus`는 Rank가 *되는 조건*이지 *Rank의 본질 속성*이 아님. enum 필드는 *영구한 속성*만.
151
+ - **MISS/NONE fallback > Exception**. enum이 전 케이스를 표현하면 *예외 던질 일 없음*. `find {. } ?: MISS`.
152
+ - **TDD 커밋 단위 = "다른 사람이 리뷰 가능한 단위"**. 테스트만 있는 커밋은 빌드 실패. 둘을 합치면 *완결된 기능*.
153
+ - **이전 reviewee가 다음 라운드 reviewer로** — racingcar 학생 krrong이 lotto에서 어떻게 학습한 걸 리뷰로 돌려주는지 패턴을 보여주는 PR.