library

This documentation is automatically generated by online-judge-tools/verification-helper

View the Project on GitHub rajyan/library

:heavy_check_mark: test/own/Matrix2D_Basic.test.cpp

Depends on

Code

#define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ITP1_1_A"

#include "../../src/makevec.hpp"
#include "../../src/Matrix2D.hpp"

#include <cassert>
#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>

using namespace std;
using lint = long long;

struct init {
    init() {
        cin.tie(nullptr);
        ios::sync_with_stdio(false);
        cout << fixed << setprecision(10);
    }
} init_;

int main() {

    // default constructor
    mat M1;
    assert(M1.r0 == pnt{} && M1.r1 == pnt{});
    // constructor
    mat M2(pnt(1, 2), pnt(3, 4));
    assert(M2.r0 == pnt(1, 2) && M2.r1 == pnt(3, 4));
    // initializer_list construct, == operator
    mat M3{{1, 2},
           {3, 4}};
    assert(M3 == M2);
    // copy constructor, == operator
    mat M4 = M3;
    assert(M4 == M3);
    // vector, implicit conversion
    vector<mat> v(10);
    assert(all_of(v.begin(), v.end(), [](const mat &m) { return m == mat{}; }));
    // +=, + operator
    mat M5{{1, 2},
           {3, 4}};
    mat M6{{1, 2},
           {3, 4}};
    assert(M5 + M6 == mat({2, 4}, {6, 8}));
    M5 += M6;
    assert(M5 == mat({2, 4}, {6, 8}));
    // -=, -, - pnt operator
    mat M7{};
    mat M8{{-1, 0},
           {-4, 3}};
    assert(M7 - M8 == -M8);
    M7 -= M8;
    assert(M7 == -M8);
    // *=, * operator
    mat M9{{1, 2},
           {3, 4}};
    mat M10{{0, 1},
            {2, 3}};
    assert(M9 * M10 == mat({4, 7}, {8, 15}));
    M9 *= M10;
    assert(M9 == mat({4, 7}, {8, 15}));
    // mat * pnt operator
    mat M11{{1, 2},
            {3, 4}};
    pnt p{1, 2};
    assert(M11 * p == pnt(5, 11));
    // transpose
    mat M12{{0, 2},
            {3, 5}};
    assert(M12.trans() == mat({0, 3}, {2, 5}));
    // identity
    mat M13{{5, 1},
            {4, 2}};
    assert(mat().identity() == mat({1, 0}, {0, 1}));
    assert(M13 * mat().identity() == M13);
    // power
    mat M14{{1, 2},
            {3, 4}};
    assert(M14.pow(2) == M14 * M14);
    assert(M14.pow(5) == M14 * M14 * M14 * M14 * M14);
    // determinant
    assert(M14.det() == -2);

    //// test constexpr

    // default constructor
    constexpr mat CM1;
    static_assert(CM1.r0 == pnt{} && CM1.r1 == pnt{});
    // constructor
    constexpr mat CM2(pnt(1, 2), pnt(3, 4));
    static_assert(CM2.r0 == pnt(1, 2) && CM2.r1 == pnt(3, 4));
    // initializer_list construct, == operator
    constexpr mat CM3{{1, 2},
                      {3, 4}};
    static_assert(CM3 == CM2);
    // copy constructor, == operator
    constexpr mat CM4 = CM3;
    static_assert(CM4 == CM3);
    // array, implicit conversion
    constexpr mat cv[5];
    static_assert(cv[0] == mat{});
    static_assert(cv[1] == mat{});
    static_assert(cv[2] == mat{});
    static_assert(cv[3] == mat{});
    static_assert(cv[4] == mat{});
    // +=, + operator
    constexpr mat CM5{{1, 2},
                      {3, 4}};
    constexpr mat CM6{{3, 5},
                      {2, 1}};
    static_assert(CM5 + CM6 == mat({4, 7}, {5, 5}));
    constexpr auto additionAssign = [=]() {
        mat res = CM5;
        res += CM6;
        return res;
    };
    static_assert(additionAssign() == mat({4, 7}, {5, 5}));
    // -=, -, - pnt operator
    constexpr mat CM7{};
    constexpr mat CM8{{-1, 0},
                      {-4, 3}};
    static_assert(CM7 - CM8 == -CM8);
    constexpr auto subtractionAssign = [=]() {
        mat res = CM7;
        res -= CM8;
        return res;
    };
    static_assert(subtractionAssign() == -CM8);
    // *=, * operator
    constexpr mat CM9{{1, 2},
                      {3, 4}};
    constexpr mat CM10{{0, 1},
                       {2, 3}};
    static_assert(CM9 * CM10 == mat({4, 7}, {8, 15}));
    constexpr auto multiplicationAssign = [=]() {
        mat res = CM9;
        res *= CM10;
        return res;
    };
    static_assert(multiplicationAssign() == mat({4, 7}, {8, 15}));
    // mat * pnt operator
    constexpr mat CM11{{1, 2},
                       {3, 4}};
    constexpr pnt cp{1, 2};
    static_assert(CM11 * cp == pnt(5, 11));
    // transpose
    constexpr mat CM12{{0, 2},
                       {3, 5}};
    static_assert(CM12.trans() == mat({0, 3}, {2, 5}));
    // identity
    constexpr mat CM13{{5, 1},
                       {4, 2}};
    static_assert(mat().identity() == mat({1, 0}, {0, 1}));
    static_assert(CM13 * mat().identity() == CM13);
    // power
    constexpr mat CM14{{1, 2},
                       {3, 4}};
    static_assert(CM14.pow(2) == CM14 * CM14);
    static_assert(CM14.pow(5) == CM14 * CM14 * CM14 * CM14 * CM14);
    // determinant
    static_assert(CM14.det() == -2);

    cout << "Hello World\n";

    return 0;
}
#line 1 "test/own/Matrix2D_Basic.test.cpp"

