|
15 | 15 | import Controls from '../routes/Controls.svelte';
|
16 | 16 | import { get } from 'svelte/store';
|
17 | 17 | import { algorithmDisplayNames } from '../stores/algorithmMap.js';
|
| 18 | + import { waitUntilResume, delay, pauseIfNeeded, log } from '../stores/utils.js'; |
| 19 | +
|
| 20 | + const displayName = algorithmDisplayNames[get(selectedAlgorithm)]; |
18 | 21 |
|
19 | 22 | // ==== Alapadatok ====
|
20 | 23 |
|
21 |
| - currentStep.set(0); |
22 |
| - algorithmStatus.set('idle'); |
23 |
| - consoleLog.set([]); |
24 |
| - activeLine.set(-1); |
25 | 24 | let exchangeCoins = [1, 4, 6, 10];
|
26 |
| - const displayName = algorithmDisplayNames[get(selectedAlgorithm)]; |
27 | 25 | let dpTable: { index: number; value: number; coin: number }[] = [];
|
28 | 26 | let lastCoinTable = [];
|
29 |
| -
|
30 | 27 | let moneyToExchange = 29;
|
31 | 28 |
|
32 | 29 | let newCoin = 0;
|
33 | 30 | let showInsertForm = false;
|
34 | 31 | let showDeleteList = false;
|
35 | 32 |
|
| 33 | + // ==== Előkalkulált lépésszám ==== |
| 34 | + onMount(() => { |
| 35 | + totalSteps.set(Math.floor(moneyToExchange)); |
| 36 | + resetParameters(); |
| 37 | + }); |
| 38 | +
|
| 39 | + function resetParameters() { |
| 40 | + algorithmStatus.set('idle'); |
| 41 | + currentStep.set(0); |
| 42 | + consoleLog.set([]); |
| 43 | +
|
| 44 | + usedCoins = []; |
| 45 | + dpTable = []; |
| 46 | +
|
| 47 | + activeLine.set({ start: -1, end: -1 }); |
| 48 | + } |
| 49 | +
|
36 | 50 | function openInsertForm() {
|
37 | 51 | showInsertForm = !showInsertForm;
|
38 | 52 | showDeleteList = false;
|
|
63 | 77 | showDeleteList = false;
|
64 | 78 | }
|
65 | 79 |
|
66 |
| - // ==== Előkalkulált lépésszám ==== |
67 |
| - onMount(() => { |
68 |
| - totalSteps.set(0); |
69 |
| - }); |
70 |
| -
|
71 | 80 | // ==== Késleltetés és vezérlés ====
|
72 |
| - function log(message: string) { |
73 |
| - consoleLog.update((logs) => [...logs, message]); |
74 |
| - currentStep.update((n) => n + 1); |
75 |
| - } |
76 |
| - function delay(ms: number) { |
77 |
| - return new Promise((resolve) => setTimeout(resolve, ms)); |
78 |
| - } |
79 |
| - function waitUntilResume(): Promise<void> { |
80 |
| - return new Promise((resolve) => { |
81 |
| - const unsub = resumeSignal.subscribe(() => { |
82 |
| - if (get(algorithmStatus) === 'running') { |
83 |
| - unsub(); |
84 |
| - resolve(); |
85 |
| - } |
86 |
| - }); |
87 |
| - }); |
88 |
| - } |
89 |
| - function waitUntilRestart(): Promise<void> { |
90 |
| - return new Promise((resolve) => { |
91 |
| - const unsub = resumeSignal.subscribe(() => { |
92 |
| - if (get(algorithmStatus) === 'idle') { |
93 |
| - consoleLog.set([]); |
94 |
| - currentStep.set(0); |
95 |
| -
|
96 |
| - usedCoins = []; |
97 |
| - dpTable = []; |
98 |
| -
|
99 |
| - unsub(); |
100 |
| - resolve(); |
101 |
| - } |
102 |
| - }); |
103 |
| - }); |
104 |
| - } |
105 |
| - async function pauseIfNeeded() { |
106 |
| - if (get(algorithmStatus) === 'paused') { |
107 |
| - await waitUntilResume(); |
108 |
| - } |
109 |
| - } |
110 | 81 | async function restartAlgorithm() {
|
111 | 82 | if (get(algorithmStatus) === 'finished') {
|
112 |
| - await waitUntilRestart(); |
| 83 | + return new Promise((resolve) => { |
| 84 | + const unsub = resumeSignal.subscribe(() => { |
| 85 | + if (get(algorithmStatus) === 'idle') { |
| 86 | + resetParameters(); |
| 87 | + unsub(); |
| 88 | + resolve(); |
| 89 | + } |
| 90 | + }); |
| 91 | + }); |
113 | 92 | }
|
114 | 93 | }
|
115 | 94 |
|
|
125 | 104 | showDeleteList = false;
|
126 | 105 |
|
127 | 106 | let amount = Math.floor(moneyToExchange);
|
| 107 | + totalSteps.set(amount); |
128 | 108 | let coins = exchangeCoins.map((c) => Math.floor(c));
|
129 |
| - dpTable = []; |
130 | 109 |
|
131 | 110 | await coinExchange(amount, coins);
|
132 | 111 |
|
| 112 | + activeLine.set({ start: -1, end: -1 }); |
| 113 | +
|
133 | 114 | consoleLog.update((logs) => [...logs, 'A futás befejeződött!']);
|
134 | 115 | algorithmStatus.set('finished');
|
135 | 116 | await restartAlgorithm();
|
|
144 | 125 |
|
145 | 126 | dp[0] = 0;
|
146 | 127 |
|
147 |
| - totalSteps.set(amount); |
148 |
| -
|
149 | 128 | for (let i = 1; i <= amount; i++) {
|
150 |
| - activeLine.set(6); |
151 |
| - await pauseIfNeeded(); |
| 129 | + activeLine.set({ start: 7, end: 7 }); |
152 | 130 | await delay(700 - get(speed) * 8);
|
| 131 | + await pauseIfNeeded(); |
| 132 | +
|
153 | 133 | for (let coin of coins) {
|
154 |
| - activeLine.set(7); |
155 |
| - await pauseIfNeeded(); |
| 134 | + activeLine.set({ start: 8, end: 8 }); |
156 | 135 | await delay(700 - get(speed) * 8);
|
| 136 | + await pauseIfNeeded(); |
| 137 | +
|
157 | 138 | if (i - coin >= 0 && dp[i - coin] + 1 < dp[i]) {
|
158 | 139 | dp[i] = dp[i - coin] + 1;
|
159 | 140 | lastCoin[i] = coin;
|
160 |
| - activeLine.set(9); |
161 |
| - await pauseIfNeeded(); |
| 141 | + activeLine.set({ start: 10, end: 13 }); |
162 | 142 | await delay(700 - get(speed) * 8);
|
| 143 | + await pauseIfNeeded(); |
163 | 144 | }
|
164 | 145 | }
|
165 | 146 |
|
166 | 147 | dpTable = [...dpTable, { index: i, value: dp[i], coin: lastCoin[i] }];
|
167 | 148 |
|
168 |
| - activeLine.set(12); |
169 |
| - await pauseIfNeeded(); |
| 149 | + activeLine.set({ start: 16, end: 16 }); |
170 | 150 | await delay(700 - get(speed) * 8);
|
| 151 | + await pauseIfNeeded(); |
| 152 | +
|
171 | 153 | log(`Összeg: ${i}, Minimum érme: ${dp[i]}, Utolsó érme: ${lastCoin[i]}`);
|
172 | 154 | }
|
173 | 155 |
|
|
176 | 158 | while (current > 0) {
|
177 | 159 | let coin = lastCoin[current];
|
178 | 160 | if (coin === -1) {
|
179 |
| - activeLine.set(20); |
180 |
| - await pauseIfNeeded(); |
| 161 | + activeLine.set({ start: 24, end: 26 }); |
181 | 162 | await delay(700 - get(speed) * 8);
|
| 163 | + await pauseIfNeeded(); |
| 164 | +
|
182 | 165 | consoleLog.update((logs) => [...logs, 'Nem lehet pontosan felváltani!']);
|
183 | 166 | break;
|
184 | 167 | }
|
185 | 168 | usedCoins.push(coin);
|
186 | 169 | current -= coin;
|
187 | 170 | }
|
188 | 171 |
|
189 |
| - activeLine.set(-1); |
190 |
| -
|
191 | 172 | consoleLog.update((logs) => [...logs, `Minimum érme szám: ${usedCoins.length}`]);
|
192 | 173 | consoleLog.update((logs) => [...logs, `Felhasznált érmék: ${usedCoins}`]);
|
193 | 174 | }
|
|
199 | 180 | let dp = Array(amount + 1).fill(Infinity);
|
200 | 181 | let lastCoin = Array(amount + 1).fill(-1);
|
201 | 182 | dp[0] = 0;
|
| 183 | +
|
202 | 184 | for (let i = 1; i <= amount; i++) {
|
203 | 185 | for (let coin of coins) {
|
| 186 | +
|
204 | 187 | if (i - coin >= 0 && dp[i - coin] + 1 < dp[i]) {
|
205 | 188 | dp[i] = dp[i - coin] + 1;
|
206 | 189 | lastCoin[i] = coin;
|
207 | 190 | }
|
| 191 | +
|
208 | 192 | }
|
209 | 193 | dpTable = [...dpTable, { index: i, value: dp[i], coin: lastCoin[i] }];
|
210 | 194 | }
|
211 | 195 |
|
212 | 196 | usedCoins = [];
|
213 | 197 | let current = amount;
|
| 198 | +
|
214 | 199 | while (current > 0) {
|
215 | 200 | let coin = lastCoin[current];
|
216 | 201 | if (coin === -1) {
|
|
219 | 204 | usedCoins.push(coin);
|
220 | 205 | current -= coin;
|
221 | 206 | }
|
| 207 | +
|
222 | 208 | }`
|
223 | 209 | );
|
224 | 210 | </script>
|
|
227 | 213 | <div class="custom-input">
|
228 | 214 | <div>
|
229 | 215 | <label for="order">Felváltandó:</label>
|
230 |
| - <input id="order" bind:value={moneyToExchange} /> |
| 216 | + <input |
| 217 | + id="order" |
| 218 | + type="number" |
| 219 | + disabled={$algorithmStatus !== 'idle'} |
| 220 | + bind:value={moneyToExchange} |
| 221 | + /> |
231 | 222 | </div>
|
232 | 223 |
|
233 | 224 | <div class="custom-buttons">
|
234 | 225 | <div class="button-group">
|
235 |
| - <button on:click={openInsertForm}>Beszúrás</button> |
| 226 | + <button disabled={$algorithmStatus !== 'idle'} on:click={openInsertForm}>Beszúrás</button> |
236 | 227 | {#if showInsertForm}
|
237 |
| - <div class="dropdown"> |
| 228 | + <div class="dropdown insert-dropdown"> |
238 | 229 | <input type="number" placeholder="Érme értéke" bind:value={newCoin} />
|
239 | 230 | <button on:click={insertNewCoin}>Hozzáadás</button>
|
240 | 231 | </div>
|
241 | 232 | {/if}
|
242 | 233 | </div>
|
243 | 234 |
|
244 | 235 | <div class="button-group">
|
245 |
| - <button on:click={openDeleteList}>Kivétel</button> |
| 236 | + <button disabled={$algorithmStatus !== 'idle'} on:click={openDeleteList}>Kivétel</button> |
246 | 237 | {#if showDeleteList}
|
247 | 238 | <div class="dropdown">
|
248 | 239 | {#each exchangeCoins as coin, index}
|
|
260 | 251 | <!-- ==== Komponens markup ==== -->
|
261 | 252 | <div class="algorithm-container">
|
262 | 253 | <Controls {currentStep} {totalSteps} on:start={startAlgorithm} />
|
263 |
| - <div class="tag">Vászon</div> |
264 | 254 | <div class="coin-visual">
|
265 | 255 | <div class="left-container">
|
266 | 256 | <div>Felhasználható</div>
|
|
309 | 299 |
|
310 | 300 | <!-- ==== Stílus ==== -->
|
311 | 301 | <style>
|
312 |
| - .tag { |
313 |
| - display: inline-block; |
314 |
| - top: 0; |
315 |
| - left: 0; |
316 |
| - background-color: #484848; |
317 |
| - color: white; |
318 |
| - padding: 3px; |
319 |
| - } |
320 | 302 | .coin-visual {
|
321 | 303 | display: flex;
|
322 | 304 | gap: 40px;
|
|
353 | 335 | border-bottom: 3px solid #505050;
|
354 | 336 | }
|
355 | 337 | .custom-input input {
|
| 338 | + text-align: center; |
| 339 | + font-size: 1rem; |
356 | 340 | width: 55px;
|
357 | 341 | padding: 0.5rem;
|
358 |
| - margin-right: 10px; |
359 | 342 | border-radius: 5px;
|
360 | 343 | background-color: #2f2f2f;
|
361 | 344 | border: 3px solid #505050;
|
362 | 345 | }
|
| 346 | + .custom-input input:disabled { |
| 347 | + opacity: 0.6; |
| 348 | + cursor: not-allowed; |
| 349 | + border-color: #3a3a3a; |
| 350 | + } |
363 | 351 | .custom-input button {
|
364 | 352 | padding: 0.5rem 1rem;
|
365 | 353 | background-color: #444;
|
|
371 | 359 | .custom-input button:hover {
|
372 | 360 | background-color: #5cb85c;
|
373 | 361 | }
|
| 362 | + .custom-input button:disabled { |
| 363 | + opacity: 0.6; |
| 364 | + cursor: not-allowed; |
| 365 | + border-color: #3a3a3a; |
| 366 | + } |
374 | 367 | .custom-input label {
|
375 | 368 | width: 150px;
|
376 | 369 | text-align: center;
|
|
415 | 408 | color: white;
|
416 | 409 | border: 1px solid #666;
|
417 | 410 | }
|
| 411 | + .insert-dropdown { |
| 412 | + align-items: center; |
| 413 | + } |
418 | 414 | .delete-item {
|
419 | 415 | display: flex;
|
420 | 416 | flex-direction: column;
|
|
0 commit comments