Alternade words: Difference between revisions

From Rosetta Code
Content added Content deleted
m (use mapreduce for varying intervals)
m (→‎{{header|Phix}}: trimmed output)
Line 319: Line 319:
end if
end if
sequence words = split_any(text," \r\n",no_empty:=true)
sequence words = split_any(text," \r\n",no_empty:=true)
constant minlens = {0,6,9,10,12,12}
constant minlens = {0,6,10,11,12,12}
for n=2 to 6 do
for n=2 to 6 do
sequence res = {}
sequence res = {}
Line 334: Line 334:
end if
end if
end for
end for
printf(1,"Every %s letter:\n",{ordinal(n)})
printf(1,"\nEvery %s letter of length>=%d:\n",{ordinal(n),minlens[n]})
pp(shorten(res,"alternade words found",5),{pp_Nest,1})
pp(shorten(res,"alternade words found",5),{pp_Nest,1})
end for
end for
Line 340: Line 340:
{{out}}
{{out}}
<pre>
<pre>
Every second letter:
Every second letter of length>=6:
{{`accost`, `acs`, `cot`},
{{`accost`, `acs`, `cot`},
{`accuse`, `acs`, `cue`},
{`accuse`, `acs`, `cue`},
Line 353: Line 353:
{`twirly`, `til`, `wry`},
{`twirly`, `til`, `wry`},
` (58 alternade words found)`}
` (58 alternade words found)`}

Every third letter:
Every third letter of length>=10:
{{`abominate`, `ama`, `bit`, `one`},
{`apprehend`, `are`, `pen`, `phd`},
{{`benevolent`, `belt`, `eve`, `non`},
{`benevolent`, `belt`, `eve`, `non`},
{`rejuvenate`, `rune`, `eva`, `jet`}}

{`ninetieth`, `nee`, `itt`, `nih`},
Every fourth letter of length>=11:
{`rejuvenate`, `rune`, `eva`, `jet`},
{`separated`, `sat`, `ere`, `pad`},
{{`meteorology`, `moo`, `erg`, `toy`, `el`},
{`tularemia`, `tam`, `uri`, `lea`}}
{`protectorate`, `per`, `rca`, `ott`, `toe`}}

Every fourth letter:
Every fifth letter of length>=12:
{{`invitation`, `ito`, `nan`, `vt`, `ii`},
{`laurentian`, `lea`, `ann`, `ut`, `ri`},
{`manservant`, `men`, `art`, `nv`, `sa`},
{`meteorology`, `moo`, `erg`, `toy`, `el`},
{`officemate`, `oct`, `fee`, `fm`, `ia`},
{`propionate`, `pit`, `roe`, `on`, `pa`},
{`protectorate`, `per`, `rca`, `ott`, `toe`},
{`stationary`, `sir`, `toy`, `an`, `ta`}}
Every fifth letter:
{{`inappropriate`, `ira`, `not`, `ape`, `pr`, `pi`}}
{{`inappropriate`, `ira`, `not`, `ape`, `pr`, `pi`}}

Every sixth letter:
Every sixth letter of length>=12:
{{`aristotelean`, `at`, `re`, `il`, `se`, `ta`, `on`},
{{`aristotelean`, `at`, `re`, `il`, `se`, `ta`, `on`},
{`warehouseman`, `wu`, `as`, `re`, `em`, `ha`, `on`}}
{`warehouseman`, `wu`, `as`, `re`, `em`, `ha`, `on`}}

Revision as of 03:17, 30 November 2020

Alternade 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.

An alternade is a word whose alternating letters themselves form two words. For example, the word lounge contains the word lug (lounge) and the word one (lounge). For a word to be an alternade, all its letters must be used. The two words that form an alternade don't need to be the same length; for example, the word board is an alternade made up of the words bad (board) and or (board).

Task

Print out every alternade in unixdict.txt whose length is 6 or greater, also showing both the words that make up the alternade.

See also

Factor

