SHOW:
|
|
- or go back to the newest paste.
1 | - | %% |
1 | + | |
2 | - | %% Authors: |
2 | + | |
3 | - | %% Christian Schulte <schulte@imit.kth.se> |
3 | + | |
4 | - | %% LECS, IMIT, KTH - Royal Institute of Technology |
4 | + | encontrar: Encontrar |
5 | - | %% Stockholm, Sweden |
5 | + | aplicarMovimientos:AplicarMovimientos |
6 | - | %% |
6 | + | aplicarMovimiento:AplicarMovimiento |
7 | - | %% Copyright: |
7 | + | |
8 | - | %% Christian Schulte, 2002 |
8 | + | % Estructura de los datos estado(principal:P uno:U dos:D) |
9 | - | %% |
9 | + | fun {AplicarMovimiento S M} |
10 | - | %% Last change: |
10 | + | case S of estado(principal:P uno:U dos:D)then |
11 | - | %% $Date: 2002/07/24 14:23:31 $ by $Author: schulte $ |
11 | + | |
12 | - | %% $Revision: 1.5 $ |
12 | + | local Lp PrimerosU UltimosU PrimerosP UltimosP PrimerosD UltimosD Subl in |
13 | - | %% |
13 | + | % {Browse P} |
14 | - | %% Purpose: |
14 | + | |
15 | - | %% Datalogi II, Lab A, Visualizing the shunting station |
15 | + | Lp={Length P} |
16 | - | %% |
16 | + | |
17 | %Si el movimiento se hace en la linea uno | |
18 | case M of uno(N) then | |
19 | Subl=Lp-N | |
20 | - | import |
20 | + | |
21 | - | Tk |
21 | + | {ParticionN U N PrimerosU UltimosU} |
22 | {ParticionN P Subl PrimerosP UltimosP} | |
23 | - | Visualizar |
23 | + | |
24 | - | define |
24 | + | if(N<0) |
25 | - | proc {Visualizar States} |
25 | + | then estado(principal:{Append S.principal PrimerosU} uno:UltimosU dos:D) |
26 | - | %% Dimensions for graphics |
26 | + | elseif (N==0)then estado(principal:P uno:U dos:D) |
27 | - | N = {Max ({Length States.1.principal} + |
27 | + | else estado(principal:PrimerosP uno:{Append UltimosP U} dos:D) |
28 | - | {Length States.1.uno} + |
28 | + | end |
29 | - | {Length States.1.dos}) 4} |
29 | + | |
30 | - | % Maximal number of wagons per track |
30 | + | %Si el movimiento se hace en la linea dos |
31 | - | W = 55 % Width of a wagon |
31 | + | [] dos(N) then |
32 | - | %% WD = 5 % Space between wagons |
32 | + | Subl=Lp-N |
33 | - | H = 45 % Height of a wagon |
33 | + | {ParticionN D N PrimerosD UltimosD} |
34 | - | %% HD = 5 % Space between wagon and track border |
34 | + | {ParticionN P Subl PrimerosP UltimosP} |
35 | - | B = 25 % Border around tracks |
35 | + | if(N<0) |
36 | - | %% Window structure |
36 | + | then estado(principal:{Append P UltimosD} uno:U dos:UltimosD) |
37 | - | T = {New Tk.toplevel tkInit(title:'Visualizador de maniobras')} |
37 | + | elseif (N==0)then estado(principal:P uno:U dos:D) |
38 | - | F = {New Tk.frame tkInit(parent:T)} |
38 | + | else estado(principal:PrimerosP uno:U dos:{Append UltimosP D}) |
39 | - | %% Buttons with logic |
39 | + | end |
40 | - | Pos = {NewCell 1} % Stores the state currently displayed |
40 | + | end |
41 | - | Prev = {New Tk.button tkInit(parent: F |
41 | + | end |
42 | - | text: 'Ant.' |
42 | + | end |
43 | - | action: |
43 | + | end |
44 | - | proc {$} |
44 | + | |
45 | - | I I1={Exchange Pos I} |
45 | + | %Aplicar una secuencia de movimientos sobre un estado inicial |
46 | - | in |
46 | + | fun {AplicarMovimientos S Ms} |
47 | - | if I==2 then |
47 | + | case S of estado(principal:P uno:U dos:D) |
48 | - | {Prev tk(configure state:disabled)} |
48 | + | then |
49 | - | end |
49 | + | case Ms |
50 | - | I1=I-1 |
50 | + | of nil then S |
51 | - | {Next tk(configure state:normal)} |
51 | + | [] H|T then {AplicarMovimientos {AplicarMovimiento S H} T} |
52 | - | {Show {Nth States I1}} |
52 | + | end |
53 | - | end |
53 | + | |
54 | - | state: disabled |
54 | + | end |
55 | - | )} |
55 | + | |
56 | - | Next = {New Tk.button tkInit(parent: F |
56 | + | %Procedimiento para particionar la lista en 2 sublistas de n y longitud total - n elementos, respectivamente |
57 | - | text: 'Sig.' |
57 | + | proc {ParticionN L N ?H ?T} |
58 | - | action: |
58 | + | if (N>0) then |
59 | - | proc {$} |
59 | + | case L of nil then skip |
60 | - | I I1={Exchange Pos I} |
60 | + | [] Ca|Co then {ParticionN Co (N-1) {Append H Ca} T} |
61 | - | in |
61 | + | end |
62 | - | if I+1=={Length States} then |
62 | + | end |
63 | - | {Next tk(configure state:disabled)} |
63 | + | end |
64 | - | end |
64 | + | %{Browse {ParticionN [a b c d e] 3 }} |
65 | - | I1=I+1 |
65 | + | |
66 | - | {Prev tk(configure state:normal)} |
66 | + | |
67 | - | {Show {Nth States I1}} |
67 | + | |
68 | - | end |
68 | + | %Funcion para invertir una lista |
69 | - | state: if {Length States}==1 then |
69 | + | fun {Invertir L} |
70 | - | disabled |
70 | + | case L of nil then nil |
71 | - | else |
71 | + | [] H|T then {Append {Invertir T} [H]} |
72 | - | normal |
72 | + | end |
73 | - | end |
73 | + | end |
74 | - | |
74 | + | |
75 | - | )} |
75 | + | {Browse {AplicarMovimiento estado(principal:[a b c d e] uno:[g] dos:[f]) uno(2)}} |
76 | - | %% Important coordinates |
76 | + | |
77 | - | Y0 = B+0 |
77 | + | |
78 | - | Y1 = B+H |
78 | + | %Funcion para encontrar el total de vagones que tiene un tren |
79 | - | Y2 = B+2*H |
79 | + | fun {NumeroVagones S } |
80 | - | Y25 = Y2 + H div 2 |
80 | + | case S of estado(principal:P uno:U dos:D)then |
81 | - | Y3 = B+3*H |
81 | + | local L L1 L2 |
82 | - | Y4 = B+4*H |
82 | + | in L={List.length P} L1={List.length U} L2={List.length D} |
83 | - | Y5 = B+5*H |
83 | + | L+L1+L2 |
84 | - | X0 = B+0 |
84 | + | |
85 | - | X1 = B+N*W |
85 | + | end |
86 | - | X2 = X1 + H div 2 + H div 4 |
86 | + | end |
87 | - | X3 = X1 + 2*H+10 |
87 | + | |
88 | - | X31 = X1 + 2*H |
88 | + | %Determinar si 2 trenes tienen el mismo numero de vagones |
89 | - | X4 = X3 + N*W |
89 | + | fun {IgualdadVagones Xs Ys} |
90 | ({NumeroVagones Xs}=={NumeroVagones Ys}) | |
91 | - | %% The drawing area |
91 | + | end |
92 | - | C = {New Tk.canvas tkInit(parent: T |
92 | + | |
93 | - | bg: wheat |
93 | + | %Comparar longitud de las listas |
94 | - | width: X4+B |
94 | + | fun {CompararItems L1 L2} |
95 | - | height: 2*B+5*H)} |
95 | + | case L1 of |
96 | - | /* |
96 | + | nil then true |
97 | - | %% Routines for drawing a single wagon |
97 | + | [] H|T then |
98 | - | proc {Wagon X Y T} |
98 | + | if(H==L2.1) then {CompararItems T L2.2} |
99 | - | {C tk(create rectangle X+WD Y+HD X+W-WD Y+H-HD |
99 | + | else false |
100 | - | fill:grey)} |
100 | + | end |
101 | - | {C tk(create text X+W div 2 Y + H div 2 text:T)} |
101 | + | end |
102 | end | |
103 | - | */ |
103 | + | |
104 | - | %% Routines for drawing a single wagon |
104 | + | |
105 | - | proc {Wagon X Y T} |
105 | + | fun {CompararListas L1 L2} |
106 | - | N Engine |
106 | + | if {List.length L1}=={List.length L2} |
107 | - | in |
107 | + | then {CompararItems L1 L2} |
108 | - | N = ({Atom.toString T}.1 - 96) mod 11 |
108 | + | else false |
109 | - | Engine = {New Tk.image tkInit(type:photo file:'images/'#N#'.gif')} |
109 | + | end |
110 | - | {C tk(create image X+W div 2 Y+H div 2 image:Engine)} |
110 | + | end |
111 | - | {C tk(create text X+W div 2 Y anchor:n text:T)} |
111 | + | |
112 | ||
113 | ||
114 | - | %% Display a state |
114 | + | % Detectar vagones repetidos al interior de un tren |
115 | - | proc {Show State} |
115 | + | fun {DetectarRepetidos Ls Ant} |
116 | if (Ls==nil) then false | |
117 | - | %% Display each track |
117 | + | elseif (Ant==Ls.1) then true |
118 | - | proc {Main Ws} |
118 | + | else {Or false {DetectarRepetidos Ls.2 Ls.1}} |
119 | - | {List.forAllInd {Reverse Ws} |
119 | + | end |
120 | - | proc {$ I T} |
120 | + | end |
121 | - | {Wagon X1-I*W Y2 T} |
121 | + | |
122 | - | end} |
122 | + | |
123 | %Devolver una lista con los estados intermedios que se generan, tras aplicarle una serie de movimientos sobre una estado inicial | |
124 | fun {EstadosIntermedios S Ms} | |
125 | - | proc {One Ws} |
125 | + | case S of estado(principal:P uno:U dos:D) |
126 | - | {List.forAllInd Ws |
126 | + | then |
127 | - | proc {$ I T} |
127 | + | case Ms of |
128 | - | {Wagon X3+(I-1)*W Y0 T} |
128 | + | nil then S |
129 | - | end} |
129 | + | [] H|T then |
130 | local Actual | |
131 | in Actual= {AplicarMovimiento S H} | |
132 | - | proc {Two Ws} |
132 | + | Actual|{EstadosIntermedios Actual T} |
133 | - | {List.forAllInd Ws |
133 | + | end |
134 | - | proc {$ I T} |
134 | + | end |
135 | - | {Wagon X3+(I-1)*W Y4 T} |
135 | + | end |
136 | - | end} |
136 | + | end |
137 | ||
138 | ||
139 | - | in |
139 | + | %SubListas coincidentes |
140 | - | %% Reset drawing |
140 | + | fun {SublistasCoincidentes Xs Ys} |
141 | - | {C tk(delete all)} |
141 | + | case Xs of |
142 | - | %% Create tracks |
142 | + | nil then nil |
143 | - | {C tk(create polygon |
143 | + | else {LongitudCoincidencia Xs Ys 0}|{SublistasCoincidentes Xs.2 Ys.2} |
144 | - | X0 Y2 X0 Y3 X1 Y3 X31 Y5 X4 Y5 |
144 | + | |
145 | - | X4 Y4-1 X3 Y4-1 X2 Y25 X3 Y1 X4 Y1 |
145 | + | end |
146 | - | X4 Y0 X31 Y0 X1 Y2 X0 Y2 |
146 | + | %Esto se puede optimizar tantisimo |
147 | - | fill: white |
147 | + | |
148 | - | outline: black)} |
148 | + | |
149 | - | %% Create railroads |
149 | + | |
150 | - | %%{C tk(create line X0 Y2+25 X1 Y2+25 width:2)} |
150 | + | %Longitud de las sublista coincidente |
151 | - | {C tk(create line X0 Y3-4 X1+3 Y3-4 width:2)} |
151 | + | fun {LongitudCoincidencia Xs Ys Cont} |
152 | - | {C tk(create line X1+2 Y3-4 X31+2 Y5-4 width:2)} |
152 | + | case Xs of |
153 | - | {C tk(create line X31+2 Y5-4 X4 Y5-4 width:2)} |
153 | + | nil then cont |
154 | - | {C tk(create line X1+2 Y3-4 X31+2 Y1-4 width:2)} |
154 | + | [] H|T then |
155 | - | {C tk(create line X31+2 Y1-4 X4 Y1-4 width:2)} |
155 | + | case Ys of |
156 | H1|T1 then | |
157 | - | %% Label tracks |
157 | + | if(H==H1)then {LongitudCoincidencia T T1 (Cont + 1)} |
158 | - | {C tk(create text X0+10 Y2-10 anchor:w text:'principal')} |
158 | + | else cont |
159 | - | {C tk(create text X3+10 Y0-10 anchor:w text:'uno')} |
159 | + | end |
160 | - | {C tk(create text X3+10 Y4-10 anchor:w text:'dos')} |
160 | + | |
161 | - | %% Draw trains |
161 | + | end |
162 | - | {Main State.principal} |
162 | + | end |
163 | - | {One State.uno} |
163 | + | |
164 | - | {Two State.dos} |
164 | + | %Devuelve la posicion del elemento e al interior de la lista l |
165 | fun {EncontrarPosicion E L Pos} | |
166 | case L of | |
167 | - | in |
167 | + | H|T then if(H==E) then pos |
168 | - | {Tk.batch [grid(F row:0 column:0) |
168 | + | else {EncontrarPosicion e T (Pos + 1)} |
169 | - | pack(Prev Next side:left padx:5#m pady:2#m) |
169 | + | |
170 | - | grid(C row:1 column:0)]} |
170 | + | |
171 | - | {Show States.1} |
171 | + | |
172 | ||
173 | - | %%{Visualize [estado(principal:[a b] uno:[a] dos:[b]) estado(principal:[b] uno:[a] dos:[b]) estado(principal:[c b] uno:[d] dos:[a b])]} |
173 | + | |
174 | %Funcion que retorna la lista de movimientos para llevar el estado Xs al estado Ys | |
175 | fun {Encontrar Xs Ys} | |
176 | ||
177 | %Caso trivial | |
178 | if(Xs==Ys)then uno(0)|nil | |
179 | else | |
180 | %Validar que el tamaño de los trenes sea el mismo | |
181 | if({IgualdadVagones Xs Ys}) | |
182 | then | |
183 | %Validar que no hallan vagones repetidos al interior de ningun tren | |
184 | if({Not{Or {DetectarRepetidos Xs nil}{DetectarRepetidos Ys nil}}}) | |
185 | then | |
186 | %Validar que los vagones de los trenes sean permutaciones sobre el mismo conjunto | |
187 | if({CompararListas {Sort Xs '<'}{Sort Ys '<'}}) | |
188 | then | |
189 | local ListaCoincidencias in | |
190 | ListaCoincidencias={SublistasCoincidentes Xs Ys} | |
191 | {EncontrarAux Xs Ys ListaCoincidencias} | |
192 | end | |
193 | end | |
194 | end | |
195 | end | |
196 | end | |
197 | end | |
198 | ||
199 | fun {EncontrarAux Xs Ys Cs} | |
200 | local L NCoincidencias NEquivocados Siguiente Antes Despues in | |
201 | L={Length Xs} | |
202 | NCoincidencias=Cs.1 | |
203 | %Caso 1:Sublistas iniciales coincidentes | |
204 | if(NCoincidencias>0) | |
205 | then NEquivocados=L- NCoincidencias | |
206 | {EncontrarAux {Ultimos Xs NEquivocados}{Ultimos Ys NEquivocados}{Ultimos Cs NEquivocados}} | |
207 | ||
208 | %Caso 2:Sublistas inicialmente diferentes | |
209 | else | |
210 | Siguiente={EncontrarPosicion Ys.1 Xs 0} | |
211 | Despues= L-Siguiente+1 | |
212 | Antes= L-Despues | |
213 | %Movemos el bloque de tamaño Longitud de la lista-Siguiente +1 | |
214 | [dos(Despues) uno(Antes) dos(~1) uno(~Antes) dos(~(Despues-1))] | {EncontrarAux Xs.2 Ys.2 Cs.2} | |
215 | end | |
216 | end | |
217 | end | |
218 | ||
219 | end |