RabbitFarm
2026-07-25
The Weekly Challenge 383 (Prolog Solutions)
The examples used here are from the weekly challenge problem statement and demonstrate the working solution.
Part 1: Similar List
You are given three list of strings. Write a script to find out if the first two list are similar with the help the third list. The third list contains the similar words map.
Our solution is short and will be contained in a single file that has the following structure.
First we’ll define a couple of helper predicates for constructing pairs from the given input lists. These pairs will be used as a data structure for the given mappings.
-
make_kv(K, V, K-V).
make_kv(L, KV):-
L = [H|T],
maplist(make_kv(H), T, KV1),
reverse(L, LR),
LR = [HR|TR],
maplist(make_kv(HR), TR, KVR),
append(KV1, KVR, KV).
make_kvs([], []).
make_kvs([H|T], [KV|KVs]):-
make_kvs(T, KVs),
make_kv(H, KV).
◇
-
Fragment referenced in 1.
Now we’ll compare the lists. First is just a small predicate for calling the DCG using phrase/2.
-
similar(L1, L2, M):-
make_kvs(M, KV1),
flatten(KV1, KVs),
phrase(similar(KVs, L1), L2).
◇
-
Fragment referenced in 1.
This makes use of the following DCG definition.
-
similar(_, []) --> [].
similar(_, []) --> [_], {!, fail}.
similar(KVs, L) --> [W], {L = [H|T], (H == W; member(H-W, KVs);
member(W-H, KVs))}, similar(KVs, T).
◇
-
Fragment referenced in 1.
Sample Run
% gprolog --consult-file prolog/ch-1.p | ?- similar([great, acting], [fine, drama], [[great, fine], [acting, drama]]). true ? yes | ?- similar([apple, pie], [banana, pie], [[apple, peach], [peach, banana]]). no | ?- similar([perl4, python], [raku, python], [[perl4, perl5, raku]]). true ? yes | ?- similar([enjoy, challenge], [love, weekly, challenge], [[enjoy, love]]). no | ?- similar([fast, car], [quick, vehicle], [[quick, fast], [vehicle, car]]). true ? yes | ?-
Part 2: Nearest RGB
You are given a 6-digit hex color. Write a script to round the RGB channels to the nearest web-safe value and return the nearest RGB color.
This will proceed in a way very similar to Part 1, but this is a short enough problem so we won’t bother writing DCG rules.
We’ll define a few helper predicates first.
-
leading_octothorpe(Hex, Hex1):-
nth(1, Hex, 35),
Hex = [_|Hex1].
◇
-
Fragment referenced in 10.
-
codes_nearest_hex(Codes, Hex):-
atom_codes(A, Codes),
atom_concat(’0x’, A, A1),
number_atom(Decimal, A1),
N is truncate((Decimal + 25.5) / 51) * 51,
Offset is N + 256,
format_to_atom(Temp, ’~16R’, [Offset]),
sub_atom(Temp, 1, 2, _, Hex).
◇
-
Fragment referenced in 10.
-
rgb(Hex, R, G, B):-
length(R, 2),
length(G, 2),
length(B, 2),
append(R, GB, Hex),
append(G, B, GB).
◇
-
Fragment referenced in 10.
-
nearest_rgb(R, G, B, Nearest):-
maplist(codes_nearest_hex, [R, G, B], [R1, G1, B1]),
atom_concat(’#’, R1, H1),
atom_concat(H1, G1, H2),
atom_concat(H2, B1, Nearest).
◇
-
Fragment referenced in 10.
Finally we’ll have a small predicate for tying everything together.
-
nearest_rgb(Hex, Nearest):-
leading_octothorpe(Hex, Hex1),
rgb(Hex1, R, G, B),
nearest_rgb(R, G, B, Nearest).
◇
-
Fragment referenced in 5.
Sample Run
% gprolog --consult-file prolog/ch-2.p | ?- nearest_rgb("#F4B2D1", Nearest). Nearest = ’#FF99CC’ yes | ?- nearest_rgb("#15E6E5", Nearest). Nearest = ’#00FFCC’ yes | ?- nearest_rgb("#191A65", Nearest). Nearest = ’#003366’ yes | ?- nearest_rgb("#2D5A1B", Nearest). Nearest = ’#336633’ yes | ?- nearest_rgb("#00FF66", Nearest). Nearest = ’#00FF66’ yes | ?-
References
posted at: 23:22 by: Adam Russell | path: /prolog | permanent link to this entry