프로그래머스 : 모의고사 ( 함수형 프로그래밍 + 지연실행)

KHW·2021년 8월 13일
0

코딩테스트

목록 보기
5/17
post-custom-banner

문제

1. 일반 코드

function solution(answers) {
    let array1=[1,2,3,4,5];
    let array2=[2,1,2,3,2,4,2,5];
    let array3=[3,3,1,1,2,2,4,4,5,5];
    let i=0,count1=0,count2=0,count3=0,answer=[];
    for(let i=0;i<answers.length;i++)
        {
            if(array1[i%5]==answers[i])
                count1++;
            if(array2[i%8]==answers[i])
                count2++;
            if(array3[i%10]==answers[i])
                count3++;
        }
   var max = Math.max(count1,count2,count3);

    if (count1 === max) {answer.push(1)};
    if (count2 === max) {answer.push(2)};
    if (count3 === max) {answer.push(3)};


    return answer;
}

2. 지연 코드

const go = (...list) => reduce((a, f) => f(a), list);

const curry = (f) => (a, ..._) =>
  _.length ? f(a, ..._) : (..._) => f(a, ..._);

const reduce = curry((f, acc, iter) => {
  if (!iter) {
    iter = acc[Symbol.iterator]();
    acc = iter.next().value;
  }
  for (const a of iter) {
    acc = f(acc, a);
  }
  return acc;
});

const L = {};

// 일정 길이만큼 가져온다. (현재는 사용X)
L.range = function* (l) {
  let i = -1;
  while (++i < l) {
    yield i;
  }
};

// 배열만큼을 순회한다. (현재는 사용X)
L.map = curry(function* (f, iter) {
  for (const a of iter) yield f(a);
});

// 해당 값과 index 값을 배열로 받아온다.
L.arrAndIdx = curry(function* (f, iter) {
  var index = 0;
  for (const a of iter)
    if (f(a)) {
      yield [a, index++];
    }
});

// 함수를 만족하는 filter 값을 가져온다.
L.realFilter = curry(function* (f, iter) {
  for (const a of iter) {
          if (f(a)) {
            yield f(a);
          }
  }
});

//원하는 갯수만큼 지연 값을 가져온다
const take = curry((l, iter) => {
  let res = [];
  for (const a of iter) {
    res.push(a);
    if (res.length == l) return res;
  }
});

function solution(answers) {
    let array1=[1,2,3,4,5];
    let array2=[2,1,2,3,2,4,2,5];
    let array3=[3,3,1,1,2,2,4,4,5,5];
    let count1=0,count2=0,count3=0,answer=[];
    const answers_length = answers.length;
    
    const result = go(
                answers,
                L.arrAndIdx((n) => n),
                L.realFilter((n) => {
                             if(array1[n[1]%5]==n[0])
                                count1++;
                            if(array2[n[1]%8]==n[0])
                                count2++;
                            if(array3[n[1]%10]==n[0])
                            count3++;}),
                take(answers_length)
                )

    const max = Math.max(count1,count2,count3);
    if (count1 === max) {answer.push(1)};
    if (count2 === max) {answer.push(2)};
    if (count3 === max) {answer.push(3)};

    return answer;
}

배열의 arr과 idx를 받아와 filter를 통해 처리하고 해당 answers의 길이만큼 take를 진행하여 최대값 max를 찾고 맞으면 값을 넣어 결과를 리턴한다.

3. 지연코드 + 수정

  1. n[1] , n[0]은 가독성에 안좋으므로 배열이 아닌 객체로 처리했다.
  2. pipe 사용을 추가
const go = (...list) => reduce((a, f) => f(a), list);
const pipe = (...fs) => (a) => go(a, ...fs);
const curry = (f) => (a, ..._) =>
  _.length ? f(a, ..._) : (..._) => f(a, ..._);

const reduce = curry((f, acc, iter) => {
  if (!iter) {
    iter = acc[Symbol.iterator]();
    acc = iter.next().value;
  }
  for (const a of iter) {
    acc = f(acc, a);
  }
  return acc;
});

const L = {};

// 일정 길이만큼 가져온다. (현재는 사용X)
L.range = function* (l) {
  let i = -1;
  while (++i < l) {
    yield i;
  }
};

// 배열만큼을 순회한다. (현재는 사용X)
L.map = curry(function* (f, iter) {
  for (const a of iter) yield f(a);
});

// 해당 값과 index 값을 객체로 받아온다.
L.arrAndIdx = curry(function* (f, iter) {
  var index = 0;
  for (const a of iter)
    if (f(a)) {
      yield {val : a, idx : index++};
    }
});

// 함수를 만족하는 filter 값을 가져온다.
L.realFilter = curry(function* (f, iter) {
  for (const a of iter) {
          if (f(a)) {
            yield f(a);
          }
  }
});

//원하는 갯수만큼 지연 값을 가져온다
const take = curry((l, iter) => {
  let res = [];
  for (const a of iter) {
    res.push(a);
    if (res.length == l) return res;
  }
});

function solution(answers) {
    let array1=[1,2,3,4,5];
    let array2=[2,1,2,3,2,4,2,5];
    let array3=[3,3,1,1,2,2,4,4,5,5];
    let count1=0,count2=0,count3=0,answer=[];
    const answers_length = answers.length;
    
    const f = pipe(
                L.arrAndIdx((n) => n),
                L.realFilter((n) => {
                             if(array1[n.idx%5]==n.val)
                                count1++;
                            if(array2[n.idx%8]==n.val)
                                count2++;
                            if(array3[n.idx%10]==n.val)
                            count3++;}),
                take(answers_length)
                )
    f(answers);
    
    const max = Math.max(count1,count2,count3);
    if (count1 === max) {answer.push(1)};
    if (count2 === max) {answer.push(2)};
    if (count3 === max) {answer.push(3)};

    return answer;
}

위와 다르게 idx , val을 통해 가독성을 높였다.

profile
나의 하루를 가능한 기억하고 즐기고 후회하지말자
post-custom-banner

0개의 댓글