DevLog ๐ถ
[์ฐ์ํํ ํฌ์ฝ์ค] 5๊ธฐ ๋ฐฑ์๋ 1์ฃผ์ฐจ ํ๋ฆฌ์ฝ์ค ํ๊ณ ๋ก ๋ณธ๋ฌธ
[์ฐ์ํํ ํฌ์ฝ์ค] 5๊ธฐ ๋ฐฑ์๋ 1์ฃผ์ฐจ ํ๋ฆฌ์ฝ์ค ํ๊ณ ๋ก
dolmeng2 2022. 11. 9. 22:40- 2์ฃผ์ฐจ๊ฐ ๋๋์์ผ ์์ฑํ๋ 1์ฃผ์ฐจ ํ๋ฆฌ์ฝ์ค ํ๊ณ ๋ก...(?)
- 1์ฃผ์ฐจ์๋ ์ ์ ์์ด ๊ตฌํํ๊ณ ์ปค๋ฐํ๊ณ ๋ฆฌํฉํ ๋งํ๊ณ ๊ทธ๋ฌ๋๋ผ ํ ์ฃผ๊ฐ ๊ฐ๋์ง๋ ๋ชจ๋ฅด๊ฒ ๋๋ฌ๋ ๊ฒ ๊ฐ๋ค.
๋ค๋ฅธ ๋ถ๋ค์ด ๋งค์ฃผ ํ๊ณ ๋ก์ ์์ฑํ์๋ ๊ฒ ๊ฝค ๋ฉ์์ด ๋ณด์ด๊ธฐ๋ ํ๊ณ , ๊ฐ์ธ์ ์ผ๋ก ์ฌ๋ฆ/๊ฒจ์ธ๋ง๋ค ํ๊ณ ๋ก์ ์์ฑํ๊ณ ์์์ด์ ์ฐํ ์ฝ ์ฐธ์ฌ ๊ธฐ๊ฐ ๋์์ ๋๋ ํ๊ณ ๋ก์ ๋จ๊ฒจ๋ณด๊ณ ์ ํ๋ค :D ์ฝ๋ ์ง๋ฉด์ ๋๋ฌด ๋ฐฐ์ฐ๋ ์ ์ด ๋ง์์ ๊ธฐ์๋ค.
- 1์ฃผ์ฐจ ๊ณผ์ ์ฝ๋๋ ์๋์์!
https://github.com/Cl8D/java-onboarding/tree/cl8d
- ์ฌ์ค 1์ฃผ์ฐจ ๊ณผ์ ๋ ์ฝํ ๋ฌธ์ ๋ ๊ฑฐ์ ๋ณ๋ค๋ฅผ ๊ฒ ์์๋ค๊ณ ๋ณธ๋ค.
๋์ด๋๋ง ๋ณด๋ฉด... 1๋ฒ์ ๊ตฌํํ ๊ฒ ์กฐ๊ธ ์๊ณ , 2~5๋ฒ์ ํ์ดํ๊ณ 6~7๋ฒ์ด ์กฐ๊ธ ์ด๋ ค์ ๋ ๊ฒ ๊ฐ๋ค.
- ๊ทผ๋ฐ ์ฌ์ค์ ์ฐํ ์ฝ๋ ๋์ด๋๋ฅผ ๋ฐ์ง๊ธฐ๋ณด๋จ, ์ด๊ฑธ ์ด๋ป๊ฒ ํ๋ฉด '๋ ๊น๋ํ๊ฒ, ํด๋ฆฐ ์ฝ๋๋ฅผ ์ธ ์ ์์๊น?'์ ๊ณ ๋ฏผ์ด ๊ฐ์ฅ ํฐ ๊ฒ ๊ฐ๋ค.
๊ธฐ๋ฅ ๊ตฌํ์ ๋ง์ ๋จน์ผ๋ฉด 1์๊ฐ ๋ด์๋ ๊ฐ๋ฅํ์ง๋ง, ์์ ํ๋๋ฐ ๋ฉฐ์น ์ฉ ๊ฑธ๋ฆฌ๊ธฐ ๋๋ฌธ...๐ต๐ซ
| ๊ณผ์ ์์ ์
- ์ฒซ ๊ณผ์ ์ธ ๋งํผ ๊ธด์ฅ ์๋ฉ ํ๊ณ ์ฌ๋ฌ ๊ฐ์ง ์ฐพ์๋ดค๋ ๊ธฐ์ต์ด ๋๋ค.
๋ณ์ ๋ค์ด๋ฐ, ๋ฉ์๋ ๋ค์ด๋ฐ, ์ปค๋ฐ ์ปจ๋ฒค์ , ๋ช ๋ช ๊ท์น, ํด๋ฆฐ์ฝ๋ ์ฒดํฌ๋ฆฌ์คํธ๊น์ง...
์ฌ์ค ์ง๊ธ๊น์ง ๊ฐ๋ฐํ ๋ ์์ฐ์ค๋ฝ๊ฒ ์ด๋ฐ ์์ผ๋ก ์จ์ผ์ง~๋ ํ์ง๋ง ๋ง์ ๊ฐ ์ก๊ณ ํ๋ ค๊ณ ํ๋๊น ๋๋ฌด ์ด์ง๋ฌ์ ๋ค.
- ํ์ง๋ง... ์ง๊ธ์ด ์๋๋ฉด ๋ค์๋ ์ฝ๋ฉ ์ต๊ด์ ์ ๋ชป ์ก์ ๊ฒ ๊ฐ๋ค๋ ์๊ฐ ํ๋๋ก ์งํค๋ ค๊ณ ์์ฒญ ์ ์ผ๋ค.
๊ฐ๊ฐ ์ฐธ๊ณ ํ๋ ๋ธ๋ก๊ทธ๋ ๋ค์๊ณผ ๊ฐ๋ค.
[๋ช ๋ช ๊ท์น]
[๋ณ์ ๋ค์ด๋ฐ]
[๋ฉ์๋ ๋ค์ด๋ฐ]
- ์ฌ๊ธฐ์ ์๋์ ์ผ๋ก ์งํค๋ ค๊ณ ํ๋ ๊ฑด ์ซ์ ๊ทธ๋๋ก ์ ๋ฐ๋ ๊ฑฐ. ์ด๊ฑฐ๋ 2์ฃผ์ฐจ์์๋ ์ ๊ฒฝ์ฐ๋ ค๊ณ ๋ ธ๋ ฅํ๋ค.
- ๋ํ, ์ด๋ฆ์ ๊ธธ๊ฒ ๊ฐ์ ธ๊ฐ๋ ๊ฑฐ์ ๋๋ ค์ํ์ง ์๋ ๊ฒ. ์คํ๋ ค ๋ฉ์๋๊ฐ ํ๋ ์ผ์ ์ ๋ด์ ์ ์๋ ๊ฒ ๊ฐ์์ ์ ๊ฒฝ์ฐ๋ ๋ถ๋ถ์ด๋ค.
๋ง์ฝ ๋ฉ์๋๊ฐ ๋๋ฌด ๋ค์ํ ์ผ์ ํด์ ๋ฉ์๋๋ช ์ด ๊ธธ์ด์ง๋ค? > ์ด๋ฌ๋ฉด ๋ฉ์๋ ๋ถ๋ฆฌ๊ฐ ํ์ํ๋ค๋ ๋ถ๋ถ์ด๊ธฐ ๋๋ฌธ์ ์ฒดํฌํ๋ฉด ๋๋ค.
- ๊ทธ๋ฆฌ๊ณ getXXX, createXXX... ๊ฐ์ด ๋์ฌ๋ก ์์ํ๊ฒ ํ๋ ๊ฑฐ. ๊ฐ์ธ์ ์ผ๋ก ์กฐํ๋ get์ผ๋ก ๊ณ ์ ํ๋ ๊ฒ ๋ณด๊ธฐ ์ข์ ๊ฒ ๊ฐ๋ค.
[์ปค๋ฐ ์ปจ๋ฒค์ ]
- ๊ฐ์ธ์ ์ผ๋ก 2๋ฒ์งธ ๋ธ๋ก๊ทธ์ ๋ด์ฉ์ ๋๋ฌด ์ ์ฝ์๋ค. ํนํ scope์ ๊ดํ ๋ถ๋ถ.
์ฌ์ค feat, chore, fix ๋ง๊ณ ์ง๊ธ๊น์ง๋ ๊ฐ๋ฐํ๋ฉด์ ๊ฑฐ์ ์ ์ผ๋ ๊ฒ ๊ฐ์๋ฐ 1์ฃผ์ฐจ ๊ณผ์ ํ๋ฉด์ ๋ฌธ์ ๋ฒํธ๋ฅผ scope๋ก ๋๊ณ ์ปค๋ฐํ๋๊น ๊ฐ๋ ์ฑ์ด ํ์คํ ์ข์์ก๋ค๋ ๊ฑธ ๋๊ผ๋ค.
- ๋๋ง ๊ทธ๋ ๊ฒ ๋๋ผ๋ ๊ฑฐ๋ฉด ๋ง๊ณ ....
- ๊ทธ๋ฆฌ๊ณ ์ปค๋ฐ ๋ฉ์์ง์๋ ์๋ฌธ์๋ง ์ฐ๋ ๊ฒ๋ ์์ง ๋ง๊ธฐ. ์ฒ์์ ๋ฌด์์์ ์ผ๋ก ๋๋ฌธ์๋ ๊ฐ์ด ๋ฃ์ด์ ๊ณ ์ํ๋ค.
(๋ช ๋ธ๋ก๊ทธ์์๋ ์ฒซ ๋ฌธ์๋ ๋๋ฌธ์๋ผ๊ณ ๋ ํ์ง๋ง... ๋๋ค์๋ ์๋ฌธ์๋ก ์ฐ๋ ๊ฒ ๋ง๋ค๊ณ ํด์ ์ฐ์ ๋๋ ์๋ฌธ์๋ก ๊ณ ์ ํด์ ์ฌ์ฉ ์ค์ด๋ค)
[ํด๋ฆฐ ์ฝ๋ ์ฒดํฌ๋ฆฌ์คํธ]
- ๊ฐ์ธ์ ์ผ๋ก ์ ๋ง ๋๋ฌด ์ค์ํ๋ค๊ณ ์๊ฐํ๋ ๋ถ๋ถ. ํนํ else ์ ์ฐ๋ ๊ฑฐ๋, ์ธ๋ดํธ ์ค์ด๋ ๊ฑฐ.
1์ฃผ์ฐจ ๋๋ ๊ทธ ๋ ๊ฐ๋ ์ถ๊ฐ์ ์ผ๋ก ๋ฉ์๋์ ์ธ์์ 3๊ฐ ์ด์์ผ๋ก ์ ๋ค์ด๊ฐ๋๋ก ๋ ธ๋ ฅํ๋ ๊ฒ ๊ฐ๋ค.
| 1๋ฒ ๋ฌธ์
- ํฌ๊ฒ ๊ณ ๋ฏผํ๋ ๋ถ๋ถ์ '์ ํ์ฌํญ์ ์ฝ๋๋ก ๋ฃ๋ ๊ฒ ๋ง๋๊ฐ?' ์ด ๋ถ๋ถ์ด์๋ ๊ฒ ๊ฐ๋ค.
๋ณดํต ๋ฐฑ์ค์ด๋ ํ๋ก๊ทธ๋๋จธ์ค์์๋ ์ ํ์ฌํญ์ ์๋ฐฐ๋๋ ์ ๋ ฅ๊ฐ์ ์ ๋ค์ด์ค๊ธฐ๋ ํ๊ณ , ์ฌ๊ธฐ์๋ ์ฌ์ค ๊ทธ๋ด ๊ฒ ๊ฐ์๊ธฐ ๋๋ฌธ...
ํ์ง๋ง! ๊ตฌํ ํ๋ ๋ ํ๋ค๊ณ ๋์ ๊ฑด ์ ํ ์๊ธฐ ๋๋ฌธ์ ๋ฐ๋ก ๊ตฌํํ๋ค ใ ใ
package onboarding;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
class Problem1 {
static final int FIRST_PAGE = 1;
static final int LAST_PAGE = 400;
public static int solution(List<Integer> pobi, List<Integer> crong) {
// ์
๋ ฅ ํ์ด์ง ๊ฒ์ฆ ํ ์์ธ ์ฌํญ์ผ ๊ฒฝ์ฐ -1์ ๋ฆฌํดํ๋ค.
if (isNotPageValid(pobi) || isNotPageValid(crong)) {
return -1;
}
// ํฌ๋น์ ์ผ์ชฝ, ์ค๋ฅธ์ชฝ ํ์ด์ง ๋ฒํธ๋ฅผ ๊ตฌํ๋ค.
int pobiLeftPage = pobi.get(0);
int pobiRightPage = pobi.get(1);
// ํฌ๋กฑ์ ์ผ์ชฝ, ์ค๋ฅธ์ชฝ ํ์ด์ง ๋ฒํธ๋ฅผ ๊ตฌํ๋ค.
int crongLeftPage = crong.get(0);
int crongRightPage = crong.get(1);
// ํฌ๋น์ ๊ฒฐ๊ณผ ๋ฆฌ์คํธ๋ฅผ ๊ตฌํ๋ค.
List<Integer> pobiResultList = List.of(getSumValue(pobiLeftPage), getSumValue(pobiRightPage),
getMultiplyValue(pobiLeftPage), getMultiplyValue(pobiRightPage));
int pobiScore = getMaxValue(pobiResultList);
// ํฌ๋กฑ์ ๊ฒฐ๊ณผ ๋ฆฌ์คํธ๋ฅผ ๊ตฌํ๋ค.
List<Integer> crongResultList = List.of(getSumValue(crongLeftPage), getSumValue(crongRightPage),
getMultiplyValue(crongLeftPage), getMultiplyValue(crongRightPage));
int crongScore = getMaxValue(crongResultList);
return compareResult(pobiScore, crongScore);
}
/**
* ์
๋ ฅ ํ์ด์ง์ ๋ํ ๊ฒ์ฆ์ ์งํํ๋ค.
*
* @param pageNums ์ฌ์ฉ์์ ํ์ด์ง ๋ฒํธ ๋ฆฌ์คํธ
* @return ์ฌ๋ฐ๋ฅด์ง ์์ ํ์ด์ง ๋ฆฌ์คํธ๋ผ๋ฉด true, ์๋๋ผ๋ฉด false
*/
private static boolean isNotPageValid(List<Integer> pageNums) {
int leftPage = pageNums.get(0);
int rightPage = pageNums.get(1);
/* ์
๋ ฅ ํ์ด์ง์ ๋ํด์ ๊ฒ์ฆ์ ์งํํ๋ค. ๋ค์์ ์์ธ ์ฌํญ์ผ๋ก ๊ฐ์ฃผํ๋ค.
1. ํ์ด์ง์ ๋ฒ์๊ฐ 1~400 ์ฌ์ด๊ฐ ์๋ ๊ฒฝ์ฐ
2. ํ์ด์ง๊ฐ ์์์ด๋ ๋ง์ง๋ง ๋ฉด์ธ ๊ฒฝ์ฐ
3. ์ผ์ชฝ ํ์ด์ง๊ฐ ํ์๊ฐ ์๋๊ณ , ์ค๋ฅธ์ชฝ ํ์ด์ง๊ฐ ์ง์๊ฐ ์๋ ๊ฒฝ์ฐ
4. ์ผ์ชฝ, ์ค๋ฅธ์ชฝ ํ์ด์ง์ ์ฐจ๊ฐ 1์ด ์๋ ๊ฒฝ์ฐ (์ฐ์๋ ํ์ด์ง๊ฐ ์๋)
*/
return isNotPageRange(leftPage, rightPage) || isPageFirstOrLast(leftPage) ||
isNotPageOddAndEven(leftPage, rightPage) || isNotPageContinuous(leftPage, rightPage);
}
/**
* ์
๋ ฅ ํ์ด์ง์ ๋ฒ์๊ฐ 1~400 ์ฌ์ด๊ฐ ์๋์ง ํ๋จํ๋ค.
*
* @param leftPage ์ผ์ชฝ ํ์ด์ง
* @param rightPage ์ค๋ฅธ์ชฝ ํ์ด์ง
* @return 1~400 ์ฌ์ด๊ฐ ์๋๋ผ๋ฉด true, ๋ง๋ค๋ฉด false
*/
private static boolean isNotPageRange(int leftPage, int rightPage) {
return leftPage < FIRST_PAGE || leftPage >= LAST_PAGE || rightPage <= FIRST_PAGE || rightPage > LAST_PAGE;
}
/**
* ์ผ์ชฝ ํ์ด์ง ๋ฒํธ๊ฐ ์์ ๋ฉด์ด๊ฑฐ๋ ๋ง์ง๋ง ๋ฉด์ธ์ง ํ๋จํ๋ค.
*
* @param leftPage ์ผ์ชฝ ํ์ด์ง
* @return ์ผ์ชฝ ํ์ด์ง์ ๊ฐ์ด 1์ด๊ฑฐ๋ 399๋ผ๋ฉด true, ์๋๋ผ๋ฉด false
*/
private static boolean isPageFirstOrLast(int leftPage) {
return leftPage == FIRST_PAGE || leftPage == LAST_PAGE-1;
}
/**
* ์ผ์ชฝ ํ์ด์ง๊ฐ ํ์, ์ค๋ฅธ์ชฝ ํ์ด์ง๊ฐ ์ง์๊ฐ ์๋์ง ํ๋จํ๋ค.
*
* @param leftPage ์ผ์ชฝ ํ์ด์ง
* @param rightPage ์ค๋ฅธ์ชฝ ํ์ด์ง
* @return ์ผ์ชฝ ํ์ด์ง๊ฐ ํ์๊ฐ ์๋๊ณ ์ค๋ฅธ์ชฝ ํ์ด์ง๊ฐ ์ง์๊ฐ ์๋๋ฉด true, ์๋๋ผ๋ฉด false
*/
private static boolean isNotPageOddAndEven(int leftPage, int rightPage) {
return leftPage % 2 != 1 && rightPage % 2 != 0;
}
/**
* ์ผ์ชฝ, ์ค๋ฅธ์ชฝ ํ์ด์ง๊ฐ ์ฐ์์ ์ด์ง ์์์ง ํ์ธํ๋ค.
*
* @param leftPage ์ผ์ชฝ ํ์ด์ง
* @param rightPage ์ค๋ฅธ์ชฝ ํ์ด์ง
* @return ์ค๋ฅธ์ชฝ, ์ผ์ชฝ ํ์ด์ง์ ์ฐจ๊ฐ 1์ด ์๋๋ผ๋ฉด true, ์๋๋ผ๋ฉด false
*/
private static boolean isNotPageContinuous(int leftPage, int rightPage) {
return rightPage - leftPage != 1;
}
/**
* ์
๋ ฅ ๋ฐ์ ํ์ด์ง ๋ฒํธ์ ๊ฐ ์๋ฆฌ์์ ํฉ์ ๊ตฌํ๋ค.
*
* @param page ํ์ด์ง ๋ฒํธ
* @return ๊ฐ ์๋ฆฌ์์ ํฉ
*/
private static int getSumValue(int page) {
int[] pageArr = getPageValueArray(page);
return Arrays.stream(pageArr).sum();
}
/**
* ์
๋ ฅ ๋ฐ์ ํ์ด์ง ๋ฒํธ์ ๊ฐ ์๋ฆฌ์์ ๊ณฑ์ ๊ตฌํ๋ค.
*
* @param page ํ์ด์ง ๋ฒํธ
* @return ๊ฐ ์๋ฆฌ์์ ๊ณฑ
*/
private static int getMultiplyValue(int page) {
int[] pageArr = getPageValueArray(page);
int multiVal = 1;
for(int pageVal : pageArr) {
multiVal *= pageVal;
}
return multiVal;
}
/**
* ์
๋ ฅ ๋ฐ์ ํ์ด์ง์ ๊ฐ ์๋ฆฟ์๋ฅผ ๋ด์ ๋ฐฐ์ด์ ๊ตฌํ๋ค.
*
* @param page ํ์ด์ง ๋ฒํธ
* @return ๊ฐ ์๋ฆฟ์๊ฐ ๋ด๊ธด ๋ฐฐ์ด
*/
private static int[] getPageValueArray(int page) {
String[] digitStrArr = String.valueOf(page).split("");
return Stream.of(digitStrArr).mapToInt(Integer::parseInt).toArray();
}
/**
* ํ์ด์ง ๋ฒํธ์ ๋ฐ๋ฅธ ์๋ฆฌ์ ๊ณ์ฐ ๊ฒฐ๊ณผ ์ค ๊ฐ์ฅ ํฐ ๊ฐ์ ๋ฆฌํดํ๋ค.
*
* @param resultArr ์๋ฆฌ์ ๊ณ์ฐ ๊ฒฐ๊ณผ๋ฅผ ๋ด์ ๋ฆฌ์คํธ
* @return ๊ฐ์ฅ ํฐ ๊ฐ
*/
private static int getMaxValue(List<Integer> resultArr) {
int maxVal = 0;
for(int resultVal : resultArr) {
maxVal = Math.max(maxVal, resultVal);
}
return maxVal;
}
/**
* ๋ ์ฌ๋์ ์ ์๋ฅผ ๋น๊ตํ์ฌ ๊ฒฐ๊ณผ๋ฅผ ์ถ๋ ฅํ๋ค.
*
* @param pobiScore ํฌ๋น์ ์ ์
* @param crongScore ํฌ๋กฑ์ ์ ์
* @return ํฌ๋น๊ฐ ์ด๊ธฐ๋ฉด 1, ํฌ๋กฑ์ด ์ด๊ธฐ๋ฉด 2, ๋ฌด์น๋ถ๋ 0์ ๋ฆฌํดํ๋ค.
*/
private static int compareResult(int pobiScore, int crongScore) {
if (pobiScore > crongScore) {
return 1;
}
if (pobiScore < crongScore) {
return 2;
}
return 0;
}
}
- ๊ทธ๋ฅ ๊ฐ๋จํ๊ฒ ์์ํ ์ ๊ฒฝ์ฐ๊ณ , ํ๋์ ์ผ๋ง ํ๋๋ก ๋ฉ์๋๋ฅผ ์ต๋ํ ์๊ฒ ๋ถ๋ฆฌํ๋ค.
Stream.of.mapToInt ์ฌ์ฉํด์ ์๋ฆฟ์ ๋ฐฐ์ด ๋ง๋ ๊ฒ ๊ฐ์ฅ ๊ธฐ์ต์ ๋จ๋ ๋ฌธ์ ์ด๋ค.
| 2๋ฒ ๋ฌธ์
- 2๋ฒ ๋ฌธ์ ๋ ์๊ฐ๋ณด๋ค ๊น๋ค๋ก์ ๋ค. ํ(๋ฑ)๋ฅผ ์ฌ์ฉํด์ ํ๊น ๊ณ ๋ฏผํ๋ค๊ฐ ๊ทธ๋ผ ๋๋ฌด ๋ณต์กํด์ง ๊ฒ ๊ฐ์๊ธฐ ๋๋ฌธ...
๊ทธ๋์ while๋ฌธ์ ๋๊น, ์๋๋ฉด 2์ค for๋ฌธ์ ๋๊น ๊ณ ๋ฏผํ๋ค๊ฐ ๋ ๋ค ๋ง์์ ์ ๋ค์ด์ ์์ฒญ ๊ณ ๋ฏผํ๋ค ์ ๊ท์์ผ๋ก ํ์๋ค!
๊ฐ์ธ์ ์ผ๋ก ํ๊ณ ๋์ ๋๋ฌด ๋ฟ๋ฏํ๋ ๋ฌธ์ ใ ใ
package onboarding;
import onboarding.common.InputStringUtil;
import onboarding.common.ValidationUtil;
public class Problem2 {
public static String solution(String cryptogram) {
// ์
๋ ฅ ์ํธ๋ฌธ ๋ํ ์ ํ์ฌํญ์ ๊ฒ์ฆํ๋ค.
verifyCryptogram(cryptogram);
// ์
๋ ฅ ๋ฌธ์์ด์ charํ ๋ฐฐ์ด๋ก ๋ถํดํ๋ค.
char[] cryptogramArr = InputStringUtil.getCharArr(cryptogram);
// ๋ฐฐ์ด์ ์ํํ๋ฉฐ ํด๋น ์์๋ฅผ ๊ธฐ์ค์ผ๋ก ์ค๋ณต ๋ฌธ์์ด์ ์ฒดํฌํ๋ค.
for(Character element : cryptogramArr) {
// ํด๋น ๋ฌธ์๊ฐ 2๋ฒ ์ด์ ๋ฐ๋ณต๋๋ค๋ฉด ์ ๊ฑฐํ์ฌ ์๋ณธ ์ํธ๋ฌธ์ ๋ณ๊ฒฝํ๋ค.
cryptogram = removeDuplicateElement(cryptogram, element);
}
return cryptogram;
}
/**
* ์
๋ ฅ๋ฐ์ ์ํธ๋ฌธ์ ๋ํ ๊ฒ์ฆ ์์
์ ์งํํ๋ค.
*
* @param cryptogram ์
๋ ฅ ์ํธ๋ฌธ
*/
private static void verifyCryptogram(String cryptogram) {
// ์ํธ๋ฌธ์ ๊ธธ์ด๋ 1~1000 ์ฌ์ด๋ก ์ ํ๋์ด ์๋ค.
ValidationUtil cryptogramValidation = new ValidationUtil();
cryptogramValidation.addVarName("cryptogram");
cryptogramValidation.checkStrLowerCase(cryptogram, 1, 1000);
}
/**
* 2๋ฒ ์ด์ ์ค๋ณต๋ ๋ฌธ์์ด์ ์ ๊ฑฐํ๋ค.
*
* @param cryptogram ์ ๊ฑฐ ์งํํ ๋ฌธ์์ด
* @param element ์ ๊ฑฐ์ ๊ธฐ์ค์ด ๋๋ ์์
* @return String - ์ ๊ฑฐ ์์
์ด ์๋ฃ๋ ๋ฌธ์์ด์ ๋ฆฌํดํ๋ค.
*/
private static String removeDuplicateElement(String cryptogram, Character element) {
return cryptogram.replaceAll(element + "{2,}", "");
}
}
- ๋ค์ 1์ฃผ์ฐจ ๊ณผ์ ๋ ์ฃผ์์ ์์ฒญ ๋ฌ๋ค ๋ณด๋๊น ์ฝ๋๊ฐ ๊ธธ๋ค...
์๋ฌดํผ...! ์ ๊ท์์ ํตํด์ {2, } -> 2๋ฒ ์ด์ ๋ฐ๋ณตํ๋ ๋ฌธ์์ ๋ํด์ ์ ๋ถ ์ญ์ ์ฒ๋ฆฌ๋ฅผ ์งํํด์ฃผ์๋ค.
์์์ ์ญ์ ๋ฅผ ์ฒ๋ฆฌํ๋ฉด ๋ฐ๋ณต๋ฌธ์ ํตํด ๊ทธ ๋ค์ ์์๋ฅผ ๋์๋ ๋ ๋ค์ ์ค๋ณต๋๋ ๋ฌธ์๋ฅผ ์ ๊ฑฐํด์ค ์ ์๊ธฐ ๋๋ฌธ์ 1์ค for๋ฌธ์ผ๋ก๋ ํ ์ ์์ด์ ์ข์๋ค.
- ์ถ๊ฐ์ ์ผ๋ก ๊ฒ์ฆ์ ๊ดํ ๋ถ๋ถ์ ๋ฐ๋ก ์๋์ ์์ฑํ ์์ ์ด๋ค.
| 3๋ฒ ๋ฌธ์
- 3๋ฒ์ ์ง์ง ๊ธฐ์ด ๋ฌธ์ ์ฌ์ ํฌ๊ฒ ์ด๋ ค์ธ ๊ฒ ์์ด ํ์๋ค.
package onboarding;
import onboarding.common.ValidationUtil;
public class Problem3 {
static final String[] NUM_FOR_CLAPS = {"3", "6", "9"};
public static int solution(int number) {
int answer = 0;
// ์
๋ ฅ๋ฐ์ ์ซ์์ ๋ํ ๊ฒ์ฆ ์์
์ ์งํํ๋ค.
verifyNumber(number);
// 1๋ถํฐ ์
๋ ฅ์ผ๋ก ์ฃผ์ด์ง ๋ฒํธ๊น์ง ์ํ๋ฅผ ์งํํ๋ค.
for (int num = 1; num <= number; num++) {
// ๊ฐ ๋ฒํธ๋ฅผ ๋ฌธ์์ด๋ก ๋ณ๊ฒฝํ๊ณ , ์๋ณธ ๊ธธ์ด๋ฅผ ๊ตฌํ๋ค.
String strNum = String.valueOf(num);
int originLen = strNum.length();
// ๋ฐ์ ํ์๋ฅผ ๊ณ์ ๋ํด์ค๋ค.
answer += getClapCount(strNum, originLen);
}
return answer;
}
/**
* ์
๋ ฅ๋ฐ์ ์ซ์์ ๋ํ ๊ฒ์ฆ ์์
์ ์งํํ๋ค.
*
* @param number ์
๋ ฅ๋ฐ์ ์ซ์
*/
private static void verifyNumber(int number) {
ValidationUtil numValidation = new ValidationUtil();
numValidation.addVarName("number");
// ์ซ์์ ๋ฒ์๋ 1~10000 ์ฌ์ด๋ก ์ ํ๋์ด ์๋ค.
numValidation.checkNumRange(number, 1, 10000);
}
/**
* ๋ฐ์ ํ์๋ฅผ ๊ตฌํ๋ค.
*
* @param strNum ๊ธฐ์ค ๋ฌธ์์ด
* @param originLen ๊ธฐ์ค ๋ฌธ์์ด์ ์๋ณธ ๊ธธ์ด
* @return int - 3/6/9๊ฐ ํฌํจ๋์์ ๋ ์น ๋ฐ์ ํ์๋ฅผ ๋ฆฌํดํ๋ค.
*/
private static int getClapCount(String strNum, int originLen) {
int clapCount = 0;
for(String clapNum : NUM_FOR_CLAPS) {
int newLen = checkClapNumAndGetLength(strNum, clapNum);
// ์ ๊ฑฐ๋ ๊ธธ์ด๋งํผ์ด ๋ฐ์๋ฅผ ์น ํ์๊ฐ ๋๋ค.
if (newLen != -1) {
clapCount += (originLen - newLen);
}
}
return clapCount;
}
/**
* ๊ธฐ์ค ๋ฌธ์์ด์ 3/6/9๊ฐ ํฌํจ์ด ๋์ด ์๋ค๋ฉด ์ ๊ฑฐ ํ ๊ธธ์ด๋ฅผ ๊ตฌํ๋ค.
*
* @param strNum ๊ธฐ์ค ๋ฌธ์์ด
* @param clapNum 369 ๊ฒ์์ ๊ธฐ์ค์ด ๋๋ ๋ฒํธ (3/6/9)
* @return int - ์ ๊ฑฐ ์๋ฃ๋ ๋ฌธ์์ด์ ๊ธธ์ด๋ฅผ ๋ฆฌํดํ๋ค. ๋ณ๊ฒฝ์ฌํญ์ด ์์ ๊ฒฝ์ฐ -1์ ๋ฆฌํดํ๋ค.
*/
private static int checkClapNumAndGetLength(String strNum, String clapNum) {
if (strNum.contains(clapNum)) {
String removedStr = removeClapNum(strNum, clapNum);
return removedStr.length();
}
return -1;
}
/**
* ๋ฌธ์์ด์ ์กด์ฌํ๋ clapNum (3/6/9)๋ฅผ ์ ๊ฑฐํ๋ค.
*
* @param strNum ๊ธฐ์ค ๋ฌธ์์ด
* @param clapNum 369 ๊ฒ์์ ๊ธฐ์ค์ด ๋๋ ๋ฒํธ (3/6/9)
* @return String - ์ ๊ฑฐ๊ฐ ์๋ฃ๋ ๋ฌธ์์ด์ ๋ฆฌํดํ๋ค.
*/
private static String removeClapNum(String strNum, String clapNum) {
return strNum.replaceAll(clapNum, "");
}
}
- ๋ค๋ฅธ ๋ถ๋ค ์ฝ๋๋ฅผ ๋ณด๋๊น ์ํ์ ์ผ๋ก ์ ๊ทผํ์ ๋ถ๋ค๋ ๊ณ์ จ๋๋ฐ, ๋๋ ๊ทธ์ ๋๋ก ๋จธ๋ฆฌ๊ฐ ๊ตด๋ฌ๊ฐ์ง ์๊ธฐ ๋๋ฌธ์...
์ด์ฐจํผ 3, 6, 9๋ผ๋ ๊ธธ์ด๊ฐ 1์ธ ๋ฌธ์์ ๋ํด์๋ง ์ ๊ฑฐ ์ฒ๋ฆฌ๋ฅผ ํ๋ฉด, ๊ทธ๊ฒ ๊ณง ๋ฐ์ ํ์๊ฐ ๋๊ธฐ ๋๋ฌธ์ ๊ธธ์ด๊ฐ ์ด๋ ์ ๋ ๋ฌ๋ผ์ก๋์ง๋ก ํ๋จํ๋ค.
์ด๊ฒ๋ ๊ฝค... ๋ ํนํ๊ฒ ํ์๋ค๊ณ ์๊ฐํ๋๋ฐ ๋๋ง ๊ทธ๋ด์ง๋...?
| 4๋ฒ ๋ฌธ์
- 4๋ฒ์ ์์คํค๋ฅผ ํ์ฉํ๋ ๋ฌธ์ ! ์์คํค์ฝ๋ํ ๋ณด๋ฉด์ ํ์๋ค ใ ใ ใ ใ ใ
package onboarding;
public class Problem4 {
static final char START_ASCII_BY_UPPER_CASE = 'A';
static final char END_ASCII_BY_UPPER_CASE = 'Z';
static final char START_ASCII_BY_LOWER_CASE = 'a';
static final char END_ASCII_BY_LOWER_CASE = 'z';
public static String solution(String word) {
StringBuilder answer = new StringBuilder("");
// ์
๋ ฅ ๋ฌธ์์ด์ ๋ฐฐ์ด๋ก ๋ณํํ๋ค.
char[] wordArr = getCharArr(word);
for(Character wordVal : wordArr) {
// ๋ง์ฝ ์ํ๋ฒณ์ด ์๋๋ผ๋ฉด ๊ณต๋ฐฑ์ผ๋ก ๊ฐ์ฃผํ๋ค.
if(isNotAlphabetic(wordVal)) {
answer.append(' ');
continue;
}
// ์ํ๋ฒณ์ด๋ผ๋ฉด ๋ณํ ์์
์ ์งํํ๋ค.
char reversedVal = changeReversed(wordVal);
answer.append(reversedVal);
}
return answer.toString();
}
/**
* ์ฒญ๊ฐ๊ตฌ๋ฆฌ ์ฌ์ ์ ๋ฐ๋ผ ๋จ์ด๋ฅผ ๋ณํํ๋ค.
*
* @param value ์๋ณธ ๋จ์ด ์์
* @return char - ์ฌ์ ์ ๋ฐ๋ผ ๋ณํ๋ ์์๋ฅผ ๋ฆฌํดํ๋ค. ๋๋ฌธ์๋ ๋๋ฌธ์๋ก, ์๋ฌธ์๋ ์๋ฌธ์๋ก ๋ฆฌํด๋๋ค.
*/
private static char changeReversed(char value) {
if (Character.isUpperCase(value))
return (char) (END_ASCII_BY_UPPER_CASE - (value - START_ASCII_BY_UPPER_CASE));
return (char) (END_ASCII_BY_LOWER_CASE - (value - START_ASCII_BY_LOWER_CASE));
}
/**
* ์์๊ฐ ์ํ๋ฒณ์ด ์๋์ง ํ๋จํ๋ค.
*
* @param value ํ๋จํ ์์
* @return ์ํ๋ฒณ์ด ์๋๋ผ๋ฉด true, ๋ง๋ค๋ฉด false
*/
private static boolean isNotAlphabetic(Character value) {
return !Character.isAlphabetic(value);
}
/**
* ํ๋ผ๋ฏธํฐ๋ก ๋ฐ์ ๋ฌธ์์ด์ charํ ๋ฐฐ์ด๋ก ๋ถํดํ์ฌ ๋ฆฌํดํ๋ค.
*
* @param str ๋ฌธ์์ด
* @return char[] - ์
๋ ฅ์ผ๋ก ๋ฐ์ ๋ฌธ์์ด์ ๋ํด charํ ๋ฐฐ์ด๋ก ์ชผ๊ฐ ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํดํ๋ค.
*/
private static char[] getCharArr(String str) {
return str.toCharArray();
}
}
- ์ฌ์ค ์ฌ์ ์ ๊ทธ๋ฅ ์ฒญ๊ฐ๊ตฌ๋ฆฌ ์ฌ์ ์ ๊ฐ์ ์ง์ ํด๋๊ณ ํ์๋ค๋ฉด ๋ ๊ฐ๋จํ๊ฒ ์ง๋ง... ์ฝ๋๊ฐ ๊ฐ์ง๊ฐ ์๋ค. ๊ทธ๋ฐ ๊ฑด ์ฉ๋ฉ ๋ถ๊ฐ.
| 5๋ฒ ๋ฌธ์
- 5๋ฒ๋ ์ง์ง ๊ธฐ์ด ๋ฌธ์ ์๊ธฐ ๋๋ฌธ์ ์ด๋ ต์ง ์๊ฒ ํ ์ ์์๋ค.
package onboarding;
import onboarding.common.ValidationUtil;
import java.util.ArrayList;
import java.util.List;
public class Problem5 {
static final int[] MONETARY_UNIT = {50000, 10000, 5000, 1000, 500, 100, 50, 10, 1};
public static List<Integer> solution(int money) {
List<Integer> answer = new ArrayList<>();
// ์
๋ ฅ๋ ๊ธ์ก์ ๋ํ ๊ฒ์ฆ์ ์งํํ๋ค.
moneyValidation(money);
// ๋ด๋ฆผ์ฐจ์์ผ๋ก ์ ๋ ฌ๋ ํํ ๋จ์๋ฅผ ์ํํ๋ค.
for(int unit : MONETARY_UNIT) {
// ๊ธฐ์กด ๊ธ์ก์ด ๋จ์๋ณด๋ค ์์ผ๋ฉด ํด๋น ํํ์ ๊ฐ์๋ 0์ผ๋ก ๊ฐ์ฃผํ๋ค.
if (money < unit) {
answer.add(0);
continue;
}
// ๊ทธ๊ฒ ์๋๋ผ๋ฉด ๊ธฐ์กด ๊ธ์ก์์ ํํ ๋จ์๋ก ๋๋ ๋ชซ์ด ๊ฐ์๊ฐ ๋๋ค.
answer.add(money/unit);
// ๊ธฐ์กด ๊ธ์ก์ ํํ ๋จ์๋ก ๋๋ ๋๋จธ์ง๋ก ๊ฐฑ์ ํ๋ค.
money %= unit;
}
return answer;
}
/**
* ์
๋ ฅ์ผ๋ก ๋ค์ด์จ ๊ธ์ก์ ๋ํด ๊ฒ์ฆํ๋ค.
*
* @param money ์
๋ ฅ๋ฐ์ ๊ธ์ก
*/
private static void moneyValidation(int money) {
ValidationUtil moneyValidation = new ValidationUtil();
moneyValidation.addVarName("money");
// ๊ธ์ก์ 1~1000000 ์ฌ์ด์ ๊ฐ์ด์ด์ผ ํ๋ค.
moneyValidation.checkNumRange(money, 1, 1000000);
}
}
- ์ฝ๊ฐ... ๋ฐฑ์ค์์ ๋ณผ ๊ฒ ๊ฐ์ ๋ฌธ์ ์๋ค.
| 6๋ฒ ๋ฌธ์
- 6๋ฒ๋ถํฐ ์ ์ ๋์ด๋๊ฐ ์ด๋ ค์์ก๋ ๋๋...
ํ์ง๋ง ๊ฐ์ธ์ ์ผ๋ก Map, Set ๊ฐ์ ์๋ฃ๊ตฌ์กฐ๋ฅผ ์ด์ฉํ ๋ฌธ์ ํธ๋ ๊ฑธ ๋๋ฌด ์ข์ํ๊ธฐ ๋๋ฌธ์ ํ๋ฉด์ ์ฌ๋ฐ์๋ค ใ ใ
package onboarding;
import onboarding.common.ValidationUtil;
import onboarding.exception.InputRangeException;
import onboarding.exception.InputTypeException;
import java.util.*;
import java.util.regex.Pattern;
public class Problem6 {
// ๋ถ๋ถ ๋๋ค์ ๋ฌธ์์ด๊ณผ ์ด๋ฉ์ผ ์ ๋ณด๋ฅผ ๋ด์ ๋งต์ด๋ค.
static Map<String, String> partNameWithEmail;
// ๊ฒฐ๊ณผ ์ด๋ฉ์ผ์ ๋ด๋ TreeSet์ด๋ค.
static Set<String> answer;
public static List<String> solution(List<List<String>> forms) {
partNameWithEmail = new HashMap<>();
answer = new TreeSet<>();
// ํฌ๋ฃจ์ ์ธ์ ์์ ๋ํด์ ๊ฒ์ฆํ๋ค.
verifyCrewNum(forms);
for(List<String> form : forms) {
// ํฌ๋ฃจ๋ค์ ์ด๋ฉ์ผ๊ณผ ๋๋ค์ ์ ๋ณด๋ฅผ ๊ฐ๊ฐ ์ถ์ถํ๋ค.
String email = form.get(0);
// ์ด๋ฉ์ผ์ ๋ํ ๋๋ฉ์ธ ๊ฒ์ฆ์ ์งํํ๋ค.
checkEmailCond(email);
String nickname = form.get(1);
// ๋๋ค์์ ๋ํ ์กฐ๊ฑด์ ๊ฒ์ฆํ๋ค.
checkNicknameCond(nickname);
// ์ด๋ฉ์ผ์ ํ ๊ธ์์ฉ ๋์ด์ ๋ฐฐ์ด๋ก ๋ง๋ ๋ค.
String[] nameArr = nickname.split("");
// 2๊ธ์์ฉ ๋์ด์ ๋ถ๋ถ ๋๋ค์์ ์์ฑํ ๋ค ์ค๋ณต์ ์ฒดํฌํ๋ค.
createPartNicknameAndCheck(email, nameArr);
}
// ๊ฒฐ๊ณผ๋ฅผ ์ค๋ฆ์ฐจ์์ผ๋ก ์ ๋ ฌํ๋ค.
List<String> answerList = new ArrayList<>(answer);
answerList.sort(String::compareTo);
return answerList;
}
/**
* ์
๋ ฅ๋ฐ์ ํฌ๋ฃจ์ ์ธ์์์ ๋ํด์ ๊ฒ์ฆํ๋ค.
*
* @param forms ํฌ๋ฃจ ๋ฆฌ์คํธ
*/
private static void verifyCrewNum(List<List<String>> forms) {
ValidationUtil crewSizeValidation = new ValidationUtil();
crewSizeValidation.addVarName("crew member size");
// ํฌ๋ฃจ์ ์ฌ์ด์ฆ๋ 1~10000 ์ฌ์ด์ด๋ค.
crewSizeValidation.checkNumRange(forms.size(), 1, 10000);
}
/**
* ๋๋ค์์ ๋ํ ํ์์ ๊ฒ์ฆํ๋ค.
*
* @param nickname ์
๋ ฅ๋ฐ์ ๋๋ค์
*/
private static void checkNicknameCond(String nickname) {
// ๋๋ค์์ ํ๊ธ๋ก๋ง ์ด๋ฃจ์ด์ ธ ์์ผ๋ฉฐ, ๊ธธ์ด๋ 1~19 ์ฌ์ด์ฌ์ผ ํ๋ค.
String regex = "^[ใฑ-ใ
ใ
-ใ
ฃ๊ฐ-ํฃ]{1,19}$";
if (!Pattern.matches(regex, nickname)) {
throw new InputRangeException("๋๋ค์์ ํ๊ธ๋ก๋ง ์ด๋ฃจ์ด์ ธ์ผ ํ๋ฉฐ, ๊ธธ์ด๋ 1~19์๊น์ง ๊ฐ๋ฅํฉ๋๋ค.");
}
}
/**
* ์ด๋ฉ์ผ์ ๋ํ ํ์์ ๊ฒ์ฆํ๋ค.
*
* @param email ์
๋ ฅ๋ฐ์ ์ด๋ฉ์ผ
*/
private static void checkEmailCond(String email) {
// ์ด๋ฉ์ผ์ @email.com ๋๋ฉ์ธ์ผ๋ก ๊ตฌ์ฑ๋์ด ์์ผ๋ฉฐ, ์ ์ฒด ๊ธธ์ด๋ 11~20์ ๋ฏธ๋ง์ด๋ค.
// @email.com์ด 10์์ด๊ธฐ ๋๋ฌธ์, ์๋จ์ ์์ด๋๋ 1~9์๊น์ง ๋ ์ ์๋ค.
String regex = "^[a-zA-Z0-9]{1,9}@email[.]com$";
if (!Pattern.matches(regex, email)) {
throw new InputTypeException("์ด๋ฉ์ผ์ 11~20์ ์ฌ์ด์ด๋ฉฐ, ๋๋ฉ์ธ์ @email.com๋ก ์ ํ๋์ด ์์ต๋๋ค.");
}
}
/**
* ๋๋ค์ ๋ฐฐ์ด๋ก๋ถํฐ 2๊ธ์์ฉ ์๋ฅด๊ณ ์ค๋ณต์ ์ฒดํฌํ๋ค.
*
* @param email ์ฌ์ฉ์์ ์ด๋ฉ์ผ
* @param nameArr ์ฌ์ฉ์์ ๋๋ค์ ๋ฐฐ์ด
*/
private static void createPartNicknameAndCheck(String email, String[] nameArr) {
for (int i = 0; i < nameArr.length-1; i++) {
String partNickname = nameArr[i] + nameArr[i+1];
// ๋ถ๋ถ ๋๋ค์ ๋ฌธ์์ด์ ๋ํ ์ค๋ณต ์ฒดํฌ๋ฅผ ์งํํ๋ค.
checkDuplicatedAndAddResult(email, partNickname);
partNameWithEmail.put(partNickname, email);
}
}
/**
* ๋ถ๋ถ ๋๋ค์ ๋ฌธ์์ด์ ๋ํ ์ค๋ณต ์ฒดํฌ๋ฅผ ์งํํ ๋ค ๊ฒฐ๊ณผ Set์ ๋ด๋๋ค.
*
* @param email ์ฌ์ฉ์์ ์ด๋ฉ์ผ
* @param partNickname ์ฌ์ฉ์์ ๋ถ๋ถ ๋๋ค์ ๋ฌธ์์ด
*/
private static void checkDuplicatedAndAddResult(String email, String partNickname) {
if(partNameWithEmail.containsKey(partNickname)) {
// ํด๋น ์ฌ์ฉ์์ ์ด๋ฉ์ผ์ ๊ฒฐ๊ณผ Set์ ์ถ๊ฐํ๋ค.
answer.add(email);
// ์ค๋ณต๋ ๋ถ๋ถ ๋ฌธ์์ด์ ๊ฐ์ง ์ฌ์ฉ์์ ์ด๋ฉ์ผ์ ๊ฒฐ๊ณผ Set์ ์ถ๊ฐํ๋ค.
answer.add(partNameWithEmail.get(partNickname));
}
}
}
- ์ญ์ ๊ธฐ์ต์ ๋จ๋ ๊ฑด ์ ๊ท์...
์ ํ์ฌํญ ๊ฒ์ฆ์ ์ฝ๋์ ๋ฃ์ง ์์๋ค๋ฉด ์ฌ์ค ํ์์๋ ๋ถ๋ถ์ด์์ง๋ง, ๋ฃ๊ฒ ๋๋ฉด์ ์ ๊ท์๋ ์์ฒญ ์ฐพ์๊ฐ๋ฉด์ ๊ณต๋ถํ๋ค. ใ ใ ใ ใ
^[]{} : ์ด๋ฐ ์์ผ๋ก ์์ ํจํด์ ๋ฃ๊ณ , ๋ค์ ๊ธธ์ด๋ฅผ ๋ฃ์ผ๋ฉด ํด๋น ๊ธธ์ด + ํ์๊น์ง ๊ฒ์ฆํ ์ ์๋ ๊ฒ ๋๋ฌด ์ ๊ธฐํ๋ค...
์์ง ์ ๊ท์ ์ฐ๋ ๊ฑด ์ ์ต์ํด์, ์์ผ๋ก ๋ ์ต์ํด์ง๋๋ก ๋ ธ๋ ฅํด์ผ ๋ ๊ฒ ๊ฐ๋ค.
| 7๋ฒ ๋ฌธ์
- 7๋ฒ!! ์ฌ์ค ๊ฐ์ฅ ์๊ฐ์ ๋ง์ด ์ผ๋ ๋ฌธ์ ์ด๋ค. ์๋๋ฉด ์ฒ์์ ๋ฌธ์ ์์ฒด๋ฅผ ์ดํด ๋ชป ํด์ ์๊ฐ ๋ญ๋น๋ฅผ ํ๊ธฐ ๋๋ฌธ... ๐
'์ฌ์ฉ์์ ํจ๊ป ์๋ ์น๊ตฌ์ ์' << ์ฌ์ค ์ด ๋ง์ ์ ๋ณด๋ฉด ์ดํดํ ์ ์๋๋ฐ ์ด๋๋ ์ฌ์ฉ์์ ์น๊ตฌ์ ์น๊ตฌ๋ผ๋ ๊ฑด๊ฐ...? ์ด๋ฌ๋ฉด์ ์์ฒญ ํท๊ฐ๋ คํ๋ค.
๊ทธ๋ฅ ์ฌ์ฉ์์ ์น๊ตฌ๊ฐ ์๋ ์ ์ฒด ์ ์ ์ค์์ ์ฌ์ฉ์์ ์น๊ตฌ๊ฐ ์ด๋ ์ ๋ ๊ฒน์น๋์ง ์ฒดํฌํ๋ฉด ๋๋ ๊ฑฐ์๋๋ฐ... ใ ใ
๊ทธ๋๋ ์ด๊ฒ๋ Map ์ฐ๋ ๊ฑฐ์ฌ์ ๊ตฌํํ๋ฉด์ ์ฌ๋ฐ์๋ค. ใ ใ
package onboarding;
import onboarding.common.ValidationUtil;
import java.util.*;
public class Problem7 {
// ์ ์ฒด ์ฌ์ฉ์์ ์น๊ตฌ ๊ด๊ณ๋ฅผ ์ ์ํ Map์ ์ ์ธํ๋ค.
// key ๊ฐ์ผ๋ก ์ฌ์ฉ์์ ์์ด๋, value ๊ฐ์ผ๋ก ๋ฆฌ์คํธ๋ก ํด๋น ์ฌ์ฉ์์ ์น๊ตฌ ๋ฆฌ์คํธ๊ฐ ๋ค์ด๊ฐ๋ค.
static Map<String, List<String>> friendMap;
// ์ ์ ์ ๋ณด๋ฅผ ๊ด๋ฆฌํ Map์ ์ ์ธํ๋ค.
// key ๊ฐ์ผ๋ก ์ฌ์ฉ์์ ์์ด๋, value ๊ฐ์ผ๋ก ์ ์๊ฐ ๋ค์ด๊ฐ๋ค.
static Map<String, Integer> scoreMap;
// ์ฌ์ฉ์์ ์น๊ตฌ ๋ชฉ๋ก ๋ฆฌ์คํธ๋ฅผ ๊ด๋ฆฌํ๋ค.
static List<String> userFriendList;
public static List<String> solution(String user, List<List<String>> friends, List<String> visitors) {
friendMap = new HashMap<>();
scoreMap = new HashMap<>();
// ์
๋ ฅ๋ฐ์ ๋ฆฌ์คํธ๋ค์ ๋ํ ๊ฒ์ฆ ์์
์ ์งํํ๋ค.
verifyInputList(user, friends, visitors);
// ์ ์ฒด ์ฌ์ฉ์์ ๋ํ ์น๊ตฌ ๊ด๊ณ๋ฅผ ์ ์ํ๋ค.
for(List<String> relationship : friends) {
// ๊ฐ ์์์ ์ฌ์ด์ฆ๊ฐ 2์ธ์ง ๊ฒ์ฆํ๋ค.
verifyRelationship(relationship);
defineFriendship(relationship);
}
// ์ฌ์ฉ์์ ์น๊ตฌ ๋ชฉ๋ก์ ์กฐํํ๋ค.
userFriendList = friendMap.get(user);
// ์น๊ตฌ ๊ด๊ณ Map์์ ์ฌ์ฉ์์ ์ ๋ณด๋ฅผ ์ ๊ฑฐํ๋ค. (๊ธฐ์ค์ด ์ฌ์ฉ์์ด๊ธฐ ๋๋ฌธ)
friendMap.remove(user);
// ๋ค๋ฅธ ์ฌ์ฉ์์ ์น๊ตฌ ๋ฆฌ์คํธ๋ฅผ ์กฐํํ์ฌ ์ฌ์ฉ์์ ์น๊ตฌ ๋ฆฌ์คํธ์ ๋น๊ตํ๋ค.
for(String diffUser : friendMap.keySet()) {
getFriendsOfDiffUserAndCompare(diffUser);
}
// ์ฌ์ฉ์์ ํ์๋ผ์ธ์ ๋ฐฉ๋ฌธํ ์ฌ์ฉ์์ ๋ํด 1์ ์ฉ ๋ถ์ฌํ๋ค.
addOneScoreToVisitors(visitors);
// ์ฌ์ฉ์์ ์ด๋ฏธ ์น๊ตฌ์ธ ์ฌ์ฉ์๋ ์ถ์ฒ์์ ์ ์ธํ๋ค.
removeAlreadyUserFriend();
// ์ ์๊ฐ 0์ ์ธ ์ฌ์ฉ์๋ ์ ๊ฑฐํ๋ค.
for(String recommendUser : scoreMap.keySet()) {
removeUserWithZeroScore(recommendUser);
}
// ์ ์์ ์ด๋ฆ ์์๋๋ก ์ ๋ ฌ์ ์งํํ๋ค.
List<String> recommendUserList = new ArrayList<>(scoreMap.keySet());
recommendUserList.sort(Problem7::sortByScoreAndName);
// ์ต์ข
์ ์ผ๋ก ์ถ์ฒํ ์ธ์์ ์ ๋ณํ๋ค.
return selectRecommendUsers(recommendUserList);
}
/**
* ์น๊ตฌ ๊ด๊ณ ๋ฆฌ์คํธ์ ๋ํ ๊ฒ์ฆ ์์
์ ์งํํ๋ค.
*
* @param relationship ์น๊ตฌ ๊ด๊ณ ๋ฆฌ์คํธ
*/
private static void verifyRelationship(List<String> relationship) {
ValidationUtil relationshipValidation = new ValidationUtil();
relationshipValidation.addVarName("relationship size");
// ๊ฐ ์์์ ์ฌ์ด์ฆ๋ 2์ฌ์ผ ํ๋ค.
relationshipValidation.checkNumRange(relationship.size(), 2, 2);
}
/**
* ์
๋ ฅ๋ฐ์ ๋ฆฌ์คํธ๋ค์ ๋ํ ๊ฒ์ฆ ์์
์ ์งํํ๋ค.
*
* @param user ์ฌ์ฉ์ ์์ด๋
* @param friends ์น๊ตฌ ๊ด๊ณ ์ ๋ณด
* @param visitors ์ฌ์ฉ์ ํ์๋ผ์ธ ๋ฐฉ๋ฌธ ๊ธฐ๋ก
*/
private static void verifyInputList(String user, List<List<String>> friends, List<String> visitors) {
// ์
๋ ฅ์ผ๋ก ๋ฐ์ user ๋ฌธ์์ด์ ๋ํด ๊ฒ์ฆํ๋ค.
ValidationUtil userValidation = new ValidationUtil();
userValidation.addVarName("user length");
userValidation.checkNumRange(user.length(), 1, 30);
// friends์ ์ฌ์ด์ฆ์ ๋ํด์ ๊ฒ์ฆํ๋ค.
ValidationUtil friendsValidation = new ValidationUtil();
friendsValidation.addVarName("friends size");
friendsValidation.checkNumRange(friends.size(), 1, 10000);
// visitors ์ฌ์ด์ฆ์ ๋ํด์ ๊ฒ์ฆํ๋ค.
ValidationUtil visitorsValidation = new ValidationUtil();
visitorsValidation.addVarName("visitors size");
visitorsValidation.checkNumRange(visitors.size(), 0, 10000);
}
/**
* ์ต์ข
์ ์ผ๋ก ์ถ์ฒํ ์ฌ์ฉ์๋ฅผ ๋ฝ๋๋ค.
*
* @param recommendUserList ์ ๋ ฌ๋ ์ฌ์ฉ์ ๋ฆฌ์คํธ
* @return ์ถ์ฒํ ์ฌ์ฉ์ ๋ฆฌ์คํธ๋ฅผ ๋ฆฌํดํ๋ค.
*/
private static List<String> selectRecommendUsers(List<String> recommendUserList) {
List<String> answer = new ArrayList<>();
// ๊ธฐ์กด ์ถ์ฒ ๋ฆฌ์คํธ์ ๋ด๊ธด ์ธ์์ด 5๋ช
๋ณด๋ค ์์ผ๋ฉด ๊ทธ๋๋ก, ์๋๋ผ๋ฉด ์ต๋ 5๋ช
๊น์ง ์ ๋ณํ๋ค.
int numberOfUser = Math.min(recommendUserList.size(), 5);
for(int i=0; i<numberOfUser; i++) {
answer.add(recommendUserList.get(i));
}
return answer;
}
/**
* ์ถ์ฒ ๋ฆฌ์คํธ๋ฅผ ์ ์(๋ด๋ฆผ์ฐจ์)์ ์ด๋ฆ(์ฌ์ ์)์ ๋ฐ๋ผ ์ ๋ ฌํ๋ค.
*
* @param userA ๋น๊ตํ ์ฌ์ฉ์ A
* @param userB ๋น๊ตํ ์ฌ์ฉ์ B
* @return ์ ๋ ฌ ๊ฒฐ๊ณผ์ ๋ฐ๋ฅธ -1, 0(๋ณ๊ฒฝํ์ง ์์), 1(์๋ฆฌ ๋ณ๊ฒฝ)์ด ๋ฆฌํด๋๋ค.
*/
private static int sortByScoreAndName(String userA, String userB) {
// ์ ์๊ฐ ๊ฐ๋ค๋ฉด ์ด๋ฆ์์ผ๋ก ์ ๋ ฌํ๋ค.
if (Objects.equals(scoreMap.get(userA), scoreMap.get(userB))) {
return userA.compareTo(userB);
}
// ๊ทธ๊ฒ ์๋๋ผ๋ฉด ์ ์๋ฅผ ๊ธฐ์ค์ผ๋ก ๋ด๋ฆผ์ฐจ์ ์ ๋ ฌํ๋ค.
return scoreMap.get(userB) - scoreMap.get(userA);
}
/**
* ์ ์๊ฐ 0์ ์ธ ์ฌ์ฉ์๋ ์ ์ Map์์ ์ ๊ฑฐํ๋ค.
*
* @param recommendUser ์ถ์ฒ ํ๋ณด ์ฌ์ฉ์ ์์ด๋
*/
private static void removeUserWithZeroScore(String recommendUser) {
if (scoreMap.get(recommendUser) == 0) {
scoreMap.remove(recommendUser);
}
}
/**
* ์ฌ์ฉ์์ ์ด๋ฏธ ์น๊ตฌ์ธ ๊ฒฝ์ฐ ์ ๊ฑฐํ๋ค.
*/
private static void removeAlreadyUserFriend() {
for(String userFriend : userFriendList) {
scoreMap.remove(userFriend);
}
}
/**
* ์ฌ์ฉ์์ ํ์๋ผ์ธ์ ๋ฐฉ๋ฌธํ ์ฌ์ฉ์์๊ฒ 1์ ์ฉ ๋ถ์ฌํ๋ค.
*
* @param visitors ์ฌ์ฉ์์ ํ์๋ผ์ธ ๋ฐฉ๋ฌธ์
*/
private static void addOneScoreToVisitors(List<String> visitors) {
for(String visitor : visitors) {
scoreMap.put(visitor, scoreMap.getOrDefault(visitor,0) + 1);
}
}
/**
* ๋ค๋ฅธ ์ฌ์ฉ์์ ์น๊ตฌ ๋ฆฌ์คํธ๋ฅผ ์กฐํํ์ฌ ์ฌ์ฉ์์ ์น๊ตฌ ๋ฆฌ์คํธ์ ๋น๊ตํ๋ค.
*
* @param diffUser ๋ค๋ฅธ ์ฌ์ฉ์์ ์์ด๋
*/
private static void getFriendsOfDiffUserAndCompare(String diffUser) {
List<String> diffFriendList = friendMap.get(diffUser);
for(String friendOfDiffUser : diffFriendList) {
addTenScore(diffUser, friendOfDiffUser);
}
}
/**
* ์ฌ์ฉ์์ ์น๊ตฌ ๋ฆฌ์คํธ์ ๋์ผํ ์น๊ตฌ๋ฅผ ๊ฐ์ง๊ณ ์๋ค๋ฉด, ํด๋น ์ฌ์ฉ์์๊ฒ 10์ ์ ๋ถ์ฌํ๋ค.
*
* @param diffUser ๋ค๋ฅธ ์ฌ์ฉ์ ์์ด๋
* @param friendOfDiffUser ๋ค๋ฅธ ์ฌ์ฉ์์ ์น๊ตฌ
*/
private static void addTenScore(String diffUser, String friendOfDiffUser) {
if (userFriendList.contains(friendOfDiffUser)) {
scoreMap.put(diffUser, scoreMap.getOrDefault(diffUser, 0) + 10);
}
}
/**
* ์ ์ฒด ์ฌ์ฉ์์ ์น๊ตฌ ๋ชฉ๋ก์ ์น๊ตฌ ๊ด๊ณ Map์ ์ ์ฅํ๋ค.
*
* @param relationship ์น๊ตฌ ๊ด๊ณ ์ ๋ณด
*/
private static void defineFriendship(List<String> relationship) {
String userA = relationship.get(0);
String userB = relationship.get(1);
// ์์ด๋์ ๋ํ ๊ฒ์ฆ์ ์งํํ๋ค.
idValidation(userA, userB);
// ๋ง์ฝ ์ฒ์ ์ฝ์
๋๋ค๋ฉด ์ด๊ธฐํ ์์
์ ์งํํด์ค๋ค.
List<String> friendListOfUserA = friendMap.getOrDefault(userA, new ArrayList<>());
// ์น๊ตฌ ์ ๋ณด๋ฅผ ์ถ๊ฐํ๋ค.
friendListOfUserA.add(userB);
List<String> friendListOfUserB = friendMap.getOrDefault(userB, new ArrayList<>());
friendListOfUserB.add(userA);
// ์น๊ตฌ ๊ด๊ณ Map์ ์ถ๊ฐํ๋ค.
friendMap.put(userA, friendListOfUserA);
friendMap.put(userB, friendListOfUserB);
}
/**
* ์ฌ์ฉ์์ ์์ด๋์ ๋ํ ๊ฒ์ฆ ์์
์ ์งํํ๋ค.
*
* @param userA ์ฌ์ฉ์ A
* @param userB ์ฌ์ฉ์ B
*/
private static void idValidation(String userA, String userB) {
// ์ฌ์ฉ์์ ์์ด๋์ ๊ธธ์ด๋ 1~30 ์ฌ์ด์ฌ์ผ ํ๋ฉฐ, ์๋ฌธ์๋ก ์ด๋ฃจ์ด์ ธ ์๋ค.
ValidationUtil userAValidation = new ValidationUtil();
userAValidation.addVarName("userId");
userAValidation.checkStrLowerCase(userA, 1, 30);
ValidationUtil userBValidation = new ValidationUtil();
userBValidation.addVarName("userId");
userBValidation.checkStrLowerCase(userB, 1, 30);
}
}
- ๊ฐ์ธ์ ์ผ๋ก ์ด๋ ๊ฒ ์๊ตฌ์ฌํญ ์๋ฉ ์ฃผ๊ณ ์๋ฃํ์ ๋ฃ๋ค ๋บ๋ค ํ๋ ๋ฌธ์ ๊ฐ ์ฌ๋ฐ๋ ๊ฒ ๊ฐ๋ค.
์ด ๋ฌธ์ ๋ฅผ ์ฒ์ ์ ํ ์ฌ๋์ด์๋ค๋ฉด ์ด ๋ฌธ์ ํ๋ ํด๊ฒฐํจ์ผ๋ก์ Map์ ์๋ฒฝ ๋ง์คํฐ ํ ์ ์์ง ์์๊น... ๋ผ๊ณ ์๊ฐํ๋ค!
| ๊ณตํต ํด๋์ค
- ๋ฆฌํฉํ ๋ง ํ๋ฉด์ ๋ง๋ค์๋ ๊ณตํต ํด๋์ค!
package onboarding.common;
/**
* ์
๋ ฅ์ผ๋ก ๋ค์ด์จ ๋ฌธ์์ด์ ๋ํ ํตํฉ ๊ด๋ฆฌ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ ํด๋์ค.
*/
public class InputStringUtil {
/**
* ๋ฌธ์์ด์ charํ ๋ฐฐ์ด๋ก ๋ถํดํ์ฌ ๋ฆฌํดํ๋ค.
*
* @param str ๋ฌธ์์ด
* @return char[] - ์
๋ ฅ์ผ๋ก ๋ฐ์ ๋ฌธ์์ด์ ๋ํด charํ ๋ฐฐ์ด๋ก ์ชผ๊ฐ ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํดํ๋ค.
*/
public static char[] getCharArr(String str) {
return str.toCharArray();
}
}
- ๋ฌธ์์ด์ ๋ฐฐ์ด๋ก ๋ฐ๋ ๋ถ๋ถ์ด ์๋นํ ๋ง์์ ๊ทธ๋ฅ ๋ถ๋ฆฌํ๋๋ฐ... ์ฌ์ค ์ด ์ ๋๊น์ง๋ ๋ถ๋ฆฌ ์ ํด๋ ๋์ง ์์์๊น ์ถ๋ค. ใ ใ ใ
package onboarding.common;
import onboarding.exception.InputRangeException;
import onboarding.exception.InputTypeException;
import java.util.regex.Pattern;
/**
* ์
๋ ฅ์ผ๋ก ๋ค์ด์จ ๊ฐ์ ๋ํด ๊ณตํต ๊ฒ์ฆ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ ํด๋์ค.
*/
public class ValidationUtil {
private String varName;
/**
* ์ค๋ฅ ๋ฉ์์ง ์ ๋ฌ ์ ์ฌ์ฉํ ์
๋ ฅ ๋ณ์ ์ด๋ฆ ์ค์ ๋ฉ์๋
*
* @param varName ์
๋ ฅํ ๋ณ์ ์ด๋ฆ
*/
public void addVarName(String varName) {
this.varName = varName;
}
/**
* ์
๋ ฅ๋ฐ์ number์ ๋ฒ์์ ๋ํ ๊ฒ์ฆ์ ์งํํ๋ค.
*
* @param number ์
๋ ฅ์ผ๋ก ๋ค์ด์จ number
* @param start ์์ ๋ฒ์
* @param end ๋ ๋ฒ์
*/
public void checkNumRange(int number, int start, int end) {
if (number < start || number > end) {
if (start == end)
throw new InputRangeException(this.varName + "์(๋) " + start + "๋ก ์ ํ๋์ด ์์ต๋๋ค.");
throw new InputRangeException(this.varName + "์(๋) " + start + "~" + end + " ์ฌ์ด๋ก ์ ํ๋์ด ์์ต๋๋ค.");
}
}
/**
* ์
๋ ฅ๋ฐ์ ๋ฌธ์์ด์ด ์๋ฌธ์๋ก ๊ตฌ์ฑ๋์ด ์๋์ง ๊ฒ์ฆํ๋ค.
*
* @param str ์
๋ ฅ๋ฐ์ ๋ฌธ์์ด
* @param startLen ์์ ๊ธธ์ด
* @param endLen ๋ ๊ธธ์ด
*/
public void checkStrLowerCase(String str, int startLen, int endLen) {
String regex = "^[a-z]{" + startLen + "," + endLen + "}$";
if (!Pattern.matches(regex, str)) {
throw new InputTypeException(this.varName + "์ ๊ธธ์ด๋ " + startLen + "~" + endLen +
" ์ฌ์ด๋ก ์ ํ๋์ด ์์ผ๋ฉฐ, ์๋ฌธ์๋ก๋ง ๊ตฌ์ฑ๋์ด์ผ ํฉ๋๋ค.");
}
}
}
- ๊ฐ์ธ์ ์ผ๋ก ์ด๋ฒ ์ฃผ์ฐจ์์ ๋ ๊ณ ๋ฏผํ๋ ๊ฒ์ฆ ํด๋์ค!
๊ฒ์ฆ ๋ฉ์์ง๋ฅผ ์ฒ๋ฆฌํ ๋ ๋ณ์ ์ด๋ฆ์ ํจ๊ป ์ถ๋ ฅํด์ฃผ๊ณ ์ถ์ด์ ํด๋์ค ๋ด๋ถ ๋ณ์๋ก varName์ ์ ์ธํด ๊ด๋ฆฌํ๋ค.
๊ฐ์ธ์ ์ผ๋ก ์๋ฌธ์ ๊ฒ์ฆ๋ ํ๋ผ๋ฏธํฐ๋ก ๊ธธ์ด๋ฅผ ๋ฐ์์ ์ฒ๋ฆฌํด๋ ๊ฒ ๋ง์์ ๋ ๋ค!
| ์๊ฐ
- ๊นํ์๋ ์ฌ๋ ค๋ ๊ฑฐ์ง๋ง ๋ฐ๋ก ์ ์ฅํด๋๊ณ ์ถ์ด์ ์ ์ด๋๋ ์๊ฐ :D
๋งํฌ๋ค์ด์ด ํฐ์คํ ๋ฆฌ์์ ๋ค์ ๊นจ์ง๋ ๊ฒฝํฅ์ด ์๋ ๊ฒ ์ซ์ด์ ์บก์ณ๋ก ์ฌ๋ ค๋๋ค.
1์ฃผ์ฐจ๋ ์ด๋ฐ ์์ผ๋ก ์ฝ๋ ๊ตฌํ์ ํ์๋๋ฐ... ์ผ์ฃผ์ผ ๋์ ์ฝ๋ ๋ฐ๋ผ๋ณด๋ฉด์ ์์ ํ ๊ฒฐ๊ณผ์ธ ๋งํผ ๊ฝค ๋ฟ๋ฏํ๋ค.
์ฌ์ค ์ผ๋ฅธ 2์ฃผ์ฐจ ํ๊ณ ์จ์ผ๊ฒ ๋ค๋ ์๊ฐ๋ฟ์ด์ง๋ง ใ ใ ใ ์์ผ๋ก๋ ๋ฐ๋ฆฌ์ง ์๊ณ ์จ์ผ๊ฒ ๋ค...
์์ผ๋ก ๋จ์ ์๊ฐ๋ ํ์ดํ ! ๊ผญ ํฉ๊ฒฉํ์ผ๋ฉด ๐