color(red).
color(green).
color(blue).
color(yellow).
adjacent(鶴見, 神奈川).
adjacent(神奈川, 西).
adjacent(西, 中).
adjacent(中, 南).
adjacent(南, 港南).
adjacent(港南, 磯子).
adjacent(磯子, 金沢).
adjacent(金沢, 栄).
adjacent(栄, 港南).
adjacent(中, 保土ケ谷).
adjacent(保土ケ谷, 西).
adjacent(保土ケ谷, 旭).
adjacent(旭, 瀬谷).
adjacent(瀬谷, 泉).
adjacent(泉, 戸塚).
adjacent(戸塚, 栄).
adjacent(都筑, 港北).
adjacent(都筑, 青葉).
adjacent(都筑, 緑).
adjacent(港北, 神奈川).
adjacent(緑, 青葉).
adjacent(港北, 鶴見).
adjacent(保土ケ谷, 緑).
% 隣接しているか
adjacent_undirected(X,Y) :- adjacent(X,Y).
adjacent_undirected(X,Y) :- adjacent(Y,X).
% 色が隣接区と違うことをチェック
safe_color(_, _, []).
safe_color(区, 色, [H-色H | T]) :-
(adjacent_undirected
(区
, H
) -> 色 \
= 色H
; true), safe_color(区, 色, T).
% 順番に色割り当て、割り当て済みと矛盾がないか確認
assign_colors([], _).
assign_colors([区 | 残り], 割当済み) :-
color(色),
safe_color(区, 色, 割当済み),
assign_colors(残り, [区-色 | 割当済み]).
% 実行用
run :-
順番 = [鶴見, 神奈川, 西, 中, 南, 港南,
磯子, 金沢, 栄, 保土ケ谷, 旭, 瀬谷,
泉, 戸塚, 都筑, 港北, 緑, 青葉],
assign_colors(順番, []),
% 割当済みの色リストは逆順なので逆にする
reverse(割当済み, 色リスト),
print_colors(色リスト).
print_colors([]).
print_colors([区-色 | 残り]) :-
print_colors(残り).
:- run.
Y29sb3IocmVkKS4KY29sb3IoZ3JlZW4pLgpjb2xvcihibHVlKS4KY29sb3IoeWVsbG93KS4KCmFkamFjZW50KOm2tOimiywg56We5aWI5bedKS4KYWRqYWNlbnQo56We5aWI5bedLCDopb8pLgphZGphY2VudCjopb8sIOS4rSkuCmFkamFjZW50KOS4rSwg5Y2XKS4KYWRqYWNlbnQo5Y2XLCDmuK/ljZcpLgphZGphY2VudCjmuK/ljZcsIOejr+WtkCkuCmFkamFjZW50KOejr+WtkCwg6YeR5rKiKS4KYWRqYWNlbnQo6YeR5rKiLCDmoIQpLgphZGphY2VudCjmoIQsIOa4r+WNlykuCmFkamFjZW50KOS4rSwg5L+d5Zyf44Kx6LC3KS4KYWRqYWNlbnQo5L+d5Zyf44Kx6LC3LCDopb8pLgphZGphY2VudCjkv53lnJ/jgrHosLcsIOaXrSkuCmFkamFjZW50KOaXrSwg54Cs6LC3KS4KYWRqYWNlbnQo54Cs6LC3LCDms4kpLgphZGphY2VudCjms4ksIOaIuOWhmikuCmFkamFjZW50KOaIuOWhmiwg5qCEKS4KYWRqYWNlbnQo6YO9562RLCDmuK/ljJcpLgphZGphY2VudCjpg73nrZEsIOmdkuiRiSkuCmFkamFjZW50KOmDveetkSwg57eRKS4KYWRqYWNlbnQo5riv5YyXLCDnpZ7lpYjlt50pLgphZGphY2VudCjnt5EsIOmdkuiRiSkuCmFkamFjZW50KOa4r+WMlywg6ba06KaLKS4KYWRqYWNlbnQo5L+d5Zyf44Kx6LC3LCDnt5EpLgoKJSDpmqPmjqXjgZfjgabjgYTjgovjgYsKYWRqYWNlbnRfdW5kaXJlY3RlZChYLFkpIDotIGFkamFjZW50KFgsWSkuCmFkamFjZW50X3VuZGlyZWN0ZWQoWCxZKSA6LSBhZGphY2VudChZLFgpLgoKJSDoibLjgYzpmqPmjqXljLrjgajpgZXjgYbjgZPjgajjgpLjg4Hjgqfjg4Pjgq8Kc2FmZV9jb2xvcihfLCBfLCBbXSkuCnNhZmVfY29sb3Io5Yy6LCDoibIsIFtILeiJskggfCBUXSkgOi0KICAgIChhZGphY2VudF91bmRpcmVjdGVkKOWMuiwgSCkgLT4g6ImyIFw9IOiJskggOyB0cnVlKSwKICAgIHNhZmVfY29sb3Io5Yy6LCDoibIsIFQpLgoKJSDpoIbnlarjgavoibLlibLjgorlvZPjgabjgIHlibLjgorlvZPjgabmuIjjgb/jgajnn5vnm77jgYzjgarjgYTjgYvnorroqo0KYXNzaWduX2NvbG9ycyhbXSwgXykuCmFzc2lnbl9jb2xvcnMoW+WMuiB8IOaui+OCil0sIOWJsuW9k+a4iOOBvykgOi0KICAgIGNvbG9yKOiJsiksCiAgICBzYWZlX2NvbG9yKOWMuiwg6ImyLCDlibLlvZPmuIjjgb8pLAogICAgYXNzaWduX2NvbG9ycyjmrovjgoosIFvljLot6ImyIHwg5Ymy5b2T5riI44G/XSkuCgolIOWun+ihjOeUqApydW4gOi0KICAgIOmghueVqiA9IFvptrTopossIOelnuWliOW3nSwg6KW/LCDkuK0sIOWNlywg5riv5Y2XLAogICAgICAgICAgICDno6/lrZAsIOmHkeayoiwg5qCELCDkv53lnJ/jgrHosLcsIOaXrSwg54Cs6LC3LAogICAgICAgICAgICDms4ksIOaIuOWhmiwg6YO9562RLCDmuK/ljJcsIOe3kSwg6Z2S6JGJXSwKICAgIGFzc2lnbl9jb2xvcnMo6aCG55WqLCBbXSksCiAgICB3cml0ZSgnNOiJsuOBp+Whl+OCiuWIhuOBkeWPr+iDvScpLCBubCwKICAgICUg5Ymy5b2T5riI44G/44Gu6Imy44Oq44K544OI44Gv6YCG6aCG44Gq44Gu44Gn6YCG44Gr44GZ44KLCiAgICByZXZlcnNlKOWJsuW9k+a4iOOBvywg6Imy44Oq44K544OIKSwKICAgIHByaW50X2NvbG9ycyjoibLjg6rjgrnjg4gpLgoKcHJpbnRfY29sb3JzKFtdKS4KcHJpbnRfY29sb3JzKFvljLot6ImyIHwg5q6L44KKXSkgOi0KICAgIHdyaXRlKOWMuiksIHdyaXRlKCcgLT4gJyksIHdyaXRlKOiJsiksIG5sLAogICAgcHJpbnRfY29sb3JzKOaui+OCiikuCgo6LSBydW4uCg==