aboutsummaryrefslogtreecommitdiff
path: root/challenge-259
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-259
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-259')
-rwxr-xr-xchallenge-259/archargelod/nim/ch_1.nim32
-rwxr-xr-xchallenge-259/archargelod/nim/ch_2.nim96
2 files changed, 128 insertions, 0 deletions
diff --git a/challenge-259/archargelod/nim/ch_1.nim b/challenge-259/archargelod/nim/ch_1.nim
new file mode 100755
index 0000000000..9f058082b6
--- /dev/null
+++ b/challenge-259/archargelod/nim/ch_1.nim
@@ -0,0 +1,32 @@
+#!/usr/bin/env -S nim r -d:release --verbosity:0 --hints:off
+import std/times
+
+proc bankingDay(
+ date: DateTime, offset: int, holidays: openarray[DateTime] = @[]
+): DateTime =
+ result = date
+
+ var offset = offset
+ while offset > 0:
+ result += 1.days
+ if result.weekday notin {dSat, dSun} and result notin holidays:
+ dec offset
+
+when isMainModule:
+ import std/unittest
+
+ let
+ Test: seq[tuple[start: DateTime, offset: int, holidays: seq[DateTime]]] = @[
+ (dateTime(2018, mJun, 28), 3, @[dateTime(2018, mJul, 3)]),
+ (dateTime(2018, mJun, 28), 3, @[]),
+ ]
+ Expected = [
+ dateTime(2018, mJul, 4),
+ dateTime(2018, mJul, 3),
+ ]
+
+ suite "Banking Day Offset":
+ test "Example 1":
+ check bankingDay(Test[0].start, Test[0].offset, Test[0].holidays) == Expected[0]
+ test "Example 2":
+ check bankingDay(Test[1].start, Test[1].offset, Test[1].holidays) == Expected[1]
diff --git a/challenge-259/archargelod/nim/ch_2.nim b/challenge-259/archargelod/nim/ch_2.nim
new file mode 100755
index 0000000000..0928ec77c3
--- /dev/null
+++ b/challenge-259/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, tables]
+
+type
+ ValueKind = enum
+ StringValue
+ IntValue
+
+ Value = object
+ case kind: ValueKind
+ of StringValue:
+ strval: string
+ of IntValue:
+ intval: int
+
+ Struct = object
+ id: string
+ fields: OrderedTable[string, Value] # assuming order is important
+
+proc `==`(v: Value, s: string): bool =
+ v.kind == StringValue and v.strval == s
+
+proc `==`(v: Value, i: SomeInteger): bool =
+ v.kind == IntValue and v.intval == i
+
+template consume(input: string, amount: int = 1) =
+ index += amount
+ if index > input.high:
+ raise newException(ValueError, "Unexpected end.")
+
+template consume(input, token: string) =
+ for i, c in token:
+ if index + i > input.high or c != input[index + i]:
+ raise newException(ValueError, "Expected: " & token)
+ index += token.len
+
+proc parseStruct(input: string): Struct =
+ var index = 0
+ input.consume("{%")
+
+ # parse ID
+ index += input.skipWhitespace(index)
+ let tokenLength = input.skipWhile(Letters + Digits + {'_'}, index)
+ result.id = input[index ..< index + tokenLength]
+ index += tokenLength
+
+ index += input.skipWhitespace(index)
+
+ # parse fields
+ while index < input.len:
+ if input[index] notin Letters + Digits + {'_'}:
+ break
+
+ let fieldNameLength = input.skipWhile(Letters + Digits + {'_'}, index)
+ if index + fieldNameLength > input.high:
+ raise newException(ValueError, "Unexpected end.")
+
+ let fieldName = input[index ..< index + fieldNameLength]
+ input.consume fieldNameLength
+
+ input.consume "="
+
+ if input[index] == '"':
+ input.consume()
+ var strVal = ""
+ while true:
+ if input[index] == '\\':
+ input.consume()
+ elif input[index] == '"':
+ break
+ strVal &= input[index]
+ input.consume()
+
+ result.fields[fieldName] = Value(kind: StringValue, strval: strVal)
+ input.consume "\""
+ else:
+ let intLength = input.skipWhile(Digits, index)
+ let intVal = parseInt(input[index ..< index + intLength])
+ result.fields[fieldName] = Value(kind: IntValue, intval: intVal)
+ input.consume intLength
+
+ input.consume input.skipWhitespace(index)
+ input.consume "%}"
+
+when isMainModule:
+ import std/unittest
+
+ const
+ Test = """{% youtube title="Title \\ \"quoted\" done" some_field=12 %}"""
+
+ suite "Line Parser":
+ test "Example 1":
+ let struct = parseStruct(Test)
+ check struct.id == "youtube"
+ check struct.fields["title"] == "Title \\ \"quoted\" done"
+ check struct.fields["some_field"] == 12