<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title></title>
    <description>
I'm a Junior Front-end Developer! I can use Javascript, React, Sass, Tailwind CSS and a little bit Node.js
</description>
    <link>https://owni14.github.io</link>
    <atom:link href="https://owni14.github.io/feed.xml" rel="self" type="application/rss+xml" />
	<lastBuildDate>Wed, 01 May 2024 00:00:00 +0900</lastBuildDate>
	
	<item>
		<title>[Js] 모던 자바스크립트 Deep Dive - 변수(4장)</title>
        
        
            <description>&lt;!-- prettier-ignore --&gt;
&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#변수란-무엇일까&quot; id=&quot;markdown-toc-변수란-무엇일까&quot;&gt;변수란 무엇일까?&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#변수-선언과-호이스팅&quot; id=&quot;markdown-toc-변수-선언과-호이스팅&quot;&gt;변수 선언과 호이스팅&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;변수란-무엇일까&quot;&gt;변수란 무엇일까?&lt;/h2&gt;

&lt;hr /&gt;

&lt;p&gt;프로그래밍을 하면서 가장 많이 접한 단어가 변수, 함수 단어가 아닐까 싶다. 나는 이번에 변수 챕터를 읽으면서 변수에 대해 몰랐던 것도 알게 되었다. 많이 접한 단어인데 정확한 개념을 모르고 있었단는 것을 알고 기초부터 차근차근 쌓아나가자는 생각을 많이하게 되었다.&lt;/p&gt;

&lt;p&gt;그렇다면 본론으로 돌아가서 변수란 정확한 어떤 뜻일까? &lt;strong&gt;변수란 하나의 값을 저장하기 위해 확보한 공간 자체 또는 그 메모리 공간을 식별하기 위해 붙인 이름&lt;/strong&gt;이라고 나와있다. 한마디로 변수를 사용해서 메모리 공간을 확보하고 해당 메모리 주소를 가리키는 식별자라고 생각하면 좋을꺼 같다.&lt;/p&gt;

&lt;h2 id=&quot;변수-선언과-호이스팅&quot;&gt;변수 선언과 호이스팅&lt;/h2&gt;

&lt;hr /&gt;

&lt;p&gt;변수를 사용하기 위해서는 &lt;strong&gt;반드시 선언이 필요&lt;/strong&gt;하다. 변수를 선언하기 위해서는 &lt;strong&gt;var&lt;/strong&gt;, &lt;strong&gt;const&lt;/strong&gt;, &lt;strong&gt;let&lt;/strong&gt;과 같은 키워드를 사용해서 선언한다. var, const, let키워드는 모두 차이점이 존재하는데 해당 키워드를 소개하는 챕터가 따로 존재해서 그 부분을 읽게 되면 다시 블로그에 정리해서 올리려고 한다.&lt;/p&gt;

&lt;p&gt;먼저 변수를 아래 코드와 같이 선언과 동시에 할당을 하거나 선언과 동시에 할당을 하거나 두 가지 방법이 존재한다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;var sum; // 변수 선언
sum = 50; // 변수 할당

var score = 50; // 변수 선언과 동시에 할당
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;인터프리터에 의해 소스 코드를 한 줄씩 실행이 되는데 선언부는 Javascript 메커니즘에 의해서 &lt;strong&gt;코드의 상단으로 끌어올려지는 호이스팅&lt;/strong&gt;이 발생한다. 변수인 var, let, const뿐만 아니라 function, class과 같은 키워드도 코드 상단으로 끌어올려진다.&lt;/p&gt;

&lt;p&gt;변수가 상단으로 끌어올려지면 값이 할당이 안되어 있기 때문에 &lt;strong&gt;undefined&lt;/strong&gt;가 할당되어 있을 것이다. 아래와 같이 콘솔을 찍게 되면 &lt;strong&gt;undefined&lt;/strong&gt;가 출력된다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;console.log(score)
var score = 10;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;변수는 선언과 동시에 메모리공간을 차지하게 되고 초기에는 undefined값이 할당되어 있을 것이다. 그 후 인터프리터에 의해 소스 코드를 한 줄씩 실행이 되며 할당이 되는데 그때 기존에 undefined가 할당되어 있던 메모리 공간을 지우고 메모리 공간에 할당하는게 아니라 새로운 메모리 공간을 확보하고 그곳에 새롭게 할당하게 된다. 이 부분은 나도 잘 몰랐던 부분이었다.&lt;/p&gt;

&lt;p&gt;그럼 undefined가 있던 메모리 공간은 어떻게 되나싶은 생각이 있을텐데 undefined 메모리 공간은 &lt;strong&gt;가비지 콜렉터&lt;/strong&gt;에 의해 정리되어지게 된다. 가비지 콜렉터란 &lt;strong&gt;애플리케이션이 할당한 메모리 공간을 주기적으로 검사하여 더 이상 사용되지 않는 메모리 공간을 해제하는 기능&lt;/strong&gt;을 의미한다.&lt;/p&gt;
</description>
        
        <pubDate>Wed, 01 May 2024 00:00:00 +0900</pubDate>
        <link>https://owni14.github.io/dev/js-modern-javascript.html</link>
        <guid isPermaLink="true">https://owni14.github.io/dev/js-modern-javascript.html</guid>
      </item>
    
	<item>
		<title>[LeetCode] Debounce</title>
        
        
            <description>&lt;!-- prettier-ignore --&gt;
&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#problems&quot; id=&quot;markdown-toc-problems&quot;&gt;PROBLEMS&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#description&quot; id=&quot;markdown-toc-description&quot;&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#example&quot; id=&quot;markdown-toc-example&quot;&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#constraints&quot; id=&quot;markdown-toc-constraints&quot;&gt;&lt;strong&gt;Constraints&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#solution&quot; id=&quot;markdown-toc-solution&quot;&gt;Solution&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#retrospect&quot; id=&quot;markdown-toc-retrospect&quot;&gt;Retrospect&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;problems&quot;&gt;PROBLEMS&lt;/h2&gt;

&lt;h3 id=&quot;description&quot;&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/h3&gt;

&lt;hr /&gt;

&lt;p&gt;Given a function fn and a time in milliseconds t, return a debounced version of that function.&lt;/p&gt;

&lt;p&gt;A debounced function is a function whose execution is delayed by t milliseconds and whose execution is cancelled if it is called again within that window of time. The debounced function should also receive the passed parameters.&lt;/p&gt;

&lt;p&gt;For example, let’s say t = 50ms, and the function was called at 30ms, 60ms, and 100ms.&lt;/p&gt;

&lt;p&gt;The first 2 function calls would be cancelled, and the 3rd function call would be executed at 150ms.&lt;/p&gt;

&lt;p&gt;If instead t = 35ms, The 1st call would be cancelled, the 2nd would be executed at 95ms, and the 3rd would be executed at 135ms.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../../../assets/img/development/2024/05/01/debounce.png&quot; alt=&quot;debounce&quot; /&gt;
The above diagram shows how debounce will transform events. Each rectangle represents 100ms and the debounce time is 400ms. Each color represents a different set of inputs.&lt;/p&gt;

&lt;p&gt;Please solve it without using lodash’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_.debounce()&lt;/code&gt; function.&lt;/p&gt;

&lt;h3 id=&quot;example&quot;&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/h3&gt;

&lt;hr /&gt;

&lt;p&gt;Example 1:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Input:&lt;br /&gt;
t = 50&lt;br /&gt;
calls = [&lt;br /&gt;
{“t”: 50, inputs: [1]},&lt;br /&gt;
{“t”: 75, inputs: [2]}&lt;br /&gt;
]&lt;br /&gt;
Output: [{“t”: 125, inputs: [2]}]&lt;br /&gt;
Explanation:&lt;br /&gt;
let start = Date.now();&lt;br /&gt;
function log(…inputs) {&lt;br /&gt;
console.log([Date.now() - start, inputs ])&lt;br /&gt;
}&lt;br /&gt;
const dlog = debounce(log, 50);&lt;br /&gt;
setTimeout(() =&amp;gt; dlog(1), 50);&lt;br /&gt;
setTimeout(() =&amp;gt; dlog(2), 75);&lt;/p&gt;

  &lt;p&gt;The 1st call is cancelled by the 2nd call because the 2nd call occurred before 100ms&lt;br /&gt;
