aboutsummaryrefslogtreecommitdiff
path: root/challenge-027/archargelod
diff options
context:
space:
mode:
authorArchargelod <archargelod@gmail.com>2024-03-08 19:02:07 +0800
committerArchargelod <archargelod@gmail.com>2024-03-08 19:02:07 +0800
commitc45f2d8a7ae3836921747c832d2bfe9db7cc9aa9 (patch)
treecea6fb0f51440f00210ab68d018e334c92bc7ef5 /challenge-027/archargelod
parent510484bb98b0d2413f8c09c0a827e91b992d2533 (diff)
downloadperlweeklychallenge-club-c45f2d8a7ae3836921747c832d2bfe9db7cc9aa9.tar.gz
perlweeklychallenge-club-c45f2d8a7ae3836921747c832d2bfe9db7cc9aa9.tar.bz2
perlweeklychallenge-club-c45f2d8a7ae3836921747c832d2bfe9db7cc9aa9.zip
weeks 27-40, 259 in Nim
Diffstat (limited to 'challenge-027/archargelod')
-rw-r--r--challenge-027/archargelod/README1
-rwxr-xr-xchallenge-027/archargelod/nim/ch_1.nim40
-rwxr-xr-xchallenge-027/archargelod/nim/ch_2.nim59
3 files changed, 100 insertions, 0 deletions
diff --git a/challenge-027/archargelod/README b/challenge-027/archargelod/README
new file mode 100644
index 0000000000..6cd57e1074
--- /dev/null
+++ b/challenge-027/archargelod/README
@@ -0,0 +1 @@
+Solution by archargelod
diff --git a/challenge-027/archargelod/nim/ch_1.nim b/challenge-027/archargelod/nim/ch_1.nim
new file mode 100755
index 0000000000..15e65d5812
--- /dev/null
+++ b/challenge-027/archargelod/nim/ch_1.nim
@@ -0,0 +1,40 @@
+#!/usr/bin/env -S nim r -d:release --verbosity:0 --hints:off
+import std/options
+
+type
+ Point = tuple[x, y: float]
+ Line = (Point, Point)
+
+func getIntersection(l1, l2: Line): Option[Point] =
+ ## can't handle co-linear lines
+ let
+ ix: Line =
+ ((l1[1].x - l1[0].x, l1[1].y - l1[0].y), (l2[1].x - l2[0].x, l2[1].y - l2[0].y))
+ s: float =
+ (-ix[0].y * (l1[0].x - l2[0].x) + ix[0].x * (l1[0].y - l2[0].y)) /
+ (-ix[1].x * ix[0].y + ix[0].x * ix[1].y)
+ t: float =
+ (ix[1].x * (l1[0].y - l2[0].y) - ix[1].y * (l1[0].x - l2[0].x)) /
+ (-ix[1].x * ix[0].y + ix[0].x * ix[1].y)
+
+ if s >= 0 and s <= 1 and t >= 0 and t <= 1:
+ # Collision detected
+ return some((l1[0].x + (t * ix[0].x), l1[0].y + (t * ix[0].y)))
+
+ none(Point)
+
+when isMainModule:
+ import std/unittest
+
+ const
+ TestLines = [
+ ((0.0, 0.0), (10.0, 10.0)), ((10.0, 0.0), (0.0, 10.0)),
+ ((0.0, 0.0), (10.0, 10.0)), ((10.0, 0.0), (6.0, 4.0)),
+ ]
+ Expected = [some(Point (5.0, 5.0)), none(Point)]
+
+ suite "Intersection of two lines":
+ test "intersection detected":
+ check getIntersection(TestLines[0], TestLines[1]) == Expected[0]
+ test "no intersection":
+ check getIntersection(TestLines[2], TestLines[3]) == Expected[1]
diff --git a/challenge-027/archargelod/nim/ch_2.nim b/challenge-027/archargelod/nim/ch_2.nim
new file mode 100755
index 0000000000..2cd2eec204
--- /dev/null
+++ b/challenge-027/archargelod/nim/ch_2.nim
@@ -0,0 +1,59 @@
+#!/usr/bin/env -S nim r -d:release --verbosity:0 --hints:off
+type Hist*[T] = object
+ # object fields without `*` are private and can't be accesed
+ h_val: T
+ h_history: seq[T]
+
+func initHist*[T](value: T): Hist[T] =
+ Hist[T](h_val: value)
+
+func `history`*[T](obj: Hist[T]): seq[T] =
+ ## getter for previous values of a historical type
+ obj.h_history
+
+func `val`*[T](obj: Hist[T]): T =
+ ## getter for current value of a historical type
+ obj.h_val
+
+func `val=`*[T](obj: var Hist[T], value: T) =
+ ## setter for value of a historical type
+ if obj.h_val != value:
+ obj.h_history.add obj.h_val
+ obj.h_val = value
+
+func `clearHistory`*[T](obj: var Hist[T]) =
+ ## clear previous values of a historical type
+ obj.h_history.setLen(0)
+
+func `$`*[T](obj: Hist[T]): string =
+ $obj.h_val
+
+when isMainModule:
+ import std/unittest
+
+ suite "Historical values":
+ test "basic example":
+ var x = initHist[int](10)
+ x.val = 20
+ x.val = x.val - 5
+
+ check x.val == 15
+ check x.history == [10, 20]
+
+ test "history doesn't change if value didn't change":
+ var x = initHist[int](69)
+ x.val = 69
+ x.val = 420
+ x.val = 420
+
+ check x.val == 420
+ check x.history == [69]
+
+ test "clearHistory clears the history":
+ var x = initHist[int](42)
+ x.val = x.val + 1
+ x.clearHistory()
+ x.val = 133
+
+ check x.val == 133
+ check x.history == [43]