因數分解美國總統
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 
( 45 ) Donald John Trump
1529 = 11 * 139 
(46) Joe Biden
768 = 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 3 * 1 
 OK