Skip to content

Commit

Permalink
Add a starting C++ solution
Browse files Browse the repository at this point in the history
  • Loading branch information
LivInTheLookingGlass committed Jul 19, 2024
1 parent c44c28c commit 611aca8
Show file tree
Hide file tree
Showing 14 changed files with 774 additions and 156 deletions.
95 changes: 95 additions & 0 deletions .github/workflows/cplusplus.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
name: C++

on:
push:
paths-ignore:
- 'docs/**'
- 'README.rst'
schedule:
- cron: "0 0 1 * *"

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
c-lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
submodules: true

- name: Setup clang-tidy
uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: clang-tidy
version: 1.0

- name: Run tests
run: make cpp_lint

cpp:
strategy:
fail-fast: false
matrix:
# compiler: ["llvm", "gcc"]
# # compiler targets (ideally): clang, gcc, MSVCC, pcc, tcc, icc,
os: [ubuntu-latest, windows-latest, macos-latest, macos-13, 'ubuntu-20.04']
# include:
# - os: windows-latest
# compiler: msvc
# - os: windows-latest
# compiler: mingw
runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v3
with:
submodules: true

- name: Use Python 3.10
uses: actions/setup-python@v5
with:
python-version: "3.10"
cache-dependency-path: '*/requirements.txt'

- name: Setup tcc, pcc
uses: awalsh128/cache-apt-pkgs-action@latest
if: ${{ matrix.os == 'ubuntu-latest' }}
with:
packages: tcc pcc
version: 1.0

- name: Setup MSVC
uses: aminya/setup-cpp@v1
if: ${{ contains(matrix.os, 'windows') }}
with:
compiler: msvc
vcvarsall: true

# - name: Set up MinGW
# if: ${{ contains(matrix.os, 'windows') }}
# uses: egor-tensin/setup-mingw@v2
# with:
# platform: x64

- name: Run tests (linux)
if: ${{ contains(matrix.os, 'ubuntu') }}
run: make c_test${{ (matrix.os != 'ubuntu-latest' && '_auto') || '' }} COV=true

- name: Run tests (windows)
if: ${{ contains(matrix.os, 'windows') }}
run: make c_test_auto

- name: Run tests (macos)
if: ${{ contains(matrix.os, 'macos') }}
run: make c_test_auto
env:
NO_OPTIONAL_TESTS: true
COMPILER_OVERRIDE: clang

- name: Upload coverage reports to Codecov
uses: codecov/[email protected]
with:
token: ${{ secrets.CODECOV_TOKEN }}
10 changes: 8 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ help:
@echo "The following jobs are available under the c_ prefix"
@$(MAKE) c_help $(MFLAGS) --no-print-directory
@echo
@echo "The following jobs are available under the cp_ prefix"
@$(MAKE) cp_help $(MFLAGS) --no-print-directory
@echo
@echo "The following jobs are available under the cs_ prefix"
@$(MAKE) cs_help $(MFLAGS) --no-print-directory
@echo
Expand All @@ -34,11 +37,14 @@ help:
html dirhtml singlehtml epub latex:
@$(MAKE) docs_$@ $(MFLAGS)

clean: cs_clean c_clean js_clean py_clean rs_clean docs_clean
clean: cs_clean cp_clean c_clean js_clean py_clean rs_clean docs_clean

cs_%:
@cd csharp && $(MAKE) $* $(MFLAGS)

cp_%:
@cd csharp && $(MAKE) $* $(MFLAGS)

c_%:
@cd c && $(MAKE) $* $(MFLAGS)

Expand All @@ -55,4 +61,4 @@ rs_%:
@cd rust && $(MAKE) $* $(MFLAGS)

