본문으로 건너뛰기
/ Docs

수학 응용 (2) (Day 21-22)

[프로그래머스] 일일 도전 과제 문제 풀이 정리입니다.
관련 개념도 첨부하였으니 필요한 분들은 참고하세요.
코딩 기초 트레이닝, 코딩테스트 입문 문제를 Day별로 풀고 정리한 내용입니다.

🌞

✨Day 21-22

🧱‼ 입문 어려움 ‼🧱

목표: 수학 응용 (2)

  • BigInt Number보다 큰 정수를 표현
  • 배열 순회
    some ✨ 조건을 만족하는 요소가 있으면 true
    every ✨ 모든 요소가 조건을 만족하면 true

볼만한 코드 문제들만 가져왔습니다.! 오늘은 입문 난이도가 떡상해서 기초 먼저..

기초

전국 대회 선발 고사

function solution(rank, attendance) {
const [f, s, t] = rank
.map((v,idx)=>{if(attendance[idx]) return [v,idx]})
.sort((a,b)=>a[0]-b[0])
.slice(0,3);
return f[1]*10000 + s[1]*100 + t[1];
}

🍞 map 배열 각 요소를 rank, index로 변환
🍞 sort 오름차순 정렬

function solution(rank, attendance) {
const [a, b, c] = rank
.map((r, i) => [r, i])
.filter(([_, i]) => attendance[i])
.sort(([a], [b]) => a - b);
return 10000 * a[1] + 100 * b[1] + c[1];
}

🍞 map 배열 각 요소를 rank, index로 변환
🍞 filter attendance true만 남김
🍞 sort 오름차순 정렬


0떼기

function solution(n_str) {
return +(n_str)+""
}

🍞 +(string) 문자열을 숫자로
🍞 (number)+"" 숫자를 문자열로


두 수의 합

function solution(a, b) {
let aIdx=a.length, bIdx=b.length;
const answer = [];
while(true){
aIdx--;
bIdx--;
if(aIdx>=0 && bIdx>=0){
answer.push((+a[aIdx])+(+b[bIdx]))
}else if(aIdx>=0){
answer.push(+a[aIdx])
}else if(bIdx>=0){
answer.push(+b[bIdx])
}else break;
}
for(let i=0;i<answer.length;i++){
if(answer[i]>=10){
answer[i] = answer[i]-10;
i+1===answer.length ? answer.push(1) : answer[i+1]++;
}
}
return answer.reverse().join("")
}

🍞 범위가 넘어가므로 각 자리마다 합하고 10이 넘을 경우 자리 넘김

function solution(a, b) {
return String(BigInt(a) + BigInt(b));
}

🍞 BigInt Number보다 큰 정수를 표현


입문

숨어있는 숫자의 덧셈 (2)

function solution(my_string) {
return my_string
.replace(/[^0-9]/g, " ")
.split(" ")
.map((v)=>Number(v))
.reduce((acc,cur)=> acc+ cur, 0)
}

🍞 replace(/[^0-9]/g, " ") 숫자가 아닌 문자를 공백으로


function solution(my_string) {
return my_string
.split(/\D+/)
.reduce((acc, cur) => acc + Number(cur), 0);
}

🍞 split(/\D+/) 숫자가 아닌 문자를 기분으로 문자열 분리


안전지대

function solution(board) {
const n = board.length;
const dx = [-1, -1, -1, 0, 0, 1, 1, 1];
const dy = [-1, 0, 1, -1, 1, -1, 0, 1];

for(let x=0;x<n;x++){
for(let y=0;y<n;y++){
if(board[x][y]===1){
for(let d = 0; d < 8; d++){
const cx = x+dx[d];
const cy = y+dy[d];
if(cx>=0 && cx<n && cy>=0 && cy<n){
if(board[cx][cy]===0){
board[cx][cy]=2;
}
}
}
}
}
}

let answer = 0;
for (let x = 0; x < n; x++) {
for (let y = 0; y < n; y++) {
if (board[x][y] === 0) answer++;
}
}
return answer;
}

🍞 dx, dy 주변 좌표 (8칸)
🍞 for~for 폭탄을 찾고 주변 칸을 0 -> 2로

function solution(b) {
const directions = [[0,0],[0,1],[0,-1],[1,1],[1,0],[1,-1],[-1,-1],[-1,0],[-1,1]]
let bombSet = new Set();

for(let i = 0; i < b.length; i++) {
for(let j = 0; j < b[i].length; j++) {
if(b[i][j] == 1) {
directions.forEach(el => {
let [nextX, nextY] = el;
[nextX, nextY] = [i+nextX, j+nextY];
if(nextX >= 0 && nextX < b.length && nextY >= 0 && nextY < b[i].length) {
bombSet.add(nextX+' '+nextY);
}
})
}
}
}
return b.length * b[0].length - bombSet.size;
}

🍞 directions 주변 좌표 (9칸)
🍞 for~for 폭탄을 찾고 주변 좌표를 Set에 추가 (중복 제거)