<lang factor>USING: formatting io.encodings.ascii io.files kernel literals math sequences sequences.extras sets strings ;

<< CONSTANT: words $[ "unixdict.txt" ascii file-lines ] >>

CONSTANT: wordset $[ words HS{ } set-like ]

word? ( str -- ? ) wordset in? ;
subwords ( str -- str str )
   dup <evens> >string swap <odds> >string ;
alternade? ( str -- ? ) subwords [ word? ] both? ;

words [ alternade? ] filter [ length 5 > ] filter [ dup subwords "%-8s %-4s %-4s\n" printf ] each</lang>

Output:
accost   acs  cot 
accuse   acs  cue 
afield   ail  fed 
agleam   ala  gem 
alcott   act  lot 
allele   all  lee 
allied   ale  lid 
alpert   apr  let 
ambient  abet min 
annette  ante net 
apport   apr  pot 
ariadne  aide ran 
assist   ass  sit 
battle   btl  ate 
blaine   ban  lie 
brenda   bed  rna 
calliope clip aloe
choose   cos  hoe 
choosy   cos  hoy 
claire   car  lie 
collude  clue old 
effete   eft  fee 
fabric   fbi  arc 
fealty   fat  ely 
fluent   fun  let 
forwent  fret own 
friend   fin  red 
george   gog  ere 
inroad   ira  nod 
israel   ire  sal 
jaunty   jut  any 
joanne   jan  one 
lounge   lug  one 
oriole   oil  roe 
oswald   owl  sad 
parrot   pro  art 
peoria   poi  era 
pierre   per  ire 
poodle   pol  ode 
pounce   puc  one 
racial   rca  ail 
realty   rat  ely 
sordid   sri  odd 
spatial  sail pta 
sprain   sri  pan 
strain   sri  tan 
strait   sri  tat 
sturdy   sud  try 
sweaty   set  way 
tattle   ttl  ate 
theorem  term hoe 
though   tog  huh 
throaty  tray hot 
triode   tid  roe 
triune   tin  rue 
troupe   top  rue 
truant   tun  rat 
twirly   til  wry 

Go

<lang go>package main

import (

   "bytes"
   "fmt"
   "io/ioutil"
   "log"
   "unicode/utf8"

)

func main() {

   b, err := ioutil.ReadFile("unixdict.txt")
   if err != nil {
       log.Fatal("Error reading file")
   }
   bwords := bytes.Fields(b)
   dict := make(map[string]bool, len(bwords))
   words := make([]string, len(bwords))
   for i, bword := range bwords {
       word := string(bword)
       dict[word] = true
       words[i] = word
   }
   fmt.Println("'unixdict.txt' contains the following alternades of length 6 or more:\n")
   count := 0
   for _, word := range words {
       if utf8.RuneCountInString(word) < 6 {
           continue
       }
       var w1 = ""
       var w2 = ""
       for i, c := range word {
           if i%2 == 0 {
               w1 += string(c)
           } else {
               w2 += string(c)
           }
       }
       _, ok1 := dict[w1]
       _, ok2 := dict[w2]
       if ok1 && ok2 {
           count++
           fmt.Printf("%2d: %-8s -> %-4s %-4s\n", count, word, w1, w2)
       }
   }

}</lang>

Output:
'unixdict.txt' contains the following alternades of length 6 or more:

 1: accost   -> acs  cot 
 2: accuse   -> acs  cue 
 3: afield   -> ail  fed 
 4: agleam   -> ala  gem 
 5: alcott   -> act  lot 
 6: allele   -> all  lee 
 7: allied   -> ale  lid 
 8: alpert   -> apr  let 
 9: ambient  -> abet min 
