一道有趣的erlang建模練習

来源:http://www.cnblogs.com/magicbowen/archive/2016/05/26/5529523.html
-Advertisement-
Play Games

一道有趣的erlang建模練習 領域建模在於不斷挖掘領域的本質,然後用優秀的代碼簡潔地表現出來。而函數式非常適合將領域映射到數學本質上。前一陣子學習erlang,用erlang做了一些練習,分享其中的一個。 practice 1 : count tiangle 題目: 數數如下圖形中一共包含多少三角 ...


一道有趣的erlang建模練習

領域建模在於不斷挖掘領域的本質,然後用優秀的代碼簡潔地表現出來。而函數式非常適合將領域映射到數學本質上。前一陣子學習erlang,用erlang做了一些練習,分享其中的一個。

practice 1 : count tiangle

題目: 數數如下圖形中一共包含多少三角形?

答案是24,你數對了嗎?回憶一下你剛纔是怎麼數的?

這道題如果由人來數,每個人數法各異!但是如果要交給電腦來做,就必須將數的方法描述成電腦可以執行的形式化演算法。這種描述方法可以有非常多種,而我們希望找到一套抽象層次高的和領域非常貼切的描述,以降低後續理解、維護成本。

對於該問題,我們首先站在領域角度定義什麼是三角形?

triangle([A, B, C]) ->
    connected(A, B) andalso
    connected(B, C) andalso
    connected(C, D) andalso
    (not in_same_line(A, B, C)).

如上,我們定義了一個三角形就是三個點,兩兩相連,但是三個點不同時在一條直線上。

對於如上描述,關鍵是如何定義connectedin_same_line
對於connected,就是兩個點同時在一條直線連接上。那麼什麼是一條直線連接?
由於我們關註的是點線上上的關係,所以我們定義一條直線為在直線上所有點得集合。
例如對以上例,我們存在直線:[a, b, h],[a, c, g, i]等等。

我們把上圖中所有直線用erlang描述出來:

lines() ->
    ["abh", "acgi", "adfj", "aek", "bcde", "hgfe", "hijk"].

由於我們用單字元表示點,而字元串在erlang中實際就是list,所以我們將一條直線簡寫為線上上所有點的字元的字元串。

有了對直線的定義,接下來,一個點是否在直線上,那就是元素與集合的屬於關係;而兩個點是否相連就是集合與集合之間的包含關係。

subset([], _S) -> true;
subset([H|T], S) -> 
    lists:member(H, S) andalso subset(T, S).

belong(_, []) -> false;
belong(S, [H|T]) -> subset(S, H) orelse belong(S, T).

connected(P1, P2) -> belong([P1, P2], lines()).

in_same_line(P1, P2, P3) -> belong([P1, P2, P3], lines()).

可以看到,connected的定義是兩個點組成的集合屬於所有直線的集合的任一個的子集。而in_same_line則是三個點的集合屬於所有直線的集合的任一個的子集。
我們在這裡將該問題映射到熟悉的集合領域。

在有了對connectedin_same_line的定以後,我們就可以對triangle進行測試了!

test() ->
    true = triangle("abc"),
    false = triangle("abh").

下來我們來進行數三角形。要能夠數三角形,我們需要找到所有三個點的組合,用來驗證是否滿足triangle?將滿足triangle的進行統計,這樣我們就得到了結果!

在這裡我們已經有了所有點的集合:

Points = "abcdefghijk"

為了得到所有3個點的組合,我們實現一個演算法,對於集合L,求其N個元素的所有組合的集合。

comb(L, 1) -> [[I] || I <- L];
comb(L, N) when length(L) =:= N -> [L];
comb([H|T], N) -> 
    [[H|R] || R <- comb(T, N - 1)] ++ comb(T, N).
Points = "abcdefghijk",
TriplePoints = comb(Points, 3),

下麵我們實現一個count方法,用來數滿足要求的三角形個數:

count(Triple) -> count(Triple, 0).

count([], N) -> N;
count([H|T], N) ->
    case triangle(H) of
        true -> count(T, N + 1);
        false -> count(T, N)
    end.

最後可以調用run測試一下是不是24!

run() ->
    Points = "abcdefghijk",
    TriplePoints = comb(Points, 3),
    count(TriplePoints).

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

-Advertisement-
Play Games
更多相關文章
  • http://www.cnblogs.com/huangcong/archi s.strip() .lstrip() .rstrip(',') 去空格及特殊符號 複製字元串 Python 1 #strcpy(sStr1,sStr2) 2 sStr1 = 'strcpy' 3 sStr2 = sStr ...
  • 1、首先我們必須弄清楚什麼是冒泡排序,不理解冒泡排序的原理,我們就無法寫出代碼。 冒泡排序(BubbleSort)的基本概念是:依次比較相鄰的兩個數,將小數放在前面,大數放在後面。即在第一趟:首先比較第1個和第2個數,將小數放前,大數放後。然後比較第2個數和第3個數,將小數放前,大數放後,如此繼續, ...
  • 在使用Qt開發時,肯定是想讓開發的項目界面統一風格;不希望每個界面都要程式員用代碼去修飾美化以及進行事件處理等等,這樣非常繁瑣,容易出錯而且沒有格調;所以我就開發一個動態鏈接庫,封裝統一的風格界面、事件處理等等;自己開發的這個庫叫做CQU;CQU庫最終提供給用戶的文件只有如下三個文件: CQU.dl ...
  • 1.Appfuse是個什麼鬼? AppFuse是一個集成了當前最流行的Web應用框架的一個更高層次的Web開發框架。換句話說,AppFuse就是一個完整的各主流框架的整合版本。AppFuse總是能夠緊隨java的主流技術框架。 2.使用AppFuse的環境要求 JDK1.7+ MySQL5.5+ m ...
  • 第一次系統的學習數據結構是在半年前,看小甲魚的數據結構與演算法視頻,自學的話有許多不懂得地方,什麼AVL樹,紅黑樹,圖的最短路徑,最小生成樹...但總歸對數據結構與演算法有一個大體的印象,到現在隨著不斷寫代碼,做OJ題,愈發認識到數據結構與演算法的重要性,打算再看一遍,現在看著:大話數據結構(程傑著),數 ...
  • 最好用的離線markdown編輯器Haroopad介紹 經常寫技術文檔,需要將文檔像代碼一樣管理,例如可以提交SVN或者GIT,可以比對歷史差異。用WORD之類的工具,文檔不是純文本,沒法滿足需求。用簡單文本沒有格式不美觀。Latex最強大,但是對於一般文檔撰寫又太重量,配置一個好的模板太費神,而且 ...
  • 分頁在後臺管理中是經常使用的功能,分頁顯示方便大量數據的管理。 實例代碼如下: ...
  • 所謂內置方法,就是凡是字元串都能用的方法,這個方法在創建字元串的類中,下麵是總結: 首先,我們要學習一個獲取幫助的內置函數 help(對象) ,對象可以是一個我們創建出來的,也可以是創建對象的那個類,類也是一個對象,被稱為類對象。 當我們進入解釋器的交互模式中輸入以下代碼時: 其中,str就是創建字 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...