%:
@$(MAKE) c_$* cs_$* js_$* py_$* rs_$* $(MFLAGS)
@$(MAKE) c_$* cp_$* cs_$* js_$* py_$* rs_$* $(MFLAGS)
7 changes: 6 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ LivInTheLookingGlass’s Project Euler solutions
:target: https://github.com/LivInTheLookingGlass/Euler/actions/workflows/c.yml
.. |C#i| image:: https://github.com/LivInTheLookingGlass/Euler/actions/workflows/csharp.yml/badge.svg
:target: https://github.com/LivInTheLookingGlass/Euler/actions/workflows/csharp.yml
.. |Cpi| image:: https://github.com/LivInTheLookingGlass/Euler/actions/workflows/cplusplus.yml/badge.svg
:target: https://github.com/LivInTheLookingGlass/Euler/actions/workflows/cplusplus.yml
.. |JavaScript| image:: https://github.com/LivInTheLookingGlass/Euler/actions/workflows/javascript.yml/badge.svg
:target: https://github.com/LivInTheLookingGlass/Euler/actions/workflows/javascript.yml
.. |Python| image:: https://github.com/LivInTheLookingGlass/Euler/actions/workflows/python.yml/badge.svg
Expand All @@ -28,11 +30,13 @@ LivInTheLookingGlass’s Project Euler solutions
+------------+---------------------+--------+---------------+
| Language | Version | Solved | Status |
+============+=====================+========+===============+
| C | C11+ in: ``gcc``, | 17 | |Ci| |
| C | C99+ in: ``gcc``, | 17 | |Ci| |
| | |br| ``clang``, | | |
| | ``msvc``, |br| | | |
| | ``pcc``, ``tcc`` | | |
+------------+---------------------+--------+---------------+
| C++ | C++98+ | 1 | |Cpi| |
+------------+---------------------+--------+---------------+
| C# | .NET 2+ | 5 | |C#i| |
+------------+---------------------+--------+---------------+
| JavaScript | Node 12+ | 5 | |JavaScript| |
Expand Down Expand Up @@ -77,6 +81,7 @@ The repo is divided into sections for each language. The top-level
Makefile will direct recipes using prefixes