10: annette  -> ante net 
11: apport   -> apr  pot 
12: ariadne  -> aide ran 
13: assist   -> ass  sit 
14: battle   -> btl  ate 
15: blaine   -> ban  lie 
16: brenda   -> bed  rna 
17: calliope -> clip aloe
18: choose   -> cos  hoe 
19: choosy   -> cos  hoy 
20: claire   -> car  lie 
21: collude  -> clue old 
22: effete   -> eft  fee 
23: fabric   -> fbi  arc 
24: fealty   -> fat  ely 
25: fluent   -> fun  let 
26: forwent  -> fret own 
27: friend   -> fin  red 
28: george   -> gog  ere 
29: inroad   -> ira  nod 
30: israel   -> ire  sal 
31: jaunty   -> jut  any 
32: joanne   -> jan  one 
33: lounge   -> lug  one 
34: oriole   -> oil  roe 
35: oswald   -> owl  sad 
36: parrot   -> pro  art 
37: peoria   -> poi  era 
38: pierre   -> per  ire 
39: poodle   -> pol  ode 
40: pounce   -> puc  one 
41: racial   -> rca  ail 
42: realty   -> rat  ely 
43: sordid   -> sri  odd 
44: spatial  -> sail pta 
45: sprain   -> sri  pan 
46: strain   -> sri  tan 
47: strait   -> sri  tat 
48: sturdy   -> sud  try 
49: sweaty   -> set  way 
50: tattle   -> ttl  ate 
51: theorem  -> term hoe 
52: though   -> tog  huh 
53: throaty  -> tray hot 
54: triode   -> tid  roe 
55: triune   -> tin  rue 
56: troupe   -> top  rue 
57: truant   -> tun  rat 
58: twirly   -> til  wry 

Julia

<lang julia>function alternade(wordfile, minlength, interval)

   println("\nWord source: $wordfile")
   words = split(read(wordfile, String), r"\s+")
   dict, results = Dict(w => 1 for w in words), []
   for word in words
       len, wordlist, isalternade = length(word), [word], true
       (len < minlength) && continue
       for n in 1:interval
           subword = mapreduce(i -> word[i], *, n:interval:len)
           if !haskey(dict, subword)
               isalternade = false
               break
           end
           push!(wordlist, subword)
       end
       isalternade && push!(results, wordlist)
   end
   println("Found: a total of ", length(results), " word", length(results) != 1 ? "s" : "",
           " of at least length $minlength spelling words in alternate letters of interval $interval.")
   for (i, lis) in enumerate(results)
       println(join([rpad("$i.", 4), rpad(lis[1], 20), [rpad(lis[j], 10) for j in 2:interval+1]...]))
   end

end

alternade("unixdict.txt", 6, 2) alternade("unixdict.txt", 12, 4)

</lang>

Output:

Word source: unixdict.txt
Found: a total of 58 words of at least length 6 spelling words in alternate letters of interval 2.
1.  accost              acs       cot
2.  accuse              acs       cue
3.  afield              ail       fed
4.  agleam              ala       gem
5.  alcott              act       lot
6.  allele              all       lee
7.  allied              ale       lid
8.  alpert              apr       let
9.  ambient             abet      min
10. annette             ante      net
11. apport              apr       pot
12. ariadne             aide      ran
13. assist              ass       sit
14. battle              btl       ate
15. blaine              ban       lie
16. brenda              bed       rna
17. calliope            clip      aloe
18. choose              cos       hoe
19. choosy              cos       hoy
20. claire              car       lie
21. collude             clue      old
22. effete              eft       fee
23. fabric              fbi       arc
24. fealty              fat       ely
25. fluent              fun       let
26. forwent             fret      own
27. friend              fin       red
28. george              gog       ere
29. inroad              ira       nod
30. israel              ire       sal
31. jaunty              jut       any
32. joanne              jan       one
33. lounge              lug       one
34. oriole              oil       roe
35. oswald              owl       sad
36. parrot              pro       art
37. peoria              poi       era
38. pierre              per       ire
39. poodle              pol       ode
40. pounce              puc       one
41. racial              rca       ail
42. realty              rat       ely
43. sordid              sri       odd
44. spatial             sail      pta
45. sprain              sri       pan
46. strain              sri       tan
47. strait              sri       tat
48. sturdy              sud       try
49. sweaty              set       way
50. tattle              ttl       ate
51. theorem             term      hoe
52. though              tog       huh
53. throaty             tray      hot
54. triode              tid       roe
55. triune              tin       rue
56. troupe              top       rue
57. truant              tun       rat
58. twirly              til       wry

