Jump to content

Prime words

From Rosetta Code
Revision as of 10:56, 26 August 2024 by Tigerofdarkness (talk | contribs) (Moved Ada to the correct place)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Prime words is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

A word is a   prime word   if all its individual letters   (expressed as an ASCII decimal code)   are primes.


        A   ASCII decimal code is:   65 
        B   ASCII decimal code is:   66 
        C   ASCII decimal code is:   67 
                 
        X   ASCII decimal code is:   88 
        Y   ASCII decimal code is:   89 
        Z   ASCII decimal code is:   90 
                 
        a   ASCII decimal code is:   97 
        b   ASCII decimal code is:   98 
        c   ASCII decimal code is:   99 
                 
        x   ASCII decimal code is:   120 
        y   ASCII decimal code is:   121 
        z   ASCII decimal code is:   122 
Task

Show here on this page every   prime word   in unixdict.txt.



11l

F is_prime(Int a)
   I a == 2
      R 1B
   I a < 2 | a % 2 == 0
      R 0B
   L(i) (3 .. Int(sqrt(a))).step(2)
      I a % i == 0
         R 0B
   R 1B

Set[Int] prime_chars
L(c) ‘a’.code .. ‘z’.code
   I is_prime(c)
      prime_chars.add(c)
L(c) ‘A’.code .. ‘Z’.code
   I is_prime(c)
      prime_chars.add(c)

L(word) File(‘unixdict.txt’).read().split("\n")
   L(c) word
      I c.code !C prime_chars
         L.break
   L.was_no_break
      print(word)
Output:
a
aaa
age
agee
ak
am
ama
e
egg
eke
em
emma
g
ga
gag
gage
gam
game
gamma
ge
gee
gem
gemma
gm
k
keg
m
ma
mae
magma
make
mamma
me
meek
meg
q

Action!

In the following solution the input file is loaded from H6 drive. Altirra emulator automatically converts CR/LF character from ASCII into 155 character in ATASCII charset used by Atari 8-bit computer when one from H6-H10 hard drive under DOS 2.5 is used.

INCLUDE "H6:SIEVE.ACT"

BYTE FUNC IsPrimeWord(CHAR ARRAY word BYTE ARRAY primes)
  BYTE i,c

  FOR i=1 TO word(0)
  DO
    c=word(i)
    IF primes(c)=0 THEN
      RETURN (0)
    FI
  OD
RETURN (1)

PROC FindPrimeWords(CHAR ARRAY fname BYTE ARRAY primes)
  CHAR ARRAY line(256)
  CHAR ARRAY tmp(256)
  BYTE pos,dev=[1]

  pos=2
  Close(dev)
  Open(dev,fname,4)
  WHILE Eof(dev)=0
  DO
    InputSD(dev,line)
    IF IsPrimeWord(line,primes) THEN
      IF pos+line(0)>=39 THEN
        PutE() pos=2
      FI
      Print(line) Put(32)
      pos==+line(0)+1
    FI
  OD
  Close(dev)
RETURN

PROC Main()
  DEFINE MAX="128"
  BYTE ARRAY primes(MAX+1)
  CHAR ARRAY fname="H6:UNIXDICT.TXT"

  Put(125) PutE() ;clear the screen
  Sieve(primes,MAX+1)
  FindPrimeWords(fname,primes)
RETURN
Output:

Screenshot from Atari 8-bit computer

a aaa age agee ak am ama e egg eke em emma g ga gag gage gam game gamma ge gee gem gemma gm k keg m ma mae magma make mamma me meek meg q

Ada

-- Rosetta Code Task written in Ada
-- Task Name: Prime words
-- Task URL: https://rosettacode.org/wiki/Prime_words
-- August 2024, R. B. E.

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Strings; use Ada.Strings;
with Ada.Strings.Fixed; use Ada.Strings.Fixed;

