#! /usr/bin/env ueforth

s" /usr/share/dict/words" r/o open-file throw value dict-words
dict-words file-size throw constant dict-size
dict-size 1+ allocate throw value dict-data
dict-data dict-size dict-words read-file throw drop
0 dict-data dict-size + c!  ( null terminate )

: upper ( ch -- ch) 95 and ;
: upper*s ( a n -- ) 0 do dup c@ upper over c! 1+ loop drop ;
dict-data dict-size upper*s

: next-word ( a -- a ) begin 1+ dup c@ nl = until 1+ ;
: each-step ( a -- a' a n ) dup next-word swap over over - 1- ;
: each{   postpone begin postpone dup postpone c@
          postpone while postpone each-step ; immediate
: }each   postpone repeat ; immediate

create letters 256 cells allot
letters 256 cells 0 fill
0 value total
: letter+ ( ch -- ) cells letters + 1 swap +! ;
: letter@ ( ch -- n ) cells letters + @ ;
: init-frequencies
  dict-data each{
    0 ?do dup i + c@ letter+ 1 +to total loop drop 
  }each
;

: n. ( n -- )
  10000 total */ <# # # # # [char] . hold #s #> type ;
: table.
  [char] Z 1+ [char] A do
    i emit space i letter@ n. cr
  loop
;

: letter? ( ch -- f ) dup [char] A >= swap [char] Z <= and ;
: letters? ( a n ) -1 swap 0 do >r dup c@ letter? >r 1+ r> r> and loop nip ;

: word-freq ( a n -- n ) 
  0 -rot 0 do dup i + c@ letter@ rot + swap loop drop ;
: run
  init-frequencies
  table.
  cr
  dict-data each{
    dup 5 = >r 2dup letters? r> and if
      2dup type space
      word-freq n. cr
    else
      2drop
    then
  }each
;
run bye

A 0.0771
B 0.0185
C 0.0380
D 0.0336
E 0.1049
F 0.0125
G 0.0268
H 0.0232
I 0.0790
J 0.0023
K 0.0101
L 0.0488
M 0.0267
N 0.0677
O 0.0582
P 0.0261
Q 0.0018
R 0.0679
S 0.1088
T 0.0623
U 0.0309
V 0.0094
W 0.0089
X 0.0025
Y 0.0150
Z 0.0039

6112 five letter words
   out of 102401

AARON 0.3482
ABBAS 0.3002
ABDUL 0.2092
ABNER 0.3364
ABRAM 0.2676
ABUJA 0.2062
ACCRA 0.2983
ACRUX 0.2166
ACTON 0.3035
ACUFF 0.1712
ADAMS 0.3235
ADANA 0.3329
ADDIE 0.3284
ADELA 0.3417
ADELE 0.3695
ADLER 0.3325
ADOLF 0.2304
ADVIL 0.2481
AESOP 0.3752

YOKEL 0.2371
YOKES 0.2971
YOLKS 0.2410
YOUNG 0.1987
YOURS 0.2809
YOUTH 0.1898
YOWLS 0.2398
YUCCA 0.1991
YUCKS 0.2029
YUCKY 0.1091
YUMMY 0.1144
YUPPY 0.1132
ZEBRA 0.2725
ZEBUS 0.2672
ZEROS 0.3438
ZESTS 0.3888
ZILCH 0.1931
ZINCS 0.2975
ZINGS 0.2863
ZIPPY 0.1502
ZOMBI 0.1865
ZONAL 0.2559
ZONED 0.2685
ZONES 0.3436
ZOOMS 0.2559