/* Rosalind problem Complementing a Strand of DNA Picat. https://rosalind.info/problems/revc/ """ In DNA strings, symbols 'A' and 'T' are complements of each other, as are 'C' and 'G'. The reverse complement of a DNA string s is the string sc formed by reversing the symbols of s, then taking the complement of each symbol (e.g., the reverse complement of "GTCA" is "TGAC"). Given: A DNA string s of length at most 1000 bp. Return: The reverse complement sc of s. Sample Dataset AAAACCCGGT Sample Output ACCGGGTTTT """ This model was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import util. import v3_utils. import rosalind_utils. main => go. go ?=> DNA = "AAAACCCGGT", Expected = "ACCGGGTTTT", println('dna '=DNA), println(expected=Expected), println(revc1), revc1(DNA,Revc1), println(revc1=Revc1), if Revc1 == Expected then println(ok1) else println(not_ok1) end, nl, println(revc2), revc2(DNA,Revc2), println(revc2=Revc2), if Revc2 == Expected then println(ok2) else println(not_ok2) end, println(revc3), Revc3 = revc3(DNA), println(revc3=Revc3), if Revc3 == Expected then println(ok3) else println(not_ok3) end, println(revc4), Revc4 = revc4(DNA), println(revc4=Revc4), if Revc4 == Expected then println(ok4) else println(not_ok4) end, println(revc5), Revc5 = revc5(DNA), println(revc5=Revc5), if Revc5 == Expected then println(ok5) else println(not_ok5) end, nl. go => true. /* - revc1: 0.037s - revc2: 0.024s <-- - revc3: 0.033s - revc4: 0.289s - revc5: 0.135s */ go2 ?=> garbage_collect(300_000), _ = random2(), println(gen_dna), Len = 1_000_000, DNA = new_list(Len), time(dna_gen1(DNA,"",[])), % println(DNA), println(revc1), time(revc1(DNA,_Revc1)), println(revc2), time(revc2(DNA,_Revc2)), println(revc3), time(_Revc3 = revc3(DNA)), println(revc4), time(_Revc4 = revc4(DNA)), println(revc5), time(_Revc5 = revc5(DNA)), % go2, nl. go2 => true. % The Challenge go3 ?=> DNA = "GATCGTAGTAATGTGCGTTCTTATTTGGACTTCCGTCTAACTAACACAGTGCCTCAACTAATGGAAACGTCCTGCTCATTATCACGACCTACGTCCGCCCGCCGCCAGCTTTAGACGCATAGACTCTTGGATGCCTACGGTCTGTCTCGGTACCAAGAATCACGCCATACGATCCACAGCGAGAGATCCAAAGGGTTGGGCCCGTATTGGGAATACGGTGGTAGAAGATTAAGCAGTGACTTCTTACATATTCCATGCTCCCATTGAGCTTTGACACTTGGACACAATCTCGGTTACTACCAGCGACTGTCCCTGTTACCCCCCGGCTTTATGTCCTGACACTGGACCGTATTATTCAGCTACTCGCGGTACTTTCGCATTTGCTTGGCAGAACCCTGTAACTCTACATACAGAAGGTCCCAGAGATTAATAAAACGCGAAATGAGTCAACAGAAGTACGTTGTCGGTTGGTCGTACGTCGTTTAGGGGCGATAATAGGACGTCGACACATTGTCGTGGGCGATAATGTAATGACTAAACACGGATTGCATAGACCCAGGGTTTGTCTACATTACCATCTAAATGTCTCTATTGTTGCAAAGTGGGAGCCGAATACCACAGTCGACCCCTCACGTGTCTTAGTGTGTTGTCTCCGATCTGGCGAACAAAAGTAGACAAGGCCAGGGGCCCCCTCCGGACAGAGTTACAGTAGAACGCTCTTAGCAGAATAAAGTCCACATGAGGAACGCCAGAAAGACGGTACACGATGCGGCCTGTAAATGGAAGATATACATCTTGCGTTACTAAGGATTTCTTCA", revc1(DNA,RNA), println(RNA), nl. go3 => true. conv('A','T'). conv('T','A'). conv('C','G'). conv('G','C'). % Fast. Reverses directly. revc1(Cs,L) :- revc1(Cs,[],L). revc1([],L,L). % Reverse directly revc1([C|Cs],L0,L) :- conv(C,R), revc1(Cs,[R|L0],L). % Reverses directly. % Very slow w/o the cut. Slow with cut revc2(Cs,L) :- revc2(Cs,[],L). revc2([],L,L). revc2(['A'|Cs],L0,L) :- !, revc2(Cs,['T'|L0],L). revc2(['T'|Cs],L0,L) :- !, revc2(Cs,['A'|L0],L). revc2(['C'|Cs],L0,L) :- !, revc2(Cs,['G'|L0],L). revc2(['G'|Cs],L0,L) :- !, revc2(Cs,['C'|L0],L). % Foreach loop, not fast revc3(Cs) = Revc => Revc1 = [], foreach(C in Cs) conv(C,R), Revc1 := [R|Revc1] end, Revc = Revc1. % Way too slow! revc4(Cs) = reverse(Rs) => revc4(Rs,Cs,[]). % This does not reverse the string. revc4([R|Rs]) --> [C], {conv(C,R)}, revc4(Rs). revc4([]) --> []. % % Using replace_many/4 % revc5(Cs) = reverse(Rs) => once(replace_many(Cs,"ACGT","TGCA",Rs)). % % replace_many(String,FromChars,ToChars,Result) % replace_many(String,FromChars,ToChars,Result) :- replace_many(String,FromChars,ToChars,[],Result). replace_many([],_FromChars,_ToChars,Result,Result). replace_many([C|Cs],FromChars,ToChars,Result0,[R|Result]) :- nth(Ix,FromChars,C), !, nth(Ix,ToChars,R), replace_many(Cs,FromChars,ToChars,Result0,Result). replace_many([C|Cs],FromChars,ToChars,Result0,[C|Result]) :- replace_many(Cs,FromChars,ToChars,Result0,Result).