From 112022f2465a0245470e7e1aecc9cdfa694fe63a Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Wed, 25 Sep 2019 22:35:56 -0700 Subject: [PATCH 01/41] Add partial support for pcc compiler --- .scripts/shippable_script.sh | 14 ++++++++++++++ c/include/macros.h | 8 ++++++-- c/test_euler.py | 28 +++++++++++++++++++++++----- shippable.yml | 4 ++++ 4 files changed, 47 insertions(+), 7 deletions(-) diff --git a/.scripts/shippable_script.sh b/.scripts/shippable_script.sh index 77a4acfd..bbe876bc 100644 --- a/.scripts/shippable_script.sh +++ b/.scripts/shippable_script.sh @@ -30,6 +30,20 @@ else else sudo apt-get update sudo apt-get install -y gcc clang tcc python3-pip + if [ $pcc ]; then + sudo apt-get install -y build-essential flex bison + mkdir pcc pcc-libs + wget -O - -o /dev/null http://pcc.ludd.ltu.se/ftp/pub/pcc/pcc-20190926.tgz | tar -xz --no-seek -C pcc --strip-components=1 + wget -O - -o /dev/null http://pcc.ludd.ltu.se/ftp/pub/pcc-libs/pcc-libs-20190926.tgz | tar -xz --no-seek -C pcc-libs --strip-components=1 + cd pcc + sed -i 's/MANPAGE=@BINPREFIX@cpp/MANPAGE=@BINPREFIX@pcc-cpp/' cc/cpp/Makefile.in + ./configure --prefix=/usr --libexecdir=/usr/lib/{x86_64,i386}-linux-gnu + sudo make install + cd ../pcc-libs + ./configure --prefix=/usr --libexecdir=/usr/lib/{x86_64,i386}-linux-gnu + sudo make install + cd .. + fi cd c && make test USER_FLAG= fi fi diff --git a/c/include/macros.h b/c/include/macros.h index 8e680036..3e461cd7 100644 --- a/c/include/macros.h +++ b/c/include/macros.h @@ -11,7 +11,7 @@ #else #define CLANG_COMPILER 0 #endif -#if (defined(__GNUC__) && !defined(__clang__)) && !defined(__INTEL_COMPILER) +#if (defined(__GNUC__) && !defined(__clang__)) && !defined(__INTEL_COMPILER) && !defined(__PCC__) #define GCC_COMPILER 1 #else #define GCC_COMPILER 0 @@ -21,7 +21,11 @@ #else #define INTEL_COMPILER 0 #endif -#define PCC_COMPILER 0 +#ifdef __PCC__ + #define PCC_COMPILER 1 +#else + #define PCC_COMPILER 0 +#endif #define TCC_COMPILER (!CL_COMPILER && !CLANG_COMPILER && !GCC_COMPILER && !INTEL_COMPILER && !PCC_COMPILER) #ifndef max diff --git a/c/test_euler.py b/c/test_euler.py index facdb07b..e770d9db 100644 --- a/c/test_euler.py +++ b/c/test_euler.py @@ -5,7 +5,7 @@ from pathlib import Path from platform import machine, processor, system from shutil import rmtree, which -from subprocess import check_call, check_output +from subprocess import CalledProcessError, check_call, check_output from sys import path from tempfile import TemporaryFile from typing import List, Set, Union @@ -34,6 +34,11 @@ known_slow: Set[int] = set() # this is the set of problems where I have the right answer but wrong solution +fails_pcc: Set[Union[str, int]] = {3, 5, 7, 10, 34, 'is_prime'} +# this is the set of tests that fail on PCC compiler +# this is because (at least on my system) including or result in syntax errors +# for the moment that is just limited to anything that includes primes.h or digits.h + # platform variables section IN_WINDOWS = system() == 'Windows' @@ -95,7 +100,8 @@ 'CLANG': "clang {} -O2 -lm -Werror -std=c11 -o {}", 'CL': "cl -Fe:{1} -Foobjs\\ -O2 -TC {0}", 'TCC': "tcc -lm -Werror -o {1} {0}", - 'ICC': "icc {} -O2 -lm -Werror -std=c11 -o {}" + 'ICC': "icc {} -O2 -lm -Werror -std=c11 -o {}", + 'PCC': "pcc -O2 -o {1} {0}", } if 'COMPILER_OVERRIDE' in environ: @@ -113,9 +119,7 @@ def cleanup_objs(): makedirs('objs', exist_ok=True) compilers.append('CL') - if which('pcc'): - raise NotImplementedError() - for x in ('clang', 'icc', 'tcc'): + for x in ('clang', 'icc', 'pcc', 'tcc'): if which(x): compilers.append(x.upper()) if not compilers: @@ -180,6 +184,13 @@ def test_is_prime(benchmark, compiler): # sometimes benchmark disables itself, so check for .stats if hasattr(benchmark, 'stats') and benchmark.stats.stats.max > 200 * MAX_PRIME // 1000000: fail("Exceeding 200ns average!") + except CalledProcessError: + if compiler == 'PCC' and 'is_prime' in fails_pcc: + xfail("Including or on PCC seems to yield syntax errors") + raise + else: + if compiler == 'PCC' and 'is_prime' in fails_pcc: + fail("This test is expected to fail, yet it didn't!") finally: try: remove(exename) @@ -205,6 +216,13 @@ def test_problem(benchmark, key, compiler): if hasattr(benchmark, 'stats') and benchmark.stats.stats.max > 60: fail_func = xfail if key in known_slow else fail fail_func("Exceeding 60s!") + except CalledProcessError: + if compiler == 'PCC' and key in fails_pcc: + xfail("Including or on PCC seems to yield syntax errors") + raise + else: + if compiler == 'PCC' and key in fails_pcc: + fail("This test is expected to fail, yet it didn't!") finally: try: remove(exename) diff --git a/shippable.yml b/shippable.yml index e9c090f7..7a7acff5 100644 --- a/shippable.yml +++ b/shippable.yml @@ -36,8 +36,12 @@ matrix: - language: c env: COMPILER_OVERRIDE=tcc python: 3.7 + - language: c + env: COMPILER_OVERRIDE=pcc pcc=true + python: 3.7 allow_failures: - env: COMPILER_OVERRIDE=tcc + - env: COMPILER_OVERRIDE=pcc pcc=true build: ci: From c9649135363805cea8b14a01896fb030f1136dba Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Thu, 26 Sep 2019 07:58:36 -0700 Subject: [PATCH 02/41] Adjust compiler installation methods --- .scripts/shippable_script.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.scripts/shippable_script.sh b/.scripts/shippable_script.sh index bbe876bc..003cd22d 100644 --- a/.scripts/shippable_script.sh +++ b/.scripts/shippable_script.sh @@ -29,7 +29,6 @@ else make clint else sudo apt-get update - sudo apt-get install -y gcc clang tcc python3-pip if [ $pcc ]; then sudo apt-get install -y build-essential flex bison mkdir pcc pcc-libs @@ -38,11 +37,13 @@ else cd pcc sed -i 's/MANPAGE=@BINPREFIX@cpp/MANPAGE=@BINPREFIX@pcc-cpp/' cc/cpp/Makefile.in ./configure --prefix=/usr --libexecdir=/usr/lib/{x86_64,i386}-linux-gnu - sudo make install + sudo make && make install cd ../pcc-libs ./configure --prefix=/usr --libexecdir=/usr/lib/{x86_64,i386}-linux-gnu - sudo make install + sudo make && make install cd .. + else + sudo apt-get install -y $COMPILER_OVERRIDE python3-pip fi cd c && make test USER_FLAG= fi From 57e1e61aef30af619d21bb64666d1fb3706fd48f Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Thu, 26 Sep 2019 20:28:06 -0700 Subject: [PATCH 03/41] Update readme, add provisional support for aocc --- README.md | 2 +- c/README.md | 17 ++++++++++++++++- c/include/macros.h | 1 + c/test_euler.py | 6 ++++-- c/tests/test_compiler_macros.c | 3 ++- 5 files changed, 24 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 3afecb71..0fa61cec 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,6 @@ The repo is divided into sections for each language. The top-level Makefile will 1: Windows testing is only enabled for Python and Javascript at the moment until I get configuration set up correctly for CL -2: Linux testing is done on Ubuntu 14.04 for C, Python, and Javascript. C compilers are gcc, clang, and tcc +2: Linux testing is done on Ubuntu 14.04 for C, Python, and Javascript. C compilers are gcc, clang, tcc, and pcc. The pcc and tcc compilers are marked as allowed failures because tcc implements no optimizations and might have time failures, and pcc seems to have errors including `` and `` 3: OSX testing is done on C, Python, and Javascript. C compilers are gcc and clang diff --git a/c/README.md b/c/README.md index a0ba50ce..7050deb7 100644 --- a/c/README.md +++ b/c/README.md @@ -24,6 +24,20 @@ This recipe runs tests in multiple threads, using however many are specified by ## Tests +### Compiler Detection Macros + +There are a set of macros which detect which compiler is being used. While these are not actively used in any of the problems, they are checked for validity with each test. + +### Prime Infrastructure Test + +This test checks five things: + +1. It checks `is_prime()` for numbers up to `MAX_PRIME`, where that is defined in the test +2. It checks that `is_composite()` returns truthy values on composites in that range, and falsey values on primes +3. It checks that `is_composite()` returns the smallest prime factor on composite numbers +4. It checks that the prime numbers are generated in the correct order +5. It checks that all these operations are completed in less than 200ns * `MAX_PRIME` + ### Generic Problems For each problem it will check the answer against a known dictionary. If the problem is not in the "known slow" category (meaning that I generate the correct answer with a poor solution), it will run it as many times as the benchmark plugin wants. Otherwise it is run exactly once. @@ -42,11 +56,12 @@ Note that there are optional test that leverage the Python infrastructure. If yo If this variable is defined, it should contain a comma-separated list of the compilers you would like to test from the following list (case insensitive): +* aocc (not yet supported) * cl * clang * gcc * icc (not yet supported) -* pcc (not yet supported) +* pcc (partial support) * tcc If this variable is not defined, compilers will be auto-detected using `which()`. diff --git a/c/include/macros.h b/c/include/macros.h index 3e461cd7..3fe23910 100644 --- a/c/include/macros.h +++ b/c/include/macros.h @@ -21,6 +21,7 @@ #else #define INTEL_COMPILER 0 #endif +#define AMD_COMPILER 0 #ifdef __PCC__ #define PCC_COMPILER 1 #else diff --git a/c/test_euler.py b/c/test_euler.py index e770d9db..5b153e83 100644 --- a/c/test_euler.py +++ b/c/test_euler.py @@ -102,6 +102,7 @@ 'TCC': "tcc -lm -Werror -o {1} {0}", 'ICC': "icc {} -O2 -lm -Werror -std=c11 -o {}", 'PCC': "pcc -O2 -o {1} {0}", + 'AOCC': "aocc {} -O2 -lm -Werror -std=c11 -o {}", } if 'COMPILER_OVERRIDE' in environ: @@ -119,7 +120,7 @@ def cleanup_objs(): makedirs('objs', exist_ok=True) compilers.append('CL') - for x in ('clang', 'icc', 'pcc', 'tcc'): + for x in ('aocc', 'clang', 'icc', 'pcc', 'tcc'): if which(x): compilers.append(x.upper()) if not compilers: @@ -145,11 +146,12 @@ def test_compiler_macros(compiler): try: check_call(templates[compiler].format(test_path, exename).split()) buff = check_output([exename]) - is_CL, is_CLANG, is_GCC, is_INTEL, is_PCC, is_TCC = (int(x) for x in buff.split()) + is_CL, is_CLANG, is_GCC, is_INTEL, is_AMD, is_PCC, is_TCC = (int(x) for x in buff.split()) assert bool(is_CL) == (compiler == "CL") assert bool(is_CLANG) == (compiler == "CLANG") assert bool(is_GCC) == (compiler == "GCC") assert bool(is_INTEL) == (compiler == "ICC") + assert bool(is_AMD) == (compiler == "AOCC") assert bool(is_PCC) == (compiler == "PCC") assert bool(is_TCC) == (compiler == "TCC") finally: diff --git a/c/tests/test_compiler_macros.c b/c/tests/test_compiler_macros.c index 8cc2d38b..acac4f3c 100644 --- a/c/tests/test_compiler_macros.c +++ b/c/tests/test_compiler_macros.c @@ -3,11 +3,12 @@ int main(int argc, char const *argv[]) { printf( - "%d %d %d %d %d %d", + "%d %d %d %d %d %d %d", CL_COMPILER, CLANG_COMPILER, GCC_COMPILER, INTEL_COMPILER, + AMD_COMPILER, PCC_COMPILER, TCC_COMPILER ); From 44d6bc043b274fcd8ecaa377778960a49aa84416 Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Thu, 26 Sep 2019 20:28:45 -0700 Subject: [PATCH 04/41] Fix linting errors, add gruopwise test --- python/test_euler.py | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/python/test_euler.py b/python/test_euler.py index 9ca69c14..2d937f7c 100644 --- a/python/test_euler.py +++ b/python/test_euler.py @@ -3,10 +3,10 @@ from pathlib import Path from shutil import which from sys import path -from typing import Any, Union +from typing import Any, Callable, Union from warnings import warn -from pytest import fail, fixture, skip, xfail +from pytest import fail, fixture, mark, skip, xfail from umsgpack import load PY_FOLDER = Path(__file__).parent @@ -14,6 +14,7 @@ from p0003 import primes # noqa: E402 # isort:skip from p0007 import is_prime # noqa: E402 # isort:skip +from p0008 import groupwise # noqa: E402 # isort:skip answers = { 1: 233168, @@ -123,7 +124,21 @@ def key(request): # type: ignore return int(request.param) # reduce processing burden on test -def test_is_prime(benchmark) -> None: +@mark.parametrize("group_size_str", ("{:0>2}".format(x) for x in range(2, 65))) +def test_groupwise(benchmark: Any, group_size_str: str) -> None: + def test_func(): + return tuple(groupwise(range(10_000 + group_size), group_size)) + + if ONLY_SLOW or NO_OPTIONAL_TESTS: + skip() + group_size = int(group_size_str) + groups = benchmark(test_func) + comparison = tuple(range(10_000 + group_size)) # adding group_size produces an equal number of groups + for idx, group in enumerate(groups): + assert group == comparison[idx:idx+group_size] + + +def test_is_prime(benchmark: Any) -> None: def func(set_of_primes): last = 2 for x, y in zip(primes(), set_of_primes): @@ -145,13 +160,13 @@ def func(set_of_primes): def test_problem(benchmark: Any, key: int) -> None: if (NO_SLOW and key in known_slow) or (ONLY_SLOW and key not in known_slow): skip() - module = __import__("p{:0>4}".format(key)) + test_func: Callable[[], int] = __import__("p{:0>4}".format(key)).main # type: ignore if key in known_slow: - answer = benchmark.pedantic(module.main, iterations=1, rounds=1) + answer = benchmark.pedantic(test_func, iterations=1, rounds=1) else: - answer = benchmark(module.main) + answer = benchmark(test_func) assert answers[key] == answer - del module + del test_func gc.collect() # sometimes benchmark disables itself, so check for .stats if hasattr(benchmark, 'stats') and benchmark.stats.stats.max > 60: From 73f224600919c37db9ac1af71873e0b0d890bf4e Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Thu, 26 Sep 2019 20:32:40 -0700 Subject: [PATCH 05/41] Fix linting makefile recipe --- python/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/Makefile b/python/Makefile index 54c15855..8c189d69 100644 --- a/python/Makefile +++ b/python/Makefile @@ -13,7 +13,7 @@ ifeq ($(LINT),false) pytest_args?= -v --benchmark-min-time=0.05 --benchmark-sort=fullname --benchmark-group-by=fullfunc --benchmark-verbose else ifeq ($(LINT),true) -pytest_args?= -v --mypy --mypy-ignore-missing-imports --flake8 --isort -k 'not test_problem and not test_is_prime' +pytest_args?= -v --mypy --mypy-ignore-missing-imports --flake8 --isort -k 'not test_problem and not test_is_prime and not test_groupwise' else ifeq ($(LINT),less) pytest_args?= -v --flake8 --isort --benchmark-min-time=0.05 --benchmark-sort=fullname --benchmark-group-by=fullfunc --benchmark-verbose From 77e337f67e229ac5b36a7915aa2ca20efc47dc5f Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Thu, 26 Sep 2019 20:35:00 -0700 Subject: [PATCH 06/41] Add node.js v11 tests --- .travis.yml | 8 ++++++-- shippable.yml | 7 +++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8a0498c4..2aed9e7e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,13 +7,17 @@ matrix: # pydist=macports # pydist=homebrew - language: node_js - node_js: "10" + node_js: "11" os: osx - env: jsver=10 linter=true + env: jsver=11 linter=true - language: c os: osx env: linter=true script: brew install llvm; ln -s "/usr/local/opt/llvm/bin/clang-tidy" "/usr/local/bin/clang-tidy"; make clint + - language: node_js + node_js: "11" + os: osx + env: jsver=11 - language: node_js node_js: "10" os: osx diff --git a/shippable.yml b/shippable.yml index 7a7acff5..6767bbef 100644 --- a/shippable.yml +++ b/shippable.yml @@ -14,10 +14,13 @@ matrix: - python: 3.7 env: pyver=true linter=true - language: node_js - node_js: "10" - env: jsver=10 linter=true + node_js: "11" + env: jsver=11 linter=true - language: c env: linter=true + - language: node_js + node_js: "11" + env: jsver=11 - language: node_js node_js: "10" env: jsver=10 From d54720324b54c1028b95405f3729059b8d6c2c88 Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Thu, 26 Sep 2019 21:05:26 -0700 Subject: [PATCH 07/41] Try a release build of PCC to see if there's no syntax errors --- .scripts/shippable_script.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.scripts/shippable_script.sh b/.scripts/shippable_script.sh index 003cd22d..3cfbb67b 100644 --- a/.scripts/shippable_script.sh +++ b/.scripts/shippable_script.sh @@ -32,8 +32,8 @@ else if [ $pcc ]; then sudo apt-get install -y build-essential flex bison mkdir pcc pcc-libs - wget -O - -o /dev/null http://pcc.ludd.ltu.se/ftp/pub/pcc/pcc-20190926.tgz | tar -xz --no-seek -C pcc --strip-components=1 - wget -O - -o /dev/null http://pcc.ludd.ltu.se/ftp/pub/pcc-libs/pcc-libs-20190926.tgz | tar -xz --no-seek -C pcc-libs --strip-components=1 + wget -O - -o /dev/null http://pcc.ludd.ltu.se/ftp/pub/pcc-releases/pcc-1.1.0.tgz | tar -xz --no-seek -C pcc --strip-components=1 + wget -O - -o /dev/null http://pcc.ludd.ltu.se/ftp/pub/pcc-releases/pcc-libs-1.1.0.tgz | tar -xz --no-seek -C pcc-libs --strip-components=1 cd pcc sed -i 's/MANPAGE=@BINPREFIX@cpp/MANPAGE=@BINPREFIX@pcc-cpp/' cc/cpp/Makefile.in ./configure --prefix=/usr --libexecdir=/usr/lib/{x86_64,i386}-linux-gnu From 488c9a0bf267f021a96ad052f47a96940d7480fe Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Thu, 26 Sep 2019 21:32:47 -0700 Subject: [PATCH 08/41] Further optimize python/p0076 --- python/p0076.py | 25 +++++++++++++++++-------- python/test_euler.py | 2 +- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/python/p0076.py b/python/p0076.py index 6b85786a..b58cac42 100644 --- a/python/p0076.py +++ b/python/p0076.py @@ -19,6 +19,11 @@ a, b, n in [0, 100] is (100 - n) / 2 + 1. Additionally, I ported the optimization from Revision 2 to work in the case of the 2s count. These together brought runtime down from ~6m 40s -> ~1m 15s. +Revision 4: + +Switch to defaultdict for counter storage, and replace 2 instances of sum() with closed-form math. Total speed increase +is ~1m 15s -> ~45s. + Problem: It is possible to write five as a sum in exactly six different ways: @@ -33,28 +38,32 @@ How many different ways can one hundred be written as a sum of at least two positive integers? """ -from typing import List +from collections import defaultdict +from typing import DefaultDict def main() -> int: answer = 0 - counts: List[int] = [0] * 101 + counts: DefaultDict[int, int] = defaultdict(int) total = counts[2] = 100 - while not counts[100]: + while True: counts[2] += 2 if total >= 100: answer += (100 + counts[2] - total) // 2 - counts[2] = 0 # because I can't do-while + # because I can't do-while[] + total += 3 - counts[2] + counts[2] = 0 # set to 0 instead of delete because it will be quickly set again counts[3] += 3 idx = 3 - total = sum(counts) while total > 100: - counts[idx] = 0 + total += 1 + idx - counts[idx] + del counts[idx] idx += 1 counts[idx] += idx - total = sum(counts) + if idx == 100: + break counts[2] = 100 - total - (total % 2) - total = sum(counts) + total = sum(counts.values()) return answer diff --git a/python/test_euler.py b/python/test_euler.py index 2d937f7c..d5216f59 100644 --- a/python/test_euler.py +++ b/python/test_euler.py @@ -89,7 +89,7 @@ 206: 1389019170, } -known_slow = {76, 118, 123, 145} +known_slow = {118, 123, 145} # this is the set of problems where I have the right answer but wrong solution IN_TERMUX = bool(which('termux-setup-storage')) From d2562bb9de4bbc607a1134d94e5268acbb857637 Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Thu, 26 Sep 2019 22:32:25 -0700 Subject: [PATCH 09/41] Microoptimization to python/p0145 --- python/p0145.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/p0145.py b/python/p0145.py index 02938ed8..3dc92361 100644 --- a/python/p0145.py +++ b/python/p0145.py @@ -26,14 +26,14 @@ def main() -> int: seen: Set[int] = set() + seen_update = seen.update odd_digits = {"1", "3", "5", "7", "9"} for x in chain.from_iterable(range(x, 10**8 // 2, 10) for x in range(1, 10)): if x in seen: continue inverse = int(repr(x)[::-1]) if all(digit in odd_digits for digit in repr(x + inverse)): - # print(x, inverse) - seen.update((x, inverse)) + seen_update((x, inverse)) return len(seen) From 7bef249edc1c5a84d747f915cea6754d7921c808 Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Thu, 26 Sep 2019 22:33:28 -0700 Subject: [PATCH 10/41] Re-add python/p0076 to known_slow Turns out that Appveyor runs ~half the speed of my laptop, so that's good to note for future tests --- python/test_euler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/test_euler.py b/python/test_euler.py index d5216f59..2d937f7c 100644 --- a/python/test_euler.py +++ b/python/test_euler.py @@ -89,7 +89,7 @@ 206: 1389019170, } -known_slow = {118, 123, 145} +known_slow = {76, 118, 123, 145} # this is the set of problems where I have the right answer but wrong solution IN_TERMUX = bool(which('termux-setup-storage')) From 444ccdadfd93119c30d83e03b5d1c5d6c3907b9b Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Thu, 26 Sep 2019 23:17:58 -0700 Subject: [PATCH 11/41] add ONLY_SLOW test to shippable, appveyor --- appveyor.yml | 7 +++++++ shippable.yml | 3 +++ 2 files changed, 10 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index 9df992c0..168fa0f8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -44,9 +44,16 @@ environment: PYPY: "powershell.exe %APPVEYOR_BUILD_FOLDER%\\.scripts\\installpypy3.ps1" NO_SLOW: "true" + - PYTHON: "C:\\Python37-x64" + PYTHON_VERSION: "3.7" + RUN: "%PYTHON%\\python" + PIP: "%PYTHON%\\Scripts\\pip" + ONLY_SLOW: "true" + matrix: allow_failures: - PYTHON_VERSION: "pypy3" + - ONLY_SLOW: "true" test: off diff --git a/shippable.yml b/shippable.yml index 6767bbef..7a572075 100644 --- a/shippable.yml +++ b/shippable.yml @@ -42,9 +42,12 @@ matrix: - language: c env: COMPILER_OVERRIDE=pcc pcc=true python: 3.7 + - python: 3.7 + env: pyver=true ONLY_SLOW=true NO_SLOW= allow_failures: - env: COMPILER_OVERRIDE=tcc - env: COMPILER_OVERRIDE=pcc pcc=true + - env: pyver=true ONLY_SLOW=true NO_SLOW= build: ci: From 30e5fb59b0a572a57fe5907e22bad40f51b36c27 Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Fri, 27 Sep 2019 07:27:19 -0700 Subject: [PATCH 12/41] Attempt to work around PCC's include errors The theory here is that I won't need to reimplement free/malloc/realloc, and if I reimplement the math portions then it can compile --- c/include/digits.h | 28 ++++++++++++++++++++++++++-- c/include/primes.h | 30 ++++++++++++++++++++++++++++-- 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/c/include/digits.h b/c/include/digits.h index 84f9b7ce..43bfef64 100644 --- a/c/include/digits.h +++ b/c/include/digits.h @@ -1,9 +1,33 @@ #ifndef _DIGITS #define _DIGITS +#include "macros.h" #include "iterator.h" -#include -#include + +#if !PCC_COMPILER + #include + #include +#else + #include "primes.h" + + double ln(double x) { + double old_sum = 0.0; + double xmlxpl = (x - 1) / (x + 1); + double xmlxpl_2 = xmlxpl * xmlxpl; + double denom = 1.0; + double frac = xmlxpl; + double term = frac; // denom start from 1.0 + double sum = term; + while (sum != old_sum) { + old_sum = sum; + denom += 2.0; + frac *= xmlxpl_2; + sum += frac / denom; + } + return 2.0 * sum; + } + #define log10(x) ln(x) / 2.3025850929940456840179914546844 +#endif typedef struct digit_counter digit_counter; struct digit_counter { diff --git a/c/include/primes.h b/c/include/primes.h index 0e6f5019..5b059f4e 100644 --- a/c/include/primes.h +++ b/c/include/primes.h @@ -1,10 +1,36 @@ #ifndef _PRIMES #define _PRIMES -#include -#include +#include "macros.h" + +#if !PCC_COMPILER + #include + #include +#endif + #include "iterator.h" +#if PCC_COMPILER + double sqrt(double S) { + // implements the Bakhshali method of square root computation to fix a PCC error + double a, x = S / 2; + unsigned int i; + for (i = 0; i < 8; i++) { + a = (S - x*x) / (2 * x); + x = x + a - (a * a) / (2 * (x + a)); + } + return x; + } + + unsigned long long ceil(double x) { + unsigned long long ret = (unsigned long long) x; + if (x == (double) ret) { + return ret; + } + return ret + 1; + } +#endif + typedef struct prime_sieve prime_sieve; typedef struct prime_counter prime_counter; struct prime_counter { From a68a592bc6cb7324b03df78e05316ef9e1b1b31e Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Fri, 27 Sep 2019 07:32:39 -0700 Subject: [PATCH 13/41] Reorder shippable tests --- shippable.yml | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/shippable.yml b/shippable.yml index 7a572075..b9c4cdcc 100644 --- a/shippable.yml +++ b/shippable.yml @@ -1,16 +1,7 @@ language: python -python: - - 3.7 - - pypy3 - -env: - - pyver: "true" - NO_SLOW: "true" - matrix: include: - - env: py36=true pyver=true NO_SLOW=true - python: 3.7 env: pyver=true linter=true - language: node_js @@ -42,8 +33,13 @@ matrix: - language: c env: COMPILER_OVERRIDE=pcc pcc=true python: 3.7 - - python: 3.7 - env: pyver=true ONLY_SLOW=true NO_SLOW= + - env: pyver=true NO_SLOW=true + python: 3.7 + - env: py36=true pyver=true NO_SLOW=true + - env: pyver=true NO_SLOW=true + python: pypy3 + - env: pyver=true ONLY_SLOW=true NO_SLOW= + python: 3.7 allow_failures: - env: COMPILER_OVERRIDE=tcc - env: COMPILER_OVERRIDE=pcc pcc=true From 9d58740dc3a06e406d7ee8197dfad796df75e0f6 Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Fri, 27 Sep 2019 12:27:59 -0700 Subject: [PATCH 14/41] Improve PCC support; rework test file --- .gitignore | 4 +- .stignore | 4 +- c/README.md | 2 +- c/include/digits.h | 27 +++----- c/test_euler.py | 152 +++++++++++++++++---------------------------- 5 files changed, 71 insertions(+), 118 deletions(-) diff --git a/.gitignore b/.gitignore index 4eb20384..4f324336 100644 --- a/.gitignore +++ b/.gitignore @@ -5,8 +5,6 @@ javascript/node_modules/** .vscode/** **log*.txt **/a.out -**/*.x86* **/*.exe -**/*.aarch64 -**/objs/** +**/build/** venv/** diff --git a/.stignore b/.stignore index 4124dc86..70cbc1c2 100644 --- a/.stignore +++ b/.stignore @@ -3,8 +3,6 @@ **/.mypy_cache/** javascript/node_modules/** **/a.out -**/*.x86* **/*.exe -**/*.aarch64 -**/objs/** +**/build/** venv/** diff --git a/c/README.md b/c/README.md index 7050deb7..068deff1 100644 --- a/c/README.md +++ b/c/README.md @@ -26,7 +26,7 @@ This recipe runs tests in multiple threads, using however many are specified by ### Compiler Detection Macros -There are a set of macros which detect which compiler is being used. While these are not actively used in any of the problems, they are checked for validity with each test. +There are a set of macros which detect which compiler is being used. These macros are mostly used to route around issues with particular compilers. For instance, PCC does not allow me to include `` or `` on the systems I've tested it on, so I need to route around that. This test checks that those macros are correct. ### Prime Infrastructure Test diff --git a/c/include/digits.h b/c/include/digits.h index 43bfef64..5f45164c 100644 --- a/c/include/digits.h +++ b/c/include/digits.h @@ -8,25 +8,14 @@ #include #include #else - #include "primes.h" - - double ln(double x) { - double old_sum = 0.0; - double xmlxpl = (x - 1) / (x + 1); - double xmlxpl_2 = xmlxpl * xmlxpl; - double denom = 1.0; - double frac = xmlxpl; - double term = frac; // denom start from 1.0 - double sum = term; - while (sum != old_sum) { - old_sum = sum; - denom += 2.0; - frac *= xmlxpl_2; - sum += frac / denom; + unsigned long long imprecise_log10(unsigned long long x) { + unsigned long long answer = 0; + while (x) { + x /= 10; + ++answer; } - return 2.0 * sum; + return answer; } - #define log10(x) ln(x) / 2.3025850929940456840179914546844 #endif typedef struct digit_counter digit_counter; @@ -46,7 +35,11 @@ unsigned char advance_digit_counter(digit_counter *dc) { digit_counter digits(unsigned long long n) { digit_counter ret; IteratorInitHead(ret, advance_digit_counter); +#if !PCC_COMPILER size_t digit_len = ceil(log10(n + 1)); +#else + size_t digit_len = imprecise_log10(n + 1); +#endif ret.digits = (unsigned char *) malloc(digit_len * sizeof(unsigned char)); for (size_t i = 0; i < digit_len; i++) { ret.digits[i] = n % 10; diff --git a/c/test_euler.py b/c/test_euler.py index 5b153e83..637f8a43 100644 --- a/c/test_euler.py +++ b/c/test_euler.py @@ -1,19 +1,19 @@ from atexit import register from functools import partial -from os import environ, makedirs, remove, sep -from os.path import expanduser +from os import environ, sep from pathlib import Path from platform import machine, processor, system from shutil import rmtree, which -from subprocess import CalledProcessError, check_call, check_output +from subprocess import check_call, check_output from sys import path from tempfile import TemporaryFile from typing import List, Set, Union from warnings import warn -from pytest import fail, fixture, skip, xfail +from pytest import fail, fixture, mark, skip, xfail C_FOLDER = Path(__file__).parent +BUILD_FOLDER = C_FOLDER.joinpath('build') path.append(str(C_FOLDER.parent.joinpath("python"))) answers = { @@ -44,6 +44,9 @@ IN_WINDOWS = system() == 'Windows' IN_TERMUX = bool(which('termux-setup-storage')) +if IN_TERMUX: + BUILD_FOLDER = Path.home().joinpath('build') # Termux can't make executable files outside of $HOME + _raw_NO_SLOW = environ.get('NO_SLOW') try: _parsed_NO_SLOW: Union[str, int, None] = int(_raw_NO_SLOW) # type: ignore @@ -84,12 +87,8 @@ EXE_EXT = "exe" SOURCE_TEMPLATE = "{}{}p{{:0>4}}.c".format(C_FOLDER, sep) -if IN_TERMUX: - EXE_TEMPLATE = "{}/p{{:0>4}}.{{}}.{}".format(expanduser("~"), EXE_EXT) - # Termux can't make executable files outside of $HOME -else: - EXE_TEMPLATE = "{}{}p{{:0>4}}.{{}}.{}".format(C_FOLDER, sep, EXE_EXT) - # include sep in the recipe so that Windows won't complain +EXE_TEMPLATE = "{}{}p{{:0>4}}.{{}}.{}".format(BUILD_FOLDER, sep, EXE_EXT) +# include sep in the recipe so that Windows won't complain GCC_BINARY = environ.get('GCC_OVERRIDE', 'gcc') @@ -98,7 +97,7 @@ templates = { 'GCC': "{} {{}} -O2 -lm -Werror -std=c11 -o {{}}".format(GCC_BINARY), 'CLANG': "clang {} -O2 -lm -Werror -std=c11 -o {}", - 'CL': "cl -Fe:{1} -Foobjs\\ -O2 -TC {0}", + 'CL': "cl -Fe:{{1}} -Fo{}\\ -O2 -TC {{0}}".format(BUILD_FOLDER.joinpath('objs').relative_to(Path.cwd())), 'TCC': "tcc -lm -Werror -o {1} {0}", 'ICC': "icc {} -O2 -lm -Werror -std=c11 -o {}", 'PCC': "pcc -O2 -o {1} {0}", @@ -111,14 +110,7 @@ if not (IN_TERMUX and GCC_BINARY == 'gcc') and which(GCC_BINARY): # Termux maps gcc->clang compilers.append('GCC') if which('cl'): - @register - def cleanup_objs(): - try: - rmtree('objs') # only present with cl compiler - except Exception: - pass # if in multiprocess, this race-conditions - - makedirs('objs', exist_ok=True) + BUILD_FOLDER.joinpath('objs').mkdir(parents=True, exist_ok=True) compilers.append('CL') for x in ('aocc', 'clang', 'icc', 'pcc', 'tcc'): if which(x): @@ -126,6 +118,13 @@ def cleanup_objs(): if not compilers: raise RuntimeError("No compilers detected!") +BUILD_FOLDER.mkdir(parents=True, exist_ok=True) + + +@register +def cleanup(): + rmtree(BUILD_FOLDER) + @fixture(params=sorted(compilers)) def compiler(request): # type: ignore @@ -138,66 +137,44 @@ def key(request): # type: ignore return int(request.param) # reduce casting burden on test +@mark.skipif('NO_OPTIONAL_TESTS') def test_compiler_macros(compiler): - if NO_OPTIONAL_TESTS: - skip() exename = EXE_TEMPLATE.format("test_compiler_macros", compiler) test_path = Path(__file__).parent.joinpath("tests", "test_compiler_macros.c") - try: - check_call(templates[compiler].format(test_path, exename).split()) - buff = check_output([exename]) - is_CL, is_CLANG, is_GCC, is_INTEL, is_AMD, is_PCC, is_TCC = (int(x) for x in buff.split()) - assert bool(is_CL) == (compiler == "CL") - assert bool(is_CLANG) == (compiler == "CLANG") - assert bool(is_GCC) == (compiler == "GCC") - assert bool(is_INTEL) == (compiler == "ICC") - assert bool(is_AMD) == (compiler == "AOCC") - assert bool(is_PCC) == (compiler == "PCC") - assert bool(is_TCC) == (compiler == "TCC") - finally: - try: - remove(exename) - except Exception: - warn("EXE may not have been deleted") - - + check_call(templates[compiler].format(test_path, exename).split()) + buff = check_output([exename]) + is_CL, is_CLANG, is_GCC, is_INTEL, is_AMD, is_PCC, is_TCC = (int(x) for x in buff.split()) + assert bool(is_CL) == (compiler == "CL") + assert bool(is_CLANG) == (compiler == "CLANG") + assert bool(is_GCC) == (compiler == "GCC") + assert bool(is_INTEL) == (compiler == "ICC") + assert bool(is_AMD) == (compiler == "AOCC") + assert bool(is_PCC) == (compiler == "PCC") + assert bool(is_TCC) == (compiler == "TCC") + + +@mark.skipif('NO_OPTIONAL_TESTS or ONLY_SLOW') def test_is_prime(benchmark, compiler): - if NO_OPTIONAL_TESTS or ONLY_SLOW: - skip() from p0007 import is_prime, prime_factors, primes - MAX_PRIME = 1_000_000 exename = EXE_TEMPLATE.format("test_is_prime", compiler) test_path = Path(__file__).parent.joinpath("tests", "test_is_prime.c") args = templates[compiler].format(test_path, exename) + " -DMAX_PRIME={}".format(MAX_PRIME) - try: - check_call(args.split()) - with TemporaryFile('wb+') as f: - run_test = partial(check_call, [exename], stdout=f) - benchmark.pedantic(run_test, iterations=1, rounds=1) - prime_cache = tuple(primes(MAX_PRIME)) - for line in f.readlines(): - num, prime, composite, idx = (int(x) for x in line.split()) - assert bool(prime) == bool(is_prime(num)) - assert bool(composite) == (not is_prime(num)) - assert composite == next(iter(prime_factors(num))) - assert idx == -1 or prime_cache[idx] == num - - # sometimes benchmark disables itself, so check for .stats - if hasattr(benchmark, 'stats') and benchmark.stats.stats.max > 200 * MAX_PRIME // 1000000: - fail("Exceeding 200ns average!") - except CalledProcessError: - if compiler == 'PCC' and 'is_prime' in fails_pcc: - xfail("Including or on PCC seems to yield syntax errors") - raise - else: - if compiler == 'PCC' and 'is_prime' in fails_pcc: - fail("This test is expected to fail, yet it didn't!") - finally: - try: - remove(exename) - except Exception: - warn("EXE may not have been deleted") + check_call(args.split()) + with TemporaryFile('wb+') as f: + run_test = partial(check_call, [exename], stdout=f) + benchmark.pedantic(run_test, iterations=1, rounds=1) + prime_cache = tuple(primes(MAX_PRIME)) + for line in f.readlines(): + num, prime, composite, idx = (int(x) for x in line.split()) + assert bool(prime) == bool(is_prime(num)) + assert bool(composite) == (not is_prime(num)) + assert composite == 0 or composite == next(iter(prime_factors(num))) + assert idx == -1 or prime_cache[idx] == num + + # sometimes benchmark disables itself, so check for .stats + if hasattr(benchmark, 'stats') and benchmark.stats.stats.max > 200 * MAX_PRIME // 1000000: + fail("Exceeding 200ns average!") def test_problem(benchmark, key, compiler): @@ -205,28 +182,15 @@ def test_problem(benchmark, key, compiler): skip() filename = SOURCE_TEMPLATE.format(key) exename = EXE_TEMPLATE.format(key, compiler) # need to have both to keep name unique - try: - check_call(templates[compiler].format(filename, exename).split()) - run_test = partial(check_output, [exename]) - - if key in known_slow: - answer = benchmark.pedantic(run_test, iterations=1, rounds=1) - else: - answer = benchmark(run_test) - assert answers[key] == int(answer.strip()) - # sometimes benchmark disables itself, so check for .stats - if hasattr(benchmark, 'stats') and benchmark.stats.stats.max > 60: - fail_func = xfail if key in known_slow else fail - fail_func("Exceeding 60s!") - except CalledProcessError: - if compiler == 'PCC' and key in fails_pcc: - xfail("Including or on PCC seems to yield syntax errors") - raise + check_call(templates[compiler].format(filename, exename).split()) + run_test = partial(check_output, [exename]) + + if key in known_slow: + answer = benchmark.pedantic(run_test, iterations=1, rounds=1) else: - if compiler == 'PCC' and key in fails_pcc: - fail("This test is expected to fail, yet it didn't!") - finally: - try: - remove(exename) - except Exception: - warn("EXE may not have been deleted") + answer = benchmark(run_test) + assert answers[key] == int(answer.strip()) + # sometimes benchmark disables itself, so check for .stats + if hasattr(benchmark, 'stats') and benchmark.stats.stats.max > 60: + fail_func = xfail if key in known_slow else fail + fail_func("Exceeding 60s!") From db738ca563f35eb3d8b902402924d219f3bc24af Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Fri, 27 Sep 2019 17:07:21 -0700 Subject: [PATCH 15/41] Move problem data to common folder --- {python => _data}/p0022_names.txt | 0 {python => _data}/p0042_words.txt | 0 {python => _data}/p0059_cipher.txt | 0 {python => _data}/p0067_triangle.txt | 0 python/p0022.py | 2 +- python/p0042.py | 2 +- python/p0059.py | 2 +- python/p0067.py | 2 +- 8 files changed, 4 insertions(+), 4 deletions(-) rename {python => _data}/p0022_names.txt (100%) rename {python => _data}/p0042_words.txt (100%) rename {python => _data}/p0059_cipher.txt (100%) rename {python => _data}/p0067_triangle.txt (100%) diff --git a/python/p0022_names.txt b/_data/p0022_names.txt similarity index 100% rename from python/p0022_names.txt rename to _data/p0022_names.txt diff --git a/python/p0042_words.txt b/_data/p0042_words.txt similarity index 100% rename from python/p0042_words.txt rename to _data/p0042_words.txt diff --git a/python/p0059_cipher.txt b/_data/p0059_cipher.txt similarity index 100% rename from python/p0059_cipher.txt rename to _data/p0059_cipher.txt diff --git a/python/p0067_triangle.txt b/_data/p0067_triangle.txt similarity index 100% rename from python/p0067_triangle.txt rename to _data/p0067_triangle.txt diff --git a/python/p0022.py b/python/p0022.py index acf770a3..9693fd04 100644 --- a/python/p0022.py +++ b/python/p0022.py @@ -26,7 +26,7 @@ def score(name: str, idx: int) -> int: def main() -> int: - with Path(__file__).parent.joinpath('p0022_names.txt').open('r') as f: + with Path(__file__).parent.parent.joinpath('_data', 'p0022_names.txt').open('r') as f: names = sorted(f.read().upper().replace('"', '').split(',')) return sum(score(name, idx) for idx, name in enumerate(names, 1)) diff --git a/python/p0042.py b/python/p0042.py index 30efdec9..275c34cc 100644 --- a/python/p0042.py +++ b/python/p0042.py @@ -36,7 +36,7 @@ def is_in_triangle(n: int) -> bool: def main(): answer = 0 - with Path(__file__).parent.joinpath('p0042_words.txt').open('rb') as f: + with Path(__file__).parent.parent.joinpath('_data', 'p0042_words.txt').open('rb') as f: words = f.read().replace(b'"', b'').split(b',') for word in words: value = sum(x - 64 for x in word) diff --git a/python/p0059.py b/python/p0059.py index c65eddd4..abd4ddf7 100644 --- a/python/p0059.py +++ b/python/p0059.py @@ -38,7 +38,7 @@ def main() -> int: - with Path(__file__).parent.joinpath('p0059_cipher.txt').open('r') as f: + with Path(__file__).parent.parent.joinpath('_data', 'p0059_cipher.txt').open('r') as f: ciphertext = bytes(int(x) for x in f.read().split(',')) for key in permutations(alphabet, 3): plaintext = bytes(x ^ y for x, y in zip(ciphertext, cycle(key))) diff --git a/python/p0067.py b/python/p0067.py index 72ae88e0..3abd112d 100644 --- a/python/p0067.py +++ b/python/p0067.py @@ -31,7 +31,7 @@ def main(): rows = [] - with Path(__file__).parent.joinpath("p0067_triangle.txt").open("r") as f: + with Path(__file__).parent.parent.joinpath("_data", "p0067_triangle.txt").open("r") as f: for line in f.readlines(): rows.append([int(x) for x in line.split()]) return reduce_triangle(rows) From 5bbf03340f3ad8abd0504536c5bf8551caf2e1cd Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Fri, 27 Sep 2019 17:09:36 -0700 Subject: [PATCH 16/41] Move new/redefined math functions to common file --- c/include/digits.h | 9 +-------- c/include/math.h | 44 ++++++++++++++++++++++++++++++++++++++++++++ c/include/primes.h | 23 ++--------------------- c/p0034.c | 9 +-------- 4 files changed, 48 insertions(+), 37 deletions(-) create mode 100644 c/include/math.h diff --git a/c/include/digits.h b/c/include/digits.h index 5f45164c..2758e8b1 100644 --- a/c/include/digits.h +++ b/c/include/digits.h @@ -8,14 +8,7 @@ #include #include #else - unsigned long long imprecise_log10(unsigned long long x) { - unsigned long long answer = 0; - while (x) { - x /= 10; - ++answer; - } - return answer; - } + #include "math.h" #endif typedef struct digit_counter digit_counter; diff --git a/c/include/math.h b/c/include/math.h new file mode 100644 index 00000000..4ec09e2f --- /dev/null +++ b/c/include/math.h @@ -0,0 +1,44 @@ +#ifndef _EULER_MATH_H +#define _EULER_MATH_H + +#include "macros.h" + +unsigned long long factorial(unsigned long long n) { + unsigned long long ret = 1; + for (unsigned long long i = 2; i <= n; i++) { + ret *= i; + } + return ret; +} + +#if PCC_COMPILER + unsigned long long imprecise_log10(unsigned long long x) { + unsigned long long answer = 0; + while (x) { + x /= 10; + ++answer; + } + return answer; + } + + double sqrt(double S) { + // implements the Bakhshali method of square root computation to fix a PCC error + double a, x = S / 2; + unsigned int i; + for (i = 0; i < 8; i++) { + a = (S - x*x) / (2 * x); + x = x + a - (a * a) / (2 * (x + a)); + } + return x; + } + + unsigned long long ceil(double x) { + unsigned long long ret = (unsigned long long) x; + if (x == (double) ret) { + return ret; + } + return ret + 1; + } +#endif + +#endif diff --git a/c/include/primes.h b/c/include/primes.h index 5b059f4e..12071c23 100644 --- a/c/include/primes.h +++ b/c/include/primes.h @@ -6,31 +6,12 @@ #if !PCC_COMPILER #include #include +#else + #include "math.h" #endif #include "iterator.h" -#if PCC_COMPILER - double sqrt(double S) { - // implements the Bakhshali method of square root computation to fix a PCC error - double a, x = S / 2; - unsigned int i; - for (i = 0; i < 8; i++) { - a = (S - x*x) / (2 * x); - x = x + a - (a * a) / (2 * (x + a)); - } - return x; - } - - unsigned long long ceil(double x) { - unsigned long long ret = (unsigned long long) x; - if (x == (double) ret) { - return ret; - } - return ret + 1; - } -#endif - typedef struct prime_sieve prime_sieve; typedef struct prime_counter prime_counter; struct prime_counter { diff --git a/c/p0034.c b/c/p0034.c index 221166fd..048f99e5 100644 --- a/c/p0034.c +++ b/c/p0034.c @@ -12,14 +12,7 @@ Note: as 1! = 1 and 2! = 2 are not sums they are not included. */ #include #include "include/digits.h" - -unsigned long long factorial(unsigned long long n) { - unsigned long long ret = 1; - for (unsigned long long i = 2; i <= n; i++) { - ret *= i; - } - return ret; -} +#include "include/math.h" int main(int argc, char const *argv[]) { unsigned long long answer = 0, sum; From 1383806fc3b97bfe6cd890cf9575d6a30b0a91fc Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Sat, 28 Sep 2019 21:35:50 -0700 Subject: [PATCH 17/41] Solve c/p0015 --- c/include/macros.h | 4 +++ c/include/math.h | 77 ++++++++++++++++++++++++++++++++++++++++++---- c/p0015.c | 28 +++++++++++++++++ c/test_euler.py | 5 +-- 4 files changed, 106 insertions(+), 8 deletions(-) create mode 100644 c/p0015.c diff --git a/c/include/macros.h b/c/include/macros.h index 3fe23910..d42e3454 100644 --- a/c/include/macros.h +++ b/c/include/macros.h @@ -37,4 +37,8 @@ #define min(a, b) (((a) < (b)) ? (a) : (b)) #endif +#define MAX_FACTORIAL_64 20 +#define MAX_FACTORIAL_32 12 +#define PCC_SQRT_ACCURACY 8 + #endif diff --git a/c/include/math.h b/c/include/math.h index 4ec09e2f..d2974d6c 100644 --- a/c/include/math.h +++ b/c/include/math.h @@ -1,18 +1,81 @@ #ifndef _EULER_MATH_H #define _EULER_MATH_H +#if !PCC_COMPILER + #include +#endif + #include "macros.h" -unsigned long long factorial(unsigned long long n) { +unsigned long long factorial(unsigned long long n); +inline unsigned long long factorial(unsigned long long n) { unsigned long long ret = 1; - for (unsigned long long i = 2; i <= n; i++) { + for (unsigned long long i = 2; i <= n; ++i) { ret *= i; } return ret; } +unsigned long long n_choose_r(unsigned long long n, unsigned long long r) { + // function returns -1 if it overflows + if ((sizeof(unsigned long long) == 8 && n <= MAX_FACTORIAL_64) || (sizeof(unsigned long long) == 4 && n <= MAX_FACTORIAL_32)) { + // fast path if small enough + return factorial(n) / factorial(r) / factorial(n-r); + } + // slow path for larger numbers + signed char *factors; + unsigned long long answer, i, j; + factors = (signed char *) malloc(sizeof(signed char) * (n + 1)); + // collect factors of final number + for (i = 2; i <= n; i++) { + factors[i] = 1; + } + // negative factor values indicate need to divide + for (i = 2; i <= r; i++) { + factors[i] -= 1; + } + for (i = 2; i <= n - r; i++) { + factors[i] -= 1; + } + // this loop reduces to prime factors only + for (i = n; i > 1; i--) { + for (j = 2; j < i; j++) { + if (i % j == 0) { + factors[j] += factors[i]; + factors[i / j] += factors[i]; + factors[i] = 0; + break; + } + } + } + i = 2; + answer = 1; + while (i < n) { + while (factors[i] > 0) { + j = answer; + answer *= i; + if (answer < j) { + return -1; // this indicates an overflow + } + factors[i]--; + } + i++; + } + i = 2; + while (i < n) { + while (factors[i] < 0) { + answer *= i; + factors[i]++; + } + i++; + } + free(factors); + return answer; +} + #if PCC_COMPILER - unsigned long long imprecise_log10(unsigned long long x) { + unsigned long long imprecise_log10(unsigned long long x); + inline unsigned long long imprecise_log10(unsigned long long x) { unsigned long long answer = 0; while (x) { x /= 10; @@ -21,18 +84,20 @@ unsigned long long factorial(unsigned long long n) { return answer; } - double sqrt(double S) { + double sqrt(double S); + inline double sqrt(double S) { // implements the Bakhshali method of square root computation to fix a PCC error double a, x = S / 2; unsigned int i; - for (i = 0; i < 8; i++) { + for (i = 0; i < PCC_SQRT_ACCURACY; i++) { a = (S - x*x) / (2 * x); x = x + a - (a * a) / (2 * (x + a)); } return x; } - unsigned long long ceil(double x) { + unsigned long long ceil(double x); + inline unsigned long long ceil(double x) { unsigned long long ret = (unsigned long long) x; if (x == (double) ret) { return ret; diff --git a/c/p0015.c b/c/p0015.c new file mode 100644 index 00000000..f4f92290 --- /dev/null +++ b/c/p0015.c @@ -0,0 +1,28 @@ +/* +Project Euler Problem 15 + +Turns out this is easy, if you think sideways a bit + +You can only go down or right. If we say right=1, then you can only have 20 1s, since otherwise you go off the grid. +You also can't have fewer than 20 1s, since then you go off the grid the other way. This means you can look at it as a +bit string, and the number of 40-bit strings with 20 1s is 40c20. + +Problem: + +Starting in the top left corner of a 2×2 grid, and only being able to move to the right and down, there are exactly 6 +routes to the bottom right corner. + +How many such routes are there through a 20×20 grid? +*/ +#include +#include "include/math.h" + +#define lattice_paths(height, width) (n_choose_r(height + width, height)) + + +int main(int argc, char const *argv[]) { + unsigned long long answer; + answer = lattice_paths(20, 20); + printf("%llu", answer); + return 0; +} diff --git a/c/test_euler.py b/c/test_euler.py index 637f8a43..b4300a7c 100644 --- a/c/test_euler.py +++ b/c/test_euler.py @@ -27,11 +27,12 @@ 9: 31875000, 10: 142913828922, 14: 837799, + 15: 137846528820, 34: 40730, 76: 190569291, } -known_slow: Set[int] = set() +known_slow: Set[int] = set([15]) # this is the set of problems where I have the right answer but wrong solution fails_pcc: Set[Union[str, int]] = {3, 5, 7, 10, 34, 'is_prime'} @@ -97,7 +98,7 @@ templates = { 'GCC': "{} {{}} -O2 -lm -Werror -std=c11 -o {{}}".format(GCC_BINARY), 'CLANG': "clang {} -O2 -lm -Werror -std=c11 -o {}", - 'CL': "cl -Fe:{{1}} -Fo{}\\ -O2 -TC {{0}}".format(BUILD_FOLDER.joinpath('objs').relative_to(Path.cwd())), + 'CL': "cl -Fe:{{1}} -Fo{}\\ -O2 -TC {{0}}".format(BUILD_FOLDER.joinpath('objs')), 'TCC': "tcc -lm -Werror -o {1} {0}", 'ICC': "icc {} -O2 -lm -Werror -std=c11 -o {}", 'PCC': "pcc -O2 -o {1} {0}", From d2592517816552bd1fcdd9bd9f510fab55338839 Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Sat, 28 Sep 2019 21:49:30 -0700 Subject: [PATCH 18/41] Remove python/p0145 from known_slow (close #5) --- python/p0145.py | 6 +++++- python/test_euler.py | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/python/p0145.py b/python/p0145.py index 3dc92361..be7fc46e 100644 --- a/python/p0145.py +++ b/python/p0145.py @@ -10,6 +10,10 @@ Turns out that using the built-in repr function makes this go much (~5x) faster, so I'll switch to that until I find a narrower solution. It's very nearly at the 60s mark now. +Revision 2: + +I reduced the search space by trial and error, getting it down to ~3.15% of the original + Problem: Some positive integers n have the property that the sum [ n + reverse(n) ] consists entirely of odd (decimal) digits. @@ -28,7 +32,7 @@ def main() -> int: seen: Set[int] = set() seen_update = seen.update odd_digits = {"1", "3", "5", "7", "9"} - for x in chain.from_iterable(range(x, 10**8 // 2, 10) for x in range(1, 10)): + for x in chain.from_iterable(range(x, 10**8 // 2, 10) for x in (2, 4, 5, 6, 7, 8)): if x in seen: continue inverse = int(repr(x)[::-1]) diff --git a/python/test_euler.py b/python/test_euler.py index 2d937f7c..bf9fe1cd 100644 --- a/python/test_euler.py +++ b/python/test_euler.py @@ -89,7 +89,7 @@ 206: 1389019170, } -known_slow = {76, 118, 123, 145} +known_slow = {76, 118, 123} # this is the set of problems where I have the right answer but wrong solution IN_TERMUX = bool(which('termux-setup-storage')) From 6d5034735b733793cc1d31c07bad2a832cb2d60f Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Sat, 28 Sep 2019 21:59:48 -0700 Subject: [PATCH 19/41] Remove python/p0123 from known_slow --- python/p0123.py | 10 ++++++---- python/test_euler.py | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/python/p0123.py b/python/p0123.py index 537ff5ba..ca27ff62 100644 --- a/python/p0123.py +++ b/python/p0123.py @@ -6,6 +6,10 @@ Additionally, I narrowed the search range by figuring that the remainder has to take place after the prime is 10**5. +Revision 1: + +Reduce search space further by remembering that it's unlikely for n % (10**10 + epsilon) >= 10**10 + Problem: Let p[n] be the nth prime: 2, 3, 5, 7, 11, ..., and let r be the remainder when @@ -21,12 +25,10 @@ def main() -> int: - ten_five = 10**5 + min_p = 235_000 ten_ten = 10**10 for n, p in enumerate(primes(), 1): - if p < ten_five: - continue - elif n & 1 == 0: # Seems to always produce remainder of 2? + if p < min_p or n & 1 == 0: # Seems to always produce remainder of 2? continue base = ((p-1)**n + (p+1)**n) if base < ten_ten: diff --git a/python/test_euler.py b/python/test_euler.py index bf9fe1cd..6914e526 100644 --- a/python/test_euler.py +++ b/python/test_euler.py @@ -89,7 +89,7 @@ 206: 1389019170, } -known_slow = {76, 118, 123} +known_slow = {76, 118} # this is the set of problems where I have the right answer but wrong solution IN_TERMUX = bool(which('termux-setup-storage')) From 00cb010fce9ccf8a310a41b4b6640ab67dfca932 Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Sat, 28 Sep 2019 22:25:54 -0700 Subject: [PATCH 20/41] Clean up minor errors [skip ci] --- .scripts/appveyor_script.bat | 2 +- c/include/macros.h | 1 - c/include/math.h | 7 ++++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.scripts/appveyor_script.bat b/.scripts/appveyor_script.bat index f2608152..35e007bc 100644 --- a/.scripts/appveyor_script.bat +++ b/.scripts/appveyor_script.bat @@ -12,7 +12,7 @@ IF DEFINED PIP ( %PIP% install -r requirements.txt IF DEFINED LINT ( ECHO "7" - %RUN% -m pytest -v --mypy --mypy-ignore-missing-imports --flake8 --isort -k "not test_problem and not test_is_prime" || goto :error + %RUN% -m pytest -v --mypy --mypy-ignore-missing-imports --flake8 --isort -k "not test_problem and not test_is_prime and not test_groupwise" || goto :error ) ELSE ( ECHO "7" %RUN% -m pytest test_euler.py -v --benchmark-min-time=0.05 --benchmark-sort=fullname --benchmark-verbose || goto :error diff --git a/c/include/macros.h b/c/include/macros.h index d42e3454..b896cea3 100644 --- a/c/include/macros.h +++ b/c/include/macros.h @@ -38,7 +38,6 @@ #endif #define MAX_FACTORIAL_64 20 -#define MAX_FACTORIAL_32 12 #define PCC_SQRT_ACCURACY 8 #endif diff --git a/c/include/math.h b/c/include/math.h index d2974d6c..e674ba1c 100644 --- a/c/include/math.h +++ b/c/include/math.h @@ -9,6 +9,7 @@ unsigned long long factorial(unsigned long long n); inline unsigned long long factorial(unsigned long long n) { + // note that this function only works for numbers smaller than MAX_FACTORIAL_64 unsigned long long ret = 1; for (unsigned long long i = 2; i <= n; ++i) { ret *= i; @@ -18,14 +19,14 @@ inline unsigned long long factorial(unsigned long long n) { unsigned long long n_choose_r(unsigned long long n, unsigned long long r) { // function returns -1 if it overflows - if ((sizeof(unsigned long long) == 8 && n <= MAX_FACTORIAL_64) || (sizeof(unsigned long long) == 4 && n <= MAX_FACTORIAL_32)) { + if (n <= MAX_FACTORIAL_64) { // fast path if small enough return factorial(n) / factorial(r) / factorial(n-r); } // slow path for larger numbers - signed char *factors; + int *factors; unsigned long long answer, i, j; - factors = (signed char *) malloc(sizeof(signed char) * (n + 1)); + factors = (int *) malloc(sizeof(int) * (n + 1)); // collect factors of final number for (i = 2; i <= n; i++) { factors[i] = 1; From a76e9254ef07fb37e6ea822fbf1fa0687e25c48a Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Sun, 29 Sep 2019 00:11:59 -0700 Subject: [PATCH 21/41] python/p0145 still slow on Travis --- python/test_euler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/test_euler.py b/python/test_euler.py index 6914e526..8b792602 100644 --- a/python/test_euler.py +++ b/python/test_euler.py @@ -89,7 +89,7 @@ 206: 1389019170, } -known_slow = {76, 118} +known_slow = {76, 118, 145} # this is the set of problems where I have the right answer but wrong solution IN_TERMUX = bool(which('termux-setup-storage')) From 116020475c3a22a56cae78b534c1acfdde704020 Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Sun, 29 Sep 2019 00:12:26 -0700 Subject: [PATCH 22/41] c/p0015 was accidentally marked slow --- c/test_euler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c/test_euler.py b/c/test_euler.py index b4300a7c..8c1fa966 100644 --- a/c/test_euler.py +++ b/c/test_euler.py @@ -32,7 +32,7 @@ 76: 190569291, } -known_slow: Set[int] = set([15]) +known_slow: Set[int] = set() # this is the set of problems where I have the right answer but wrong solution fails_pcc: Set[Union[str, int]] = {3, 5, 7, 10, 34, 'is_prime'} From 183cfd76f0e29e0382bd72466d846082de20438c Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Sun, 29 Sep 2019 00:12:37 -0700 Subject: [PATCH 23/41] Fix lint recipe --- c/Makefile | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/c/Makefile b/c/Makefile index 4ab89142..5212e7cf 100644 --- a/c/Makefile +++ b/c/Makefile @@ -1,4 +1,3 @@ - PY?=python3 PROXY?= USER_FLAG?=--user @@ -20,4 +19,8 @@ dependencies: $(PIP) install -r requirements.txt $(USER_FLAG) $(PROXY_ARG) lint: - clang-tidy *.c # -warnings-as-errors=* + if test -z "$(clang-tidy p0000_template.c -warnings-as-errors=* 2>&1 | grep "Unknown command line argument")"; then \ + clang-tidy *.c -warnings-as-errors=*; \ + else \ + clang-tidy *.c; \ + fi From 9f404c0e801f02a83619d263da53a5b48d7d8655 Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Sun, 29 Sep 2019 00:13:01 -0700 Subject: [PATCH 24/41] Attempt to make n_choose_r() more overflow resistant --- c/include/math.h | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/c/include/math.h b/c/include/math.h index e674ba1c..86e091ba 100644 --- a/c/include/math.h +++ b/c/include/math.h @@ -25,7 +25,7 @@ unsigned long long n_choose_r(unsigned long long n, unsigned long long r) { } // slow path for larger numbers int *factors; - unsigned long long answer, i, j; + unsigned long long answer, i, j, tmp; factors = (int *) malloc(sizeof(int) * (n + 1)); // collect factors of final number for (i = 2; i <= n; i++) { @@ -49,26 +49,33 @@ unsigned long long n_choose_r(unsigned long long n, unsigned long long r) { } } } - i = 2; + i = j = 2; answer = 1; while (i < n) { while (factors[i] > 0) { - j = answer; + tmp = answer; answer *= i; - if (answer < j) { + while (answer < tmp && j < n) { + while (factors[j] < 0) { + tmp /= j; + factors[j]++; + } + j++; + answer = tmp * i; + } + if (answer < tmp) { return -1; // this indicates an overflow } factors[i]--; } i++; } - i = 2; - while (i < n) { - while (factors[i] < 0) { - answer *= i; - factors[i]++; + while (j < n) { + while (factors[j] < 0) { + answer /= j; + factors[j]++; } - i++; + j++; } free(factors); return answer; From bae98845a751020c9f990ebdb8f145a19361e918 Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Sun, 29 Sep 2019 00:22:41 -0700 Subject: [PATCH 25/41] More overflow resiliance code (possible fail on PCC) --- c/include/macros.h | 1 + c/include/math.h | 11 +++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/c/include/macros.h b/c/include/macros.h index b896cea3..31db0458 100644 --- a/c/include/macros.h +++ b/c/include/macros.h @@ -38,6 +38,7 @@ #endif #define MAX_FACTORIAL_64 20 +#define MAX_FACTORIAL_128 34 #define PCC_SQRT_ACCURACY 8 #endif diff --git a/c/include/math.h b/c/include/math.h index 86e091ba..2f1bc768 100644 --- a/c/include/math.h +++ b/c/include/math.h @@ -1,11 +1,13 @@ #ifndef _EULER_MATH_H #define _EULER_MATH_H +#include "macros.h" + #if !PCC_COMPILER #include #endif -#include "macros.h" +#include unsigned long long factorial(unsigned long long n); inline unsigned long long factorial(unsigned long long n) { @@ -17,15 +19,16 @@ inline unsigned long long factorial(unsigned long long n) { return ret; } -unsigned long long n_choose_r(unsigned long long n, unsigned long long r) { +uintmax_t n_choose_r(unsigned int n, unsigned int r) { // function returns -1 if it overflows - if (n <= MAX_FACTORIAL_64) { + if ((sizeof(uintmax_t) == 8 && n <= MAX_FACTORIAL_64) || (sizeof(uintmax_t) == 16 && n <= MAX_FACTORIAL_128)) { // fast path if small enough return factorial(n) / factorial(r) / factorial(n-r); } // slow path for larger numbers int *factors; - unsigned long long answer, i, j, tmp; + uintmax_t answer, tmp; + unsigned int i, j; factors = (int *) malloc(sizeof(int) * (n + 1)); // collect factors of final number for (i = 2; i <= n; i++) { From 6f2ad428755817786e02c183d4d81cc3ce8568cf Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Sun, 29 Sep 2019 11:13:45 -0700 Subject: [PATCH 26/41] Make factorial more overflow resistant --- c/include/math.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/c/include/math.h b/c/include/math.h index 2f1bc768..612253fc 100644 --- a/c/include/math.h +++ b/c/include/math.h @@ -9,11 +9,13 @@ #include -unsigned long long factorial(unsigned long long n); -inline unsigned long long factorial(unsigned long long n) { +uintmax_t factorial(unsigned int n); +inline uintmax_t factorial(unsigned int n) { // note that this function only works for numbers smaller than MAX_FACTORIAL_64 - unsigned long long ret = 1; - for (unsigned long long i = 2; i <= n; ++i) { + if ((sizeof(uintmax_t) == 8 && n > MAX_FACTORIAL_64) || (sizeof(uintmax_t) == 16 && n > MAX_FACTORIAL_128)) + return -1; + uintmax_t ret = 1; + for (unsigned int i = 2; i <= n; ++i) { ret *= i; } return ret; From 0ca6c63eeb5a794ade8d092aa3149171b160578c Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Sun, 29 Sep 2019 12:06:01 -0700 Subject: [PATCH 27/41] Minor error corrections --- .scripts/shippable_script.sh | 4 +++- c/include/math.h | 12 ++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/.scripts/shippable_script.sh b/.scripts/shippable_script.sh index 3cfbb67b..467b01c5 100644 --- a/.scripts/shippable_script.sh +++ b/.scripts/shippable_script.sh @@ -26,7 +26,9 @@ else if [ $linter ]; then sudo apt-get update sudo apt-get install -y clang-tidy - make clint + cd c + clang-tidy --help + clang-tidy *.c else sudo apt-get update if [ $pcc ]; then diff --git a/c/include/math.h b/c/include/math.h index 612253fc..af9f6fe2 100644 --- a/c/include/math.h +++ b/c/include/math.h @@ -56,11 +56,11 @@ uintmax_t n_choose_r(unsigned int n, unsigned int r) { } i = j = 2; answer = 1; - while (i < n) { + while (i <= n) { while (factors[i] > 0) { tmp = answer; answer *= i; - while (answer < tmp && j < n) { + while (answer < tmp && j <= n) { while (factors[j] < 0) { tmp /= j; factors[j]++; @@ -75,7 +75,7 @@ uintmax_t n_choose_r(unsigned int n, unsigned int r) { } i++; } - while (j < n) { + while (j <= n) { while (factors[j] < 0) { answer /= j; factors[j]++; @@ -87,9 +87,9 @@ uintmax_t n_choose_r(unsigned int n, unsigned int r) { } #if PCC_COMPILER - unsigned long long imprecise_log10(unsigned long long x); - inline unsigned long long imprecise_log10(unsigned long long x) { - unsigned long long answer = 0; + unsigned char imprecise_log10(unsigned long long x); + inline unsigned char imprecise_log10(unsigned long long x) { + unsigned char answer = 0; while (x) { x /= 10; ++answer; From d4b421f1e4ba5b40e7975642f5249123b54eb550 Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Sun, 29 Sep 2019 12:15:24 -0700 Subject: [PATCH 28/41] First attempt at PCC build for travis --- .scripts/travis_script.sh | 25 ++++++++++++++++++++++++- .travis.yml | 9 ++++++--- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/.scripts/travis_script.sh b/.scripts/travis_script.sh index 51aeeada..c89a859c 100644 --- a/.scripts/travis_script.sh +++ b/.scripts/travis_script.sh @@ -19,7 +19,7 @@ if [ $pyver ]; then else make pytest PY=python LINT=false MYPY= USER_FLAG= fi -else +elif [ $jsver ]; then if [ $linter ]; then cd javascript; npm install eslint-config-google@latest eslint@>=5.16.0; @@ -27,4 +27,27 @@ else else make jstest; fi +else + if [ $linter ]; then + brew install llvm; + ln -s "/usr/local/opt/llvm/bin/clang-tidy" "/usr/local/bin/clang-tidy"; + make clint; + else + if [ $pcc ]; then + brew install flex bison + mkdir pcc pcc-libs + wget -O - -o /dev/null http://pcc.ludd.ltu.se/ftp/pub/pcc-releases/pcc-1.1.0.tgz | tar -xz --no-seek -C pcc --strip-components=1 + wget -O - -o /dev/null http://pcc.ludd.ltu.se/ftp/pub/pcc-releases/pcc-libs-1.1.0.tgz | tar -xz --no-seek -C pcc-libs --strip-components=1 + cd pcc + ./configure + sudo make && make install + cd ../pcc-libs + ./configure + sudo make && make install + cd .. + else + brew install $COMPILER_OVERRIDE; + fi + make ctest; + fi fi diff --git a/.travis.yml b/.travis.yml index 2aed9e7e..19559a0f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,6 @@ matrix: - language: c os: osx env: linter=true - script: brew install llvm; ln -s "/usr/local/opt/llvm/bin/clang-tidy" "/usr/local/bin/clang-tidy"; make clint - language: node_js node_js: "11" os: osx @@ -33,12 +32,13 @@ matrix: - language: c os: osx env: COMPILER_OVERRIDE=clang - script: brew install clang python3; make ctest - language: c os: osx env: COMPILER_OVERRIDE=gcc GCC_OVERRIDE=gcc-9 osx_image: xcode10.1 - script: brew install gcc; make ctest + - language: c + os: osx + env: COMPILER_OVERRIDE=pcc pcc=true - language: generic python: 3.6 os: osx @@ -61,6 +61,9 @@ matrix: python: pypy3 os: osx env: pyver=pypy3 pydist=homebrew NO_SLOW=true + allow_failures: + - env: COMPILER_OVERRIDE=pcc pcc=true + - python: pypy3 script: - sh ./.scripts/travis_script.sh From 7bec0f3b0b0dbd73edab399ef4084a9d78c502be Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Sun, 29 Sep 2019 12:27:17 -0700 Subject: [PATCH 29/41] Let's try setting up a C build on windows --- appveyor.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index 168fa0f8..b593adb5 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,6 +9,11 @@ environment: PIP: "%PYTHON%\\Scripts\\pip" LINT: "true" + - C: "TRUE" + on_finish: + - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) + + - NODE: "8" - NODE: "9" - NODE: "10" @@ -43,6 +48,8 @@ environment: PIP: "%RUN% -m pip" PYPY: "powershell.exe %APPVEYOR_BUILD_FOLDER%\\.scripts\\installpypy3.ps1" NO_SLOW: "true" + on_finish: + - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) - PYTHON: "C:\\Python37-x64" PYTHON_VERSION: "3.7" @@ -57,5 +64,8 @@ matrix: test: off +init: + - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) + build_script: - .scripts\\appveyor_script.bat From 44e14ac6872eea1e44ae076d2b76d8255b0d7f4c Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Sun, 29 Sep 2019 12:28:18 -0700 Subject: [PATCH 30/41] Redo --- appveyor.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index b593adb5..0f56e768 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,8 +11,7 @@ environment: - C: "TRUE" on_finish: - - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) - + - ps: "$blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))" - NODE: "8" - NODE: "9" @@ -49,7 +48,7 @@ environment: PYPY: "powershell.exe %APPVEYOR_BUILD_FOLDER%\\.scripts\\installpypy3.ps1" NO_SLOW: "true" on_finish: - - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) + - ps: "$blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))" - PYTHON: "C:\\Python37-x64" PYTHON_VERSION: "3.7" @@ -65,7 +64,7 @@ matrix: test: off init: - - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) + - ps: "iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))" build_script: - .scripts\\appveyor_script.bat From c1b1e9592663327bb839980a10956ad80b862b27 Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Sun, 29 Sep 2019 12:29:25 -0700 Subject: [PATCH 31/41] block for all --- appveyor.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 0f56e768..f6a95ad6 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,8 +10,6 @@ environment: LINT: "true" - C: "TRUE" - on_finish: - - ps: "$blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))" - NODE: "8" - NODE: "9" @@ -47,8 +45,6 @@ environment: PIP: "%RUN% -m pip" PYPY: "powershell.exe %APPVEYOR_BUILD_FOLDER%\\.scripts\\installpypy3.ps1" NO_SLOW: "true" - on_finish: - - ps: "$blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))" - PYTHON: "C:\\Python37-x64" PYTHON_VERSION: "3.7" @@ -64,7 +60,10 @@ matrix: test: off init: - - ps: "iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))" + - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) + +on_finish: +- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) build_script: - .scripts\\appveyor_script.bat From 20c74cbb7ed3c2213befcc18a44f1b1d23d142c9 Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Sun, 29 Sep 2019 12:36:54 -0700 Subject: [PATCH 32/41] try C build on 2015 --- appveyor.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index f6a95ad6..19296fc1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,3 +1,6 @@ +image: +- Visual Studio 2017 + environment: matrix: - NODE: "11" @@ -10,6 +13,7 @@ environment: LINT: "true" - C: "TRUE" + VCVARS: 'call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86' - NODE: "8" - NODE: "9" From b7c8098230a1b45436dbe25bd65dcb11d4d23856 Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Sun, 29 Sep 2019 12:45:56 -0700 Subject: [PATCH 33/41] Expand C builds to have all currently known Windows targets --- appveyor.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index 19296fc1..24b9d8ba 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -14,6 +14,28 @@ environment: - C: "TRUE" VCVARS: 'call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86' + COMPILER_OVERRIDE: 'cl' + NO_SLOW: "true" + + - C: "TRUE" + WIN_SDK: 'call "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x64' + VCVARS: 'call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86_amd64' + COMPILER_OVERRIDE: 'cl' + NO_SLOW: "true" + + - C: "TRUE" + VCVARS: 'call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars32.bat"' + COMPILER_OVERRIDE: 'cl' + NO_SLOW: "true" + + - C: "TRUE" + VCVARS: 'call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat"' + COMPILER_OVERRIDE: 'cl' + NO_SLOW: "true" + + - C: "TRUE" + COMPILER_OVERRIDE: 'clang' + NO_SLOW: "true" - NODE: "8" - NODE: "9" From e3d6e185a406f743a55eb9f762d99434c88d6a8f Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Sun, 29 Sep 2019 12:55:07 -0700 Subject: [PATCH 34/41] Adjust CL test script --- appveyor.yml | 10 +++++----- c/test_euler.py | 6 ++++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 24b9d8ba..0a1d3eaf 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -12,28 +12,28 @@ environment: PIP: "%PYTHON%\\Scripts\\pip" LINT: "true" - - C: "TRUE" + - C: "VS 2015 x86" VCVARS: 'call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86' COMPILER_OVERRIDE: 'cl' NO_SLOW: "true" - - C: "TRUE" + - C: "VS 2015 x86_64" WIN_SDK: 'call "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x64' VCVARS: 'call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86_amd64' COMPILER_OVERRIDE: 'cl' NO_SLOW: "true" - - C: "TRUE" + - C: "VS 2017 x86" VCVARS: 'call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars32.bat"' COMPILER_OVERRIDE: 'cl' NO_SLOW: "true" - - C: "TRUE" + - C: "VS 2017 x86_64" VCVARS: 'call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat"' COMPILER_OVERRIDE: 'cl' NO_SLOW: "true" - - C: "TRUE" + - C: "Clang" COMPILER_OVERRIDE: 'clang' NO_SLOW: "true" diff --git a/c/test_euler.py b/c/test_euler.py index 8c1fa966..bbfcc8b5 100644 --- a/c/test_euler.py +++ b/c/test_euler.py @@ -111,7 +111,6 @@ if not (IN_TERMUX and GCC_BINARY == 'gcc') and which(GCC_BINARY): # Termux maps gcc->clang compilers.append('GCC') if which('cl'): - BUILD_FOLDER.joinpath('objs').mkdir(parents=True, exist_ok=True) compilers.append('CL') for x in ('aocc', 'clang', 'icc', 'pcc', 'tcc'): if which(x): @@ -119,7 +118,10 @@ if not compilers: raise RuntimeError("No compilers detected!") -BUILD_FOLDER.mkdir(parents=True, exist_ok=True) +if 'CL' in compilers: + BUILD_FOLDER.joinpath('objs').mkdir(parents=True, exist_ok=True) +else: + BUILD_FOLDER.mkdir(parents=True, exist_ok=True) @register From 7c2179d92f743341b6fff81daa2affa1eaa3036c Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Sun, 29 Sep 2019 13:51:32 -0700 Subject: [PATCH 35/41] Add GCC, try to fix Windows clang --- appveyor.yml | 10 ++++++++++ c/test_euler.py | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 0a1d3eaf..66358b9f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -37,6 +37,16 @@ environment: COMPILER_OVERRIDE: 'clang' NO_SLOW: "true" + - C: "cygwin GCC x86" + COMPILER_OVERRIDE: 'gcc' + NO_SLOW: "true" + GCC_OVERRIDE: "C:\cygwin64\bin\gcc.exe" + + - C: "cygwin GCC x86_64" + COMPILER_OVERRIDE: 'gcc' + NO_SLOW: "true" + GCC_OVERRIDE: "C:\cygwin\bin\gcc.exe" + - NODE: "8" - NODE: "9" - NODE: "10" diff --git a/c/test_euler.py b/c/test_euler.py index bbfcc8b5..52f21d9b 100644 --- a/c/test_euler.py +++ b/c/test_euler.py @@ -97,7 +97,7 @@ compilers: List[str] = [] templates = { 'GCC': "{} {{}} -O2 -lm -Werror -std=c11 -o {{}}".format(GCC_BINARY), - 'CLANG': "clang {} -O2 -lm -Werror -std=c11 -o {}", + 'CLANG': "clang {{}} -O2 {} -Werror -std=c11 -o {{}}".format('' if IN_WINDOWS else '-lm'), 'CL': "cl -Fe:{{1}} -Fo{}\\ -O2 -TC {{0}}".format(BUILD_FOLDER.joinpath('objs')), 'TCC': "tcc -lm -Werror -o {1} {0}", 'ICC': "icc {} -O2 -lm -Werror -std=c11 -o {}", From 1a560465a77a4c3d6d9284febb0483799ababae8 Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Sun, 29 Sep 2019 13:54:08 -0700 Subject: [PATCH 36/41] Fix syntax error --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 66358b9f..b54c3db1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -40,12 +40,12 @@ environment: - C: "cygwin GCC x86" COMPILER_OVERRIDE: 'gcc' NO_SLOW: "true" - GCC_OVERRIDE: "C:\cygwin64\bin\gcc.exe" + GCC_OVERRIDE: "C:\\cygwin64\\bin\\gcc.exe" - C: "cygwin GCC x86_64" COMPILER_OVERRIDE: 'gcc' NO_SLOW: "true" - GCC_OVERRIDE: "C:\cygwin\bin\gcc.exe" + GCC_OVERRIDE: "C:\\cygwin\\bin\\gcc.exe" - NODE: "8" - NODE: "9" From d83419f0dd82ce6e7a663676f7749ca113ed9b94 Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Sun, 29 Sep 2019 14:29:25 -0700 Subject: [PATCH 37/41] Remove gcc, rdp; clean up script Their copy of GCC seems to be broken, can't compile even simple programs with no options --- .scripts/appveyor_script.bat | 19 +------------------ appveyor.yml | 16 ---------------- c/include/macros.h | 2 +- 3 files changed, 2 insertions(+), 35 deletions(-) diff --git a/.scripts/appveyor_script.bat b/.scripts/appveyor_script.bat index 35e007bc..3a137e31 100644 --- a/.scripts/appveyor_script.bat +++ b/.scripts/appveyor_script.bat @@ -1,46 +1,29 @@ IF DEFINED PIP ( - ECHO %PYTHON% %PYTHON_VERSION%%APPVEYOR_BUILD_FOLDER% - ECHO "3" - set HOME=%APPVEYOR_BUILD_FOLDER% - ECHO "4" %PYPY% - dir -r - dir /S - ECHO "5" cd python - ECHO "6" %PIP% install -r requirements.txt IF DEFINED LINT ( - ECHO "7" %RUN% -m pytest -v --mypy --mypy-ignore-missing-imports --flake8 --isort -k "not test_problem and not test_is_prime and not test_groupwise" || goto :error ) ELSE ( - ECHO "7" %RUN% -m pytest test_euler.py -v --benchmark-min-time=0.05 --benchmark-sort=fullname --benchmark-verbose || goto :error ) ) ELSE ( IF DEFINED NODE ( - dir C:\avvm\node - ECHO "3" powershell -Command "Install-Product node $env:NODE" - ECHO "4" cd javascript - ECHO "5" IF DEFINED LINT ( npm install eslint-config-google@latest eslint@>=5.16.0 - ECHO "6" npx eslint *.js || goto :error ) ELSE ( npm install - ECHO "6" npx mocha || goto :error ) ) ELSE ( cd c C:\Python36\python -m pip install -r requirements.txt %WIN_SDK% - ECHO %VCVARS% %VCVARS% - C:\Python36\python -m pytest test_euler.py -v --benchmark-min-time=0.05 --benchmark-sort=fullname --benchmark-verbose || goto :error + C:\Python36\python -m pytest test_euler.py -v --benchmark-min-time=0.05 --benchmark-group-by=fullfunc --benchmark-sort=fullname --benchmark-verbose || goto :error ) ) goto :EOF diff --git a/appveyor.yml b/appveyor.yml index b54c3db1..cf01d5d1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -37,16 +37,6 @@ environment: COMPILER_OVERRIDE: 'clang' NO_SLOW: "true" - - C: "cygwin GCC x86" - COMPILER_OVERRIDE: 'gcc' - NO_SLOW: "true" - GCC_OVERRIDE: "C:\\cygwin64\\bin\\gcc.exe" - - - C: "cygwin GCC x86_64" - COMPILER_OVERRIDE: 'gcc' - NO_SLOW: "true" - GCC_OVERRIDE: "C:\\cygwin\\bin\\gcc.exe" - - NODE: "8" - NODE: "9" - NODE: "10" @@ -95,11 +85,5 @@ matrix: test: off -init: - - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) - -on_finish: -- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) - build_script: - .scripts\\appveyor_script.bat diff --git a/c/include/macros.h b/c/include/macros.h index 31db0458..8d3b2a28 100644 --- a/c/include/macros.h +++ b/c/include/macros.h @@ -1,7 +1,7 @@ #ifndef _MACROS_H #define _MACROS_H -#ifdef _MSC_VER +#if (defined(_MSC_VER) && !defined(__clang__)) #define CL_COMPILER 1 #else #define CL_COMPILER 0 From 0966fa01344e55825b7e71ddcd1c2021e100ac9a Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Sun, 29 Sep 2019 14:32:29 -0700 Subject: [PATCH 38/41] Update readme [skip ci] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0fa61cec..7434fc61 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ The repo is divided into sections for each language. The top-level Makefile will ## Footnotes -1: Windows testing is only enabled for Python and Javascript at the moment until I get configuration set up correctly for CL +1: Windows testing is done on C, Python, and Javascript. C compilers are CL (MSVC 2015/2017 x86/x64) and clang 2: Linux testing is done on Ubuntu 14.04 for C, Python, and Javascript. C compilers are gcc, clang, tcc, and pcc. The pcc and tcc compilers are marked as allowed failures because tcc implements no optimizations and might have time failures, and pcc seems to have errors including `` and `` From 33c6d15ecb9dad7ab0474471b5ac154cf3598f91 Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Mon, 30 Sep 2019 21:20:20 -0700 Subject: [PATCH 39/41] Fix build scripts --- .scripts/shippable_script.sh | 4 ++-- .scripts/travis_script.sh | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.scripts/shippable_script.sh b/.scripts/shippable_script.sh index 467b01c5..e6fb81bc 100644 --- a/.scripts/shippable_script.sh +++ b/.scripts/shippable_script.sh @@ -39,10 +39,10 @@ else cd pcc sed -i 's/MANPAGE=@BINPREFIX@cpp/MANPAGE=@BINPREFIX@pcc-cpp/' cc/cpp/Makefile.in ./configure --prefix=/usr --libexecdir=/usr/lib/{x86_64,i386}-linux-gnu - sudo make && make install + sudo make && sudo make install cd ../pcc-libs ./configure --prefix=/usr --libexecdir=/usr/lib/{x86_64,i386}-linux-gnu - sudo make && make install + sudo make && sudo make install cd .. else sudo apt-get install -y $COMPILER_OVERRIDE python3-pip diff --git a/.scripts/travis_script.sh b/.scripts/travis_script.sh index c89a859c..fe26881c 100644 --- a/.scripts/travis_script.sh +++ b/.scripts/travis_script.sh @@ -36,17 +36,17 @@ else if [ $pcc ]; then brew install flex bison mkdir pcc pcc-libs - wget -O - -o /dev/null http://pcc.ludd.ltu.se/ftp/pub/pcc-releases/pcc-1.1.0.tgz | tar -xz --no-seek -C pcc --strip-components=1 - wget -O - -o /dev/null http://pcc.ludd.ltu.se/ftp/pub/pcc-releases/pcc-libs-1.1.0.tgz | tar -xz --no-seek -C pcc-libs --strip-components=1 + wget -O - -o /dev/null http://pcc.ludd.ltu.se/ftp/pub/pcc-releases/pcc-1.1.0.tgz | tar -xz -C pcc --strip-components=1 + wget -O - -o /dev/null http://pcc.ludd.ltu.se/ftp/pub/pcc-releases/pcc-libs-1.1.0.tgz | tar -xz -C pcc-libs --strip-components=1 cd pcc ./configure - sudo make && make install + sudo make && sudo make install cd ../pcc-libs ./configure - sudo make && make install + sudo make && sudo make install cd .. - else - brew install $COMPILER_OVERRIDE; + elif [ $GCC_OVERRIDE ]; then + brew install gcc; fi make ctest; fi From 146b8415661ff6c6267eecc560b8d3777afd1e47 Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Mon, 30 Sep 2019 21:20:59 -0700 Subject: [PATCH 40/41] Detect normal proxy variables instead of defining my own --- c/Makefile | 9 ++++++--- python/Makefile | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/c/Makefile b/c/Makefile index 5212e7cf..c4ccac7e 100644 --- a/c/Makefile +++ b/c/Makefile @@ -1,13 +1,16 @@ PY?=python3 -PROXY?= USER_FLAG?=--user PIP?=$(PY) -m pip -ifneq ($(PROXY), ) -PROXY_ARG="--proxy=$(PROXY)" +ifneq ($(https_proxy), ) +PROXY_ARG=--proxy=$(https_proxy) +else +ifneq ($(http_proxy), ) +PROXY_ARG=--proxy=$(http_proxy) else PROXY_ARG= endif +endif test_%: dependencies $(PY) -m pytest -v -n$* test_euler.py diff --git a/python/Makefile b/python/Makefile index 8c189d69..50ef7cfa 100644 --- a/python/Makefile +++ b/python/Makefile @@ -1,6 +1,5 @@ LINT?= PY?=python3 -PROXY?= USER_FLAG?=--user PIP?=$(PY) -m pip MYPY?=true @@ -23,11 +22,15 @@ endif endif endif -ifneq ($(PROXY), ) -PROXY_ARG="--proxy=$(PROXY)" +ifneq ($(https_proxy), ) +PROXY_ARG=--proxy=$(https_proxy) +else +ifneq ($(http_proxy), ) +PROXY_ARG=--proxy=$(http_proxy) else PROXY_ARG= endif +endif test: dependencies _test From 4aa44de5ddc285ff4e8dde55ce50c091ad88ea6f Mon Sep 17 00:00:00 2001 From: Gabe Appleton Date: Mon, 30 Sep 2019 21:22:32 -0700 Subject: [PATCH 41/41] Clean up test script, add compiler args --- c/test_euler.py | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/c/test_euler.py b/c/test_euler.py index 52f21d9b..78d8f5ea 100644 --- a/c/test_euler.py +++ b/c/test_euler.py @@ -35,11 +35,6 @@ known_slow: Set[int] = set() # this is the set of problems where I have the right answer but wrong solution -fails_pcc: Set[Union[str, int]] = {3, 5, 7, 10, 34, 'is_prime'} -# this is the set of tests that fail on PCC compiler -# this is because (at least on my system) including or result in syntax errors -# for the moment that is just limited to anything that includes primes.h or digits.h - # platform variables section IN_WINDOWS = system() == 'Windows' @@ -96,10 +91,10 @@ # compiler variables section compilers: List[str] = [] templates = { - 'GCC': "{} {{}} -O2 -lm -Werror -std=c11 -o {{}}".format(GCC_BINARY), - 'CLANG': "clang {{}} -O2 {} -Werror -std=c11 -o {{}}".format('' if IN_WINDOWS else '-lm'), - 'CL': "cl -Fe:{{1}} -Fo{}\\ -O2 -TC {{0}}".format(BUILD_FOLDER.joinpath('objs')), - 'TCC': "tcc -lm -Werror -o {1} {0}", + 'GCC': "{} {{}} -O2 -lm -Wall -Werror -std=c11 -o {{}}".format(GCC_BINARY), + 'CLANG': "clang {{}} -O2 {} -Wall -Werror -std=c11 -o {{}}".format('' if IN_WINDOWS else '-lm'), + 'CL': "cl -Fe:{{1}} -Fo{}\\ -O2 -Brepro -TC {{0}}".format(BUILD_FOLDER.joinpath('objs')), + 'TCC': "tcc -lm -Wall -Werror -o {1} {0}", 'ICC': "icc {} -O2 -lm -Werror -std=c11 -o {}", 'PCC': "pcc -O2 -o {1} {0}", 'AOCC': "aocc {} -O2 -lm -Werror -std=c11 -o {}", @@ -143,7 +138,7 @@ def key(request): # type: ignore @mark.skipif('NO_OPTIONAL_TESTS') def test_compiler_macros(compiler): exename = EXE_TEMPLATE.format("test_compiler_macros", compiler) - test_path = Path(__file__).parent.joinpath("tests", "test_compiler_macros.c") + test_path = C_FOLDER.joinpath("tests", "test_compiler_macros.c") check_call(templates[compiler].format(test_path, exename).split()) buff = check_output([exename]) is_CL, is_CLANG, is_GCC, is_INTEL, is_AMD, is_PCC, is_TCC = (int(x) for x in buff.split()) @@ -161,7 +156,7 @@ def test_is_prime(benchmark, compiler): from p0007 import is_prime, prime_factors, primes MAX_PRIME = 1_000_000 exename = EXE_TEMPLATE.format("test_is_prime", compiler) - test_path = Path(__file__).parent.joinpath("tests", "test_is_prime.c") + test_path = C_FOLDER.joinpath("tests", "test_is_prime.c") args = templates[compiler].format(test_path, exename) + " -DMAX_PRIME={}".format(MAX_PRIME) check_call(args.split()) with TemporaryFile('wb+') as f: