//https://w...content-available-to-author-only...t.com/r/dailyprogrammer/comments/5st2so/20170208_challenge_302_intermediate_ascii/

#include <iostream>
#include <vector>

class histogram_t
{
public:
    histogram_t()
        : m_bar_width( 10 )
    {}
    histogram_t( const std::pair< int, int > xrange, const std::pair< int, int >yrange )
            : m_bar_width( 10 ),
              m_width_min( xrange.first ),
              m_width_max( xrange.second ),
              m_height_max( yrange.second ),
              m_height_min( yrange.first )
    {
        create_and_init_bars();
    }
    void print( const char marker = '*')
    {

        int fwidth = get_format_width();

        for( int height = 0; height <= m_height_max; height++ )
        {
            printf( "%*d|",fwidth , m_height_max - height );
            if ( height != m_height_max )
            {
                for ( int width = 0; width < m_bars.size(); width++ )
                {
                    printf( "%*.c", fwidth + 1, ( m_bars[width] < m_height_max - height ? ' ' : marker ) );
                }
                std::cout << std::endl;
            }
            else
            {

                for ( int width = 0; width <= m_bars.size(); width++ )
                {
                    printf("%*d ", fwidth, m_width_min + ( width * m_bar_width ) );
                }
            }
        }


    }
    void set_height( const std::pair< int, int > range )
    {
        m_height_max = range.second;
        m_height_min = range.first;
    }
    void set_width( const std::pair< int, int > range )
    {
        m_width_max = range.second;
        m_width_min = range.first;
        create_and_init_bars();
    }

    void add_data( std::vector<std::pair<int,int>> values )
    {
        std::vector<std::pair<int, int>>::iterator it;
        for( it = values.begin(); it != values.end(); it++ )
        {
            add_data( *it );
        }
    }
    void add_data( std::pair<int, int> data )
    {
        add_data( data.first, data.second );
    }

protected:
    int calculate_bar( const int number ) const { return ( number - m_width_min )  / m_bar_width; }
    void create_and_init_bars( void )
    {
        m_bars.clear();
        int barn = ( m_width_max - m_width_min ) / m_bar_width;
        for( int i = 0; i < barn; i++ )
        {
            m_bars.push_back( 0 );
        }
    }
    int get_format_width( void )
    {
        int max = m_width_max;
        int rc = 0;
        while( max > 0)
        {
            rc++;
            max /= 10;
        }
        return rc;
    }
    void add_data( const int bar, const int frequency )
    {
        m_bars[ calculate_bar( bar ) ] += frequency;
    }
    const int m_bar_width;
    int m_height_min,
    m_height_max,
    m_width_min,
    m_width_max;
    std::vector<int> m_bars;

};

int main ()
{
    histogram_t h( { 0, 50 }, { 1,10 } );
    h.add_data({ { 0, 1 }, { 10, 3 }, { 20, 6 }, { 30, 4 }, { 40, 2 } } );
    h.print( '|' );
    return 0;
}