因數分解美國總統
Ching-Tang
Tseng
Hamilton, New
Zealand
16 January
2019
ilikeforth@gmail.com
這是一個展示能從傳統 FORTH 程式叫用 BASIC 式程式的精簡範例‧
題目很簡單:就是把英文字串的碼加總起來,當作該字串的特徵值‧然後,將此值進行澈底地因數分解,最後,列印出以全部質數連乘方式表示的結果‧
提供程式所需資料的來源,採用易於取得的歷任美國總統姓名作為輸入字串‧第 0 筆資料則故意安排為本文作者的姓名‧
為了顯示 FORTH 程式語言的傳承效果,本文刻意採用 35 年前(1983)古聖先賢 Martin Tracy 在其設計之 APPLE II MicroMotion FORTH-79 系統中的創作,來設計字串陣列的結構‧這樣的資料結構,照樣能適用於
35 年後今天正在使用中的 64 位元 Lina64 系統,此一特性凸顯出傳承效果的可貴‧資料結構的設計方法不是僅此一種,採用這樣的設計,純粹只是為了程式使用時很方便所做的選擇‧
由於提供程式使用的資料量有 46 筆,數量稍嫌過大,因此,將資料結構的宣告程式,以及全部輸入的字串資料,安排在另一個提供資料來源的 MartinTracyString.f 檔案中形成‧
從 factorize.f 主程式的內容中可以看得出來,BASIC 式程式的語法,有利於設計數學計算程式,但不利於設計字串輸出方面的程式‧因此,這部份的功能缺陷,仍然需要使用傳統 FORTH 的格式設計程式,然後,再在 BASIC 式程式中,強行利用 RUN 指令來執行 FORTH 指令,以達到彌補功能缺陷目的‧有些答案尾端帶有 * 1 的結果,那是為了美化輸出所做的例外安排‧
原始程式是全用傳統 FORTH 設計的‧原本執行因數分解的部分,由於閱讀困難,不易追蹤,因此,重新改寫成以
BASIC 方式執行的程式,程式便可一目了然‧後續主程式的部分,則完全不需改寫,也是其特色‧
1. 主程式
factorize.f
\ Designer: Ching-Tang Tseng
\ Date: 20190116, Hamilton,
New Zealand
FLOAD MartinTracyString.f
VARIABLE LUCKY
5 integers N D P Q R
: FACTORIZE ( n -- )
[[ N ]] !
BASIC
\ 10 print " Enter
integer number to be factorized "
\ 20 inputi N
30 print " " ; N ;
" = "
\ Test if multiple of 2
40 let R = 2
50 let D = N mod R
60 if D = 0 then 80
70 goto 110
80 run R . ." * "
90 let N = N / R
100 goto -50
\ Test if multiple of 3
110 let R = 3
120 let D = N mod R
130 if D = 0 then 150
140 goto 200
150 run R . ." * "
160 let N = N / R
170 goto -120
\ Test of divisors 6P-1 and
6P+1 up to sqr(N)
\ Prime numbers are of the
form 6P-1 or 6P+1
200 let Q = sqrt ( N ) + 1
210 for P = 6 to Q step 6
220 let R = P - 1
230 let D = N mod R
240 if D = 0 then 260
250 goto 300
260 run R . ." * "
270 let N = N / R
280 goto -230
300 let R = P + 1
310 let D = N mod R
320 if D = 0 then 340
330 goto 400
340 run R . ." * "
350 let N = N / R
360 goto -310
400 next P
500 if N > 1 then 530
510 run 1 .
520 goto 600
530 run N .
600 end ;
: STRING>PAD>NUMBER ( addr cnt -- n )
PAD 80 BLANK
>R PAD R@ CMOVE
0
R> 0
DO PAD I + C@
DUP 32 =
IF DROP ELSE + THEN
LOOP ;
: MAIN ( -- )
46 0 \
46 is adjustable
DO
I USP STRING>PAD>NUMBER LUCKY !
CR ." ( " I . ." ) " I USP TYPE
LUCKY @ FACTORIZE CR
LOOP ;
2. 提供數據來源的資料程式 MartinTracyString.f
\ String array designed by
Martin Tracy
\ APPLE II MicroMotion
FORTH-79, Martin Tracy, 1983
\ Modified to fit AMDX86
ciforth 5.3.0 (Lina64), 20190116
: SARRAY ( cnt n -- ) \ cnt characters/array, total n arrays
CREATE 1+ 0 ( cnt n -- )
DO DUP C, 0 C, DUP ALLOT LOOP DROP
DOES> DUP C@ 2 + ROT * + 1+ COUNT ; ( n -- addr cnt )
: S! ( addr1 cnt1 addr2 cnt2
-- )
DROP DUP 2 - C@
ROT MIN >R DUP 1- R@ SWAP C! R> CMOVE ;
80 100 SARRAY USP
\ 0
S" Ching Tang
Tseng" 0 USP S!
\ 1
S" George
Washington" 1 USP S!
\ 2
S" John Adams" 2 USP S!
\ 3
S" Thomas
Jefferson" 3 USP S!
\ 4
S" James
Madison" 4 USP S!
\ 5
S" James Monroe" 5 USP S!
\ 6
S" John Quincy
Adams" 6 USP S!
\ 7
S" Andrew
Jackson" 7 USP S!
\ 8
S" Martin Van
Buren" 8 USP S!
\ 9
S" William Henry
Harrison" 9 USP S!
\ 10
S" John Tyler" 10 USP S!
\ 11
S" James K.
Polk" 11 USP S!
\ 12
S" Zachary
Taylor" 12 USP S!
\ 13
S" Millard
Fillmore" 13 USP S!
\ 14
S" Franklin
Pierce" 14 USP S!
\ 15
S" James
Buchanan" 15 USP S!
\ 16
S" Abraham
Lincoln" 16 USP S!
\ 17
S" Andrew
Johnson" 17 USP S!
\ 18
S" Ulysses S.
Grant" 18 USP S!
\ 19
S" Rutherford B.
Hayes" 19 USP S!
\ 20
S" James A.
Garfield" 20 USP S!
\ 21
S" Chester A.
Arthur" 21 USP S!
\ 22
S" Grover
Cleveland" 22 USP S!
\ 23
S" Benjamin
Harrison" 23 USP S!
\ 24
S" Grover
Cleveland" 24 USP S!
\ 25
S" William
McKinley" 25 USP S!
\ 26
S" Theodore
Roosevelt" 26 USP S!
\ 27
S" William Howard
Taft" 27 USP S!
\ 28
S" Woodrow
Wilson" 28 USP S!
\ 29
S" Warren G.
Harding" 29 USP S!
\ 30
S" Calvin
Coolidge" 30 USP S!
\ 31
S" Herbert
Hoover" 31 USP S!
\ 32
S" Franklin D.
Roosevelt" 32 USP S!
\ 33
S" Harry S.
Truman" 33 USP S!
\ 34
S" Dwight D. Eisenhower" 34 USP S!
\ 35
S" John F.
Kennedy" 35 USP S!
\ 36
S" Lyndon B.
Johnson" 36 USP S!
\ 37
S" Richard
Nixon" 37 USP S!
\ 38
S" Gerald Ford" 38 USP S!
\ 39
S" Jimmy
Carter" 39 USP S!
\ 40
S" Ronald
Reagan" 40 USP S!
\ 41
S" George H. W.
Bush" 41 USP S!
\ 42
S" Bill
Clinton" 42 USP S!
\ 43
S" George W.
Bush" 43 USP S!
\ 44
S" Barack
Obama" 44 USP S!
\ 45
S" Donald John
Trump" 45 USP S!
\ 46
S" Joe Biden" 46 USP S!
3. 執行結果
ching@center:~$ cd lina64
ching@center:~/lina64$ ./f
AMDX86 ciforth 5.3.0
fload factorize.f
n : ISN'T UNIQUE
D : ISN'T UNIQUE
p : ISN'T UNIQUE
OK
main
( 0 ) Ching Tang Tseng
1396 = 2 * 2 * 349
( 1 ) George Washington
1659 = 3 * 7 * 79
( 2 ) John Adams
885 = 3 * 5 * 59
( 3 ) Thomas Jefferson
1550 = 2 * 5 * 5 * 31
( 4 ) James Madison
1211 = 7 * 173
( 5 ) James Monroe
1120 = 2 * 2 * 2 * 2 * 2 * 5 *
7 * 1
( 6 ) John Quincy Adams
1518 = 2 * 3 * 11 * 23
( 7 ) Andrew Jackson
1322 = 2 * 661
( 8 ) Martin Van Buren
1420 = 2 * 2 * 5 * 71
( 9 ) William Henry Harrison
2075 = 5 * 5 * 83
( 10 ) John Tyler
927 = 3 * 3 * 103
( 11 ) James K. Polk
1023 = 3 * 11 * 31
( 12 ) Zachary Taylor
1357 = 23 * 59
( 13 ) Millard Fillmore
1535 = 5 * 307
( 14 ) Franklin Pierce
1421 = 7 * 7 * 29 * 1
( 15 ) James Buchanan
1296 = 2 * 2 * 2 * 2 * 3 * 3 *
3 * 3 * 1
( 16 ) Abraham Lincoln
1403 = 23 * 61
( 17 ) Andrew Johnson
1344 = 2 * 2 * 2 * 2 * 2 * 2 *
3 * 7 * 1
( 18 ) Ulysses S. Grant
1397 = 11 * 127
( 19 ) Rutherford B. Hayes
1679 = 23 * 73
( 20 ) James A. Garfield
1405 = 5 * 281
( 21 ) Chester A. Arthur
1459 = 1459
( 22 ) Grover Cleveland
1539 = 3 * 3 * 3 * 3 * 19
( 23 ) Benjamin Harrison
1642 = 2 * 821
( 24 ) Grover Cleveland
1539 = 3 * 3 * 3 * 3 * 19
( 25 ) William McKinley
1515 = 3 * 5 * 101
( 26 ) Theodore Roosevelt
1789 = 1789
( 27 ) William Howard Taft
1731 = 3 * 577
( 28 ) Woodrow Wilson
1389 = 3 * 463
( 29 ) Warren G. Harding
1441 = 11 * 131
( 30 ) Calvin Coolidge
1411 = 17 * 83
( 31 ) Herbert Hoover
1343 = 17 * 79
( 32 ) Franklin D. Roosevelt
1898 = 2 * 13 * 73
( 33 ) Harry S. Truman
1278 = 2 * 3 * 3 * 71
( 34 ) Dwight D. Eisenhower
1778 = 2 * 7 * 127
( 35 ) John F. Kennedy
1233 = 3 * 3 * 137
( 36 ) Lyndon B. Johnson
1475 = 5 * 5 * 59
( 37 ) Richard Nixon
1225 = 5 * 5 * 7 * 7 * 1
( 38 ) Gerald Ford
986 = 2 * 17 * 29
( 39 ) Jimmy Carter
1127 = 7 * 7 * 23 * 1
( 40 ) Ronald Reagan
1198 = 2 * 599
( 41 ) George H. W. Bush
1254 = 2 * 3 * 11 * 19
( 42 ) Bill Clinton
1114 = 2 * 557
( 43 ) George W. Bush
1136 = 2 * 2 * 2 * 2 * 71
( 44 ) Barack Obama
1060 = 2 * 2 * 5 * 53
(46) Joe Biden
768 = 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 3 * 1
OK