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]

One thought 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 😉

Leave a Reply

Your email address will not be published.