The 2nd call is delayed by 50ms and executed at 125ms. The inputs were (2).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Example 2:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Input:&lt;br /&gt;
t = 20&lt;br /&gt;
calls = [&lt;br /&gt;
{“t”: 50, inputs: [1]},&lt;br /&gt;
{“t”: 100, inputs: [2]}&lt;br /&gt;
]&lt;br /&gt;
Output: [{“t”: 70, inputs: [1]}, {“t”: 120, inputs: [2]}]&lt;br /&gt;
Explanation:
The 1st call is delayed until 70ms. The inputs were (1).&lt;br /&gt;
The 2nd call is delayed until 120ms. The inputs were (2).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Example 3:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Input:&lt;br /&gt;
t = 150&lt;br /&gt;
calls = [&lt;br /&gt;
{“t”: 50, inputs: [1, 2]},&lt;br /&gt;
{“t”: 300, inputs: [3, 4]},&lt;br /&gt;
{“t”: 300, inputs: [5, 6]}&lt;br /&gt;
]&lt;br /&gt;
Output: [{“t”: 200, inputs: [1,2]}, {“t”: 450, inputs: [5, 6]}]&lt;br /&gt;
Explanation:&lt;br /&gt;
The 1st call is delayed by 150ms and ran at 200ms. The inputs were (1, 2).&lt;br /&gt;
The 2nd call is cancelled by the 3rd call&lt;br /&gt;
The 3rd call is delayed by 150ms and ran at 450ms. The inputs were (5, 6).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;constraints&quot;&gt;&lt;strong&gt;Constraints&lt;/strong&gt;&lt;/h3&gt;

&lt;hr /&gt;

&lt;ul&gt;
  &lt;li&gt;0 &amp;lt;= t &amp;lt;= 1000&lt;/li&gt;
  &lt;li&gt;1 &amp;lt;= calls.length &amp;lt;= 10&lt;/li&gt;
  &lt;li&gt;0 &amp;lt;= calls[i].t &amp;lt;= 1000&lt;/li&gt;
  &lt;li&gt;0 &amp;lt;= calls[i].inputs.length &amp;lt;= 10&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;solution&quot;&gt;Solution&lt;/h3&gt;

&lt;hr /&gt;

&lt;ul&gt;
  &lt;li&gt;Runtime: 56ms&lt;/li&gt;
  &lt;li&gt;Memory: 49.04MB&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/**
 * @param {Function} fn
 * @param {number} t milliseconds
 * @return {Function}
 */
var debounce = function (fn, t) {
    let timerId
    return function (...args) {
        clearTimeout(timerId)
        timerId = setTimeout(() =&amp;gt; fn(...args), t)
    }
};

/**
 * const log = debounce(console.log, 100);
 * log('Hello'); // cancelled
 * log('Hello'); // cancelled
 * log('Hello'); // Logged at t=100ms
 */
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;retrospect&quot;&gt;Retrospect&lt;/h3&gt;

&lt;hr /&gt;

&lt;p&gt;이번 문제는 debounce함수를 지속적으로 호출했을때, 파라미터로 받은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;t&lt;/code&gt; 밀리초보다 먼저 호출하게 되면 값을 반환하지 않고 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;t&lt;/code&gt; 밀리초동안 아무 호출이 없을 경우 반환하는 함수를 만드는 것이었다. 한마디로 설명하자면 시간간격을 두고 호출하는 함수였다.&lt;/p&gt;

&lt;p&gt;시간 간격을 두기 위해서라면 무조건 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setTimeout&lt;/code&gt;메서드가 필요하다고 생각했다. 그리고 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;timerId&lt;/code&gt;는 전역에 선언해두었는데 이렇게 한 이유가 계속해서 debounce함수를 호출했을때, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;t&lt;/code&gt;밀리초 이전에 함수를 계속 호출하게 되면 반환하는 함수에서 바로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;clearTimeout&lt;/code&gt;을 이용해 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setTimeout&lt;/code&gt;를 취소하기 위해 사용했다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;timerId&lt;/code&gt;를 전역으로 선언하지 않고 내부에서 선언하고 return할때 clearTimeout을 사용하게 된다면, 호출할때마다 매 호출 건에 대해 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;t&lt;/code&gt; 밀리초 delay가 되서 출력이 될 것이기 때문이다.&lt;/p&gt;
</description>
        
        <pubDate>Wed, 01 May 2024 00:00:00 +0900</pubDate>
        <link>https://owni14.github.io/dev/algorithm-Debounce.html</link>
        <guid isPermaLink="true">https://owni14.github.io/dev/algorithm-Debounce.html</guid>
      </item>
    
	<item>
		<title>[LeetCode] Promise Time Limit</title>
        
        
            <description>&lt;!-- prettier-ignore --&gt;
&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#problems&quot; id=&quot;markdown-toc-problems&quot;&gt;PROBLEMS&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#description&quot; id=&quot;markdown-toc-description&quot;&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#example&quot; id=&quot;markdown-toc-example&quot;&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#constraints&quot; id=&quot;markdown-toc-constraints&quot;&gt;&lt;strong&gt;Constraints&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#solution&quot; id=&quot;markdown-toc-solution&quot;&gt;Solution&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#retrospect&quot; id=&quot;markdown-toc-retrospect&quot;&gt;Retrospect&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#reference&quot; id=&quot;markdown-toc-reference&quot;&gt;Reference&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;problems&quot;&gt;PROBLEMS&lt;/h2&gt;

&lt;h3 id=&quot;description&quot;&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/h3&gt;

&lt;hr /&gt;

&lt;p&gt;Given an asynchronous function fn and a time t in milliseconds, return a new time limited version of the input function. fn takes arguments provided to the time limited function.&lt;/p&gt;

&lt;p&gt;The time limited function should follow these rules:&lt;/p&gt;

&lt;p&gt;If the fn completes within the time limit of t milliseconds, the time limited function should resolve with the result.
If the execution of the fn exceeds the time limit, the time limited function should reject with the string “Time Limit Exceeded”.&lt;/p&gt;

&lt;h3 id=&quot;example&quot;&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/h3&gt;

&lt;hr /&gt;

&lt;p&gt;Example 1:&lt;/p&gt;

&lt;!-- prettier-ignore --&gt;
&lt;blockquote&gt;
  &lt;p&gt;Input:&lt;br /&gt;
fn = async (n) =&amp;gt; {  &lt;br /&gt;
await new Promise(res =&amp;gt; setTimeout(res, 100)); &lt;br /&gt;
return n * n;&lt;br /&gt;
}&lt;br /&gt;
inputs = [5]&lt;br /&gt;
t = 50&lt;br /&gt;
Output: {“rejected”:”Time Limit Exceeded”,”time”:50}&lt;br /&gt;
Explanation:&lt;br /&gt;
const limited = timeLimit(fn, t)&lt;br /&gt;
const start = performance.now()&lt;br /&gt;
let result;&lt;br /&gt;
try {&lt;br /&gt;
const res = await limited(…inputs)&lt;br /&gt;
result = {“resolved”: res, “time”: Math.floor(performance.now() - start)};&lt;br /&gt;
} catch (err) {&lt;br /&gt;
result = {“rejected”: err, “time”: Math.floor(performance.now() - start)};&lt;br /&gt;
}&lt;br /&gt;
console.log(result) // Output&lt;br /&gt;
The provided function is set to resolve after 100ms. However, the time limit is set to 50ms. It rejects at t=50ms because the time limit was reached.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Example 2:&lt;/p&gt;

&lt;!-- prettier-ignore --&gt;
&lt;blockquote&gt;
  &lt;p&gt;Input:&lt;br /&gt;
fn = async (n) =&amp;gt; {&lt;br /&gt;
await new Promise(res =&amp;gt; setTimeout(res, 100));&lt;br /&gt;
return n * n;&lt;br /&gt;
}&lt;br /&gt;
inputs = [5]&lt;br /&gt;
t = 150&lt;br /&gt;
Output: {“resolved”:25,”time”:100}&lt;br /&gt;
Explanation:&lt;br /&gt;
The function resolved 5 _ 5 = 25 at t=100ms. The time limit is never reached.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Example 3:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Input:&lt;br /&gt;
fn = async (a, b) =&amp;gt; {&lt;br /&gt;
await new Promise(res =&amp;gt; setTimeout(res, 120));&lt;br /&gt;
return a + b;&lt;br /&gt;
}&lt;br /&gt;
inputs = [5,10]&lt;br /&gt;
t = 150&lt;br /&gt;
Output: {“resolved”:15,”time”:120}&lt;br /&gt;
Explanation:&lt;br /&gt;
​​​​The function resolved 5 + 10 = 15 at t=120ms. The time limit is never reached.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Example 4:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Input:&lt;br /&gt;
fn = async () =&amp;gt; {&lt;br /&gt;
throw “Error”;&lt;br /&gt;
}&lt;br /&gt;
inputs = []&lt;br /&gt;
t = 1000&lt;br /&gt;
Output: {“rejected”:”Error”,”time”:0}&lt;br /&gt;
Explanation:&lt;br /&gt;
The function immediately throws an error.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;constraints&quot;&gt;&lt;strong&gt;Constraints&lt;/strong&gt;&lt;/h3&gt;

