본문 바로가기

javascript/javascript 알고리즘

[js] 프로그래머스 1단계

로또의 최고 순위와 최저 순위

function solution(lottos, win_nums) {
  var answer = [];
  let a=lottos.filter(v=>v!==0)
  let long=lottos.length-a.length
  let count=0;
  a.forEach(v=>{
    if(win_nums.includes(v)) count+=1;
  })
  if(count==0) answer=long==0?[6,6]:[7-long,6]
  else answer=[7-count-long,7-count]
  return answer;
}

 하드코딩 했네... ㅠㅠ

1. 0의 개수를 구하는 것이 우선이었다.

2. 0제거를 위해 filter함수를 써서 0을 제거했고, 전체길이에서 0을 제거한 배열의 길이를 빼서 0의 개수를 구했다.

3. 0을제거한 배열의 요소를 하나씩 로또번호와 비교해서(forEach) count했다. for of를 사용하려 했으나 안돼서 ...ㅎ

4. 최저순위는 딱 맞춘개수이고, 최고순위는 찢어진부분 즉, 0인개수를 다 맞았다고 쳤을때 최고순위니까 구성했다....


신고결과 받기

const id_list=["muzi", "frodo", "apeach", "neo"];
const report=["muzi frodo","apeach frodo","frodo neo","muzi neo","apeach muzi"];
const k=2;

function solution(a,b,c) {
let answer=[];
let obj={};    //신고당한id:[신고한놈들] 이렇게 만들거야
for(prop of a){
  obj[prop]=[]; //prop이라는 이름의 배열을 만들거야
  answer.push(0);  //prop개수만큼 답의 길이를 만들거야.초기화
}console.log(obj);  //{"muzi":[],"frodo":[], .....}
for(prop of report){
  [신고한id, 신고당한id]=prop.split(' ');//split한것에 id부여하기
  obj[신고당한id].indexOf(신고한id)==-1?//신고한id가 배열내에 없어?
  obj[신고당한id].push(신고한id):null;//그럼 push하고 아님 암것도..하지마
  // if(!obj[reprotedID].includes(reportID)){obj[reprotedID].push(reportID)}랑 같다.
}
 console.log(obj);
for(prop of a){
  if(obj[prop].length>=2){
    for(kkk of obj[prop]){  //  obj[prop].map(v=>answer[a.indexOf(v)]+=1)
      answer[a.indexOf(kkk)]+=1;
    }
  }
}
  console.log(answer)
}

solution(id_list,report,k)

실제 제출엔 console.log 지우고 return해야함


신규 아이디추천

function solution(new_id) {
  let test1=/[^a-z0-9._-]/g;  
   new_id=new_id.toLowerCase().
   replace(test1,"")
  .replace(/[.]{2,}/g,'.')
  .replace(/^[.]|[.]$/g,"")
  if(new_id=='') new_id="a"
  else if(new_id.length>15)  new_id=new_id.slice(0,15).replace(/[.]$/,'');
  while(new_id.length<3) {
    new_id+= new_id[new_id.length-1]}
  return new_id;
}

숫자 문자열과 영단어

function solution(s) {
    let answer=s.replace(/zero/g,0).replace(/one/g,1).replace(/two/g,2)
    .replace(/three/g,3).replace(/four/g,4).replace(/five/g,5)
    .replace(/six/g,6).replace(/seven/g,7).replace(/eight/g,8).replace(/nine/g,9);
    answer=parseInt(answer);
    return answer;
}

와.. 다른사람풀이보다가 엄청난 걸 봐버렸다.

function solution(s) {
    let numbers = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"];
    var answer = s;

    for(let i=0; i< numbers.length; i++) {
        let arr = answer.split(numbers[i]);
      console.log(arr)
        answer = arr.join(i);
    }

    return Number(answer);
}console.log(solution(s))

해당 문자로 쪼개진 걸 다시 숫자(index)로 join하다니.... 정말 멋있다.

 


키패드 누르기