Word source: unixdict.txt
Found: a total of 1 word of at least length 12 spelling words in alternate letters of interval 4.
1.  protectorate        per       rca       ott       toe

Perl

<lang perl>#!/usr/bin/perl

use strict; use warnings;

my $words = do { local (@ARGV, $/) = 'unixdict.txt'; <> }; my %words = map { $_, 1 } $words =~ /^.{3,}$/gm; for ( $words =~ /^.{6,}$/gm )

 {
 my $even = s/(.).?/$1/gr;
 my $odd = s/.(.?)/$1/gr;
 $words{$even} && $words{$odd} and print "$_ => [ $even $odd ]\n";
 }</lang>

Phix

<lang Phix>object text = get_text("unixdict.txt") if not string(text) then

   crash("unixdict.txt error, download from http://www.puzzlers.org/pub/wordlists/unixdict.txt")

end if sequence words = split_any(text," \r\n",no_empty:=true) constant minlens = {0,6,10,11,12,12} for n=2 to 6 do

   sequence res = {}
   for i=1 to length(words) do
       string word = words[i]
       if length(word)>=minlens[n] then
           sequence sn = repeat("",n)
           for j=1 to length(word) do
               sn[mod(j-1,n)+1] &= word[j]
           end for
           if sum(sq_gt(apply(true,binary_search,{sn,{words}}),0))=n then
               res = append(res,prepend(sn,word))
           end if 
       end if
   end for
   printf(1,"\nEvery %s letter of length>=%d:\n",{ordinal(n),minlens[n]})
   pp(shorten(res,"alternade words found",5),{pp_Nest,1})

end for </lang>

Output:
Every second letter of length>=6:
{{`accost`, `acs`, `cot`},
 {`accuse`, `acs`, `cue`},
 {`afield`, `ail`, `fed`},
 {`agleam`, `ala`, `gem`},
 {`alcott`, `act`, `lot`},
 `...`,
 {`triode`, `tid`, `roe`},
 {`triune`, `tin`, `rue`},
 {`troupe`, `top`, `rue`},
 {`truant`, `tun`, `rat`},
 {`twirly`, `til`, `wry`},
 ` (58 alternade words found)`}

Every third letter of length>=10:
{{`benevolent`, `belt`, `eve`, `non`},
 {`rejuvenate`, `rune`, `eva`, `jet`}}

Every fourth letter of length>=11:
{{`meteorology`, `moo`, `erg`, `toy`, `el`},
 {`protectorate`, `per`, `rca`, `ott`, `toe`}}

Every fifth letter of length>=12:
{{`inappropriate`, `ira`, `not`, `ape`, `pr`, `pi`}}

Every sixth letter of length>=12:
{{`aristotelean`, `at`, `re`, `il`, `se`, `ta`, `on`},
 {`warehouseman`, `wu`, `as`, `re`, `em`, `ha`, `on`}}

Raku

<lang perl6>unit sub MAIN ($file = 'unixdict.txt', :$min = 6);

my %words = $file.IO.slurp.words.map: * => 1;

my @alternades;

for %words {

   next if .key.chars < $min;
   my @letters = .key.comb;
   my @alts = @letters[0,2 … *].join, @letters[1,3 … *].join;
   @alternades.push(.key => @alts) if %words{@alts[0]} && %words{@alts[1]};

}

@alternades.=sort;

say "{+@alternades} alternades longer than {$min-1} characters found in $file:";

.say for @alternades > 10

 ?? (flat @alternades.head(5), '...', @alternades.tail(5))
 !! @alternades;</lang>
