Lawful Evil #5 – instrukcja retum

Nie byłem pewien, czy dodawać tę historię, ponieważ nie zakończyła się ona pełnym sukcesem, ale uznałem, że rozwiązanie na to zasługuje. Historia zaczęła się pewnego pięknego środowego popołudnia:

Hej koledzy z #programowanie #cpp Potrzebuje pilnej pomocy ! place jak za króla ;D Pisze własne kolosa mam czas do okooło 18:30 jest do drugi termin 🙁 Tresc zadania
1.Napisac program wykorzystujacy stos, ktory sprawdza czy w danym wyrazeniu nawiasy sa prawidlowo zagniezdzone. Przetestowac dzialanie na wyrazeniu ” [ [ ] [ [ ] [ [ ] ”

2.Opracowac rekurnecyjny algorytm pozwalajacy zamienic liczbe dziesietna na liczbe w systemie trojkowym. Sprawdzic dla liczby 123

Liczy na was 5 osob

Rozwiązałem tylko zadanie drugie – na pierwsze zabrakło czasu i pomysłu.

Przede wszystkim, zacznijmy od definicji awangardowej instrukcji retum:

#define retum throw

Teraz można zabrać się za implementację. Warto trochę pogeneralizować, i utworzyć funkcję pozwalającą ustalać podstawę rozwinięcia:

template<int Base>
string to_base(int value)
try
{
    to_base_impl<Base>(value);
    return {};
}
catch(return_value rv)
{
    return rv.val;
}

W funkcji to_base_impl można już użyć tercetu try, catch i retum:

template<int Base>
void to_base_impl(int value)
{
    try {
        if(value/Base)
            to_base_impl<Base>(value/Base);
        else
            retum return_value{};
    } catch(return_value rv) {
        rv.val += to_string(value % Base);
        retum rv;
    }
}

retum wymaga specjalnego typu zwracanego:

struct return_value : exception
{
    std::string val;
    char const* what() const noexcept override {
        return val.c_str();
    }
};

Czyli składając to wszystko do kupy:

#define retum throw
 
struct return_value : exception
{
    std::string val;
    char const* what() const noexcept override {
        return val.c_str();
    }
};
 
template<int Base>
void to_base_impl(int value)
{
    try {
        if(value/Base)
            to_base_impl<Base>(value/Base);
        else
            retum return_value{};
    } catch(return_value rv) {
        rv.val += to_string(value % Base);
        retum rv;
    }
}
 
template<int Base>
string to_base(int value)
try
{
    to_base_impl<Base>(value);
    return {};
}
catch(return_value rv)
{
    return rv.val;
}
 
int main()
{
    DBG(to_base<3>(1));
    DBG(to_base<3>(2));
    DBG(to_base<3>(3));
    DBG(to_base<3>(123));
}

[link]

4 thoughts on “Lawful Evil #5 – instrukcja retum

  1. Zadanie z nawiasami to klasyka informatyki na studiach 😀 Przy otwarciu nawiasu pushujemy na stos, a przy zamknieciu popujemy. Jezeli po zakonczeniu dzialania mamy pusty stos, a w trakcie nie probowalismy pobrac z niego wiecej niz bylo to znaczy, ze wszystko bylo w porzadku 😉

    1. Takie zadania otwarte są dziwne, nie wiadomo jak mają się zakończyć, zrobisz po swojemu, a potem się dowiesz że miało być inaczej tylko nie wiadomo jak, często na rozmowach rekrutacyjnych to stosują, mówię o tym 1 i do tego robisz na czas np: 15 – 20 minut, to z nawiasami jest łatwiejsze to pewnie 5 minut 😉 i nie wiem co to ma udowodnić.

  2. Nie wiem czemu wykładowcy to masochiści i babrają się w tym z C++ jak jest dużo lepszych rozwiązań xD

    1. Nie ma wielu lepszych rozwiązań od C++. Jest po prostu wiele osób, którym nie chce się zagłębić w możliwości jakie daje ten wspaniały język programowania. ; ) Choć porównanie dwóch zbiorów i zwrócenie wszystkich wspólnych elementów prościej jest wykonać skryptem *.py, używając kwargs…

Leave a Reply

Your email address will not be published.