Last active
May 29, 2023 07:15
-
-
Save qnkhuat/eac3b1eaa05d47be6199a89ed950d49c to your computer and use it in GitHub Desktop.
Reverse engineer the mapping logic from 18 to 24
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;; ------------------------- Implementation by Sasha converted to clojure ------------------------- ;;; | |
(def mapping {0 {:start 0 :end 0} | |
1 {:start 1 :end 2} | |
2 {:start 3 :end 3} | |
3 {:start 4 :end 4} | |
4 {:start 5 :end 6} | |
5 {:start 7 :end 7} | |
6 {:start 8 :end 8} | |
7 {:start 9 :end 10} | |
8 {:start 11 :end 11} | |
9 {:start 12 :end 12} | |
10 {:start 13 :end 14} | |
11 {:start 15 :end 15} | |
12 {:start 16 :end 16} | |
14 {:start 19 :end 19} | |
13 {:start 17 :end 18} | |
15 {:start 20 :end 20} | |
16 {:start 21 :end 22} | |
17 {:start 23 :end 23} | |
18 {:start 24 :end 24}}) | |
(defn migrate18-to-24 [start width] | |
(let [end (+ start width -1) | |
new-start (:start (get mapping start)) | |
new-end (:end (get mapping end)) | |
width (- (inc new-end) new-start)] | |
[new-start width])) | |
#_(map (fn [[f s]] [f (:start s)]) (sort-by first mapping)) | |
(def ground-truth-start | |
"A mapping from start in grid 18 -> start in grid 24. | |
Start is `report_dashboardcard.col`." | |
[[0 0] | |
[1 1] | |
[2 3] | |
[3 4] | |
[4 5] | |
[5 7] | |
[6 8] | |
[7 9] | |
[8 11] | |
[9 12] | |
[10 13] | |
[11 15] | |
[12 16] | |
[13 17] | |
[14 19] | |
[15 20] | |
[16 21] | |
[17 23] | |
[18 24]]) | |
#_(map (fn [[f s]] [f (:end s)]) (sort-by first mapping)) | |
(def ground-truth-end | |
"A mapping from end in grid 18 -> end in grid 24. | |
End is `report_dashboardcard.col + report_dashboardcard.size_x`." | |
[[0 0] | |
[1 2] | |
[2 3] | |
[3 4] | |
[4 6] | |
[5 7] | |
[6 8] | |
[7 10] | |
[8 11] | |
[9 12] | |
[10 14] | |
[11 15] | |
[12 16] | |
[13 18] | |
[14 19] | |
[15 20] | |
[16 22] | |
[17 23] | |
[18 24]]) | |
;;; ------------------------- Step 1: deduced by inference from output pattern of start and end column ------------------------- ;;; | |
(defn start-from-18-to-24 | |
"Given `start` position in grid 18, returns `start` in grid 24." | |
[x] (+ x (quot (+ x 1) 3))) | |
;; TEST: does start-from-18-to-24 match the ground-truth? | |
(= (map (fn [x] [x (start-from-18-to-24 x)]) (range 19)) | |
ground-truth-start) | |
;; => true | |
(defn end-f | |
"Given `end` position in grid 18, returns `end` in grid 24." | |
[x] (+ x (quot (+ x 2) 3))) | |
;; TEST: does end-f match the ground-truth? | |
(= (map (fn [x] [x (end-f x)]) (range 19)) | |
ground-truth-end) | |
;; => true | |
;; putting it all together | |
(defn migrate18-to-24-reversed-engineering | |
"This is the equivalent algorithm that uses the mapping above. | |
An advantage of this algorithm is that it's purely math, there is no mapping needed" | |
[start width] | |
(let [new-start (start-from-18-to-24 start) | |
new-end (end-f (+ start width -1)) | |
width (- (inc new-end) new-start)] | |
[new-start width])) | |
;; TEST: brute force test to make sure the output match with the original implementation | |
(def results | |
(for [w (range 1 6) | |
s (range 0 (- 19 w))] | |
(let [original-result (migrate18-to-24 s w) | |
my-result (migrate18-to-24-reversed-engineering s w)] | |
[[s w] original-result my-result (= original-result my-result)]))) | |
(take 3 results) | |
;; => ( | |
;; [[0 1] [0 1] [0 1] true] | |
;; [[1 1] [1 2] [1 2] true] | |
;; [[2 1] [3 1] [3 1] true] | |
;; ) | |
(every? true? (map last results)) | |
;; => true | |
;;; ------------------------------------ Step 2: shorten the formula ------------------------------------ ;;; | |
(defn migrate18-to-24-short | |
"This should yield the same results as `migrate18-to-24-reversed-engineering` | |
The advantage of this algoirthm to the last is it has less operations and variables, thus easier to write an SQL for." | |
[start width] | |
(let [new-start (+ start (quot (+ start 1) 3)) | |
new-width (- (+ width | |
(quot (+ start width 1) 3)) | |
(quot (+ start 1) 3))] | |
[new-start new-width])) | |
;; TEST: same test as above | |
(def results | |
(for [w (range 1 6) | |
s (range 0 (- 19 w))] | |
(let [original-result (migrate18-to-24 s w) | |
my-result (migrate18-to-24-short s w)] | |
[[s w] original-result my-result (= original-result my-result)]))) | |
(take 3 results) | |
;; => ( | |
;; [[0 1] [0 1] [0 1] true] | |
;; [[1 1] [1 2] [1 2] true] | |
;; [[2 1] [3 1] [3 1] true] | |
;; ) | |
(every? true? (map last results)) | |
;; => true |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment