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
로 구현 패턴 ㄴ 수 즉, 각각의 루프를 통과에 새로이 평가 될 수 있도록
SetAttributes[generatorSelect, HoldFirst]
generatorSelect[generator_, predicate_] :=
While[True, generator /. s_ :> If[predicate[s], Return[s]]]
generator
인자가 평가되지 않은 형태로 유지된다 : 임의 발생 및 필터링 기능을 수락 파라미터 E. 이 새로운 기능을 다음과 같이 사용할 수 있습니다.
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 루프의 마지막 줄 while의 출력은';'로 인해 억제되므로 아무 것도하지 않습니다. 루프가 원하는 조건과 일치하는 목록을 선택하면 루프 뒤의'f'가 선택된 목록을 반환합니다. – rcollyer