Skip to content

Instantly share code, notes, and snippets.

@qnkhuat
Last active May 29, 2023 07:15
Show Gist options
  • Save qnkhuat/eac3b1eaa05d47be6199a89ed950d49c to your computer and use it in GitHub Desktop.
Save qnkhuat/eac3b1eaa05d47be6199a89ed950d49c to your computer and use it in GitHub Desktop.
Reverse engineer the mapping logic from 18 to 24
;;; ------------------------- 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