КДП/К2 2022 — разлика између измена

Извор: SI Wiki
Пређи на навигацију Пређи на претрагу
(Kolokvijum danas i moja rešenja)
 
м (kategorije zadataka)
Ред 2: Ред 2:
'''Други колоквијум 2022. године''' одржан је 15. маја.
'''Други колоквијум 2022. године''' одржан је 15. маја.


== 1. задатак ==
== {{категорија|1. задатак|Монитори}} ==
=== Поставка ===
=== Поставка ===
Решити проблем Читалаца и писаца (Readers/Writers) користећи мониторе са дисциплином ''Signal and Continue''. Проблем решити користећи технику прослеђивања услова (''Passing the Condition''). Монитор треба да поседује 4 методе: <code>lockShared()</code> — желим да читам, <code>lockExclusive()</code> — желим да пишем, <code>unlock()</code> — завршавам, и <code>upgradeLock()</code> — са читања прелазим на писање.
Решити проблем Читалаца и писаца (Readers/Writers) користећи мониторе са дисциплином ''Signal and Continue''. Проблем решити користећи технику прослеђивања услова (''Passing the Condition''). Монитор треба да поседује 4 методе: <code>lockShared()</code> — желим да читам, <code>lockExclusive()</code> — желим да пишем, <code>unlock()</code> — завршавам, и <code>upgradeLock()</code> — са читања прелазим на писање.
Ред 63: Ред 63:
</syntaxhighlight>
</syntaxhighlight>


== 2. задатак ==
== {{категорија|2. задатак|Региони}} ==
=== Поставка ===
=== Поставка ===
На обали реке се налази чамац који може да прими тачно десет путника. Чамац могу да користе мушкарци, жене и деца. Чамац може да исплови само ако се у њему налази тачно онолико путника колики му је капацитет, али само под условом да се у чамцу налазе бар два мушкарца. Деца не смеју ући у чамац уколико се у њему не налазе бар једна одрасла особа и по завршетку вожње у чамцу не смеју да остану само деца. Сматрати да ће се<sup>[sic]</sup> чамац након искрцавања свих путника одмах бити спреман да прими наредну групу путника. Користећи регионе написати програм који решава овај проблем.
На обали реке се налази чамац који може да прими тачно десет путника. Чамац могу да користе мушкарци, жене и деца. Чамац може да исплови само ако се у њему налази тачно онолико путника колики му је капацитет, али само под условом да се у чамцу налазе бар два мушкарца. Деца не смеју ући у чамац уколико се у њему не налазе бар једна одрасла особа и по завршетку вожње у чамцу не смеју да остану само деца. Сматрати да ће се<sup>[sic]</sup> чамац након искрцавања свих путника одмах бити спреман да прими наредну групу путника. Користећи регионе написати програм који решава овај проблем.

Верзија на датум 11. фебруар 2023. у 04:57

Други колоквијум 2022. године одржан је 15. маја.

1. задатак

Поставка

Решити проблем Читалаца и писаца (Readers/Writers) користећи мониторе са дисциплином Signal and Continue. Проблем решити користећи технику прослеђивања услова (Passing the Condition). Монитор треба да поседује 4 методе: lockShared() — желим да читам, lockExclusive() — желим да пишем, unlock() — завршавам, и upgradeLock() — са читања прелазим на писање.

Решење

class ReadersWriters {
    private int readers = 0;
    private int writers = 0;
    private int ticket = 1;
    private Condition okToRead = new Condition();
    private Condition okToWrite = new Condition();
    public synchronized void lockShared() {
        if (writers == 0 && okToWrite.empty()) {
            ++readers;
        } else {
            okToRead.wait(ticket++);
        }
    }
    public synchronized void lockExclusive() {
        if (readers == 0 && writers == 0) {
            ++writers;
        } else {
            okToWrite.wait(ticket++);
        }
    }
    public synchronized void unlock() {
        if (readers > 0) {
            if (--readers == 0 && okToWrite.queue()) {
                writers = 1;
                okToWrite.signal();
            }
        } else {
            boolean readersNext = okToRead.queue() && (okToWrite.empty() || okToRead.minrank() < okToWrite.minrank());
            boolean writersNext = okToWrite.queue() && (okToRead.empty() || okToWrite.minrank() < okToRead.minrank());
            if (readersNext) {
                while (okToRead.queue() && okToRead.minrank() < okToWrite.minrank()) {
                    ++readers;
                    okToRead.signal();
                }
            } else if (writersNext) {
                okToWrite.signal();
            } else {
                writers = 0;
            }
        }
    }
    public synchronized void upgradeLock() {
        if (readers == 1) {
            // Ако је само један читалац, конвертуј га у писца
            readers = 0;
            writers = 1;
        } else {
            // У супротном, мораће да сачека остале читаоце и писце како би постао писац
            unlock();
            lockExclusive();
        }
    }
}

2. задатак

Поставка

На обали реке се налази чамац који може да прими тачно десет путника. Чамац могу да користе мушкарци, жене и деца. Чамац може да исплови само ако се у њему налази тачно онолико путника колики му је капацитет, али само под условом да се у чамцу налазе бар два мушкарца. Деца не смеју ући у чамац уколико се у њему не налазе бар једна одрасла особа и по завршетку вожње у чамцу не смеју да остану само деца. Сматрати да ће се[sic] чамац након искрцавања свих путника одмах бити спреман да прими наредну групу путника. Користећи регионе написати програм који решава овај проблем.

Решење

struct Boat {
    // Број мушкараца, жена и деце
    int men = 0;
    int women = 0;
    int children = 0;
    // Да ли је вожња готова (да ли је у току искрцавање)
    bool done;
    // Помоћне методе
    int total() {
        return men + women + children;
    }
    int adults() {
        return men + women;
    }
};
Boat boat;

void boatP() {
    while (true) {
        region (boat) {
            boat.done = false;
            await (boat.total() == 10 && boat.men >= 2);
        }
        // Вожња
        region (boat) {
            boat.done = true;
            await (boat.total() == 0);
        }
    }
}

void man() {
    while (true) {
        region (boat) {
            await (!boat.done);
            if (boat.total() < 10) {
                ++boat.men;
                break;
            } else {
                // Нисмо се укрцали, чекамо да се заврши вожња па поново
                await (boat.done);
            }
        }
    }
    // Укрцани смо
    region (boat) {
        await (boat.done);
        // Ако смо последњи одрасли, чекамо да сва деца изађу
        if (boat.adults() == 1 && boat.children > 0) {
            await (boat.children == 0);
        }
        --boat.men;
    }
}

void woman() {
    while (true) {
        region (boat) {
            await (!boat.done);
            if (boat.total() < 10 && boat.total() - boat.men >= 2) {
                ++boat.women;
                break;
            } else {
                // Нисмо се укрцали, чекамо да се заврши вожња па поново
                await (boat.done);
            }
        }
    }
    // Укрцани смо
    region (boat) {
        await (boat.done);
        // Ако смо последњи одрасли, чекамо да сва деца изађу
        if (boat.adults() == 1 && boat.children > 0) {
            await (boat.children == 0);
        }
        --boat.women;
    }
}

void child() {
    while (true) {
        region (boat) {
            await (!boat.done);
            if (boat.total() < 10 && boat.total() - boat.men >= 2 && boat.adults() > 0) {
                ++boat.children;
                break;
            } else {
                // Нисмо се укрцали, чекамо да се заврши вожња па поново
                await (boat.done);
            }
        }
    }
    // Укрцани смо
    region (boat) {
        await (boat.done);
        --boat.children;
    }
}