Exemple #1
0
def eval_is_solvable(n, m, solvable=False):
    print(f"Checking if solvable {n}x{m}")
    pirellone = random_pirellone(n, m, solvable=solvable)

    read = [[False for j in range(m + 1)] for i in range(n + 1)]

    def is_on(i, j):
        if read[i][j]:
            ta.goals["decision_no_double_read"] = False
        read[i][j] = True
        p.check(1 <= i <= n, "row index out of range")
        p.check(1 <= j <= m, "column index out of range")
        return pirellone[i - 1][j - 1]

    with ta.run_algorithm(ta.submission.source) as p:
        res = bool(p.functions.is_solvable(n, m, callbacks=[is_on]))

    solvable = is_solvable(pirellone, n, m)
    if res == solvable:
        print("Correct!")
        return True
    if res:
        print(
            "You said that the pirellone was solvable, but it is not, take a look"
        )
    else:
        print(
            "You said that the pirellone was not solvable, but it is, take a look"
        )

    if n <= 50:
        print_pirellone(pirellone)
    send_pirellone_file(pirellone)
    return False
Exemple #2
0
def test_case(A, B, C):
    print(f"testing case len(A) = {len(A)}, len(B) = {len(B)}\t", end="")
    with ta.run_algorithm(ta.submission.source) as p:
        try:
            p.procedures.merge(len(A), A, len(B), B, len(C))

            res = [p.functions.getElement(i) for i in range(len(C))]

            for i in range(len(C)):

                if res[i] != C[i]:
                    print(
                        f"\nWrong merge at element {i}: expected {C[i]}, found {res[i]}"
                    )
                    if len(C) <= 20:
                        print(f"A array = {A}")
                        print(f"B array = {B}")
                        print(f"Your merge = {res}")
                        print(f"Correct merge = {C}")
                    return False

        except ta.AlgorithmError as e:
            print(f"\nError: {e}")
            return False
    print("CORRECT")
    return True
def test_case(N):
    with run_algorithm(submission.source) as p:
        res = p.che_mai_saralo_sto_numer()
        if res != N:
            print(
                "Il numero che avevo in mente era %d, non %d come da tè affermato."
                % (N, res))
            goals[exponential_algorithm] = False
            goals[optimum_algorithm] = False
            if N <= 100:
                goals[polynomial_algorithm] = False

        operations_done = 0
        n = N

        def se_mia_zero():
            return n == 0

        def se_mia_pari():
            return n % 2 == 0

        def caveghe_zo_uno():
            nonlocal operations_done
            if n == 0:
                print(
                    "Anna era partita col numero N=%d, ma ora, a seguito delle operazion che le avevi già richiesto, si ritrovava ora con uno zero. Ed ora gli chiedi di togliere uno? Questo non ti è consentito."
                    % N)
                goals[exponential_algorithm] = False
                goals[optimum_algorithm] = False
                if N <= 100:
                    goals[polynomial_algorithm] = False
            n -= 1
            operations_done += 1

        def dividi_par_do():
            nonlocal operations_done
            if n % 2 == 1:
                print(
                    "Anna era partita col numero N=%d, ma ora, a seguito delle operazion che le avevi già richiesto, si ritrovava ora con %n, un numero dispari. Non ti è consentito richiedere la divisione per due di un numero dispari."
                    % (N, n))
                goals[exponential_algorithm] = False
                goals[optimum_algorithm] = False
                if N <= 100:
                    goals[polynomial_algorithm] = False
            n /= 2
            operations_done += 1

        res = p.che_mai_saralo_sto_numer(callbacks=[
            caveghe_zo_uno, dividi_par_do, se_mia_pari_cio, se_mia_zero_ah
        ])
        if res != N:
            print(
                "Anna era partita col numero N=%d, non col numero %d come restituito dalla tua funzione che_mai_saralo_sto_numer."
                % (N, res))
            goals[exponential_algorithm] = False
            goals[optimum_algorithm] = False
            if N <= 100:
                goals[polynomial_algorithm] = False
Exemple #4
0
def run (before, script, w, max_ants, g, interface_path = None):
	global goal
	goal = g
	build_enviroment (w, max_ants)
	before ()
	try:
		with ta.run_algorithm (ta.submission.source, interface_path) as p:
			script (p)
	except ta.AlgorithmError as e:
		ta.goals[goal] = False
		print (e)
	ta.goals.setdefault(g, True)
	print(f"{g}: {ta.goals[g]}")
Exemple #5
0
def run(algorithm, s):
    with ta.run_algorithm(algorithm, time_limit=0.05) as process:
        process.procedures.compute(len(s), s)
        subsequence_length = process.functions.max_length()
        subsequence = [
            x for i, x in enumerate(s) if process.functions.takes(i)
        ]
        color = []
        for i in range(len(s)):
            color.append(process.functions.color_of(i))
    if DEBUG:
        print(f"Time usage: {process.time_usage}", file=sys.stderr)
    return (subsequence_length, subsequence, color)
Exemple #6
0
def eval_solve(n, m):
    print(f"Getting solution for {n}x{m}")

    pirellone = random_pirellone(n, m, solvable=True)

    count = 0
    read = [[False for j in range(m + 1)] for i in range(n + 1)]

    def is_on(i, j):
        nonlocal count
        if read[i][j]:
            ta.goals["solve_no_double_read"] = False
        read[i][j] = True

        count += 1
        if count > n + m - 1:
            ta.goals["solve_minimum_reads"] = False
        p.check(1 <= i <= n, "row index out of range")
        p.check(1 <= j <= m, "column index out of range")
        return pirellone[i - 1][j - 1]

    def switch_row(i):
        i -= 1
        for j in range(m):
            pirellone[i][j] = int(not pirellone[i][j])

    def switch_col(j):
        j -= 1
        for i in range(n):
            pirellone[i][j] = int(not pirellone[i][j])

    with ta.run_algorithm(ta.submission.source) as p:
        p.procedures.solve(n, m, callbacks=[is_on, switch_row, switch_col])

    solved = not any(any(pirellone[i][j] for j in range(m)) for i in range(n))
    if not solved:
        print("You didn't turn off all the lights. Take a look")
        if n <= 50:
            print_pirellone(pirellone)
        send_pirellone_file(pirellone)
    else:
        print("Correct!")
    return solved
