-
Notifications
You must be signed in to change notification settings - Fork 5
/
matchsticks.pl
98 lines (82 loc) · 3.13 KB
/
matchsticks.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
:- use_module(library(clpz)).
:- use_module(library(clpb)).
:- use_module(library(between)).
:- use_module(library(pairs)).
:- use_module(library(format)).
:- use_module(library(lists)).
:- use_module(library(dcgs)).
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Task: Remove minimum number of matchsticks so that no subsquare remains.
Tested with Scryer Prolog.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
o = inside of the square
variable = matchstick
x = nothing here
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
layout(L) :-
L = [[x,_,x,_,x,_,x,_,x],
[_,o,_,o,_,o,_,o,_],
[x,_,x,_,x,_,x,_,x],
[_,o,_,o,_,o,_,o,_],
[x,_,x,_,x,_,x,_,x],
[_,o,_,o,_,o,_,o,_],
[x,_,x,_,x,_,x,_,x],
[_,o,_,o,_,o,_,o,_],
[x,_,x,_,x,_,x,_,x]].
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
?- matchsticks(L, Vs),
same_length(Vs, Coeffs), maplist(=(1), Coeffs),
weighted_maximum(Coeffs, Vs, Maximum),
maplist(portray_clause, L).
%@ [x,1,x,0,x,1,x,1,x].
%@ [1,o,1,o,1,o,1,o,1].
%@ [x,0,x,1,x,0,x,0,x].
%@ [1,o,1,o,1,o,1,o,1].
%@ [x,1,x,0,x,0,x,1,x].
%@ [1,o,1,o,1,o,1,o,1].
%@ [x,0,x,1,x,1,x,0,x].
%@ [1,o,1,o,0,o,1,o,1].
%@ [x,1,x,1,x,1,x,1,x].
%@ L = [[x,1,x,0,x,1,x,1,x]|...], Vs = [1,1,0,1,0,1,1,1,0,1,1,0,1,1,1,1,0,1,0,1,...], Coeffs = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,...], Maximum = 31
%@ ; ... .
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
matchsticks(L, Vs) :-
findall(L-S, layout_subsquare(L,S), LSs),
pairs_keys_values(LSs, Ls, Subs),
maplist(=(L), Ls),
maplist(not_subsquare, Subs),
term_variables(Subs, Vs).
list_odds_evens([], [], []).
list_odds_evens([E], [], [E]).
list_odds_evens([E,O|Ls], [O|Os], [E|Es]) :- list_odds_evens(Ls, Os, Es).
not_subsquare(Subs) :- sat(~ *(Subs)).
layout_subsquare(L, Sub) :-
layout(L),
anyeven(SubList, Len),
Len #> 0,
anyeven(DropsTop, _),
append(DropsTop, Rest0, L),
anyeven(DropsLeft, _),
maplist(drop_first(DropsLeft), Rest0, Rest),
Rest = [First|_],
phrase(horizontals(SubList, First), Tops),
nth0(Len, Rest, Bot),
phrase(horizontals(SubList, Bot), Bots),
phrase(verticals(SubList, Rest), Lefts),
maplist(drop_first(SubList), Rest, Rests1),
phrase(verticals(SubList, Rests1), Rights),
append([Tops,Lefts,Bots,Rights], Sub).
%?- findall(., layout_subsquare(_, _), Ls), length(Ls, L).
%?- layout_subsquare(L, Sub), maplist(writeln, L).
verticals([], _) --> [].
verticals([_,_|Vs], [_,[Var|_]|Rest]) --> [Var], verticals(Vs, Rest).
horizontals([], _) --> [].
horizontals([_,_|Hs], [_,Var|Rest]) --> [Var], horizontals(Hs, Rest).
drop_first(Ls0, Rests0, Rests) :-
same_length(Ls0, Ls),
append(Ls, Rests, Rests0).
anyeven(Ls, E) :-
between(0, 4, E0),
E #= E0 * 2,
length(Ls, E).