<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Schaos &#8211; 科技島-掌握科技新聞、科技職場最新資訊</title>
	<atom:link href="https://www.technice.com.tw/tag/schaos/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.technice.com.tw</link>
	<description>專注於科技新聞、科技職場、科技知識相關資訊，包含生成式AI、人工智慧、Web 3.0、區塊鏈、科技職缺百科、生物科技、軟體發展、雲端技術等豐富內容，適合熱衷科技及從事科技專業人事第一手資訊的平台。</description>
	<lastBuildDate>Thu, 04 Aug 2022 07:32:51 +0000</lastBuildDate>
	<language>zh-TW</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.4.2</generator>

<image>
	<url>https://www.technice.com.tw/wp-content/uploads/2022/12/cropped-wordpress_512x512-150x150.png</url>
	<title>Schaos &#8211; 科技島-掌握科技新聞、科技職場最新資訊</title>
	<link>https://www.technice.com.tw</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>工程師們刷題刷起來 — CodeWars 刷題心得分享</title>
		<link>https://www.technice.com.tw/experience/13122/</link>
					<comments>https://www.technice.com.tw/experience/13122/#respond</comments>
		
		<dc:creator><![CDATA[科編推薦]]></dc:creator>
		<pubDate>Thu, 04 Aug 2022 07:32:45 +0000</pubDate>
				<category><![CDATA[產業]]></category>
		<category><![CDATA[CodeWars]]></category>
		<category><![CDATA[leetcode]]></category>
		<category><![CDATA[Schaos]]></category>
		<category><![CDATA[演算法]]></category>
		<category><![CDATA[資料結構]]></category>
		<category><![CDATA[面試經驗]]></category>
		<guid isPermaLink="false">https://www.technice.com.tw/?p=13122</guid>

					<description><![CDATA[<p><img width="880" height="440" src="https://www.technice.com.tw/wp-content/uploads/2022/08/0_ljtLRtU8o7tEmzWg.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="0 ljtLRtU8o7tEmzWg" decoding="async" srcset="https://www.technice.com.tw/wp-content/uploads/2022/08/0_ljtLRtU8o7tEmzWg.png 880w, https://www.technice.com.tw/wp-content/uploads/2022/08/0_ljtLRtU8o7tEmzWg-300x150.png 300w, https://www.technice.com.tw/wp-content/uploads/2022/08/0_ljtLRtU8o7tEmzWg-768x384.png 768w" sizes="(max-width: 880px) 100vw, 880px" title="工程師們刷題刷起來 — CodeWars 刷題心得分享 1"></p>
<p>這一年來，一直斷斷續續的有在 CodeWars 上練習解題，也就是工程師俗稱的刷題啦；最近這幾個月玩的比較認真，終於達到了 1000 分的小目標，於是想稍微整理一下這陣子的心得和大家分享。<content><!-- wp:image {"id":13124,"sizeSlug":"full","linkDestination":"none"} --></p>
<figure class="wp-block-image size-full"><img src="https://www.technice.com.tw/wp-content/uploads/2022/08/0_ljtLRtU8o7tEmzWg.png" alt="" class="wp-image-13124"/></figure>
<p><!-- /wp:image --></p>
<p><!-- wp:paragraph --></p>
<p>圖文／<a href="https://medium.com/schaoss-blog/%E5%B7%A5%E7%A8%8B%E5%B8%AB%E5%80%91%E5%88%B7%E9%A1%8C%E5%88%B7%E8%B5%B7%E4%BE%86-codewars-%E5%88%B7%E9%A1%8C%E5%BF%83%E5%BE%97%E5%88%86%E4%BA%AB-13a89e8e7736">Schaos</a></p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:paragraph --></p>
<p id="551a">這一年來，一直斷斷續續的有在 <a href="https://www.codewars.com/" target="_blank" rel="noreferrer noopener">CodeWars</a> 上練習解題，也就是工程師俗稱的刷題啦；最近這幾個月玩的比較認真，終於達到了 1000 分的小目標，於是想稍微整理一下這陣子的心得和大家分享。</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:heading {"level":1} --></p>
<h1 id="6bdc">CodeWars 是什麼？</h1>
<p><!-- /wp:heading --></p>
<p><!-- wp:paragraph --></p>
<p id="490a">CodeWars 就是一個類似&nbsp;<a href="https://leetcode.com/" rel="noreferrer noopener" target="_blank">LeetCode</a>&nbsp;的程式練習網站，但結合了經驗值、等級、戰隊、排行榜等許多遊戲化的要素，讓你刷題不無聊。</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:heading --></p>
<h2 id="4615">與 LeetCode 的比較</h2>
<p><!-- /wp:heading --></p>
<p><!-- wp:paragraph --></p>
<p id="ca5c">刷題時最常被同事問到的就是這個。</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:paragraph --></p>
<p id="0bf2">同樣是刷題網站的兩者相比較起來，LeetCode 的題目來源主要是蒐集是各大科技公司的 面試題目；且 LeetCode 會在題目完成後，告知你提交的程式效能如何、使用的記憶體、運行時間贏過全部挑戰者中的多少百分比，是重視「演算法」、「資料結構」等基本功的練習平台。</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:paragraph --></p>
<p id="a40b">而 CodeWars 則開放讓所有使用者自創題目，再由其他玩家協同開發各語言版本、提供 Test case、回報 issue 等等，自成一個小社群；並在通過測試、提交答案之後，就能查看別人提交的程式碼，除了給予評論、點讚等社交互動外，也能藉由理解別人的程式來再次釐清自己的想法、看到自己的盲點。</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:paragraph --></p>
<p id="4832">對我來說，LeetCode 比較正規、嚴肅，如果有要去大公司面試，好像真的要把上面的經典題目刷過一輪比較保險；CodeWars 相對 LeetCode 就多元有趣了不少，挑戰不同領域會遇到的實際題目，下班、周末沒事來刷個一兩題當遊戲也是很棒的練習，於是我就在這邊一直玩下去了 XD</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:heading {"level":1} --></p>
<h1 id="a1a7">印象深刻的題目</h1>
<p><!-- /wp:heading --></p>
<p><!-- wp:paragraph --></p>
<p id="b3b8">好啦我知道前面字太多了，該來點程式了；我平常練習時會把大部分的解題過程都丟在&nbsp;<a href="https://github.com/schaoss/HappyCodeWars" rel="noreferrer noopener" target="_blank">這裡</a>，想參考我玩過的題目可以去逛逛。</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:quote --></p>
<blockquote class="wp-block-quote">
<p><em>Talk is cheap. Show me the code. — Linus Torvalds</em></p>
</blockquote>
<p><!-- /wp:quote --></p>
<p><!-- wp:heading --></p>
<h2 id="3c5d">Connect Four</h2>
<p><!-- /wp:heading --></p>
<p><!-- wp:paragraph --></p>
<p id="487a"><a href="https://www.codewars.com/kata/56882731514ec3ec3d000009" rel="noreferrer noopener" target="_blank">原始題目連結</a></p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:paragraph --></p>
<p id="6a29">相信大家多少都玩過 <a href="https://en.wikipedia.org/wiki/Connect_Four" target="_blank" rel="noreferrer noopener">四連環</a> 這款經典的益智對戰遊戲；這題要實作出四連環的獲勝者判斷機制，可以說是非常輕鬆且貼近生活的題目。</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:image {"id":13125,"sizeSlug":"full","linkDestination":"none"} --></p>
<figure class="wp-block-image size-full"><img src="https://www.technice.com.tw/wp-content/uploads/2022/08/0_aN7onTQ_DR6zMjDe.gif" alt="" class="wp-image-13125"/></figure>
<p><!-- /wp:image --></p>
<p><!-- wp:paragraph --></p>
<p id="e43b">題目會給予一段資料陣列，內容就依序是參加者各別的下子位置，要求的輸出則是遊戲贏家；我的想法是要先設計遊戲機制的邏輯，也就是落子到棋盤的這部分，接著在每次落子時加上勝負判斷的機制。</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:preformatted --></p>
<pre class="wp-block-preformatted">// &lt; 4 kyu > - Connect Four
// <a href="https://www.codewars.com/kata/connect-four-1" target="_blank" rel="noreferrer noopener">https://www.codewars.com/kata/connect-four-1</a>

function whoIsWinner(input) {
  // 棋盤
  const grid = new Array(7).fill(0).map(() => [])
  let winner = 'Draw'  

  // 依序落子
  for (let i = 0; i &lt; input.length; i++) {
    let [char, color] = input[i].split('_')
    let row = char.charCodeAt() - 65    
 // drop item
    grid[row].push(color)    
 // check winner
    if (i > 6 &amp;&amp; check(row, color)) {
      winner = color
      break
    }
  }
  return winner  
  
  // 判斷勝負
  function check(i) {
    let j = grid[i].length - 1
    if (checkV() || checkH() || checkS() || checkRS()) {
      return true
    }
    return false    
  
  // 垂直
    function checkV() {
      if (j > 2) {
        return grid[i][j] === grid[i][j - 1] &amp;&amp; grid[i][j - 1] === grid[i][j - 2] &amp;&amp; grid[i][j - 2] === grid[i][j - 3]
      }
      return false
    }    

  // 水平
    function checkH() {
      for (let k = 0; k &lt; 4; k++) {
        if (
          grid[k][j] &amp;&amp;
          grid[k + 1][j] &amp;&amp;
          grid[k + 2][j] &amp;&amp;
          grid[k + 3][j] &amp;&amp;
          grid[k][j] === grid[k + 1][j] &amp;&amp;
          grid[k + 1][j] === grid[k + 2][j] &amp;&amp;
          grid[k + 2][j] === grid[k + 3][j]
        ) {
          return true
        }
      }
      return false
    }    

  // 斜向 ↗
    function checkS() {
      for (let x = i - Math.min(i, j), y = j - Math.min(i, j); x &lt; 4 &amp;&amp; y &lt; 3; x++, y++) {
        if (
          grid[x][y] &amp;&amp;
          grid[x + 1][y + 1] &amp;&amp;
          grid[x + 2][y + 2] &amp;&amp;
          grid[x + 3][y + 3] &amp;&amp;
          grid[x][y] === grid[x + 1][y + 1] &amp;&amp;
          grid[x + 1][y + 1] === grid[x + 2][y + 2] &amp;&amp;
          grid[x + 2][y + 2] === grid[x + 3][y + 3]
        ) {
          return true
        }
      }
      return false
    }    

  // 反斜 ↖
    function checkRS() {
      for (let x = i + Math.min(6 - i, j), y = j - Math.min(6 - i, j); x > 2 &amp;&amp; y &lt; 3; x--, y++) {
        if (
          grid[x][y] &amp;&amp;
          grid[x - 1][y + 1] &amp;&amp;
          grid[x - 2][y + 2] &amp;&amp;
          grid[x - 3][y + 3] &amp;&amp;
          grid[x][y] === grid[x - 1][y + 1] &amp;&amp;
          grid[x - 1][y + 1] === grid[x - 2][y + 2] &amp;&amp;
          grid[x - 2][y + 2] === grid[x - 3][y + 3]
        ) {
          return true
        }
      }
      return false
    }
  }
}</pre>
<p><!-- /wp:preformatted --></p>
<p><!-- wp:paragraph --></p>
<p id="23bc">主要的難點大概是勝負判斷的部分，要考慮各個方向判斷邏輯微妙的不同。最後我將各個方向的判斷各自拆出分別實作，降低一點點複雜度。</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:heading --></p>
<h2 id="89a2">Javascript Magic Function</h2>
<p><!-- /wp:heading --></p>
<p><!-- wp:paragraph --></p>
<p id="e7f2"><a href="https://www.codewars.com/kata/55caf9ff29c318407c00001f" rel="noreferrer noopener" target="_blank">原始題目連結</a></p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:paragraph --></p>
<p id="eefa">這題是個活用 Javascript 特性的巧妙題目。要求寫出一個神奇的 Function，可以接受任意數量的參數、被連續呼叫任意次、且會回傳所有參數數字的總和。</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:paragraph --></p>
<p id="d686">由於可以被呼叫任意次，因此一定要回傳 Function；但當在進行比較時，卻要能回傳出正確的數字。乍看之下好像不太可能，但如果理解 Javascript 中「一般相等」的運作機制，修改&nbsp;<code>valueOf()</code>函式，好像就能找到突破口了。</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:preformatted --></p>
<pre class="wp-block-preformatted">function MagicFunction(...argu) {
  // 參數加總
  let sum = argu
    .filter(a => !isNaN(a))
    .map(Number)
    .reduce((acc, c) => acc + c, 0)
  
  // 透過 bind，將加總帶到新函式中
  let func = MagicFunction.bind(this, sum)  

  // 改寫函式的 valueOf -> 在一般相等比較時回傳參數的加總
  func.valueOf = () => sum  

  // 回傳函式 -> 可以連續呼叫
  return func
}</pre>
<p><!-- /wp:preformatted --></p>
<p><!-- wp:heading {"level":1} --></p>
<h1 id="120c">目前成果</h1>
<p><!-- /wp:heading --></p>
<p><!-- wp:paragraph --></p>
<p id="cfc6">稍微比較了我自己以前跟現在的工作習慣與題目解法，整理了自己有感的幾點成長：</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:heading --></p>
<h2 id="a905">更熟悉語言原生特性</h2>
<p><!-- /wp:heading --></p>
<p><!-- wp:paragraph --></p>
<p id="c9e2">在與陣列有關的地方，我發現自己變得非常喜歡用原本不太熟悉的&nbsp;<code>array.reduce</code>&nbsp;來解決事情，能夠繞完一圈就把資料全部整理乾淨，真的很方便！另外也對於&nbsp;<code>Function.prototype</code>、函式中的&nbsp;<code>arguments</code>&nbsp;等特性有了更多認識，並且趁機搞懂了&nbsp;<a href="https://github.com/schaoss/blog/blob/master/doc/apply_bind_call.md" rel="noreferrer noopener" target="_blank">前端面試最愛問的 Javascript apply、bind、call</a>。</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:paragraph --></p>
<p id="d78d">還有一般寫程式時會被要求盡量避免甚至禁止的&nbsp;<code>eval</code>，在特定的情況也會有奇效；能夠把字串處理後的結果轉回程式再執行，又是一種完全不同的思考方向。還有像前面提到的一般相等、絕對相等之間的差異，自動轉型的運作機制，也都是在解題過程中逐步摸索出來的。</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:paragraph --></p>
<p id="5641">藉由刷題，也能稍微熟悉了這些在目前的工作中比較少用到的語言特性，一點一點的增加自己基礎知識的儲備量。</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:heading --></p>
<h2 id="eb20">練習 Functional Programming</h2>
<p><!-- /wp:heading --></p>
<p><!-- wp:paragraph --></p>
<p id="95f0">因應一部分題目的要求，也開始對 Functional Programming 的核心概念有了理解。例如純函數、 Higher order Function、<a href="https://zh.wikipedia.org/zh-tw/%E6%9F%AF%E9%87%8C%E5%8C%96" rel="noreferrer noopener" target="_blank">Curry 化</a>&nbsp;函數、Compose 組合函數、鏈式函式串接等等。</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:paragraph --></p>
<p id="2b81">現在遇到關於字串處理的問題，可能就會實作成陣列 &amp; 字串的函式串接。 像是&nbsp;<a href="https://www.codewars.com/kata/5411c4205f3a7fd3f90009ea" rel="noreferrer noopener" target="_blank">這題</a>&nbsp;我的解法：</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:preformatted --></p>
<pre class="wp-block-preformatted">const stringParse = s =&gt; typeof s !== 'string' ? 'Please enter a valid string' <br>  : s.length &lt; 3 ? s <br>  : s.split('')<br>     .reduce((acc, c, i, arr) =&gt; (c === arr[i - 1] ? [...acc, c] : [...acc, '|', c]))<br>     .join('')<br>     .split('|')<br>     .map(c =&gt; (c.length &gt; 2 ? `${c.substring(0, 2)}[${c.substring(2)}]` : c))<br>     .join('')</pre>
<p><!-- /wp:preformatted --></p>
<p><!-- wp:paragraph --></p>
<p id="ae11">透過不同的思考模式，練習不同的撰寫風格也是一種很棒的成長。</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:heading --></p>
<h2 id="c64b">各種玄妙技巧</h2>
<p><!-- /wp:heading --></p>
<p><!-- wp:paragraph --></p>
<p id="46d7">由於 CodeWars 提交答案後可以看到別人的解法；即使是在相對簡單的題目中，也可以見識到各路大神們腦洞大開的解法，並從中學到不少奇妙的小技巧。</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:paragraph --></p>
<p id="4fbd">例如用&nbsp;<code>~~</code>&nbsp;取代&nbsp;<code>parseInt()</code>，更短的寫法、更好的效能，但更<strong>&nbsp;低&nbsp;</strong>的可讀性：</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:preformatted --></p>
<pre class="wp-block-preformatted">parseInt('456.123')<br>// 456<br>~~'456.123'<br>// 456</pre>
<p><!-- /wp:preformatted --></p>
<p><!-- wp:paragraph --></p>
<p id="eaed">也可以透過 逗號 串接多個命令句並回傳最後一個的結果：</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:preformatted --></p>
<pre class="wp-block-preformatted">function awesome(arr) {<br>  return (n = arr.length), arr[n - 1] ** 2<br>}</pre>
<p><!-- /wp:preformatted --></p>
<p><!-- wp:paragraph --></p>
<p id="89e1">其他還有在連續乘 2 除 2 的地方可以活用&nbsp;<a href="https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Guide/Expressions_and_Operators#%E4%BD%8D%E5%85%83%E9%81%8B%E7%AE%97%E5%AD%90" rel="noreferrer noopener" target="_blank">左移 &amp; 右移</a>，連續布靈值的合併可以用 AND、OR、XOR 運算子等等。</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:paragraph --></p>
<p id="1422">雖然這些寫法不一定實用，工作中用了可能未來的同事（或自己）會有點痛苦，但從疑惑一步步走到理解的過程也是很有趣的對吧？</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:heading {"level":1} --></p>
<h1 id="c65c">總結</h1>
<p><!-- /wp:heading --></p>
<p><!-- wp:paragraph --></p>
<p id="3178">在練習的過程，一步一步感受到自己的成長與進步，真的是很有成就感的事情；終於達到 1000 分的當下真的是超感動的。如果你也是個想要透過持續練習來讓自己進步的工程師，又不喜歡一直練習冷冰冰的題目，我想 CodeWars 是個開心、有趣又不失成效的練習平台。</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:paragraph --></p>
<p id="e99d">以上就是近期的刷題心得，等我哪一天能升到 <a href="https://github.com/Codewars/codewars.com/wiki/Honor-&amp;-Ranks" target="_blank" rel="noreferrer noopener">kyu 1</a> 時再來續集吧～如果對於內文有任何問題，或是文中有錯誤、不清楚的地方，都歡迎您回應討論喔。</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:pullquote --></p>
<figure class="wp-block-pullquote">
<blockquote>
<p>本文由 <a href="https://medium.com/@schaos">Schaos</a> 授權轉載，原文<a href="https://www.technice.com.tw/wp-admin/post.php?post=13122&amp;action=edit">連結</a></p>
</blockquote>
</figure>
<p><!-- /wp:pullquote --></content></p>
<p>這篇文章 <a rel="nofollow" href="https://www.technice.com.tw/experience/13122/">工程師們刷題刷起來 — CodeWars 刷題心得分享</a> 最早出現於 <a rel="nofollow" href="https://www.technice.com.tw">科技島-掌握科技新聞、科技職場最新資訊</a>。</p>
]]></description>
		
					<wfw:commentRss>https://www.technice.com.tw/experience/13122/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
