RabbitFarm

2023-10-23

The Weekly Challenge 239 (Prolog Solutions)

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

Part 1

You are given two arrays of strings. Write a script to find out if the word created by concatenating the array elements is the same.

Solution


concatenate_all([], '').
concatenate_all([H|T], Concatenated):-
    concatenate_all(T, C),
    atom_concat(H, C, Concatenated).

same_string(L0, L1):-
    concatenate_all(L0, C0),
    concatenate_all(L1, C1),
    C0 == C1. 

Sample Run


% gprolog --consult-file prolog/ch-1.p
| ?- same_string([ab, c], [a, bc]).

yes
| ?- same_string([ab, c], [ac, b]). 

no
| ?- same_string([ab, cd, e], [abcde]).

yes
| ?- 

Notes

The problem is given as strings, which I interpret here as meaning atoms, in which case we need to concatenate all the atoms together and then check to see if they are equal.

If, instead, I had strictly used strings (arrays of character codes) then there would be no need to actually concatenate anything. In that case we could just flatten the lists and then check to see if the lists were the same.

Part 2

You are given an array of strings and allowed string having distinct characters. A string is consistent if all characters in the string appear in the string allowed. Write a script to return the number of consistent strings in the given array.

Solution


consistent(Allowed, String, Consistent):-
    subtract(String, Allowed, Subtracted),
    length(Subtracted, SubtractedLength),
    ((SubtractedLength == 0, Consistent = 1);
     (SubtractedLength == 1, Consistent = 0)).

consistent_strings(Strings, Allowed, ConsistentStringsCount):-
    maplist(consistent(Allowed), Strings, ConsistentStrings),
    sum_list(ConsistentStrings, ConsistentStringsCount).

Sample Run


% gprolog --consult-file prolog/ch-2.p 
| ?- consistent_strings(["ad", "bd", "aaab", "baa", "badab"], "ab", ConsistentStrings).

ConsistentStrings = 2 ? 

(1 ms) yes
| ?- consistent_strings(["a", "b", "c", "ab", "ac", "bc", "abc"], "abc", ConsistentStrings).

ConsistentStrings = 7 ? 

yes
| ?- consistent_strings(["cc", "acd", "b", "ba", "bac", "bad", "ac", "d"], "cad", ConsistentStrings).

ConsistentStrings = 4 ? 

yes
| ?- 

Notes

Here I count up all the consistent strings by using a maplist/3 to create a list of 0s and 1s. 0 if the string is not consistent, 1 if it is consistent. The check for if a string is consistent is done in a helper predicate which works by removing all the allowed characters and then checking if all characters have been removed, which satisfies the criteria.

References

Challenge 239

posted at: 00:37 by: Adam Russell | path: /prolog | permanent link to this entry