Help in Convex Hull

I am trying to solve this problem (just convex hull with Graham’s scan). My code doesn’t even pass the sample test case. I get three points instead of four. I can’t find the error in my implementation. Can someone please help me fix it?

Code
#include <bits/stdc++.h>
 
using namespace std;
 
#define ll long long
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define pb push_back
#define eb emplace_back
#define F first
#define S second
#define mp make_pair
 
template <typename Container>
void print(Container& container)
{
    auto Start = container.begin(), End = container.end();
    while (Start != End) cout << *(Start++) << " ";
    cout << '\n';
}

typedef double ftype;

struct point {
    ftype x, y;
    point() {};
    point(int x, int y) : x(x), y(y) {}

    point& operator += (const point& t) {
        x += t.x;
        y += t.y;
        return *this;
    }

    point& operator -= (const point& t) {
        x -= t.x;
        y -= t.y;
        return *this;
    }

    point& operator *= (ftype t) {
        x *= t;
        y *= t;
        return *this;
    }

    point& operator /= (ftype t) {
        x /= t;
        y /= t;
        return *this;
    }

    point operator + (const point& t) const {
        return point(*this) += t;
    }

    point operator - (const point& t) const {
        return point(*this) -= t;
    }

    point operator * (ftype t) const {
        return point(*this) *= t;
    }

    point operator / (ftype t) const {
        return point(*this) /= t;
    }
};

ftype cross(point a, point b) {
    return a.x * b.y - a.y * b.x;
}

ftype signed_area_parallelogram(point a, point b, point c) {
    return cross(b - a, c - b);
}

bool clockwise(point a, point b, point c) {
    return signed_area_parallelogram(a, b, c) < 0;
}

bool counter_clockwise(point a, point b, point c) {
    return signed_area_parallelogram(a, b, c) > 0;
}

bool cmp(point& a, point& b) {
    return a.x < b.x || (a.x == b.x && a.y < b.y);
}

void convex_hull(vector <point>& a) {
    if (a.size() == 1) return;
    sort(a.begin(), a.end(), cmp);
    point p1 = a.front(), p2 = a.back();
    vector <point> up, down;
    up.push_back(p1);
    down.push_back(p1);
    for (int i = 1; i < (int)a.size(); ++i) {
        if (i == (int)a.size() - 1 || clockwise(p1, a[i], p2)) {
            while ((int)up.size() >= 2 && !clockwise(up[(int)up.size() - 2], up[(int)up.size() - 1], a[i])) up.pop_back();
            up.push_back(a[i]);
        }
        if (i == (int)a.size() - 1 || counter_clockwise(p1, a[i], p2)) {
            while ((int)down.size() >= 2 && !counter_clockwise(down[(int)down.size() - 2], down[(int)down.size() - 1], a[i])) down.pop_back();
            down.push_back(a[i]);
        }
    }
    a.clear();
    for (int i = 0; i < (int)up.size(); ++i) a.push_back(up[i]);
    for (int i = (int)down.size() - 2; i > 0; --i) a.push_back(up[i]);
}

inline void solve()
{
    int n;
    cin >> n;
    vector <point> points(n);
    for (auto& [x, y] : points) cin >> x >> y;
    convex_hull(points);
    cout << points.size() << '\n';
    for (const auto& [x, y] : points) cout << x << " " << y << '\n';
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int t = 1;
    while (t--) solve();
}

If you prefer a link: click

Here, points A, D, and C are collinear. So D doesn’t get added in the convex hull.


How to fix this?