본문으로 건너뛰기
/ Docs

수학 응용 (1) (Day 19-20)

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

🌞

✨Day 19-20

문자열, 배열, 조건문, 수학, 시뮬레이션, 문자열, 사칙연산

목표: 수학 응용

  • 배열 생성/초기화
    fill ❇️ 배열 채우기 | 원본 변경
    push/pop 💚 요소 추가 | 원본 변경 new Set() : 배열 중복 제거

  • 문자열 검색/확인
    includes 🔍 문자열 포함 여부 확인
    match 🔍 정규식으로 일치하는 부분 검색

  • 수학 Math.pow, 2 ** x : 거듭제곱
    Math.log2 : 2를 밑으로 한 로그
    Math.floor : 소수 내림
    Math.ceil : 소수 올림
    Math.abs : 절댓값


볼만한 코드 문제들만 가져왔습니다.!

입문

잘라서 배열로 저장하기

function solution(my_str, n) {
const answer = [];
[...my_str].forEach((_, idx)=> {
if(idx%n===n-1) {
answer.push(my_str.slice(idx+1-n, idx+1));
}
else if(idx===my_str.length-1){
answer.push(my_str.slice(idx-(my_str.length%n)+1, my_str.length))
}
})
return answer;
}

function solution(my_str, n) {
return my_str.match(new RegExp(`.{1,${n}}`, "g"));
}

🍞 정규표현식사용 {찾는것 처음, 찾는것 끝}


캐릭터의 좌표

const ops = {
"left" : [-1, 0],
"right" : [1, 0],
"up" : [0, 1],
"down" : [0, -1],
}

function solution(keyinput, board) {
let sum = [0, 0];
const [w, h] = board
keyinput.map((v)=> ops[v]).forEach(([x,y])=>{
sum[0] += x;
sum[1] += y;
if(sum[0]>(w-1)/2) sum[0]--;
else if(sum[0]<(w-1)/2*-1) sum[0]++;
if(sum[1]>(h-1)/2) sum[1]--;
else if(sum[1]<(h-1)/2*-1) sum[1]++;
})
return sum;
}

🍞 ops 객체로 좌표를 정의
🍞 이동 -> 초과 확인 -> 되돌리기

function solution(keyinput, board) {
let res = [0,0];
for (let p of keyinput) {
switch(p){
case 'left': if (-res[0] < board[0]/2-1) res[0]--; break;
case 'right': if (res[0] < board[0]/2-1) res[0]++; break;
case 'up': if (res[1] < board[1]/2-1) res[1]++; break;
case 'down': if (-res[1] < board[1]/2-1) res[1]--; break;
}
}
return res;
}

🍞 switch 문으로 방향마다 처리
🍞 이동 전에 범위 조건 검사

function solution(keyinput, board) {
let key = {"right" : [1,0], "up" : [0,1], "down" : [0,-1], "left" : [-1,0]};

let rslt = keyinput.map(v => key[v]).reduce((a,b) => {
if (Math.abs(a[0] + b[0]) > board[0]/2 || Math.abs(a[1] + b[1]) > board[1]/2)
return [a[0],a[1]] ;

return [a[0] + b[0], a[1] + b[1]];}
, [0,0])

return rslt;
}

🍞 map 으로 방향을 좌표로 바꾸고
🍞 reduce 로 누적하면서 이동 : 좌표 '절댓값'이 보드 절반 크기를 초과하면 이동하지 않음


다항식 더하기

function solution(polynomial) {
let a=0, b=0
polynomial.split(' + ').forEach((v)=>{
if(v.includes('x')) a += Number(v.slice(0,v.indexOf('x'))) || 1
else b += Number(v)
})
return b ?
a ? a===1 ? `x + ${b}` : `${a}x + ${b}`
: `${b}` :
a===1 ? `x` : `${a}x`
}

🍞 + 기준으로 잘라서 항별로 배열 생성
🍞 x 있으면 숫자부분만 숫자로 -> 숫자가 없으면 1


기초

세 개의 구분자

function solution(myStr) {
let array = [];
array = myStr.split(/[abc]/).filter((v)=>v)
return array.length>0 ? array : ["EMPTY"]
}

🍞 a,b,c 를 기준으로 split
🍞 filter 로 빈 문자열 없애기

const solution(s){
return s.match(/[^a-c]+/g)||['EMPTY']
}

🍞 match : 문자열이 정규식과 매치되는 부분을 검색
🍞 match : ^a-c a~c가 아닌~~


배열의 원소만큼 추가하기

function solution(arr) {
const answer = [];
arr.forEach((v)=> {
for(let i=0;i<v;i++){
answer.push(v)
}
})
return answer
}

🍞 forEach : 각 원소에 대해 for문으로 v번 push

function solution(arr) {
return arr.reduce((list, num) => [...list, ...new Array(num).fill(num)], []);
}

