Track less-effective main.hy
dkl9

dkl9 commited on 2025-355 21:08:48
Showing 1 changed files, with 118 additions and 0 deletions.

... ...
@@ -0,0 +1,118 @@
1
+(require hyrule [-> unless] :readers [%])
2
+(import hyrule [dec inc reduce])
3
+(import bisect itertools pprint random)
4
+
5
+(setv [W H K M] [6 6 5 10])
6
+(setv DIRS [#(1 0) #(0 1) #(-1 0) #(0 -1)])
7
+
8
+(defn edge-len [layer even?] (+ (* 2 layer) even?))
9
+
10
+(defn partition-layer [layer even?]
11
+    (setv polys [])
12
+    (setv theta 0)
13
+    (while (and (< (len polys) (// (* W H) K)) (< theta (* (edge-len layer even?) 4)))
14
+        (setv dt (min (random.randint 2 K) (- (* (edge-len layer even?) 4) theta)))
15
+        (polys.append #(theta (+ theta dt)))
16
+        (+= theta dt))
17
+    polys)
18
+
19
+(defn scale-out [layer even? angle]
20
+    (let [el (edge-len layer even?)]
21
+        (+ (* (+ el 2) (// angle el)) (% angle el) 1)))
22
+
23
+(defn part-graph [even? pll]
24
+    (let [nodes (list (itertools.chain #* (map #%(let [l (get %1 0)]
25
+        (map #% #(l (get %1 0) (get %1 1)) (get %1 1))) (enumerate pll))))]
26
+        (dfor a nodes #(a) (sfor b nodes
27
+            :if (or
28
+                (and
29
+                    (= (get a 0) (inc (get b 0)))
30
+                    (> (scale-out (get b 0) even? (get b 2)) (get a 1))
31
+                    (> (get a 2) (scale-out (get b 0) even? (get b 1))))
32
+                (and
33
+                    (= (get b 0) (inc (get a 0)))
34
+                    (> (scale-out (get a 0) even? (get a 2)) (get b 1))
35
+                    (> (get b 2) (scale-out (get a 0) even? (get a 1)))))
36
+            #(b)))))
37
+
38
+(defn contraction [g a b]
39
+    (let [ab (+ a b) sab (| (get g a) (get g b))]
40
+        (setv (get g ab) sab)
41
+        (for [nb g] (let [nbs (get g nb)]
42
+            (when (or (in a nbs) (in b nbs)) (.add nbs ab))
43
+            (.discard nbs a)
44
+            (.discard nbs b)))
45
+        (.discard (get g ab) ab)
46
+        (del (get g a) (get g b))))
47
+
48
+(defn weight [pl] (sum (map #%(- (get %1 2) (get %1 1)) pl)))
49
+
50
+(defn merge-lightest [pg tl th]
51
+    (let [lightest (min pg
52
+        :key #%(+ (* 2 (weight %1)) (min (map weight (get pg %1)) :default (** W 2))))]
53
+        (when (and (< (weight lightest) tl) (get pg lightest))
54
+            (let [ln (min (get pg lightest) :key weight)]
55
+                (when (<= (+ (weight lightest) (weight ln)) th)
56
+                    (contraction pg lightest ln)
57
+                    True)))))
58
+
59
+(defn add [p q] #((+ (get p 0) (get q 0)) (+ (get p 1) (get q 1))))
60
+
61
+(defn corners [poly]
62
+    #(#((min (map #%(get %1 0) poly)) (min (map #%(get %1 1) poly)))
63
+        #((max (map #%(get %1 0) poly)) (max (map #%(get %1 1) poly)))))
64
+
65
+(defn polar->rect [layer even? angle]
66
+    (when (and (= layer 0) (not even?)) (return #(0 0)))
67
+    (setv el (edge-len layer even?))
68
+    (setv [q r] [(// angle el) (% angle el)])
69
+    (match q
70
+        0 #((- r layer) layer)
71
+        1 #((+ layer even?) (- layer r))
72
+        2 #((- (+ layer even?) r) (- (+ layer even?)))
73
+        3 #((- layer) (- r (+ layer even?)))))
74
+
75
+(defn coordify [layer even? poly]
76
+    (cond
77
+        (isinstance (get poly 0) tuple) (reduce #%(| %1 %2) (map #%(coordify layer even? %1) poly))
78
+        (= (len poly) 3) (coordify (get poly 0) even? #((get poly 1) (get poly 2)))
79
+        True (sfor t (range (get poly 0) (get poly 1)) (polar->rect layer even? t))))
80
+
81
+(defn rotate [points rights]
82
+    (sfor #(x y) points #(
83
+        (+ (* (% (inc rights) 2) (** -1 (// rights 2)) x) (* (% rights 2) -1 (** -1 (// rights 2)) y))
84
+        (+ (* (% rights 2) (** -1 (// rights 2)) x) (* (% (inc rights) 2) (** -1 (// rights 2)) y)))))
85
+
86
+(defn normalised [poly]
87
+    (unless poly (return poly))
88
+    (setv mc (get (corners poly) 0))
89
+    (setv mc #((- (get mc 0)) (- (get mc 1))))
90
+    (set (map #%(add %1 mc) poly)))
91
+
92
+(defn display [poly]
93
+    (unless poly (return "(empty)"))
94
+    (if (isinstance poly list)
95
+        (let [mc #((dec W) (dec W))] ; TODO: calculate correctly
96
+            (.join "\n" (lfor y (range (inc (get mc 1))) (.join ""
97
+                (lfor x (range (inc (get mc 0)))
98
+                    (get (next (itertools.dropwhile
99
+                        #%(and (get %1 1) (not-in #((- x (// W 2) -1) (- y (// W 2))) (get %1 1)))
100
+                        (itertools.chain
101
+                            (zip ["#" "$" "%" "&" "+" "=" "?" "@"] poly)
102
+                            [#("." #{})]))) 0))))))
103
+        (let [mc (get (corners poly) 1)]
104
+            (.join "\n" (lfor y (range (inc (get mc 1))) (.join "" (lfor x (range (inc (get mc 0)))
105
+                (if (in #(x y) poly) "#" "."))))))))
106
+
107
+(defn divider [] (print (* W "-")))
108
+
109
+(setv mlp (lfor l (range (// W 2)) (partition-layer l True)))
110
+(setv pg (part-graph True mlp))
111
+(while (merge-lightest pg K M))
112
+(for [p pg]
113
+        (divider)
114
+        (-> None (coordify True p) (rotate (random.randint 0 3)) (normalised) (display) (print)))
115
+(input "show solution? ")
116
+(-> (map #%(coordify None True %1) pg) (list) (display) (print))
117
+
118
+; TODO: better algorithm
0 119