說說Codewars 裡面的Multi Line Task

Madao-3發表於2019-03-15

筆者最近開始玩兒起了Codewars ,這是一個類似LeetCode 的平臺,不過題目的型別不限於演算法,而且社群比LC 活躍。裡有不少語言特性還有最佳實踐向的題目,Passed 之後還能看到別人的solutions 並互相評價,一刷起來就容易停不下來。

Codewars 裡面有一個特定的 Kata,就是「Multi Line Task」,大致就是限制每行的程式碼長度,限制行數,完成一個簡單的程式碼問題,語言選擇的話只有 Javascript。年前順手把Voile 在裡頭髮布的Kata 都做了,這裡記錄下思路。

Multi Line Task: Fizz Buzz\Multi Line Task: GCD Function

這兩題基本上沒有什麼解題的障礙,因為一行能寫三個字元之多,所以這類5 kyu 一下就能水過去了。 關鍵字:箭頭函式

Multi Line Task++: Hello World

這算是Multi Line 題裡的分界線了,這個的題解你基本上會寫這個:

 $ = ''['slice']['bind']('Hello world!')
複製程式碼

那你就距離答案只差幾個轉義符了。

關鍵字:bind

Multi Line Task: Hello World (Without Letters)

本以為1kyu Multi Line Task∞: Hello World 的才是最終boss,實質上No Letter 所包含的坑遠遠比我想得多。

第一直覺就是這直接轉換為JSF**K,直接jsfuck即可,一氣呵成地把: $ = ''['slice']['bind']('Hello world!') 轉換並優化成了

$ = `
`[
  (![] + [])[3] +
    (![] + [])[2] +
    ([][[]] + [])[5] +
    ([] + {})[5] +
    ([][[]] + [])[3]
][([] + {})[2] + ([][[]] + [])[5] + ([][[]] + [])[1] + ([][[]] + [])[2]](
  "H" +
    ([][[]] + [])[3] +
    (![] + [])[2] +
    (![] + [])[2] +
    ([] + {})[1] +
    ([] + {})[7] +
    [4 * 8][0][
      (!![] + [])[0] +
        ([] + {})[1] +
        $[0] +
        (!!$ + "")[0] +
        (!!$ + "")[1] +
        ([][[]] + [])[5] +
        ([][[]] + [])[1] +
        $[2]
    ](9 * 4 - 3) +
    ([] + {})[1] +
    (!![] + [])[1] +
    (![] + [])[2] +
    ([][[]] + [])[2] +
    `
!
`[1]
)();

複製程式碼

所以很明顯,這道題的核心難點在於如何得到 H 這個字元, jsfuck 原始碼中使用的 unescape 得到 H,但是這在node 環境下是做不到的,因為它得到 p 的方法是用location 的字串形式得到當前網址,從http 中得到 p。腦洞雖大,但是在node 環境下不可用。於是過了一遍 jsfsck 的原始碼,還是很明確。

然後我的目標轉向了fromCharCode,但是生成 fromCharCode 這幾個字即使用上了初始提供的 let $ = 'CSg',也得用381個字串,也就是381行,但是之前實現的基礎部分已經使用了370行左右,所以剩餘的程式碼量不能超過330行。

這時候的問題已經縮小到了如何減少行數,所以很簡單:提前壓縮好所需的字串即可解題。

關鍵字:JSFuck,提前壓縮變數

Multi Line Task∞: Hello World

作為一道1kyu 的題,這一題所需的知識點太少了,在之前的Multi Line 的技巧加上下面這個知識點你就能過關了。

[,a,,b,,,c] = ` a b  c`;
console.log(a,b,c)
$ a b c
複製程式碼

關鍵字:解構賦值

以上就基本上是現階段CW 裡Javascript 相關的Multi Line Task 題目了。

原文地址

相關文章