#define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ITP1_1_A"

#line 2 "src/makevec.hpp"

#include <vector>

using namespace std;

template<class T>
vector<T> make_vec(size_t s, T val) { return vector<T>(s, val); }
template<class... Size>
auto make_vec(size_t s, Size... tail) {
    return vector<decltype(make_vec(tail...))>(s, make_vec(tail...));
}
#line 2 "src/Matrix2D.hpp"

#line 2 "src/Point2D.hpp"

#include <cmath>
#include <iostream>
#line 6 "src/Point2D.hpp"

using namespace std;
using lint = long long;

template<class T>
struct Point2D {
    T x{}, y{};

    constexpr Point2D() = default;
    constexpr Point2D(const T &x, const T &y) noexcept: x(x), y(y) {};
    constexpr explicit Point2D(const pair<T, T> &p) noexcept: x(p.first), y(p.second) {};

    constexpr bool operator==(const Point2D &rhs) const noexcept { return x == rhs.x && y == rhs.y; }
    constexpr bool operator!=(const Point2D &rhs) const noexcept { return !(*this == rhs); }
    constexpr bool operator<(const Point2D &rhs) const noexcept { return x < rhs.x || (x == rhs.x && y < rhs.y); }
    constexpr bool operator>(const Point2D &rhs) const noexcept { return rhs < *this; }
    constexpr bool operator<=(const Point2D &rhs) const noexcept { return !(*this > rhs); }
    constexpr bool operator>=(const Point2D &rhs) const noexcept { return !(*this < rhs); }

    constexpr Point2D operator+(const Point2D &rhs) const noexcept { return {x + rhs.x, y + rhs.y}; }
    constexpr Point2D operator-(const Point2D &rhs) const noexcept { return {x - rhs.x, y - rhs.y}; }
    constexpr Point2D operator*(const T &k) const noexcept { return {k * x, k * y}; }
    constexpr Point2D operator/(const T &k) const noexcept { return {x / k, y / k}; }
    constexpr Point2D &operator+=(const Point2D &rhs) noexcept { return *this = *this + rhs; }
    constexpr Point2D &operator-=(const Point2D &rhs) noexcept { return *this = *this - rhs; }
    constexpr Point2D &operator*=(const T &k) noexcept { return *this = *this * k; }
    constexpr Point2D &operator/=(const T &k) noexcept { return *this = *this / k; }
    constexpr Point2D &operator--() noexcept { return *this -= Point2D(1, 1); };
    constexpr Point2D &operator++() noexcept { return *this += Point2D(1, 1); };
    constexpr Point2D operator--(int) noexcept { Point2D res = *this; --*this; return res; };
    constexpr Point2D operator++(int) noexcept { Point2D res = *this; ++*this; return res; };
    constexpr Point2D operator-() const noexcept { return {-x, -y}; }

    constexpr T operator*(const Point2D &rhs) const noexcept { return x * rhs.x + y * rhs.y; }

