Skip to content

Commit

Permalink
Add task 04
Browse files Browse the repository at this point in the history
  • Loading branch information
nb committed Apr 12, 2013
1 parent 2c36b28 commit e2b0ca9
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 0 deletions.
65 changes: 65 additions & 0 deletions tasks/04/README.markdown
@@ -0,0 +1,65 @@
# Ескалатори в мола

В тази задача ще трябва да моделирате как обитателите на мола обикалят по ескалаторите.

Молът е матрица 4×4 като всяка клетка е магазин. Координатите са като на тази картинка:

![Координати](https://raw.github.com/fmi/clojure-homework/master/tasks/04/coordinates.png)

В някои от магазините има обитатели, чиято цел е постоянно да обикалят по ескалаторите в мола и да ходят по магазините. В един магазин никога няма повече от един обитател.

Животът на един обитател протича по следния начин:

0. Тръгва от някой магазин.
1. Хваща ескалатор до първия свободен магазин (без друг обитател в него). Редът, в който се пробват магазините е следния:

![Координати](https://raw.github.com/fmi/clojure-homework/master/tasks/04/order-of-trying.png)

Първо горе-вляво, после долу-вдясно, после долу вляво и накрая горе-вдясно. Ако някой от тези опити излиза извън мола, просто отиваме от другата му страна в същата посока:

![Координати](https://raw.github.com/fmi/clojure-homework/master/tasks/04/out-of-bounds.png)

2. Движи се по този този начин или докато направи 100 премествания или докато не бъде заклещен и няма къде да ходи. Което и от двете да се случи, обитателят спира и никога повече не се мърда.

Целта е при дадено начално състояние на мола да симулирате как ще се движат обитателите и да ни дадете лог от случилите се събития в правилния ред.

Функцията, която трябва да напишете се казва `play-mall` и приема един
аргумент – двумерен вектор 4×4, в който празните магазини са обозначени
с `:-`, а хората с `:X`.

Трябва да върнете вектор от двойки с координати – начална и крайна точка на
съответния ход.

Пример:

[[:- :- :- :-]
[:- :- :- :-]
[:- :- :- :-]
[:- :- :- :X]]

За този мол резултатът ще е:

[[[3 3] [2 2]] [[2 2] [1 1]] … [[3 3] :no-more]]

Ако някой обитател изчерпа ходовете си, то след стотното преместване в лога трябва да има още един елемент, в който крайната точка е `:no-more`

Още един пример:

[[:X :X :X :X]
[:X :X :X :X]
[:X :X :X :X]
[:X :X :X :X]]

За този модул резултатът ще е подобен на:

[[[0 0] :stuck] [[0 1] :stuck] … [[3 3] :stuck]]

Ако някой обитател няма накъде да мърда, в лога слагаме още един елемент с крайна точка `:stuck`. Тъй като обитателите може да тръгнат в различен ред, в този случай някои от елементите на лога може да са в различен от този ред. В тестовете ще проверяваме за консистентността на вашия лог, а няма да очакваме определен ред.

Някои особености и подсказки:

* Обитателите трябва да се мърдат паралелно един с друг и независимо един от друг. Не се опитвайте да изпълнявате всичко последователно.
* Последователността от ходовете в лога трябва да е консистентна. Ако възпроизведем събитията от лога в никой момент не трябва да има повече от един обитател на едно поле, обитателите не трябва да правят ходове, ако са стигнали лимита си, или ако са заклещени.
* Подсказка (научено по трудния начин): `await` чака само действия пуснати в текущия thread или агент.
* Подсказка: агентите винаги изпълняват действията си в реда на подаването им.
* [Примерният тест си е в github](https://github.com/fmi/clojure-homework/blob/master/tasks/04/sample_test.clj).
Binary file added tasks/04/coordinates.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tasks/04/order-of-trying.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tasks/04/out-of-bounds.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 25 additions & 0 deletions tasks/04/sample_test.clj
@@ -0,0 +1,25 @@
(use 'clojure.test)

(load-file "solution.clj")

(deftest task-04-test
(let [all-stuck (set (for [x [0 1 2 3]
y [0 1 2 3]]
[[x y] :stuck]))
up-left-moves (for [i (range 103 3 -1)
:let [start (mod i 4)
end (mod (dec i) 4)]]
[[start start] [end end]])
up-left (conj (vec up-left-moves) [[3 3] :no-more])]
(is (= all-stuck (set (play-mall [[:X :X :X :X]
[:X :X :X :X]
[:X :X :X :X]
[:X :X :X :X]])))
"Test all stuck")
(is (= up-left (play-mall [[:- :- :- :-]
[:- :- :- :-]
[:- :- :- :-]
[:- :- :- :X]]))
"Test single dweller, going up and left")))

(run-tests)

0 comments on commit e2b0ca9

Please sign in to comment.