Commit 5cd32e7f authored by nagayama15's avatar nagayama15

順列生成関数を実装

parent 571e3bbe
...@@ -6,3 +6,5 @@ ...@@ -6,3 +6,5 @@
*.o *.o
*.ll *.ll
*.s *.s
test_*
LLVM_INCLUDE_DIRS := $(shell llvm-config-6.0 --includedir)
CXX := g++ CXX := g++
CXXFLAGS := \ CXXFLAGS := \
...@@ -6,18 +8,34 @@ CXXFLAGS := \ ...@@ -6,18 +8,34 @@ CXXFLAGS := \
-Wextra \ -Wextra \
-pedantic \ -pedantic \
-Werror \ -Werror \
$(shell llvm-config-6.0 --cxxflags) ${LLVM_INCLUDE_DIRS:%=-I%}
LDFLAGS := \ LDFLAGS := \
$(shell llvm-config-6.0 --ldflags) \ $(shell llvm-config-6.0 --ldflags) \
$(shell llvm-config-6.0 --libs) $(shell llvm-config-6.0 --libs)
.PHONY: all clean .PHONY: all test clean
all: testpass.so test_pass
test: test_pass
./test_pass
testpass.so: \
src/nykk/pass/TestPass.o \
src/nykk/pass/BlockCounterPass.o \
src/nykk/pass/BlockWatermarkPass.o
test/Test.o: \
test/Test.cpp \
test/TestPermutationTable.hpp \
src/nykk/PermutationTable.hpp
all: testpass.so test_pass: test/Test.o
${CXX} ${CXXFLAGS} -o $@ $^ ${LDFLAGS}
testpass.so: src/nykk/pass/TestPass.o src/nykk/pass/BlockCounterPass.o %.so:
${CXX} ${CXXFLAGS} -shared -o $@ $^ ${LDFLAGS} ${CXX} ${CXXFLAGS} -shared -o $@ $^ ${LDFLAGS}
clean: clean:
${RM} *.so src/*/*.o ${RM} *.so test_pass src/*/*.o test/*.o
#ifndef INCLUDE_NYKK_PERMUTATIONTABLE_HPP
#define INCLUDE_NYKK_PERMUTATIONTABLE_HPP
#include <cassert>
#include <cstdint>
#include <algorithm>
#include <numeric>
#include <type_traits>
#include <vector>
#include <iostream>
namespace nykk
{
/**
* @brief Compute factorial `x!`.
*
* @param[in] x
*
* @tparam Integer Integer type.
* @tparam <unnamed>
*
* @return `x!`.
*/
template <typename Integer, std::enable_if_t<std::is_integral_v<Integer>, std::nullptr_t> = nullptr>
[[nodiscard]]
constexpr Integer factorial(Integer x)
{
Integer n = 1;
for (Integer i = 1; i <= x; ++i)
{
n *= i;
}
return n;
}
/**
* @brief Compute a permutation table of sequence [0, n).
*
* @param[in] n Size of a number sequence.
*
* @return Pre-computed permutation table.
*/
[[nodiscard]]
inline std::vector<std::vector<std::uint8_t>> create_permutation_table(std::size_t n)
{
assert(n < 13 && "too large `n` to compute permutation table");
auto table = std::vector<std::vector<std::uint8_t>> {};
table.reserve(factorial(n));
// [0, n)
auto v = std::vector<std::uint8_t>(n);
std::iota(std::begin(v), std::end(v), 0);
do
{
table.emplace_back(v);
} while (std::next_permutation(std::begin(v), std::end(v)));
return table;
}
}
#endif
#include "TestPermutationTable.hpp"
int main()
{
run_test_permutation_table();
}
#ifndef INCLUDE_TEST_TESTPERMUTATIONTABLE_HPP
#define INCLUDE_TEST_TESTPERMUTATIONTABLE_HPP
#include "../src/nykk/PermutationTable.hpp"
template <typename T, typename U>
[[nodiscard]]
inline bool range_test(std::initializer_list<T> expected, U&& actual)
{
return std::equal(std::begin(expected), std::end(expected), std::begin(actual), std::end(actual));
}
inline void run_test_permutation_table()
{
static_assert(nykk::factorial(0) == 1);
static_assert(nykk::factorial(1) == 1);
static_assert(nykk::factorial(2) == 2);
static_assert(nykk::factorial(5) == 120);
const auto table = nykk::create_permutation_table(3);
assert(table.size() == 6);
assert(range_test({0, 1, 2}, table[0]));
assert(range_test({0, 2, 1}, table[1]));
assert(range_test({1, 0, 2}, table[2]));
assert(range_test({1, 2, 0}, table[3]));
assert(range_test({2, 0, 1}, table[4]));
assert(range_test({2, 1, 0}, table[5]));
}
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment