一道erlang的建模練習(xí)

領(lǐng)域建模在于不斷挖掘領(lǐng)域的本質(zhì)广料,然后用優(yōu)秀的代碼簡潔地表現(xiàn)出來。而函數(shù)式非常適合將領(lǐng)域映射到數(shù)學(xué)本質(zhì)上幼驶。前一陣子學(xué)習(xí)erlang艾杏,用erlang做了一些練習(xí),分享其中的一個(gè)盅藻。


題目: 數(shù)數(shù)如下圖形中一共包含多少三角形购桑?

答案是24,你數(shù)對了嗎氏淑?回憶一下你剛才是怎么數(shù)的其兴?

這道題如果由人來數(shù),每個(gè)人數(shù)法各異夸政!但是如果要交給計(jì)算機(jī)來做元旬,就必須將數(shù)的方法描述成計(jì)算機(jī)可以執(zhí)行的形式化算法。這種描述方法可以有非常多種守问,而我們希望找到一套抽象層次高的和領(lǐng)域非常貼切的描述匀归,以降低后續(xù)理解、維護(hù)成本耗帕。

對于該問題穆端,我們首先站在領(lǐng)域角度定義什么是三角形?

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

如上仿便,我們定義了一個(gè)三角形就是三個(gè)點(diǎn)体啰,兩兩相連攒巍,但是三個(gè)點(diǎn)不同時(shí)在一條直線上。

對于如上描述荒勇,關(guān)鍵是如何定義connectedin_same_line柒莉。
對于connected,就是兩個(gè)點(diǎn)同時(shí)在一條直線連接上沽翔。那么什么是一條直線連接兢孝?
由于我們關(guān)注的是點(diǎn)在線上的關(guān)系,所以我們定義一條直線為在直線上所有點(diǎn)得集合仅偎。
例如對以上例跨蟹,我們存在直線:[a, b, h],[a, c, g, i]等等。

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

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

由于我們用單字符表示點(diǎn)橘沥,而字符串在erlang中實(shí)際就是list窗轩,所以我們將一條直線簡寫為在線上所有點(diǎn)的字符的字符串。

有了對直線的定義座咆,接下來品姓,一個(gè)點(diǎn)是否在直線上,那就是元素與集合的屬于關(guān)系箫措;而兩個(gè)點(diǎn)是否相連就是集合與集合之間的包含關(guān)系。

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的定義是兩個(gè)點(diǎn)組成的集合屬于所有直線的集合的任一個(gè)的子集斤蔓。而in_same_line則是三個(gè)點(diǎn)的集合屬于所有直線的集合的任一個(gè)的子集。
我們在這里將該問題映射到熟悉的集合領(lǐng)域镀岛。

在有了對connectedin_same_line的定以后弦牡,我們就可以對triangle進(jìn)行測試了!

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

下來我們來進(jìn)行數(shù)三角形漂羊。要能夠數(shù)三角形驾锰,我們需要找到所有三個(gè)點(diǎn)的組合,用來驗(yàn)證是否滿足triangle走越?將滿足triangle的進(jìn)行統(tǒng)計(jì)椭豫,這樣我們就得到了結(jié)果!

在這里我們已經(jīng)有了所有點(diǎn)的集合:

Points = "abcdefghijk"

為了得到所有3個(gè)點(diǎn)的組合旨指,我們實(shí)現(xiàn)一個(gè)算法赏酥,對于集合L,求其N個(gè)元素的所有組合的集合谆构。

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),

下面我們實(shí)現(xiàn)一個(gè)count方法,用來數(shù)滿足要求的三角形個(gè)數(shù):

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.

最后可以調(diào)用run測試一下是不是24搬素!

run() ->
    Points = "abcdefghijk",
    TriplePoints = comb(Points, 3),
    count(TriplePoints).
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末呵晨,一起剝皮案震驚了整個(gè)濱河市魏保,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌摸屠,老刑警劉巖谓罗,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異餐塘,居然都是意外死亡妥衣,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進(jìn)店門戒傻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來税手,“玉大人,你說我怎么就攤上這事需纳÷梗” “怎么了?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵不翩,是天一觀的道長兵扬。 經(jīng)常有香客問我,道長口蝠,這世上最難降的妖魔是什么器钟? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮妙蔗,結(jié)果婚禮上傲霸,老公的妹妹穿的比我還像新娘。我一直安慰自己眉反,他們只是感情好昙啄,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著寸五,像睡著了一般梳凛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上梳杏,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天韧拒,我揣著相機(jī)與錄音,去河邊找鬼十性。 笑死叭莫,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的烁试。 我是一名探鬼主播雇初,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼减响!你這毒婦竟也來了靖诗?” 一聲冷哼從身側(cè)響起郭怪,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎刊橘,沒想到半個(gè)月后鄙才,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡促绵,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年攒庵,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片败晴。...
    茶點(diǎn)故事閱讀 39,991評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡浓冒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出尖坤,到底是詐尸還是另有隱情稳懒,我是刑警寧澤,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布慢味,位于F島的核電站场梆,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏纯路。R本人自食惡果不足惜或油,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望驰唬。 院中可真熱鬧顶岸,春花似錦、人聲如沸定嗓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽宵溅。三九已至,卻和暖如春上炎,著一層夾襖步出監(jiān)牢的瞬間恃逻,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工藕施, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留寇损,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓裳食,卻偏偏與公主長得像矛市,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子诲祸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評論 2 355

推薦閱讀更多精彩內(nèi)容