Output:
58 alternades longer than 5 characters found in unixdict.txt:
accost => [acs cot]
accuse => [acs cue]
afield => [ail fed]
agleam => [ala gem]
alcott => [act lot]
...
triode => [tid roe]
triune => [tin rue]
troupe => [top rue]
truant => [tun rat]
twirly => [til wry]

Ring

<lang ring> load "stdlib.ring"

cStr = read("unixdict.txt") wordList = str2list(cStr) sum = 0 see "working..." + nl + nl

for n = 1 to len(wordList)

   wordOdd = ""
   wordEven = ""
   for m = 1 to len(wordList[n]) step 2
       wordOdd = wordOdd + wordList[n][m] 
   next
   for m = 2 to len(wordList[n]) step 2
       wordEven = wordEven + wordList[n][m] 
   next
   indOdd = find(wordList,wordOdd)
   indEven = find(wordList,wordEven)
   if indOdd > 0 and indEven > 0 and len(wordList[indOdd]) > 2 and len(wordList[indEven]) > 2
      sum = sum + 1 
      see "" + sum + ". "
      see "word = " + wordList[n] + nl
      see "wordOdd = " + wordList[indOdd] + nl
      see "wordEven = " + wordList[indEven] + nl + nl
   ok

next see "done..." + nl </lang> Output:

working...

1. word = accost
wordOdd = acs
wordEven = cot

2. word = accuse
wordOdd = acs
wordEven = cue

3. word = afield
wordOdd = ail
wordEven = fed

4. word = agleam
wordOdd = ala
wordEven = gem

5. word = alcott
wordOdd = act
wordEven = lot

6. word = allele
wordOdd = all
wordEven = lee

7. word = allied
wordOdd = ale
wordEven = lid

8. word = alpert
wordOdd = apr
wordEven = let

9. word = ambient
wordOdd = abet
wordEven = min

10. word = annette
wordOdd = ante
wordEven = net

11. word = apport
wordOdd = apr
wordEven = pot

12. word = ariadne
wordOdd = aide
wordEven = ran

13. word = assist
wordOdd = ass
wordEven = sit

14. word = battle
wordOdd = btl
wordEven = ate

15. word = blaine
wordOdd = ban
wordEven = lie

16. word = brenda
wordOdd = bed
wordEven = rna

17. word = calliope
wordOdd = clip
wordEven = aloe

18. word = choose
wordOdd = cos
wordEven = hoe

19. word = choosy
wordOdd = cos
wordEven = hoy

20. word = claire
wordOdd = car
wordEven = lie

21. word = collude
wordOdd = clue
wordEven = old

22. word = effete
wordOdd = eft
wordEven = fee

23. word = fabric
wordOdd = fbi
wordEven = arc

24. word = fealty
wordOdd = fat
wordEven = ely

25. word = fluent
wordOdd = fun
wordEven = let

26. word = forwent
wordOdd = fret
wordEven = own

27. word = friend
wordOdd = fin
wordEven = red

28. word = george
wordOdd = gog
wordEven = ere

29. word = inroad
wordOdd = ira
wordEven = nod

30. word = israel
wordOdd = ire
wordEven = sal

31. word = jaunty
wordOdd = jut
wordEven = any

32. word = joanne
wordOdd = jan
wordEven = one

33. word = lounge
wordOdd = lug
wordEven = one

34. word = oriole
wordOdd = oil
wordEven = roe

35. word = oswald
wordOdd = owl
wordEven = sad

36. word = parrot
wordOdd = pro
wordEven = art

37. word = peoria
wordOdd = poi
wordEven = era

38. word = pierre
wordOdd = per
wordEven = ire

39. word = poodle
wordOdd = pol
wordEven = ode

40. word = pounce
wordOdd = puc
wordEven = one

41. word = racial
wordOdd = rca
wordEven = ail

42. word = realty
wordOdd = rat
wordEven = ely

43. word = sordid
wordOdd = sri
wordEven = odd

