Submission details
Task:Monikulmio
Sender:henri0
Submission time:2025-10-30 06:47:07 +0200
Language:C++ (C++17)
Status:READY
Result:62
Feedback
groupverdictscore
#162
Test results
testverdicttimescore
#1ACCEPTED0.00 s10details
#2ACCEPTED0.00 s10details
#3ACCEPTED0.00 s7details
#4ACCEPTED0.00 s7details
#5ACCEPTED0.00 s7details
#6ACCEPTED0.00 s7details
#7--0details
#8ACCEPTED0.00 s7details
#9ACCEPTED0.00 s7details
#10--0details

Compiler report

input/code.cpp: In member function 'void RenderSurface::Print()':
input/code.cpp:97:27: warning: comparison of integer expressions of different signedness: 'int' and 'size_t' {aka 'long unsigned int'} [-Wsign-compare]
   97 |         for (int y = 0; y < m_data.GetHeight(); ++y) {
      |                         ~~^~~~~~~~~~~~~~~~~~~~
input/code.cpp:98:31: warning: comparison of integer expressions of different signedness: 'int' and 'size_t' {aka 'long unsigned int'} [-Wsign-compare]
   98 |             for (int x = 0; x < m_data.GetWidth(); ++x) {
      |                             ~~^~~~~~~~~~~~~~~~~~~
input/code.cpp: In member function 'void RenderSurface::DrawShape(const std::vector<Vector2<int> >&)':
input/code.cpp:178:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<Vector2<int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  178 |         for (int i = 0; i < vertices.size(); ++i) {
      |                         ~~^~~~~~~...

Code

#include <iostream>
#include <string>
#include <sstream>
#include <memory>
#include <vector>
#include <cstdint>

template <typename T>
struct Vector2 {

    Vector2() = default;

    Vector2(T X, T Y)
        : x(X), y(Y) {}

    template <typename X>
    Vector2(const Vector2<X>& other)
        : x(static_cast<T>(other.x)), y(static_cast<T>(other.y)) {}

    T x, y;
};

using Vector2i = Vector2<int>;
using Vector2f = Vector2<float>;

template <typename T>
Vector2<T> operator+(const Vector2<T>& left, const Vector2<T>& right) {
    return Vector2<T>(left.x + right.x, left.y + right.y);
}

template <typename T>
bool operator==(const Vector2<T>& left, const Vector2<T>& right) {
    return left.x == right.x && left.y == right.y;
}

template <typename T>
Vector2<T> operator-(const Vector2<T>& left, const Vector2<T>& right) {
    return Vector2<T>(left.x - right.x, left.y - right.y);
}

template <typename T>
Vector2<T> operator*(const Vector2<T>& left, const Vector2<T>& right) {
    return Vector2<T>(left.x * right.x, left.y * right.y);
}

template <typename T>
Vector2<T> operator/(const Vector2<T>& left, const Vector2<T>& right) {
    return Vector2<T>(left.x / right.x, left.y / right.y);
}

template <typename T>
Vector2<T> Flip(const Vector2<T>& v) {
    return Vector2<T>(v.y, v.x);
}

template <typename T>
class Grid2D {
public:
    Grid2D(size_t width, size_t height, const T& fill = T()) 
        : m_width(width), m_height(height) 
    { m_data.resize(width * height, fill); }
        
    const T& At(size_t x, size_t y) const { return m_data.at(GetIndex(x, y)); }

    T& At(size_t x, size_t y) { return m_data.at(GetIndex(x, y));  }

    size_t GetWidth() const { return m_width; }

    size_t  GetHeight() const { return m_height; }

private:

    size_t GetIndex(size_t x, size_t y) const { return y * m_width + x; }

    std::vector<T> m_data;
    size_t m_width = 0;
    size_t m_height = 0;
};

enum CellState : uint8_t {
    Empty = 0,
    Point,
    LineHorizontal,
    LineVertical,
    LineRTilt,
    LineLTilt,
    Filled
};

class RenderSurface {
public:

    RenderSurface(size_t x, size_t y)
        : m_data(x, y, CellState::Empty) {}

    void Print() {
        for (int y = 0; y < m_data.GetHeight(); ++y) {
            for (int x = 0; x < m_data.GetWidth(); ++x) {
                CellState val = m_data.At(x, y);

                switch (val) {
                    case CellState::Empty:
                        std::cout << ".";
                        break;
                    case CellState::Point:
                        std::cout << "*";
                        break;
                    case CellState::LineHorizontal:
                        std::cout << "=";
                        break;
                    case CellState::LineVertical:
                        std::cout << "|";
                        break;
                    case CellState::LineRTilt:
                        std::cout << "/";
                        break;
                    case CellState::LineLTilt:
                        std::cout << "\\";
                        break;
                    case CellState::Filled:
                        std::cout << "#";
                        break;
                    default: 
                        break;
                }
            }
            std::cout << std::endl;
        }
    }

    void DrawLine(Vector2i start, Vector2i end) {
        m_data.At(start.x, start.y) = CellState::Point;
        m_data.At(end.x, end.y) = CellState::Point;

        // Horizontal line
        if (start.y == end.y) {
            for (int i = 0; i <= abs(start.x - end.x); ++i) {
                if (start.x < end.x) {
                    FillCell(start.x + i, start.y, CellState::LineHorizontal);
                } else {
                    FillCell(start.x - i, start.y, CellState::LineHorizontal);
                }
            }
        }

        // Vertical line
        else if (start.x == end.x) {
            for (int i = 0; i <= abs(start.y - end.y); ++i) {
                if (start.y > end.y) {
                    FillCell(start.x, start.y - i, CellState::LineVertical);
                } else {
                    FillCell(start.x, start.y + i, CellState::LineVertical);
                }
                
            }
        }

        // Tilted line
        else {
            Vector2i from = start.y < end.y ? start : end;
            Vector2i to = from == start ? end : start;

            Vector2i pos = from;

            for (int i = 0; i < abs(start.x - end.x) && i < abs(start.y - end.y); ++i) {
                if (from.x < to.x) {
                    pos = pos + Vector2i(1, 1);
                    FillCell(pos.x, pos.y, CellState::LineLTilt);
                } else {
                    pos = pos + Vector2i(-1, 1);
                    FillCell(pos.x, pos.y, CellState::LineRTilt);
                }
            }
        }
    }

    void DrawShape(const std::vector<Vector2i>& vertices) {
        for (int i = 0; i < vertices.size(); ++i) {
            if (i + 1 < vertices.size()) {
                DrawLine(vertices.at(i), vertices.at(i+1));
            }
        }
        DrawLine(vertices.front(), vertices.back());
    }

    void FillShape() {
        for (int y = 0; y < m_data.GetHeight(); ++y) {
            /*int begin = -1;
            int end = 0;
            for (int x = 0; x < m_data.GetWidth(); ++x) {
                CellState state = m_data.At(x, y);
                if (state != CellState::Empty) {
                    if (begin == -1) begin = x;
                    end = x;
                }
            }
            for (int i = abs(begin); i < end; ++i) {
                FillCell(i, y, CellState::Filled);
            }*/
            bool stop = false;
            int prevEnd = 0;
            while (!stop) {
            

            int begin = -1;
            int end = -1;

            for (int i = prevEnd; i < m_data.GetWidth(); ++i) {
                if (m_data.At(i, y) == CellState::Point || 
                    m_data.At(i, y) == CellState::LineVertical || 
                    m_data.At(i, y) == CellState::LineRTilt ||
                    m_data.At(i, y) == CellState::LineLTilt) 
                {
                    if (begin == -1) {
                        begin = i;
                    } else {
                        end = i;
                        break;
                    }
                }
                if (i == m_data.GetWidth()-1) {
                    stop = true;
                }
            }
            if (begin != -1 && end != -1) {
                for (int i = begin; i < end; ++i) {
                    FillCell(i, y, CellState::Filled);
                }
                prevEnd = end+1;
            }
            
            }
        }
    }

    void FillCell(size_t x, size_t y, CellState state) {
        if (m_data.At(x,y) == CellState::Empty) m_data.At(x,y) = state;
    } 

    Grid2D<CellState> m_data;

};

void ReadSurInfo(const std::string& line, int* width, int* height, int* numvx) {
    std::stringstream ss(line);
    std::string token;

    std::getline(ss, token, ' ');
    *height = std::stoi(token);

    std::getline(ss, token, ' ');
    *width = std::stoi(token);

    std::getline(ss, token, ' ');
    *numvx = std::stoi(token);
}

Vector2i ReadVertex(const std::string& line) {
    std::stringstream ss(line);
    std::string token;

    Vector2i result(0, 0);

    std::getline(ss, token, ' ');
    result.y = std::stoi(token)-1;

    std::getline(ss, token, ' ');
    result.x = std::stoi(token)-1;

    return result;
}

int main() {

    std::string shapeInfoInput;
    std::getline(std::cin, shapeInfoInput);

    int width = 0;
    int height = 0;
    int numvx = 0;

    ReadSurInfo(shapeInfoInput, &width, &height, &numvx);

    std::vector<Vector2i> vertices;
    for (int i = 0; i < numvx; ++i) {
        std::string vxline;
        std::getline(std::cin, vxline);
        vertices.push_back(ReadVertex(vxline));
    }

    RenderSurface sur(width, height);

    // muista -1
    sur.DrawShape(vertices);

    sur.FillShape();

    sur.Print();


    return 0;
}

Test details

Test 1 (public)

Verdict: ACCEPTED

input
8 9 5
5 2
2 5
5 8
7 8
...

correct output
.........
....*....
.../#\...
../###\..
.*#####*.
...

user output
.........
....*....
.../#\...
../###\..
.*#####*.
...

Test 2 (public)

Verdict: ACCEPTED

input
20 40 4
5 10
5 30
15 30
15 10

correct output
.................................

user output
.................................

Test 3 (public)

Verdict: ACCEPTED

input
20 40 29
8 7
13 2
14 2
9 7
...

correct output
.................................

user output
.................................

Feedback: Lines are drawn correctly. Incorrect fill character on row 3, col 31: expected '.', got '#'

Test 4 (public)

Verdict: ACCEPTED

input
20 40 14
5 12
5 25
8 28
13 28
...

correct output
.................................

user output
.................................

Feedback: Lines are drawn correctly. Incorrect fill character on row 16, col 26: expected '#', got '.'

Test 5 (public)

Verdict: ACCEPTED

input
20 40 12
3 20
7 16
7 9
11 13
...

correct output
.................................

user output
.................................

Feedback: Lines are drawn correctly. Incorrect fill character on row 7, col 17: expected '#', got '.'

Test 6 (public)

Verdict: ACCEPTED

input
9 35 33
2 3
2 8
4 8
4 5
...

correct output
.................................

user output
.................................

Feedback: Lines are drawn correctly. Incorrect fill character on row 4, col 9: expected '.', got '#'

Test 7 (public)

Verdict:

input
30 100 69
6 10
6 14
7 14
7 18
...

correct output
.................................

user output
(empty)

Test 8 (public)

Verdict: ACCEPTED

input
40 60 192
11 3
11 5
10 6
11 7
...

correct output
.................................

user output
.................................

Feedback: Lines are drawn correctly. Incorrect fill character on row 3, col 30: expected '#', got '.'

Test 9 (public)

Verdict: ACCEPTED

input
50 100 142
1 1
1 7
1 11
1 14
...

correct output
*=====*===*==*...................

user output
*=====*===*==*...................

Feedback: Lines are drawn correctly. Incorrect fill character on row 2, col 11: expected '#', got '.'

Test 10 (public)

Verdict:

input
100 100 1000
10 1
4 7
1 4
1 9
...

correct output
...*====*........................

user output
(empty)