Exemple #7
0
def evaluate(n):
    a, b = 1, n
    trials = 0

    print(f"guess({a}, {b})... ")

    def answer(c):
        nonlocal a, b, trials
        trials += 1
        p.check(trials <= ta.parameters.easy_max_trials, "too many guesses")

        assert a <= b

        if a == b == c:
            print("guessed correctly!")
            p.exit()

        if c < a:
            return +1
        if c > b:
            return -1

        if c < (a + b) / 2:
            a = c + 1
            return +1
        else:
            b = c - 1
            return -1

    try:
        with ta.run_algorithm(ta.submission.source) as p:
            p.procedures.guess(a, b, callbacks=[answer])
            p.fail("procedure guess returned before guessing correctly")
    except ta.InterfaceExit:
        return trials
    except ta.AlgorithmError as e:
        print(f"{e}")
        return None

    assert False, "unexpected end"
Exemple #8
0
def run_test_case(g):
    with ta.run_algorithm(ta.submission.source) as process:
        process.procedures.solve(
            g.order(),
            g.size(),
            [u for u, v in g.edges()],
            [v for u, v in g.edges()],
        )

        cycle_len = process.functions.length()

        process.check(cycle_len <= ta.parameters['longest_allowed_walk'],
                      f"cycle too long")

        cycle = [process.functions.get_node(i) for i in range(cycle_len)]

        print(f"Answer: {cycle}, checking...")

        for i in range(len(cycle)):
            u, v = cycle[i], cycle[(i + 1) % len(cycle)]
            process.check(g.has_edge(u, v), f"there is no edge ({u}, {v})")
        process.check(len(cycle) % 2 == 1, f"not in state 'SLURP'")
Exemple #9
0
            nx.gnm_random_graph(N, M - len(graph.edges())).edges())

    for u, v, d in graph.edges(data=True):
        d["weight"] = random.randint(0, 1)

    assert len(graph.nodes()) <= MAXN
    assert len(graph.edges()) <= MAXM
    assert nx.is_connected(graph)

    #with ta.run_algorithm("solutions/correct.cpp") as p:
    #    correct_output = p.functions.shortest_path(
    #        len(graph.nodes()),
    #        len(graph.edges()),
    #        [u for u, v, w in graph.edges(data="weight")],
    #        [v for u, v, w in graph.edges(data="weight")],
    #        [w for u, v, w in graph.edges(data="weight")])

    correct_output = nx.dijkstra_path_length(graph, 0, len(graph.nodes()) - 1)

    with ta.run_algorithm(submitted_solution) as p:
        output = p.functions.shortest_path(
            len(graph.nodes()), len(graph.edges()),
            [u for u, v, w in graph.edges(data="weight")],
            [v for u, v, w in graph.edges(data="weight")],
            [w for u, v, w in graph.edges(data="weight")])

    if output == correct_output:
        print("correct! (%d == %d)" % (output, correct_output))
    else:
        print("wrong (%d != %d)" % (output, correct_output))
Exemple #10
0
import random

import turingarena as ta

for _ in range(10):
    z = random.randint(-500, 500)

    try:
        with ta.run_algorithm(ta.submission.source) as process:
            n = process.functions.rank(z)
            zz = process.functions.unrank(n)
    except ta.AlgorithmError as e:
        ta.goals["correct"] = False
        print(e)
    if z == zz:
        print(
            f"Correct! Hai codificato in numero intero {z} nel numero naturale {n} e la tua decodifica ti ha correttamente decodificato {n} come {zz}"
        )
    else:
        ta.goals.setdefault("correct", False)
        print(
            f"Pias menga! Hai codificato in numero intero {z} nel numero naturale {n} ma poi, mi decodifichi {n} come {zz}, invece che tornarmi in {z}."
        )

