aboutsummaryrefslogtreecommitdiff
path: root/challenge-017/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-017/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-017/archargelod')
-rw-r--r--challenge-017/archargelod/README1
-rwxr-xr-xchallenge-017/archargelod/nim/ch_1.nim16
-rwxr-xr-xchallenge-017/archargelod/nim/ch_2.nim96
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]