    [[nodiscard]] constexpr Point2D nor() const noexcept { return {y, -x}; }
    [[nodiscard]] constexpr long double hypot() const noexcept { return ::hypotl(x, y); }
    [[nodiscard]] constexpr bool inGrid(const T &H, const T &W) const noexcept { return 0 <= x && x < H && 0 <= y && y < W; }
    template<class U>
    [[nodiscard]] constexpr U &operator[](vector<vector<U>> &v) const noexcept { return v[x][y]; }

    constexpr friend istream &operator>>(istream &is, Point2D &p) { return is >> p.x >> p.y; }
    constexpr friend ostream &operator<<(ostream &os, const Point2D &p) { return os << p.x << ' ' << p.y; }
};

using pnt = Point2D<lint>;
#line 4 "src/Matrix2D.hpp"

template<class T>
struct Matrix2D {
    Point2D<T> r0{}, r1{};

    constexpr Matrix2D() = default;
    constexpr Matrix2D(const Point2D<T> &r0_, const Point2D<T> &r1_) noexcept: r0(r0_), r1(r1_) {};
    constexpr explicit Matrix2D(const T &diag) noexcept: r0{diag, 0}, r1{0, diag} {}

    constexpr bool operator==(const Matrix2D &rhs) const noexcept { return r0 == rhs.r0 && r1 == rhs.r1; }
    constexpr bool operator!=(const Matrix2D &rhs) const noexcept { return !(*this == rhs); }

    constexpr Matrix2D operator+(const Matrix2D &rhs) const noexcept { return {r0 + rhs.r0, r1 + rhs.r1}; }
    constexpr Matrix2D operator-(const Matrix2D &rhs) const noexcept { return {r0 - rhs.r0, r1 - rhs.r1}; }
    constexpr Matrix2D operator*(const Matrix2D &rhs) const noexcept {
        const Matrix2D rhs_T = rhs.trans();
        return {{r0 * rhs_T.r0, r0 * rhs_T.r1},
                {r1 * rhs_T.r0, r1 * rhs_T.r1}};
    }
    constexpr Matrix2D &operator+=(const Matrix2D &rhs) noexcept { return *this = *this + rhs; }
    constexpr Matrix2D &operator-=(const Matrix2D &rhs) noexcept { return *this = *this - rhs; }
    constexpr Matrix2D &operator*=(const Matrix2D &rhs) noexcept { return *this = *this * rhs; }
    constexpr Matrix2D operator-() const noexcept { return {-r0, -r1}; }

    constexpr Point2D<T> operator*(const Point2D<T> &b_T) const noexcept { return {r0 * b_T, r1 * b_T}; }

    [[nodiscard]] constexpr Matrix2D trans() const noexcept {
        return {{r0.x, r1.x},
                {r0.y, r1.y}};
    }
    [[nodiscard]] constexpr Matrix2D identity() const noexcept { return Matrix2D{T{1}}; }
    [[nodiscard]] constexpr Matrix2D pow(lint n) const noexcept {
        Matrix2D res{Matrix2D{}.identity()}, tmp{*this};
        while (n > 0) {
            if (n & 1) res *= tmp;
            tmp *= tmp;
            n >>= 1;
        }
        return res;
    }
    [[nodiscard]] constexpr T det() const noexcept { return r0 * r1.nor(); }
};

using mat = Matrix2D<lint>;
#line 6 "test/own/Matrix2D_Basic.test.cpp"

#include <cassert>
#line 9 "test/own/Matrix2D_Basic.test.cpp"
#include <iomanip>
#line 11 "test/own/Matrix2D_Basic.test.cpp"
#include <algorithm>

using namespace std;
using lint = long long;

struct init {
    init() {
        cin.tie(nullptr);
        ios::sync_with_stdio(false);
        cout << fixed << setprecision(10);
    }
} init_;

