#!/usr/bin/env python3 # # Testing tool for the Faulty Connection problem # # Usage: # # python3 testing_tool.py -f inputfile # # # Use the -f parameter to specify the input file, e.g. 1.in. # The input file should contain the following: # - The first line contains "send". # - The second line contains an integer to send. # You can compile and run your solution as follows: # C++: # g++ solution.cpp # python3 testing_tool.py -f 1.in ./a.out # Python: # python3 testing_tool.py -f 1.in python3 ./solution.py # Java: # javac solution.java # python3 testing_tool.py -f 1.in java solution # Kotlin: # kotlinc solution.kt # python3 testing_tool.py -f 1.in kotlin solutionKt # The tool is provided as-is, and you should feel free to make # whatever alterations or augmentations you like to it. # # The tool attempts to detect and report common errors, but it is not an exhaustive test. # It is not guaranteed that a program that passes this testing tool will be accepted. import argparse import subprocess import traceback import random parser = argparse.ArgumentParser(description="Testing tool for problem Faulty Connection.") parser.add_argument( "-f", dest="inputfile", metavar="inputfile", default=None, type=argparse.FileType("r"), required=True, help="The input file to use.", ) parser.add_argument("program", nargs="+", help="Invocation of your solution") args = parser.parse_args() def single_pass(action: str, input_numbers: list[int]) -> list[int]: with ( subprocess.Popen( " ".join(args.program), shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, universal_newlines=True, ) as p, ): assert p.stdin is not None and p.stdout is not None raw = "\n".join([action, " ".join(map(str, input_numbers))]) stdout, stderr = p.communicate(input=raw) output_numbers = list(map(int, stdout.strip().split())) print(f"{action} exit code: {p.returncode}") print(f"{action} output:") print() print(stdout, flush=True) if action == "send": assert len(output_numbers) == 30, ( f"Your submission printed {len(output_numbers)} numbers, when it needed to print 30 numbers" ) else: assert len(output_numbers) == 1, ( f"Your submission printed {len(output_numbers)} numbers, when it needed to print 1 number" ) assert len(output_numbers) == len(set(output_numbers)), "Your submission printed duplicate numbers" return output_numbers try: with args.inputfile as f: # Parse input lines = [line.strip() for line in f.readlines()] action = lines[0] sent_number = int(lines[1].strip()) assert action == "send", f"Initial action must be 'send', but got {action}" returned_numbers = single_pass("send", [sent_number]) receive_numbers = random.sample(returned_numbers, 2) print("Running receive with numbers:", receive_numbers) print() received_number = single_pass("receive", receive_numbers) assert received_number[0] == sent_number, f"Expected received number {sent_number}, but got {received_number[0]}" print("Success.") except AssertionError as e: print() print(f"Error: {e}") print() exit(1) except Exception: print() print("Unexpected error:") traceback.print_exc() print() exit(1)