1. makeFib.js

문제 조건

makeFib 함수는 클로저의 형태로 작성되어야 하고, 리턴된 함수가 호출될 때마다 피보나치 수열을 순차적으로 출력한다.

 

예제

var fn = makeFib();
fn(); // 0
fn(); // 1
fn(); // 1
fn(); // 2
fn(); // 3
fn(); // 5

코드

function makeFib() {
  // your code here
  var count = 0;
  var fibo = [0,1];

  return function(){
    // 첫번째, 두번째 호출 일 때는 각각 0과 1을 반환한다
    if(count === 0 ){
      count++;
      return fibo[0];
    }else if(count === 1){
      count++;
      return fibo[1];
    }else{
      // 배열 fibo에 호출 될 때 마다 앞 두개의 값을 합친 값을 넣어준 뒤 반환한다
      fibo.push(fibo[fibo.length-1] + fibo[fibo.length-2]);
      return fibo[fibo.length-1];
    }
  };
}

어떻게 풀었나

클로저의 핵심은 함수가 함수를 리턴 한다는 것이다. 그리고 위 예제처럼 var fn = makeFib(); 선언해서 사용하는데, 이때 makeFib()함수 안에 var 키워드를 이용해 변수를 만들어 놓으면, 함수가 호출될 때 마다 해당 값을 이용할 수 있다. 이 문제에서는 fibo라는 배열을 먼저 선언해 놓은 뒤 함수가 호출될 때 마다 fibo에 값을 추가 하도록 하였다

 

 

2. transformEmployeeData.js

문제 조건

배열로서 주어진 사원들의 정보를 객체로 이루어진 배열의 형태로 변환하여 반환하는 함수 transformEmployeeData()를 작성한다. 이때, Array의 map 메소드와 reduce 메소드를 반드시 사용하여 문제를 해결해야 한다.

 

예제

// INPUT
[
  [['firstName', 'Joe'], ['lastName', 'Blow'], ['age', 42], ['role', 'clerk']],
  [['firstName', 'Mary'], ['lastName', 'Jenkins'], ['age', 36], ['role', 'manager']]
];

// OUTPUT
[
  { firstName: 'Joe', lastName: 'Blow', age: 42, role: 'clerk' },
  { firstName: 'Mary', lastName: 'Jenkins', age: 36, role: 'manager' }
];

코드

function transformEmployeeData(array) {
  // your code here
  let Data_before = Object.assign(array);

  // 1. Array.map()을 이용해 각각 사원에 접근한다
  let Data_after = Data_before.map(function(person, index){
    // array[0], array[1]... 은 각각 사원을 나타낸다 => reduce를 사용해 하나의 객체로 만들어주기
    // 2. Array.reduce()를 이용해 각각 사원의 데이터를 담은 배열을 하나의 객체로 바꿔준다
    return person.reduce(function(acc, data){
      acc[data[0]] = data[1];
      return acc;
    }, {});
  });

  return Data_after;
  
}

어떻게 풀었나

map과 reduce를 적절히 사용할 수 있는지 묻는 문제였다. 이 문제를 계기로 map과 reduce에 대해 정확히 알고 넘어갈 수 있게 되었다. 

map(function())은 주어진 배열의 모든 요소들에 대해서 인자로 받은 함수를 실행하고 그 결과들로 이루어진 새로운 배열을 반환한다.

reduce(function(acc,cur), initial)는 주어진 배열을 하나의 값 혹은 객체(배열)로 변환할 때 사용된다.

 

3. getObjectById.js

문제 조건

객체로 구성된 배열 안에서, 인자로 넘기는 특정 id값을 가진 객체를 리턴하는 함수를 작성한다. 이 때 객체는 children이라는 키 값에 자식 노드를 가질 수 있고, 부모 뿐만이 아닌 자식 노드 중에서도 id값을 가진 객체가 있는지를 찾아야 한다. 

 

예제

let output = getObjectById(TREE_DATA.items, '1'));
console.log(output); // --> { "id": "1", "name": "johnny" }

코드

