diff --git a/level-3/N-Queen.js b/level-3/N-Queen.js new file mode 100644 index 0000000..8d36ad5 --- /dev/null +++ b/level-3/N-Queen.js @@ -0,0 +1,39 @@ +//https://github.com/codeisneverodd/programmers-coding-test +//완벽한 정답이 아닙니다. +//정답 1 - codeisneverodd +function solution(n) { + /* + 1. 0번째 행에 0번째 queen을 놓는다. + 2. 그 다음 행의 퀸은 이전 퀸들의 범위와 겹치지 않는 곳에 놓는다. 퀸은 한 행에 반드시 하나 두어야한다. + 3. 마지막 열까지 도달하면 성공으로 간주하고 answer에 1을 더한다. + 4. 0번째 queen의 위치를 바꿔가며 모두 시도한다. + 4. 단, 체스판은 일차원 배열로 선언하고 index = 행, 값 = 열 로 생각한다. + */ + let answer = 0; + const canBePlacedOn = (chess, currentRow) => { + //해당 행에 둔 queen이 유효한지 + for (let prevRow = 0; prevRow < currentRow; prevRow++) { + const onDiagonal = currentRow - prevRow === Math.abs(chess[currentRow] - chess[prevRow]) + const onStraight = chess[prevRow] === chess[currentRow] + if (onDiagonal || onStraight) return false + } + return true + } + const placeQueen = (chess, currentRow) => { + //queen을 배치하다가 끝 행에 도착하면 1을 리턴, 도착하지 못하면 0을 리턴하여, 재귀적으로 모든 경우를 합하여 리턴 + let count = 0 + if (currentRow === chess.length) return 1 + for (let currentQueen = 0; currentQueen < n; currentQueen++) { + //queen을 우선 배치한 후 가능한지 살펴본다. + chess[currentRow] = currentQueen + if (canBePlacedOn(chess, currentRow)) count += placeQueen(chess, currentRow + 1) + } + return count + } + for (let firstQueen = 0; firstQueen < n; firstQueen++) { + const chess = new Array(n).fill(-1) + chess[0] = firstQueen + answer += placeQueen(chess, 1) + } + return answer; +} \ No newline at end of file diff --git "a/level-4/\353\213\250\354\226\264-\355\215\274\354\246\220.js" "b/level-4/\353\213\250\354\226\264-\355\215\274\354\246\220.js" new file mode 100644 index 0000000..475cc45 --- /dev/null +++ "b/level-4/\353\213\250\354\226\264-\355\215\274\354\246\220.js" @@ -0,0 +1,34 @@ +//https://github.com/codeisneverodd/programmers-coding-test +//완벽한 정답이 아닙니다. +//정답 1 - codeisneverodd +//코드 참고자료: https://velog.io/@longroadhome/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-LV.4-%EB%8B%A8%EC%96%B4-%ED%8D%BC%EC%A6%90 +function solution(strs, t) { + const tLength = t.length; //자주 쓰는 값 미리 계산 + //Infinity 로 선언을 해야 조합이 불가능한 영역의 값을 무한으로 두고, 그 영역에 하나를 더해도 불가능하다는 것을 Infinity로 표현할 수 있게 된다. + const minCountToIndex = new Array(tLength).fill(Infinity); + for (let currentIndex = 0; currentIndex < tLength; currentIndex++) { + //내가 검사할 부분은 t의 0~currentIndex 영역 + const currentSlice = t.slice(0, currentIndex + 1); + for (const str of strs) { + //현재 영역이 strs에 있는 조각들 중 하나로 끝난다면 + if (currentSlice.endsWith(str)) { + //frontLength 는 str 조각을 제외한 앞 쪽의 남은 조각의 길이 + const frontLength = currentIndex - str.length + 1; + if (frontLength === 0) { + //앞쪽에 남은 것이 없다면, 현재 검사중인 영역 = strs에 있는 조각 + minCountToIndex[currentIndex] = 1; + } else { + //앞쪽에 남은 것이 있다면, 현재 검사중이 영역까지 필요한 조각 수는, 지금까지 구한 최소 값과 지금 구한 값 중 최소값 + minCountToIndex[currentIndex] = Math.min( + minCountToIndex[currentIndex], + minCountToIndex[frontLength - 1] + 1 + ); + } + } + } + } + //마지막 영역이 Infinity 이면 만들기 불가능한 단어, 아니라면 마지막 영역의 값을 리턴 + return minCountToIndex[tLength - 1] === Infinity + ? -1 + : minCountToIndex[tLength - 1]; +}