% 色の定義
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( 保土ケ谷, 緑) .
adjacent_undirected( X, Y) :- adjacent( X, Y) .
adjacent_undirected( X, Y) :- adjacent( Y, X) .
% 隣接区と色が違うことを確認
safe_color( _, _, [ ] ) .
safe_color( District, Color, [ OtherDistrict- OtherColor | Rest] ) :-
( adjacent_undirected
( District
, OtherDistrict
) - > Color \
= OtherColor
; true ) , safe_color( District, Color, Rest) .
% 色割り当て。割当済みリストを渡してチェックしながら進む
assign_colors( [ ] , Assigned, Assigned) .
assign_colors( [ D| Ds] , AssignedSoFar, Assigned) :-
color( Color) ,
safe_color( D, Color, AssignedSoFar) ,
assign_colors( Ds, [ D- Color| AssignedSoFar] , Assigned) .
% 横浜市18区のリスト(探索順)
districts( [ 鶴見, 神奈川, 西, 中, 南, 港南,
磯子, 金沢, 栄, 保土ケ谷, 旭, 瀬谷,
泉, 戸塚, 都筑, 港北, 緑, 青葉] ) .
% 結果の表示
print_colors( [ ] ) .
print_colors( [ D- C| Rest] ) :-
format( '~w -> ~w~n' , [ D, C] ) ,
print_colors( Rest) .
% メイン実行ルーチン
run :-
districts( Ds) ,
assign_colors( Ds, [ ] , Assigned) ,
reverse( Assigned, AssignedReversed) ,
print_colors( AssignedReversed) .
JSDoibLjga7lrprnvqkKY29sb3IocmVkKS4KY29sb3IoZ3JlZW4pLgpjb2xvcihibHVlKS4KY29sb3IoeWVsbG93KS4KCiUg6Zqj5o6l6Zai5L+C77yI5Y+M5pa55ZCR44Gn5a6a576p77yJCmFkamFjZW50KOm2tOimiywg56We5aWI5bedKS4KYWRqYWNlbnQo6ba06KaLLCDmuK/ljJcpLgphZGphY2VudCjnpZ7lpYjlt50sIOilvykuCmFkamFjZW50KOelnuWliOW3nSwg5riv5YyXKS4KYWRqYWNlbnQo6KW/LCDkuK0pLgphZGphY2VudCjkuK0sIOWNlykuCmFkamFjZW50KOWNlywg5riv5Y2XKS4KYWRqYWNlbnQo5riv5Y2XLCDno6/lrZApLgphZGphY2VudCjno6/lrZAsIOmHkeayoikuCmFkamFjZW50KOmHkeayoiwg5qCEKS4KYWRqYWNlbnQo5qCELCDmuK/ljZcpLgphZGphY2VudCjkuK0sIOS/neWcn+OCseiwtykuCmFkamFjZW50KOS/neWcn+OCseiwtywg6KW/KS4KYWRqYWNlbnQo5L+d5Zyf44Kx6LC3LCDml60pLgphZGphY2VudCjml60sIOeArOiwtykuCmFkamFjZW50KOeArOiwtywg5rOJKS4KYWRqYWNlbnQo5rOJLCDmiLjloZopLgphZGphY2VudCjmiLjloZosIOaghCkuCmFkamFjZW50KOmDveetkSwg5riv5YyXKS4KYWRqYWNlbnQo6YO9562RLCDpnZLokYkpLgphZGphY2VudCjpg73nrZEsIOe3kSkuCmFkamFjZW50KOa4r+WMlywg6ba06KaLKS4KYWRqYWNlbnQo57eRLCDpnZLokYkpLgphZGphY2VudCjkv53lnJ/jgrHosLcsIOe3kSkuCgphZGphY2VudF91bmRpcmVjdGVkKFgsIFkpIDotIGFkamFjZW50KFgsIFkpLgphZGphY2VudF91bmRpcmVjdGVkKFgsIFkpIDotIGFkamFjZW50KFksIFgpLgoKJSDpmqPmjqXljLrjgajoibLjgYzpgZXjgYbjgZPjgajjgpLnorroqo0Kc2FmZV9jb2xvcihfLCBfLCBbXSkuCnNhZmVfY29sb3IoRGlzdHJpY3QsIENvbG9yLCBbT3RoZXJEaXN0cmljdC1PdGhlckNvbG9yIHwgUmVzdF0pIDotCiAgICAoYWRqYWNlbnRfdW5kaXJlY3RlZChEaXN0cmljdCwgT3RoZXJEaXN0cmljdCkgLT4gQ29sb3IgXD0gT3RoZXJDb2xvciA7IHRydWUpLAogICAgc2FmZV9jb2xvcihEaXN0cmljdCwgQ29sb3IsIFJlc3QpLgoKJSDoibLlibLjgorlvZPjgabjgILlibLlvZPmuIjjgb/jg6rjgrnjg4jjgpLmuKHjgZfjgabjg4Hjgqfjg4Pjgq/jgZfjgarjgYzjgonpgLLjgoAKYXNzaWduX2NvbG9ycyhbXSwgQXNzaWduZWQsIEFzc2lnbmVkKS4KYXNzaWduX2NvbG9ycyhbRHxEc10sIEFzc2lnbmVkU29GYXIsIEFzc2lnbmVkKSA6LQogICAgY29sb3IoQ29sb3IpLAogICAgc2FmZV9jb2xvcihELCBDb2xvciwgQXNzaWduZWRTb0ZhciksCiAgICBhc3NpZ25fY29sb3JzKERzLCBbRC1Db2xvcnxBc3NpZ25lZFNvRmFyXSwgQXNzaWduZWQpLgoKJSDmqKrmtZzluIIxOOWMuuOBruODquOCueODiO+8iOaOoue0oumghu+8iQpkaXN0cmljdHMoW+m2tOimiywg56We5aWI5bedLCDopb8sIOS4rSwg5Y2XLCDmuK/ljZcsCiAgICAgICAgICAg56Ov5a2QLCDph5HmsqIsIOaghCwg5L+d5Zyf44Kx6LC3LCDml60sIOeArOiwtywKICAgICAgICAgICDms4ksIOaIuOWhmiwg6YO9562RLCDmuK/ljJcsIOe3kSwg6Z2S6JGJXSkuCgolIOe1kOaenOOBruihqOekugpwcmludF9jb2xvcnMoW10pLgpwcmludF9jb2xvcnMoW0QtQ3xSZXN0XSkgOi0KICAgIGZvcm1hdCgnfncgLT4gfnd+bicsIFtELCBDXSksCiAgICBwcmludF9jb2xvcnMoUmVzdCkuCgolIOODoeOCpOODs+Wun+ihjOODq+ODvOODgeODswpydW4gOi0KICAgIGRpc3RyaWN0cyhEcyksCiAgICBhc3NpZ25fY29sb3JzKERzLCBbXSwgQXNzaWduZWQpLAogICAgd3JpdGUoJzToibLjgafloZfjgorliIbjgZHlj6/og73jgafjgZnjgIInKSwgbmwsCiAgICByZXZlcnNlKEFzc2lnbmVkLCBBc3NpZ25lZFJldmVyc2VkKSwKICAgIHByaW50X2NvbG9ycyhBc3NpZ25lZFJldmVyc2VkKS4KCjotIGluaXRpYWxpemF0aW9uKHJ1bikuCg==