function solution(numbers, hand) {
  var answer = '';
  let keypad={
    1:[0,3],    2:[1,3],    3:[2,3],
    4:[0,2],    5:[1,2],    6:[2,2],
    7:[0,1],    8:[1,1],    9:[2,1],
    0:[1,0],
  }
  let hleft=[0,0]
  let hright=[2,0]

  for(prop of numbers){
    if(prop==1||prop==4||prop==7) {
      answer+="L"; hleft=keypad[prop]
    }
    else if(prop==3||prop==6||prop==9) {
      answer+='R'; hright=keypad[prop]
    }
    else{
      let ll=Math.abs(keypad[prop][0]-hleft[0])+
             Math.abs(keypad[prop][1]-hleft[1]);
      let rr=Math.abs(keypad[prop][0]-hright[0])+
             Math.abs(keypad[prop][1]-hright[1]);
      if(ll==rr) {
        hand=="left"?
        (answer+='L',hleft=keypad[prop]):(answer+='R',hright=keypad[prop]);
      }
      else if(ll<rr) {answer+="L"; hleft=keypad[prop]}
      else {answer+='R'; hright=keypad[prop]}
    }
  }
    return answer;
}

크레인 인형뽑기 게임  틀림 아직못품

 let board= [[0,0,0,0,0],[0,0,1,0,3],[0,2,5,0,1],[4,2,4,4,2],[3,5,1,3,1]]	;
let moves=[3,5,2,3,5,1,2,3,4,5];
function solution(board, moves) {
 var answer=[];
 let obj={};
 let count=0;
 for(let i=0;i<board.length;i++){
     obj[i+1]=[];
   for(let j=0;j<board.length;j++){
    obj[i+1].push(board[j][i]);     
  }
 }
  console.log(obj)
  //[4,3,1,1,3,2,4]
  for(let i=0;i<moves.length;i++){
    if(obj[moves[i]].lastIndexOf(0)!==board[0].length-1) {
    myidx=obj[moves[i]][obj[moves[i]].lastIndexOf(0)+1];
      if(answer[answer.length-1]==myidx) {count+=2,answer.pop(answer.length-1);}
      else{
        answer.push(myidx);
        obj[moves[i]][obj[moves[i]].lastIndexOf(0)+1]=0;
      }
    }  console.log(i,count, answer)
  }
 return answer;
}
solution(board, moves);

없는숫자 더하기

let numbers=[1,2,3,4,6,7,8,0];

function solution(numbers) {
    var answer = 0;
    let array=[0,1,2,3,4,5,6,7,8,9];
    for (prop of array){
      numbers.includes(prop) ? null:answer+=prop;
    }return answer;
}

그리고 어떤사람의 풀이..... numbers의 숫자들이 중복안되니까 이렇게도 사용할 수 있구나

function solution(numbers) {
    return 45 - numbers.reduce((cur, acc) => cur + acc, 0);
}

음양더하기

function solution(absolutes, signs) {
    var answer = 0;
    for(let i=0 ; i<absolutes.length ; i++){
      answer+=signs[i]?absolutes[i]:(-absolutes[i]);
    } return answer;
}

function solution(absolutes, signs) {
    return absolutes.reduce((acc, val, i) => acc + (val * (signs[i] ? 1 : -1)), 0);
}

내적구하기

function solution(a, b) {
    var answer =a.reduce((v,c,i)=>v+=a[i]*b[i],0)
    return answer;
}

소수구하기

function sosu(a){
  let count=0;
  for(let i=1;i<=a;i++){
    a%i==0 ? count++ : null;
  }return a==1 ?true:(count==2?true:false)
}
function solution(nums) {
    let left=0;
    let right=nums.length-1;
    let answer=0;
    for(let i=0;i<nums.length;i++){
      for(let j=i+1;j<nums.length;j++){
        for(let k=j+1;k<nums.length;k++){
          sosu(nums[i]+nums[j]+nums[k])?answer++:null;
        }
      }
    }console.log(answer)
    return answer;
}

완주하지 못한 선수

시간초과..

function solution(participant, completion) {
  var answer = [];
  for(prop of participant){
    completion.includes(prop)?completion.splice(completion.indexOf(prop),1)
    :answer.push(prop);    
  }
  return answer[0];
}

