Impl n_to_one and one_to_n (up to 4) with tests

This commit is contained in:
Stephen Seo 2021-06-08 21:44:22 +09:00
parent 3f85a1cb77
commit 8febe36276
8 changed files with 688 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
UnitTests
src/*.o
src/tests/*.o

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "third_party/Catch2"]
path = third_party/Catch2
url = https://github.com/catchorg/Catch2.git

14
Makefile Normal file
View File

@ -0,0 +1,14 @@
CFLAGS = -Wall -Wextra -Wpedantic
CXXFLAGS = -Wall -Wextra -Wpedantic -Ithird_party/Catch2/single_include/catch2
all: UnitTests
UnitTests: src/n_to_one.o src/tests/test_main.o src/tests/test_n_to_one.o
$(CXX) $(CXXFLAGS) -o UnitTests $^
.PHONY:
clean:
rm -f UnitTests
rm -f src/*.o
rm -f src/tests/*.o

125
src/n_to_one.c Normal file
View File

@ -0,0 +1,125 @@
#include "n_to_one.h"
unsigned long two_to_one(
unsigned long x,
unsigned long y,
unsigned long x_width) {
return x + y * x_width;
}
void one_to_two(
unsigned long idx,
unsigned long *x,
unsigned long *y,
unsigned long x_width) {
*x = idx % x_width;
*y = idx / x_width;
}
unsigned long three_to_one(
unsigned long x,
unsigned long y,
unsigned long z,
unsigned long x_width,
unsigned long y_width){
return x + y * x_width + z * x_width * y_width;
}
void one_to_three(
unsigned long idx,
unsigned long *x,
unsigned long *y,
unsigned long *z,
unsigned long x_width,
unsigned long y_width) {
*x = idx % x_width;
*y = (idx / x_width) % y_width;
*z = idx / x_width / y_width;
}
unsigned long four_to_one(
unsigned long x,
unsigned long y,
unsigned long z,
unsigned long i,
unsigned long x_width,
unsigned long y_width,
unsigned long z_width) {
return x + y * x_width + z * x_width * y_width + i * x_width * y_width * z_width;
}
void one_to_four(
unsigned long idx,
unsigned long *x,
unsigned long *y,
unsigned long *z,
unsigned long *i,
unsigned long x_width,
unsigned long y_width,
unsigned long z_width) {
*x = idx % x_width;
*y = (idx / x_width) % y_width;
*z = ((idx / x_width) / y_width) % z_width;
*i = ((idx / x_width) / y_width) / z_width;
}
unsigned long long two_to_one_l(
unsigned long long x,
unsigned long long y,
unsigned long long x_width) {
return x + y * x_width;
}
void one_to_two_l(
unsigned long long idx,
unsigned long long *x,
unsigned long long *y,
unsigned long long x_width) {
*x = idx % x_width;
*y = idx / x_width;
}
unsigned long long three_to_one_l(
unsigned long long x,
unsigned long long y,
unsigned long long z,
unsigned long long x_width,
unsigned long long y_width){
return x + y * x_width + z * x_width * y_width;
}
void one_to_three_l(
unsigned long long idx,
unsigned long long *x,
unsigned long long *y,
unsigned long long *z,
unsigned long long x_width,
unsigned long long y_width) {
*x = idx % x_width;
*y = (idx / x_width) % y_width;
*z = idx / x_width / y_width;
}
unsigned long long four_to_one_l(
unsigned long long x,
unsigned long long y,
unsigned long long z,
unsigned long long i,
unsigned long long x_width,
unsigned long long y_width,
unsigned long long z_width) {
return x + y * x_width + z * x_width * y_width + i * x_width * y_width * z_width;
}
void one_to_four_l(
unsigned long long idx,
unsigned long long *x,
unsigned long long *y,
unsigned long long *z,
unsigned long long *i,
unsigned long long x_width,
unsigned long long y_width,
unsigned long long z_width) {
*x = idx % x_width;
*y = (idx / x_width) % y_width;
*z = ((idx / x_width) / y_width) % z_width;
*i = ((idx / x_width) / y_width) / z_width;
}

96
src/n_to_one.h Normal file
View File

@ -0,0 +1,96 @@
#ifndef MULTIDIMENSIONAL_TO_ONE_H
#define MULTIDIMENSIONAL_TO_ONE_H
#ifdef __cplusplus
extern "C" {
#endif
unsigned long two_to_one(
unsigned long x,
unsigned long y,
unsigned long x_width);
void one_to_two(
unsigned long idx,
unsigned long *x,
unsigned long *y,
unsigned long x_width);
unsigned long three_to_one(
unsigned long x,
unsigned long y,
unsigned long z,
unsigned long x_width,
unsigned long y_width);
void one_to_three(
unsigned long idx,
unsigned long *x,
unsigned long *y,
unsigned long *z,
unsigned long x_width,
unsigned long y_width);
unsigned long four_to_one(
unsigned long x,
unsigned long y,
unsigned long z,
unsigned long i,
unsigned long x_width,
unsigned long y_width,
unsigned long z_width);
void one_to_four(
unsigned long idx,
unsigned long *x,
unsigned long *y,
unsigned long *z,
unsigned long *i,
unsigned long x_width,
unsigned long y_width,
unsigned long z_width);
unsigned long long two_to_one_l(
unsigned long long x,
unsigned long long y,
unsigned long long x_width);
void one_to_two_l(
unsigned long long idx,
unsigned long long *x,
unsigned long long *y,
unsigned long long x_width);
unsigned long long three_to_one_l(
unsigned long long x,
unsigned long long y,
unsigned long long z,
unsigned long long x_width,
unsigned long long y_width);
void one_to_three_l(
unsigned long long idx,
unsigned long long *x,
unsigned long long *y,
unsigned long long *z,
unsigned long long x_width,
unsigned long long y_width);
unsigned long long four_to_one_l(
unsigned long long x,
unsigned long long y,
unsigned long long z,
unsigned long long i,
unsigned long long x_width,
unsigned long long y_width,
unsigned long long z_width);
void one_to_four_l(
unsigned long long idx,
unsigned long long *x,
unsigned long long *y,
unsigned long long *z,
unsigned long long *i,
unsigned long long x_width,
unsigned long long y_width,
unsigned long long z_width);
#ifdef __cplusplus
}
#endif
#endif

2
src/tests/test_main.cpp Normal file
View File

@ -0,0 +1,2 @@
#define CATCH_CONFIG_MAIN
#include <catch.hpp>

444
src/tests/test_n_to_one.cpp Normal file
View File

@ -0,0 +1,444 @@
#include <catch.hpp>
#include "../n_to_one.h"
struct Indices {
unsigned long long x;
unsigned long long y;
unsigned long long z;
unsigned long long i;
};
TEST_CASE("two_to_one", "n_to_one") {
unsigned long x = 5;
unsigned long y = 4;
unsigned long x_width = 10;
CHECK(two_to_one(x, y, x_width) == 45);
x = 3;
CHECK(two_to_one(x, y, x_width) == 43);
y = 7;
CHECK(two_to_one(x, y, x_width) == 73);
}
TEST_CASE("one_to_two", "n_to_one") {
unsigned long x;
unsigned long y;
unsigned long x_width = 10;
unsigned long idx = 45;
one_to_two(idx, &x, &y, x_width);
CHECK(x == 5);
CHECK(y == 4);
idx = 43;
one_to_two(idx, &x, &y, x_width);
CHECK(x == 3);
CHECK(y == 4);
idx = 73;
one_to_two(idx, &x, &y, x_width);
CHECK(x == 3);
CHECK(y == 7);
}
TEST_CASE("three_to_one", "n_to_one") {
unsigned long x = 5;
unsigned long y = 4;
unsigned long z = 3;
unsigned long x_width = 10;
unsigned long y_width = 10;
CHECK(three_to_one(x, y, z, x_width, y_width) == 345);
x = 3;
z = 7;
CHECK(three_to_one(x, y, z, x_width, y_width) == 743);
x = 1;
y = 5;
z = 9;
CHECK(three_to_one(x, y, z, x_width, y_width) == 951);
}
TEST_CASE("one_to_three", "n_to_one") {
unsigned long x;
unsigned long y;
unsigned long z;
unsigned long x_width = 10;
unsigned long y_width = 10;
unsigned long idx = 123;
one_to_three(idx, &x, &y, &z, x_width, y_width);
CHECK(x == 3);
CHECK(y == 2);
CHECK(z == 1);
idx = 957;
one_to_three(idx, &x, &y, &z, x_width, y_width);
CHECK(x == 7);
CHECK(y == 5);
CHECK(z == 9);
idx = 482;
one_to_three(idx, &x, &y, &z, x_width, y_width);
CHECK(x == 2);
CHECK(y == 8);
CHECK(z == 4);
}
TEST_CASE("four_to_one", "n_to_one") {
unsigned long x = 1;
unsigned long y = 2;
unsigned long z = 3;
unsigned long i = 4;
unsigned long x_width = 10;
unsigned long y_width = 10;
unsigned long z_width = 10;
CHECK(four_to_one(x, y, z, i, x_width, y_width, z_width) == 4321);
y_width = 5;
// 1 + 2 * 10 + 3 * 10 * 5 + 4 * 10 * 5 * 10 == 2171
CHECK(four_to_one(x, y, z, i, x_width, y_width, z_width) == 2171);
y_width = 10;
x = 9;
y = 7;
z = 4;
i = 2;
CHECK(four_to_one(x, y, z, i, x_width, y_width, z_width) == 2479);
}
TEST_CASE("one_to_four", "n_to_one") {
unsigned long x;
unsigned long y;
unsigned long z;
unsigned long i;
unsigned long x_width = 10;
unsigned long y_width = 10;
unsigned long z_width = 10;
unsigned long idx = 1234;
one_to_four(idx, &x, &y, &z, &i, x_width, y_width, z_width);
CHECK(x == 4);
CHECK(y == 3);
CHECK(z == 2);
CHECK(i == 1);
y_width = 5;
// x = 4, y = 3, z = 1234 / 10 / 5 % 10 == 4, i = 1234 / 10 / 5 / 10 == 2
one_to_four(idx, &x, &y, &z, &i, x_width, y_width, z_width);
CHECK(x == 4);
CHECK(y == 3);
CHECK(z == 4);
CHECK(i == 2);
y_width = 10;
idx = 7125;
one_to_four(idx, &x, &y, &z, &i, x_width, y_width, z_width);
CHECK(x == 5);
CHECK(y == 2);
CHECK(z == 1);
CHECK(i == 7);
}
TEST_CASE("n=2 objects long", "n_to_one") {
Indices indices[5*4];
unsigned long x;
unsigned long y;
unsigned long idx;
for(idx = 0; idx < 5*4; ++idx) {
one_to_two(idx, &x, &y, 5);
indices[idx].x = x;
indices[idx].y = y;
}
for(y = 0; y < 4; ++y) {
for(x = 0; x < 5; ++x) {
idx = two_to_one(x, y, 5);
REQUIRE(idx <= 5*4);
CHECK(indices[idx].x == x);
CHECK(indices[idx].y == y);
}
}
}
TEST_CASE("n=3 objects long", "n_to_one") {
Indices indices[5*4*3];
unsigned long x;
unsigned long y;
unsigned long z;
unsigned long idx;
for(idx = 0; idx < 5*4*3; ++idx) {
one_to_three(idx, &x, &y, &z, 5, 4);
indices[idx].x = x;
indices[idx].y = y;
indices[idx].z = z;
}
for(z = 0; z < 3; ++z) {
for(y = 0; y < 4; ++y) {
for(x = 0; x < 5; ++x) {
idx = three_to_one(x, y, z, 5, 4);
REQUIRE(idx <= 5*4*3);
CHECK(indices[idx].x == x);
CHECK(indices[idx].y == y);
CHECK(indices[idx].z == z);
}
}
}
}
TEST_CASE("n=4 objects long", "n_to_one") {
Indices indices[5*4*3*2];
unsigned long x;
unsigned long y;
unsigned long z;
unsigned long i;
unsigned long idx;
for(idx = 0; idx < 5*4*3*2; ++idx) {
one_to_four(idx, &x, &y, &z, &i, 5, 4, 3);
indices[idx].x = x;
indices[idx].y = y;
indices[idx].z = z;
indices[idx].i = i;
}
for(i = 0; i < 2; ++i) {
for(z = 0; z < 3; ++z) {
for(y = 0; y < 4; ++y) {
for(x = 0; x < 5; ++x) {
idx = four_to_one(x, y, z, i, 5, 4, 3);
REQUIRE(idx <= 5*4*3*2);
CHECK(indices[idx].x == x);
CHECK(indices[idx].y == y);
CHECK(indices[idx].z == z);
CHECK(indices[idx].i == i);
}
}
}
}
}
TEST_CASE("two_to_one_l", "n_to_one") {
unsigned long long x = 5;
unsigned long long y = 4;
unsigned long long x_width = 10;
CHECK(two_to_one_l(x, y, x_width) == 45);
x = 3;
CHECK(two_to_one_l(x, y, x_width) == 43);
y = 7;
CHECK(two_to_one_l(x, y, x_width) == 73);
}
TEST_CASE("one_to_two_l", "n_to_one") {
unsigned long long x;
unsigned long long y;
unsigned long long x_width = 10;
unsigned long long idx = 45;
one_to_two_l(idx, &x, &y, x_width);
CHECK(x == 5);
CHECK(y == 4);
idx = 43;
one_to_two_l(idx, &x, &y, x_width);
CHECK(x == 3);
CHECK(y == 4);
idx = 73;
one_to_two_l(idx, &x, &y, x_width);
CHECK(x == 3);
CHECK(y == 7);
}
TEST_CASE("three_to_one_l", "n_to_one") {
unsigned long long x = 5;
unsigned long long y = 4;
unsigned long long z = 3;
unsigned long long x_width = 10;
unsigned long long y_width = 10;
CHECK(three_to_one_l(x, y, z, x_width, y_width) == 345);
x = 3;
z = 7;
CHECK(three_to_one_l(x, y, z, x_width, y_width) == 743);
x = 1;
y = 5;
z = 9;
CHECK(three_to_one_l(x, y, z, x_width, y_width) == 951);
}
TEST_CASE("one_to_three_l", "n_to_one") {
unsigned long long x;
unsigned long long y;
unsigned long long z;
unsigned long long x_width = 10;
unsigned long long y_width = 10;
unsigned long long idx = 123;
one_to_three_l(idx, &x, &y, &z, x_width, y_width);
CHECK(x == 3);
CHECK(y == 2);
CHECK(z == 1);
idx = 957;
one_to_three_l(idx, &x, &y, &z, x_width, y_width);
CHECK(x == 7);
CHECK(y == 5);
CHECK(z == 9);
idx = 482;
one_to_three_l(idx, &x, &y, &z, x_width, y_width);
CHECK(x == 2);
CHECK(y == 8);
CHECK(z == 4);
}
TEST_CASE("four_to_one_l", "n_to_one") {
unsigned long long x = 1;
unsigned long long y = 2;
unsigned long long z = 3;
unsigned long long i = 4;
unsigned long long x_width = 10;
unsigned long long y_width = 10;
unsigned long long z_width = 10;
CHECK(four_to_one_l(x, y, z, i, x_width, y_width, z_width) == 4321);
y_width = 5;
// 1 + 2 * 10 + 3 * 10 * 5 + 4 * 10 * 5 * 10 == 2171
CHECK(four_to_one_l(x, y, z, i, x_width, y_width, z_width) == 2171);
y_width = 10;
x = 9;
y = 7;
z = 4;
i = 2;
CHECK(four_to_one_l(x, y, z, i, x_width, y_width, z_width) == 2479);
}
TEST_CASE("one_to_four_l", "n_to_one") {
unsigned long long x;
unsigned long long y;
unsigned long long z;
unsigned long long i;
unsigned long long x_width = 10;
unsigned long long y_width = 10;
unsigned long long z_width = 10;
unsigned long long idx = 1234;
one_to_four_l(idx, &x, &y, &z, &i, x_width, y_width, z_width);
CHECK(x == 4);
CHECK(y == 3);
CHECK(z == 2);
CHECK(i == 1);
y_width = 5;
// x = 4, y = 3, z = 1234 / 10 / 5 % 10 == 4, i = 1234 / 10 / 5 / 10 == 2
one_to_four_l(idx, &x, &y, &z, &i, x_width, y_width, z_width);
CHECK(x == 4);
CHECK(y == 3);
CHECK(z == 4);
CHECK(i == 2);
y_width = 10;
idx = 7125;
one_to_four_l(idx, &x, &y, &z, &i, x_width, y_width, z_width);
CHECK(x == 5);
CHECK(y == 2);
CHECK(z == 1);
CHECK(i == 7);
}
TEST_CASE("n=2 objects long long", "n_to_one") {
Indices indices[5*4];
unsigned long long x;
unsigned long long y;
unsigned long long idx;
for(idx = 0; idx < 5*4; ++idx) {
one_to_two_l(idx, &x, &y, 5);
indices[idx].x = x;
indices[idx].y = y;
}
for(y = 0; y < 4; ++y) {
for(x = 0; x < 5; ++x) {
idx = two_to_one_l(x, y, 5);
REQUIRE(idx <= 5*4);
CHECK(indices[idx].x == x);
CHECK(indices[idx].y == y);
}
}
}
TEST_CASE("n=3 objects long long", "n_to_one") {
Indices indices[5*4*3];
unsigned long long x;
unsigned long long y;
unsigned long long z;
unsigned long long idx;
for(idx = 0; idx < 5*4*3; ++idx) {
one_to_three_l(idx, &x, &y, &z, 5, 4);
indices[idx].x = x;
indices[idx].y = y;
indices[idx].z = z;
}
for(z = 0; z < 3; ++z) {
for(y = 0; y < 4; ++y) {
for(x = 0; x < 5; ++x) {
idx = three_to_one_l(x, y, z, 5, 4);
REQUIRE(idx <= 5*4*3);
CHECK(indices[idx].x == x);
CHECK(indices[idx].y == y);
CHECK(indices[idx].z == z);
}
}
}
}
TEST_CASE("n=4 objects long long", "n_to_one") {
Indices indices[5*4*3*2];
unsigned long long x;
unsigned long long y;
unsigned long long z;
unsigned long long i;
unsigned long long idx;
for(idx = 0; idx < 5*4*3*2; ++idx) {
one_to_four_l(idx, &x, &y, &z, &i, 5, 4, 3);
indices[idx].x = x;
indices[idx].y = y;
indices[idx].z = z;
indices[idx].i = i;
}
for(i = 0; i < 2; ++i) {
for(z = 0; z < 3; ++z) {
for(y = 0; y < 4; ++y) {
for(x = 0; x < 5; ++x) {
idx = four_to_one_l(x, y, z, i, 5, 4, 3);
REQUIRE(idx <= 5*4*3*2);
CHECK(indices[idx].x == x);
CHECK(indices[idx].y == y);
CHECK(indices[idx].z == z);
CHECK(indices[idx].i == i);
}
}
}
}
}

1
third_party/Catch2 vendored Submodule

@ -0,0 +1 @@
Subproject commit 7727c15290ce2d289c1809d0eab3cceb88384ad6