- ``make c_*`` will go to the c Makefile
- ``make cp_*`` will go to the csharp Makefile
- ``make cs_*`` will go to the csharp Makefile
- ``make docs_*`` will go to the docs Makefile
- ``make js_*`` will go to the javascript Makefile
Expand Down
2 changes: 1 addition & 1 deletion c/p0000_template.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ unsigned long long p0000() {
#ifndef UNITY_END
int main(int argc, char const *argv[]) {
unsigned long long answer = p0000();
printf("%llu", answer);
printf("%llu\n", answer);
return 0;
}
#endif
Expand Down
42 changes: 42 additions & 0 deletions cplusplus/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
PY?=python3
USER_FLAG?=--user
PIP?=$(PY) -m pip
BLUE=\033[0;34m
NC=\033[0m # No Color

ifneq ($(https_proxy), )
PROXY_ARG=--proxy=$(https_proxy)
else
ifneq ($(http_proxy), )
PROXY_ARG=--proxy=$(http_proxy)
else
PROXY_ARG=
endif
endif

help:
@echo " $(BLUE)test$(NC) run through all tests in sequence. Utilizes the Python test runner infrastructure"
@echo " $(BLUE)test_*$(NC) run through all tests in parallel with the given number of threads. Use auto to allow the test runner to determine it. Utilizes the Python test runner infrastructure"
@echo " $(BLUE)dependencies$(NC) initialize submodules and install any Python dependencies"
@echo " $(BLUE)lint$(NC) run clang-tidy across each of the .cpp and .h files"
@echo " $(BLUE)clean$(NC) clean up any stray files"

test_%: dependencies
cd ../python; $(MAKE) dependencies $(MFLAGS)
$(PY) -m pytest -vl -n$* test_euler.py --cov

test: dependencies
$(PY) -m pytest -vl --benchmark-sort=fullname --benchmark-group-by=fullfunc --benchmark-verbose test_euler.py --cov

dependencies:
$(PIP) install -r requirements.txt -r ../python/requirements.txt $(USER_FLAG) $(PROXY_ARG)

lint:
if test -z "$(clang-tidy p0000_template.cpp -warnings-as-errors=* 2>&1 | grep "Unknown command line argument")"; then \
clang-tidy *.cpp -warnings-as-errors=-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling; \
else \
clang-tidy *.cpp; \
fi

clean:
rm -r build ./{*,*/*}{.pyc,__pycache__,.mypy_cache} || echo
85 changes: 85 additions & 0 deletions cplusplus/include/macros.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#ifndef MACROS_H
#define MACROS_H

// compiler info section

#if (defined(_MSC_VER) && !defined(__clang__))
#define CL_COMPILER 1
#else
#define CL_COMPILER 0
#endif
#if (defined(__clang__) && (!defined(AMD_COMPILER) || !AMD_COMPILER))
#define CLANG_COMPILER 1
#else
#define CLANG_COMPILER 0
#endif
#if (defined(__GNUC__) && !defined(__clang__)) && !defined(__INTEL_COMPILER)
#define GCC_COMPILER 1
#else
#define GCC_COMPILER 0
#endif
#ifdef __INTEL_COMPILER
#define INTEL_COMPILER 1
#else
#define INTEL_COMPILER 0
#endif
#ifndef AMD_COMPILER
#if CLANG_COMPILER
#warning "This suite can't detect the difference between clang and aocc. You need to specify -DAMD_COMPILER={0 or 1}"
#endif
#define AMD_COMPILER 0
#endif

#if (defined(_M_X64) || defined(_M_AMD64) || defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64))
#define X64_COMPILER 1
#else
#define X64_COMPILER 0
#endif
#if (!X64_COMPILER && (defined(_M_X86) || defined(_M_IX86) || defined(i386) || defined(__i386) || defined(__i386__) || defined(_X86_)))
#define X86_COMPILER 1
#else
#define X86_COMPILER 0
#endif
#if (defined(__arm__) || defined(__aarch64__) || defined(__thumb__) || defined(_M_ARM) || defined(_M_ARMT) || defined(__ARM_ARCH))
#define ARM_COMPILER 1
#else
#define ARM_COMPILER 0
#endif
#if (ARM_COMPILER && (defined(__thumb__) || defined(_M_ARMT)))
#define ARM_THUMB 1
#else
#define ARM_THUMB 0
#endif

// helper macro function section

#ifndef max
#define max(a, b) (((a) > (b)) ? (a) : (b))
#endif

#ifndef min
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif

#if !(CL_COMPILER)
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#else
#define likely(x) x
#define unlikely(x) x
#endif

// constants section

#define MAX_FACTORIAL_64 20
#define MAX_FACTORIAL_128 34
#define MAX_POW_10_16 10000U
#define POW_OF_MAX_POW_10_16 4
#define MAX_POW_10_32 1000000000UL
#define POW_OF_MAX_POW_10_32 9
#define MAX_POW_10_64 10000000000000000000ULL
#define POW_OF_MAX_POW_10_64 19
#define MAX_POW_10_128 ((uintmax_t) MAX_POW_10_64 * (uintmax_t) MAX_POW_10_64)
#define POW_OF_MAX_POW_10_128 38

#endif
25 changes: 25 additions & 0 deletions cplusplus/p0000_template.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
Project Euler Template
This template is used to format Project Euler solution scripts. This paragraph
should be replaced by a description of how I approached the problem, as well as
critque.
This paragraph should be replaced by the problem description, excluding images.
*/
#ifndef EULER_P0000
#define EULER_P0000
#include <stdio.h>

unsigned long long p0000() {
return 0;
}

#ifndef UNITY_END
int main(int argc, char const *argv[]) {
unsigned long long answer = p0000();
printf("%llu\n", answer);
return 0;
}
#endif
#endif
40 changes: 40 additions & 0 deletions cplusplus/p0001.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Project Euler Problem 1
*
* I did this the traditional way in C++, mostly because I want to see if there
* is a way to do iteration in native C++ before hacking together a solution just
* because I can.
*
* Problem:
*
* If we list all the natural numbers below 10 that are multiples of 3 or 5, we
* get 3, 5, 6 and 9. The sum of these multiples is 23.
*
* Find the sum of all the multiples of 3 or 5 below 1000.
*/
#ifndef EULER_P0001
#define EULER_P0001
#include <stdio.h>

unsigned long long p0001() {
unsigned long long answer = 0;
for (int i = 0; i < 1000; i += 3) {
answer += i;
}
for (int i = 0; i < 1000; i += 5) {
answer += i;
}
for (int i = 0; i < 1000; i += 15) {
answer -= i;
}
return answer;
}

#ifndef UNITY_END
int main(int argc, char const *argv[]) {
unsigned long long answer = p0001();
printf("%llu\n", answer);
return 0;
}
#endif
#endif
4 changes: 4 additions & 0 deletions cplusplus/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pytest
pytest-benchmark
sortedcontainers
u-msgpack-python
Loading

0 comments on commit 611aca8

Please sign in to comment.