sort해서 정렬한 뒤, 어차피 같을테니 오름차순같은거 신경안씀.. index끼리 비교했을 때 다른값이 나오면

참가자 이름을 뱉어냄... 참가자가 1명 더 많으니까

function solution(participant, completion) {
  participant.sort();
  completion.sort();
  for(let i = 0; i < participant.length; i++){
      if(participant[i] !== completion[i]){ 
        return participant[i] ;
       }
  }
}

K번째 수

function solution(array, commands) {
    var answer = [];
  for(let i=0;i<commands.length;i++){
    let test=commands[i]
    let array2=[...array]
    let array3=array2.slice(test[0]-1,test[1]).sort((a,b)=>a-b)
    answer.push(array3[test[2]-1])
  } 
    return answer;
}

다른 사람 풀이...

function solution(array, commands) {
    return commands.map(command => {
        const [sPosition, ePosition, position] = command
        const newArray = array
            .filter((value, fIndex) => fIndex >= sPosition - 1 && fIndex <= ePosition - 1)
            .sort((a,b) => a - b)    
        return newArray[position - 1]
    })
}
-------------------------------------------------------------
function solution(array, commands) {
    return commands.map(v => {
        return array.slice(v[0] - 1, v[1]).sort((a, b) => a - b).slice(v[2] - 1, v[2])[0];
    });
}

모의고사

function solution(answers) {
    var answer = [];
    let n=[[1,2,3,4,5],[2,1,2,3,2,4,2,5],[3,3,1,1,2,2,4,4,5,5]]
    let count=[0,0,0];
    for(let k=0;k<count.length;k++){
     count[k]=answers.filter((v,i)=>(v==n[k][i%n[k].length])).length;
    }
    let max=Math.max(...count)
    for(i=0;i<count.length;i++){
      if(count[i]==max) answer.push(i+1)
    }return answer;
}

나머지로 구하는거 너무 어렵다.... 처음엔 push나 concat으로 문제개수에 따라 잘라서 추가로 붙여야하나 했는데..

 


체육복

function solution(n, lost, reserve) {
   let obj={};
   let count=0;
   for(let i=0;i<n;i++){
   obj[i+1]=0;
   }
  for(prop of reserve){
     obj[prop]+=1;
    }
  for(prop of lost){
    obj[prop]-=1;
  }
  for(let i=1;i<=n;i++){
    if(obj[i]<0){
        if(obj[i-1]>0){obj[i-1]-=1;obj[i]+=1}
        else if(obj[i+1]>0){obj[i+1]-=1;obj[i]+=1}}
  if(obj[i]>=0) count++;
  }  
  return count;
}

실패율

function solution(N, stages) {
    var answer = [];
    var answer = [];
    let people=stages.length;
    for(let i=1;i<=N;i++){
        let sum=0;
        let clear=stages.filter(v=>v>i).length
        sum=(people-clear)/people
        answer.push([i,sum])
        people=clear;
    }
    return answer.sort((a,b)=>b[1]-a[1]).map(v=>v[0]);
}

약수의 개수와 덧셈

function yacksu(a){
  let count=0;
  for(let i=1;i<=a;i++){
    if(a%i==0) count++;
  }return count;
}
function solution(left, right) {
    var answer = 0;
    for(let i=left;i<=right;i++){
      answer=yacksu(i)%2==0?answer+i:answer-i;
    }
    return answer;
}

3진법 뒤집기

function solution(n) {
        return parseInt(n.toString(3).split('').reverse().join(''),3)
}

예산

function solution(d, budget) {
    let arr=d.sort((a,b)=>a-b)
    console.log(arr)
    let count=0;
    let sum=0;
    for(let i=0;i<d.length;i++){
    sum+=arr[i]
    if(sum<=budget) count++;
    }
    return count;
}

두 개 뽑아서 더하기

function solution(numbers) {
    var answer = [];
    for(let i=0;i<numbers.length;i++){
      for(let j=i+1;j<numbers.length;j++){
        answer.push(numbers[i]+numbers[j])
      }
    }
    answer=[...new Set(answer)].sort((a,b)=>a-b)
  return answer;
}

최소직사각형