&lt;hr /&gt;

&lt;ul&gt;
  &lt;li&gt;0 &amp;lt;= inputs.length &amp;lt;= 10&lt;/li&gt;
  &lt;li&gt;0 &amp;lt;= t &amp;lt;= 1000&lt;/li&gt;
  &lt;li&gt;fn returns a promise&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;solution&quot;&gt;Solution&lt;/h3&gt;

&lt;hr /&gt;

&lt;ul&gt;
  &lt;li&gt;Runtime: 54ms&lt;/li&gt;
  &lt;li&gt;Memory: 49.05MB&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/**
 * @param {Function} fn
 * @param {number} t
 * @return {Function}
 */
 // Solution1
var timeLimit = function (fn, t) {
    return async function (...args) {

        const timeoutPromise = new Promise((_, reject) =&amp;gt; {
            setTimeout(() =&amp;gt; { reject('Time Limit Exceeded') }, t);
        })

        return Promise.race([fn(...args), timeoutPromise]);
    }
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;retrospect&quot;&gt;Retrospect&lt;/h3&gt;

&lt;hr /&gt;

&lt;p&gt;이번 문제는 온전히 나의 힘으로 풀지 못했고 풀이에 의존해야했다. 문제를 해석하자면, fn함수에 있는 setTimeout의 시간보다 파라미터를 통해 넘겨준 t시간이 더 크면 setTimeout을 실행시킨 값을 반환하면 되고 아니면 에러를 반환하면 됐다. 일단 문제를 보면 resolve로 실행된 &lt;strong&gt;Fn함수&lt;/strong&gt;와 reject로 &lt;strong&gt;‘Time Limit Exceeded’&lt;/strong&gt;를 반환하는 문제였기 때문에 new Promise를 새로 생성해서 &lt;strong&gt;Promise&lt;/strong&gt;를 반환하자는 생각을 하였다.&lt;/p&gt;

&lt;p&gt;그런데 나는 new Promise 안쪽에서 setTimeout를 선언하긴 했는데 setTimeout함수에 Fn함수를 같이 넣어서 자꾸 이상하게 문제를 푸는 것이었다. 계속 고민하다가 이 방법은 아닌거 같아서 풀이를 보니 new Promise안쪽에서 setTimeout은 Fn함수를 넣을게 아니라 그냥 reject로 에러를 넘겨주고 받아온 t밀리초 만큼 딜레이를 주면 되는 것이었다. fn함수는 그냥 Promise.race에 넘겨주면 끝이었다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Promise.race&lt;/code&gt;란 &lt;strong&gt;iterable 안에 있는 프로미스 중에 가장 먼저 완료된 것의 결과값으로 그대로 이행하거나 거부합니다.&lt;/strong&gt;라고 문서에 나와있다. 그 말은 즉, new Promise로 만들어준 setTimeout이 먼저 끝나면 reject가 반환 될 것이고 그게 아니라면 Fn함수에서 실행한 setTimeout이 Promise로 반환 될 것이다.&lt;/p&gt;

&lt;p&gt;이번에 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Promise.race&lt;/code&gt;라는 메서드를 처음 알게 되었는데 실제로 현업에서 나는 사용해본적이 없지만 되게 유용하게 사용할 수 있을꺼 같은 느낌이 든다.&lt;/p&gt;

&lt;h3 id=&quot;reference&quot;&gt;Reference&lt;/h3&gt;

&lt;hr /&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise/race&quot;&gt;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise/race&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        
        <pubDate>Tue, 30 Apr 2024 00:00:00 +0900</pubDate>
        <link>https://owni14.github.io/dev/algorithm-Promise-Time-Limit.html</link>
        <guid isPermaLink="true">https://owni14.github.io/dev/algorithm-Promise-Time-Limit.html</guid>
      </item>
    
	<item>
		<title>[LeetCode](Linked List) Convert Binary Number in a Linked List to Integer</title>
        
        
            <description>&lt;!-- prettier-ignore --&gt;
&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#problems&quot; id=&quot;markdown-toc-problems&quot;&gt;PROBLEMS&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#description&quot; id=&quot;markdown-toc-description&quot;&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#example&quot; id=&quot;markdown-toc-example&quot;&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#constraints&quot; id=&quot;markdown-toc-constraints&quot;&gt;&lt;strong&gt;Constraints&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#solution&quot; id=&quot;markdown-toc-solution&quot;&gt;Solution&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#retrospect&quot; id=&quot;markdown-toc-retrospect&quot;&gt;Retrospect&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;problems&quot;&gt;PROBLEMS&lt;/h2&gt;

&lt;h3 id=&quot;description&quot;&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/h3&gt;

&lt;hr /&gt;

&lt;p&gt;Given head which is a reference node to a singly-linked list. The value of each node in the linked list is either 0 or 1. The linked list holds the binary representation of a number.&lt;/p&gt;

&lt;p&gt;Return the decimal value of the number in the linked list.&lt;/p&gt;

&lt;p&gt;The most significant bit is at the head of the linked list.&lt;/p&gt;

&lt;h3 id=&quot;example&quot;&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/h3&gt;

&lt;hr /&gt;

&lt;p&gt;Example 1:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../../../assets/img/development/2024/04/29/linked-list.png&quot; alt=&quot;linked-list&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Input: head = [1,0,1]&lt;br /&gt;
Output: 5&lt;br /&gt;
Explanation: (101) in base 2 = (5) in base 10&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Example 2:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Input: head = [0]&lt;br /&gt;
Output: 0&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;constraints&quot;&gt;&lt;strong&gt;Constraints&lt;/strong&gt;&lt;/h3&gt;

&lt;hr /&gt;

&lt;ul&gt;
  &lt;li&gt;The Linked List is not empty.&lt;/li&gt;
  &lt;li&gt;Number of nodes will not exceed 30.&lt;/li&gt;
  &lt;li&gt;Each node’s value is either 0 or 1.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;solution&quot;&gt;Solution&lt;/h3&gt;

&lt;hr /&gt;

&lt;ul&gt;
  &lt;li&gt;Runtime: 58ms&lt;/li&gt;
  &lt;li&gt;Memory: 51.54MB&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/**
 * Definition for singly-linked list.
 * class ListNode {
 *     val: number
 *     next: ListNode | null
 *     constructor(val?: number, next?: ListNode | null) {
 *         this.val = (val===undefined ? 0 : val)
 *         this.next = (next===undefined ? null : next)
 *     }
 * }
 */

// My Solution
function getDecimalValue(head: ListNode | null): number {
    let current: ListNode = head
    let sum = 0
    const valList = []

    while (current !== null) {
        valList.push(current.val)
        current = current.next
    }

    valList.reverse().map((val: number, idx: number) =&amp;gt; {
        if(val === 1) {
            sum += 2 ** idx
        }
    })

    return sum
};

// Another Solution
function getDecimalValue(head: ListNode | null): number {
    let current: ListNode = head
    let binary = &quot;&quot;

    while (current !== null) {
        binary += current.val
        current = current.next
    }

    return parseInt(binary, 2)
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;retrospect&quot;&gt;Retrospect&lt;/h3&gt;

&lt;hr /&gt;

&lt;p&gt;자료구조에 대해서 학습할 필요가 있을꺼 같아 이번에 Linked List에 대해서 문제를 풀었다. 내가 푼 문제는 Linked List중에 쉽고 정답률이 높은 편이었지만 나한테는 처음 접하는 Linked List의 알고리즘 문제였고 생각보다 어렵게만 다가왔었다. 그리고 Linked List의 Node, next등의 개념이 처음에는 잘 이해가 되지 않았다.&lt;/p&gt;

&lt;p&gt;그렇지만 계속해서 이해할려고하고 보다보니 어느정도 이해는 된거 같다. 대략적으로 설명하자면, &lt;strong&gt;head&lt;/strong&gt;라는 것은 Linked List에서 가장 처음 위치하는 노드를 가리키며 리스트 전체를 참조하는데 사용된다. &lt;strong&gt;Node&lt;/strong&gt;라는 것은 데이터를 저장하는 데이터 필드와 다음 노드를 가리키는 링크 필드로 구성되어 있다. 문제에서 next라는 것이 다음 노드를 가리키는 링크 필드인 것이다.&lt;/p&gt;

&lt;p&gt;문제의 내용을 살펴보면 [1, 0, 1]과 같이 데이터가 들어올때, 배열이 ListNode로 변환되어서 들어오는거 같은데 해당 부분은 좀 더 찾아봐야할꺼 같다. 하여튼 배열이 들어오게 되면 101을 이진수로 바꾸면 되는 문제였다. 여기서 제일 처음에 나는 101을 그냥 순서대로 2의 0승, 2의 1승으로 계산했었는데 알고 보니 반대로 뒤집어서 문제를 풀어야했다. 그래서 while문을 통해 무한 반복을 하는데 current를 current.next로 할당하면서 다음 노드로 자꾸 옮겨가게 했으며, valList라는 변수에 데이터를 누적해서 담아주었다.&lt;/p&gt;

&lt;p&gt;그 후, reverse와 map을 이용해서 배열을 반대로 뒤집었고 반복을 했다. 반복문을 통해 1인 경우에 해당 인덱스를 2의 인덱스승수를 계속해서 sum에 누적해서 더해 나갔고 마지막엔 sum을 반환해 답을 찾아냈다.&lt;/p&gt;

&lt;p&gt;문제를 다 풀고 난 후, 다른 사람의 풀이를 보니 각 노드를 순회하면서 binary라는 변수를 통해 값을 누적해서 더한 다음 parseInt를 통해 이진수로 정말 간단하게 변형하는 것이었다. 이번 기회를 통해 좀 더 쉽게 구하는 방법을 알아가는 계기가 되었다.&lt;/p&gt;
</description>
        
        <pubDate>Mon, 29 Apr 2024 00:00:00 +0900</pubDate>
        <link>https://owni14.github.io/dev/algorithm-linkedlist-1290.html</link>
        <guid isPermaLink="true">https://owni14.github.io/dev/algorithm-linkedlist-1290.html</guid>
      </item>
    
	<item>
		<title>[LeetCode] Interval Cancellation</title>
        
        
            <description>&lt;!-- prettier-ignore --&gt;
&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#problems&quot; id=&quot;markdown-toc-problems&quot;&gt;PROBLEMS&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#description&quot; id=&quot;markdown-toc-description&quot;&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#example&quot; id=&quot;markdown-toc-example&quot;&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#constraints&quot; id=&quot;markdown-toc-constraints&quot;&gt;&lt;strong&gt;Constraints&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#solution&quot; id=&quot;markdown-toc-solution&quot;&gt;Solution&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#retrospect&quot; id=&quot;markdown-toc-retrospect&quot;&gt;Retrospect&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;problems&quot;&gt;PROBLEMS&lt;/h2&gt;

&lt;h3 id=&quot;description&quot;&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/h3&gt;

&lt;hr /&gt;

&lt;p&gt;Given a function fn, an array of arguments args, and an interval time t, return a cancel function cancelFn.&lt;/p&gt;

&lt;p&gt;After a delay of cancelTimeMs, the returned cancel function cancelFn will be invoked.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;setTimeout(cancelFn, cancelTimeMs)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The function fn should be called with args immediately and then called again every t milliseconds until cancelFn is called at cancelTimeMs ms.&lt;/p&gt;

&lt;h3 id=&quot;example&quot;&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/h3&gt;

&lt;hr /&gt;

&lt;p&gt;Example 1:&lt;/p&gt;

&lt;!-- prettier-ignore --&gt;
&lt;blockquote&gt;
  &lt;p&gt;Input: fn = (x) =&amp;gt; x _ 2, args = [4], t = 35&lt;br /&gt;
Output:&lt;br /&gt;
[&lt;/p&gt;

  &lt;p&gt;{“time”: 0, “returned”: 8},
 {“time”: 35, “returned”: 8},
 {“time”: 70, “returned”: 8},
 { “time”: 105, “returned”: 8},
 {“time”: 140, “returned”: 8},
 {“time”: 175, “returned”: 8}
]&lt;br /&gt;
 Explanation:&lt;br /&gt;
const cancelTimeMs = 190;&lt;br /&gt;
const cancelFn = cancellable((x) =&amp;gt; x _ 2, [4], 35);&lt;br /&gt;
setTimeout(cancelFn, cancelTimeMs);&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;Every 35ms, fn(4) is called. Until t=190ms, then it is cancelled.&lt;br /&gt;
1st fn call is at 0ms. fn(4) returns 8.&lt;br /&gt;
2nd fn call is at 35ms. fn(4) returns 8.&lt;br /&gt;
3rd fn call is at 70ms. fn(4) returns 8.&lt;br /&gt;
4th fn call is at 105ms. fn(4) returns 8.&lt;br /&gt;
5th fn call is at 140ms. fn(4) returns 8.&lt;br /&gt;
6th fn call is at 175ms. fn(4) returns 8.&lt;br /&gt;
Cancelled at 190ms&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Example 2:&lt;/p&gt;

&lt;!-- prettier-ignore --&gt;
&lt;blockquote&gt;
  &lt;p&gt;Input: fn = (x1, x2) =&amp;gt; (x1 _ x2), args = [2, 5], t = 30&lt;br /&gt;
Output:&lt;br /&gt;
[&lt;/p&gt;

  &lt;p&gt;{“time”: 0, “returned”: 10},
{“time”: 30, “returned”: 10},
{“time”: 60, “returned”: 10},
{“time”: 90, “returned”: 10},
{“time”: 120, “returned”: 10},
{“time”: 150, “returned”: 10}
]&lt;br /&gt;
Explanation:&lt;br /&gt;
const cancelTimeMs = 165;&lt;br /&gt;
const cancelFn = cancellable((x1, x2) =&amp;gt; (x1 _ x2), [2, 5], 30)&lt;br /&gt;
setTimeout(cancelFn, cancelTimeMs)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;Every 30ms, fn(2, 5) is called. Until t=165ms, then it is cancelled.&lt;br /&gt;
1st fn call is at 0ms&lt;br /&gt;
2nd fn call is at 30ms&lt;br /&gt;
3rd fn call is at 60ms&lt;br /&gt;
4th fn call is at 90ms&lt;br /&gt;
5th fn call is at 120ms&lt;br /&gt;
6th fn call is at 150ms&lt;br /&gt;
Cancelled at 165ms&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Example 3:&lt;/p&gt;

&lt;!-- prettier-ignore --&gt;
&lt;blockquote&gt;
  &lt;p&gt;Input: fn = (x1, x2, x3) =&amp;gt; (x1 + x2 + x3), args = [5, 1, 3], t = 50&lt;br /&gt;
Output: &lt;br /&gt;
[&lt;br /&gt;
 {“time”: 0, “returned”: 9},&lt;br /&gt;
 {“time”: 50, “returned”: 9},&lt;br /&gt;
 {“time”: 100, “returned”: 9},&lt;br /&gt;
 {“time”: 150, “returned”: 9}&lt;br /&gt;
]&lt;br /&gt;
Explanation: &lt;br /&gt;
const cancelTimeMs = 180;&lt;br /&gt;
const cancelFn = cancellable((x1, x2, x3) =&amp;gt; (x1 + x2 + x3), [5, 1, 3], 50)&lt;br /&gt;
setTimeout(cancelFn, cancelTimeMs)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;Every 50ms, fn(5, 1, 3) is called. Until t=180ms, then it is cancelled.&lt;br /&gt;
1st fn call is at 0ms&lt;br /&gt;
2nd fn call is at 50ms&lt;br /&gt;
3rd fn call is at 100ms&lt;br /&gt;
4th fn call is at 150ms&lt;br /&gt;
Cancelled at 180ms&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;constraints&quot;&gt;&lt;strong&gt;Constraints&lt;/strong&gt;&lt;/h3&gt;

&lt;hr /&gt;

&lt;ul&gt;
  &lt;li&gt;fn is a function&lt;/li&gt;
  &lt;li&gt;args is a valid JSON array&lt;/li&gt;
  &lt;li&gt;1 &amp;lt;= args.length &amp;lt;= 10&lt;/li&gt;
  &lt;li&gt;30 &amp;lt;= t &amp;lt;= 100&lt;/li&gt;
  &lt;li&gt;10 &amp;lt;= cancelTimeMs &amp;lt;= 500&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;solution&quot;&gt;Solution&lt;/h3&gt;

&lt;hr /&gt;

&lt;ul&gt;
  &lt;li&gt;Runtime: 63ms&lt;/li&gt;
  &lt;li&gt;Memory: 49.82MB&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/**
 * @param {Function} fn
 * @param {Array} args
 * @param {number} t
 * @return {Function}
 */
var cancellable = function(fn, args, t) {
    fn(...args);

    const timeout = setInterval(() =&amp;gt; {
        fn(...args)
    }, t);

    return function cancel() {
        clearInterval(timeout);
    }
};

/**
 *  const result = [];
 *
 *  const fn = (x) =&amp;gt; x * 2;
 *  const args = [4], t = 35, cancelTimeMs = 190;
 *
 *  const start = performance.now();
 *
 *  const log = (...argsArr) =&amp;gt; {
 *      const diff = Math.floor(performance.now() - start);
 *      result.push({&quot;time&quot;: diff, &quot;returned&quot;: fn(...argsArr)});
 *  }
 *
 *  const cancel = cancellable(log, args, t);
 *
 *  setTimeout(cancel, cancelTimeMs);
 *
 *  setTimeout(() =&amp;gt; {
 *      console.log(result); // [
 *                           //     {&quot;time&quot;:0,&quot;returned&quot;:8},
 *                           //     {&quot;time&quot;:35,&quot;returned&quot;:8},
 *                           //     {&quot;time&quot;:70,&quot;returned&quot;:8},
 *                           //     {&quot;time&quot;:105,&quot;returned&quot;:8},
 *                           //     {&quot;time&quot;:140,&quot;returned&quot;:8},
 *                           //     {&quot;time&quot;:175,&quot;returned&quot;:8}
 *                           // ]
 *  }, cancelTimeMs + t + 15)
 */
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;retrospect&quot;&gt;Retrospect&lt;/h3&gt;

&lt;hr /&gt;

&lt;p&gt;이전에 풀었던 setTimeout이랑 비슷한 유형의 문제같다는 생각을 했다. setTimeout으로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cancelTimeMs&lt;/code&gt;변수의 시간이 끝난 후, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cancelFn&lt;/code&gt;를 실행시키면 되는 문제였기 때문에 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cancelFn&lt;/code&gt;안에서는 interval을 멈추는 함수를 실행해주었다.&lt;/p&gt;

&lt;p&gt;제일 처음 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cancellable&lt;/code&gt;함수에 값을 넘겨주면 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cancellable&lt;/code&gt;안쪽에서는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setInterval&lt;/code&gt;함수를 호출해서 계속해서 interval을 하게끔 만들어주었다. 처음에 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cancellable&lt;/code&gt;함수에 생설될때 time은 0이 될텐데 setInterval로만 실행하게 되면 time이 0일때는 실행이 안되어서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fn(...args)&lt;/code&gt;로 따로 빼서 한번 실행해주었다.&lt;/p&gt;

&lt;p&gt;마지막 반환값으로는 interval을 멈추는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;clearInterval&lt;/code&gt;함수를 호출하여 외부에서 setTimeout이 호출될때 interval을 중지시키므로써 문제에서 요구하는 답을 추출하게끔 했다.&lt;/p&gt;
</description>
        
        <pubDate>Sun, 28 Apr 2024 00:00:00 +0900</pubDate>
        <link>https://owni14.github.io/dev/algorithm-Interval-Cancellation.html</link>
        <guid isPermaLink="true">https://owni14.github.io/dev/algorithm-Interval-Cancellation.html</guid>
      </item>
    
	<item>
		<title>[LeetCode] Timeout Cancellation</title>
        
        
            <description>&lt;!-- prettier-ignore --&gt;
&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#problems&quot; id=&quot;markdown-toc-problems&quot;&gt;PROBLEMS&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#description&quot; id=&quot;markdown-toc-description&quot;&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#example&quot; id=&quot;markdown-toc-example&quot;&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#constraints&quot; id=&quot;markdown-toc-constraints&quot;&gt;&lt;strong&gt;Constraints&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#solution&quot; id=&quot;markdown-toc-solution&quot;&gt;Solution&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#retrospect&quot; id=&quot;markdown-toc-retrospect&quot;&gt;Retrospect&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;problems&quot;&gt;PROBLEMS&lt;/h2&gt;

&lt;h3 id=&quot;description&quot;&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/h3&gt;

&lt;hr /&gt;

&lt;p&gt;Given a function fn, an array of arguments args, and a timeout t in milliseconds, return a cancel function cancelFn.&lt;/p&gt;

&lt;p&gt;After a delay of cancelTimeMs, the returned cancel function cancelFn will be invoked.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;setTimeout(cancelFn, cancelTimeMs)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Initially, the execution of the function fn should be delayed by t milliseconds.&lt;/p&gt;

&lt;p&gt;If, before the delay of t milliseconds, the function cancelFn is invoked, it should cancel the delayed execution of fn. Otherwise, if cancelFn is not invoked within the specified delay t, fn should be executed with the provided args as arguments.&lt;/p&gt;

&lt;h3 id=&quot;example&quot;&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/h3&gt;

&lt;hr /&gt;

&lt;p&gt;Example 1:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Input: fn = (x) =&amp;gt; x _ 5, args = [2], t = 20&lt;br /&gt;
Output: [{“time”: 20, “returned”: 10}]&lt;br /&gt;
Explanation:&lt;br /&gt;
const cancelTimeMs = 50;&lt;br /&gt;
const cancelFn = cancellable((x) =&amp;gt; x _ 5, [2], 20);&lt;br /&gt;
setTimeout(cancelFn, cancelTimeMs);&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;The cancellation was scheduled to occur after a delay of cancelTimeMs (50ms), which happened after the execution of fn(2) at 20ms.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Example 2:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Input: fn = (x) =&amp;gt; x&lt;strong&gt;2, args = [2], t = 100&lt;br /&gt;
Output: []&lt;br /&gt;
Explanation:&lt;br /&gt;
const cancelTimeMs = 50;&lt;br /&gt;
const cancelFn = cancellable((x) =&amp;gt; x&lt;/strong&gt;2, [2], 100);&lt;br /&gt;
setTimeout(cancelFn, cancelTimeMs);&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;The cancellation was scheduled to occur after a delay of cancelTimeMs (50ms), which happened before the execution of fn(2) at 100ms, resulting in fn(2) never being called.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Example 3:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Input: fn = (x1, x2) =&amp;gt; x1 _ x2, args = [2,4], t = 30&lt;br /&gt;
Output: [{“time”: 30, “returned”: 8}]&lt;br /&gt;
Explanation:&lt;br /&gt;
const cancelTimeMs = 100;&lt;br /&gt;
const cancelFn = cancellable((x1, x2) =&amp;gt; x1 _ x2, [2,4], 30);&lt;br /&gt;
setTimeout(cancelFn, cancelTimeMs);&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;The cancellation was scheduled to occur after a delay of cancelTimeMs (100ms), which happened after the execution of fn(2,4) at 30ms.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;constraints&quot;&gt;&lt;strong&gt;Constraints&lt;/strong&gt;&lt;/h3&gt;

&lt;hr /&gt;

&lt;ul&gt;
  &lt;li&gt;fn is a function&lt;/li&gt;
  &lt;li&gt;args is a valid JSON array&lt;/li&gt;
  &lt;li&gt;1 &amp;lt;= args.length &amp;lt;= 10&lt;/li&gt;
  &lt;li&gt;20 &amp;lt;= t &amp;lt;= 1000&lt;/li&gt;
  &lt;li&gt;10 &amp;lt;= cancelTimeMs &amp;lt;= 1000&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;solution&quot;&gt;Solution&lt;/h3&gt;

&lt;hr /&gt;

&lt;ul&gt;
  &lt;li&gt;Runtime: 58ms&lt;/li&gt;
  &lt;li&gt;Memory: 49.49MB&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/**
 * @param {Function} fn
 * @param {Array} args
 * @param {number} t
 * @return {Function}
 */
var cancellable = function (fn, args, t) {
    const timer = setTimeout(() =&amp;gt; {
        fn(...args)
    }, t)

    return ()=&amp;gt; {
        clearTimeout(timer)
    }
};

/**
 *  const result = [];
 *
 *  const fn = (x) =&amp;gt; x * 5;
 *  const args = [2], t = 20, cancelTimeMs = 50;
 *
 *  const start = performance.now();
 *
 *  const log = (...argsArr) =&amp;gt; {
 *      const diff = Math.floor(performance.now() - start);
 *      result.push({&quot;time&quot;: diff, &quot;returned&quot;: fn(...argsArr)});
 *  }
 *
 *  const cancel = cancellable(log, args, t);
 *
 *  const maxT = Math.max(t, cancelTimeMs);
 *
 *  setTimeout(cancel, cancelTimeMs);
 *
 *  setTimeout(() =&amp;gt; {
 *      console.log(result); // [{&quot;time&quot;:20,&quot;returned&quot;:10}]
 *  }, maxT + 15)
 */
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;retrospect&quot;&gt;Retrospect&lt;/h3&gt;

&lt;hr /&gt;

&lt;p&gt;이번 문제는 솔직히 오로지 나 혼자만의 힘으로 푼게 아니다.. 구글링을 통해 setTimeout과 clearTimeout을 검색해서 헷갈리거나 자세하게 알지 못했던 내용을 이해하고 문제를 풀었다. &lt;strong&gt;setTimeout&lt;/strong&gt;, &lt;strong&gt;clearTimeout&lt;/strong&gt; 간단하게 요약하자면 &lt;strong&gt;setTimeout&lt;/strong&gt;같은 경우 &lt;strong&gt;일정 시간이 지난 후에 실행&lt;/strong&gt;되는 함수이고, &lt;strong&gt;clearTimeout&lt;/strong&gt;은 s&lt;strong&gt;etTimeout함수를 취소하고 싶을때&lt;/strong&gt; 사용하는 함수이다.&lt;/p&gt;

&lt;p&gt;먼저, 문제의 설명을 살펴보면 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cancellable&lt;/code&gt;함수는 파라미터로 받는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;t&lt;/code&gt;만큼 시간 지연을 두고 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fn&lt;/code&gt;함수를 실행해야하는 함수이다. 그러나 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cancellable&lt;/code&gt;외부에서는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setTimeou&lt;/code&gt;함수를 통해 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cancelTimeMs&lt;/code&gt;만큼 시간 지연을 하게 되는데, 만약 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cancellable&lt;/code&gt;함수로 넘겨준 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;t&lt;/code&gt;보다 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cancelTimeMs&lt;/code&gt;가 작을 경우 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fn&lt;/code&gt;함수는 실행하면 안되고 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;t&lt;/code&gt;가 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cancelTimeMs&lt;/code&gt;보다 더 크게 될 경우 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fn&lt;/code&gt;함수를 실행시키면 된다. 설명이 좀 어렵다고 느껴질 수 있는데 차근차근 풀이를 살펴보도록 하자.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cancellable&lt;/code&gt;함수에서는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;t&lt;/code&gt;만큼의 시간 지연이 필요하니 무조건 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setTimeout&lt;/code&gt;함수를 사용해야한다. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setTimeout&lt;/code&gt;함수 &lt;strong&gt;timerId&lt;/strong&gt;를 반환하게 되는데 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setTimeout&lt;/code&gt;을 취소 하고 싶을때 필요하기 때문에 timer라는 변수로 따로 선언해두었다. 반환 값으로는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;clearTimeout&lt;/code&gt;함수를 사용했는데, 외부에서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setTimeout&lt;/code&gt;함수를 실행할때 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;t&lt;/code&gt;보다 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cancelTimeMs&lt;/code&gt;가 작을 경우 내부의 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setTimeout&lt;/code&gt;을 실행시키면 안되기 때문에 실행되기 전에 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;clearTimeout&lt;/code&gt;을 통해 실행되지 않게 했다.&lt;/p&gt;

&lt;p&gt;이번은 좀 더 깊게 생각하고 문제에 접근하는 계기가 된거 같다. 난이도는 &lt;strong&gt;easy&lt;/strong&gt;로 표시되어 있었으나 나는 그렇게 쉬운 문제였던게 아니었다. js 개념이나 동작원리에 대한 이해도가 낮구나라는 생각을 많이해서 조금씩 쌓아가면 개발해야겠다고 생각을 많이 하게되었다.&lt;/p&gt;
</description>
        
        <pubDate>Sat, 27 Apr 2024 00:00:00 +0900</pubDate>
        <link>https://owni14.github.io/dev/algorithm-Timeout-Cancellation.html</link>
        <guid isPermaLink="true">https://owni14.github.io/dev/algorithm-Timeout-Cancellation.html</guid>
      </item>
    
	<item>
		<title>[LeetCode] Sleep</title>
        
        
            <description>&lt;!-- prettier-ignore --&gt;
&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#problems&quot; id=&quot;markdown-toc-problems&quot;&gt;PROBLEMS&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#description&quot; id=&quot;markdown-toc-description&quot;&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#example&quot; id=&quot;markdown-toc-example&quot;&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#constraints&quot; id=&quot;markdown-toc-constraints&quot;&gt;&lt;strong&gt;Constraints&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#solution&quot; id=&quot;markdown-toc-solution&quot;&gt;Solution&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#retrospect&quot; id=&quot;markdown-toc-retrospect&quot;&gt;Retrospect&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;problems&quot;&gt;PROBLEMS&lt;/h2&gt;

&lt;h3 id=&quot;description&quot;&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/h3&gt;

&lt;hr /&gt;

&lt;p&gt;Given a positive integer millis, write an asynchronous function that sleeps for millis milliseconds. It can resolve any value.&lt;/p&gt;

&lt;h3 id=&quot;example&quot;&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/h3&gt;

&lt;hr /&gt;

&lt;p&gt;Example 1:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Input: millis = 100&lt;br /&gt;
Output: 100&lt;br /&gt;
Explanation: It should return a promise that resolves after 100ms.&lt;br /&gt;
let t = Date.now();&lt;br /&gt;
sleep(100).then(() =&amp;gt; { console.log(Date.now() - t); // 100 });&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Example 2:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Input: millis = 200&lt;br /&gt;
Output: 200&lt;br /&gt;
Explanation: It should return a promise that resolves after 200ms.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;constraints&quot;&gt;&lt;strong&gt;Constraints&lt;/strong&gt;&lt;/h3&gt;

&lt;hr /&gt;

&lt;ul&gt;
  &lt;li&gt;1 &amp;lt;= millis &amp;lt;= 1000&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;solution&quot;&gt;Solution&lt;/h3&gt;

&lt;hr /&gt;

&lt;ul&gt;
  &lt;li&gt;Runtime: 51ms&lt;/li&gt;
  &lt;li&gt;Memory: 49MB&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/**
 * @param {number} millis
 * @return {Promise}
 */
async function sleep(millis) {
    return new Promise((resolve) =&amp;gt; {
        setTimeout(() =&amp;gt;{
            resolve(millis)
        }, millis)
    })
}

/**
 * let t = Date.now()
 * sleep(100).then(() =&amp;gt; console.log(Date.now() - t)) // 100
 */
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;retrospect&quot;&gt;Retrospect&lt;/h3&gt;

&lt;hr /&gt;

&lt;p&gt;양의 정수가 파라미터로 들어오면 들어온 파라미터만큼 뒤에 실행되는 Promise객체를 반환하면 되는 문제였고 반환 값은 어떤 것이든 상관 없었다. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;new Promise&lt;/code&gt;를 이용해서 Promise 객체를 생성한 후 setTimeout으로 파라미터로 들어온 양의 정수로 시간 간격을 두고 값을 반환해주었다.&lt;/p&gt;
</description>
        
        <pubDate>Fri, 26 Apr 2024 00:00:00 +0900</pubDate>
        <link>https://owni14.github.io/dev/algorithm-Sleep.html</link>
        <guid isPermaLink="true">https://owni14.github.io/dev/algorithm-Sleep.html</guid>
      </item>
    
	<item>
		<title>[LeetCode] Add Two Promises</title>
        
        
            <description>&lt;!-- prettier-ignore --&gt;
&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#problems&quot; id=&quot;markdown-toc-problems&quot;&gt;PROBLEMS&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#description&quot; id=&quot;markdown-toc-description&quot;&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#example&quot; id=&quot;markdown-toc-example&quot;&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#constraints&quot; id=&quot;markdown-toc-constraints&quot;&gt;&lt;strong&gt;Constraints&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#solution&quot; id=&quot;markdown-toc-solution&quot;&gt;Solution&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#retrospect&quot; id=&quot;markdown-toc-retrospect&quot;&gt;Retrospect&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;problems&quot;&gt;PROBLEMS&lt;/h2&gt;

&lt;h3 id=&quot;description&quot;&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/h3&gt;

&lt;hr /&gt;

&lt;p&gt;Given two promises promise1 and promise2, return a new promise. promise1 and promise2 will both resolve with a number. The returned promise should resolve with the sum of the two numbers.&lt;/p&gt;

&lt;h3 id=&quot;example&quot;&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/h3&gt;

&lt;hr /&gt;

&lt;p&gt;Example 1:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Input:&lt;br /&gt;
promise1 = new Promise(resolve =&amp;gt; setTimeout(() =&amp;gt; resolve(2), 20)),&lt;br /&gt;
promise2 = new Promise(resolve =&amp;gt; setTimeout(() =&amp;gt; resolve(5), 60))&lt;br /&gt;
Output: 7&lt;br /&gt;
Explanation: The two input promises resolve with the values of 2 and 5 respectively. The returned promise should resolve with a value of 2 + 5 = 7. The time the returned promise resolves is not judged for this problem.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Example 2:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Input:&lt;br /&gt;
promise1 = new Promise(resolve =&amp;gt; setTimeout(() =&amp;gt; resolve(10), 50)),&lt;br /&gt;
promise2 = new Promise(resolve =&amp;gt; setTimeout(() =&amp;gt; resolve(-12), 30))&lt;br /&gt;
Output: -2&lt;br /&gt;
Explanation: The two input promises resolve with the values of 10 and -12 respectively. The returned promise should resolve with a value of 10 + -12 = -2.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;constraints&quot;&gt;&lt;strong&gt;Constraints&lt;/strong&gt;&lt;/h3&gt;

&lt;hr /&gt;

&lt;ul&gt;
  &lt;li&gt;promise1 and promise2 are promises that resolve with a number&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;solution&quot;&gt;Solution&lt;/h3&gt;

&lt;hr /&gt;

&lt;ul&gt;
  &lt;li&gt;Runtime: 68ms&lt;/li&gt;
  &lt;li&gt;Memory: 49.57MB&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/**
 * @param {Promise} promise1
 * @param {Promise} promise2
 * @return {Promise}
 */
const addTwoPromises = async function(promise1, promise2) {
    const firstNum = await promise1
    const secondNum = await promise2
    return firstNum + secondNum
};

/**
 * addTwoPromises(Promise.resolve(2), Promise.resolve(2))
 *   .then(console.log); // 4
 */
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;retrospect&quot;&gt;Retrospect&lt;/h3&gt;

&lt;hr /&gt;

&lt;p&gt;비동기함수로 이제 들어왔다 많이 써보지는 않았지만 개념은 알고 있는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;async&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;await&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;promise&lt;/code&gt;에 대한 것들이 나왔다. 처음에 문제를 봤을때 Promise 객체로 받으니까 각 Promise에 대해 await를 걸어줘 Promise를 기다렸다가 숫자를 받아오게끔 처리했다. 그 후 각 받아온 값에 대해 반환을 하여 정답을 구했다.&lt;/p&gt;

&lt;p&gt;이번문제는 비동기에 대한 정말 기초적인 개념에 대해서 알려주고 있는거 같다. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;async&lt;/code&gt;를 사용하게 되면 항상 Promise객체를 반환하게 되고 안쪽에서 API를 받아와서 반환하는 로직이 많이 작성되는거 같다.&lt;/p&gt;
</description>
        
        <pubDate>Fri, 26 Apr 2024 00:00:00 +0900</pubDate>
        <link>https://owni14.github.io/dev/algorithm-Add-Two-Promises.html</link>
        <guid isPermaLink="true">https://owni14.github.io/dev/algorithm-Add-Two-Promises.html</guid>
      </item>
    
	<item>
		<title>[LeetCode] Memoize</title>
        
        
            <description>&lt;!-- prettier-ignore --&gt;
&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#problems&quot; id=&quot;markdown-toc-problems&quot;&gt;PROBLEMS&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#description&quot; id=&quot;markdown-toc-description&quot;&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#example&quot; id=&quot;markdown-toc-example&quot;&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#constraints&quot; id=&quot;markdown-toc-constraints&quot;&gt;&lt;strong&gt;Constraints&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#solution&quot; id=&quot;markdown-toc-solution&quot;&gt;Solution&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#retrospect&quot; id=&quot;markdown-toc-retrospect&quot;&gt;Retrospect&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;problems&quot;&gt;PROBLEMS&lt;/h2&gt;

&lt;h3 id=&quot;description&quot;&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/h3&gt;

&lt;hr /&gt;

&lt;p&gt;Given a function fn, return a memoized version of that function.&lt;/p&gt;

&lt;p&gt;A memoized function is a function that will never be called twice with the same inputs. Instead it will return a cached value.&lt;/p&gt;

&lt;p&gt;You can assume there are 3 possible input functions: sum, fib, and factorial.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;sum accepts two integers a and b and returns a + b. Assume that if a value has already been cached for the arguments (b, a) where a != b, it cannot be used for the arguments (a, b). For example, if the arguments are (3, 2) and (2, 3), two separate calls should be made.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;fib accepts a single integer n and returns 1 if n &amp;lt;= 1 or fib(n - 1) + fib(n - 2) otherwise.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;factorial accepts a single integer n and returns 1 if n &amp;lt;= 1 or factorial(n - 1) * n otherwise.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;example&quot;&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/h3&gt;

&lt;hr /&gt;

&lt;p&gt;Example 1:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Input:&lt;br /&gt;
fnName = “sum”&lt;br /&gt;
actions = [“call”,”call”,”getCallCount”,”call”,”getCallCount”]&lt;br /&gt;
values = [[2,2],[2,2],[],[1,2],[]]&lt;br /&gt;
Output: [4,4,1,3,2]&lt;br /&gt;
Explanation:&lt;br /&gt;
const sum = (a, b) =&amp;gt; a + b;&lt;br /&gt;
const memoizedSum = memoize(sum);&lt;br /&gt;
memoizedSum(2, 2); // “call” - returns 4. sum() was called as (2, 2) was not seen before.&lt;br /&gt;
memoizedSum(2, 2); // “call” - returns 4. However sum() was not called because the same inputs were seen before.&lt;br /&gt;
// “getCallCount” - total call count: 1&lt;br /&gt;
memoizedSum(1, 2); // “call” - returns 3. sum() was called as (1, 2) was not seen before.&lt;br /&gt;
// “getCallCount” - total call count: 2&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Example 2:&lt;/p&gt;

&lt;!-- prettier-ignore --&gt;
&lt;blockquote&gt;
  &lt;p&gt;Input:&lt;br /&gt;
fnName = “factorial”&lt;br /&gt;
actions = [“call”,”call”,”call”,”getCallCount”,”call”,”getCallCount”]&lt;br /&gt;
values = [[2],[3],[2],[],[3],[]]&lt;br /&gt;
Output: [2,6,2,2,6,2]&lt;br /&gt;
Explanation:&lt;br /&gt;
const factorial = (n) =&amp;gt; (n &amp;lt;= 1) ? 1 : (n * factorial(n - 1));&lt;br /&gt;
const memoFactorial = memoize(factorial);&lt;br /&gt;
memoFactorial(2); // “call” - returns 2.&lt;br /&gt;
memoFactorial(3); // “call” - returns 6.&lt;br /&gt;
memoFactorial(2); // “call” - returns 2. However factorial was not called because 2 was seen before.&lt;br /&gt;
// “getCallCount” - total call count: 2&lt;br /&gt;
memoFactorial(3); // “call” - returns 6. However factorial was not called because 3 was seen before.&lt;br /&gt;
// “getCallCount” - total call count: 2&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Example 3:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Input:&lt;br /&gt;
fnName = “fib”&lt;br /&gt;
actions = [“call”,”getCallCount”]&lt;br /&gt;
values = [[5],[]]&lt;br /&gt;
Output: [8,1]&lt;br /&gt;
Explanation:&lt;br /&gt;
fib(5) = 8 // “call”&lt;br /&gt;
// “getCallCount” - total call count: 1&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;constraints&quot;&gt;&lt;strong&gt;Constraints&lt;/strong&gt;&lt;/h3&gt;

&lt;hr /&gt;

&lt;ul&gt;
  &lt;li&gt;0 &amp;lt;= a, b &amp;lt;= 105&lt;/li&gt;
  &lt;li&gt;1 &amp;lt;= n &amp;lt;= 10&lt;/li&gt;
  &lt;li&gt;0 &amp;lt;= actions.length &amp;lt;= 105&lt;/li&gt;
  &lt;li&gt;actions.length === values.length&lt;/li&gt;
  &lt;li&gt;actions[i] is one of “call” and “getCallCount”&lt;/li&gt;
  &lt;li&gt;fnName is one of “sum”, “factorial” and “fib”&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;solution&quot;&gt;Solution&lt;/h3&gt;

&lt;hr /&gt;

&lt;ul&gt;
  &lt;li&gt;Runtime: 366ms&lt;/li&gt;
  &lt;li&gt;Memory: 85.91MB&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/**
 * @param {Function} fn
 * @return {Function}
 */
function memoize(fn) {
    const cache = {}
    return function (...args) {
        if(args in cache) {
            return cache[args]
        }
        const getValue = fn(...args)
        cache[args] = getValue
        return getValue
    }
}


/**
 * let callCount = 0;
 * const memoizedFn = memoize(function (a, b) {
 *	 callCount += 1;
 *   return a + b;
 * })
 * memoizedFn(2, 3) // 5
 * memoizedFn(2, 3) // 5
 * console.log(callCount) // 1
 */
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;retrospect&quot;&gt;Retrospect&lt;/h3&gt;

&lt;hr /&gt;

&lt;p&gt;문제의 설명은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memozie&lt;/code&gt;함수가 아닌 inner함수(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return function(...arge){}&lt;/code&gt;)를 여러번 호출하게 될 경우 동일한 파라미터를 넘겨주게 되면 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memoize&lt;/code&gt;함수를 실행하지 않는 것이었고, 이전에 들어왔던 &lt;strong&gt;동일한 값&lt;/strong&gt;을 캐싱하고 있다가 반환해주는 것이었다. 그래서 나는 outer함수인 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memozie&lt;/code&gt;함수에 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cache&lt;/code&gt;라는 변수를 하나 선언해두고 해당 변수에 값을 캐싱하여 동일한 값이 들어오면 캐싱 된 값을 반환을 했다.&lt;/p&gt;

&lt;p&gt;if 조건문을 통해 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cache&lt;/code&gt;의 속성에 파라미터로 넘어온 args가 존재하게 되면, 캐싱된 값을 리턴하게 했다. 그게 아니라면 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memozie&lt;/code&gt;함수를 호출하여 값을 얻은 값을 cache에 args가 키를 가지도록 해서 넣어주었고, 함수 실행을 통해 얻은 값을 반환했다.&lt;/p&gt;

&lt;p&gt;이번 문제는 생각보다 시간이 오래걸렸는데 자꾸 실행을하니 getCallCount가 자꾸 함수를 실행한만큼 나오는 것이었다. 나는 함수를 실행시키고 추출해서 나온 동일한 값에 대해서만 조건을 주고 캐싱된 값을 반환하고 있었는데 문제를 다시 읽어보니, &lt;strong&gt;A memoized function is a function that will never be called twice with the same inputs&lt;/strong&gt;라는 문구가 눈에 띄었다.&lt;/p&gt;

&lt;p&gt;실제로 함수를 메모이제이션해서 호출되지 않게끔 해야했었다. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;useMemo&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;useCallBack&lt;/code&gt;과 동일한 개념이 사용되었다. 이렇게 메모이제이션해서 사용하게 되면 메모리가 절약되기 때문에 성능상 유리한 측면이 있다고 생각된다.&lt;/p&gt;
</description>
        
        <pubDate>Thu, 25 Apr 2024 00:00:00 +0900</pubDate>
        <link>https://owni14.github.io/dev/algorithm-Memoize.html</link>
        <guid isPermaLink="true">https://owni14.github.io/dev/algorithm-Memoize.html</guid>
      </item>
    
	<item>
		<title>[LeetCode] Allow One Function Call</title>
        
        
            <description>&lt;!-- prettier-ignore --&gt;
&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#problems&quot; id=&quot;markdown-toc-problems&quot;&gt;PROBLEMS&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#description&quot; id=&quot;markdown-toc-description&quot;&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#example&quot; id=&quot;markdown-toc-example&quot;&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#constraints&quot; id=&quot;markdown-toc-constraints&quot;&gt;&lt;strong&gt;Constraints&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#solution&quot; id=&quot;markdown-toc-solution&quot;&gt;Solution&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#retrospect&quot; id=&quot;markdown-toc-retrospect&quot;&gt;Retrospect&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;problems&quot;&gt;PROBLEMS&lt;/h2&gt;

&lt;h3 id=&quot;description&quot;&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/h3&gt;

&lt;hr /&gt;

&lt;p&gt;Given a function fn, return a new function that is identical to the original function except that it ensures fn is called at most once.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The first time the returned function is called, it should return the same result as fn.&lt;/li&gt;
  &lt;li&gt;Every subsequent time it is called, it should return undefined.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;example&quot;&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/h3&gt;

&lt;hr /&gt;

&lt;p&gt;Example 1:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Input: fn = (a,b,c) =&amp;gt; (a + b + c), calls = [[1,2,3],[2,3,6]]&lt;br /&gt;
Output: [{“calls”:1,”value”:6}]&lt;br /&gt;
Explanation:&lt;br /&gt;
const onceFn = once(fn);&lt;br /&gt;
onceFn(1, 2, 3); // 6&lt;br /&gt;
onceFn(2, 3, 6); // undefined, fn was not called&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Example 2:&lt;/p&gt;

&lt;!-- prettier-ignore --&gt;
&lt;blockquote&gt;
  &lt;p&gt;Input: fn = (a,b,c) =&amp;gt; (a * b * c), calls = [[5,7,4],[2,3,6],[4,6,8]]&lt;br /&gt;
Output: [{“calls”:1,”value”:140}]&lt;br /&gt;
Explanation:&lt;br /&gt;
const onceFn = once(fn);&lt;br /&gt;
onceFn(5, 7, 4); // 140&lt;br /&gt;
onceFn(2, 3, 6); // undefined, fn was not called&lt;br /&gt;
onceFn(4, 6, 8); // undefined, fn was not called&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;constraints&quot;&gt;&lt;strong&gt;Constraints&lt;/strong&gt;&lt;/h3&gt;

&lt;hr /&gt;

&lt;ul&gt;
  &lt;li&gt;calls is a valid JSON array&lt;/li&gt;
  &lt;li&gt;1 &amp;lt;= calls.length &amp;lt;= 10&lt;/li&gt;
  &lt;li&gt;1 &amp;lt;= calls[i].length &amp;lt;= 100&lt;/li&gt;
  &lt;li&gt;2 &amp;lt;= JSON.stringify(calls).length &amp;lt;= 1000&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;solution&quot;&gt;Solution&lt;/h3&gt;

&lt;hr /&gt;

&lt;ul&gt;
  &lt;li&gt;Runtime: 39ms&lt;/li&gt;
  &lt;li&gt;Memory: 48.32MB&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/**
 * @param {Function} fn
 * @return {Function}
 */
var once = function(fn) {
    let isFirstCall = true
    return function(...args) {
        if(isFirstCall) {
            isFirstCall = false
            return fn(...args)
        }
    }
};

/**
 * let fn = (a,b,c) =&amp;gt; (a + b + c)
 * let onceFn = once(fn)
 *
 * onceFn(1,2,3); // 6
 * onceFn(2,3,6); // returns undefined without calling fn
 */
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;retrospect&quot;&gt;Retrospect&lt;/h3&gt;

&lt;hr /&gt;

&lt;p&gt;문제의 설명은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;once&lt;/code&gt;라는 함수가 여러번 호출되게 될 경우 처음만 호출되고 나머지 호출이 되지 않아야한다라고 나와있다. 나는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;once&lt;/code&gt;함수를 제일 처음 생성했을때 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;isFirstCall&lt;/code&gt;라는 변수 명을 하나 같이 선언해주었는데 이렇게 해준 이유는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;once&lt;/code&gt;함수를 처음 호출했는지 확인하기 위해서이다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;onceFn(1,2,3)&lt;/code&gt;을 호출하게 되면 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;isFirstCall&lt;/code&gt;은 true가 되니 조건문 안쪽으로 들어가겠고, 함수에 파라미터를 전달해 원하는 값을 추추할 수 있게 된다. 여기서 이제 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;isFristCall&lt;/code&gt;변수를 false로 바꿔 처음 함수 호출이 끝났다고 알려주면 다음에 호출할때는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;onceFn&lt;/code&gt;함수가 호출되지 않을꺼고 문제에서 원하는 답을 찾을 수 있게 될 것이다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;onceFn&lt;/code&gt;함수 내에서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;isFirstCall&lt;/code&gt;을 생성하게되면 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;isFirstCall&lt;/code&gt;이라는 변수는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;onceFn&lt;/code&gt;의 렉시컬 환경에 대한 참조를 저장하게 된다. 안쪽 함수에서는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;isFirstCall&lt;/code&gt;을 사용할 수 있게 되고 상태가 바뀌게 되면 바뀐 상태 값도 참조할 수 있게 되는 것이다. 만약 안쪽 함수에서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;isFirstCall&lt;/code&gt;을 선언하고 return 전에 값을 true로 바꾸게 된다면, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;onceFn&lt;/code&gt; 다시 호출될 때 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;isFirstCall&lt;/code&gt;은 초기값인 false로 바껴있을 것이다.&lt;/p&gt;

&lt;p&gt;실질적으로 호출되는 부분은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;function(..args)&lt;/code&gt;인데 해당 함수를 호출하게 되면 렉시컬환경이 계속 새롭게 생성되어질 것이고, 값은 초기화가 될 것이다. 그래서 렉시컬스코프에 의해 상위 스코프에 변수를 선언해서 사용하면 상태 변화를 알 수 있을 것이다.&lt;/p&gt;
</description>
        
        <pubDate>Wed, 24 Apr 2024 00:00:00 +0900</pubDate>
        <link>https://owni14.github.io/dev/algorithm-Allow-One-Function-Call.html</link>
        <guid isPermaLink="true">https://owni14.github.io/dev/algorithm-Allow-One-Function-Call.html</guid>
      </item>
    
  </channel>
</rss>