ta.goals.setdefault("correct", True)
print(ta.goals)
def test_case(n_u, n_v, m):
    print(f"\nEvaluating test case: N_U = {n_u}, N_V = {n_u}, M = {m}...  "
          )  #)\t", end="")

    res = 1

    N = n_u
    M = n_v

    # edges density
    edges = m

    # create random graph
    G = nx.bipartite.gnmk_random_graph(N, M, edges, seed=0xC0FFEE)
    # U is 0..N-1, V is N..N+M-1
    U, V = range(0, N), range(N, N + M)

    try:
        with ta.run_algorithm(ta.submission.source, time_limit=0.15) as p:
            # build the graphs
            n1 = len(U)
            n2 = len(V)
            mG = edges

            u = [x for x, _ in sorted(G.edges)]
            v = [y for _, y in sorted(G.edges)]

            # initialize the H graph
            H = nx.DiGraph()
            H_edges = -1
            flow_start = None
            flow_end = None

            def size_of_H(nH, mH):
                nonlocal H, H_edges
                if nH < 0:
                    raise Exception('negative number of nodes')
                if mH < 0:
                    raise Exception('negative number of edges')
                H.add_nodes_from(range(0, nH))
                H_edges = mH

            def add_edge(u, v, w):
                nonlocal H, H_edges
                if len(H.edges) == H_edges:
                    raise Exception('too many edges added with add_edge')
                if not H.has_node(u):
                    raise Exception('invalid node u={}'.format(u))
                if not H.has_node(v):
                    raise Exception('invalid node v={}'.format(v))
                H.add_edge(u, v, capacity=w)

            def set_s(s):
                nonlocal flow_start
                flow_start = s

            def set_t(t):
                nonlocal flow_end
                flow_end = t

            # the solution build H
            p.procedures.prepare_H_from_G(
                n1,
                n2,
                mG,
                u,
                v,
                callbacks=[size_of_H, add_edge, set_s, set_t])

            # test that the information provided for H are consistent
            if flow_start is None:
                raise Exception('flow start not set (use set_s)')
            if flow_end is None:
                raise Exception('flow end not set (use set_t)')
            if len(H.edges) != H_edges:
                raise Exception('inconsistent number of edges')

            max_flow, flow = nx.algorithms.flow.maximum_flow(
                H, flow_start, flow_end)

            matching = []
            cover_on_U = set()
            cover_on_V = set()

            def put_in_matching(u, v):
                nonlocal matching
                matching.append([u, v])

            def put_in_node_cover_on_side_U(u):
                nonlocal cover_on_U
                cover_on_U.add(u)

            def put_in_node_cover_on_side_V(v):
                nonlocal cover_on_V
                cover_on_V.add(v)

            def flow_val(u, v):
                nonlocal flow
                return flow[u][v]

            p.procedures.max_card_matching_and_min_node_cover_in_G(
                n1,
                n2,
                mG,
                u,
                v,
                callbacks=[
                    put_in_matching, put_in_node_cover_on_side_U,
                    put_in_node_cover_on_side_V, flow_val
                ])

            print("Evaluating the matching... \t", end="")

            try:
                # check the matching
                if max_flow != len(matching):
                    raise Exception('matching is not massimal')

                from_set = set()
                to_set = set()
                for u, v in matching:
                    # is a valid edge
                    if not G.has_edge(u, v):
                        raise Exception('({},{}) is not an edge'.format(v, u))

                    # single matching for every node
                    if u in from_set:
                        raise Exception('multiple matching for u={}'.format(u))
                    from_set.add(u)
                    if v in to_set:
                        raise Exception('multiple matching for v={}'.format(v))
                    to_set.add(v)

                # The matching is correct
                print("[CORRECT]")
                res = res * 2
            except Exception as e:
                print(f"[WRONG] \t error: {e}")

            print("Evaluating the node cover... \t", end="")

            try:
                # check the node cover
                if max_flow != (len(cover_on_U) + len(cover_on_V)):
                    raise Exception('wrong size of cover, {} vs {}'.format(
                        max_flow, (len(cover_on_U) + len(cover_on_V))))

                for (x, y) in G.edges:
                    if not x in cover_on_U and not y in cover_on_V:
                        raise Exception('edges ({},{}) is not covered'.format(
                            x, y))

                # The node cover is correct

                print("[CORRECT]")
                res = res * 3

            except Exception as e:
                print(f"[WRONG] \t error: {e}")

            # compute the minimum cut

            min_cut, partition = nx.algorithms.flow.minimum_cut(
                H, flow_start, flow_end)

            reachable, non_reachable = partition

            cutset = set()
            for u, nbrs in ((n, H[n]) for n in reachable):
                cutset.update((u, v) for v in nbrs if v in non_reachable)

            cutset = [(x, y) for x, y in cutset]

            iter_cut_left = 0
            iter_cut_right = 0
            cover_on_U = set()
            cover_on_V = set()

            def put_in_node_cover_on_side_U(u):
                nonlocal cover_on_U
                cover_on_U.add(u)

            def put_in_node_cover_on_side_V(v):
                nonlocal cover_on_V
                cover_on_V.add(v)

            def min_cut_value():
                nonlocal min_cut
                return min_cut

            def next_in_min_cut_left():
                nonlocal min_cut, iter_cut_left, cutset
                if iter_cut_left >= min_cut:
                    raise Exception('cut left has only {} nodes'.format(n1))
                iter_cut_left += 1
                return cutset[iter_cut_left - 1][0]

            def next_in_min_cut_right():
                nonlocal min_cut, iter_cut_right, cutset
                if iter_cut_right >= min_cut:
                    raise Exception('cut right has only {} nodes'.format(n1))
                iter_cut_right += 1
                return cutset[iter_cut_right - 1][1]

            p.procedures.min_node_cover_from_min_cut(
                n1,
                n2,
                callbacks=[
                    put_in_node_cover_on_side_U, put_in_node_cover_on_side_V,
                    min_cut_value, next_in_min_cut_left, next_in_min_cut_right
                ])

            print("Evaluating the node cover... \t", end="")
            try:
                # check the node cover
                if max_flow != (len(cover_on_U) + len(cover_on_V)):
                    raise Exception('wrong size of cover, {} vs {}'.format(
                        max_flow, (len(cover_on_U) + len(cover_on_V))))

                for (x, y) in G.edges:
                    if not x in cover_on_U and not y in cover_on_V:
                        raise Exception('edges ({},{}) is not covered'.format(
                            x, y))

                # The node cover is correct

                print("[CORRECT]")
                res = res * 5

            except Exception as e:
                print(f"[WRONG] \t error: {e}")

        if DEBUG:
            print(f"Time usage: {p.time_usage}")
    except Exception as e:
        print(f"[WRONG] \t error: {e}")

    if res == 2 * 3 * 5:
        print(f"test case: N_U = {n_u}, N_V = {n_u}, M = {m} [PASSED]")
    else:
        print(f"test case: N_U = {n_u}, N_V = {n_u}, M = {m} [FAILED]")

    return res