int main() {

    // default constructor
    mat M1;
    assert(M1.r0 == pnt{} && M1.r1 == pnt{});
    // constructor
    mat M2(pnt(1, 2), pnt(3, 4));
    assert(M2.r0 == pnt(1, 2) && M2.r1 == pnt(3, 4));
    // initializer_list construct, == operator
    mat M3{{1, 2},
           {3, 4}};
    assert(M3 == M2);
    // copy constructor, == operator
    mat M4 = M3;
    assert(M4 == M3);
    // vector, implicit conversion
    vector<mat> v(10);
    assert(all_of(v.begin(), v.end(), [](const mat &m) { return m == mat{}; }));
    // +=, + operator
    mat M5{{1, 2},
           {3, 4}};
    mat M6{{1, 2},
           {3, 4}};
    assert(M5 + M6 == mat({2, 4}, {6, 8}));
    M5 += M6;
    assert(M5 == mat({2, 4}, {6, 8}));
    // -=, -, - pnt operator
    mat M7{};
    mat M8{{-1, 0},
           {-4, 3}};
    assert(M7 - M8 == -M8);
    M7 -= M8;
    assert(M7 == -M8);
    // *=, * operator
    mat M9{{1, 2},
           {3, 4}};
    mat M10{{0, 1},
            {2, 3}};
    assert(M9 * M10 == mat({4, 7}, {8, 15}));
    M9 *= M10;
    assert(M9 == mat({4, 7}, {8, 15}));
    // mat * pnt operator
    mat M11{{1, 2},
            {3, 4}};
    pnt p{1, 2};
    assert(M11 * p == pnt(5, 11));
    // transpose
    mat M12{{0, 2},
            {3, 5}};
    assert(M12.trans() == mat({0, 3}, {2, 5}));
    // identity
    mat M13{{5, 1},
            {4, 2}};
    assert(mat().identity() == mat({1, 0}, {0, 1}));
    assert(M13 * mat().identity() == M13);
    // power
    mat M14{{1, 2},
            {3, 4}};
    assert(M14.pow(2) == M14 * M14);
    assert(M14.pow(5) == M14 * M14 * M14 * M14 * M14);
    // determinant
    assert(M14.det() == -2);

    //// test constexpr

    // default constructor
    constexpr mat CM1;
    static_assert(CM1.r0 == pnt{} && CM1.r1 == pnt{});
    // constructor
    constexpr mat CM2(pnt(1, 2), pnt(3, 4));
    static_assert(CM2.r0 == pnt(1, 2) && CM2.r1 == pnt(3, 4));
    // initializer_list construct, == operator
    constexpr mat CM3{{1, 2},
                      {3, 4}};
    static_assert(CM3 == CM2);
    // copy constructor, == operator
    constexpr mat CM4 = CM3;
    static_assert(CM4 == CM3);
    // array, implicit conversion
    constexpr mat cv[5];
    static_assert(cv[0] == mat{});
    static_assert(cv[1] == mat{});
    static_assert(cv[2] == mat{});
    static_assert(cv[3] == mat{});
    static_assert(cv[4] == mat{});
    // +=, + operator
    constexpr mat CM5{{1, 2},
                      {3, 4}};
    constexpr mat CM6{{3, 5},
                      {2, 1}};
    static_assert(CM5 + CM6 == mat({4, 7}, {5, 5}));
    constexpr auto additionAssign = [=]() {
        mat res = CM5;
        res += CM6;
        return res;
    };
    static_assert(additionAssign() == mat({4, 7}, {5, 5}));
    // -=, -, - pnt operator
    constexpr mat CM7{};
    constexpr mat CM8{{-1, 0},
                      {-4, 3}};
    static_assert(CM7 - CM8 == -CM8);
    constexpr auto subtractionAssign = [=]() {
        mat res = CM7;
        res -= CM8;
        return res;
    };
    static_assert(subtractionAssign() == -CM8);
    // *=, * operator
    constexpr mat CM9{{1, 2},
                      {3, 4}};
    constexpr mat CM10{{0, 1},
                       {2, 3}};
    static_assert(CM9 * CM10 == mat({4, 7}, {8, 15}));
    constexpr auto multiplicationAssign = [=]() {
        mat res = CM9;
        res *= CM10;
        return res;
    };
    static_assert(multiplicationAssign() == mat({4, 7}, {8, 15}));
    // mat * pnt operator
    constexpr mat CM11{{1, 2},
                       {3, 4}};
    constexpr pnt cp{1, 2};
    static_assert(CM11 * cp == pnt(5, 11));
    // transpose
    constexpr mat CM12{{0, 2},
                       {3, 5}};
    static_assert(CM12.trans() == mat({0, 3}, {2, 5}));
    // identity
    constexpr mat CM13{{5, 1},
                       {4, 2}};
    static_assert(mat().identity() == mat({1, 0}, {0, 1}));
    static_assert(CM13 * mat().identity() == CM13);
    // power
    constexpr mat CM14{{1, 2},
                       {3, 4}};
    static_assert(CM14.pow(2) == CM14 * CM14);
    static_assert(CM14.pow(5) == CM14 * CM14 * CM14 * CM14 * CM14);
    // determinant
    static_assert(CM14.det() == -2);

    cout << "Hello World\n";

    return 0;
}
Back to top page