Odd words
Given a list of words, (use the words from the dictionary unixdict.txt).
Take the letters at odd indices letters from each word. If the result is present in the list, then display the result. The length of the odd word should be > 4.
- Metrics
- Counting
- Word frequency
- Letter frequency
- Jewels and stones
- I before E except after C
- Bioinformatics/base count
- Count occurrences of a substring
- Count how many vowels and consonants occur in a string
- Remove/replace
- XXXX redacted
- Conjugate a Latin verb
- Remove vowels from a string
- String interpolation (included)
- Strip block comments
- Strip comments from a string
- Strip a set of characters from a string
- Strip whitespace from a string -- top and tail
- Strip control codes and extended characters from a string
- Anagrams/Derangements/shuffling
- Word wheel
- ABC problem
- Sattolo cycle
- Knuth shuffle
- Ordered words
- Superpermutation minimisation
- Textonyms (using a phone text pad)
- Anagrams
- Anagrams/Deranged anagrams
- Permutations/Derangements
- Find/Search/Determine
- ABC words
- Odd words
- Word ladder
- Semordnilap
- Word search
- Wordiff (game)
- String matching
- Tea cup rim text
- Alternade words
- Changeable words
- State name puzzle
- String comparison
- Unique characters
- Unique characters in each string
- Extract file extension
- Levenshtein distance
- Palindrome detection
- Common list elements
- Longest common suffix
- Longest common prefix
- Compare a list of strings
- Longest common substring
- Find common directory path
- Words from neighbour ones
- Change e letters to i in words
- Non-continuous subsequences
- Longest common subsequence
- Longest palindromic substrings
- Longest increasing subsequence
- Words containing "the" substring
- Sum of the digits of n is substring of n
- Determine if a string is numeric
- Determine if a string is collapsible
- Determine if a string is squeezable
- Determine if a string has all unique characters
- Determine if a string has all the same characters
- Longest substrings without repeating characters
- Find words which contains all the vowels
- Find words which contain the most consonants
- Find words which contains more than 3 vowels
- Find words whose first and last three letters are equal
- Find words with alternating vowels and consonants
- Formatting
- Substring
- Rep-string
- Word wrap
- String case
- Align columns
- Literals/String
- Repeat a string
- Brace expansion
- Brace expansion using ranges
- Reverse a string
- Phrase reversals
- Comma quibbling
- Special characters
- String concatenation
- Substring/Top and tail
- Commatizing numbers
- Reverse words in a string
- Suffixation of decimal numbers
- Long literals, with continuations
- Numerical and alphabetical suffixes
- Abbreviations, easy
- Abbreviations, simple
- Abbreviations, automatic
- Song lyrics/poems/Mad Libs/phrases
- Mad Libs
- Magic 8-ball
- 99 bottles of beer
- The Name Game (a song)
- The Old lady swallowed a fly
- The Twelve Days of Christmas
- Tokenize
- Text between
- Tokenize a string
- Word break problem
- Tokenize a string with escaping
- Split a character string based on change of character
- Sequences
11l
V wordSet = Set(File(‘unixdict.txt’).read().split("\n"))
Set[String] oddWordSet
L(word) wordSet
I word.len >= 9 & word[(0..).step(2)] C wordSet
oddWordSet.add(word[(0..).step(2)])
L(i) sorted(Array(oddWordSet))
print(i)
- Output:
brain cider cried grata hades plain point saute sight slain spree trial
AArch64 Assembly
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program oddwords64.s */
/************************************/
/* Constantes */
/************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"
.equ BUFFERSIZE, 300000
.equ WORDSIZE, 4
//.include "../../ficmacros64.inc" // use for developper debugging
/*******************************************/
/* Structures **/
/*******************************************/
/* structure words array */
.struct 0
st_word_adr:
.struct st_word_adr + 8
st_word_size:
.struct st_word_size + 8
st_word_end:
/************************************/
/* Initialized data */
/************************************/
.data
szMessOpen: .asciz "File open error.\n"
szMessRead: .asciz "File read error.\n"
szMessClose: .asciz "File close error.\n"
szFileName: .asciz "unixdict.txt"
szMessResult: .asciz " : "
szCarriageReturn: .asciz "\n"
szMessStart: .asciz "Program 64 bits start.\n"
/************************************/
/* UnInitialized data */
/************************************/
.bss
sZoneConv: .skip 24
sBuffer: .skip BUFFERSIZE // file buffer
.align 4
WordArray: .skip st_word_end * 0x10000
/************************************/
/* code section */
/************************************/
.text
.global main
main: // entry of program
ldr x0,qAdrszMessStart
bl affichageMess
ldr x0,qAdrszFileName // file name
ldr x1,qAdrsBuffer // read buffer address
ldr x2,#iBufferSize // buffer size
ldr x3,qAdrWordArray // word address array
bl readFile
cmp x0,#-1 // file error ?
beq 100f
mov x2,x0 // word counter
ldr x0,qAdrsBuffer
ldr x1,qAdrWordArray // array address
bl traitWord
100: // standard end of the program
mov x0, #0 // return code
mov x8, #EXIT // request to exit program
svc 0 // perform the system call
qAdrsZoneConv: .quad sZoneConv
qAdrszMessResult: .quad szMessResult
qAdrszCarriageReturn: .quad szCarriageReturn
qAdrszMessStart: .quad szMessStart
qAdrszFileName: .quad szFileName
qAdrszMessOpen: .quad szMessOpen
qAdrszMessRead: .quad szMessRead
qAdrszMessClose: .quad szMessClose
qAdrsBuffer: .quad sBuffer
iBufferSize: .quad BUFFERSIZE
qAdrWordArray: .quad WordArray
/***************************************************/
/* read file and create array words */
/***************************************************/
/* x0 contains file name */
/* x1 contains a file buffer */
/* x2 contains buffer size */
/* x3 contains array word address */
readFile:
stp x1,lr,[sp,-16]!
stp x2,x3,[sp,-16]!
stp x4,x5,[sp,-16]!
stp x6,x7,[sp,-16]!
stp x8,x9,[sp,-16]!
mov x9,x1 // file buffer
mov x6,x2
mov x1,x0
mov x10,x3
mov x0,AT_FDCWD
mov x2,#O_RDWR // flags
mov x3,#0 // mode
mov x8,#OPEN // file open
svc 0
cmp x0,#0 // error ?
ble 99f
mov x7,x0 // FD save
mov x0,x7
mov x1,x9 // read buffer address
mov x2,x6
mov x8,#READ // call system read file
svc 0
cmp x0,#0 // error read ?
blt 97f
mov x6,x0 // save file size
mov x0,x7 // FD
mov x8,#CLOSE // call system close file
svc 0
cmp x0,#0 // error close ?
blt 96f
mov x1,#0 // index buffer
mov x2,x9 // file buffer address
mov x3,#0 // word length
mov x5,#0 // word counter
1:
ldrb w4,[x9,x1] // load character file buffer
cmp x4,#0x0D // end word ?
beq 2f // yes
add x1,x1,#1 // increment index and length
add x3,x3,#1
b 1b // and loop
2: //
strb wzr,[x9,x1] // store 0 final in word
cmp x3,#WORDSIZE // word length ?
ble 3f // no ?
mov x0,#st_word_end // structure size
madd x0,x5,x0,x10 // compute word item address
str x2,[x0,#st_word_adr] // store word address in array word
str x3,[x0,#st_word_size] // store word size in array word
add x5,x5,#1 // increment word counter
3:
add x1,x1,#2 // increment index buffer (0D0A)
cmp x1,x6 // end ?
bge 4f
add x2,x9,x1 // new word begin
mov x3,#0 // init word length
b 1b // and loop
4:
mov x0,x5 // return word counter
b 100f
96: // display error messages
ldr x0,qAdrszMessClose
bl affichageMess
mov x0,#-1 // error
b 100f
97:
ldr x0,qAdrszMessRead
bl affichageMess
mov x0,#-1 // error
b 100f
99:
ldr x0,qAdrszMessOpen
bl affichageMess
mov x0,#-1 // error
100:
ldp x8,x9,[sp],16
ldp x6,x7,[sp],16
ldp x4,x5,[sp],16
ldp x2,x3,[sp],16
ldp x1,lr,[sp],16
ret
/***************************************************/
/* word analyse */
/***************************************************/
/* x0 contains a file buffer */
/* x1 contains array word address */
/* x2 contains array element */
traitWord:
stp x1,lr,[sp,-16]!
stp x2,x3,[sp,-16]!
stp x4,x5,[sp,-16]!
stp x6,x7,[sp,-16]!
stp x8,x9,[sp,-16]!
stp x10,x12,[sp,-16]!
mov x7,x0 // save buffer address
mov x8,x1 // save array word address
mov x9,x2 // save size
mov x10,#0 // init index word array
sub sp,sp,#80 // reserve 80 byte on stack for work array
mov fp,sp // work array address
1:
mov x0,#st_word_end // structure size
madd x0,x10,x0,x8 // compute word item address
ldr x12,[x0,#st_word_adr] // load one word address
ldr x5,[x0,#st_word_size] // load word size
mov x3,#0 // index word
mov x6,#0 // size new word
2:
ldrb w4,[x12,x3] // load characters on odd index
strb w4,[fp,x6] // store in wprk array on stack
add x6,x6,#1 // increment size new word
add x3,x3,#2 // increment index
cmp x3,x5 // end word ?
ble 2b
cmp x6,#WORDSIZE // length new word ok ?
ble 10f
strb wzr,[fp,x6] // store 0 final new word
// search new word in word array by binary search
// in french recherche dichotomique
mov x3,#0 // low index
sub x4,x9,#1 // high index = number of elements - 1
3: // begin search loop
cmp x3,x4 // low > high
bgt 10f // not found
add x7,x3,x4 // compute (low + high) /2
lsr x7,x7,#1
mov x1,#st_word_end // structure size
madd x2,x7,x1,x8 // compute word item address
ldr x0,[x2,#st_word_adr] // load word array address at new index r7
mov x1,fp // search word address
bl comparerChaines // alpha comparison
cmp x0,#0
beq 4f // find
add x0,x7,1
csel x3,x0,x3,lt // lower -> index low = index + 1
sub x0,x7,1
csel x4,x0,x4,gt // bigger -> index high = index - 1
b 3b // and loop
4: // ok -> display result
mov x0,x12
bl affichageMess
ldr x0,qAdrszMessResult
bl affichageMess
mov x0,fp
bl affichageMess
ldr x0,qAdrszCarriageReturn
bl affichageMess
10:
mov x6,#0 // init new length new word
add x10,x10,#1 // increment index word array
cmp x10,x9 // end ?
blt 1b // no -> loop
100:
add sp,sp,#80 // stack alignement release work array
ldp x10,x12,[sp],16
ldp x8,x9,[sp],16
ldp x6,x7,[sp],16
ldp x4,x5,[sp],16
ldp x2,x3,[sp],16
ldp x1,lr,[sp],16
ret
/***************************************************/
/* ROUTINES INCLUDE */
/***************************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeARM64.inc"
- Output:
Program 64 bits start. barbarian : brain childbear : cider corrigenda : cried gargantuan : grata headdress : hades palladian : plain propionate : point salvation : slain siltation : slain slingshot : sight statuette : saute supersede : spree supervene : spree terminable : trial
Ada
Using instances of generic procedure to filter odd/even words.
with Ada.Text_Io;
with Ada.Containers.Indefinite_Ordered_Maps;
procedure Odd_Words is
use Ada.Text_Io;
package String_Maps is
new Ada.Containers.Indefinite_Ordered_Maps (Key_Type => String,
Element_Type => String);
Filename : constant String := "unixdict.txt";
Words : String_Maps.Map;
function Get_Odd (Word : String) return String is
Odd : String (1 .. (Word'Length + 1) / 2);
begin
for Index in Odd'Range loop
Odd (Index) := Word (1 + 2 * (Index - 1));
end loop;
return Odd;
end Get_Odd;
function Get_Even (Word : String) return String is
Even : String (1 .. Word'Length / 2);
begin
for Index in Even'Range loop
Even (Index) := Word (1 + 1 + 2 * (Index - 1));
end loop;
return Even;
end Get_Even;
generic
with function Filter (Word : String) return String;
procedure Iterate_Map;
procedure Iterate_Map is
begin
for Word of Words loop
declare
Half : constant String := Filter (Word);
begin
if Half'Length > 4 and then Words.Contains (Half) then
Put (Word); Set_Col (15); Put_Line (Half);
end if;
end;
end loop;
end Iterate_Map;
procedure Put_Odd_Words is new Iterate_Map (Get_Odd);
procedure Put_Even_Words is new Iterate_Map (Get_Even);
File : File_Type;
begin
Open (File, In_File, Filename);
while not End_Of_File (File) loop
declare
Word : constant String := Get_Line (File);
begin
Words.Insert (Word, Word);
end;
end loop;
Close (File);
Put_Line ("Odd words:");
Put_Odd_Words;
New_Line;
Put_Line ("Even words:");
Put_Even_Words;
end Odd_Words;
- Output:
Odd words: barbarian brain childbear cider corrigenda cried gargantuan grata headdress hades palladian plain propionate point salvation slain siltation slain slingshot sight statuette saute supersede spree supervene spree terminable trial Even words: cannonball annal importation motto psychopomp scoop starvation train upholstery posey
ALGOL 68
Note the source of the RC library ALGOL 68-files and ALGOL 68-sort libraries are on separate pages on Rosetta Code, see the above links. Based on (and almost identical to) the Alternade Words sample.
BEGIN # find words of 9 or more characters where the odd letters also #
# form a word; the odd characters must therefore form a word of at #
# least 5 characters #
PR read "files.incl.a68" PR # include file utilities #
PR read "sort.incl.a68" PR # include sort utilities #
# returns w split into n parts by taking alternate characters #
PRIO SPLIT = 1;
OP SPLIT = ( STRING w, INT n )[]STRING:
BEGIN
[ n ]STRING result;
FOR r pos FROM LWB result TO UPB result DO result[ r pos ] := "" OD;
INT n pos := 1;
FOR w pos FROM LWB w TO UPB w DO
result[ n pos ] +:= w[ w pos ];
n pos +:= 1;
IF n pos > n THEN n pos := 1 FI
OD;
result
END # SPLIT # ;
[ 1 : 25 000 ]STRING words; # unixdict.txt has around 22 000 5+ #
# character words #
# stores word in words, if it is at least 5 characters long #
# returns TRUE if word was stored, FALSE otherwise #
# count so far will contain the number of words stored so far #
PROC store 5 plus character words = ( STRING word, INT count so far )BOOL:
IF ( UPB word - LWB word ) + 1 < 5
THEN FALSE # short word #
ELSE words[ count so far + 1 ] := word; # word is long enough #
TRUE
FI # store 5 plus character words # ;
# returns TRUE if words[ low : high ] comntains s, FALSE otherwise #
PROC is word = ( STRING s, INT low, high )BOOL:
IF high < low THEN FALSE
ELSE INT mid = ( low + high ) OVER 2;
IF words[ mid ] > s THEN is word( s, low, mid - 1 )
ELIF words[ mid ] = s THEN TRUE
ELSE is word( s, mid + 1, high )
FI
FI # is word # ;
IF INT w count = "unixdict.txt" EACHLINE store 5 plus character words;
w count < 0
THEN print( ( "Unable to open unixdict.txt", newline ) )
ELSE words QUICKSORT ELEMENTS( 1, w count ); # sort the words #
FOR i TO w count DO # find the words where the odd letters #
STRING word = words[ i ]; # form a 5+ character word #
IF INT w len = ( UPB word - LWB word ) + 1;
w len > 8
THEN # word is at least 9 characters long #
[]STRING sub word = word SPLIT 2;
IF is word( sub word[ 1 ], 1, w count )
THEN print( ( word, ": " ) );
FROM w len + 1 TO 18 DO print( ( " " ) ) OD;
print( ( sub word[ 1 ], newline ) )
FI
FI
OD
FI
END
- Output:
barbarian: brain childbear: cider corrigenda: cried gargantuan: grata headdress: hades palladian: plain propionate: point salvation: slain siltation: slain slingshot: sight statuette: saute supersede: spree supervene: spree terminable: trial
ARM Assembly
/* ARM assembly Raspberry PI */
/* program oddwords.s */
/************************************/
/* Constantes */
/************************************/
/* for this file see task include a file in language ARM assembly*/
.include "../constantes.inc"
.equ READ, 3
.equ WRITE, 4
.equ OPEN, 5
.equ CLOSE, 6
.equ O_RDWR, 0x0002 @ open for reading and writing
.equ BUFFERSIZE, 300000
.equ WORDSIZE, 4
//.include "../../ficmacros32.inc" @ use for developper debugging
/*******************************************/
/* Structures **/
/*******************************************/
/* structure words array */
.struct 0
st_word_adr:
.struct st_word_adr + 4
st_word_size:
.struct st_word_size + 4
st_word_end:
/************************************/
/* Initialized data */
/************************************/
.data
szMessOpen: .asciz "File open error.\n"
szMessRead: .asciz "File read error.\n"
szMessClose: .asciz "File close error.\n"
szFileName: .asciz "unixdict.txt"
szMessResult: .asciz " : "
szCarriageReturn: .asciz "\n"
szMessStart: .asciz "Program 32 bits start.\n"
/************************************/
/* UnInitialized data */
/************************************/
.bss
sZoneConv: .skip 24
sBuffer: .skip BUFFERSIZE @ file buffer
.align 4
WordArray: .skip st_word_end * 0x10000
/************************************/
/* code section */
/************************************/
.text
.global main
main: @ entry of program
ldr r0,iAdrszMessStart
bl affichageMess
ldr r0,iAdrszFileName @ file name
ldr r1,iAdrsBuffer @ read buffer address
ldr r2,#iBufferSize @ buffer size
ldr r3,iAdrWordArray @ word address array
bl readFile
cmp r0,#-1 @ file error ?
beq 100f
mov r2,r0 @ word counter
ldr r0,iAdrsBuffer
ldr r1,iAdrWordArray @ array address
bl traitWord
100: @ standard end of the program
mov r0, #0 @ return code
mov r7, #EXIT @ request to exit program
svc 0 @ perform the system call
iAdrsZoneConv: .int sZoneConv
iAdrszMessResult: .int szMessResult
iAdrszCarriageReturn: .int szCarriageReturn
iAdrszMessStart: .int szMessStart
iAdrszFileName: .int szFileName
iAdrszMessOpen: .int szMessOpen
iAdrszMessRead: .int szMessRead
iAdrszMessClose: .int szMessClose
iAdrsBuffer: .int sBuffer
iBufferSize: .int BUFFERSIZE
iAdrWordArray: .int WordArray
/***************************************************/
/* read file and create array words */
/***************************************************/
/* r0 contains file name */
/* r1 contains a file buffer */
/* r2 contains buffer size */
/* r3 contains array word address */
readFile:
push {r1-r9,lr} @ save registers
mov r9,r1 @ file buffer
mov r6,r2
mov r10,r3
mov r1,#O_RDWR @ flags
mov r2,#0 @ mode
mov r7,#OPEN @ file open
svc 0
cmp r0,#0 @ error ?
ble 99f
mov r8,r0 @ FD save
mov r0,r8
mov r1,r9 @ read buffer address
mov r2,r6
mov r7,#READ @ call system read file
svc 0
cmp r0,#0 @ error read ?
blt 97f
mov r6,r0 @ save file size
mov r0,r8 @ FD
mov r7,#CLOSE @ call system close file
svc 0
cmp r0,#0 @ error close ?
blt 96f
mov r1,#0 @ index buffer
mov r2,r9 @ file buffer address
mov r3,#0 @ word length
mov r5,#0 @ word counter
1:
ldrb r4,[r9,r1] @ load character file buffer
cmp r4,#0x0D @ end word ?
beq 2f @ yes
add r1,r1,#1 @ increment index and length
add r3,r3,#1
b 1b @ and loop
2:
mov r4,#0 @
strb r4,[r9,r1] @ store 0 final in word
cmp r3,#WORDSIZE @ word length ?
ble 3f @ no ?
mov r0,#st_word_end @ structure size
mla r0,r5,r0,r10 @ compute word item address
str r2,[r0,#st_word_adr] @ store word address in array word
str r3,[r0,#st_word_size] @ store word size in array word
add r5,r5,#1 @ increment word counter
3:
add r1,r1,#2 @ increment index buffer (0D0A)
cmp r1,r6 @ end ?
bge 4f
add r2,r9,r1 @ new word begin
mov r3,#0 @ init word length
b 1b @ and loop
4:
mov r0,r5 @ return word counter
b 100f
96: @ display error messages
ldr r0,iAdrszMessClose
bl affichageMess
mov r0,#-1 @ error
b 100f
97:
ldr r0,iAdrszMessRead
bl affichageMess
mov r0,#-1 @ error
b 100f
99:
ldr r0,iAdrszMessOpen
bl affichageMess
mov r0,#-1 @ error
100:
pop {r1-r9,pc}
/***************************************************/
/* word analyse */
/***************************************************/
/* r0 contains a file buffer */
/* r1 contains array word address */
/* r2 contains array element */
traitWord:
push {r1-r12,lr} @ save registers
mov r7,r0 @ save buffer address
mov r8,r1 @ save array word address
mov r9,r2 @ save size
mov r10,#0 @ init index word array
sub sp,sp,#80 @ reserve 80 byte on stack for work array
mov fp,sp @ work array address
1:
mov r0,#st_word_end @ structure size
mla r0,r10,r0,r8 @ compute word item address
ldr r12,[r0,#st_word_adr] @ load one word address
ldr r5,[r0,#st_word_size] @ load word size
mov r3,#0 @ index word
mov r6,#0 @ size new word
2:
ldrb r4,[r12,r3] @ load characters on odd index
strb r4,[fp,r6] @ store in wprk array on stack
add r6,r6,#1 @ increment size new word
add r3,r3,#2 @ increment index
cmp r3,r5 @ end word ?
ble 2b
cmp r6,#WORDSIZE @ length new word ok ?
ble 10f
mov r4,#0 @ store 0 final new word
strb r4,[fp,r6]
@ search new word in word array by binary search
@ in french recherche dichotomique
mov r3,#0 @ low index
sub r4,r9,#1 @ high index = number of elements - 1
3: @ begin search loop
cmp r3,r4 @ low > high
bgt 10f @ not found
add r7,r3,r4 @ compute (low + high) /2
lsr r7,#1
mov r1,#st_word_end @ structure size
mla r2,r7,r1,r8 @ compute word item address
ldr r0,[r2,#st_word_adr] @ load word array address at new index r7
mov r1,fp @ search word address
bl comparaison @ alpha comparison
cmp r0,#0
beq 4f @ find
addlt r3,r7,#1 @ lower -> index low = index + 1
subgt r4,r7,#1 @ bigger -> index high = index - 1
b 3b @ and loop
4: @ ok -> display result
mov r0,r12
bl affichageMess
ldr r0,iAdrszMessResult
bl affichageMess
mov r0,fp
bl affichageMess
ldr r0,iAdrszCarriageReturn
bl affichageMess
10:
mov r6,#0 @ init new length new word
add r10,r10,#1 @ increment index word array
cmp r10,r9 @ end ?
blt 1b @ no -> loop
100:
add sp,sp,#80 @ stack alignement release work array
pop {r1-r12,pc}
/***************************************************/
/* ROUTINES INCLUDE */
/***************************************************/
/* for this file see task include a file in language ARM assembly*/
.include "../affichage.inc"
- Output:
Program 32 bits start. barbarian : brain childbear : cider corrigenda : cried gargantuan : grata headdress : hades palladian : plain propionate : point salvation : slain siltation : slain slingshot : sight statuette : saute supersede : spree supervene : spree terminable : trial
Arturo
words: read.lines relative "unixdict.txt"
getOdd: function [w][
odd: new ""
loop.with:'i w 'ch [
if even? i -> 'odd ++ ch
]
odd
]
loop words 'word [
ow: getOdd word
if and? [4 < size ow][contains? words ow] ->
print [word "=>" ow]
]
- Output:
barbarian => brain childbear => cider corrigenda => cried gargantuan => grata headdress => hades palladian => plain propionate => point salvation => slain siltation => slain slingshot => sight statuette => saute supersede => spree supervene => spree terminable => trial
AWK
# syntax: GAWK -f ODD_WORDS.AWK unixdict.txt
#
# sorting:
# PROCINFO["sorted_in"] is used by GAWK
# SORTTYPE is used by Thompson Automation's TAWK
#
{ arr[$0]++ }
END {
PROCINFO["sorted_in"] = "@ind_str_asc" ; SORTTYPE = 1
main("13579","odd")
main("02468","even")
exit(0)
}
function main(pattern,text, i,tmp,word) {
pattern = sprintf("[%s]$",pattern)
printf("\n%s:\n",text)
for (word in arr) {
tmp = ""
for (i=1; i<=length(word); i++) {
if (i ~ pattern) {
tmp = tmp substr(word,i,1)
}
}
if (length(tmp) > 4 && tmp in arr) {
printf("%-11s %s\n",word,tmp)
}
}
}
- Output:
odd: barbarian brain childbear cider corrigenda cried gargantuan grata headdress hades palladian plain propionate point salvation slain siltation slain slingshot sight statuette saute supersede spree supervene spree terminable trial even: cannonball annal importation motto psychopomp scoop starvation train upholstery posey
BQN
Odds ← ⊑˘↑‿2⊸⥊
•Show Odds¨⊸(∊/≍˘˜) (4<≠¨)⊸/ •Flines "unixdict.txt"
- Output:
┌─ ╵ "barbarian" "brain" "childbear" "cider" "corrigenda" "cried" "gargantuan" "grata" "headdress" "hades" "palladian" "plain" "propionate" "point" "salvation" "slain" "siltation" "slain" "slingshot" "sight" "statuette" "saute" "supersede" "spree" "supervene" "spree" "terminable" "trial" ┘
C++
#include <cstdlib>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <set>
#include <string>
#include <utility>
#include <vector>
using word_list = std::vector<std::pair<std::string, std::string>>;
void print_words(std::ostream& out, const word_list& words) {
int n = 1;
for (const auto& pair : words) {
out << std::right << std::setw(2) << n++ << ": "
<< std::left << std::setw(14) << pair.first
<< pair.second << '\n';
}
}
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;
}
const int min_length = 5;
std::string line;
std::set<std::string> dictionary;
while (getline(in, line)) {
if (line.size() >= min_length)
dictionary.insert(line);
}
word_list odd_words, even_words;
for (const std::string& word : dictionary) {
if (word.size() < min_length + 2*(min_length/2))
continue;
std::string odd_word, even_word;
for (auto w = word.begin(); w != word.end(); ++w) {
odd_word += *w;
if (++w == word.end())
break;
even_word += *w;
}
if (dictionary.find(odd_word) != dictionary.end())
odd_words.emplace_back(word, odd_word);
if (dictionary.find(even_word) != dictionary.end())
even_words.emplace_back(word, even_word);
}
std::cout << "Odd words:\n";
print_words(std::cout, odd_words);
std::cout << "\nEven words:\n";
print_words(std::cout, even_words);
return EXIT_SUCCESS;
}
- Output:
Odd words: 1: barbarian brain 2: childbear cider 3: corrigenda cried 4: gargantuan grata 5: headdress hades 6: palladian plain 7: propionate point 8: salvation slain 9: siltation slain 10: slingshot sight 11: statuette saute 12: supersede spree 13: supervene spree 14: terminable trial Even words: 1: cannonball annal 2: importation motto 3: psychopomp scoop 4: starvation train 5: upholstery posey
Delphi
procedure ShowOddWords(Memo: TMemo);
var I,J: integer;
var W,S: string;
begin
{Iterate all entries in dictionary}
for I:=0 to UnixDict.Count-1 do
if Length(UnixDict[I])>8 then {Word must be >4, so every other is >8}
begin
W:=UnixDict[I];
{Take every other letter}
J:=1; S:='';
while J<=Length(W) do
begin
S:=S+W[J];
Inc(J,2);
end;
{Check if it is in Dictionary}
if UnixDict.IndexOf(S)>0 then
begin
Memo.Lines.Add(W+' -> '+S);
end;
end;
end;
- Output:
barbarian -> brain childbear -> cider corrigenda -> cried gargantuan -> grata headdress -> hades palladian -> plain propionate -> point salvation -> slain siltation -> slain slingshot -> sight statuette -> saute supersede -> spree supervene -> spree terminable -> trial Elapsed Time: 44.351 ms.
DuckDB
create or replace function oddly(str) as (
regexp_extract_all(str, '.')
.list_filter( (x,i) -> i%2 = 1)
.array_to_string('')
);
with cte as (
from read_csv('unixdict.txt', header=false)
where column0 ~ '^[a-zA-Z].*'
and length(column0) > 4)
select odd
from (
select column0 as str, oddly(str) as odd
from cte
where odd IN (from cte) );
- Output:
┌─────────┐ │ odd │ │ varchar │ ├─────────┤ │ brain │ │ cider │ │ cried │ │ grata │ │ hades │ │ plain │ │ point │ │ slain │ │ slain │ │ sight │ │ saute │ │ spree │ │ spree │ │ trial │ ├─────────┤ │ 14 rows │ └─────────┘
EasyLang
repeat
s$ = input
until s$ = ""
if len s$ >= 5
w$[] &= s$
.
.
func binsearch s$ .
max = len w$[] + 1
while min + 1 < max
mid = min + (max - min) div 2
h = strcmp w$[mid] s$
if h = 0
return 1
elif h < 0
min = mid
else
max = mid
.
.
return 0
.
for w$ in w$[]
if len w$ >= 9
h$[] = strchars w$
h$ = ""
for i = 1 step 2 to len h$[]
h$ &= h$[i]
.
if binsearch h$ = 1
print w$ & " -> " & h$
.
.
.
# the content of unixdict.txt
input_data
10th
.
barbarian
.
brain
.
F#
// Odd words: Nigel Galloway. June 9th., 2021
let dict=seq{use n=System.IO.File.OpenText("unixdict.txt") in while not n.EndOfStream do yield n.ReadLine()}|>Seq.filter(fun n->n.Length>4)|>List.ofSeq
let fN g=let n=g|>String.mapi(fun n g->if n%2=0 then g else ' ')|>String.filter((<>)' ') in match List.contains n dict with true->Some(n,g) |_->None
dict|>Seq.filter(fun n->n.Length>6)|>Seq.choose fN|>Seq.iter(fun(n,g)->printfn "%s -> %s" g n)
- Output:
barbarian -> brain childbear -> cider corrigenda -> cried gargantuan -> grata headdress -> hades palladian -> plain propionate -> point salvation -> slain siltation -> slain slingshot -> sight statuette -> saute supersede -> spree supervene -> spree terminable -> trial
Factor
This is basically the same program as https://rosettacode.org/wiki/Alternade_words#Factor. <evens>
is a virtual sequence representing the (zero-based) even indices of the input sequence, which this task calls the odd indices.
USING: formatting hash-sets io io.encodings.ascii io.files
kernel literals math sequences sequences.extras sets strings ;
<< CONSTANT: words $[ "unixdict.txt" ascii file-lines ] >>
CONSTANT: wordset $[ words >hash-set ]
: odd ( str -- newstr ) <evens> >string ;
"Odd words > 4:" print
words
[ length 8 > ] filter
[ odd wordset in? ] filter
[ dup odd "%-15s %s\n" printf ] each
- Output:
Odd words > 4: barbarian brain childbear cider corrigenda cried gargantuan grata headdress hades palladian plain propionate point salvation slain siltation slain slingshot sight statuette saute supersede spree supervene spree terminable trial
FreeBASIC
#define NULL 0
type node
word as string*32 'enough space to store any word in the dictionary
nxt as node ptr
end type
function addword( tail as node ptr, word as string ) as node ptr
'allocates memory for a new node, links the previous tail to it,
'and returns the address of the new node
dim as node ptr newnode = allocate(sizeof(node))
tail->nxt = newnode
newnode->nxt = NULL
newnode->word = word
return newnode
end function
function crunch( word as string ) as string
dim as string ret = ""
for i as uinteger = 1 to len(word) step 2
ret += mid(word,i,1)
next i
return ret
end function
function length( word as string ) as uinteger
'necessary replacement for the built-in len function, which in this
'case would always return 32
for i as uinteger = 1 to 32
if asc(mid(word,i,1)) = 0 then return i-1
next i
return 999
end function
dim as string word
dim as node ptr tail = allocate( sizeof(node) )
dim as node ptr head = tail, curr = head, currj
tail->nxt = NULL
tail->word = "XXXXHEADER"
open "unixdict.txt" for input as #1
while true
line input #1, word
if word = "" then exit while
tail = addword( tail, word )
wend
close #1
while curr->nxt <> NULL
if length(curr->word) > 8 then word = crunch( curr->word ) else goto nextword
currj = head
while currj->nxt <> NULL
if word = currj->word then print left(curr->word,length(curr->word));" ---> ";word
currj = currj->nxt
wend
nextword:
curr = curr->nxt
wend
- Output:
barbarian ---> brain childbear ---> cider corrigenda ---> cried gargantuan ---> grata headdress ---> hades palladian ---> plain propionate ---> point salvation ---> slain siltation ---> slain slingshot ---> sight statuette ---> saute supersede ---> spree supervene ---> spree terminable ---> trial
And to discourage the creation of a whole new task for the even words, here they are. It requires only changing a 1 to a 2 in line 20, and an 8 to a 9 in line 50.
cannonball ---> annal importation ---> motto psychopomp ---> scoop starvation ---> train upholstery ---> posey
FutureBasic
#plist NSAppTransportSecurity @{NSAllowsArbitraryLoads:YES}
include "NSLog.incl"
local fn WordsPassingTest( array as CFArrayRef, obj as CFTypeRef )
end fn = ( len(obj) > 4 )
local fn WordList as CFArrayRef
CFURLRef url = fn URLWithString( @"http://wiki.puzzlers.org/pub/wordlists/unixdict.txt" )
CFStringRef string = fn StringWithContentsOfURL( url, NSUTF8StringEncoding, NULL )
CFArrayRef wordList = fn StringComponentsSeparatedByCharactersInSet( string, fn CharacterSetNewlineSet )
IndexSetRef indexes = fn ArrayIndexesOfObjectsPassingTest( wordList, @fn WordsPassingTest, NULL )
wordList = fn ArrayObjectsAtIndexes( wordList, indexes )
end fn = wordList
void local fn OddWords
dispatchglobal
CFArrayRef wordList = fn WordList
CFStringRef string
long i
for string in wordList
CFMutableStringRef wd = fn MutableStringWithCapacity(0)
for i = 0 to len(string) step 2
MutableStringAppendString( wd, mid(string,i,1) )
next
if ( len(wd) > 4 )
if ( fn ArrayContainsObject( wordList, wd ) )
NSLog(@"%@",wd)
end if
end if
next
dispatchend
end fn
fn OddWords
HandleEvents
- Output:
brain cider cried grata hades plain point slain slain sight saute spree spree trial
Go
package main
import (
"bytes"
"fmt"
"io/ioutil"
"log"
"sort"
"strings"
)
func main() {
wordList := "unixdict.txt"
b, err := ioutil.ReadFile(wordList)
if err != nil {
log.Fatal("Error reading file")
}
bwords := bytes.Fields(b)
words := make([]string, len(bwords))
for i, bword := range bwords {
words[i] = string(bword)
}
count := 0
fmt.Println("The odd words with length > 4 in", wordList, "are:")
for _, word := range words {
rword := []rune(word) // in case any non-ASCII
if len(rword) > 8 {
var sb strings.Builder
for i := 0; i < len(rword); i += 2 {
sb.WriteRune(rword[i])
}
s := sb.String()
idx := sort.SearchStrings(words, s) // binary search
if idx < len(words) && words[idx] == s { // check not just an insertion point
count = count + 1
fmt.Printf("%2d: %-12s -> %s\n", count, word, s)
}
}
}
}
- Output:
The odd words with length > 4 in unixdict.txt are: 1: barbarian -> brain 2: childbear -> cider 3: corrigenda -> cried 4: gargantuan -> grata 5: headdress -> hades 6: palladian -> plain 7: propionate -> point 8: salvation -> slain 9: siltation -> slain 10: slingshot -> sight 11: statuette -> saute 12: supersede -> spree 13: supervene -> spree 14: terminable -> trial
J
In J, the index of the first character is 0, and the index of the second character is 1, thus:
>(([-.-.) (#~ $&0 1@#)&.>) (#~ 4<#@>)cutLF fread'unixdict.txt'
annal
motto
posey
scoop
train
However, some languages have 1 for the index of the first character, which would have given us:
>(([-.-.) (#~ $&1 0@#)&.>) (#~ 4<#@>)cutLF fread'unixdict.txt'
brain
cider
cried
grata
hades
plain
point
saute
sight
slain
spree
trial
Java
import java.io.*;
import java.util.*;
public class OddWords {
public static void main(String[] args) {
try {
Set<String> dictionary = new TreeSet<>();
final int minLength = 5;
String fileName = "unixdict.txt";
if (args.length != 0)
fileName = args[0];
try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
String line;
while ((line = reader.readLine()) != null) {
if (line.length() >= minLength)
dictionary.add(line);
}
}
StringBuilder word1 = new StringBuilder();
StringBuilder word2 = new StringBuilder();
List<StringPair> evenWords = new ArrayList<>();
List<StringPair> oddWords = new ArrayList<>();
for (String word : dictionary) {
int length = word.length();
if (length < minLength + 2 * (minLength/2))
continue;
word1.setLength(0);
word2.setLength(0);
for (int i = 0; i < length; ++i) {
if ((i & 1) == 0)
word1.append(word.charAt(i));
else
word2.append(word.charAt(i));
}
String oddWord = word1.toString();
String evenWord = word2.toString();
if (dictionary.contains(oddWord))
oddWords.add(new StringPair(word, oddWord));
if (dictionary.contains(evenWord))
evenWords.add(new StringPair(word, evenWord));
}
System.out.println("Odd words:");
printWords(oddWords);
System.out.println("\nEven words:");
printWords(evenWords);
} catch (Exception e) {
e.printStackTrace();
}
}
private static void printWords(List<StringPair> strings) {
int n = 1;
for (StringPair pair : strings) {
System.out.printf("%2d: %-14s%s\n", n++,
pair.string1, pair.string2);
}
}
private static class StringPair {
private String string1;
private String string2;
private StringPair(String s1, String s2) {
string1 = s1;
string2 = s2;
}
}
}
- Output:
Odd words: 1: barbarian brain 2: childbear cider 3: corrigenda cried 4: gargantuan grata 5: headdress hades 6: palladian plain 7: propionate point 8: salvation slain 9: siltation slain 10: slingshot sight 11: statuette saute 12: supersede spree 13: supervene spree 14: terminable trial Even words: 1: cannonball annal 2: importation motto 3: psychopomp scoop 4: starvation train 5: upholstery posey
jq
Works with gojq, the Go implementation of jq if `keys_unsorted` is replaced by `keys`
Counting the letters from 1...
def lpad($len): tostring | ($len - length) as $l | (" " * $l)[:$l] + .;
INDEX(inputs | select(length>4); .)
| . as $dict
| keys_unsorted[]
| select(length > 8)
| (explode | [.[range(0;length;2)]] | implode) as $odd
| select( ($odd|length > 4) and $dict[$odd])
| "\(lpad(10)) : \($odd)"
- Output:
Illustrative invocation: jq -nrR -f program.jq unixdict.txt
barbarian : brain childbear : cider corrigenda : cried gargantuan : grata headdress : hades palladian : plain propionate : point salvation : slain siltation : slain slingshot : sight statuette : saute supersede : spree supervene : spree terminable : trial
Julia
See Alternade_words#Julia for the foreachword function.
isoddword(w, d) = (o = mapreduce(i -> w[i], *, 1:2:length(w)); haskey(d, o) ? rpad(w, 16) * ": " * o : "")
foreachword("unixdict.txt", isoddword, minlen=9, numcols=1)
- Output:
Word source: unixdict.txt barbarian : brain childbear : cider corrigenda : cried gargantuan : grata headdress : hades palladian : plain propionate : point salvation : slain siltation : slain slingshot : sight statuette : saute supersede : spree supervene : spree terminable : trial
Lua
minOddWordLength = 5
minWordLength = minOddWordLength*2-1
dict = {}
for word in io.lines('unixdict.txt') do
local n = #word
if n >= minOddWordLength then -- skip words that are too short
dict[word] = n
end
end
for word, len in pairs(dict) do
if len >= minWordLength then
local odd = ""
for o, _ in word:gmatch("(.)(.?)") do
odd = odd .. o
end
if dict[odd] then
print(string.format("%10s → %s", word, odd))
end
end
end
- Output:
Note: Output will not be alphabetical.
barbarian → brain childbear → cider corrigenda → cried supervene → spree siltation → slain terminable → trial supersede → spree slingshot → sight propionate → point salvation → slain palladian → plain gargantuan → grata headdress → hades statuette → saute
M2000 Interpreter
module odd_words (f as integer, filename as string) {
document a$
words=list
res=list
load.doc a$, filename
m=Paragraph(a$, 0)
If Forward(a$,m) then
While m
b$=Paragraph$(a$,(m))
if len(b$)>4 then append words, b$
End While
End If
m=Paragraph(a$, 0)
If Forward(a$,m) then
While m
b$=Paragraph$(a$,(m))
if len(b$)>=9 then
c$=left$(b$,1)
for i=3 to len(b$) step 2
c$+=mid$(b$,i,1)
next
if exist(words, c$) then
append res, b$:=c$
End if
End if
End While
End if
k=each(res)
while k
b$=field$(eval$(k!), 12)+"==> "+eval$(k)
print #f, b$
print b$
end while
}
open "oddwords.txt" for output as #f
odd_words f, "unixdict.txt"
close #f
win "oddwords.txt"
- Output:
barbarian ==> brain childbear ==> cider corrigenda ==> cried gargantuan ==> grata headdress ==> hades palladian ==> plain propionate ==> point salvation ==> slain siltation ==> slain slingshot ==> sight statuette ==> saute supersede ==> spree supervene ==> spree terminable ==> trial
Mathematica /Wolfram Language
dict = Import["https://web.archive.org/web/20180611003215/http://www.puzzlers.org/pub/wordlists/unixdict.txt"];
dict //= StringSplit[#, "\n"] &;
ClearAll[OddLetters, OddWordQ]
OddLetters[s_String] := StringTake[s, {1, -1, 2}]
OddWordQ[s_String] := Module[{},
If[StringLength[s] >= 9,
MemberQ[dict, OddLetters[s]]
,
False
]
]
{#, OddLetters[#]} & /@ Select[dict, OddWordQ] // Grid
- Output:
barbarian brain childbear cider corrigenda cried gargantuan grata headdress hades palladian plain propionate point salvation slain siltation slain slingshot sight statuette saute supersede spree supervene spree terminable trial
Nim
import sets, strformat, sugar
const DictFile = "unixdict.txt"
let words = collect(initHashSet, for word in DictFile.lines: {word})
var count = 0
for word in DictFile.lines:
var oddWord: string
for i in countup(0, word.high, 2): oddWord.add word[i] # First odd char is at index 0.
if oddWord.len > 4 and oddWord in words:
inc count
echo &"{count:2}: {word:12} → {oddWord}"
- Output:
1: barbarian → brain 2: childbear → cider 3: corrigenda → cried 4: gargantuan → grata 5: headdress → hades 6: palladian → plain 7: propionate → point 8: salvation → slain 9: siltation → slain 10: slingshot → sight 11: statuette → saute 12: supersede → spree 13: supervene → spree 14: terminable → trial
Pascal
Free Pascal
Program OddWords;
Uses
Classes;
Const
F_NAME = 'unixdict.txt';
Var
WordList: TStringList;
Str, ShortStr: string;
I: LongInt;
Begin
WordList := TStringList.Create;
WordList.LoadFromFile(F_NAME);
WordList.Sorted := True;
For Str In WordList Do
If Length(Str) > 8 Then
Begin
ShortStr := '';
I := 1;
Repeat
ShortStr := ShortStr + Str[I];
Inc(I, 2);
Until I > Length(Str);
If WordList.IndexOf(ShortStr) > -1 Then
Writeln(Str:12, ShortStr:10);
End;
WordList.Free;
End.
- Output:
barbarian brain childbear cider corrigenda cried gargantuan grata headdress hades palladian plain propionate point salvation slain siltation slain slingshot sight statuette saute supersede spree supervene spree terminable trial
Perl
#!/usr/bin/perl
@ARGV = 'unixdict.txt';
chomp( my @words = <> );
my %dict;
@dict{ grep length > 4, @words} = ();
for ( @words )
{
my $oddword = s/(.).?/$1/gr;
exists $dict{$oddword} and print " $_ $oddword\n";
}
- Output:
barbarian brain childbear cider corrigenda cried gargantuan grata headdress hades palladian plain propionate point salvation slain siltation slain slingshot sight statuette saute supersede spree supervene spree terminable trial
Phix
with javascript_semantics sequence words = unix_dict() function oddc(integer /*ch*/, idx) return remainder(idx,2)=1 end function function oddch(string word) return filter(word,oddc) end function function over4(string word) return length(word)>4 end function words = filter(filter(apply(words,oddch),over4),"in",words) printf(1,"%d odd words found: %s\n",{length(words),join(shorten(words,"",3),", ")})
- Output:
14 odd words found: brain, cider, cried, ..., spree, spree, trial
Alternative
Slightly more traditional, same output.
with javascript_semantics sequence words = unix_dict(), res = {} for i=1 to length(words) do string word = words[i], wodd = "" for oddchar=1 to length(word) by 2 do wodd &= word[oddchar] end for if length(wodd)>4 and find(wodd,words) then res = append(res,wodd) end if end for printf(1,"%d odd words found: %s\n",{length(res),join(shorten(res,"",3),", ")})
Python
Procedural
This implementation prints only the unique odd words which appear in unixdict.txt unlike other implementations on this page which print some words twice. The minimum base word length has to be 9 since the problem statement says that odd word lengths must be greater than 4.
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, 4th October 2021
import urllib.request
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()
oddWordSet = set({})
for word in wordList:
if len(word)>=9 and word[::2] in wordList:
oddWordSet.add(word[::2])
[print(i) for i in sorted(oddWordSet)]
- Output:
brain cider cried grata hades plain point saute sight slain spree trial
Functional
Defining a dictionary of oddWords, keyed by their sources:
'''Odd words'''
from os.path import expanduser
from json import dumps
# oddPairs :: Int -> [String] -> Dict
def oddPairs(minLength):
'''A dictionary of (word::oddWord) pairs
in which the words are drawn from a given wordList,
and the oddWords have at least a minimum length.
'''
def go(wordList):
lexicon = set(wordList)
return {
k: v for k, v in ((w, w[::2]) for w in wordList)
if minLength <= len(v) and v in lexicon
}
return go
# ------------------------- TEST -------------------------
# main :: IO ()
def main():
'''Odd words of 5 or more characters, paired with their
sources, which are drawn from a local unixdict.txt
'''
print(dumps(
oddPairs(5)(
readFile('~/unixdict.txt').split('\n')
),
indent=4
))
# ----------------------- GENERIC ------------------------
# readFile :: FilePath -> IO String
def readFile(fp):
'''The contents of any file at the path
derived by expanding any ~ in fp.
'''
with open(expanduser(fp), 'r', encoding='utf-8') as f:
return f.read()
# MAIN ---
if __name__ == '__main__':
main()
- Output:
{ "barbarian": "brain", "childbear": "cider", "corrigenda": "cried", "gargantuan": "grata", "headdress": "hades", "palladian": "plain", "propionate": "point", "salvation": "slain", "siltation": "slain", "slingshot": "sight", "statuette": "saute", "supersede": "spree", "supervene": "spree", "terminable": "trial" }
Quackery
[ stack ] is sift.test ( --> s )
protect sift.test
[ ]'[ sift.test put
[] [] rot
witheach
[ sift.test share do iff
[ nested join ]
else
[ swap dip
[ nested join ] ] ]
sift.test release ] is siftwith ( [ --> [ [ )
[ 1 & ] is odd ( n --> b )
[ stack ] is dict ( --> s )
[ dict share
dup dip find found ] is indict ( $ --> b )
$ "unixdict.txt" sharefile drop
nest$ siftwith [ dup size 4 > ]
nip dict put
dict share
siftwith [ dup size 8 > ]
nip
witheach
[ siftwith [ i^ odd ]
drop
dup indict iff
[ echo$ cr ]
else drop ]
dict release
- Output:
brain cider cried grata hades plain point slain slain sight saute spree spree trial
Raku
my %words = 'unixdict.txt'.IO.slurp.words.map: * => 1;
my (@odds, @evens);
for %words {
next if .key.chars < 9;
my $odd = .key.comb[0,2 … *].join;
@odds.push(.key => $odd) if %words{$odd} and $odd.chars > 4;
my $even = .key.comb[1,3 … *].join;
@evens.push(.key => $even) if %words{$even} and $even.chars > 4;
}
.put for flat 'Odd words > 4:', @odds.sort;
.put for flat "\nEven words > 4:", @evens.sort;
- Output:
Odd words > 4: barbarian brain childbear cider corrigenda cried gargantuan grata headdress hades palladian plain propionate point salvation slain siltation slain slingshot sight statuette saute supersede spree supervene spree terminable trial Even words > 4: cannonball annal importation motto psychopomp scoop starvation train upholstery posey
REXX
Any words longer than ten characters are truncated in the output.
version 1
/* REXX */
fid='d:\unix.txt'
ww.=0 /* ww.* the words to be analyzed */
w.=0 /* w.word = 1 if word is in unix.txt */
Do While lines(fid)>0
l=linein(fid) /* a word */
ll=length(l)
w.l=1 /* word is in unix.txt */
If ll>=9 Then Do /* worth to be analyzed */
z=ww.0+1 /* add it to the list */
ww.z=l
ww.0=z
End
End
n=0
Do i=1 To ww.0
wodd=wodd(ww.i)
If w.wodd Then Do
n=n+1
Say format(n,3) left(ww.i,10) wodd
End
End
Exit
wodd: Procedure
/* use odd indexed letters */
Parse Arg w
wo=''
Do i=1 To length(w)
If i//2=1 Then
wo=wo||substr(w,i,1)
End
Return wo
- Output:
1 barbarian brain 2 childbear cider 3 corrigenda cried 4 gargantuan grata 5 headdress hades 6 palladian plain 7 propionate point 8 salvation slain 9 siltation slain 10 slingshot sight 11 statuette saute 12 supersede spree 13 supervene spree 14 terminable trial
version 2, caseless
This REXX version doesn't care what order the words in the dictionary are in, nor does it care what
case (lower/upper/mixed) the words are in, the search for alternates is caseless.
It also allows the minimum length to be specified on the command line (CL) as well as the dictionary file identifier.
/*REXX program finds all the caseless "odd words" (within an identified dictionary). */
parse arg minL iFID . /*obtain optional arguments from the CL*/
if minL=='' | minL=="," then minL= 5 /*Not specified? Then use the default.*/
if iFID=='' | iFID=="," then iFID='unixdict.txt' /* " " " " " " */
@.= /*default value of any dictionary word.*/
do #=1 while lines(iFID)\==0 /*read each word in the file (word=X).*/
x= strip( linein( iFID) ) /*pick off a word from the input line. */
$.#= x; upper x; @.x= . /*save: original case and the semaphore*/
end /*#*/ /* [↑] semaphore name is uppercased. */
#= # - 1 /*adjust word count because of DO loop.*/
minW= minL * 2 - 1 /*minimum width of a word to be usable.*/
say copies('─', 30) # "words in the dictionary file: " iFID
say
finds= 0 /*count of the "odd words" found. */
do j=1 for #; L= length($.j) /*process all the words that were found*/
if L<minW then iterate /*Is word too short? Then ignore it. */
ow= /*initialize the "odd word". */
do k=1 by 2 to L /*only use odd indexed letters in word.*/
ow= ow || substr($.j, k, 1) /*construct the "odd word". */
end /*k*/
owU= ow; upper owU /*uppercase the odd word to be caseless*/
if @.owU=='' then iterate /*if not extant, then skip this word. */
finds= finds + 1 /*bump the count of "odd words" found. */
say right(left($.j, 20), 24) left(ow, 9) /*indent original word for readability.*/
end /*j*/
/*stick a fork in it, we're all done. */
say copies('─', 30) finds ' "odd words" found with a minimum length of ' minL
- output when using the default input:
────────────────────────────── 25104 words in the dictionary file: unixdict.txt barbarian brain childbear cider corrigenda cried gargantuan grata headdress hades palladian plain propionate point salvation slain siltation slain slingshot sight statuette saute supersede spree supervene spree terminable trial ────────────────────────────── 14 "odd words" found with a minimum length of 5
Ring
cStr = read("unixdict.txt")
wordList = str2list(cStr)
num = 0
see "Odd words are:" + nl
for n = 1 to len(wordList)
strWord = ""
len = len(wordList[n])
for m = 1 to len step 2
strWord = strWord + wordList[n][m]
next
ind = find(wordList,strWord)
if ind > 0 and len(strWord) > 4
num = num + 1
see "" + num + ". " + wordList[n] + " >> " + strWord + nl
ok
next
Output:
Odd words are: 1. barbarian >> brain 2. childbear >> cider 3. corrigenda >> cried 4. gargantuan >> grata 5. headdress >> hades 6. palladian >> plain 7. propionate >> point 8. salvation >> slain 9. siltation >> slain 10. slingshot >> sight 11. statuette >> saute 12. supersede >> spree 13. supervene >> spree 14. terminable >> trial
RPL
≪ { }
1 UnixDict SIZE FOR w
‘UnixDict’ w GET
IF DUP SIZE 9 ≥ THEN
""
1 OVER SIZE FOR k
OVER k DUP SUB +
2 STEP
SWAP DROP
IF UnixDict OVER POS THEN
IF DUP2 POS NOT THEN + ELSE DROP END
ELSE DROP END
ELSE DROP END
NEXT
≫ ‘ODDW’ STO
- Output:
1: { "brain" "cider" "cried" "grata" "hades" "plain" "point" "slain" "slain" "sight" "saute" "spree" "trial" }
Ruby
Binary search (bsearch) speeds things up.
dict = File.readlines("unixdict.txt", chomp: true).reject{|w| w.size < 5}
dict.each do |w|
next if w.size < 9
odd = w.chars.each_slice(2).map(&:first).join
puts w.ljust(14) + odd if dict.bsearch{|w| odd <=> w}
end
- Output:
barbarian brain childbear cider corrigenda cried gargantuan grata headdress hades palladian plain propionate point salvation slain siltation slain slingshot sight statuette saute supersede spree supervene spree terminable trial
Rust
use std::collections::BTreeSet;
use std::fs::File;
use std::io::{self, BufRead};
fn load_dictionary(filename: &str, min_length: usize) -> std::io::Result<BTreeSet<String>> {
let file = File::open(filename)?;
let mut dict = BTreeSet::new();
for line in io::BufReader::new(file).lines() {
let word = line?;
if word.len() >= min_length {
dict.insert(word);
}
}
Ok(dict)
}
fn print_words(words: &[(&String, String)]) {
for (i, (a, b)) in words.iter().enumerate() {
println!("{:2}: {:<14}{}", i + 1, a, b);
}
}
fn main() {
let min_length = 5;
match load_dictionary("unixdict.txt", min_length) {
Ok(dictionary) => {
let mut odd_words = Vec::new();
let mut even_words = Vec::new();
for word in &dictionary {
if word.len() < min_length + 2 * (min_length / 2) {
continue;
}
let mut odd_word = String::new();
let mut even_word = String::new();
for (i, c) in word.chars().enumerate() {
if (i & 1) == 0 {
odd_word.push(c);
} else {
even_word.push(c);
}
}
if dictionary.contains(&odd_word) {
odd_words.push((word, odd_word));
}
if dictionary.contains(&even_word) {
even_words.push((word, even_word));
}
}
println!("Odd words:");
print_words(&odd_words);
println!("\nEven words:");
print_words(&even_words);
}
Err(error) => eprintln!("{}", error),
}
}
- Output:
Odd words: 1: barbarian brain 2: childbear cider 3: corrigenda cried 4: gargantuan grata 5: headdress hades 6: palladian plain 7: propionate point 8: salvation slain 9: siltation slain 10: slingshot sight 11: statuette saute 12: supersede spree 13: supervene spree 14: terminable trial Even words: 1: cannonball annal 2: importation motto 3: psychopomp scoop 4: starvation train 5: upholstery posey
Swift
import Foundation
let minLength = 5
func loadDictionary(_ path: String) throws -> Set<String> {
let contents = try String(contentsOfFile: path, encoding: String.Encoding.ascii)
return Set<String>(contents.components(separatedBy: "\n").filter{$0.count >= minLength})
}
func pad(string: String, width: Int) -> String {
return string.count >= width ? string
: string + String(repeating: " ", count: width - string.count)
}
func printWords(words: [(String,String)]) {
for (n, (word1, word2)) in words.enumerated() {
print("\(String(format: "%2d", n + 1)): \(pad(string: word1, width: 14))\(word2)")
}
}
do {
let dictionary = try loadDictionary("unixdict.txt")
var oddWords: [(String, String)] = []
var evenWords: [(String, String)] = []
for word in dictionary {
if word.count < minLength + 2*(minLength/2) {
continue
}
var oddWord = ""
var evenWord = ""
for (i, c) in word.enumerated() {
if (i & 1) == 0 {
oddWord.append(c)
} else {
evenWord.append(c)
}
}
if dictionary.contains(oddWord) {
oddWords.append((word, oddWord))
}
if dictionary.contains(evenWord) {
evenWords.append((word, evenWord))
}
}
oddWords.sort(by: {$0.0 < $1.0})
evenWords.sort(by: {$0.0 < $1.0})
print("Odd words:")
printWords(words: oddWords)
print("\nEven words:")
printWords(words: evenWords)
} catch {
print(error.localizedDescription)
}
- Output:
Odd words: 1: barbarian brain 2: childbear cider 3: corrigenda cried 4: gargantuan grata 5: headdress hades 6: palladian plain 7: propionate point 8: salvation slain 9: siltation slain 10: slingshot sight 11: statuette saute 12: supersede spree 13: supervene spree 14: terminable trial Even words: 1: cannonball annal 2: importation motto 3: psychopomp scoop 4: starvation train 5: upholstery posey
TAV
main (parms):+
mw =: new map \ map for input words
?# wrd =: file '../unixdict.txt' give lines
mw{wrd} =: wrd.Count
mw.max =: maximum of mw.max, wrd.Count
debug print mw.Count, "words, max len:", mw.max
mow =: new map \ map for odd words
?# wrd =: map mw give keys
? wrd.Count < 9 \ no chance for ow.Count > 4
?^
\ compose odd word
ow =: ''
?# i =: from 1 upto mw.max step 2
ow =_ wrd[i]
\ look up in word map and set odd word map
? mw{ow} ~= ()
mow{ow} =: wrd
\ print the result
?# k =: map mow give keys ascending
print (pad left k to 6), mow{k}
- Output:
brain barbarian cider childbear cried corrigenda grata gargantuan hades headdress plain palladian point propionate saute statuette sight slingshot slain salvation spree supersede trial terminable
V (Vlang)
import os
fn main() {
mut num := 0
mut word_arr := []u8{}
mut odd_list :=""
word_list := os.read_file("./unixdict.txt") or {println(err) exit(-1)}.split_into_lines()
for word in word_list {
if word.len > 8 {
for idx, chars in word {if idx % 2 == 0 {word_arr << chars}}
if word_list.contains(word_arr.bytestr()) && !odd_list.contains(word) && word_arr.len > 4 {
num++
odd_list += "${num}. ${word} >> ${word_arr.bytestr()} \n"
}
}
word_arr.clear()
}
println(odd_list)
}
- Output:
1. barbarian >> brain 2. childbear >> cider 3. corrigenda >> cried 4. gargantuan >> grata 5. headdress >> hades 6. palladian >> plain 7. propionate >> point 8. salvation >> slain 9. siltation >> slain 10. slingshot >> sight 11. statuette >> saute 12. supersede >> spree 13. supervene >> spree 14. terminable >> trial
Wren
import "io" for File
import "./fmt" for Fmt
import "./sort" for Find
import "./iterate" for Stepped
var wordList = "unixdict.txt" // local copy
var words = File.read(wordList).trimEnd().split("\n")
var count = 0
System.print("The odd words with length > 4 in %(wordList) are:")
for (word in words) {
if (word.count > 8) {
var s = ""
var chars = word.toList // in case any non-ASCII
for (i in Stepped.new(0...chars.count, 2)) s = s + chars[i]
if (Find.first(words, s) >= 0) { // binary search
count = count + 1
Fmt.print("$2d: $-12s -> $s", count, word, s)
}
}
}
- Output:
The odd words with length > 4 in unixdict.txt are: 1: barbarian -> brain 2: childbear -> cider 3: corrigenda -> cried 4: gargantuan -> grata 5: headdress -> hades 6: palladian -> plain 7: propionate -> point 8: salvation -> slain 9: siltation -> slain 10: slingshot -> sight 11: statuette -> saute 12: supersede -> spree 13: supervene -> spree 14: terminable -> trial
XPL0
string 0; \use zero-terminated strings
int Dict(26000); \pointers to words (enough for unixdict.txt)
int DictSize; \actual number of pointers in Dict
func StrCmp(A, B); \Compare string A to B
char A, B; \Returns: >0 if A>B, =0 if A=B, and <0 if A<B
int I;
[for I:= 0 to -1>>1 do
[if A(I) # B(I) then return A(I) - B(I);
if A(I) = 0 then return 0;
];
]; \StrCmp
func LookUp(Word); \Return 'true' if Word is in Dict
char Word;
int Lo, Hi, I, Cmp;
[Lo:= 0; Hi:= DictSize-1;
loop [I:= (Lo+Hi) / 2; \binary search
Cmp:= StrCmp(Word, Dict(I));
if Cmp < 0 then Hi:= I-1 else Lo:= I+1;
if Cmp = 0 then return true;
if Lo > Hi then return false;
];
]; \LookUp
int I, I0, DI, Ch, Count;
char Word, Alt0(25);
def Tab=$09, LF=$0A, CR=$0D, EOF=$1A;
[FSet(FOpen("unixdict.txt", 0), ^I); \load dictionary
OpenI(3); \assume alphabetical order and all lowercase
DI:= 0; \ignore non-alpha characters: 0..9, ' and &
repeat Dict(DI):= Reserve(0); \get pointer to memory used to store Word
Word:= Dict(DI);
I:= 0;
loop [repeat Ch:= ChIn(3) until Ch # CR; \remove possible CR
if Ch=LF or Ch=EOF then quit;
Word(I):= Ch;
I:= I+1;
];
Word(I):= 0; \terminate Word string
I:= Reserve(I+1); \reserve memory used for Word
DI:= DI+1; \next dictionary entry
until Ch = EOF;
DictSize:= DI;
DI:= 0; Count:= 0;
repeat Word:= Dict(DI); \print out all odd words
I:= 0; I0:= 0;
loop [Ch:= Word(I);
if Ch = 0 then quit;
if (I&1) = 0 then [Alt0(I0):= Ch; I0:= I0+1];
I:= I+1;
];
if I >= 9 then \Word must have at least 9 chars
[Alt0(I0):= 0;
if LookUp(Alt0) then
[Count:= Count+1;
IntOut(0, Count); ChOut(0, Tab);
Text(0, Word); ChOut(0, Tab);
Text(0, Alt0); ChOut(0, Tab);
CrLf(0);
];
];
DI:= DI+1;
until DI >= DictSize;
]
- Output:
1 barbarian brain 2 childbear cider 3 corrigenda cried 4 gargantuan grata 5 headdress hades 6 palladian plain 7 propionate point 8 salvation slain 9 siltation slain 10 slingshot sight 11 statuette saute 12 supersede spree 13 supervene spree 14 terminable trial
- Draft Programming Tasks
- 11l
- AArch64 Assembly
- Ada
- ALGOL 68
- ALGOL 68-files
- ALGOL 68-sort
- ARM Assembly
- Arturo
- AWK
- BQN
- C++
- Delphi
- SysUtils,StdCtrls
- DuckDB
- EasyLang
- F Sharp
- Factor
- FreeBASIC
- FutureBasic
- Go
- J
- Java
- Jq
- Julia
- Lua
- M2000 Interpreter
- Mathematica
- Wolfram Language
- Nim
- Pascal
- Free Pascal
- Perl
- Phix
- Python
- Quackery
- Raku
- REXX
- Ring
- RPL
- Ruby
- Rust
- Swift
- TAV
- V (Vlang)
- Wren
- Wren-fmt
- Wren-sort
- Wren-iterate
- XPL0