def test_case(m, n, Sr, Sc):
    def turn_off_tell_max_goal_flags(m, n):
        if m <= 100 and n <= 100:
            ta.goals["tell_max"] = False
        ta.goals["tell_max_huge"] = False

    def turn_off_tell_min_goal_flags(m, n):
        if m <= 100 and n <= 100:
            ta.goals["tell_min"] = False
        ta.goals["tell_min_huge"] = False

    cert_NOTtransv_given = False
    cert_NOTtransv_ok = None

    def exhibit_untouched_tile(row, col, dir):
        nonlocal cert_NOTtransv_given
        nonlocal cert_NOTtransv_ok
        nonlocal Sr
        nonlocal Sc
        cert_NOTtransv_given = True
        cert_NOTtransv_ok = True
        if row < 1 or col < 1 or row > m or col > n:
            print(
                f"La tessera che proponi di inserire nel transversal fuoriesce dalla scacchiera nella cella ({row},{col})."
            )
            cert_NOTtransv_ok = False
            return
        if dir == H:
            cells = [[row, col], [row, col + 1], [row, col + 2]]
        else:
            cells = [[row, col], [row + 1, col], [row + 2, col]]
        for cell in cells:
            if cell in zip(Sr, Sc):
                print(
                    f"La tessera che proponi come certificato che S non è un transversal è invece colpita da S nella cella ({row},{col})."
                )
                cert_NOTtransv_ok = False

    print(f"case (m={m}, n={n}, Sr={Sr}, Sc={Sc})")
    with ta.run_algorithm("solutions/solution.py") as ref:
        expected_is = ref.functions.is_transversal(
            m, n, len(Sr), Sr, Sc, callbacks=[exhibit_untouched_tile])
        expected_min = ref.functions.min_card_of_a_transversal(m, n)
        expected_max = ref.functions.max_card_of_a_packing(m, n)

######## TRANSVERSAL RECOGNITION EVALUATION   ########

    cert_NOTtransv_given = False
    cert_NOTtransv_ok = None
    with ta.run_algorithm(ta.submission.source) as p:
        try:
            with p.section(time_limit=0.1):
                returned_is = p.functions.is_transversal(
                    m, n, len(Sr), Sr, Sc, callbacks=[exhibit_untouched_tile])
        except ta.AlgorithmError as e:
            print(
                f"During the execution of your is_transversal({m},{n},{len(Sr)},{Sr},{Sc}) function we got the following exception:"
            )
            print(e)
            ta.goals["is_transversal"] = False
            ta.goals["cert_NOTtransv"] = False
        else:
            print(
                f"From your is_transversal({m},{n},{len(Sr)},{Sr},{Sc}) function we expected {expected_is}, got {returned_is}"
            )
            if returned_is == expected_is:
                print("OK. The two values coincide.")
                if returned_is:
                    if (not cert_NOTtransv_given) or (not cert_NOTtransv_ok):
                        ta.goals["cert_NOTtransv"] = False
                        print(
                            "However, we require you to also exhibit a possible placement of one tile avoiding the cells of S. This is convenient certificate that S is not a transveral. Please tell us where to put this tile."
                        )
            else:
                print(
                    "NO. The two values differ. You should revise your is_transversal function."
                )
                ta.goals["is_transversal"] = False
                ta.goals["cert_NOTtransv"] = False

######## MIN CARD OF A TRANSVERSAL EVALUATION   ########

        try:
            with p.section(time_limit=0.002):
                returned_min = p.functions.min_card_of_a_transversal(m, n)
        except ta.AlgorithmError as e:
            print(
                f"During the execution of your function min_card_of_a_transversal({m},{n}) we got the following exception:"
            )
            print(e)
            turn_off_tell_min_goal_flags(m, n)
        else:
            print(
                f"From your min_card_of_a_transversal({m},{n}) function we expected {expected_min}, got {returned_min}"
            )
            if returned_min == expected_min:
                print("OK. The two values coincide.")
            else:
                turn_off_tell_min_goal_flags(m, n)
                if returned_min < expected_min:
                    print(
                        f"We disbelieve the {m}x{n}-grid admits a transversal of only {returned_min} cells.  Are you sure you can produce one?\n In case you can exhibit such a transversal, please contact turingarena.org, we look forward to see it."
                    )
                else:
                    print(
                        f"The {m}x{n}-grid admits smaller transversals of only {expected_min} cells. If you disbelieve this and/or need help to advance, have a look at the transversal offered in the highly spoiling file: ... "
                    )
                    offer_a_min_transversal(m, n)

######## MAX CARD OF A PACKING EVALUATION   ########

        try:
            with p.section(time_limit=0.002):
                returned_max = p.functions.max_card_of_a_packing(m, n)
        except ta.AlgorithmError as e:
            print(
                f"During the execution of your function max_card_of_a_packing({m},{n}) we got the following exception:"
            )
            print(e)
            turn_off_tell_max_goal_flags(m, n)
        else:
            print(
                f"From your max_card_of_a_packing({m},{n}) function we expected {expected_max}, got {returned_max}"
            )
            if returned_max == expected_max:
                print("OK. The two values coincide.")
            else:
                turn_off_tell_max_goal_flags(m, n)
                if returned_max > expected_max:
                    print(
                        f"We disbelieve you can pack {returned_max} 1,3-bars within a {m}x{n}-grid.  Are you sure?\n In case you can exhibit such a packing, please contact turingarena.org, we look forward to see it."
                    )
                else:
                    print(
                        f"You can actually pack up to {expected_max} 1,3-bars within a {m}x{n}-grid. If you disbelieve this and/or need help, have a look at the packing offered in the file: ... "
                    )
                    offer_a_max_packing(m, n)

