Ilmen

Small DNA codon → aminoacid translator in Rust, HS & Mercury

May 6th, 2019
108
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ////////////////////
  2. // RUST
  3. ////////////////////
  4.  
  5. // use std::env;
  6.  
  7. fn main() {
  8. if false {
  9. let args: Vec<String> = std::env::args().collect();
  10. println!("{:?}", args);
  11. if args.len() < 2 {
  12. println!("Not enough parameters.");
  13. } else {
  14. let aas = proceed(&args[1]);
  15. println!("{:?}", &aas);
  16. }
  17. } else {
  18. if let Some(dna) = std::env::args().nth(1) {
  19. let aas = proceed(&dna);
  20. println!("{:?}", &aas);
  21. } else {
  22. println!("Not enough parameters.");
  23. }
  24. }
  25. }
  26.  
  27. fn proceed(dna: &str) -> String {
  28. // TODO: Check for potential unnecessary allocations.
  29. let bs: Vec<char> = dna.chars().collect();
  30. let codon_iter: std::slice::Chunks<char> = bs.chunks(3);
  31. let mut result = "".to_string();
  32. for codon in codon_iter.clone() {
  33. println!("{:?}", codon);
  34. result.push_str(aa_from_codon(codon));
  35. //result.push_str(aas_from_codon_0(codon.iter().cloned().collect::<String>().as_str())); // Maybe replacing push_str with something else would save this as_str() call…
  36. }
  37. result
  38. }
  39.  
  40. fn is_pyrimidine_base(b: char) -> bool {
  41. b == 'C' || b == 'T'
  42. }
  43.  
  44. fn is_purine_base(b: char) -> bool {
  45. b == 'G' || b == 'A'
  46. }
  47.  
  48. // #[allow(dead_code)]
  49. // fn aas_from_codon_0(codon: &str) -> &str {
  50. // if codon == "aaa" {"L"} else {"X"}
  51. // }
  52.  
  53. fn aa_from_codon(codon: &[char]) -> &str {
  54. if codon.len() < 3 { "" }
  55. else {
  56. // let (i, m) = (codon[0], codon[1]);
  57. let f = codon[2];
  58. match (codon[0], codon[1]) {
  59. ('T', 'T') => if is_purine_base(f) { "Leu" } else { "Phe" },
  60. ('C', 'T') => "Leu",
  61. ('A', 'T') => if f == 'G' { "Met" } else { "Ile" },
  62. ('G', 'T') => "Val",
  63. ('T', 'C') => "Ser",
  64. ('C', 'C') => "Pro",
  65. ('A', 'C') => "Thr",
  66. ('G', 'C') => "Ala",
  67. ('T', 'A') => if among(f, vec!('T', 'C')) { "Tyr" } else { "Stp" },
  68. ('C', 'A') => if is_purine_base(f) { "Gln" } else { "His" },
  69. ('A', 'A') => if is_purine_base(f) { "Lys" } else { "Asn" },
  70. ('G', 'A') => if is_purine_base(f) { "Glu" } else { "Asp" },
  71. ('T', 'G') => if is_pyrimidine_base(f) { "Cys" }
  72. else if f == 'G' { "Trp" } else { "Stp" },
  73. ('C', 'G') => "Arg",
  74. ('A', 'G') => if is_purine_base(f) { "Arg" } else { "Ser" },
  75. ('G', 'G') => "Gly",
  76. (_, _) => "Xxx",
  77. }
  78. }
  79. }
  80.  
  81. fn among<T: Eq>(x: T, v: Vec<T>) -> bool {
  82. for e in v {
  83. if x == e {
  84. return true
  85. }
  86. }
  87. false
  88. }
  89.  
  90.  
  91. ////////////////////
  92. // HASKELL
  93. ////////////////////
  94.  
  95. import System.Environment
  96. import Data.List.Split
  97.  
  98. main :: IO ()
  99. main = do
  100. args <- getArgs
  101. case nth 1 args of
  102. Nothing -> do putStrLn "No argument provided." -- TODO: delete this 'do'?
  103. Just x -> putStrLn ("Result: " ++ proceed x)
  104. putStrLn "End."
  105.  
  106. nth :: Int -> [a] -> Maybe a
  107. nth _ [] = Nothing
  108. nth i (x:xs) = if i == 0
  109. then Just x
  110. else nth (i - 1) xs
  111.  
  112. nth' :: Int -> [a] -> a
  113. nth' _ [] = error "Index out of range!"
  114. nth' i (x:xs) = if i == 0
  115. then x
  116. else nth' (i - 1) xs
  117.  
  118. proceed :: String -> String
  119. proceed cs = joinStrList (aas_from_codons (chunksOf 3 cs))
  120.  
  121. joinStrList :: [String] -> String
  122. joinStrList ss = foldr (++) "" ss
  123.  
  124. aas_from_codons :: [String] -> [String]
  125. aas_from_codons = map aa_from_codon
  126.  
  127. aa_from_codon :: String -> String
  128. aa_from_codon c =
  129. if length c < 3
  130. then ""
  131. else
  132. let head = (nth' 0 c, nth' 1 c)
  133. in case head of
  134. ('T', 'T') -> if is_purine_base f then "Leu" else "Phe"
  135. ('C', 'T') -> "Leu"
  136. ('A', 'T') -> if f == 'G' then "Met" else "Ile"
  137. ('G', 'T') -> "Val"
  138. ('T', 'C') -> "Ser"
  139. ('C', 'C') -> "Pro"
  140. ('A', 'C') -> "Thr"
  141. ('G', 'C') -> "Ala"
  142. ('T', 'A') -> if among f ['T', 'C'] then "Tyr" else "Stp"
  143. ('C', 'A') -> if is_purine_base f then "Gln" else "His"
  144. ('A', 'A') -> if is_purine_base f then "Lys" else "Asn"
  145. ('G', 'A') -> if is_purine_base f then "Glu" else "Asp"
  146. ('T', 'G') -> if is_pyrimidine_base f
  147. then "Cys"
  148. else if f == 'G' then "Trp" else "Stp"
  149. ('C', 'G') -> "Arg"
  150. ('A', 'G') -> if is_purine_base f then "Arg" else "Ser"
  151. ('G', 'G') -> "Gly"
  152. _ -> "Xxx"
  153. where
  154. f = nth' 2 c
  155.  
  156. is_purine_base :: Char -> Bool
  157. is_purine_base b = (b == 'A' || b == 'G')
  158.  
  159. is_pyrimidine_base :: Char -> Bool
  160. is_pyrimidine_base b = (b == 'T' || b == 'C')
  161.  
  162. among :: (Eq a) => a -> [a] -> Bool
  163. among v [] = False
  164. among v (x:xs) = ((v == x) || (among v xs))
  165.  
  166.  
  167. ////////////////////
  168. // MERCURY
  169. ////////////////////
  170.  
  171. :- module dna.
  172. :- interface.
  173.  
  174. :- import_module io.
  175. :- pred main(io::di, io::uo) is det.
  176.  
  177. :- implementation.
  178. :- import_module int, list, string, char, maybe.
  179.  
  180. main(!IO) :-
  181. io.command_line_arguments(Args, !IO),
  182. % io.format("ArgNum: %d\n", [i(length(Args))], !IO),
  183. % foldl2(print_arg, Args, 1, _, !IO),
  184. NthArg = nth(0, Args),
  185. (
  186. NthArg = no,
  187. io.write_string("No argument provided.\n", !IO)
  188. ;
  189. NthArg = yes(A),
  190. io.format("Result: %s\n", [s(proceed(A))], !IO)
  191. ),
  192. io.write_string("End.\n\n", !IO).
  193.  
  194. % :- pred print_arg(string::in, int::in, int::out, io::di, io::uo) is det.
  195. % print_arg(Arg, ArgNum, ArgNum + 1, !IO) :-
  196. % io.format("the argument #%d is %s\n", [i(ArgNum), s(Arg)], !IO).
  197.  
  198. :- func nth(int, list(T)) = maybe(T).
  199. nth(_, []) = no.
  200. nth(I, [X | Xs]) = (
  201. if I = 0
  202. then yes(X)
  203. else nth(I - 1, Xs)
  204. ).
  205.  
  206. :- pred is_nth(T::out, int::in, list(T)::in) is semidet.
  207. is_nth(E, I, [X | Xs]) :-
  208. if I = 0 then E = X
  209. else is_nth(E, I - 1, Xs).
  210.  
  211. :- func proceed(string) = string.
  212. proceed(S) = joinStrList(aas_from_codons(stringChunksOf(3, S))).
  213.  
  214. :- func joinStrList(list(string)) = string.
  215. joinStrList(Ss) = S :- foldr((pred(E::in, A::in, O::out) is det :- O = append(E, A)), Ss, "", S).
  216.  
  217. :- func stringChunksOf(int, string) = list(string).
  218. stringChunksOf(L, S) = Cs :-
  219. if S \= ""
  220. then (split(S, L, SL, SR),
  221. stringChunksOf(L, SR) = Xs,
  222. Cs = [SL | Xs])
  223. else Cs = [].
  224.  
  225. :- func aas_from_codons(list(string)) = list(string).
  226. aas_from_codons(Cs) = map(aa_from_codon, Cs).
  227.  
  228. :- func aa_from_codon(string) = string.
  229. aa_from_codon(C) = AA :-
  230. if (
  231. length(C) >= 3,
  232. index(C, 0, I),
  233. index(C, 1, M),
  234. index(C, 2, F)
  235. ) then (
  236. if I = 'T', M = 'T'
  237. then (if is_purine_base(F) then AA = "Leu" else AA = "Phe")
  238. else if I = 'C', M = 'T'
  239. then AA = "Leu"
  240. else if I = 'A', M = 'T'
  241. then (if F = 'G' then AA = "Met" else AA = "Ile")
  242. else if I = 'G', M = 'T'
  243. then AA = "Val"
  244. else if I = 'T', M = 'C'
  245. then AA = "Ser"
  246. else if I = 'C', M = 'C'
  247. then AA = "Pro"
  248. else if I = 'A', M = 'C'
  249. then AA = "Ala"
  250. else if I = 'T', M = 'A'
  251. then (if is_pyrimidine_base(F) then AA = "Tyr" else AA = "Stp")
  252. else if I = 'C', M = 'A'
  253. then (if is_purine_base(F) then AA = "Gln" else AA = "His")
  254. else if I = 'A', M = 'A'
  255. then (if is_purine_base(F) then AA = "Lys" else AA = "Asn")
  256. else if I = 'G', M = 'A'
  257. then (if is_purine_base(F) then AA = "Glu" else AA = "Asp")
  258. else if I = 'T', M = 'G'
  259. then (if is_pyrimidine_base(F) then AA = "Cys" else if F = 'G' then AA = "Trp" else AA = "Stp")
  260. else if I = 'C', M = 'G'
  261. then AA = "Arg"
  262. else if I = 'A', M = 'G'
  263. then (if is_purine_base(F) then AA = "Arg" else AA = "Ser")
  264. else if I = 'G', M = 'G'
  265. then AA = "Gly"
  266. else AA = "Xxx"
  267. ) else (
  268. AA = ""
  269. ).
  270.  
  271. :- pred is_purine_base(char::in) is semidet.
  272. is_purine_base(B) :- (B = 'A' ; B = 'G').
  273.  
  274. :- pred is_pyrimidine_base(char::in) is semidet.
  275. is_pyrimidine_base(B) :- (B = 'T' ; B = 'C').
RAW Paste Data