🍞 reduce : 각 원소마다 new Array(num).fill(num) -> 배열 생성
🍞 ... : 스프레드 연산자로 기존 list와 합침


빈 배열에 추가, 삭제하기

function solution(arr, flag) {
const answer = [];

arr.forEach((v, idx)=> {
if(flag[idx]){
for(let i=0;i<v*2;i++){
answer.push(v)
}
}
else{
for(let i=0;i<v;i++){
answer.pop()
}
}
})
return answer
}

🍞 forEach : 배열 순회하면서 flag[idx] 따라 설정

function solution(arr, flag) {
return arr.reduce(
(prev, num, i) => (flag[i] ? [...prev, ...new Array(num * 2).fill(num)] : prev.slice(0, -num)),
[],
);
}

🍞 reduce : 누적배열 prev 만들고 위에 문제 처럼 배열 확장
🍞 slice : false이면 마지막 num개 제거


배열 만들기 6

function solution(arr) {
let i=0;
const stk = [];
while(i<arr.length){
if(stk.length){
if(stk[stk.length-1]===arr[i]){
stk.pop();
i++
}
else{
stk.push(arr[i++]);
}
}
else{
stk.push(arr[i++])
}
}
return stk.length > 0 ? stk : [-1]
}

🍞 while 스택이 비어있지 않으면 마지막 값과 현재 값 비교

function solution(arr) {
let stk = []
arr.forEach((x,i)=>{
if( x !== stk[stk.length - 1]){
stk.push(x)
}else{
stk.splice(-1)
}
})

if(stk.length == 0){
stk = [-1]
}
return stk;
}

🍞 forEach 마지막값과 현재값 비교
🍞 splice(-1) 배열 마지막 요소 제거


무작위로 k개의 수 뽑기

function solution(arr, k) {
let array = [];
array = arr.filter((v,idx)=> arr.indexOf(v)===idx).slice(0,k);
return array.length<k ? [...array, ...Array(k-array.length).fill(-1)]: array
}

🍞 filter 로 중복 제거 (index확인)

function solution(arr, k) {
const set = new Set(arr);
return set.size < k ? [...set, ...Array(k - set.size).fill(-1)] : [...set].slice(0, k);
}

🍞 new Set(arr) 로 중복 제거


배열의 길이를 2의 거듭제곱으로 만들기

function solution(arr) {
let i=1, exp= 0;
while(!(i>=arr.length && i==Math.pow(2,exp))){
if(i>=Math.pow(2,exp)) exp++;
i++;
}
return [...arr, ...Array(i-arr.length).fill(0)]
}

🍞 while 2의 거듭제곱 이상이면서 현재 배열 길이 이상인 숫자 i 확인
🍞 fill 나머지를 0으로 채운 배열

function solution(arr) {
const length = arr.length;
const totalLength = 2 ** Math.ceil(Math.log2(length));
return [...arr, ...new Array(totalLength - length).fill(0)];
}

🍞 Math.log2 배열 길이를 2의 로그로 변환
🍞 Math.ceil 소수점 올림 -> 2의 거듭제곱으로

const solution = (arr) => {
let num = 1;
while (arr.length > num){
num *= 2;
}
while(arr.length !== num){
arr.push(0)
}
return arr;
}

🍞 while 배열 길이보다 num이 작을 동안 2배씩 증가
🍞 push push로 채움


배열 비교하기

function solution(arr1, arr2) {
if(arr1.length===arr2.length){
const [a1, a2] = [arr1.reduce((acc,cur)=> acc + cur), arr2.reduce((acc,cur)=> acc + cur)]
return a1===a2 ? 0 : a1>a2 ? 1 : -1;
}
else{
return arr1.length> arr2.length ? 1 : -1;
}
}

🍞 reduce 각 배열 합 계산

const solution = (arr1, arr2) => {
return arr1.length !== arr2.length ? compare(arr1.length, arr2.length) : compare(arr1, arr2, "reduce");
};

const compare = (a, b, option) => {
if (option === "reduce") {
a = a.reduce((acc, cur) => acc + cur);
b = b.reduce((acc, cur) => acc + cur);
}
return a > b ? 1 : a < b ? -1 : 0;
};

🍞 solution 에서 길이 비교 -> 다르면 compare(a,b) -> 같으면 reduce


문자열 묶기

function solution(strArr) {
const array = Array(30).fill(0);
strArr.forEach((v)=> array[v.length-1]++)
array.sort((a,b)=> b-a);
return array[0]
}

🍞 array 문자열 길이(1~30)에 따라 각 인덱스++


배열의 길이에 따른 연산

function solution(arr, n) {
return arr.map((v,idx)=>{
if(arr.length%2 && !(idx%2)) return v+n
if(!(arr.length%2) && idx%2) return v+n
return v
})
}
const solution(arr, n){
return arr.map((v, idx) => (
arr.length % 2 !== idx % 2
? v + n
: v
))
}

🍞 오.. arr.length와 idx의 홀짝이 반대일때 true