procedure Prime_Words is

  procedure Get_Word is

    function Is_Prime (N : in Natural) return Boolean is
      Temp : Natural := 5;
    begin
      if N < 2 then
        return False;
      end if;
      if N mod 2 = 0 then
        return N = 2;
      end if;
      if N mod 3 = 00 then
        return N = 3;
      end if;
      while Temp * Temp <= N loop
        if N mod Temp = 0 then
          return False;
        end if;
        Temp := Temp + 2;
        if N mod Temp = 0 then
          return False;
        end if;
        Temp := Temp + 4;
      end loop;
      return True;
    end Is_Prime;

    procedure Split_Word (W : String) is
      Count_of_Prime_Letters : Natural := 0;
    begin
      for C in W'Range loop
        if (Is_Prime (Character'Pos (W (C)))) then
          Count_of_Prime_Letters := Count_of_Prime_Letters + 1;
        end if;
      end loop;
      if (W'Last = Count_of_Prime_Letters) then
        Put_Line (W);
      end if;
    end;

    File : File_Type;

  begin
    Open (File => File, Mode => In_File, Name => "unixdict.txt");
    while not End_Of_File (File) Loop
      Split_Word (Get_Line (File));
    end loop;
    Close (File);
  end Get_Word;

begin
  Get_Word;
end Prime_Words;
Output:
a
aaa
age
agee
ak
am
ama
e
egg
eke
em
emma
g
ga
gag
gage
gam
game
gamma
ge
gee
gem
gemma
gm
k
keg
m
ma
mae
magma
make
mamma
me
meek
meg
q

ALGOL 68

Does not distinguish between letters and non-letter ASCII codes (as with the REXX sample).

Note, the sources of primes.incl.a68 and files.incl.a68 are on separate pages on Rosetta Code - see the above links.

BEGIN # find words whose character codes are primes                           #

    PR read "primes.incl.a68" PR                    # include prime utilities #
    PR read  "files.incl.a68" PR                    # include file  utilities #

    # construct a sieve of primes up to the maximum character code            #
    []BOOL prime = PRIMESIEVE max abs char;

    # returns TRUE if the characters of word all have prime character codes   #
    #         FALSE otherwise                                                 #
    # count so far is the count of matching words found before this word      #
    PROC show prime word = ( STRING word, INT count so far )BOOL:
         BEGIN BOOL is prime := FALSE;
               FOR w pos FROM LWB word TO UPB word
               WHILE ( is prime := prime[ ABS word[ w pos ] ] )
               DO SKIP OD;
               IF NOT is prime
               THEN FALSE
               ELSE print( ( whole( count so far + 1, -5 ) ) );
                    print( ( ": ", word, newline ) );
                    TRUE                
               FI
         END # show prime word # ;

    IF "unixdict.txt" EACHLINE show prime word < 0 THEN
        print( ( "Unable to open unixdict.txt", newline ) )
    FI

END
Output:
    1: a
    2: aaa
    3: age
    4: agee
    5: ak
    6: am
    7: ama
    8: e
    9: egg
   10: eke
   11: em
   12: emma
   13: g
   14: ga
   15: gag
   16: gage
   17: gam
   18: game
   19: gamma
   20: ge
   21: gee
   22: gem
   23: gemma
   24: gm
   25: k
   26: keg
   27: m
   28: ma
   29: mae
   30: magma
   31: make
   32: mamma
   33: me
   34: meek
   35: meg
   36: q

Arturo

words: read.lines relative "unixdict.txt"

loop words 'word [
    if every? split word 'ch -> prime? to :integer to :char ch ->
        print word
]
Output:
a
aaa
age
agee
ak
am
ama
e
egg
eke
em
emma
g
ga
gag
gage
gam
game
gamma
ge
gee
gem
gemma
gm
k
keg
m
ma
mae
magma
make
mamma
me
meek
meg
q

AWK

# syntax: GAWK -f PRIME_WORDS.AWK unixdict.txt
BEGIN {
    for (i=0; i<=255; i++) {
      if (is_prime(i)) {
        prime_chars = sprintf("%s%c",prime_chars,i)
      }
    }
    pattern = sprintf("^[%s]+$",prime_chars)
}
{   if ($0 ~ pattern) {
      printf("%s ",$0)
    }
}
END {
    printf("\n")
    exit(0)
}
function is_prime(x,  i) {
    if (x <= 1) {
      return(0)
    }
    for (i=2; i<=int(sqrt(x)); i++) {
      if (x % i == 0) {
        return(0)
      }
    }
    return(1)
}
Output:
a aaa age agee ak am ama e egg eke em emma g ga gag gage gam game gamma ge gee gem gemma gm k keg m ma mae magma make mamma me meek meg q

C++

#include <algorithm>
#include <cstdlib>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <string>
#include "prime_sieve.hpp"

int main(int argc, char** argv) {
    const char* filename(argc < 2 ? "unixdict.txt" : argv[1]);
    std::ifstream in(filename);
    if (!in) {
        std::cerr << "Cannot open file '" << filename << "'.\n";
        return EXIT_FAILURE;
    }
    std::string line;
    prime_sieve sieve(UCHAR_MAX);
    auto is_prime = [&sieve](unsigned char c){ return sieve.is_prime(c); };
    int n = 0;
    while (getline(in, line)) {
        if (std::all_of(line.begin(), line.end(), is_prime)) {
            ++n;
            std::cout << std::right << std::setw(2) << n << ": "
                << std::left << std::setw(10) << line;
            if (n % 4 == 0)
                std::cout << '\n';
        }
    }
    return EXIT_SUCCESS;
}

Contents of prime_sieve.hpp:

#ifndef PRIME_SIEVE_HPP
#define PRIME_SIEVE_HPP

#include <algorithm>
#include <vector>

/**
 * A simple implementation of the Sieve of Eratosthenes.
 * See https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes.
 */
class prime_sieve {
public:
    explicit prime_sieve(size_t);
    bool is_prime(size_t) const;
private:
    std::vector<bool> is_prime_;
};

/**
 * Constructs a sieve with the given limit.
 *
 * @param limit the maximum integer that can be tested for primality
 */
inline prime_sieve::prime_sieve(size_t limit) {
    limit = std::max(size_t(3), limit);
    is_prime_.resize(limit/2, true);
    for (size_t p = 3; p * p <= limit; p += 2) {
        if (is_prime_[p/2 - 1]) {
            size_t inc = 2 * p;
            for (size_t q = p * p; q <= limit; q += inc)
                is_prime_[q/2 - 1] = false;
        }
    }
}

/**
 * Returns true if the given integer is a prime number. The integer
 * must be less than or equal to the limit passed to the constructor.
 *
 * @param n an integer less than or equal to the limit passed to the
 * constructor
 * @return true if the integer is prime
 */
inline bool prime_sieve::is_prime(size_t n) const {
    if (n == 2)
        return true;
    if (n < 2 || n % 2 == 0)
        return false;
    return is_prime_.at(n/2 - 1);
}

#endif
Output:
 1: a          2: aaa        3: age        4: agee      
 5: ak         6: am         7: ama        8: e         
 9: egg       10: eke       11: em        12: emma      
13: g         14: ga        15: gag       16: gage      
17: gam       18: game      19: gamma     20: ge        
21: gee       22: gem       23: gemma     24: gm        
25: k         26: keg       27: m         28: ma        
29: mae       30: magma     31: make      32: mamma     
33: me        34: meek      35: meg       36: q         

Delphi

Works with: Delphi version 6.0


function IsPrime(N: int64): boolean;
{Fast, optimised prime test}
var I,Stop: int64;
begin
if (N = 2) or (N=3) then Result:=true
else if (n <= 1) or ((n mod 2) = 0) or ((n mod 3) = 0) then Result:= false
else
     begin
     I:=5;
     Stop:=Trunc(sqrt(N+0.0));
     Result:=False;
     while I<=Stop do
           begin
           if ((N mod I) = 0) or ((N mod (I + 2)) = 0) then exit;
           Inc(I,6);
           end;
     Result:=True;
     end;
end;



procedure ShowPrimeWords(Memo: TMemo);
var I,N,Sum,Cnt: integer;
var NS,S: string;

	function IsPrimeWord(S: string): boolean;
	var I: integer;
	begin
	Result:=False;
	for I:=1 to Length(S) do
	 if not IsPrime(byte(S[I])) then exit;
	Result:=True;
	end;


begin
Cnt:=0;
S:='';
{Iterate all entries in dictionary}
for I:=0 to UnixDict.Count-1 do
 if IsPrimeWord(UnixDict[I]) then
	begin
	Inc(Cnt);
	Memo.Lines.Add(UnixDict[I]);
	end;
Memo.Lines.Add('Count = '+IntToStr(Cnt));
end;
Output:
a
aaa
age
agee
ak
am
ama
e
egg
eke
em
emma
g
ga
gag
gage
gam
game
gamma
ge
gee
gem
gemma
gm
k
keg
m
ma
mae
magma
make
mamma
me
meek
meg
q
Count = 36
Elapsed Time: 72.759 ms.


EasyLang

fastfunc isprim num .
   i = 2
   while i <= sqrt num
      if num mod i = 0
         return 0
      .
      i += 1
   .
   return 1
.
repeat
   s$ = input
   until s$ = ""
   c$ = ""
   for c$ in strchars s$
      if isprim strcode c$ = 0
         break 1
      .
   .
   if c$ = ""
      print s$
   .
.
# the content of unixdict.txt 
input_data
10th
.
age
.

Factor

Works with: Factor version 0.99 2020-08-14
USING: io.encodings.ascii io.files math.primes prettyprint sequences ;

"unixdict.txt" ascii file-lines [ [ prime? ] all? ] filter .
Output:
{
    "a"
    "aaa"
    "age"
    "agee"
    "ak"
    "am"
    "ama"
    "e"
    "egg"
    "eke"
    "em"
    "emma"
    "g"
    "ga"
    "gag"
    "gage"
    "gam"
    "game"
    "gamma"
    "ge"
    "gee"
    "gem"
    "gemma"
    "gm"
    "k"
    "keg"
    "m"
    "ma"
    "mae"
    "magma"
    "make"
    "mamma"
    "me"
    "meek"
    "meg"
    "q"
}

FreeBASIC

dim shared as boolean prime(0 to 29) =_
    {false, true, false, true, true, false, false, true, false, true, false, false, true, false,_
     false, false, true, false, true, true, false, true, true, false, true, false, false, false, false}
     
function isprimeletter( s as string ) as boolean
    dim as ubyte n = asc(s)
    if n mod 2 = 0 then return false
    return prime( (n-65)/2 )
end function

function isprimeword( s as string ) as boolean
    for i as uinteger = 1 to len(s)
        if not isprimeletter( mid(s,i,1) ) then return false
    next i
    return true
end function

dim as string word

open "unixdict.txt" for input as #1
while true
    line input #1, word
    if word = "" then exit while
    if isprimeword( word ) then print word
wend
close #1
end
Output:
a
aaa
age
agee
ak
am
ama
e
egg
eke
em
emma
g
ga
gag
gage
gam
game
gamma
ge
gee
gem
gemma
gm
k
keg
m
ma
mae
magma
make
mamma
me
meek
meg
q

FutureBasic

#plist NSAppTransportSecurity @{NSAllowsArbitraryLoads:YES}

mda(0) = {NO, YES, NO, YES, YES, NO, NO, YES, NO, YES, NO, NO, YES,¬
NO, NO, NO, YES, NO, YES, YES, NO, YES, YES, NO, YES, NO, NO, NO, NO}

local fn WordList as CFArrayRef
  CFURLRef    url    = fn URLWithString( @"http://wiki.puzzlers.org/pub/wordlists/unixdict.txt" )
  CFStringRef string = lcase(fn StringWithContentsOfURL( url, NSUTF8StringEncoding, NULL ))
  CFArrayRef wordArr = fn StringComponentsSeparatedByString( string, @"\n" )
  CFMutableArrayRef mutArr = fn MutableArrayNew
  CFStringRef tempStr
  
  for tempStr in wordArr
    CFRange range = fn StringRangeOfStringWithOptions( tempStr, @"^[a-z]+$", NSRegularExpressionSearch )
    if range.location != NSNotFound then MutableArrayAddObject( mutArr, tempStr )
  next
end fn = mutArr

local fn IsPrimeLetter( s as CFStringRef ) as BOOL
  NSUInteger index = 0
  BOOL       result = NO
  
  unichar n = fn StringCharacterAtIndex( s, index )
  if n mod 2 == 0 then exit fn = NO
  result = mda_integer( (n-65)/2 )
end fn = result

local fn IsPrimeWord( s as CFStringRef ) as BOOL
  NSUInteger i, count = len(s)
  
  for i = 0 to count -1
    if fn IsPrimeLetter( mid( s, i, 1 ) ) = NO then exit fn = NO
  next
end fn = YES

local fn FindPrimeWords
  CFArrayRef  wordArr = fn WordList
  CFStringRef wordStr
  
  for wordStr in wordArr
    if wordStr = @"" then break
    if fn IsPrimeWord( wordStr ) = YES then printf @"%@", wordStr
  next
end fn

fn FindPrimeWords

HandleEvents
Output:
a
aaa
age
agee
ak
am
ama
e
egg
eke
em
emma
g
ga
gag
gage
gam
game
gamma
ge
gee
gem
gemma
gm
k
keg
m
ma
mae
magma
make
mamma
me
meek
meg
q


Go

package main

import (
    "bytes"
    "fmt"
    "io/ioutil"
    "log"
    "strings"
)

func isPrime(n int) bool {
    if n < 2 {
        return false
    }
    if n%2 == 0 {
        return n == 2
    }
    if n%3 == 0 {
        return n == 3
    }
    d := 5
    for d*d <= n {
        if n%d == 0 {
            return false
        }
        d += 2
        if n%d == 0 {
            return false
        }
        d += 4
    }
    return true
}

func main() {
    // cache prime runes with codepoints between 33 and 255 say
    var primeRunes []rune
    for i := 33; i < 256; i += 2 {
        if isPrime(i) {
            primeRunes = append(primeRunes, rune(i))
        }
    }
    primeString := string(primeRunes)
    wordList := "unixdict.txt"
    b, err := ioutil.ReadFile(wordList)
    if err != nil {
        log.Fatal("Error reading file")
    }
    bwords := bytes.Fields(b)
    fmt.Println("Prime words in", wordList, "are:")
    for _, bword := range bwords {
        word := string(bword)
        ok := true
        for _, c := range word {
            if !strings.ContainsRune(primeString, c) {
                ok = false
                break
            }
        }
        if ok {
            fmt.Println(word)
        }
    }
}
Output:
Prime words in unixdict.txt are:
a
aaa
age
agee
ak
am
ama
e
egg
eke
em
emma
g
ga
gag
gage
gam
game
gamma
ge
gee
gem
gemma
gm
k
keg
m
ma
mae
magma
make
mamma
me
meek
meg
q

J

   ($~ _2 */\ q:@#)(#~ (1 */@p: 3 u: ])@>) cutLF fread'unixdict.txt'
┌─────┬───┬─────┬────┬─────┬───┬────┬───┬────┐
a    aaaage  ageeak   am ama e  egg 
├─────┼───┼─────┼────┼─────┼───┼────┼───┼────┤
eke  em emma g   ga   gaggagegamgame
├─────┼───┼─────┼────┼─────┼───┼────┼───┼────┤
gammage gee  gem gemmagm k   kegm   
├─────┼───┼─────┼────┼─────┼───┼────┼───┼────┤
ma   maemagmamakemammame meekmegq   
└─────┴───┴─────┴────┴─────┴───┴────┴───┴────┘

jq

Works with: jq

Works with gojq, the Go implementation of jq

A suitable implementation of `is_prime` is given at Erdős-primes#jq and is therefore not repeated here.

The task description suggests that perhaps the appropriate definition of `is_prime_word` should focus on the alphabetic characters, perhaps along the lines of:

def is_prime_word: all(gsub("[^A-Za-z]";"") | explode[]; is_prime);

All such variations are as easy to accommodate as to envision, but for unixdict.txt the following suffices:

def is_prime_word: all(explode[]; is_prime);
inputs | select(is_prime_word)
Output:

Invocation (example): jq -Rrn -f prime-words.jq unixdict.txt

a
aaa
age
agee
ak
am
ama
e
egg
eke
em
emma
g
ga
gag
gage
gam
game
gamma
ge
gee
gem
gemma
gm
k
keg
m
ma
mae
magma
make
mamma
me
meek
meg
q

Julia

See Alternade_words#Julia for the foreachword function.

const primelettervalues = [67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113]
isprimeword(w, _) = all(c -> Int(c) in primelettervalues, collect(w)) ? w : ""
foreachword("unixdict.txt", isprimeword, colwidth=10, numcols=9)
Output:
Word source: unixdict.txt

a         aaa       age       agee      ak        am        ama       e         egg
eke       em        emma      g         ga        gag       gage      gam       game
gamma     ge        gee       gem       gemma     gm        k         keg       m
ma        mae       magma     make      mamma     me        meek      meg       q

Mathematica /Wolfram Language

dict=Import["https://web.archive.org/web/20180611003215/http://www.puzzlers.org/pub/wordlists/unixdict.txt","String"];
dict//=StringSplit[#,"\n"]&;
chars=CharacterRange["A","Z"]~Join~CharacterRange["a","z"];
chars//=Select[ToCharacterCode/*First/*PrimeQ];
Select[dict,StringMatchQ[Repeated[Alternatives@@chars]]]//Column
Output:
a
aaa
age
agee
ak
am
ama
e
egg
eke
em
emma
g
ga
gag
gage
gam
game
gamma
ge
gee
gem
gemma
gm
k
keg
m
ma
mae
magma
make
mamma
me
meek
meg
q

MiniScript

This implementation is for use with the Mini Micro version of MiniScript. The command-line version does not include a HTTP library. Modify the declaration of wordList object to use the file class to read a local copy of the word list file.

isPrimeWord = function(word)
	if word.len == 0 then return false
	for ch in word.split("")
		if "aegkmq".indexOf(ch) == null then return false
	end for
	return true
end function

wordList = http.get("http://wiki.puzzlers.org/pub/wordlists/unixdict.txt").split(char(10))
primes = []
for word in wordList
	if isPrimeWord(word) then primes.push(word)
end for

print primes.join(", ")
Output:
a, aaa, age, agee, ak, am, ama, e, egg, eke, em, emma, g, ga, gag, gage, gam, game, gamma, ge, gee, gem, gemma, gm, k, keg, m, ma, mae, magma, make, mamma, me, meek, meg, q

Nim

import strformat, strutils

func isPrime(n: Natural): bool =
  if n < 2: return false
  if n mod 2 == 0: return n == 2
  if n mod 3 == 0: return n == 3
  var d = 5
  while d * d <= n:
    if n mod d == 0: return false
    inc d, 2
    if n mod d == 0: return false
    inc d, 4
  result = true

# Build set of prime characters.
const PrimeChars = static:
                     var pchars: set[char]
                     for c in Letters:
                       if ord(c).isPrime: pchars.incl c
                     pchars

var count = 0
for word in "unixdict.txt".lines:
  if word.allCharsInSet(PrimeChars):
    inc count
    echo &"{count:2}: {word}"
Output:
 1: a
 2: aaa
 3: age
 4: agee
 5: ak
 6: am
 7: ama
 8: e
 9: egg
10: eke
11: em
12: emma
13: g
14: ga
15: gag
16: gage
17: gam
18: game
19: gamma
20: ge
21: gee
22: gem
23: gemma
24: gm
25: k
26: keg
27: m
28: ma
29: mae
30: magma
31: make
32: mamma
33: me
34: meek
35: meg
36: q

Perl

#!/usr/bin/perl

use strict;
use warnings;

my $pat = join '', grep +(1 x ord) !~ /^(11+)\1+$/, 'a'..'z', 'A'..'Z';
@ARGV = 'unixdict.txt';
print join('', grep /^[$pat]+$/, <>) =~ tr/\n/ /r =~ s/.{1,71}\K /\n/gr;
Output:
a aaa age agee ak am ama e egg eke em emma g ga gag gage gam game gamma
ge gee gem gemma gm k keg m ma mae magma make mamma me meek meg q

Phix

with javascript_semantics
function sap(string word) return sum(apply(word,is_prime))==length(word) end function
sequence words = filter(unix_dict(),sap)
printf(1,"%d prime words found: %s\n",{length(words),join(shorten(words,"",3),", ")})
Output:
36 prime words found: a, aaa, age, ..., meek, meg, q

Plain English

To run:
Start up.
Put "c:\unixdict.txt" into a path.
Read the path into a buffer.
Slap a rider on the buffer.
Loop.
Move the rider (text file rules).
Subtract 1 from the rider's token's last. \newline
Put the rider's token into a word string.
If the word is blank, break.
If the word is composed of prime letters, write the word on the console.
Repeat.
Wait for the escape key.
Shut down.

To decide if a byte is prime:
If the byte is in "aegkmq", say yes.
Say no.

To decide if a string is composed of prime letters:
Slap a substring on the string.
Loop.
If the substring is blank, say yes.
If the substring's first's target is not prime, say no.
Add 1 to the substring's first.
Repeat.
Output:
a
aaa
age
agee
ak
am
ama
e
egg
eke
em
emma
g
ga
gag
gage
gam
game
gamma
ge
gee
gem
gemma
gm
k
keg
m
ma
mae
magma
make
mamma
me
meek
meg
q

Python

Given that the set is known and quite small, 52 in length, a bit of pre-processing to determine all prime positioned characters before hand will speed up the task significantly rather than determining it every time for every word in the list.

Here is the brute force pre-processor, again this can be done easily manually, but if you are feeling lazy, like me :)

for i in range(65,123):
  check = 1
  for j in range(2,i):
    if i%j == 0:
     check = 0
  if check==1:
   print(chr(i),end='')

This produces the following string :

CGIOSYaegkmq

It's possible to speed it up even more by dropping capitals since the file only contains lower case characters, but we will give that a pass.....

And here's the main program which hardcodes the output of the pre-processor above. As always :

Tested on Python 3+, the file download will work only if the link is still active. It is possible that you may be able to fetch the file in your browser but download via code may still fail. Check whether you are connected to a VPN, it works on open networks.

#Aamrun, 6th November 2021

import urllib.request
from collections import Counter
 
urllib.request.urlretrieve("http://wiki.puzzlers.org/pub/wordlists/unixdict.txt", "unixdict.txt")
 
dictionary = open("unixdict.txt","r")
 
wordList = dictionary.read().split('\n')
 
dictionary.close()
 
primeSet = set("CGIOSYaegkmq")

[print(word) for word in wordList if len(set(word).difference(primeSet))==0]

And here's the final output :

Output:
a
aaa
age
agee
ak
am
ama
e
egg
eke
em
emma
g
ga
gag
gage
gam
game
gamma
ge
gee
gem
gemma
gm
k
keg
m
ma
mae
magma
make
mamma
me
meek
meg
q

Quackery

eratosthenes and isprime are defined at Sieve of Eratosthenes#Quackery.

  128 eratosthenes

  []
  $ "rosetta/unixdict.txt" sharefile drop nest$
  witheach
    [ true over
      witheach
        [ isprime not if
            [ not conclude ] ]
      iff [ nested join ]
      else drop ]
  46 wrap$
Output:
a aaa age agee ak am ama e egg eke em emma g
ga gag gage gam game gamma ge gee gem gemma gm
k keg m ma mae magma make mamma me meek meg q

Raku

Another in a continuing series of tasks that are a minimal variation of previous ones. This is essentially Smarandache prime-digital sequence using ords instead of numerical digits. Sigh.

In an effort to anticipate / head-off a rash of tiny variant tasks, a series of one-liners:

my @words = 'unixdict.txt'.IO.words».fc;

sub display ($n, @n, $s = "First 20: ") {"$n;\n{$s}{@n.join: ', '}"}

# The task
say 'Number of words whose ords are all prime: ',
    @words.hyper.grep({ .ords.all.is-prime }).&{display +$_, $_, ''};

# Twelve other minor variants
say "\nNumber of words whose ordinal sum is prime: ",
    @words.grep({ .ords.sum.is-prime }).&{display +$_, .head(20)};

say "\nNumber of words whose ords are all prime, and whose ordinal sum is prime: ",
    @words.hyper.grep({ .ords.all.is-prime && .ords.sum.is-prime }).&{display +$_, $_, ''};

say "\n\nInterpreting the words as if they were base 36 numbers:";

say "\nNumber of words whose 'digits' are all prime in base 36: ",
    @words.hyper.grep({ !.contains(/\W/) && all(.comb».parse-base(36)).is-prime }).&{display +$_, $_, ''};

say "\nNumber of words that are prime in base 36: ",
    @words.grep({ !.contains(/\W/) && :36($_).is-prime }).&{display +$_, .head(20)};

say "\nNumber of words whose base 36 digital sum is prime: ",
    @words.grep({ !.contains(/\W/) && .comb».parse-base(36).sum.is-prime }).&{display +$_, .head(20)};

say "\nNumber of words that are prime in base 36, and whose digital sum is prime: ",
    @words.grep({ !.contains(/\W/) && :36($_).is-prime && .comb».parse-base(36).sum.is-prime }).&{display +$_, .head(20)};

say "\nNumber of words that are prime in base 36, whose digits are all prime, and whose digital sum is prime: ",
    @words.hyper.grep({ !.contains(/\W/) && all(.comb».parse-base(36)).is-prime && :36($_).is-prime && .comb».parse-base(36).sum.is-prime }).&{display +$_, $_, ''};

use Base::Any:ver<0.1.2+>;
set-digits('a'..'z');

say "\n\nTests using a custom base 26 where 'a' through 'z' is 0 through 25 and words are case folded:";

say "\nNumber of words whose 'digits' are all prime using a custom base 26: ",
    @words.hyper.grep({ !.contains(/<-alpha>/) && all(.comb».&from-base(26)).is-prime }).&{display +$_, $_, ''};

say "\nNumber of words that are prime using a custom base 26: ",
    @words.grep({ !.contains(/<-alpha>/) && .&from-base(26).is-prime }).&{display +$_, .head(20)};

say "\nNumber of words whose digital sum is prime using a custom base 26: ",
    @words.grep({ !.contains(/<-alpha>/) && .comb».&from-base(26).sum.is-prime }).&{display +$_, .head(20)};

say "\nNumber of words that are prime in a custom base 26 and whose digital sum is prime in that base: ",
    @words.grep({ !.contains(/<-alpha>/) && .&from-base(26).is-prime && .comb».&from-base(26).sum.is-prime }).&{display +$_, .head(20)};

say "\nNumber of words that are prime in custom base 26, whose digits are all prime, and whose digital sum is prime: ",
    @words.hyper.grep({ !.contains(/<-alpha>/) && all(.comb».&from-base(26)).is-prime && .&from-base(26).is-prime && .comb».&from-base(26).sum.is-prime }).&{display +$_, $_, ''};
Output:
Number of words whose ords are all prime: 36;
a, aaa, age, agee, ak, am, ama, e, egg, eke, em, emma, g, ga, gag, gage, gam, game, gamma, ge, gee, gem, gemma, gm, k, keg, m, ma, mae, magma, make, mamma, me, meek, meg, q

Number of words whose ordinal sum is prime: 3778;
First 20: 10th, 9th, a, a's, aau, ababa, abate, abhorred, abject, ablate, aboard, abrade, abroad, absentee, absentia, absolute, absorptive, absurd, abusive, accelerate

Number of words whose ords are all prime, and whose ordinal sum is prime: 12;
a, e, egg, g, gem, k, keg, m, mae, mamma, meg, q


Interpreting the words as if they were base 36 numbers:

Number of words whose 'digits' are all prime in base 36: 18;
2nd, 5th, 7th, b, d, h, j, n, nd, nh, nj, nv, t, tn, tnt, tv, v, vt

Number of words that are prime in base 36: 1106;
First 20: 10th, 1st, 2nd, 5th, 6th, 7th, abandon, abbott, abdomen, ablution, abolish, abort, abrupt, absorb, abstention, abstract, abutted, accept, accident, acid

Number of words whose base 36 digital sum is prime: 4740;
First 20: 10th, 3rd, 7th, aba, abacus, abalone, abase, abater, abelian, abelson, aberrant, abeyant, ablaze, abort, aboveground, abraham, abrasion, abrasive, abreact, abridge

Number of words that are prime in base 36, and whose digital sum is prime: 300;
First 20: 10th, 7th, abort, accident, acid, ad, adorn, adulthood, afterthought, albeit, alvin, armload, around, arragon, arraign, assassin, asteroid, astound, augean, avocation

Number of words that are prime in base 36, whose digits are all prime, and whose digital sum is prime: 8;
7th, b, d, h, j, n, t, v


Tests using a custom base 26 where 'a' through 'z' is 0 through 25 and words are case folded:

Number of words whose 'digits' are all prime using a custom base 26: 30;
c, cdc, cf, crt, ct, d, dc, dr, f, fcc, fl, ft, ftc, h, l, ltd, n, nc, ncr, nd, nh, nrc, r, rd, t, tn, tnt, ttl, tx, x

Number of words that are prime using a custom base 26: 987;
First 20: abhorrent, abolish, abreact, absurd, ac, act, actual, actuarial, ad, adjutant, adult, advisor, aerosol, aft, agent, agricultural, ah, aid, ajar, al

Number of words whose digital sum is prime using a custom base 26: 5473;
First 20: ababa, aback, abacus, abalone, abase, abater, abc, abdicate, abdomen, abe, abelian, abelson, aberrant, abeyant, ablaze, abolish, abominate, aborigine, aboveground, abraham

Number of words that are prime in a custom base 26 and whose digital sum is prime in that base: 292;
First 20: abolish, abreact, absurd, ac, ad, adjutant, adult, agricultural, ah, aid, al, allah, allied, altar, an, annal, ar, arclength, argonaut, asocial

Number of words that are prime in custom base 26, whose digits are all prime, and whose digital sum is prime: 9;
c, d, f, h, l, n, r, t, x

REXX

No attempt was made to exclude any "word" if it contained any non-letter (Latin alphabet) characters.

/*REXX program finds words whose ASCII code for its letters are prime (in a dictionary).*/
parse arg iFID .                                 /*obtain optional arguments from the CL*/
if iFID=='' | iFID=="," then iFID='unixdict.txt' /*Not specified?  Then use the default.*/
call genPrimes                                   /*generate all primes less than 256.   */
say 'reading the dictionary file: '   iFID       /*show which dictionary is being read. */
say
#= 0                                             /*count of prime words found  (so far).*/
        do recs=0  while lines(iFID)\==0         /*read each word in the file  (word=X).*/
        x= strip( linein( iFID) )                /*pick off a word from the input line. */

                 do j=1  for length(x)           /*examine each letter (char) in word.  */
                 _= c2d( substr(x, j, 1) )       /*convert each letter to a decimal num.*/
                 if \@._  then iterate recs      /*is this ASCII code letter a prime ?  */
                 end   /*j*/
        say x                                    /*display a prime word to the terminal.*/
        #= # + 1                                 /*bump the count of  prime words.      */
        end      /*recs*/                        /* [↑]   semaphore name is uppercased. */
say
say copies("─", 30)     recs     " words in the dictionary file: "       iFID
say
say 'found '    #    " prime words in the dictionary."
exit 0                                           /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
genPrimes: p=   2   3  5    7  11  13  17  19  23  29  31  37  41  43  47  53  59  61  ,
               67  71  73  79  83  89  97 101 103 107 109 113 127 131 137 139 149 151  ,
              157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251
           @.= 0;    do j=1  for words(p);  _= word(p, j);  @._= 1;  end  /*j*/;    return
output   when using the default input:
reading the dictionary file:  unixdict.txt

a
aaa
age
agee
ak
am
ama
e
egg
eke
em
emma
g
ga
gag
gage
gam
game
gamma
ge
gee
gem
gemma
gm
k
keg
m
ma
mae
magma
make
mamma
me
meek
meg
q

────────────────────────────── 25104  words in the dictionary file:  unixdict.txt

found  36  prime words in the dictionary.

Ring

load "stdlib.ring"

cStr = read("unixdict.txt")
wordList = str2list(cStr)
Words = []

for n = 1 to len(wordList)
    num = 0 
    len = len(wordList[n])
    for m = 1 to len
        asc = ascii(wordList[n][m])
        if isprime(asc)
           num = num + 1
        else
           exit
        ok
    next
    if num = len
       add(Words,wordList[n])
    ok
next

see "Prime words are:" + nl
see Words

Output:

Prime words are:
a
aaa
age
agee
ak
am
ama
e
egg
eke
em
emma
g
ga
gag
gage
gam
game
gamma
ge
gee
gem
gemma
gm
k
keg
m
ma
mae
magma
make
mamma
me
meek
meg
q

RPL

The only way in RPL to use unixdict.txt as input is to convert it into a list of 25,104 strings, stored in the global variable Dict.

« { } 
  65 120 FOR j 
     IF j ISPRIME? THEN j + END 
  NEXT 
  → primascii 
  « { } 
    1 Dict SIZE FOR j 
       'Dict' j GET 1 SF 
       1 OVER SIZE FOR j 
          IF primascii OVER j DUP SUB NUM POS NOT THEN 1 CF DUP SIZE 'j' STO END 
       NEXT 
       IF 1 FS? THEN + ELSE DROP END 
    NEXT
» » 'TASK' STO
Output:
1: { "a" "aaa" "age" "agee" "ak" "am" "ama" "e" "egg" "eke" "em" "emma" "g" "ga" "gag" "gage" "gam" "game" "gamma" "ge" "gee" "gem" "gemma" "gm" "k" "keg" "m" "ma" "mae" "magma" "make" "mamma" "me" "meek" "meg" "q" }

Ruby

require 'prime'

puts File.open("unixdict.txt").select{|line| line.chomp.chars.all?{|c| c.ord.prime?} }
Output:
a
aaa
age
agee
ak
am
ama
e
egg
eke
em
emma
g
ga
gag
gage
gam
game
gamma
ge
gee
gem
gemma
gm
k
keg
m
ma
mae
magma
make
mamma
me
meek
meg
q

Rust

// [dependencies]
// primal = "0.3"

use std::fs::File;
use std::io::{self, BufRead};

fn print_prime_words(filename: &str) -> std::io::Result<()> {
    let sieve = primal::Sieve::new(std::char::MAX as usize);
    let file = File::open(filename)?;
    let mut n = 0;
    for line in io::BufReader::new(file).lines() {
        let word = line?;
        if word.chars().all(|c| sieve.is_prime(c as usize)) {
            n += 1;
            print!("{:2}: {:<10}", n, word);
            if n % 4 == 0 {
                println!();
            }
        }
    }
    Ok(())
}

fn main() {
    match print_prime_words("unixdict.txt") {
        Ok(()) => {}
        Err(error) => eprintln!("{}", error),
    }
}
Output:
 1: a          2: aaa        3: age        4: agee      
 5: ak         6: am         7: ama        8: e         
 9: egg       10: eke       11: em        12: emma      
13: g         14: ga        15: gag       16: gage      
17: gam       18: game      19: gamma     20: ge        
21: gee       22: gem       23: gemma     24: gm        
25: k         26: keg       27: m         28: ma        
29: mae       30: magma     31: make      32: mamma     
33: me        34: meek      35: meg       36: q         

Swift

import Foundation

class BitArray {
    var array: [UInt32]

    init(size: Int) {
        array = Array(repeating: 0, count: (size + 31)/32)
    }
    
    func get(index: Int) -> Bool {
        let bit = UInt32(1) << (index & 31)
        return (array[index >> 5] & bit) != 0
    }
    
    func set(index: Int, value: Bool) {
        let bit = UInt32(1) << (index & 31)
        if value {
            array[index >> 5] |= bit
        } else {
            array[index >> 5] &= ~bit
        }
    }
}

class PrimeSieve {
    let composite: BitArray
    
    init(size: Int) {
        composite = BitArray(size: size/2)
        var p = 3
        while p * p <= size {
            if !composite.get(index: p/2 - 1) {
                let inc = p * 2
                var q = p * p
                while q <= size {
                    composite.set(index: q/2 - 1, value: true)
                    q += inc
                }
            }
            p += 2
        }
    }
    
    func isPrime(number: Int) -> Bool {
        if number < 2 {
            return false
        }
        if (number & 1) == 0 {
            return number == 2
        }
        return !composite.get(index: number/2 - 1)
    }
}

func loadDictionary(_ path: String) throws -> [String] {
    let contents = try String(contentsOfFile: path, encoding: String.Encoding.ascii)
    return contents.components(separatedBy: "\n").filter{!$0.isEmpty}
}

do {
    let dictionary = try loadDictionary("unixdict.txt")
    let sieve = PrimeSieve(size: 255)
    for word in dictionary {
        if word.allSatisfy({$0.isASCII && sieve.isPrime(number: Int($0.asciiValue!))}) {
            print(word)
        }
    }
} catch {
    print(error.localizedDescription)
}
Output:
a
aaa
age
agee
ak
am
ama
e
egg
eke
em
emma
g
ga
gag
gage
gam
game
gamma
ge
gee
gem
gemma
gm
k
keg
m
ma
mae
magma
make
mamma
me
meek
meg
q

Uiua

Works with: Uiua version 0.11.0-dev.1
⊜□ ≠@\n. &fras "unixdict.txt"
Ps ← ⇌◌⍢(▽≠0◿⊢..⟜(⊂⊢)|>0⧻.):[]+2⇡256 # Build primes
Pc ← ▽:⟜(∊-@\0)⊂¯.+@a⇡26Ps           # Test A-Za-z for primal ASCII codes
▽:⟜(≡(/×◇∊)⊙¤):Pc
Output:
{"a" "aaa" "age" "agee" "ak" "am" "ama" "e" "egg" "eke" "em" "emma" "g" "ga" "gag" "gage" "gam" "game" "gamma" "ge" "gee" "gem" "gemma" "gm" "k" "keg" "m" "ma" "mae" "magma" "make" "mamma" "me" "meek" "meg" "q"}

Wren

Library: Wren-math
Library: Wren-iterate
import "io" for File
import "./math" for Int
import "./iterate" for Stepped

// cache prime characters with codepoints between 33 and 255 say
var primeChars = []
for (i in Stepped.new(33..255, 2)) {
    if (Int.isPrime(i)) primeChars.add(String.fromCodePoint(i))
}
var wordList = "unixdict.txt" // local copy
var words = File.read(wordList).trimEnd().split("\n")
System.print("Prime words in %(wordList) are:")
for (word in words) {
    if (word.all { |c| primeChars.contains(c) }) System.print(word)
}
Output:
Prime words in unixdict.txt are:
a
aaa
age
agee
ak
am
ama
e
egg
eke
em
emma
g
ga
gag
gage
gam
game
gamma
ge
gee
gem
gemma
gm
k
keg
m
ma
mae
magma
make
mamma
me
meek
meg
q

XPL0

func IsPrime(N);        \Return 'true' if N is prime
int  N, I;
[if N <= 2 then return N = 2;
if (N&1) = 0 then \even >2\ return false;
for I:= 3 to sqrt(N) do
    [if rem(N/I) = 0 then return false;
    I:= I+1;
    ];
return true;
];

string  0;              \use zero-terminated strings
int     I, Ch;
char    Word(25);
def     LF=$0A, CR=$0D, EOF=$1A;
[FSet(FOpen("unixdict.txt", 0), ^I);
OpenI(3);
repeat  I:= 0;
        loop    [repeat Ch:= ChIn(3) until Ch # CR;     \remove possible CR
                if Ch = EOF then quit;
                if Ch = LF then
                        [Word(I):= 0;  Text(0, Word);  CrLf(0);
                        quit;
                        ];
                if not IsPrime(Ch) then
                        [repeat Ch:= ChIn(3) until Ch=LF or Ch=EOF;
                        quit;
                        ];
                Word(I):= Ch;
                I:= I+1;
                ];
until   Ch = EOF;
]
Output:
a
aaa
age
agee
ak
am
ama
e
egg
eke
em
emma
g
ga
gag
gage
gam
game
gamma
ge
gee
gem
gemma
gm
k
keg
m
ma
mae
magma
make
mamma
me
meek
meg
q
Cookies help us deliver our services. By using our services, you agree to our use of cookies.