From e94ff2985cd6693cd0353008fdf52628b77ec468 Mon Sep 17 00:00:00 2001 From: Alberto Venturini Date: Fri, 6 Sep 2024 12:32:54 +0200 Subject: [PATCH] Add Hamming Distance, Probability and Protein problems --- 09_hamm/hamm.nim | 21 +++++++++++++ 10_iprb/iprb.nim | 38 +++++++++++++++++++++++ 11_prot/prot.nim | 80 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 139 insertions(+) create mode 100644 09_hamm/hamm.nim create mode 100644 10_iprb/iprb.nim create mode 100644 11_prot/prot.nim diff --git a/09_hamm/hamm.nim b/09_hamm/hamm.nim new file mode 100644 index 0000000..ea6e2f7 --- /dev/null +++ b/09_hamm/hamm.nim @@ -0,0 +1,21 @@ +import os +import std/sequtils +import std/streams + +template useStream(stream: Stream, body: untyped) = + if not isNil(stream): + try: + body + finally: + stream.close() + +proc hammingDist(s1, s2: string): int = + doAssert s1.len == s2.len + zip(s1, s2).countIt(it[0] != it[1]) + +let fileName = paramStr(1) +let fileStream = newFileStream(fileName) +useStream(fileStream): + let s1 = readLine(fileStream) + let s2 = readLine(fileStream) + echo $hammingDist(s1, s2) \ No newline at end of file diff --git a/10_iprb/iprb.nim b/10_iprb/iprb.nim new file mode 100644 index 0000000..28b6737 --- /dev/null +++ b/10_iprb/iprb.nim @@ -0,0 +1,38 @@ +import os +import std/strutils + +let k = parseInt(paramStr(1)) +let m = parseInt(paramStr(2)) +let n = parseInt(paramStr(3)) + +let T = k+m+n + +# Let "AA" be the case when we choose an individual with 2 dominant alleles, +# "Aa" be the case when we choose an individual with 1 dominant and 1 recessive allele, +# "aa" be the case when we choose an individual with 2 recessive alleles. +# +# Event probabilities: +# p(AA) = k/T +# p(Aa) = m/T +# p(aa) = n/T +# p(AA|AA) = (k-1)/(T-1) +# p(Aa|AA) = m/(T-1) +# and so on and so on. +# +# Choosing 2 individuals for mating is the combination of the probability events of choosing 2 individuals. +# E.g., the probability of choosing two AA individuals is p(AA)*p(AA|AA) = (k/T)*((k-1)/(T-1)) +# Furthermore, for certain combinations, the probability that an offspring will display +# the dominant phenotype is < 1. For example, when two Aa individuals mate, the probability of a dominant +# phenotype is 0.75. + +let solution = + (k/T) * ((k-1)/(T-1)) + + (k/T) * (m/(T-1)) + + (k/T) * (n/(T-1)) + + (m/T) * (k/(T-1)) + + (m/T) * ((m-1)/(T-1)) * 0.75 + + (m/T) * (n/(T-1)) * 0.5 + + (n/T) * (k/(T-1)) + + (n/T) * (m/(T-1)) * 0.5 + +echo $solution \ No newline at end of file diff --git a/11_prot/prot.nim b/11_prot/prot.nim new file mode 100644 index 0000000..7fdf187 --- /dev/null +++ b/11_prot/prot.nim @@ -0,0 +1,80 @@ +import os +import std/sequtils +import std/streams +import std/tables +import std/enumutils +import std/strutils + +template useStream(stream: Stream, body: untyped) = + if not isNil(stream): + try: + body + finally: + stream.close() + +type Codon = enum + UUU, CUU, AUU, GUU, + UUC, CUC, AUC, GUC, + UUA, CUA, AUA, GUA, + UUG, CUG, AUG, GUG, + UCU, CCU, ACU, GCU, + UCC, CCC, ACC, GCC, + UCA, CCA, ACA, GCA, + UCG, CCG, ACG, GCG, + UAU, CAU, AAU, GAU, + UAC, CAC, AAC, GAC, + UAA, CAA, AAA, GAA, + UAG, CAG, AAG, GAG, + UGU, CGU, AGU, GGU, + UGC, CGC, AGC, GGC, + UGA, CGA, AGA, GGA, + UGG, CGG, AGG, GGG + +type AminoAcid = enum + A, C, D, E, F, G, H, I, + K, L, M, N, P, Q, R, + S, T, V, W, Y, STOP + +let translationTable = { + UUU: F, CUU: L, AUU: I, GUU: V, + UUC: F, CUC: L, AUC: I, GUC: V, + UUA: L, CUA: L, AUA: I, GUA: V, + UUG: L, CUG: L, AUG: M, GUG: V, + UCU: S, CCU: P, ACU: T, GCU: A, + UCC: S, CCC: P, ACC: T, GCC: A, + UCA: S, CCA: P, ACA: T, GCA: A, + UCG: S, CCG: P, ACG: T, GCG: A, + UAU: Y, CAU: H, AAU: N, GAU: D, + UAC: Y, CAC: H, AAC: N, GAC: D, + UAA: STOP, CAA: Q, AAA: K, GAA: E, + UAG: STOP, CAG: Q, AAG: K, GAG: E, + UGU: C, CGU: R, AGU: S, GGU: G, + UGC: C, CGC: R, AGC: S, GGC: G, + UGA: STOP, CGA: R, AGA: R, GGA: G, + UGG: W, CGG: R, AGG: R, GGG: G +}.toTable + +iterator codons(dna: string): Codon = + var i = 0 + while i <= dna.len: + let codonStr = dna[i..i+2] + yield parseEnum[Codon](codonStr) + i += 3 + +proc translate(codon: Codon): AminoAcid = + translationTable[codon] + +let fileName = paramStr(1) +let fileStream = newFileStream(fileName) +useStream(fileStream): + let codonStr = readLine(fileStream) + + var aminoAcidStr = "" + + for c in codons(codonStr): + let a = translate(c) + if a == STOP: + break + aminoAcidStr.add($a) + + echo aminoAcidStr \ No newline at end of file