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-016 | |
| 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-016')
| -rw-r--r-- | challenge-016/archargelod/README | 1 | ||||
| -rwxr-xr-x | challenge-016/archargelod/nim/ch_1.nim | 21 | ||||
| -rwxr-xr-x | challenge-016/archargelod/nim/ch_2.nim | 49 |
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] |
