yipo
9/12/2017 - 4:44 PM

uva706

LC-Display

#include <bitset>
#include <functional>
#include <iostream>
#include <string>
#include <tuple>
#include <vector>
using namespace std;

class lcd
{
public:
    static string display(size_t size, const string &number)
    {
        return lcd(size, number).to_string();
    }

private:
    class digit
    {
        typedef bitset<7> segments;

    public:
        digit(char ch) : m_seg(get_segments(ch - '0'))
        {
        }

        //  -a-
        // f   b
        //  -g-
        // e   c
        //  -d-

        bool a() const { return m_seg[0]; }
        bool b() const { return m_seg[1]; }
        bool c() const { return m_seg[2]; }
        bool d() const { return m_seg[3]; }
        bool e() const { return m_seg[4]; }
        bool f() const { return m_seg[5]; }
        bool g() const { return m_seg[6]; }

    private:
        const segments &m_seg;

    private:
        static const segments &get_segments(size_t d)
        {
            static const vector<segments> table =
            {
                segments("0111111"),
                segments("0000110"),
                segments("1011011"),
                segments("1001111"),
                segments("1100110"),
                segments("1101101"),
                segments("1111101"),
                segments("0000111"),
                segments("1111111"),
                segments("1101111"),
            };
            return table.at(d); // May throw std::out_of_range.
        }
    };

private:
    lcd(size_t size, const string &number) : m_size(size), m_number(number)
    {
    }

    string to_string() const
    {
        string buf;
        buf += scanline('-', [](const digit &d)
        {
            return make_tuple(false, d.a(), false);
        });
        buf += repeat(m_size, scanline('|', [](const digit &d)
        {
            return make_tuple(d.f(), false, d.b());
        }));
        buf += scanline('-', [](const digit &d)
        {
            return make_tuple(false, d.g(), false);
        });
        buf += repeat(m_size, scanline('|', [](const digit &d)
        {
            return make_tuple(d.e(), false, d.c());
        }));
        buf += scanline('-', [](const digit &d)
        {
            return make_tuple(false, d.d(), false);
        });
        return buf;
    }

    string scanline(char sign, function<tuple<bool, bool, bool>(const digit &d)> strategy) const
    {
        string line;
        for (const auto ch : m_number)
        {
            bool left, middle, right;
            tie(left, middle, right) = strategy(ch);
            line += string(line.empty() ? "" : " ") + (left ? sign : ' ') + string(m_size, middle ? sign : ' ') + (right ? sign : ' ');
        }
        return line + '\n';
    }

private:
    const size_t m_size;
    const string m_number;

private:
    static string repeat(size_t n, const string &str)
    {
        string buf;
        while (n--) buf += str;
        return buf;
    }
};

int main()
{
    size_t size;
    string number;
    while (cin >> size >> number)
    {
        if (size == 0) break;
        cout << lcd::display(size, number) << endl;
    }
    return 0;
}