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-017/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-017/archargelod')
| -rw-r--r-- | challenge-017/archargelod/README | 1 | ||||
| -rwxr-xr-x | challenge-017/archargelod/nim/ch_1.nim | 16 | ||||
| -rwxr-xr-x | challenge-017/archargelod/nim/ch_2.nim | 96 |
3 files changed, 113 insertions, 0 deletions
diff --git a/challenge-017/archargelod/README b/challenge-017/archargelod/README new file mode 100644 index 0000000000..6cd57e1074 --- /dev/null +++ b/challenge-017/archargelod/README @@ -0,0 +1 @@ +Solution by archargelod diff --git a/challenge-017/archargelod/nim/ch_1.nim b/challenge-017/archargelod/nim/ch_1.nim new file mode 100755 index 0000000000..da820ff5d7 --- /dev/null +++ b/challenge-017/archargelod/nim/ch_1.nim @@ -0,0 +1,16 @@ +#!/usr/bin/env -S nim r -d:release --verbosity:0 --hints:off + +proc ackermann(m, n: Natural): int = + if m == 0: + n + 1 + elif n == 0: + ackermann(m - 1, 1) + else: + ackermann(m - 1, ackermann(m, n - 1)) + +when isMainModule: + import std/unittest + + suite "Ackermann function": + test "A(1, 2) == 4": + check ackermann(1, 2) == 4 diff --git a/challenge-017/archargelod/nim/ch_2.nim b/challenge-017/archargelod/nim/ch_2.nim new file mode 100755 index 0000000000..d64c57515f --- /dev/null +++ b/challenge-017/archargelod/nim/ch_2.nim @@ -0,0 +1,96 @@ +#!/usr/bin/env -S nim r -d:release --verbosity:0 --hints:off +import std/[strutils, parseutils, options] + +type Url = object + scheme, userinfo, host: string + port = 80 + path, query, fragment: string + +template consume(input: string, chars: openarray[char]): bool = + var res = true + for i, c in chars: + if ind < input.len and input[ind] == c: + inc ind + else: + ind -= i + res = false + break + res + +proc parseUrl(input: string): Url = + result = Url() + + var ind = 0 + let schemeEnd = input.skipUntil({':'}, ind) + result.scheme = input[0 ..< schemeEnd] + ind += schemeEnd + + if not input.consume(":"): + raiseAssert("expected ':'") + + if input.consume("//"): + # user:password pair (optional) + let userinfoEnd = input.skipUntil({'@'}, ind) + if ind + userinfoEnd < input.len: + result.userinfo = input[ind ..< ind + userinfoEnd] + ind += userInfoEnd + 1 + + # hostname + let hostEnd = input.skipUntil({':', '/'}, ind) + if ind + hostEnd > input.high: + raiseAssert("expected ':' or '/'") + result.host = input[ind ..< ind + hostEnd] + ind += hostEnd + + # port (optional) + if input.consume(":"): + let portEnd = input.skipWhile(Digits, ind) + result.port = parseInt input[ind ..< ind + portEnd] + ind += portEnd + + # path + let pathEnd = input.skipUntil({'?', '#'}, ind) + result.path = input[ind ..< ind + pathEnd] + ind += pathEnd + + # query (optional) + if input.consume("?"): + let queryEnd = input.skipUntil({'#'}, ind) + result.query = input[ind ..< ind + queryEnd] + ind += queryEnd + + # match fragment (optional) + if input.consume("#"): + result.fragment = input[ind ..^ 1] + +when isMainModule: + import std/unittest + + const + Test = [ + "jdbc://user:password@localhost:3306/pwc?profile=true#h1", + "file:/home/test/hello.txt" + ] + Expected = [ + Url( + scheme: "jdbc", + userinfo: "user:password", + host: "localhost", + port: 3306, + path: "/pwc", + query: "profile=true", + fragment: "h1", + ), + Url( + scheme: "file", + port: 80, + path: "/home/test/hello.txt", + ) + ] + + suite "URL parsing": + test "Example 1": + check parseUrl(Test[0]) == Expected[0] + + test "Minimal Example": + check parseUrl(Test[1]) == Expected[1] |
