모의고사 / 완주하지 못한 선수 / 기능 개발 => 함수형 프로그래밍 코드작성

KHW·2021년 8월 14일
1

코딩테스트

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

기존내용

모의고사
완주하지 못한 선수
기능개발


1. generator.mjs

3개의 코드에 공통된 코드를 모듈화

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 take = curry((l, iter) => {
  let res = [];
  for (const a of iter) {
    res.push(a);
    if (res.length == 1) return res[0];
    if (res.length == l) return res;
  }
});

const L = {};

export {pipe,curry,take , L}

2. 모의고사

import {pipe,curry,take , L} from '../module/library/generator.mjs'

// 일정 길이만큼 가져온다. (현재는 사용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.filter = curry(function* (f, iter) {
  for (const a of iter) {
    if (f(a)) {
      yield f(a);
    }
  }
});

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.filter((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;
}

console.log(JSON.stringify(solution(	[1, 2, 3, 4, 5])) === JSON.stringify([1]))       //true
console.log(JSON.stringify(solution(	[1, 3, 2, 4, 2])) === JSON.stringify(	[1, 2, 3])) //true

3. 기능개발

import {pipe,curry,take , L} from '../module/library/generator.mjs'

// 배열만큼을 순회한다. (현재는 사용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++};
    }
});

// 함수를 만족하는 days와 idx를 객체 형태로 리턴.
L.getDaysAndIdx = curry(function* (f, iter) {
  for (const a of iter) {
    if (f(a)) {
      yield f(a);
    }
  }
});

// 함수를 만족하는 계산 처리
L.deploy = curry(function* (f, iter) {
  for (const a of iter) {
    if (f(a)) {
      yield f(a);
    }
  }
});

const takeAll = take(Infinity);

function solution(progresses, speeds) {
  const real = [];
  let max = -Infinity;
  let count = 0;

  const f = pipe(
    L.arrAndIdx(n => n),
    L.getDaysAndIdx(n => ({'days' : Math.ceil((100-n.val) / speeds[n.idx]), 'idx' : n.idx})),
    L.deploy(n => {
        if(n.days == max)
          count++;
        else{
          max = Math.max(n.days,max);
          if(n.idx == 0)
            count++;
          else if(n.days == max){
            real.push(count);
            count = 1;
          }
          else{
            count++;
          }
        }
      }
    ),
    takeAll)

  f(progresses);

  if(count != 0)      //남은 count도 추가
    real.push(count);

  return real;
}


console.log(JSON.stringify(solution(	[93, 30, 55], [1, 30, 5])) === JSON.stringify([2, 1]))
console.log(JSON.stringify(solution(		[95, 90, 99, 99, 80, 99], [1, 1, 1, 1, 1, 1])) === JSON.stringify([1, 3, 2]))
console.log(JSON.stringify(solution(		[99, 99, 99], [1, 1, 1])) === JSON.stringify([3]))
//true
//true
//true

4. 완주하지 못한 선수

import {pipe,curry,take,L} from '../module/library/generator.mjs'

// 일정 길이만큼 가져온다. (현재는 사용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.filter = curry(function* (f, iter) {
  for (const a of iter) {
    if (f(a)) {
      yield f(a);
    }
  }
});

function solution(participant, completion)
{
  participant.sort()
  completion.sort()

  const result = pipe(
    L.arrAndIdx((n) => n),
    L.filter((n) => {
      if(n.val !== completion[n.idx])
        return n.val;
    }),
    take(1)
  )

  return result(participant);
}


console.log(solution(	["leo", "kiki", "eden"], ["eden", "kiki"]) === 'leo')
console.log(solution(		["marina", "josipa", "nikola", "vinko", "filipa"], ["josipa", "filipa", "marina", "nikola"]) === 'vinko')
console.log(solution(			["mislav", "stanko", "mislav", "ana"], ["stanko", "ana", "mislav"]) === 	"mislav")

//true
//true
//true

중요하게 바라볼 것

새로만든 객체를 리턴하는 arrAndIdxgetDaysAndIdx를 통해
n.idx , n.days , n.val 이런 가독성을 높이게 만들었다.


느낀점

  • 어렵고 신기하다. 그래도 어렵다
profile
나의 하루를 가능한 기억하고 즐기고 후회하지말자
post-custom-banner

0개의 댓글