######## BEGIN TRANSVERSAL CONSTRUCTION VERIFICATION   ########

        trans_construction_ok = True
        placed_in_S = 0
        S = [[False for _ in range(n + 1)] for _ in range(m + 1)]

        def place_in_S(row, col):
            nonlocal trans_construction_ok
            nonlocal placed_in_S
            nonlocal S
            placed_in_S += 1
            if row < 1 or col < 1 or row > m or col > n:
                print(
                    f"La cella che proponi di inserire nel transversal fuoriesce dalla scacchiera nella cella ({row},{col})."
                )
                trans_construction_ok = False
                return
            if S[row][col]:
                print(
                    f"Hai già inserito la cella ({row},{col}) nel transversal."
                )
                trans_construction_ok = False
            S[row][col] = True

        try:
            print(
                "[mostra il transversal (fino all'eventuale errore), magari in un file esterno da scaricare od un applet]"
            )
            with p.section(time_limit=0.2):
                p.procedures.produce_min_transversal(m,
                                                     n,
                                                     callbacks=[place_in_S])
        except ta.AlgorithmError as e:
            print(
                f"During the execution of your procedure produce_min_transversal({m},{n}) we got the following exception:"
            )
            print(e)
            ta.goals["min_transversal"] = False
        else:
            if trans_construction_ok:

                def isTransversal(S, m, n):
                    for i in range(1, m + 1):
                        for j in range(1, n - 1):
                            intersects = 0
                            for k in range(3):
                                if S[i][j + k]:
                                    intersects += 1
                            if intersects == 0:
                                return False
                    for i in range(1, m - 1):
                        for j in range(1, n + 1):
                            intersects = 0
                            for k in range(3):
                                if S[i + k][j]:
                                    intersects += 1
                            if intersects == 0:
                                return False
                    return True

                if isTransversal(S, m, n):
                    if placed_in_S == expected_min:
                        print(
                            f"Complimenti! Il tuo transversal per la griglia ({m},{n}) è corretto ed ottimo."
                        )
                    else:
                        ta.goals["min_transversal"] = False
                        print(
                            f"NO: hai collocato solo {placed_in_S} tessere contro le {expected_max} possibili. Di positivo: l'insieme di celle S composto dalla tua procedura produce_min_transversal({m},{n}) è effettivamente un transversal per quella griglia."
                        )
                else:
                    ta.goals["min_transversal"] = False
                    print(
                        f"NO: l'insieme S = {S} costruito dalla tua procedura produce_min_transversal({m},{n}) NON è un transversal per quella griglia."
                    )
            else:
                ta.goals["min_transversal"] = False

######## END TRANSVERSAL CONSTRUCTION VERIFICATION   ########
######## BRGIN PACKING CONSTRUCTION VERIFICATION   ########

        pack_construction_ok = True
        posed_tiles = 0
        covered = [[False for _ in range(n + 1)] for _ in range(m + 1)]
        lista_tiles = []

        def place_tile(row, col, dir):
            nonlocal pack_construction_ok
            nonlocal posed_tiles
            nonlocal covered
            nonlocal lista_tiles
            lista_tiles.append((row, col, dir))
            posed_tiles += 1
            if dir == H:
                cells = [[row, col], [row, col + 1], [row, col + 2]]
            else:
                cells = [[row, col], [row + 1, col], [row + 2, col]]
            for cell in cells:
                row = cell[0]
                col = cell[1]
                if row < 1 or col < 1 or row > m or col > n:
                    print(
                        f"La tua tessera fuoriesce dalla scacchiera nella cella ({row},{col})."
                    )
                    pack_construction_ok = False
                    return
                if covered[row][col]:
                    print(
                        f"Due delle tue tegole coprono la cella ({row},{col})."
                    )
                    pack_construction_ok = False
                covered[row][col] = True

        try:
            with p.section(time_limit=0.2):
                p.procedures.produce_max_packing(m, n, callbacks=[place_tile])
        except ta.AlgorithmError as e:
            print(
                f"During the execution of your procedure produce_max_packing({m},{n}) we got the following exception:"
            )
            print(e)
            ta.goals["max_packing"] = False
        else:
            if pack_construction_ok:
                if posed_tiles == expected_max:
                    print(
                        f"Complimenti! Il tuo packing della griglia ({m},{n}) è corretto ed ottimo."
                    )
                else:
                    ta.goals["max_packing"] = False
                    print(
                        f"NO: hai collocato solo {posed_tiles} tessere contro le {expected_max} possibili. Di positivo: non sei uscito dalla griglia ({m},{n}) e non hai sovrapposto tessere. Nessun conflitto."
                    )
                print(
                    "[vuoi vedere il packing generato dalla tua procedura? File esterni da scaricare: visualizzazione statica in grafica vettoriale e ASCII solo log delle piastelle da usare per debug e visualizzabile in un'applet]"
                )
            else:
                print("mostra il packing fino all'errore: ", lista_tiles)

                ta.goals["max_packing"] = False
Exemple #13
0
def test_correct_solution():
    with ta.run_algorithm("solutions/correct.cpp") as p:
        assert p.functions.sum(3, 5) == 8
