從Project Euler中我們學到了什麼?

最近做Project Euler的第41問時學到了不少東西,數論、Mathematica⋯⋯

題目是這樣的:如果一個n位數的各位數字中恰好1到n各出現了一次,那麼就說這個數pandigital。比如,2143就是一個4位的pandigital質數。請問是否存在最大的pandigital質數?

我不管三七二十一,用Ruby暴力搜索了好一會,終於獲得了論壇的入場券。Project Euler問題後面的討論是一筆寶貴的財富,你總能找到一些耀眼的思想火花。比如,我就看到了某哥們寫到:

 

以前我總認爲Mathematica不過是把圓括號變成方括號的Lisp,語法應該不難,但現在我懵了,這是什麼寫法。我不喜歡Mathematica,主要是因爲我不喜歡那一大砣看似毫無聯繫的函數。但現在,我決定好好地學學Mathematica。

Mathematica繼承了Lisp簡約的語法和統一的形式,雖然在list的實現方式上略有不同(Mathematica是用數組而非鏈接表來實現list的)。

  1. Mathematica中一切都皆爲表達式(其實也好理解,Lisp程序不就是由lisp構成的嗎)
  2. 模式匹配和代入規則

a->b

這句話的意思是,凡遇到a,則替換爲b。如果要應用規則,則需要用/.來應用規則。

Mathematica計算的核心是一個循環:它根據表達式不斷地套用規則,直到結果不再變化爲止。

 

Mathematica中的四種括號:

  • 圓括號( ),用於改變操作的結合順序;
  • 花括號{ },專用於列表;
  • 單方括號[ ],標識表達式的域;
  • 雙方括號[[ ]],Part函數的簡寫,作用同下標。

II 純函數,就是Mathematica中的Λ-算子

Function[x, body]等價於body&

這裏先介紹四個記號用於純函數中的特殊記號:

  • #n,表示第n個參數;
  • #,表示第一個參數,即#1;
  • ##,表示所有參數;
  • ##n,表示第n個及之後的參數。

III 一些語言習慣

函數都是平等的,但總有些函數更平等,因爲它們應用得更廣泛。本着少寫代碼的原則,Wolfram爲這些高階函數制定了一些“黑話”:

Mathematica中的Map和Apply

IV 最後介紹一下Mathematica中函數的幾種作用方式:

Mathematica中的函數作用方式

 

現在可以看看我們那位美國仁兄用了多少奇技淫巧了。他動用了函數的四種作用方式、Map的簡寫等來隱藏其背後蠻力搜索的直白算法^_^

Project Euler Problem 41 using Mathematica

最後,說說那個不起眼的7。我們要找一個最大的pandigital質數,但其實只要搜索1到987654321就行了。但987654321畢竟也是個很大的數,但注意到我們要考慮的只是1到n的輪換,而且還是質數,所以沒必要搜索987654321個數。另外,我們注意到

1+……+9 = 45,

1+……+8 = 36,

1+……+7 = 28

1+……+6 = 21,

1+……+5 = 15,

1+……+4 = 10

1+……+3 = 6,

1+……+2 = 3,

(1就不用考慮了,它連質數都不算)

除了1到4和1到7,其他都能被3整除(說明這些組合都是3的倍數)

其實,只需考慮1到7的情況,誰讓它大呢!

Fold[Plus, 0, Range[1, 9]]

這裏又要多一句,爲什麼一個數的各位數相加,如果其和能被3整除,則其數能被3整除。

各位數之和能被3整除,則其數能被3整除

顯而易見, 只要(an + …… + a2 + a1)能被3整除,那麼 an……a2a1也能被3整除。

P.S. 7652413

發佈了72 篇原創文章 · 獲贊 3 · 訪問量 24萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章