How to Make Fibonacci Confusing

来源:https://www.cnblogs.com/apolis/archive/2018/09/06/9600224.html
-Advertisement-
Play Games

好端端的”斐波那契“是怎麼變成這樣的,因吹斯聽,我們來回放一下。 ...


前幾天同事發了這麼一段代碼

(fn =>
    (f => f(f))(f => fn(n => f(f)(n)))
)(g =>
    n => [1, 2].indexOf(n) > -1 ? 1 : g(n - 1) + g(n - 2)
)(10);

猜你看這段代碼時,一定是這樣的心情:

What the fuck


好端端的斐波那契是怎麼變成這樣的,因吹斯聽,我們來回放一下。

從正常的寫法開始:

const fib = n => [1, 2].indexOf(n) >= 0 ? 1 : fib(n - 1) + fib(n - 2);

為了讓上面看起來不像遞歸,改寫一下。
把遞歸調用改成調用參數g

const wrappedFib = g => n => [1, 2].indexOf(n) >= 0 ? 1 : g(n - 1) + g(n - 2);

不管g傳什麼,例如就傳null,1,2兩項我都可以計算了,因為壓根和g無關。

wrappedFib(null)(1);
wrappedFib(null)(2);

如果要計算第3項,那我的g就可以是wrappedFib(null)

let g = wrappedFib(null);
wrappedFib(g)(3);

同理,第4項

let g = wrappedFib(wrappedFib(null));
wrappedFib(g)(4);

第5項......第N項我就不列了

看起來需要構造一個g,他由無限層的wrappedFib組成。

遞歸的思想

const g = n => wrappedFib(g)(n);

運行一下試試吧

const wrappedFib = g => n => [1, 2].indexOf(n) >= 0 ? 1 : g(n - 1) + g(n - 2);
const g = n => wrappedFib(g)(n);
console.log(wrappedFib(g)(10));

題外話
g本身就是由無限層wrappedFib組成的
所以wrappedFib(g)g是等價的
因此,也可以直接調console.log(g(10));

const g = n => wrappedFib(g)(n);

又看到了明顯的遞歸對不對,試著把它藏起來,思想跟開始的wrappedFib函數一樣,通過參數傳進來,這段要花點時間理解。

const g = (f => n => wrappedFib(f(f))(n))(f => n => wrappedFib(f(f))(n));

方法本身和方法傳參是一樣的,換個寫法

const g = (f => f(f))(f => n => wrappedFib(f(f))(n));

能到這裡,我們和最終的代碼已經很接近了,把g中的wrappedFib去掉,通過參數fn傳進來。

const gWaitForWrappedFib = fn => (f => f(f))(f => n => fn(f(f))(n));
const g = gWaitForWrappedFib(wrappedFib);

好了,去掉const常量的定義,全部連起來吧

(fn =>
    (f => f(f))(f => fn(n => f(f)(n)))
)(g =>
    n => [1, 2].indexOf(n) > -1 ? 1 : g(n - 1) + g(n - 2)
)(10);

拆解這段代碼挺燒腦,膜拜一下代碼的作者。
雖然想不出有什麼用,但是很有趣,有趣就值得研究:D

Code For Fun!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • React Native開發封裝Toast與載入Loading組件 在App開發中,我們避免不了使用的兩個組件,一個Toast,一個網路載入Loading,在RN開發中,也是一樣,React Native官方並沒有提供者這兩個常用組件,需要開發者自己根據需求來自定義。作者就在其他組件的基礎上在進行二 ...
  • 有時候在安裝apk的時候會出現解析軟體包出錯 (Android studio)解決方法如下: 關閉Instant Run功能: File-Settings-...看下圖: 將紅色框內的勾取消。 如果還是不行,那麼便在工程的gradle.properties里添加 android.injected.t ...
  • 1、檢查\app\src\main\AndroidMainfest.xml中是否有testOnly屬性為true,如果有去掉或者改為false 2、檢查Android Studio和gradle版本是否為alpha版本,換為穩定版本 3、檢查是否關閉Instant Run功能,關掉此功能 4、檢查是 ...
  • 一、具體問題 開發的過程中,發現某個界面部分圖片的顯示出現了問題只顯示占點陣圖片,取出圖片的url在瀏覽器卻是能打開的,各種嘗試甚至找同行的朋友幫忙在他們項目里展示都會存在問題,最終發現通過第三方框架SDWebImage或者YYWebImage下載帶有逗號的url圖片鏈接都會下載失敗,在下載方法完成的 ...
  • 關於實現MVVM,網上實在是太多了,本文為個人總結,結合源碼以及一些別人的實現 關於雙向綁定 vue 數據劫持 + 訂閱 發佈 ng 臟值檢查 backbone.js 訂閱 發佈(這個沒有使用過,並不是主流的用法) 雙向綁定,從最基本的實現來說,就是在defineProperty綁定的基礎上在綁定i ...
  • 文件夾主要建立以下文件夾: 1、Images 存放一些網站常用的圖片; 2、Css 存放一些CSS文件; 3、Flash 存放一些Flash文件; 4、PSD 存放一些PSD源文件; 5、Temp 存放所有臨時圖片和其它文件; 6、copyright 版權信息(可選) 8、readme 說明文件 c ...
  • React Native開發中自動打包腳本 在日常的RN開發中,我們避免不了需要將我們編寫的代碼編譯成安裝包,然後生成二維碼,供需要測試的人員掃描下載。但是對於非原生的開發人員來說,可能不知如何使用Xcode或者Android studio來導出ipa、apk安裝包,為瞭解決非原生開發的同學們打安裝 ...
  • JavaScript語句 JavaScript語句向瀏覽器發出命令,語句的作用是告訴瀏覽器該乾什麼。 JavaScript分號 ; 分號用於分隔JavaScript語句。 通常我們在每條可執行的語句尾添加分號。 另一個作用是在一行中編寫多條語句。 a = 5; b = 4; c = a + b; a ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...