diff options
| author | Archargelod <archargelod@gmail.com> | 2024-03-01 14:43:05 +0800 |
|---|---|---|
| committer | Archargelod <archargelod@gmail.com> | 2024-03-01 14:43:05 +0800 |
| commit | 534715243e65728db4ee90b5ee5dee644ce71dac (patch) | |
| tree | fe17b389593130a0961afea924afc8e180fb365a /challenge-021/archargelod | |
| parent | d64cde6fdb1521b4a240e30615a90febcaf46799 (diff) | |
| download | perlweeklychallenge-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/README | 1 | ||||
| -rwxr-xr-x | challenge-021/archargelod/nim/ch_1.nim | 16 | ||||
| -rwxr-xr-x | challenge-021/archargelod/nim/ch_2.nim | 71 |
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 |
