RabbitFarm

2025-05-04

The Weekly Challenge 319 (Prolog Solutions)

The examples used here are from the weekly challenge problem statement and demonstrate the working solution.

Part 1: Word Count

You are given a list of words containing alphabetic characters only. Write a script to return the count of words either starting with a vowel or ending with a vowel.

Our solution will be pretty short, contained in just a single file that has the following structure.

"ch-1.p" 1


vowels 2
start_end_vowel 3
word count 4

We’re going to be using character codes for this. For convenience let’s declare are vowels this way.

vowels 2 ⟩≡


vowel(97). % a
vowel(101). % e
vowel(105). % i
vowel(111). % o
vowel(117). % u

Fragment referenced in 1.

We’ll use a small predicate, later to be called from maplist, to check if a word starts or ends with a vowel.

start_end_vowel 3 ⟩≡


start_end_vowel(Word, StartsEnds):-
((nth(1, Word, FirstLetter),
vowel(FirstLetter));
(last(Word, LastLetter),
vowel(LastLetter))),
StartsEnds = true.
start_end_vowel(_, -1).

Fragment referenced in 1.

We’ll need a predicate to tie everything together, that’s what this next one does.

word count 4 ⟩≡


word_count(Words, Count):-
maplist(start_end_vowel, Words, StartsEndsAll),
delete(StartsEndsAll, -1, StartsEnds),
length(StartsEnds, Count).

Fragment referenced in 1.

Sample Run
$ gprolog --consult-file prolog/ch-1.p 
| ?- word_count(["unicode", "xml", "raku", "perl"], Count). 
 
Count = 2 ? 
 
yes 
| ?- word_count(["the", "weekly", "challenge"], Count). 
 
Count = 2 ? 
 
yes 
| ?- word_count(["perl", "python", "postgres"], Count). 
 
Count = 0 
 
yes 
| ?-
    

Part 2: Minimum Common

You are given two arrays of integers. Write a script to return the minimum integer common to both arrays. If none found return -1.

As in the first part, our solution will be pretty short, contained in just a single file.

"ch-2.p" 5


minimum common 7

To check for common elements is easy in Prolog. First we subtract/3 all elements of one list from the other. That will give us the unique elements. Then we’ll delete the unique elements from one of the original lists to get all common elements. After that min_list/2 determines the result.

subtract lists to determine common elemets 6 ⟩≡


subtract(List1, List2, Difference1),
subtract(List2, List1, Difference2),
append(Difference1, Difference2, Differences),
subtract(List1, Differences, Common),

Fragment referenced in 7.

Defines: Common 7.

minimum_common/3 is the main (and only) predicate we define

minimum common 7 ⟩≡


minimum_common(List1, List2, MinimumCommon):-
subtract lists to determine common elemets 6
length(Common, L),
L >= 1,
min_list(Common, MinimumCommon).
minimum_common(_, _, -1).

Fragment referenced in 5.

Uses: Common 6.

Sample Run
$ gprolog --consult-file prolog/ch-2.p 
| ?- minimum_common([1, 2, 3, 4], [3, 4, 5, 6], MinimumCommon). 
 
MinimumCommon = 3 ? 
 
yes 
| ?- minimum_common([1, 2, 3], [2, 4], MinimumCommon). 
 
MinimumCommon = 2 ? 
 
yes 
| ?- minimum_common([1, 2, 3, 4], [5, 6, 7, 8], MinimumCommon). 
 
MinimumCommon = -1 
 
yes 
| ?-
    

References

The Weekly Challenge 319
Generated Code

posted at: 14:47 by: Adam Russell | path: /prolog | permanent link to this entry