% % A program to solve the logic puzzle from % https://www.ahapuzzles.com/logic/logic-puzzles/street-mayhem % (Aha!Puzzles by james@ahapuzzles.com) % % Author: Joachim Schimpf, 2024 % Creative Commons Attribution 4.0 International License. % % ?- go. % project(may, rembrandt, henry, 25k) % project(jun, windy, derick, 50k) % project(jul, young, cat, 30k) % project(aug, fuller, irving, 38k) % project(sep, george, frank, 40k) % Yes (0.00s cpu, solution 1, maybe more) % No (0.00s cpu) % :- lib(ic_symbolic). :- lib(ic). :- import alldifferent/1, element/3, indomain/1 from ic_symbolic. :- local domain(budget('25k','30k','38k','40k','50k')), domain(manager(cat,derick,frank,henry,irving)), domain(months(may,jun,jul,aug,sep)), domain(street(fuller,george,rembrandt,windy,young)). go :- N = 5, length(Budget, N), Budget &:: budget, alldifferent(Budget), length(Mgr, N), Mgr &:: manager, alldifferent(Mgr), length(Month, N), Month &:: months, alldifferent(Month), length(Street, N), Street &:: street, alldifferent(Street), % Avoid symmetric solutions by ordering some property, e.g. months ordered(<, Month), % 1. The Fuller Ave project won't be managed by Frank Shooty. element(FullerProject, Street, fuller), element(FullerProject, Mgr, FullerMgr), FullerMgr &\= frank, % 2. The job starting in July will have a budget of $30,000. element(JulyProject, Month, jul), element(JulyProject, Budget, '30k'), % 3. The Young Drive project doesn't start in June. element(YoungProject, Street, young), element(YoungProject, Month, YoungMonth), YoungMonth &\= jun, % 4. The Rembrandt Way project begins 2 months before Cat % Banks' project. element(RemProject, Street, rembrandt), element(RemProject, Month, RemMonth), element(CatProject, Mgr, cat), element(CatProject, Month, CatMonth), shift(RemMonth, 2, CatMonth), % 5. Of the $40,000 project and the job starting in May, one will % focus on George Street and the other will be headed by Henry % Locks. element(FortyProject, Budget, '40k'), element(FortyProject, Street, FortyStreet), element(FortyProject, Mgr, FortyMgr), element(MayProject, Month, may), element(MayProject, Street, MayStreet), element(MayProject, Mgr, MayMgr), ( MayStreet &= george and FortyMgr &= henry or FortyStreet &= george and MayMgr &= henry ), % 6. Neither the $40,000 project nor the project starting in % August will be managed by Derick Steel. FortyMgr &\= derick, element(AugustProject, Month, aug), element(AugustProject, Mgr, AugustMgr), AugustMgr &\= derick, % 7. Henry Lock's project begins 3 months before the $38,000 % project. element(HenryProject, Mgr, henry), element(HenryProject, Month, HenryMonth), element(ThirtyEightProject, Budget, '38k'), element(ThirtyEightProject, Month, ThirtyEightMonth), shift(HenryMonth, 3, ThirtyEightMonth), % 8. Neither the job starting in September nor the job starting in % August is the Young Drive project. element(SeptemberProject, Month, sep), SeptemberProject #\= YoungProject, AugustProject #\= YoungProject, % 9. The Rembrandt Way project begins 1 month before the % $50,000 project. element(FiftyProject, Budget, '50k'), element(FiftyProject, Month, FiftyMonth), shift(RemMonth, 1, FiftyMonth), % 10. The Fuller Avenue project doesn't start in June. element(FullerProject, Month, FullerMonth), FullerMonth &\= jun, % Labeling ( foreach(Xs, [Budget,Month,Street,Mgr]) >> foreach(X, Xs) do indomain(X) ), % Result ( foreach(T,Month), foreach(S,Street), foreach(M,Mgr), foreach(B,Budget) do writeln(project(T,S,M,B)) ). % A list of symbols is ordered ordered(Relation, Xs) :- symbols_domain_indices(Xs, _Domain, Is), ic_global:ordered(Relation, Is).