function solution(sizes) {
  sizes=sizes.map(([a,b])=>a>b?[a,b]:[b,a])
  let array=sizes[0];
  for(let i=1;i<sizes.length;i++){
    array[0]=array[0]<sizes[i][0]?sizes[i][0]:array[0];
    array[1]=array[1]<sizes[i][1]?sizes[i][1]:array[1];
  }
  let answer=array[0]*array[1]
  return answer;
}

- if(array[0]<sizes[0]) array[0]=sizes[0] 이렇게 쓰는게 더 간결하다. 괜히 삼항연산자 쓸 필요 X

- 안풀린다 싶을땐 알고리즘을 다시생각해볼것.. 처음엔 하나라도 크면 필터를 쓰고 어쩌고 하니까 엄청길어졌었다...

 


나머지가 1이 되는 수 찾기

function solution(n) {
    let arr=[];
    for(let i=1;i<=n;i++){
      if(n%i==1) arr.push(i)
    }
    return Math.min(...arr)
}
function solution(n) {
    for(var i = 1; i < n; i++){
        if(n%i == 1){
            return i;
        }
    }
}

내가 푼 첫번째 코드로 하면 모든 수를  찾게되니까, 어차피 i는 작은 수 부터 나누니까 나머지가 1이면 바로 return.

 


부족한 금액 계산하기

function solution(price, money, count) {
    let sum=0;
    let n=1;
    while(n<=count){
      sum+=price*n;n++;
    }
    return money>sum?0:sum-money;
}

테스트 1개 통과를 못해서 뭐지? 했는데.... money가 부족하지 않을때 -로 표시되서였다! 그래서 0조건을 추가해줌


[1차]비밀지도

function solution(n, arr1, arr2) {
    var answer = [];
    let _arr1=arr1.map(v=>{
      let k=v.toString(2).split('')
      while(k.length<n){
      k=['0',...k]
      }return k
    })
    let _arr2=arr2.map(v=>{
      let k=v.toString(2).split('')
      while(k.length<n){
      k=['0',...k]
      }return k
    })
    for(let i=0;i<n;i++){
      let total='';
      for(let j=0;j<n;j++){
        total+=_arr1[i][j]=="1"||_arr2[i][j]=="1"?"#":" ";
      }
      answer.push(total)
    }
    console.log(answer)
    return answer;
}

나는 하나하나 다 바꿔서 풀었는데... 다른사람들은 한줄로도 풀고 그래서 진짜 세상에는 천재가 많구나... 생각했다@

일단은 arr1, arr2 두개로 map 함수를 쓸  필요없이 arr1과 arr2중 하나라도 1이면 1인상태에서 2진수로 바꿔준다.

여기서 사용한 것이 ' | ' 비트연산자 중 or연산자로 비교하는 비트 중에서 하나라도 1이면 1을 반환한다.

or연산자 || 와 혼동하지 말 것.

function solution(n, arr1, arr2) {
    let arr=arr1.map((v,i)=>{
      let k=(v|arr2[i]).toString(2);
      console.log(k)
      k=k.length<n?"0".repeat(n-k.length)+k:k
      console.log(k)
      k=k.replace(/1/g,'#').replace(/0/g,' ')
      return k;
    })return arr;
}

그리고 length가 부족할 때 0으로 채워주기 위해 나는 split한 뒤, 배열에 추가해주었는데 문자열은 repeat를 써서

앞에 추가해줄 수가 있다! 이번 문제는 많은 도움이 되었다.

 


가운데 글자 가져오기

function solution(s) {
    let long=s.length
    let answer=s.substring(long%2==0?long/2-1:long/2,long/2+1)
    return answer;
}

코드를 짜고보니 substring(a,b)의 b부분은 동일하고, a부분은 짝숙일땐 -1을 해줘야해서 삼항연산자를 이용.


[1차]다트게임

