2022. 12. 20. 22:11ㆍ코드스테이츠/코드스테이츠 : 페어프로그래밍
isPrime
문제
1 이상의 자연수를 입력받아 소수(prime number)인지 여부를 리턴해야 합니다.
입력
인자 1 : num
- number 타입의 수
출력
- boolean 타입을 리턴해야 합니다.
// 소수 : 1과 자신으로밖에 나누어지지 않는 고독한 숫자
// 수학에서 1과 그 수 자신 이외에는 자연수로 나눌 수 없는, 1보다 큰 자연수
// 1. 소수는 1보다 커야 한다.
// 2. 2를 제외한 짝수는 소수가 아니다 (2는 소수)
// 3. 3부터 자기 자신 '전'까지 나누어 떨어지는 수가 하나라도 있으면, 소수가 아니다.
function isPrime(num) {
// 제곱근 Math.sqrt()
let sqrt = Math.sqrt(num);
// 1이면 소수가 아니다.
if (num === 1) {
return false;
}
// 짝수는 소수가 아니다 (2를 제외하고)
if (num === 2) {
return true;
}
if (num % 2 === 0) {
return false;
}
// 3. 3부터 자기 자신 '전'까지 나누어 떨어지는 수가 하나라도 있으면, 소수가 아니다.
for (let i = 3; i < sqrt; i++) {
// num = 12
// 1 * 12
// 2 * 6
// 3 * 4
// 12의 제곱근 * 12의 제곱근
// 4 * 3
// 6 * 2
// 12 * 1
if (num % i === 0) {
return false;
}
}
return true;
}
반복문 문제를 풀면서 처음으로 난관에 봉착한 문제다.
수학이라면 머리에서 쥐가 나는 나에게는 소수가 무엇이며, 어떤식으로 접근해야 할 지 막막했다.
isPrime 문제의 키포인트는 소수를 이해하는것과 Math.sqrt 를 통해 불필요한 연산을 줄이는 것 이였다.
수학적 사고가 조금 뒤쳐지는 나는 이것을 이해하는데에 꽤나 오랜 시간을 쓴 것 같다.
listPrimes
문제
2 이상의 자연수를 입력받아 2부터 해당 수까지의 소수(prime number)들을 리턴해야 합니다.
입력
인자 1 : num
- number 타입의 정수 (num >= 2)
출력
- string 타입을 리턴해야 합니다.
- 2-3-5-7의 형식으로 리턴해야 합니다.
주의 사항
- 이중 반복문(double for loop)을 사용해야 합니다.
function listPrimes(num) {
// 이중반복문
// 9번 문제는 그냥 어떤 수가 소수인지 판단
// 문자열을 리턴
// ex) num = 12, '2-3-5-7-11'
// 외부 반복문 : 2부터 자기자신(num)까지 반복하면서 이 수가 소수인지 판단
// 내부 반복문 : 이 수가 소수인지 판단 (9번 문제)
let result = '2'; //2이상의 자연수를 입력받으니 result에 2를 줘버림
for (let i = 3; i <= num; i += 2) { // result에 2를 줬기때문에 3부터 자기자신(num)까지 반복하면서 이 수가 소수인지 판단
let isPrime = true;
for (let j = 3; j < i; j++) { // 이 수가 소수인지 판단
if (i % j === 0) { // i 가 j로 나눴을 때 딱 떨어지는 수 라면
isPrime = false; // 소수가 아니다.
}
}
// isPrime인 true인 경우도 있고, false인 경우도 있음
// 조건을 다시 분기해서, 만약에 true면, (소수면) result에 더해준다.
if (isPrime === true) {
result = `${result}-${i}`
}
}
return result; // if문에 충족하지 않는다면 바로 result를 리턴
}
바로 이전 문제인 isPrime문제를 겨우 이해하고 다음 문제로 넘왔는데 ....
무려 'listPrime'님이 기다리고 계셨습니다.
방금 소수문제를 풀어냈지만 다시봐도 쉬이 풀리지 않았다.
그래도 얼마전에 소수에대한 개념을 어렴풋이 머릿속에 넣어놨기 때문에 isPrime 문제보다는 일찍 푼 것 같다.
makePermutations
문제
문자열을 입력받아 해당 문자열에 등장하는 각 문자(letter)를 가지고 만들 수 있는 길이 2의 문자열들을 리턴해야 합니다.
입력
인자 1 : str
- string 타입의 문자열
출력
- string 타입을 리턴해야 합니다.
- 입력받은 문자열의 각 문자를 0, 1, 2, ..., n이라고 할 경우, 00,01,02,...,nn 형식으로 리턴해야 합니다.
주의 사항
- 이중 반복문(double for loop)을 사용해야 합니다.
- 빈 문자열을 입력받은 경우에는 빈 문자열을 리턴해야 합니다.
function makePermutations(str) {
// TODO: 여기에 코드를 작성합니다.
//이중반복문 사용
//빈 문자열을 받는경우 빈 문자열을 리턴 = result = ''
//String 타입을 리턴
let result = '';
for(let i = 0; i < str.length; i++){ // 문자열 탐색 디폴트값
for(let j = 0; j < str.length; j++){ // 문자열 탐색 디폴트값
result = result +`${str[i]}${str[j]},` //i=0 j=0/ i=0 j=1/i=0 j=2/ 내부 반복문 종료 => 외부 반복문 시작
}
}
return result.slice(0,result.length-1);
}
이중반복문에 대해 어느정도 이해가 생기게 된 부분이다.
내부반복문이 조건을 만족하고 종료되면 외부반복문이 한바퀴 돌고, 다시 내부반복문이 조건을 만족하고 종료되면 외부반복문이 한바퀴 돌고, 이런식으로 동작하는 것 같다.
입력이 'hat' 이라면' i=0(hh,ha,ht) i=1(ah,aa,at) i=2(th,ta,tt) 이런식으로 출력이 될 것이다.
이중반복문을 배우면서 느낀게 내부반복문은 수색견같다.
i=0이라는 섹터에 j라는 수색견을 풀어놓으면 열심히 수색하고 돌아온다.
전부 수색했으니 i=1이라는 섹터에 풀어놓으면 또 열~심히 수색하고 돌아오겠지.
hasRepeatedCharacter
문제
문자열을 입력받아 해당 문자열에 중복된 문자(letter)가 존재하는지 여부를 리턴해야 합니다.
입력
인자 1 : str
- string 타입의 문자열
출력
- boolean 타입을 리턴해야 합니다.
주의 사항
- 이중 반복문(double for loop)을 사용해야 합니다.
- 빈 문자열을 입력받은 경우에는 false을 리턴해야 합니다.
function hasRepeatedCharacter(str) {
// TODO: 여기에 코드를 작성합니다.
//문자열을 입력받아 해당 문자열에 중복된 문자가 존재하는지 여부를 불리언타입으로 리턴
//입력 'abcdefg'
//출력 false
for(let i=0; i <= str.length; i++){ // 문자열 읽기 디폴트값 / 문자열을 처음부터 끝까지 싸악~ 훑겠다.
for(let j=i+1; j<= str.length; j++){ // j=i+1 한 이유는 외부반복문처럼 0으로 줄 경우 같은위치의 문자열 인덱스를 읽게되기 때문에 계속 true가 반환됨
if(str[i] === str[j]){ //반복문이 돌기시작하면, str에 banana가 입력됐다는 가정하에 i='b' j='a'/i='b j='n'/i='b' j='a'..... 식으로 j반복문이 다 돌면 j는 초기화 후 i반복문이 돌아간다
return true // i와 j가 같은경우가 생긴다면 true.
}
}
}return false // if문에 충족하지않는다면 바로 false를 리턴
}
내가봐도 웃긴데...
편하자고 반복문을 써놓고 , 주석으로 열심히 노가다를 했다. 머리에 넣어보겠다고 ㅠㅠㅠ
미련하긴 했지만 좋게 말하면 반복문 코드의 실행과정에 대해 어느정도 이해와 설명이 가능해졌다고 생각한다.
부디 내 머릿속에 오래 남아줬으면 해..
makeMarginalString
문제
문자열을 입력받아 해당 문자열을 처음부터 한 글자(letter)씩 다시 작성하려고 합니다. 이 때, 한 글자를 추가할 때마다 부분적으로 완성된 문자열을 전부 이어붙인 문자열을 리턴해야 합니다.
입력
인자 1 : str
- string 타입의 문자열
출력
- string 타입을 리턴해야 합니다.
주의 사항
- 이중 반복문(double for loop)을 사용해야 합니다.
- str.slice, str.substr, str.substring 사용은 금지됩니다.
- 빈 문자열을 입력받은 경우에는 빈 문자열을 리턴해야 합니다.
function makeMarginalString(str) {
// TODO: 여기에 코드를 작성합니다.
//입력 : 'abc'
//출력 : 'aababc'
//이중반복문 사용
//str.slic / str.substr / str.substring 사용 금지
//maybe .concat사용?
//------------------------------------------------------
let result = ''
for(let i = 0; i < str.length; i++){
for(let j = 0; j <= i; j++ ){
result = result + str[j]
// i = 0, j = 0 => str[j] 'f'
// i = 0, j = 1 => 내부 반복문 종료
// i = 1, j = 0 => str[j] 'f' 'ff'
// i = 1, j = 1 => str[j] 'l' 'ffl'
// i = 1, j = 2 => 내부 반복문 종료
// i = 2, j = 0 => str[j] 'f' 'fflf
// i = 2, j = 1 => str[j] 'l' 'fflfl'
// i = 2, j = 2 => str[j] 'o' 'fflflo'
// i = 2, j = 3 => 내부 반복문 종료
// i = 3, j = 0 => str[j] 'f' 'fflflof
// i = 3, j = 1 => str[j] 'l' 'fflflofl
// i = 3, j = 2 => str[j] 'o' 'fflfloflo
// i = 3, j = 3 => str[j] 'w' 'fflfloflow'
// ...
// i = 5, j = 5 => str[j] 'r' 'fflfloflowfloweflower'
}
}return result
}
반복문을 이해하기 위한 마지막 발악이였던 문제다.
'문자열을 입력받아 해당 문자열을 처음부터 한 글자(letter)씩 다시 작성하려고 합니다. 이 때, 한 글자를 추가할 때마다 부분적으로 완성된 문자열을 전부 이어붙인 문자열을 리턴해야 합니다.' 를 보고 .concat을 떠올렸는데 전~혀 쓸 일이 없었다.
이미 이전 문제들에서 반복문을 단련했기때문에 수월하게 풀어냈지만! 역시 주석노가다를 통해 과정을 눈으로 봐야 머리에 남기때문에 열심히 끄적여 줬다. (생각해보니 고등학교 때 블록쌓기문제도 열심히 그렸던,,)
반복문 코플릿 배운 점
1. 내부 반복문의 조건식을 외부조건식으로 바꾸면 수색견 같던 내부반복문이 i주변을 멤도는 강아지가 된다.
ex. for(let i = 0; i < str.length; i++)
for(let j = 0; j<= i; i++) 이렇게 반복문을 돌리면 내부반복문이 외부반복문을 따라다니며 수색한다.ㅋㅋ
2. Math 메소드를 이용하면 불필요한 연산을 줄일 수 있다! (Math 연산자의 적용 사례들을 간간히 찾아보자)
3. ~~문자열을 입력받아 무엇을 찾아서 무엇을한다? for(let i = 0; i < str.length; i++) 거의 디폴트 값