-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpermutations.py
executable file
·62 lines (48 loc) · 1.65 KB
/
permutations.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#!/usr/bin/env python3
# -*- coding: utf-8; mode: python -*-
from __future__ import annotations
import loguru as LG
import rich.live as RV
import rich.logging as RL
import rich.panel as RP
import rich.pretty as RY
import rich.traceback as RT
import typer as TR
from pyata.core import (
Ctx, NoCtx, Solver, Eq, And, Or, Distinct, Vars
)
RT.install()
LG.logger.configure(handlers=[dict(
level="DEBUG",
sink=RL.RichHandler(
markup=True,
show_path=False,),
format="{message}",)])
def main(n: int = 9) -> None:
ctx, vars = Vars.fresh(NoCtx, int, n)
goal = And(*(Or(*(Eq(v, i) for i in range(n))) for v in vars),
Distinct(*vars))
solver = Solver(ctx, vars, goal)
n_solutions = 0
latest_solution = None
with RV.Live(RP.Panel.fit(RY.Pretty(solver)),
auto_refresh=False,
transient=True
) as live:
def per_sec_cb(ctx: Ctx, data: tuple[int, float]) -> Ctx:
LG.logger.info(f'Solution {n_solutions}: {latest_solution}')
live.update(
RP.Panel.fit(RY.Pretty(dict(
steps_taken = solver.steps_count,
n_solutions = n_solutions,
latest_solution = latest_solution,
solver_state = solver))),
refresh=True)
return ctx
solver.hook_per_sec(per_sec_cb)
# Solve
for solution in solver:
n_solutions += 1
latest_solution = solution
LG.logger.info(f'{n_solutions} solutions found.')
TR.run(main)