let TREE_DATA = {
  "items": [
    {
      "id": "1",
      "name": "johnny"
    },
    {
      "id": "2",
      "name": "ingi",
      "children": [
        {
          "id": "3",
          "name": "johnson"
        },
        {
          "id": "4",
          "name": "katy"
        },
        {
          "id": "5",
          "name": "steve",
          "children": [
            {
              "id": "6",
              "name": "lisa"
            },
            {
              "id": "7",
              "name": "penny",
              "children": [
                {
                  "id": "8",
                  "name": "john"
                },
                {
                  "id": "9",
                  "name": "hoyong"
                }
              ]
            },
            {
              "id": "10"
            }
          ]
        },
        {
          "id": "11"
        },
        {
          "id": "12"
        }
      ]
    },
    {
      "id": "13"
    },
    {
      "id": "14"
    }
  ]
};
function getObjectById(json, id) {

  for(let i = 0 ; i < json.length ; i++){
    if(json[i]['id'] === id){
      // 찾는 id값을 가진 객체를 찾으면 바로 해당 객체를 반환
      return json[i];
    }else{
      if(Object.keys(json[i]).includes('children')){
        // 찾고자하는 id값을 가지고 있지 않고, 자식노드를 가지고 있다면 자식노드까지 탐색한다.
        return getObjectById(json[i]['children'], id);
      }
    }
  }
}

어떻게 풀었나

Recursion을 통해서 자식노드를 가지고 있는 객체라면 다시한번 함수를 호출하고, 그렇지 않다면 객체를 출력하거나 계속해서 탐색을 하도록 구현하는 문제이다. 일단 인자로 받아온 배열의 길이만큼 탐색을 한다. 깊이 1에 해당하는(json[i]) 객체가 찾는 id값을 가졌을 경우 바로 리턴한다. 해당 id값을 가지고 있지 않음과 동시에 children이라는 키워드를 가지고 있다면 getObjectById()에 해당 children 노드와 id값을 넘겨서 호출한다.

문제설명

...더보기

수많은 마라톤 선수들이 마라톤에 참여하였습니다. 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다.

마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어질 때, 완주하지 못한 선수의 이름을 return 하도록 solution 함수를 작성해주세요.

제한사항

...더보기
  • 마라톤 경기에 참여한 선수의 수는 1명 이상 100,000명 이하입니다.
  • completion의 길이는 participant의 길이보다 1 작습니다.
  • 참가자의 이름은 1개 이상 20개 이하의 알파벳 소문자로 이루어져 있습니다.
  • 참가자 중에는 동명이인이 있을 수 있습니다.

입출력 예

...더보기
participant completion return
[leo, kiki, eden] [eden, kiki] leo
[marina, josipa, nikola, vinko, filipa] [josipa, filipa, marina, nikola] vinko
[mislav, stanko, mislav, ana] [stanko, ana, mislav] mislav

Solution

function solution(participant, completion) {
    var answer = '';
    // 해쉬테이블에 participant 입력 key: name, value: false
    // 해쉬테이블에 입력 key: name, value: true
    let hashTable = new HashTable();
    
    for(let i=0 ; i<participant.length ; i++){
        hashTable.set(participant[i],false);
    }
    // participant를 넣어서 false인 key값 찾기 get()이용
    for(let i=0 ; i<completion.length ; i++){
        hashTable.modify(completion[i],true);
    }
    for(let i=0 ; i<participant.length ; i++){
        if(!hashTable.get(participant[i])) answer = participant[i];
        // 동명이인에 대한 처리를 해줘야한다.
    }
    return answer;
}

class HashTable{
    constructor(size = 100000){
        this.buckets = new Array(size);
        this.size = size;
    }
    hash(key){
        let hashcode = 0;
        for(let i=0 ; i<key.length ; i++){
            hashcode += key.charCodeAt(i);
        }
        return hashcode % this.size;
    }
    set(key, value){
        let index = this.hash(key);
        // 없으면 만들고
        if(!this.buckets[index]){
            this.buckets[index]=[];
        }
        this.buckets[index].push([key, value]);
        return index;        
    }
    //이미 존재하는 값 수정
    modify(key, value){
        let index = this.hash(key);
        
        for(let buckets of this.buckets[index]){
            if(buckets[0] === key && !buckets[1]){
                buckets[1] = value;
                break;
            }
        }
    }
    
    get(key){
        let Namelist =[];
        let output=true;
        let index = this.hash(key);
        if(!this.buckets[index]) return null;
        
        for(let buckets of this.buckets[index]){    
            if(buckets[0] === key){
                Namelist.push(buckets[1]);
            }
        }
        Namelist.forEach(function(ele){
            if(ele===false) output = false;
        });
        
        return output;
    }
}

 

 

출처: 프로그래머스

'Algorithm' 카테고리의 다른 글

[HackerRank_javascript] 1. Array _ New Year Chaos  (0) 2019.08.06

+ Recent posts