132 lines
3.7 KiB
Python
Executable File
132 lines
3.7 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import os
|
|
import subprocess
|
|
import re
|
|
import sys
|
|
from argparse import ArgumentParser
|
|
|
|
SOLUTIONS = '.solutions.txt'
|
|
|
|
exs = ['py', 'exe']
|
|
sol_pattern = re.compile(r'(\d+)_.+\.(?:{})'.format('|'.join(exs)))
|
|
|
|
matches = map(sol_pattern.fullmatch, os.listdir('.'))
|
|
fs = {int(m.group(1)) : m.group(0) for m in matches if m != None}
|
|
solved = sorted(fs.keys())
|
|
|
|
try:
|
|
with open(SOLUTIONS) as f:
|
|
lines = (line.split() for line in f.read().rstrip().split('\n'))
|
|
solutions = {int(line[0]) : ' '.join(line[1:]) for line in lines}
|
|
except FileNotFoundError:
|
|
solutions = dict()
|
|
|
|
try:
|
|
subprocess.run(['pypy', '--version'],
|
|
stdout=subprocess.DEVNULL,
|
|
stderr=subprocess.DEVNULL)
|
|
|
|
pypy_installed = True
|
|
except FileNotFoundError:
|
|
print('warning : install pypy for faster solving time')
|
|
pypy_installed = False
|
|
|
|
try:
|
|
subprocess.run(['pypy3', '--version'],
|
|
stdout=subprocess.DEVNULL,
|
|
stderr=subprocess.DEVNULL)
|
|
|
|
pypy3_installed = True
|
|
except FileNotFoundError:
|
|
print('warning : install pypy3 for faster solving time')
|
|
pypy3_installed = False
|
|
|
|
|
|
def print_bar(i, count):
|
|
global print
|
|
step = 1
|
|
while count // step > 80:
|
|
step += 1
|
|
w = count // step
|
|
j = i // step
|
|
bar = '[{}{}] {}/{}'.format('#'*(j), '.'*(w - j), i, count)
|
|
print(bar, end='\r')
|
|
|
|
old_print = print
|
|
def new_print(x, *args, **kwargs):
|
|
global print
|
|
print = old_print
|
|
print(x + ' '*(len(bar) - len(x)), *args, **kwargs)
|
|
print = new_print
|
|
|
|
|
|
def get_cmd(fn):
|
|
ext = fn.split('.')[-1]
|
|
if ext == 'py':
|
|
with open(fn) as f:
|
|
fst_line = f.read().lstrip().split('\n')[0]
|
|
if fst_line[:2] != '#!':
|
|
return 'python '
|
|
shebang = fst_line[2:]
|
|
if pypy_installed:
|
|
return shebang.replace('python', 'pypy') + ' '
|
|
if pypy3_installed:
|
|
return shebang.replace('python3', 'pypy3') + ' '
|
|
return shebang
|
|
return './'
|
|
|
|
|
|
|
|
def run(fn, cmd=None):
|
|
cmd = get_cmd(fn) if cmd==None else cmd
|
|
|
|
proc = subprocess.run(cmd + fn, shell=True,
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.PIPE)
|
|
if len(proc.stderr) > 0:
|
|
if 'pypy' in cmd:
|
|
#print('warning : pypy failed. trying cpython', file=sys.stderr)
|
|
#print(proc.stderr)
|
|
return run(fn, cmd = cmd.replace('pypy', 'python'))
|
|
print('error : error while running solution')
|
|
print(proc.stderr.decode('utf-8'), end='')
|
|
|
|
return proc.stdout.decode('utf-8').rstrip().split('\n')[-1]
|
|
|
|
def solve_all():
|
|
print('Num Solution')
|
|
print('---------------')
|
|
for i, x in enumerate(solved, start=1):
|
|
print_bar(i, len(fs))
|
|
|
|
f = fs[x]
|
|
r = run(f)
|
|
if x in solutions.keys() and r != solutions[x]:
|
|
wrong_err = 'error : wrong solution for {}, expected {}'
|
|
print(wrong_err.format(x, solutions[x]))
|
|
print('{:>3d} {}'.format(x, r))
|
|
|
|
parser = ArgumentParser()
|
|
parser.description = \
|
|
"""Solves all Project Euler problems with provided solutions.
|
|
A solution is an executable or python file in the same directory as this file,
|
|
with a name of the format XXX_decription.[exe|py], where XXX is the number of
|
|
the problem.
|
|
The problems are available at https://projecteuler.net/"""
|
|
|
|
parser.add_argument('--get-solutions',
|
|
action='store_true',
|
|
help='downloads solutions for user')
|
|
|
|
def main():
|
|
args = parser.parse_args()
|
|
if args.get_solutions:
|
|
print('Fetching solutions')
|
|
else:
|
|
solve_all()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|