Exemple #14
0
def test_with_seq(seq):
    def turn_off_goals():
        ta.goals["correct"] = False
        ta.goals["correct_C_is_2"] = False
        ta.goals["correct_C_is_1dot1"] = False

    encoded_seq = []
    decoded_seq = []
    try:
        with ta.run_algorithm(ta.submission.source) as process:
            process.procedures.get_original_string(len(seq), seq)
            encoded_len = process.functions.tell_encoded_string_length()
            for i in range(encoded_len):
                encoded_seq.append(
                    process.functions.tell_encoded_string_ith_char(i))
    except ta.AlgorithmError as e:
        turn_off_goals()
        print(e)

    try:
        with ta.run_algorithm(ta.submission.source) as process:
            process.procedures.get_encoded_string(len(encoded_seq),
                                                  encoded_seq)
            decoded_len = process.functions.tell_original_string_length()
            for i in range(decoded_len):
                decoded_seq.append(
                    process.functions.tell_original_string_ith_char(i))
    except ta.AlgorithmError as e:
        turn_off_goals()
        print(e)

    print(f"The string to be encoded was:\n   {seq}")
    print(f"You encoded it with:\n   {encoded_seq}")
    all_allowed_keys = True
    wrong_key = None
    wrong_pos = None
    for pos, val in zip(range(len(encoded_seq)), encoded_seq):
        if val not in allowed_keys:
            turn_off_goals()
            all_allowed_keys = False
            wrong_key = val
            wrong_pos = pos
            break
    if not all_allowed_keys:
        print(
            f"NO: Use of key '{wrong_key}' forbidden in the encoded sequence. You used it in position {wrong_pos} (positions start from 0)."
        )
    else:
        print("OK. You only used allowed keys. Good!")

    print(f"Which you decoded as:\n   {decoded_seq}")
    if len(decoded_seq) != len(seq):
        turn_off_goals()
        print(
            f"NO: Notice that the lengths of the original sequence (which contained {len(decoded_seq)} charactes over the alphabet {'0','1','2','3','4','5','6','7','8','9','-1'}) and the decoded one (which contains {len(seq)} numbers over the same alphabet {'0','1','2','3','4','5','6','7','8','9','-1'}) differ."
        )
    are_equal = True
    for i in range(len(seq)):
        if seq[i] != decoded_seq[i]:
            turn_off_goals()
            are_equal = False
            break
    if not are_equal:
        print(
            f"NO: The original sequence and the decoded one differ in position {i}, where the original reports a '{seq[i]}' character and the decoded reports a '{decoded_seq[i]}' character."
        )
    else:
        print(
            "OK. You correctly reconstructed the original sequence. Congrats!")
    if len(seq) > 0:
        return (len(decoded_seq) - 3) / len(seq)
    else:
        return 1.0
Exemple #15
0
def test_case(n, m, is_sat):
    print(f"\nEvaluating test case: N = {n}, M = {m} SAT={is_sat}...  ")

    res = 1

    # edges density
    (a,b) = generate_random_formula(n,m,is_sat)

    try:
        with ta.run_algorithm(ta.submission.source, time_limit=0.15) as p:
            # initialize the H graph
            G = nx.DiGraph()
            G_edges = 0

            def size_of_G(nG,mG):
                nonlocal G, G_edges
                if nG < 0:
                    raise Exception('negative number of nodes')
                if mG < 0:
                    raise Exception('negative number of edges')
                G.add_nodes_from(range(0,nG))
                G_edges = mG

            def add_edge(u,v):
                nonlocal G, G_edges
                if len(G.edges) == G_edges:
                    raise Exception('too many edges added with add_edge')

                if not G.has_node(u):
                    raise Exception(
                            'in function add_edge. Invalid node u={}'.format(u))
                if not G.has_node(v):
                    raise Exception(
                            'in function add_edge. Invalid node v={}'.format(v))
                G.add_edge(u,v)


            print("Evaluating the satisfiability... ", end="")

            # the solution build G
            p.procedures.prepare_G(n,m,a,b,
                    callbacks=[
                        size_of_G,
                        add_edge
                        ])

            assignments = [-1]*(n+1)
            n_of_assignments = 0

            def assign_variable(letteral,value):
                nonlocal n, n_of_assignments, assignments
                if letteral > n:
                    raise Exception('in function assign_variable. Invalid letteral {}'.format(letteral))
                if assignments[letteral] != -1:
                    raise Exception('multiple assignments for letteral {}'.format(letteral))
                assignments[letteral] = False if value <= 0 else True
                n_of_assignments = n_of_assignments + 1


            nG = len(G)
            components = [-1] * nG
            comp = 0

            # generate strongly connected components in reverse topological order
            scc = nx_comp.strongly_connected_components_recursive(G)
            # assigns components in topologigical order
            for C in reversed(list(scc)):
                for node in C:
                    components[node] = comp
                comp += 1

            ris = p.functions.is_satisfiable(nG,components,
                    callbacks=[
                        assign_variable
                        ])

            if ris <= 0:
                ris = False
            else:
                ris = True

            if ris != is_sat:
                print("[WRONG]")
                if ris:
                    raise Exception('The formula is unsatisfiable, but you claim that is satisfiable')
                else:
                    raise Exception('The formula is satisfiable, but you claim that is not satisfiable')

            print("[CORRECT]")

            res *= 2

            # nothing to do for unsat instances
            if not is_sat:
                return res

            print("Evaluating the assignments... \t", end="")
            try:
                # check the assignment
                if n_of_assignments != n:
                    raise Exception('you assigned less letterals than those in the formula')

                result = True;
                for i in range(m):
                    letteral_a = abs(a[i])
                    letteral_b = abs(b[i])
                    dir_a = False if a[i] < 0 else True
                    dir_b = False if b[i] < 0 else True
                    if (assignments[letteral_a] != dir_a and assignments[letteral_b] != dir_b):
                        raise Exception('the assignment is not a model. The assignments {}={} and {}={}, falsifies the clausole ({} v {})'.format(
                                letteral_a,assignments[letteral_a],letteral_b,assignments[letteral_b],a[i],b[i]))

                # The assignement is correct
                print("[CORRECT]")
                res = res * 3
            except Exception as e:
                print(f"[WRONG] \t error: {e}")

    except Exception as e:
        print(f"[WRONG] \t error: {e}")

    if res == 2*3:
        print(f"test case: N = {n}, M = {m} [PASSED]")
    else:
        print(f"test case: N = {n}, M = {m} [FAILED]")

    return res
