aboutsummaryrefslogtreecommitdiff
path: root/challenge-016
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-016
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-016')
-rw-r--r--challenge-016/archargelod/README1
-rwxr-xr-xchallenge-016/archargelod/nim/ch_1.nim21
-rwxr-xr-xchallenge-016/archargelod/nim/ch_2.nim49
3 files changed, 71 insertions, 0 deletions
diff --git a/challenge-016/archargelod/README b/challenge-016/archargelod/README
new file mode 100644
index 0000000000..6cd57e1074
--- /dev/null
+++ b/challenge-016/archargelod/README
@@ -0,0 +1 @@
+Solution by archargelod
diff --git a/challenge-016/archargelod/nim/ch_1.nim b/challenge-016/archargelod/nim/ch_1.nim
new file mode 100755
index 0000000000..a5cc61c3f6
--- /dev/null
+++ b/challenge-016/archargelod/nim/ch_1.nim
@@ -0,0 +1,21 @@
+#!/usr/bin/env -S nim r -d:release --verbosity:0 --hints:off
+
+proc percent(value: float, pct: 0..100): float =
+ value / 100'f * pct.float
+
+proc largestPieceOfPieIndex(): int =
+ var amount = 1'f
+ var largest = 0'f
+
+ for i in 1..100:
+ let piece = amount.percent(i)
+ if piece <= largest:
+ return i - 1
+ largest = piece
+ amount -= piece
+
+when isMainModule:
+ import std/strformat
+
+ let index = largestPieceOfPieIndex()
+ echo &"{index}th guest gets the largest piece of pie."
diff --git a/challenge-016/archargelod/nim/ch_2.nim b/challenge-016/archargelod/nim/ch_2.nim
new file mode 100755
index 0000000000..52f8e2202b
--- /dev/null
+++ b/challenge-016/archargelod/nim/ch_2.nim
@@ -0,0 +1,49 @@
+#!/usr/bin/env -S nim r -d:release --verbosity:0 --hints:off
+import std/strutils
+import pkg/nimcrypto/sha2 ## `$ nimble install nimcrypto`
+
+const
+ DecodedLength = 25
+ ChecksumLength = 4
+
+func base58Decode(input: string): array[DecodedLength, byte] =
+ ## Taken from https://rosettacode.org/wiki/Bitcoin/address_validation#Nim
+ ## Tried to implement this myself, but failed to find easy to understand algorithm.
+ const Base = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
+
+ for c in input:
+ var n = Base.find(c)
+ if n < 0:
+ raise newException(ValueError, "invalid character: " & c)
+
+ for i in countdown(result.high, 0):
+ n += Base.len * result[i].int
+ result[i] = byte(n and 255)
+ n = n div 256
+
+ if n != 0:
+ raise newException(ValueError, "decoded address is too long")
+
+func validBtcChecksum(address: openarray[byte]): bool =
+ let digest1 = sha256.digest(address.toOpenArray(0, address.high - ChecksumLength)).data
+ let digest2 = sha256.digest(digest1).data
+ digest2[0 ..< ChecksumLength] == address[^ChecksumLength ..^ 1]
+
+func isValidBTCAddress(address: string): bool =
+ address.len >= 26 and address[0] in {'1', '3'} and
+ validBtcChecksum(address.base58Decode())
+
+when isMainModule:
+ import std/unittest
+
+ const
+ Valid = ["1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2", "3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy"]
+ Invalid = ["3J98t1WpEZ73CNmQviecrnyiWrDEADBEEF"]
+
+ suite "Validate bitcoin address":
+ test "Example 1":
+ check isValidBTCAddress Valid[0]
+ test "Example 2":
+ check isValidBTCAddress Valid[1]
+ test "Invalid address":
+ check not isValidBtcAddress Invalid[0]