函數f
將list
作爲自由變量而不是參數。雖然這不是一個無法克服的障礙,但它的確讓這個功能包裝起來很尷尬,所以它可以在Table
中使用。讓我們重新修正這些定義,並沿用一些簡化方法。
首先,讓我們解決測試,以樣品是否是可以接受的:
acceptableQ[sample_] :=
MemberQ[sample, n_ /; n > 31] &&
1 <= Count[sample, n_ /; n <= 12] <= 2 &&
Count[sample, n_ /; divisible2to7[n]] <= 3
divisible2to7[n_] := MemberQ[Range[2, 7], d_ /; Divisible[n, d]]
主要簡化從原來是嵌套If
報表已經變平成And
條件。新定義還利用了這樣一個事實,即Count
可以測試列表值而不必調用嵌套Select
。此外,存在檢查已使用MemberQ[...]
表示。引入了輔助函數來執行可分性檢查,以減少主要測試表達式的視覺複雜性。請注意,原始可分性檢查錯誤地返回了預期布爾值的列表。 _Integer
頭部測試已被刪除,但如果它們被認爲是可取的,則可以通過將每個n_
更改爲n_Integer
來重新引入。
現在我們只需要一種方法來生成一個循環的樣品直至達到可接受的一個發現:
generateSample[] :=
While[
True
, RandomSample[Range[36], 7] /.
s_ :> If[acceptableQ[s], Return[Sort @ s]]
]
generateSample[]
現在可以用來產生儘可能多的結果表需要:
In[113]:= Table[generateSample[], {5}]
Out[113]= {{6, 13, 17, 19, 25, 29, 33}, {1, 11, 13, 15, 31, 35, 36},
{1, 10, 17, 23, 25, 31, 32}, {1, 6, 17, 19, 22, 23, 33},
{8, 17, 19, 23, 30, 31, 36}}
歸納格局
體現在generateSample
圖案可以b ë參數接受任意發生器和濾波器功能:
SetAttributes[generatorSelect, HoldFirst]
generatorSelect[generator_, predicate_] :=
While[True, generator /. s_ :> If[predicate[s], Return[s]]]
的generator
參數被保持在不計算形式,使得可以重新在每次通過循環進行評價。這個新功能可以這樣使用:
In[114]:= Table[
generatorSelect[RandomSample[Range[36], 7], acceptableQ] // Sort
, {5}
]
Out[114]= {{9, 17, 19, 23, 27, 29, 32}, {8, 13, 17, 19, 22, 23, 35},
{4, 17, 19, 21, 23, 29, 36}, {1, 8, 15, 19, 23, 31, 33},
{1, 10, 17, 19, 24, 29, 36}}
新功能的優點是它可以與任何發生器和過濾器功能一起使用。這裏我們生成三個總和爲7的整數元組。
In[115]:= Table[
generatorSelect[RandomInteger[7, 3], Total[#] == 7 &]
, {5}
]
Out[115]= {{2, 3, 2}, {0, 5, 2}, {5, 0, 2}, {2, 4, 1}, {2, 1, 4}}
作爲一個風格問題,有些人更喜歡以避免定義與Hold
屬性,除非絕對必要的功能。 generatorSelect2
反映了設計選擇:
generatorSelect2[generator_, predicate_] :=
While[True, generator[] /. s_ :> If[predicate[s], Return[s]]]
這和generatorSelect
之間的唯一區別是,第一個參數目前預計評估的功能:
In[116]:= Table[
generatorSelect2[RandomInteger[7, 3] &, Total[#] == 7 &]
, {5}
]
Out[116]= {{5, 1, 1}, {3, 0, 4}, {0, 1, 6}, {3, 2, 2}, {4, 1, 2}}
書面,在while循環的最後一行不會做任何事情,因爲後面的';'會壓制輸出。當循環選擇一個匹配你想要的條件的列表時,循環後面的'f'將返回所選擇的列表。 – rcollyer