JavaScript 一行能做到什麼程度?
tags: JavaScript
category: Programming
description: Python一行能做到多麼喪心病狂可能你也已經習慣了,但是JavaScript呢? 讓我們接著看下去
created_at: 2021/06/29 01:00:00
Python一行能做到多麼喪心病狂可能你也已經習慣了,但是JavaScript呢? 讓我們接著看下去
以下的實現都是一些簡單的題目
一行取得Fib(費式數列)
const fib = d => ((d, f) => f(f, d))(d, (f, d, o = [0, 1]) => o[d] == undefined ? o[d] = f(f, d - 1, o) + f(f, d - 2, o) : o[d])
你可以打開F12,在Console視窗中貼上之後像下面一樣使用他
console.log(fib(5)); // 5
console.log(fib(10)); // 55
console.log(fib(20)); // 6765
一行取得全排列
const permutations = d => ((d, f) => f(f, Array.from(d)))(d, (f, d, s = '', o = []) => o.concat(...d.length == 0 ? [s] : d.map((x, i) => f(f, d.slice(0, i).concat(d.slice(i + 1)), s + d[i]))))
範例:
console.log(permutations('abc'));
console.log(permutations('123'));
console.log(permutations('abcd'));
你會得到:
(6) ["abc", "acb", "bac", "bca", "cab", "cba"]
(6) ["123", "132", "213", "231", "312", "321"]
(24) ["abcd", "abdc", "acbd", "acdb", "adbc", "adcb", "bacd", "badc", "bcad", "bcda", "bdac", "bdca", "cabd", "cadb", "cbad", "cbda", "cdab", "cdba", "dabc", "dacb", "dbac", "dbca", "dcab", "dcba"]
一行建立二元搜尋樹
你沒看錯 就是資料結構當中的Binary Search Tree
const createBinarySearchTree = data => ((data, f) => ((nodes, ff) => ff(ff, nodes))(data.splice(0), (ff, nodes, i = 0) => (i >= nodes.length) ? data : ff(ff, nodes, i + 1, data[f(data, nodes[i], f)] = nodes[i])))(data, (tree, node, f, i = 1) => tree[i] === undefined ? i : f(tree, node, f, node > tree[i] ? i * 2 + 1 : i * 2))
你可以像這樣使用他
createBinarySearchTree([4, 2, 3, 6, 1, 5, 7]);
// (8) [empty, 4, 2, 6, 1, 3, 5, 7]
回傳一個陣列,索引1是根節點(Root)
一行讓二元樹走訪
既然都提到二元搜尋樹,當然離不開前序、中序、後序走訪,所以就各實現了一次,大同小異
const preorder = tree => ((tree, f) => f(f, tree))(tree, (f, tree, o = [], i = 1) => i >= tree.length ? [] : o.concat([tree[i], ...f(f, tree, o, i * 2), ...f(f, tree, o, i * 2 + 1)])).filter(x => x !== undefined)
const inorder = tree => ((tree, f) => f(f, tree))(tree, (f, tree, o = [], i = 1) => i >= tree.length ? [] : o.concat([...f(f, tree, o, i * 2), tree[i], ...f(f, tree, o, i * 2 + 1)])).filter(x => x !== undefined)
const postorder = tree => ((tree, f) => f(f, tree))(tree, (f, tree, o = [], i = 1) => i >= tree.length ? [] : o.concat([...f(f, tree, o, i * 2), ...f(f, tree, o, i * 2 + 1), tree[i]])).filter(x => x !== undefined)
可以跟著上面建立二元搜尋樹的方法一起使用
const tree = createBinarySearchTree([4, 2, 3, 6, 1, 5, 7]);
console.log(preorder(tree));
console.log(inorder(tree));
console.log(postorder(tree));
(7) [4, 2, 1, 3, 6, 5, 7]
(7) [1, 2, 3, 4, 5, 6, 7]
(7) [1, 3, 2, 5, 7, 6, 4]
學過資料結構應該都知道二元搜尋樹建立好之後,以中序走訪就是排序好的結果,所以既然有了建立二元搜尋樹跟中序走訪的一行程式,當然免不了一行實現二元搜尋樹排序啦!
const sort = tree => (tree => ((tree, f) => f(f, tree))(tree, (f, tree, o = [], i = 1) => i >= tree.length ? [] : o.concat([...f(f, tree, o, i * 2), tree[i], ...f(f, tree, o, i * 2 + 1)])))(((data) => ((data, f) => ((nodes, ff) => ff(ff, nodes))(data.splice(0), (ff, nodes, i = 0) => (i >= nodes.length) ? data : ff(ff, nodes, i + 1, data[f(data, nodes[i], f)] = nodes[i])))(data, (tree, node, f, i = 1) => tree[i] === undefined ? i : f(tree, node, f, node > tree[i] ? i * 2 + 1 : i * 2)))(tree)).filter(x => x !== undefined)
你可以像這樣使用
console.log(sort([3, 2, 1])); // (3) [1, 2, 3]
console.log(sort([1, 3, 2])); // (3) [1, 2, 3]
最後就是這裡一行最複雜而且在現今js裡面沒有意義的事情(因為BigInt型別)
一行實現大數相加
const add = (x, y) => ((x, y) => ((x, y, f, p, g, gp) => p(p, g, gp, f(p, Array.from(x).reverse().map(n => +n), Array.from(y).reverse().map(n => +n), new Array(Math.max(x.length, y.length)+1).fill(0))).reverse().map(n => n.toString()).reduce((a, b) => (a == '' && b == '0')? '': a+b, ''))(x, y, (p, x, y, z) => z.map((n, i) => (x[i] || 0) + (y[i] || 0)), (p, g, gp, z) => z.every(n => n < 10)? z: gp(p, g, gp, z, g(z)), z => [0].concat(z.map(n => Math.floor(n / 10))), (p, gf, gp, z, g) => p(p, gf, gp, g.map((n, i) => z[i] = (z[i]||0) % 10 + n))))(x.toString(), y.toString())
你可以像這樣使用他
console.log(add("123456789", "987654321"));
console.log(add("99999999999999999999999999999999999999999", "987654321"));
console.log(add("123456789987654321123456789", "987654321"));
console.log(add("987654321", "123456789987654321123456789"));
console.log(add("1111111111111111111111111111111111111111111111111111111111", "12343545453415345345341534153453453574537453453"));
你會得到
1111111110
100000000000000000000000000000000987654320
123456789987654322111111110
123456789987654322111111110
1111111111123454656564526456456452645264564564685648564564
以上就是兩年前暑假我在某次研習中突發奇想做的事情,最後就真的被我try出來了。
不過上面那種程式還是不要真的去寫在專案中,不然看到的人應該會傻眼,而且效能應該也不會太好。頂多算是練習或挑戰吧?
也可以到我的gist上面看哦!
最後更新時間: 2021年06月29日.