aboutsummaryrefslogtreecommitdiff
path: root/challenge-021/archargelod
diff options
context:
space:
mode:
authorArchargelod <archargelod@gmail.com>2024-03-01 14:43:05 +0800
committerArchargelod <archargelod@gmail.com>2024-03-01 14:43:05 +0800
commit534715243e65728db4ee90b5ee5dee644ce71dac (patch)
treefe17b389593130a0961afea924afc8e180fb365a /challenge-021/archargelod
parentd64cde6fdb1521b4a240e30615a90febcaf46799 (diff)
downloadperlweeklychallenge-club-534715243e65728db4ee90b5ee5dee644ce71dac.tar.gz
perlweeklychallenge-club-534715243e65728db4ee90b5ee5dee644ce71dac.tar.bz2
perlweeklychallenge-club-534715243e65728db4ee90b5ee5dee644ce71dac.zip
weeks 14-26, 258 in Nim
Diffstat (limited to 'challenge-021/archargelod')
-rw-r--r--challenge-021/archargelod/README1
-rwxr-xr-xchallenge-021/archargelod/nim/ch_1.nim16
-rwxr-xr-xchallenge-021/archargelod/nim/ch_2.nim71
3 files changed, 88 insertions, 0 deletions
diff --git a/challenge-021/archargelod/README b/challenge-021/archargelod/README
new file mode 100644
index 0000000000..6cd57e1074
--- /dev/null
+++ b/challenge-021/archargelod/README
@@ -0,0 +1 @@
+Solution by archargelod
diff --git a/challenge-021/archargelod/nim/ch_1.nim b/challenge-021/archargelod/nim/ch_1.nim
new file mode 100755
index 0000000000..b93d56e1ef
--- /dev/null
+++ b/challenge-021/archargelod/nim/ch_1.nim
@@ -0,0 +1,16 @@
+#!/usr/bin/env -S nim r -d:release --verbosity:0 --hints:off
+import pkg/mapm
+
+proc approximateE(precision: int): Mapm =
+ let n = 1e41'm
+ pow(1'm + divide(1'm, n, precision), n, precision).round(precision)
+
+when isMainModule:
+ import std/unittest
+
+ const
+ Expected = "2.7182818284590452353602874713526624977572"
+
+ suite "Euler's number":
+ test "40-digit precision":
+ check $approximateE(40) == Expected
diff --git a/challenge-021/archargelod/nim/ch_2.nim b/challenge-021/archargelod/nim/ch_2.nim
new file mode 100755
index 0000000000..ec3b22ded2
--- /dev/null
+++ b/challenge-021/archargelod/nim/ch_2.nim
@@ -0,0 +1,71 @@
+#!/usr/bin/env -S nim r -d:release --verbosity:0 --hints:off
+import std/[uri, strutils, parseutils]
+
+template upd(mut, procedure: typed) =
+ mut = procedure(mut)
+
+proc normalizePercentEncoded(url: string): string =
+ result = url
+
+ template decodeUnreserved(s: string, i: int) =
+ let hex = s[i+1..i+2].parseHexInt
+ case hex
+ of 0x41..0x5A, 0x61..0x7A, 0x30..0x39, 0x2D, 0x2E, 0x5F, 0x7E:
+ s[i..i+2] = $hex.chr
+ else:
+ discard
+
+ var index = 0
+ while index < result.len:
+ if result[index] == '%':
+ result[index + 1].upd(toUpperAscii)
+ result[index + 2].upd(toUpperAscii)
+ result.decodeUnreserved(index)
+
+ index += 2
+
+ inc index
+
+proc removeDotSegments(path: string): string =
+ var stack: seq[string]
+ var ind = 1
+ while ind < path.len:
+ let segmentLength = path.skipUntil('/', ind)
+ let lastSegment = path[ind..<ind+segmentLength]
+
+ case lastSegment
+ of ".":
+ discard
+ of "..":
+ stack.setLen(stack.len - 1)
+ else:
+ stack.add lastSegment
+
+ ind += segmentLength + 1
+ '/' & stack.join("/")
+
+
+proc normalizeUrl(url: string): Uri =
+ result = url.normalizePercentEncoded.parseUri
+
+ result.scheme.upd(toLowerAscii)
+ result.hostname.upd(toLowerAscii)
+
+ result.path.upd(removeDotSegments)
+
+ # convert no path to empty path
+ if result.path.len < 1: result.path = "/"
+ # remove default port for http
+ if result.scheme == "http" and result.port == "80":
+ result.port = ""
+
+when isMainModule:
+ import std/unittest
+
+ const
+ Test = "hTtP://Example.com:80/Foo/./././././bar/../baz"
+ Expected = "http://example.com/Foo/baz"
+
+ suite "URL normalization (RFC 3986)":
+ test "Example 1":
+ check $Test.normalizeUrl() == Expected