From d51d4fdb521d8d29284b8e1aa225c9ed520e2551 Mon Sep 17 00:00:00 2001 From: Victor Payno Date: Sat, 22 Jul 2023 14:04:58 -0700 Subject: [PATCH] c++/prime-factors: 1st iteration --- cpp/README.md | 1 + cpp/prime-factors/CMakeLists.txt | 56 +++---- cpp/prime-factors/Makefile | 23 +++ cpp/prime-factors/README.md | 7 +- cpp/prime-factors/compile_commands.json | 17 ++ cpp/prime-factors/compile_flags.txt | 8 + cpp/prime-factors/prime_factors.cpp | 37 ++++- cpp/prime-factors/prime_factors.h | 10 +- cpp/prime-factors/prime_factors.plist | 14 ++ cpp/prime-factors/prime_factors_test.cpp | 30 ++-- cpp/prime-factors/prime_factors_test.plist | 14 ++ cpp/prime-factors/run-tests-cpp.txt | 173 +++++++++++++++++++++ 12 files changed, 340 insertions(+), 50 deletions(-) create mode 100644 cpp/prime-factors/Makefile create mode 100644 cpp/prime-factors/compile_commands.json create mode 100644 cpp/prime-factors/compile_flags.txt create mode 100644 cpp/prime-factors/prime_factors.plist create mode 100644 cpp/prime-factors/prime_factors_test.plist create mode 100644 cpp/prime-factors/run-tests-cpp.txt diff --git a/cpp/README.md b/cpp/README.md index 116b3220..2dfe54d6 100644 --- a/cpp/README.md +++ b/cpp/README.md @@ -33,3 +33,4 @@ - [trinary](./trinary/README.md) - [sieve](./sieve/README.md) - [nth-prime](./nth-prime/README.md) +- [prime-factors](./prime-factors/README.md) diff --git a/cpp/prime-factors/CMakeLists.txt b/cpp/prime-factors/CMakeLists.txt index 3b0589fd..d6325041 100644 --- a/cpp/prime-factors/CMakeLists.txt +++ b/cpp/prime-factors/CMakeLists.txt @@ -12,53 +12,57 @@ string(REPLACE "-" "_" file ${exercise}) # Implementation could be only a header if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.cpp) - set(exercise_cpp ${file}.cpp) + set(exercise_cpp ${file}.cpp) else() - set(exercise_cpp "") + set(exercise_cpp "") endif() # Use the common Catch library? if(EXERCISM_COMMON_CATCH) - # For Exercism track development only - add_executable(${exercise} ${file}_test.cpp ${exercise_cpp} ${file}.h $) + # For Exercism track development only + add_executable(${exercise} ${file}_test.cpp ${exercise_cpp} ${file}.h + $) elseif(EXERCISM_TEST_SUITE) - # The Exercism test suite is being run, the Docker image already - # includes a pre-built version of Catch. - find_package(Catch2 REQUIRED) - add_executable(${exercise} ${file}_test.cpp ${exercise_cpp} ${file}.h) - target_link_libraries(${exercise} PRIVATE Catch2::Catch2WithMain) - # When Catch is installed system wide we need to include a different - # header, we need this define to use the correct one. - target_compile_definitions(${exercise} PRIVATE EXERCISM_TEST_SUITE) + # The Exercism test suite is being run, the Docker image already includes a + # pre-built version of Catch. + find_package(Catch2 REQUIRED) + add_executable(${exercise} ${file}_test.cpp ${exercise_cpp} ${file}.h) + target_link_libraries(${exercise} PRIVATE Catch2::Catch2WithMain) + # When Catch is installed system wide we need to include a different header, + # we need this define to use the correct one. + target_compile_definitions(${exercise} PRIVATE EXERCISM_TEST_SUITE) else() - # Build executable from sources and headers - add_executable(${exercise} ${file}_test.cpp ${exercise_cpp} ${file}.h test/tests-main.cpp) + # Build executable from sources and headers + add_executable(${exercise} ${file}_test.cpp ${exercise_cpp} ${file}.h + test/tests-main.cpp) endif() -set_target_properties(${exercise} PROPERTIES - CXX_STANDARD 17 - CXX_STANDARD_REQUIRED OFF - CXX_EXTENSIONS OFF -) +set_target_properties( + ${exercise} + PROPERTIES CXX_STANDARD 17 + CXX_STANDARD_REQUIRED OFF + CXX_EXTENSIONS OFF) set(CMAKE_BUILD_TYPE Debug) if("${CMAKE_CXX_COMPILER_ID}" MATCHES "(GNU|Clang)") - set_target_properties(${exercise} PROPERTIES - COMPILE_FLAGS "-Wall -Wextra -Wpedantic -Werror" - ) + set_target_properties( + ${exercise} PROPERTIES COMPILE_FLAGS "-Wall -Wextra -Wpedantic -Werror") endif() # Configure to run all the tests? if(${EXERCISM_RUN_ALL_TESTS}) - target_compile_definitions(${exercise} PRIVATE EXERCISM_RUN_ALL_TESTS) + target_compile_definitions(${exercise} PRIVATE EXERCISM_RUN_ALL_TESTS) endif() # Tell MSVC not to warn us about unchecked iterators in debug builds if(${MSVC}) - set_target_properties(${exercise} PROPERTIES - COMPILE_DEFINITIONS_DEBUG _SCL_SECURE_NO_WARNINGS) + set_target_properties(${exercise} PROPERTIES COMPILE_DEFINITIONS_DEBUG + _SCL_SECURE_NO_WARNINGS) endif() # Run the tests on every build -add_custom_target(test_${exercise} ALL DEPENDS ${exercise} COMMAND ${exercise}) +add_custom_target( + test_${exercise} ALL + DEPENDS ${exercise} + COMMAND ${exercise}) diff --git a/cpp/prime-factors/Makefile b/cpp/prime-factors/Makefile new file mode 100644 index 00000000..c8853648 --- /dev/null +++ b/cpp/prime-factors/Makefile @@ -0,0 +1,23 @@ +.PHONY: clean +clean: + rm -rf ./build + +.PHONY: test +test: clean + mkdir -pv ./build + + @printf "\n" + @# each line is executed in a subshell, we have to daisy chain them so they + @# run in the build directory + cd ./build; export LDFLAGS="-lgcov --coverage" CXXFLAGS="--coverage"; cmake -DEXERCISM_RUN_ALL_TESTS=1 -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -G 'Unix Makefiles' ../; if make; then printf "\n=== All Tests Passed ===\n"; else printf "\n=== Test Failure ===\n"; false; fi + +.PHONY: coverage +coverage: test + @printf "\n" + find . -regextype posix-egrep -regex "^.*(tests-main|CompilerId).*[.](gcda|gcno)$$" -print -delete + + @printf "\n" + find . -regextype posix-egrep -regex "^.*[.](gcda|gcno)2169" + + @printf "\n" + gcovr --print-summary diff --git a/cpp/prime-factors/README.md b/cpp/prime-factors/README.md index dbc5c16f..0c698fc8 100644 --- a/cpp/prime-factors/README.md +++ b/cpp/prime-factors/README.md @@ -51,4 +51,9 @@ You can check this yourself: ### Based on -The Prime Factors Kata by Uncle Bob - http://butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata \ No newline at end of file +The Prime Factors Kata by Uncle Bob - http://butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata + +### My Solution + +- [my solution]() +- [run-tests](./run-tests-cpp.txt) diff --git a/cpp/prime-factors/compile_commands.json b/cpp/prime-factors/compile_commands.json new file mode 100644 index 00000000..fb3432c5 --- /dev/null +++ b/cpp/prime-factors/compile_commands.json @@ -0,0 +1,17 @@ +[ +{ + "directory": "/home/vpayno/git_vpayno/exercism-workspace/cpp/prime-factors/build", + "command": "/usr/bin/c++ -DEXERCISM_RUN_ALL_TESTS -g -Wall -Wextra -Wpedantic -Werror -std=c++17 -o CMakeFiles/prime-factors.dir/prime_factors_test.cpp.o -c /home/vpayno/git_vpayno/exercism-workspace/cpp/prime-factors/prime_factors_test.cpp", + "file": "/home/vpayno/git_vpayno/exercism-workspace/cpp/prime-factors/prime_factors_test.cpp" +}, +{ + "directory": "/home/vpayno/git_vpayno/exercism-workspace/cpp/prime-factors/build", + "command": "/usr/bin/c++ -DEXERCISM_RUN_ALL_TESTS -g -Wall -Wextra -Wpedantic -Werror -std=c++17 -o CMakeFiles/prime-factors.dir/prime_factors.cpp.o -c /home/vpayno/git_vpayno/exercism-workspace/cpp/prime-factors/prime_factors.cpp", + "file": "/home/vpayno/git_vpayno/exercism-workspace/cpp/prime-factors/prime_factors.cpp" +}, +{ + "directory": "/home/vpayno/git_vpayno/exercism-workspace/cpp/prime-factors/build", + "command": "/usr/bin/c++ -DEXERCISM_RUN_ALL_TESTS -g -Wall -Wextra -Wpedantic -Werror -std=c++17 -o CMakeFiles/prime-factors.dir/test/tests-main.cpp.o -c /home/vpayno/git_vpayno/exercism-workspace/cpp/prime-factors/test/tests-main.cpp", + "file": "/home/vpayno/git_vpayno/exercism-workspace/cpp/prime-factors/test/tests-main.cpp" +} +] \ No newline at end of file diff --git a/cpp/prime-factors/compile_flags.txt b/cpp/prime-factors/compile_flags.txt new file mode 100644 index 00000000..5dfc4cfe --- /dev/null +++ b/cpp/prime-factors/compile_flags.txt @@ -0,0 +1,8 @@ +-std=c++17 +-stdlib=libstdc++ +-g +-Wall +-Wextra +-Wpedantic +-Werror +-Wno-unused-parameter diff --git a/cpp/prime-factors/prime_factors.cpp b/cpp/prime-factors/prime_factors.cpp index 9a747980..16a1c862 100644 --- a/cpp/prime-factors/prime_factors.cpp +++ b/cpp/prime-factors/prime_factors.cpp @@ -2,4 +2,39 @@ namespace prime_factors { -} // namespace prime_factors +// number should be unsigned +std::vector of(int number) { + std::vector factors{}; + + switch (number) { + case 0: + [[fallthrough]]; + case 1: + return factors; + case 2: + factors.push_back(2); + return factors; + } + + int factor{0}; + + factor = 2; + while (number % factor == 0 and number > 1) { + number /= factor; + factors.push_back(factor); + } + + factor = 3; + while (number > 1) { + while (number % factor == 0 and number > 1) { + number /= factor; + factors.push_back(factor); + } + + factor += 2; + } + + return factors; +} + +} // namespace prime_factors diff --git a/cpp/prime-factors/prime_factors.h b/cpp/prime-factors/prime_factors.h index 845abe96..9ab238ff 100644 --- a/cpp/prime-factors/prime_factors.h +++ b/cpp/prime-factors/prime_factors.h @@ -1,8 +1,14 @@ #if !defined(PRIME_FACTORS_H) #define PRIME_FACTORS_H +// this is not a c++ header file (use *.hpp) + +#include + namespace prime_factors { -} // namespace prime_factors +std::vector of(int number); + +} // namespace prime_factors -#endif // PRIME_FACTORS_H \ No newline at end of file +#endif // PRIME_FACTORS_H diff --git a/cpp/prime-factors/prime_factors.plist b/cpp/prime-factors/prime_factors.plist new file mode 100644 index 00000000..4fa1e477 --- /dev/null +++ b/cpp/prime-factors/prime_factors.plist @@ -0,0 +1,14 @@ + + + + + clang_version +Debian clang version 16.0.6 (++20230610113348+7cbf1a259152-1~exp1~20230610233446.99) + diagnostics + + + files + + + + diff --git a/cpp/prime-factors/prime_factors_test.cpp b/cpp/prime-factors/prime_factors_test.cpp index fa1e29d4..abf1d56f 100644 --- a/cpp/prime-factors/prime_factors_test.cpp +++ b/cpp/prime-factors/prime_factors_test.cpp @@ -5,8 +5,7 @@ #include "test/catch.hpp" #endif -TEST_CASE("_1_yields_empty") -{ +TEST_CASE("_1_yields_empty") { const std::vector expected{}; const std::vector actual{prime_factors::of(1)}; @@ -15,8 +14,7 @@ TEST_CASE("_1_yields_empty") } #if defined(EXERCISM_RUN_ALL_TESTS) -TEST_CASE("_2_yields_2") -{ +TEST_CASE("_2_yields_2") { const std::vector expected{2}; const std::vector actual{prime_factors::of(2)}; @@ -24,8 +22,7 @@ TEST_CASE("_2_yields_2") REQUIRE(expected == actual); } -TEST_CASE("_3_yields_3") -{ +TEST_CASE("_3_yields_3") { const std::vector expected{3}; const std::vector actual{prime_factors::of(3)}; @@ -33,8 +30,7 @@ TEST_CASE("_3_yields_3") REQUIRE(expected == actual); } -TEST_CASE("_4_yields_2_2") -{ +TEST_CASE("_4_yields_2_2") { const std::vector expected{2, 2}; const std::vector actual{prime_factors::of(4)}; @@ -42,8 +38,7 @@ TEST_CASE("_4_yields_2_2") REQUIRE(expected == actual); } -TEST_CASE("_6_yields_2_3") -{ +TEST_CASE("_6_yields_2_3") { const std::vector expected{2, 3}; const std::vector actual{prime_factors::of(6)}; @@ -51,8 +46,7 @@ TEST_CASE("_6_yields_2_3") REQUIRE(expected == actual); } -TEST_CASE("_8_yields_2_2_2") -{ +TEST_CASE("_8_yields_2_2_2") { const std::vector expected{2, 2, 2}; const std::vector actual{prime_factors::of(8)}; @@ -60,8 +54,7 @@ TEST_CASE("_8_yields_2_2_2") REQUIRE(expected == actual); } -TEST_CASE("_9_yields_3_3") -{ +TEST_CASE("_9_yields_3_3") { const std::vector expected{3, 3}; const std::vector actual{prime_factors::of(9)}; @@ -69,8 +62,7 @@ TEST_CASE("_9_yields_3_3") REQUIRE(expected == actual); } -TEST_CASE("_27_yields_3_3_3") -{ +TEST_CASE("_27_yields_3_3_3") { const std::vector expected{3, 3, 3}; const std::vector actual{prime_factors::of(27)}; @@ -78,8 +70,7 @@ TEST_CASE("_27_yields_3_3_3") REQUIRE(expected == actual); } -TEST_CASE("_625_yields_5_5_5_5") -{ +TEST_CASE("_625_yields_5_5_5_5") { const std::vector expected{5, 5, 5, 5}; const std::vector actual{prime_factors::of(625)}; @@ -87,8 +78,7 @@ TEST_CASE("_625_yields_5_5_5_5") REQUIRE(expected == actual); } -TEST_CASE("_901255_yields_5_17_23_461") -{ +TEST_CASE("_901255_yields_5_17_23_461") { const std::vector expected{5, 17, 23, 461}; const std::vector actual{prime_factors::of(901255)}; diff --git a/cpp/prime-factors/prime_factors_test.plist b/cpp/prime-factors/prime_factors_test.plist new file mode 100644 index 00000000..4fa1e477 --- /dev/null +++ b/cpp/prime-factors/prime_factors_test.plist @@ -0,0 +1,14 @@ + + + + + clang_version +Debian clang version 16.0.6 (++20230610113348+7cbf1a259152-1~exp1~20230610233446.99) + diagnostics + + + files + + + + diff --git a/cpp/prime-factors/run-tests-cpp.txt b/cpp/prime-factors/run-tests-cpp.txt new file mode 100644 index 00000000..cde040ac --- /dev/null +++ b/cpp/prime-factors/run-tests-cpp.txt @@ -0,0 +1,173 @@ +Running automated test file(s): + + +=============================================================================== + +Running: make clean +rm -rf ./build + +real 0m0.015s +user 0m0.001s +sys 0m0.014s + +=============================================================================== + +export LDFLAGS="-lgcov --coverage" CXXFLAGS="--coverage" + +=============================================================================== + +Running: make coverage | ansifilter +rm -rf ./build +mkdir -pv ./build +mkdir: created directory './build' + +cd ./build; export LDFLAGS="-lgcov --coverage" CXXFLAGS="--coverage"; cmake -DEXERCISM_RUN_ALL_TESTS=1 -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -G 'Unix Makefiles' ../; if make; then printf "\n=== All Tests Passed ===\n"; else printf "\n=== Test Failure ===\n"; false; fi +-- The CXX compiler identification is GNU 10.2.1 +-- Detecting CXX compiler ABI info +-- Detecting CXX compiler ABI info - done +-- Check for working CXX compiler: /usr/bin/c++ - skipped +-- Detecting CXX compile features +-- Detecting CXX compile features - done +-- Configuring done +-- Generating done +-- Build files have been written to: /home/vpayno/git_vpayno/exercism-workspace/cpp/prime-factors/build +make[1]: Entering directory '/home/vpayno/git_vpayno/exercism-workspace/cpp/prime-factors/build' +make[2]: Entering directory '/home/vpayno/git_vpayno/exercism-workspace/cpp/prime-factors/build' +make[3]: Entering directory '/home/vpayno/git_vpayno/exercism-workspace/cpp/prime-factors/build' +make[3]: Leaving directory '/home/vpayno/git_vpayno/exercism-workspace/cpp/prime-factors/build' +make[3]: Entering directory '/home/vpayno/git_vpayno/exercism-workspace/cpp/prime-factors/build' +[ 25%] Building CXX object CMakeFiles/prime-factors.dir/prime_factors_test.cpp.o +[ 50%] Building CXX object CMakeFiles/prime-factors.dir/prime_factors.cpp.o +[ 75%] Building CXX object CMakeFiles/prime-factors.dir/test/tests-main.cpp.o +[100%] Linking CXX executable prime-factors +make[3]: Leaving directory '/home/vpayno/git_vpayno/exercism-workspace/cpp/prime-factors/build' +[100%] Built target prime-factors +make[3]: Entering directory '/home/vpayno/git_vpayno/exercism-workspace/cpp/prime-factors/build' +make[3]: Leaving directory '/home/vpayno/git_vpayno/exercism-workspace/cpp/prime-factors/build' +make[3]: Entering directory '/home/vpayno/git_vpayno/exercism-workspace/cpp/prime-factors/build' +=============================================================================== +All tests passed (10 assertions in 10 test cases) + +make[3]: Leaving directory '/home/vpayno/git_vpayno/exercism-workspace/cpp/prime-factors/build' +[100%] Built target test_prime-factors +make[2]: Leaving directory '/home/vpayno/git_vpayno/exercism-workspace/cpp/prime-factors/build' +make[1]: Leaving directory '/home/vpayno/git_vpayno/exercism-workspace/cpp/prime-factors/build' + +=== All Tests Passed === + +find . -regextype posix-egrep -regex "^.*(tests-main|CompilerId).*[.](gcda|gcno)$" -print -delete +./build/CMakeFiles/3.22.2/CompilerIdCXX/CMakeCXXCompilerId.gcno +./build/CMakeFiles/prime-factors.dir/test/tests-main.cpp.gcno +./build/CMakeFiles/prime-factors.dir/test/tests-main.cpp.gcda + +find . -regextype posix-egrep -regex "^.*[.](gcda|gcno)2169" + +gcovr --print-summary +------------------------------------------------------------------------------ + GCC Code Coverage Report +Directory: . +------------------------------------------------------------------------------ +File Lines Exec Cover Missing +------------------------------------------------------------------------------ +prime_factors.cpp 20 20 100% +prime_factors_test.cpp 50 50 100% +test/catch.hpp 48 27 56% 1448-1450,1642-1643,1827-1833,1835-1836,2016-2017,2039-2040,2227,2229,2560 +------------------------------------------------------------------------------ +TOTAL 118 97 82% +------------------------------------------------------------------------------ +lines: 82.2% (97 out of 118) +branches: 37.3% (84 out of 225) + +real 0m10.124s +user 0m9.174s +sys 0m0.945s + +=============================================================================== + +cmake-format --in-place CMakeLists.txt + +real 0m0.233s +user 0m0.142s +sys 0m0.093s + +=============================================================================== + +cmake-lint CMakeLists.txt +CMakeLists.txt +============== +CMakeLists.txt:15,06: [C0103] Invalid directory variable name "exercise_cpp" doesn't match `[A-Z][0-9A-Z_]+|_[0-9a-z_]+` +CMakeLists.txt:17,06: [C0103] Invalid directory variable name "exercise_cpp" doesn't match `[A-Z][0-9A-Z_]+|_[0-9a-z_]+` +CMakeLists.txt:61,70: [C0307] Bad indentation: + ) + ^----BodyNode: 1:0->IfBlockNode: 59:0->BodyNode: 59:11->StatementNode: 60:2->TreeNode: 61:70 + +CMakeLists.txt:66,02: [C0113] Missing COMMENT in statement which allows it + +Summary +======= +files scanned: 1 +found lint: + Convention: 4 + + +real 0m0.224s +user 0m0.144s +sys 0m0.082s + +=============================================================================== + +Running: clang-format-16 -style=file -i ./prime_factors.cpp ./prime_factors_test.cpp ./prime_factors.h + +real 0m0.019s +user 0m0.012s +sys 0m0.006s + +=============================================================================== + +Running: ../../.github/citools/cpp/clang-check +clang-check-16 --analyze ./prime_factors.cpp ./prime_factors_test.cpp ./prime_factors.h +error: argument unused during compilation: '-stdlib=libstdc++' [-Werror,-Wunused-command-line-argument] +error: invalid argument '-std=c++17' not allowed with 'C' +/home/vpayno/git_vpayno/exercism-workspace/cpp/prime-factors/prime_factors.h:6:10: fatal error: 'vector' file not found +#include + ^~~~~~~~ +1 error generated. +Error while processing /home/vpayno/git_vpayno/exercism-workspace/cpp/prime-factors/prime_factors.h. + +real 0m0.502s +user 0m0.464s +sys 0m0.038s + + +real 0m0.504s +user 0m0.464s +sys 0m0.040s + +=============================================================================== + +Running: ../../.github/citools/cpp/clang-tidy | head -n 100 +6271 warnings generated. +41659 warnings generated. +41659 warnings and 3 errors generated. +Error while processing /home/vpayno/git_vpayno/exercism-workspace/cpp/prime-factors/prime_factors.h. +Suppressed 41664 warnings (41659 in non-user code, 5 NOLINT). +Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well. +Found compiler error(s). + +real 0m6.074s +user 0m5.994s +sys 0m0.080s +Running: clang-tidy-16 ./prime_factors.cpp ./prime_factors_test.cpp ./prime_factors.h +error: invalid argument '-std=c++17' not allowed with 'C' [clang-diagnostic-error] +error: argument unused during compilation: '-stdlib=libstdc++' [clang-diagnostic-unused-command-line-argument] +/home/vpayno/git_vpayno/exercism-workspace/cpp/prime-factors/prime_factors.h:6:10: error: 'vector' file not found [clang-diagnostic-error] +#include + ^~~~~~~~ + + +real 0m6.077s +user 0m5.997s +sys 0m0.080s + +=============================================================================== +