Exemple #16
0
def evaluate_testcase(input_necklace_colors):
    #print(f"Testing with n = {len(input_necklace)} necklace = {input_necklace} ...", end=" ")
    print(f"Testing with a necklace of {len(input_necklace)} beads ...",
          end=" ")

    def num_breakpoints(necklace_colors):
        risp = 0
        if necklace_colors[len(necklace_colors) - 1] != necklace_colors[0]:
            risp += 1
        for pos in range(len(necklace_colors) - 1):
            if necklace_colors[pos] != necklace_colors[pos + 1]:
                risp += 1
        return risp

    n = len(input_necklace_colors)
    current_necklace_colors = input_necklace_colors[:]
    current_necklace_names = list(range(1, n + 1))
    pos_of_bead = [None] + list(range(n))

    def reverse_integral(a_name, b_name):
        #print(f"Evaluator reverse_integral(a_name={a_name},b_name={b_name})")

        nonlocal current_necklace_colors, current_necklace_names, pos_of_bead

        def swap(a_pos, b_pos):
            #print(f"Evaluator swap(a_pos={a_pos},b_pos={b_pos})")
            nonlocal current_necklace_colors, current_necklace_names, pos_of_bead
            pos_of_bead[current_necklace_names[b_pos]] = a_pos
            pos_of_bead[current_necklace_names[a_pos]] = b_pos
            tmp = current_necklace_names[a_pos]
            current_necklace_names[a_pos] = current_necklace_names[b_pos]
            current_necklace_names[b_pos] = tmp
            tmp = current_necklace_colors[a_pos]
            current_necklace_colors[a_pos] = current_necklace_colors[b_pos]
            current_necklace_colors[b_pos] = tmp

        a_pos = pos_of_bead[a_name]
        b_pos = pos_of_bead[b_name]
        finished = False
        while not finished:
            swap(a_pos, b_pos)
            a_pos = (a_pos + 1) % n
            if a_pos == b_pos:
                finished = True
            b_pos = (b_pos - 1 + n) % n
            if a_pos == b_pos:
                finished = True

    try:

        def reverse_interval(a_name, b_name):
            nonlocal num_made_moves, n
            #print(f"reverse_interval(a = {a_name}, b={b_name}) called.")
            if a_name < 0 or a_name > n or b_name < 0 or b_name > n:
                print(
                    f"WRONG: The call reverse_interval(a = {a_name}, b={b_name}) is not valid."
                )
                ta.goals.setdefault("solve_in_any_number_of_moves", False)
                ta.goals.setdefault("at_most_n2_moves", False)
                ta.goals.setdefault("opt_solve", False)
                ta.goals.setdefault("linear_time", False)
            else:
                num_made_moves += 1
                reverse_integral(a_name, b_name)

        #expected_answer = (num_breakpoints(input_necklace_colors)-2)/2
        with ta.run_algorithm("solutions/only_num_moves_correct.c") as p:
            expected_answer = p.functions.necklace(
                len(input_necklace),
                input_necklace,
                callbacks=[reverse_interval])

        # print(f"The reference solution says that the minimum number of moves is {expected_answer}")

        num_made_moves = 0
        with ta.run_algorithm(ta.submission.source) as p:
            obtained_answer = p.functions.necklace(
                len(input_necklace),
                input_necklace,
                callbacks=[reverse_interval])
    except ta.AlgorithmError as e:
        print(f" error: {e}")
        ta.goals.setdefault("correct_num_moves", False)
        ta.goals.setdefault("solve_in_any_number_of_moves", False)
        ta.goals.setdefault("at_most_n2_moves", False)
        ta.goals.setdefault("opt_solve", False)
        ta.goals.setdefault("linear_time", False)

    print(f"(time: {int(p.time_usage * 1000000)} us)")

    if obtained_answer == expected_answer:
        print(f" Correct minimum number of moves!", end=" ")
    else:
        ta.goals.setdefault("correct_num_moves", False)
        print(
            f"We disagree on the minimum number of moves needed to solve the necklace {input_necklace}. Your answer is {obtained_answer} while we believe the correct number is {expected_answer}.",
            end=" ")

    if num_breakpoints(current_necklace_colors) > 2:
        ta.goals.setdefault("solve_in_any_number_of_moves", False)
        ta.goals.setdefault("at_most_n2_moves", False)
        ta.goals.setdefault("opt_solve", False)
        ta.goals.setdefault("linear_time", False)
        if num_made_moves == 0:
            print(f" Your solution did no move.")
        else:
            print(
                f"Starting from the necklace {input_necklace_colors} your solution ends up with the necklace {current_necklace_colors} which is NOT entirely solved!",
                end=" ")
    else:
        if expected_answer > 0:
            print(f"Correct: your procedure fully solved the necklace.")
        else:
            print(
                f"Correct: no move was needed and no move was done by your code."
            )

    if num_made_moves > n * n:
        print(f"But used quite a lot of moves.")
        ta.goals.setdefault("at_most_n2_moves", False)
        ta.goals.setdefault("linear_time", False)

    if int(p.time_usage * 1000000) > 2000:
        print(
            f"Your procedure is too slow. There exists a linear time solution to this problem."
        )
        ta.goals.setdefault("linear_time", False)
