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-025/archargelod | |
| 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-025/archargelod')
| -rw-r--r-- | challenge-025/archargelod/README | 1 | ||||
| -rwxr-xr-x | challenge-025/archargelod/nim/ch_1.nim | 68 | ||||
| -rwxr-xr-x | challenge-025/archargelod/nim/ch_2.nim | 57 |
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 |