삼각형의 완성조건 (2)

function solution(sides) {
let c=0, answer=0;
const [a, b] = sides
while(a+b>c){
const arr = [a,b,c].sort((a,b)=>a-b)
if(arr[0]+arr[1]>arr[2]) answer++;
c++;
}
return answer
}
function solution(sides) {
return Math.min(...sides)*2-1
}

🍞 가장 짧은 변 선택 후 계산..!!


외계어사전

function solution(spell, dic) {
let flag = true;
dic.some((val)=>{
flag = true;
spell.forEach((v)=>{
if(val.indexOf(v)===-1)
flag = false;
})
return flag && val.length === spell.length;
})
return flag ? 1 : 2
}

🍞 some 조건을 만족하는 원소를 찾으면 true

function solution(spell, dic) {
const found = dic.some(val => {
const flag = spell.every(v => val.includes(v));
return flag && val.length === spell.length;
});
return found ? 1 : 2;
}

🍞 some 조건을 만족하는 원소를 찾으면 true
🍞 every 모든 문자가 val 안에 있어야 true


저주의 숫자 3

function solution(n) {
let i=1;
const answer = [];
while(answer.length<n){
if(i%3!==0 && [...String(i)].indexOf('3')===-1) answer.push(i)
i++;
}
return answer[answer.length-1];
}

🍞 if 3의 배수가 아니고 각 자리에 3이 없으면 push

function solution(n) {
return [...Array(n * 3)]
.map((_, i) => i + 1)
.filter((num) => num % 3 !== 0 && !num.toString().includes("3"))[n - 1];
}

🍞 [...Array(n * 3)] 길이가 n*3인 배열 생성
🍞 map 1,2,3...으로 채움
🍞 filter


평행

function solution(dots) {
const [[x1, y1], [x2, y2], [x3, y3], [x4, y4]] = dots;
const [[dx1, dy1], [dx2, dy2], [dx3, dy3]]
= [[x1-x2, y1-y2], [x1-x3, y1-y3], [x1-x4, y1-y4]]
const [[dx4, dy4], [dx5, dy5], [dx6, dy6]]
= [[x3-x4, y3-y4], [x2-x4, y2-y4], [x2-x3, y2-y3]];

if(dx1/dy1===dx4/dy4) return 1;
if(dx2/dy2===dx5/dy5) return 1;
if(dx3/dy3===dx6/dy6) return 1;
return 0
}

🍞 네 점을 구조분해할당하고 각각 기울기 계산

function solution(dots) {
if (calculateSlope(dots[0], dots[1]) === calculateSlope(dots[2], dots[3]))
return 1;
if (calculateSlope(dots[0], dots[2]) === calculateSlope(dots[1], dots[3]))
return 1;
if (calculateSlope(dots[0], dots[3]) === calculateSlope(dots[1], dots[2]))
return 1;
return 0;
}

function calculateSlope(arr1, arr2) {
return (arr2[1] - arr1[1]) / (arr2[0] - arr1[0]);
}

🍞 calculateSlope 기울기 계산 함수


겹치는 선분의 길이

function solution(lines) {
const answer = [];
let sum = 0;
lines.forEach(([x,y])=>{
for(let i=0;i<y-x;i++){
answer.push(x+i)
}
})
return answer
.filter((v, idx)=> idx!==(answer.lastIndexOf(v))&&idx==answer.indexOf(v))
.length
}

🍞 forEach~for 각 선분 [x,y]에 대해 1 간격으로 push ([1,4] -> [1,2,3])
🍞 filter 중복이면서 첫 등장인 인덱스만 추출

function solution(lines) {
let line = new Array(200).fill(0);

lines.forEach(([a, b]) => {
for(; a < b; a++) line[a+100]++;
});

return line.reduce((a, c) => c > 1 ? a + 1 : a, 0)
}

🍞 new Array(200).fill(0) 전체 구간 0~199 배열
🍞 forEach 각 선분에 대해 선분의 각 좌표마다 line[a+100]++
🍞 reduce 겹치는 횟수 세기


유한소수 판별하기

function solution(a, b) {
let i = b;
while(i>0){
if(a%i===0 && b%i===0)
break;
i--;
}
let s = b/i;
i = 0;
while(s>1){
if(s%2===0) s=s/2;
if(s%5===0) s=s/5;
if(i>10) return 2;
i++;
}
return s
}

🍞 while 최대공약수 구하기
🍞 while 분모가 2, 5의 배수만으로 구성됐는지 확인 - 10회 이상 반복시 무한소수 (2^10=1024)

function solution(a, b) {
let n = 1;
for (let i = 1; i <= Math.min(a,b); i++) {
if (a%i===0 && b%i===0) n = i;
}

b/=n;
while (b%2===0) b/=2;
while (b%5===0) b/=5;

return b === 1 ? 1 : 2;
}

🍞 for 최대공약수 구하기
🍞 while 2와 5만 남도록 분수 나누기