function score(a,b){
  let sum=0;
    if(/[S]/.test(b)) sum=a;
    else sum=/[D]/.test(b)?a**2:a**3;
  return sum;
}
function solution(dartResult) {
    var answer = 0;
    let sum=[0,0,0]
    let m=dartResult.split(/[A-Z,*,#]/g).filter(v=>v!=='').map(Number)
    let n=dartResult.split(/[0-9]/g).filter(v=>v!=='')
    let total=m.map((a,i)=>[a,n[i]])
    for(let i=0; i<3; i++){
      sum[i]=score(total[i][0],total[i][1]);
      if(total[i][1][1]=='*') {sum[i]=sum[i]*2;
                               sum[i-1]=sum[i-1]*2}
      else if(total[i][1][1]=='#') sum[i]=-sum[i]
      else sum[i]=sum[i]
      }
      return sum.reduce((a,c)=>a+=c);
    }

같은 숫자는 싫어

중복제거길래 set사용하려다가 모든 중복되는수가 지워져서 filter를 사용

function solution(arr)
{return answer=arr.filter((v,i)=>v!==arr[i-1]);
}

나누어 떨어지는 숫자 배열

function solution(arr, divisor) {
    let answer=arr.filter(a=>a%divisor==0).sort((a,b)=>a-b)
    return answer.length?answer:[-1]
}

두 정수 사이의 합

function solution(a, b) {
  let arr=b>a?[a,b]:[b,a]
  let answer=0;
  for(let i=arr[0];i<=arr[1];i++){
  answer+=i
}

문자열 내 마음대로 정렬하기

function solution(strings, n) {
    let answer=strings.sort((a,b)=>{
      if (a[n] > b[n]) return 1;
      else if (a[n] < b[n]) return -1;
      else if(a>b) return 1;
      else if(a<b) return -1;
    });
  return answer;
}

sort의 두번째 조건을 설정할 수 있다니 정말 재밌다~~~!


문자열 내 p와 y의 개수

function solution(s){
    let p=0;
    let y=0;
    for(prop of s.toLowerCase()){
      if(prop=="p") p++;
      if(prop=="y") y++;
    }return p==y?true:false
}

문자열 내림차순으로 배치하기

function solution(s) {
    return s.split('').sort().reverse().join('')
}

문자열 다루기 기본

function solution(s) {
    return !/[^0-9]/.test(s)&&(s.length==4||s.length==6)?true:false;
}

서울에서 김서방 찾기

function solution(seoul) {
    let kk=seoul.indexOf("Kim")
    return `김서방은 ${kk}에 있다`;
}

소수찾기

function sosu(a){
    let count=0;
    let n=1;
    while(n<=a){
     if(a%n==0) count++;
     n++;
    }
  return count==2?true:false;
}
function solution(n) {
     let count=0;  
  while(n>=2){
     if(sosu(n)) count++;
     n--;
  }return count;
}//////////////시간초과...
function solution(n) {
  let arr=new Array(n+1);
  for(let i=2;i<=n;i++) arr[i]=i; //0과1은 소수가 아니다
  for(let i=2;i<=n;i++){
    if(arr[i]==0) continue;     //이미 0이면 다음 for문으로
    for(let k=i*2;k<=n;k+=i){   //해당 숫자가 배수라면 0으로 만들어준다.
      arr[k]=0;
    }
  }
  let answer=arr.filter(v=>v!==0);  //filter함수로 0인값을 모두 제거한 뒤 길이를 구한다.
  return answer.length;
}

num의 +1길이의 배열을 만들어주고, index로 배열을 채워준다.


수박수박수박수박수박수?

function solution(n) {
    let a='수박'.repeat(n);
    return a.substr(0,n);
}

문자열을 정수로 바꾸기

function solution(s) {
    return Number(s);
}

시저 암호

function solution(s, n) {
    var answer = '';
  for(prop of s){
    if(prop==' ') answer+=' '; 
    else {answer+=prop.toUpperCase().charCodeAt()+n>90
    ? String.fromCharCode(prop.charCodeAt() + n - 26)
    : String.fromCharCode(prop.charCodeAt() + n)
    }
   }
      return answer;
}

테스트에서 오류가 나서 구글링해본 결과, b여도 숫자가 25더해질 수도 있기 때문에, 

z||Z 일때만이 아니라 prop.charCodeAt()+n > 알파벳범위를 넘어가면 -26을 해주어야 한다.

대문자로 바꿔서 그 대문자가 90넘어가는지만 보면된다. 소문자/대문자 두번 쓸 필요 없음.


약수의 합

function solution(n) {
    var answer = [];
    let a=1;
    while(a<=n){
      if(n%a==0) answer.push(a)
      a++;
    }
    return answer.length!==0?answer.reduce((a,c)=>a+=c):0;
}

이상한 문자 만들기

function solution(s) {
    let total=[];
    let arr=s.split(' ').map(v=>{
      console.log(v)
      let answer=[];
      v.split('').map((t,i)=>{
      answer+=(i%2==1?t.toLowerCase():t.toUpperCase())
      })
    total.push(answer);
    })
  return total.join(' ')
}

자릿수 더하기

function solution(n)
{
var answer = (n+'').split('').reduce((a,c)=>(a+=Number(c)),0)

    return a

자연수 뒤집어 배열로 만들기

function solution(n) {
    return (n+'').split('').map(Number).reverse();
}

정수 내림차순으로 배치하기

function solution(n) {
    return +(n+'').split('').sort((a,b)=>b-a).join('');
}

정수 제곱근 판별

function solution(n) {
  let a=Number.isInteger(Math.sqrt(n))?(Math.sqrt(n)+1)**2:-1
    return a;
}

제일 작은 수 제거하기

function solution(arr) {
  let min=[...arr].sort((a,b)=>a-b)[0]
  let arr2=arr.filter(v=>v!==min)
  return arr2.length>1?arr2:[-1]
}

짝수와 홀수

function solution(num) {
    return (num%2==1||num%2==-1)?"Odd":"Even"
}​

처음 코드짤 때, 놓친부분 : 주어진 정수 num이 음수일 수도 있다는것! -4 / 2 => -2이다.


최대공약수와 최소공배수

function yacksu(a){
  let arr=[];
  let n=1;
  while(n<=a){
    if(a%n==0) arr.push(n);
    n++;
  }return arr;
}
function solution(n, m) {
  let arr1=yacksu(n)
  let arr2=yacksu(m)
  let totalarr=[];
  arr1.map(v=>{if(arr2.includes(v)) totalarr.push(v);})
  let max=totalarr[totalarr.length-1]
  let baesu=totalarr.length==1?n*m:n*m/max
  return [max, baesu];
}

콜라츠 추측

function solution(num) {
    let n=0;
    while(num!==1){
      if(num==1) break;
      else if(n>=500) {
        n=-1;
        break;}
      num=(num%2==0)?num/2:3*num+1;
      n++;
    }
    return n;
}

평균구하기

function solution(arr) {
  return arr.reduce((a,c)=>a+=c)/arr.length;
}

하샤드 수

function solution(x) {
    let sum=0;
    for(prop of x+''){
      sum+=+prop;
    }
    return x%sum==0?true:false;
}

핸드폰 번호 가리기

function solution(phone_number) {
    let answer='*'.repeat(phone_number.length-4);
    return (answer+phone_number.substr(phone_number.length-4,phone_number.length));
}
function hide_numbers(s){
  return "*".repeat(s.length - 4) + s.slice(-4);
}

substr말고 slice(-4)를 해서 뒤에서부터 잘라오자!


행렬의 덧셈

function solution(arr1, arr2) {
    return [...arr1].map((v,i)=>v.map((w,j)=>w+=arr2[i][j]));
}

x만큼 간격이 있는 n개의 숫자

function solution(x, n) {
  let a=[];  
  let t=x;
  while(n>0){
      a.push(t)
      t+=x;
      n--;
    }
  return a
}
function solution(x, n) {
    return Array(n).fill(x).map((v, i) => (i + 1) * v)
}

모두 x로 배열을 채워놓고, index에 따라 +해준값을 map해주는 방법도 있구나!

 


직사각형 별찍기

process.stdin.setEncoding('utf8');
process.stdin.on('data', data => {
    const n = data.split(" ");
    const a = Number(n[0]), b = Number(n[1]);
    let sum='';
    for(let i=0;i<b;i++){
      for(let j=0;j<a;j++){
        sum+='*';
      }sum+=i!==b-1?'\n':'';
    }console.log(sum)
});