RabbitFarm

2025-05-11

The Weekly Challenge 320 (Prolog Solutions)

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

Part 1: Maximum Count

You are given an array of integers. Write a script to return the maximum between the number of positive and negative integers. Zero is neither positive nor negative.

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

"ch-1.p" 1


identify negatives 2
identify positives 3
count negatives 4
count positives 5
maximum count 6

We’ll define two predicates for counting the number of negative and positive numbers. These will use small helper predicates to be called via maplist.

identify negatives 2 ⟩≡


identify_negatives(Number, 1):-
Number < 0.
identify_negatives(_, 0).

Fragment referenced in 1.

identify positives 3 ⟩≡


identify_positives(Number, 1):-
Number > 0.
identify_positives(_, 0).

Fragment referenced in 1.

count negatives 4 ⟩≡


count_negatives(Numbers, Count):-
maplist(identify_negatives, Numbers, Negatives),
sum_list(Negatives, Count).

Fragment referenced in 1.

count positives 5 ⟩≡


count_positives(Numbers, Count):-
maplist(identify_positives, Numbers, Positives),
sum_list(Positives, Count).

Fragment referenced in 1.

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

maximum count 6 ⟩≡


maximum_count(Numbers, MaximumCount):-
count_negatives(Numbers, NegativesCount),
count_positives(Numbers, PositivesCount),
max_list([NegativesCount, PositivesCount], MaximumCount).

Fragment referenced in 1.

Sample Run
$ gprolog --consult-file prolog/ch-1.p 
| ?- maximum_count([-3, -2, -1, 1, 2, 3], MaximumCount). 
 
MaximumCount = 3 ? 
 
yes 
| ?- maximum_count([-2, -1, 0, 0, 1], MaximumCount). 
 
MaximumCount = 2 ? 
 
yes 
| ?- maximum_count([1, 2, 3, 4], MaximumCount). 
 
MaximumCount = 4 ? 
 
yes 
| ?-
    

Part 2: Sum Differences

You are given an array of positive integers. Write a script to return the absolute difference between digit sum and element sum of the given array.

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

"ch-2.p" 7


char_number 10
element sum 8
digit sum 9
sum differences 11

The element sum is a straightforward application of the builtin predicate sum_list/2.

element sum 8 ⟩≡


element_sum(Numbers, ElementSum):-
sum_list(Numbers, ElementSum).

Fragment referenced in 7.

To compute the digit sum we’ll first convert them to characters, via maplist, flatten the list, convert them back to numbers, and take the sum_list.

digit sum 9 ⟩≡


digit_sum(Numbers, DigitSum):-
maplist(number_chars, Numbers, Characters),
flatten(Characters, CharactersFlattened),
maplist(char_number, CharactersFlattened, Digits),
sum_list(Digits, DigitSum).

Fragment referenced in 7.

The above predicate, for convenience of the maplist, requires a small helper predicate to reverse the arguments of numbers_chars.

char_number 10 ⟩≡


char_number(C, N):-
number_chars(N, [C]).

Fragment referenced in 7.

sum_difference/2 is the main predicate, which calls the others we’ve defined so far.

sum differences 11 ⟩≡


sum_differences(Numbers, Differences):-
element_sum(Numbers, ElementSum),
digit_sum(Numbers, DigitSum),
Differences is abs(DigitSum - ElementSum).

Fragment referenced in 7.

Sample Run
$ gprolog --consult-file prolog/ch-2.p 
| ?- sum_differences([1, 23, 4, 5], SumDifferences). 
 
SumDifferences = 18 
 
yes 
| ?- sum_differences([1, 2, 3, 4, 5], SumDifferences). 
 
SumDifferences = 0 
 
yes 
| ?- sum_differences([1, 2, 34], SumDifferences). 
 
SumDifferences = 27 
 
yes 
| ?-
    

References

The Weekly Challenge 320
Generated Code

posted at: 13:04 by: Adam Russell | path: /prolog | permanent link to this entry