Exemple #17
0
def test_case(m, n):
    def turn_off_construction_goal_flags(m, n):
        if m == 1:
            ta.goals["construction_m1"] = False
        if m <= 10 and n <= 10:
            ta.goals["construction_small"] = False
        ta.goals["construction"] = False

    def turn_off_decision_goal_flags(m, n):
        if m == 1:
            ta.goals["decision_m1"] = False
        if m <= 10 and n <= 10:
            ta.goals["decision_small"] = False
        if m <= 100 and n <= 100:
            ta.goals["decision"] = False
        ta.goals["decision_huge"] = False

    with ta.run_algorithm(ta.submission.source) as p:
        print(f"case (m={m}, n={n})")
        try:
            res = p.functions.is_tilable(m, n)
        except ta.AlgorithmError as e:
            print(
                f"During the execution of your function is_tilable({m},{n}) we got the following exception:"
            )
            print(e)
            turn_off_decision_goal_flags(m, n)
        else:
            print(
                f"From your is_tilable({m},{n}) function we expected {1 - (m % 2) * (n %2 )}, got {res}"
            )
            if res == 1 - (m % 2) * (n % 2):
                print("OK. The two values coincide.")
            else:
                turn_off_decision_goal_flags(m, n)
                if res == 0:
                    turn_off_construction_goal_flags(m, n)
                    print(
                        f"According to your is_tilable function, the {m}x{n}-grid is not tilable with dominos. However, we believe it is! Be aware that dominos can be placed either vertically or horizzontally, at your will (that is, they can cover either 1x2-subgrids or 2x1-subgrids of the {m}x{n}-grid). If you disbelieve the {m}x{n}-grid is tilable and/or need help to advance, have a look at the tiling offered in the spoiling solution file: ... "
                    )
                    offer_a_tiling(m, n)
                if res != 0:
                    print(
                        f"According to your is_tilable function, the {m}x{n}-grid is tilable. Are you sure?\n In case you can exhibit such a tiling, please contact turingarena.org, we look forward to see it."
                    )

        if (m % 2) * (n % 2) == 1 or res == 0 or m > 100 or n > 100:
            return

        # BEGIN: testing of the procedure constructing the tiling
        print(
            f"Ok, since we agree the tiling exists, and an ({m},{n})-board is still reasonably small, let's find out whether your code can actually construct the tiling and measure its efficiency."
        )
        construction_ok = True
        posed_tiles = 0
        covered = [[False for _ in range(n + 1)] for _ in range(m + 1)]
        lista_tiles = []

        def place_tile(row, col, dir):
            nonlocal construction_ok
            nonlocal posed_tiles
            nonlocal covered
            nonlocal lista_tiles
            lista_tiles.append((row, col, dir))
            posed_tiles += 1
            if dir == H:
                cells = [[row, col], [row, col + 1]]
            else:
                cells = [[row, col], [row + 1, col]]
            for cell in cells:
                row = cell[0]
                col = cell[1]
                if row < 1 or col < 1 or row > m or col > n:
                    print(
                        f"La tua tessera fuoriesce dalla scacchiera nella cella ({row},{col})."
                    )
                    construction_ok = False
                    return
                if covered[row][col]:
                    print(
                        f"Due delle tue tegole coprono la cella ({row},{col})."
                    )
                    construction_ok = False
                covered[row][col] = True

        try:
            print(
                "[mostra il tiling (fino all'eventuale errore), magari in un file esterno da scaricare od un applet]"
            )
            p.procedures.compose_tiling(m, n, callbacks=[place_tile])
        except ta.AlgorithmError as e:
            print(
                f"During the execution of your procedure compose_tiling({m},{n}) we got the following exception:"
            )
            print(e)
            turn_off_construction_goal_flags(m, n)
        else:
            if construction_ok:
                if 2 * posed_tiles == m * n:
                    print(
                        f"Complimenti! Hai riempito perfettamente la griglia ({m},{n}). Il tuo tiling è corretto."
                    )
                else:
                    print(
                        f"NO: non hai ricoperto l'intera griglia ({m},{n}). Hai collocato solo {posed_tiles} tessere. Di positivo: non sei uscito dalla griglia ({m},{n}) e non hai sovrapposto tessere. Nessun conflitto."
                    )
                    offer_a_tiling(m, n)
                    print(
                        f"Hai fornito un packing corretto ma esso non è un tiling perfetto quindi non mi è ovvio esso sia ottimo. Per ora mi hai convinto che esista un packing di almeno {posed_tiles}, ossia mi hai dato un lower-bound sul valore ottimo del packing. In esercizi successivi di questo percorso apprenderai come fornire argomenti a supporto dell'ottimalità dei tuoi packing e andiamo a vedere quanto è buono l'upper-bound che sai fornirmi. Tuttavia in questo caso (m={m} e n={n}) esiste un tiling ottimo. Quindi prendiamo per NON buono il packing che hai qui prodotto."
                    )
                    turn_off_construction_goal_flags(m, n)
                print(
                    "[vuoi vedere come la tua procedura ha collocato le piastrelle? In questo punto potremmo mettere il tiling prodotto dalla tua procedura dentro in file esterni che il problem-solver possa scaricarsi: sarebbe bella una visualizzazione statica in grafica vettoriale, con le piastrelle numerate nell'ordine di posatura, ma anche un ASCII con solo il log della sequenza delle chiamate a pose_tile da usare per eventuale debug, e comunque visualizzabile in un'applet. Come vedi, ci sono mille modi in cui puoi contribuire a rendere TA piu ricco ed interattivo. Se anche tu come noi pensi 'We don't need no education' non esistare: richiedi progetti e 'brake on through to the other side'.]"
                )
            else:
                print("mostra il tiling fino all'errore: ", lista_tiles)
                turn_off_construction_goal_flags(m, n)
Exemple #18
0
                print(
                    f"Correct! Certificato verificato: come divisore comune hai fornito un numero valido ({d})."
                )

        def give_multipliers(x, y):
            if x * a + y * b != 1:
                print(
                    f"WRONG: Fornisci due moltiplicatori x={x} ed y={y} per i quali non vale che x*a + y*b = 1."
                )
                ta.goals["correct_YES_certificate"] = False
            else:
                print(
                    f"Correct! Certificato verificato: come moltiplicatori hai fornito x={x} e y={y} ed ho verificato che x*a + y*b = 1."
                )

        with ta.run_algorithm("solutions/correct.py") as p:
            expected_answer = p.functions.are_coprime(
                a, b, callbacks=[give_divisor, give_multipliers])

        with ta.run_algorithm(ta.submission.source) as p:
            obtained_answer = p.functions.are_coprime(
                a, b, callbacks=[give_divisor, give_multipliers])
    except ta.AlgorithmError as e:
        print(f" error: {e}")
        ta.goals.setdefault("correct_answer", False)
        ta.goals.setdefault("correct_NO_certificate", False)
        ta.goals.setdefault("correct_YES_certificate", False)

    if obtained_answer == 0:
        print(f" your answer: {a} and {b} are NOT coprime", end="")
    else: