aboutsummaryrefslogtreecommitdiff
path: root/challenge-025/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-025/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-025/archargelod')
-rw-r--r--challenge-025/archargelod/README1
-rwxr-xr-xchallenge-025/archargelod/nim/ch_1.nim68
-rwxr-xr-xchallenge-025/archargelod/nim/ch_2.nim57
3 files changed, 126 insertions, 0 deletions
diff --git a/challenge-025/archargelod/README b/challenge-025/archargelod/README
new file mode 100644
index 0000000000..6cd57e1074
--- /dev/null
+++ b/challenge-025/archargelod/README
@@ -0,0 +1 @@
+Solution by archargelod
diff --git a/challenge-025/archargelod/nim/ch_1.nim b/challenge-025/archargelod/nim/ch_1.nim
new file mode 100755
index 0000000000..d3e5472fdc
--- /dev/null
+++ b/challenge-025/archargelod/nim/ch_1.nim
@@ -0,0 +1,68 @@
+#!/usr/bin/env -S nim r -d:release --verbosity:0 --hints:off
+import std/[sequtils]
+
+func makeMap(words: openArray[string]): seq[seq[int8]] =
+ result = newSeq[seq[int8]](words.len)
+ for i, current in words:
+ for j, next in words:
+ if i == j:
+ continue
+ if current[^1] == next[0]:
+ result[i].add j.int8
+
+func longestChains*(words: openArray[string]): seq[seq[string]] =
+ let map = makeMap(words)
+ var paths = newSeqOfCap[seq[int8]](128)
+ var longest = newSeqOfCap[seq[int8]](1300)
+
+ for id, exits in map:
+ if exits.len > 0:
+ paths.add @[id.int8]
+
+ while paths.len > 0:
+ let path = paths.pop()
+ let last = path[^1]
+ var endpoint = true
+
+ for exit in map[last]:
+ if exit notin path:
+ paths.add path & exit
+ endpoint = false
+
+ if endpoint:
+ if longest.len < 1 or path.len > longest[0].len:
+ longest = @[path]
+ elif path.len == longest[0].len:
+ longest.add path
+
+ longest.mapIt(it.mapIt(words[it]))
+
+when isMainModule:
+ import std/unittest
+
+ const
+ Names = [
+ "audino", "bagon", "baltoy", "banette", "bidoof", "braviary", "bronzor",
+ "carracosta", "charmeleon", "cresselia", "croagunk", "darmanitan", "deino",
+ "emboar", "emolga", "exeggcute", "gabite", "girafarig", "gulpin", "haxorus",
+ "heatmor", "heatran", "ivysaur", "jellicent", "jumpluff", "kangaskhan",
+ "kricketune", "landorus", "ledyba", "loudred", "lumineon", "lunatone", "machamp",
+ "magnezone", "mamoswine", "nosepass", "petilil", "pidgeotto", "pikachu", "pinsir",
+ "poliwrath", "poochyena", "porygon2", "porygonz", "registeel", "relicanth",
+ "remoraid", "rufflet", "sableye", "scolipede", "scrafty", "seaking", "sealeo",
+ "silcoon", "simisear", "snivy", "snorlax", "spoink", "starly", "tirtouga",
+ "trapinch", "treecko", "tyrogue", "vigoroth", "vulpix", "wailord", "wartortle",
+ "whismur", "wingull", "yamask"
+ ]
+ Expected = @[
+ "machamp", "pinsir", "rufflet", "trapinch", "heatmor", "remoraid", "darmanitan",
+ "nosepass", "starly", "yamask", "kricketune", "exeggcute", "emboar",
+ "relicanth", "haxorus", "simisear", "registeel", "landorus", "seaking",
+ "girafarig", "gabite", "emolga", "audino"
+ ]
+
+ suite "Head to tail Pokémon names":
+ test "longest chain is 23 pokemons: machamp -> audino":
+ let longest = longestChains(Names)
+ check longest.allIt(it.len == 23)
+ check Expected in longest
diff --git a/challenge-025/archargelod/nim/ch_2.nim b/challenge-025/archargelod/nim/ch_2.nim
new file mode 100755
index 0000000000..56ca084716
--- /dev/null
+++ b/challenge-025/archargelod/nim/ch_2.nim
@@ -0,0 +1,57 @@
+#!/usr/bin/env -S nim r -d:release --verbosity:0 --hints:off
+import std/[algorithm]
+
+type
+ Alphabet = array[26, char]
+ Chaocipher* = object
+ zenith: int
+ left, right: Alphabet
+
+proc permute(disk: var Chaocipher) =
+ # permute left disk
+ let tmp = disk.left[(disk.zenith + 1) mod 26]
+ for i in disk.zenith + 1 .. disk.zenith + 12:
+ disk.left[i mod 26] = disk.left[(i + 1) mod 26]
+ disk.left[(disk.zenith + 13) mod 26] = tmp
+
+ # permute right disk
+ disk.right.rotateLeft(1)
+ let tmp2 = disk.right[(disk.zenith + 2) mod 26]
+ for i in disk.zenith + 2 .. disk.zenith + 12:
+ disk.right[i mod 26] = disk.right[(i + 1) mod 26]
+ disk.right[(disk.zenith + 13) mod 26] = tmp2
+
+proc encipher*(plaintext: string, left, right: Alphabet): string =
+ var disk = Chaocipher(left: left, right: right)
+ for c in plaintext:
+ disk.zenith = disk.right.find(c)
+ result.add disk.left[disk.zenith]
+ disk.permute()
+
+proc decipher*(ciphertext: string, left, right: Alphabet): string =
+ var disk = Chaocipher(left: left, right: right)
+ for c in ciphertext:
+ disk.zenith = disk.left.find(c)
+ result.add disk.right[disk.zenith]
+ disk.permute()
+
+when isMainModule:
+ import std/unittest
+
+ const
+ LeftAlphabet = [
+ 'b', 'f', 'v', 'g', 'u', 'h', 'w', 'j', 'k', 'n', 'c', 'p', 'e', 'd', 'q', 'r',
+ 's', 't', 'i', 'x', 'y', 'l', 'm', 'o', 'z', 'a',
+ ]
+ RightAlphabet = [
+ 'c', 'm', 'o', 'p', 'r', 't', 'u', 'v', 'j', 'x', 'a', 'y', 'z', 'n', 'b', 'q',
+ 'd', 's', 'e', 'f', 'g', 'h', 'l', 'w', 'i', 'k',
+ ]
+ Plaintext = "allgoodqquickbrownfoxesjumpoverlazydogtosavetheirpartyw"
+ Ciphertext = "clytzpnzklddqgfbootysnepuagkiunkncrinrcvkjnhtoafqpdpncv"
+
+ suite "Chaocipher":
+ test "Encipher text":
+ check Plaintext.encipher(LeftAlphabet, RightAlphabet) == Ciphertext
+ test "Decipher text":
+ check Ciphertext.decipher(LeftAlphabet, RightAlphabet) == Plaintext