최소공배수는 어찌저찌 맞게 구한 것 같은데 최대공약수가 이상하다. 아무리 해도 나오지가 않는다.
for문 안에 if를 계속 거는 것은 좋지 않다고 했었는데, 한번에 나올 방법이 없을까?
-> 고민해봤지만 혼자서는 떠올릴 수 없었다. 이 해법은 '유클리드 호제법' 이라는 방법이 있었다.
유클리드를 모르는건 아니지만 유클리드 기하학에서밖에 이름을 들어보지 못했는데(...)
구원의 위키독스
호제는 서로 나눈다는 뜻. [3, 12] 같은 숫자쌍이 아니고서야 분명히 서로끼리는 나누어 떨어지지 않을 것이다.
하여 큰 수를 작은 수로 나눴을 때의 몫을 다시 큰 수 자리에 넣고 나머지를 다시 작은 수 자리에 넣어, 나머지가 0이 될 때 까지 나누기를 반복하는 것이다. 그 나누기를 반복하다가 나머지가 0이 되는 순간의 몫이 최대공약수가 되는 것.
while (n !== 0) {
// 51, 21이라 가정하면 이렇게만 썼을 때 m = 21이 되어버린다
// 같은 수로 나누는 꼴이니 n이 바로 0이 나온다. 그러니 그냥 인풋이 리턴되어 버림.
m = n;
n = m % n;
}
다만 while문을 이렇게만 써줄 경우 제대로 동작하지 않으니 주의.
(언어의 특성이 달라서 JS는 기대한 대로 한줄 씩 실행되지 않는다고 한다. Python은 잘 굴러간다고.)
while문은 이렇게 써주자. 자리바꾸기가 필요하다.
while (n !== 0) {
// 51, 21이라 가정하면 tmp = 21, n = 51 % 21이므로 9, m에 tmp인 21을 넣게 된다.
// 이렇게 자리바꾸기 식으로 회당 연산의 작은수와 나머지를 보존하여 큰수와 작은수 자리에 집어넣어주게 된다.
// 그리고 우리는 '나머지가 0인' 수를 구해야 하니까 나머지인 n값이 0이 아닐 동안만 돌아가는 것.
let tmp = n;
n = m % n;
m = tmp;
}
의외로 최소공배수는 맞았다. 그런데 불필요한 for문과 if문을 걸어줄 필요는 없었다.
for (let i = n; i <= m; i++) {
if (answer[0] !== 1) {
answer[1] = (m * n) / answer[0];
} else answer[1] = m * n;
}
원래는 이렇게 썼었는데, 생각해보면 answer[0] === 1이면 어차피 나눠도 그대로 m * n이므로 윗 식만 써도 무방했다!
answer[1] = (m * n) / answer[0];
TMI : 스불재는 스스로 불러온 재앙 의 약자
뭐에요, 바꿔주세요. 왜 교환 불가야.
아무튼. 돌아가지 않는 문제의 코드.
function solution(left, right) {
var answer = 0;
for (let i = left; i <= right; i++) {
if(Number.isInteger(i)) {
i = -i;
}
answer += i;
}
return answer;
}
원했던 것: 약수의 개수가 홀수인 수에 -를 붙여서 answer에 더해줘야지
실행 결과: 뜬금 음수가 된 i는 두배가 된 증감문을 쌔가 빠지게 돌아가려다가 실행시간을 초과해버림
그래서 수정한 방향: 제곱수인지 판별해보고 제곱수라면 마이너스를 붙여주자. 그런데 어떻게?
-> Math.sqrt(숫자)의 바깥에 정수인지 판별하는 메소드인 Number.isInteger()를 써서, 제곱근이 정수이면 약수의 갯수는 홀수인걸로 간주!
function solution(left, right) {
var answer = 0;
let dividors = 0;
for (let i = left; i <= right; i++) {
dividors = i;
if(Number.isInteger(Math.sqrt(i))) {
dividors = -i;
}
answer += dividors;
console.log(dividors)
}
return answer;
}
function solution(left, right) {
let answer = 0;
for (let i = left; i <= right; i++) {
let count = 0;
for (let j = 1; j <= i; j++) {
if (i % j === 0) count++;
}
if (count % 2) answer -= i;
else answer += i;
}
return answer;
}
<추천 툴>
thunder client
SQLTool
VS Code는 마이크로소프트에서 만든 툴이라 거의 모든 기능이 다 확장 프로그램으로 들어가 있다. 그래서 좋은 익스텐션을 고르는 안목이 중요하다.
router.get('/goods/:goodsId/', (req, res) => {
const goodsId = req.params.goodsId;
const foundGood = goods.find((oneGoods) => oneGoods.goodsId === +goodsId);
// undefined를 반환하지 않도록 하자
if (!foundGood) throw new Error('업성');
return res.status(200).json({
goods: foundGood
});
});
router.get('/goods/:goodsId/'), (req, res) => {
const goodsId = req.params.goodsId;
const foundGood = goods.find((oneGoods) => oneGoods.goodsId === +goodsId);
// undefined를 반환하지 않도록 하자
if (!foundGood) throw new Error('업성');
return res.status(200).json({
goods: foundGood
});
};
이 괄호 하나 때문에 정섭튜터님과 정말 이것 저것 모두 다 실행해 보았지만 되지 않았다... 이 오류는 웅상님이 잡아주셨다.
여기에 'goods/' 라고 썼더니 POST가 제대로 작동하지 않았다.
문득 정섭 튜터님이 말씀해주신 'URL 앞에 슬래시를 안 붙이면 제대로 동작하지 않는다' 가 생각나서 붙여봤더니 잘 됐다.
category나 price처럼 왼쪽이 필드, 왼쪽이 데이터타입인 식으로 써줘도 된다.
이걸 붙이지 않으면 제대로 실행되지 않을 수 있으니 주의!