44. word = spatial
wordOdd = sail
wordEven = pta

45. word = sprain
wordOdd = sri
wordEven = pan

46. word = strain
wordOdd = sri
wordEven = tan

47. word = strait
wordOdd = sri
wordEven = tat

48. word = sturdy
wordOdd = sud
wordEven = try

49. word = sweaty
wordOdd = set
wordEven = way

50. word = tattle
wordOdd = ttl
wordEven = ate

51. word = theorem
wordOdd = term
wordEven = hoe

52. word = though
wordOdd = tog
wordEven = huh

53. word = throaty
wordOdd = tray
wordEven = hot

54. word = triode
wordOdd = tid
wordEven = roe

55. word = triune
wordOdd = tin
wordEven = rue

56. word = troupe
wordOdd = top
wordEven = rue

57. word = truant
wordOdd = tun
wordEven = rat

58. word = twirly
wordOdd = til
wordEven = wry

done...

Wren

Library: Wren-set
Library: Wren-fmt

<lang ecmascript>import "io" for File import "/set" for Set import "/fmt" for Fmt

var wordList = "unixdict.txt" // local copy var set = Set.new() var words = File.read(wordList).trimEnd().split("\n") for (word in words) set.add(word) System.print("'unixdict.txt' contains the following alternades of length 6 or more:\n") var count = 0 for (word in words) {

   if (word.count >= 6) {
       var w1 = ""
       var w2 = ""
       var i = 0
       for (c in word) {
          if (i%2 == 0) {
               w1 = w1 + c
          } else {
               w2 = w2 + c
          }
          i = i + 1
       }
       if (set.contains(w1) && set.contains(w2)) {
           count = count + 1
           Fmt.print("$2d: $-8s -> $-4s $-4s", count, word, w1, w2)
       }
   }

}</lang>

Output:
'unixdict.txt' contains the following alternades of length 6 or more:

 1: accost   -> acs  cot 
 2: accuse   -> acs  cue 
 3: afield   -> ail  fed 
 4: agleam   -> ala  gem 
 5: alcott   -> act  lot 
 6: allele   -> all  lee 
 7: allied   -> ale  lid 
 8: alpert   -> apr  let 
 9: ambient  -> abet min 
10: annette  -> ante net 
11: apport   -> apr  pot 
12: ariadne  -> aide ran 
13: assist   -> ass  sit 
14: battle   -> btl  ate 
15: blaine   -> ban  lie 
16: brenda   -> bed  rna 
17: calliope -> clip aloe
18: choose   -> cos  hoe 
19: choosy   -> cos  hoy 
20: claire   -> car  lie 
21: collude  -> clue old 
22: effete   -> eft  fee 
23: fabric   -> fbi  arc 
24: fealty   -> fat  ely 
25: fluent   -> fun  let 
26: forwent  -> fret own 
27: friend   -> fin  red 
28: george   -> gog  ere 
29: inroad   -> ira  nod 
30: israel   -> ire  sal 
31: jaunty   -> jut  any 
32: joanne   -> jan  one 
33: lounge   -> lug  one 
34: oriole   -> oil  roe 
35: oswald   -> owl  sad 
36: parrot   -> pro  art 
37: peoria   -> poi  era 
38: pierre   -> per  ire 
39: poodle   -> pol  ode 
40: pounce   -> puc  one 
41: racial   -> rca  ail 
42: realty   -> rat  ely 
43: sordid   -> sri  odd 
44: spatial  -> sail pta 
45: sprain   -> sri  pan 
46: strain   -> sri  tan 
47: strait   -> sri  tat 
48: sturdy   -> sud  try 
49: sweaty   -> set  way 
50: tattle   -> ttl  ate 
51: theorem  -> term hoe 
52: though   -> tog  huh 
53: throaty  -> tray hot 
54: triode   -> tid  roe 
55: triune   -> tin  rue 
56: troupe   -> top  rue 
57: truant   -> tun  rat 
58: twirly   -> til  wry