Solution of Gunes Erkan


;transcripts a DNA nucleotide into an mRNA nucleotide
(define (convert-to-mrna x) (cond ((equal? x 'T) 'A)
                                  ((equal? x 'A) 'U)
                                  ((equal? x 'G) 'C)
                                  ((equal? x 'C) 'G)
                                  (else           x)))

;transcripts a DNA chain (given as a list) into an mRNA list 
(define (m-list l) (every convert-to-mrna l))

;synthesizes an aminoacid from a list of three nucleotides of DNA;but note that 
;the DNA nucleotides are transcripted in the "let" step
(define (aa nuc) (let ((three (m-list nuc)))
                 (let ((bul  (bl three)))
     (cond
     ((or (equal? three '(U U U)) (equal? three '(U U C))) 'PHE)
     ((or (equal? bul     '(U U)) (equal? bul     '(C U))) 'LEU)
     ((or (equal? three '(U A U)) (equal? three '(U A C))) 'TYR)
     ((or (equal? three '(U A A)) (equal? three '(U A G)) (equal? three '(U G A)                                                                       )) 'stop)
     ((or (equal? three '(C A U)) (equal? three '(C A C))) 'HIS)
     ((or (equal? three '(A A U)) (equal? three '(A A C))) 'ASN)
     ((or (equal? three '(G A U)) (equal? three '(G A C))) 'ASP)
     ((or (equal? three '(U G U)) (equal? three '(U G C))) 'CYS)
     ((or (equal? bul '(C G)) (equal? three '(A G A)) (equal? three '(A G G)))                                                                             'ARG)
     ((and (equal? bul '(A U)) (not (equal? (last three) 'G))) 'ILE)
                    ((equal? bul '(A U)) 'MET)
                    ((equal? bul '(G U)) 'VAL)
                    ((equal? bul '(U C)) 'SER)
                    ((equal? bul '(C C)) 'PRO)
                    ((equal? bul '(A C)) 'THR)
                    ((equal? bul '(G C)) 'ALA)
                    ((equal? bul '(C A)) 'GLN)
                    ((equal? bul '(A A)) 'LYS)
                    ((equal? bul '(G A)) 'GLU)
                    ((equal? three '(U G G)) 'TRP)
                    ((equal? bul '(A G)) 'SER)
                    ((equal? bul '(G G)) 'GLY) 
                     (else '() )))))
    
;takes the first three elements of a list and gives them as a sentence
;beginning from the first element
(define (take-f3 list) (if (< (count list) 3) '(K K K)                                                  (se (car list) (cadr list) (caddr list))))

;takes the first three elements of a list and gives them as a sentence
;beginning from the third element
(define (take-l3 list) (if (< (count list) 3) '(K K K)                                                  (se (caddr list) (cadr list) (car list))))

;gives the "number of nucleotides of first exon" by comparing the dna nucleotide
;sequence with the amino acid list three by three beginning from the first 
;elements of the list 
(define (exon-1 l1 l2) (cond
        ((equal? l2 '()) 0)
        ((equal? (aa (take-f3 l1)) (car l2))                                                     (+ 3 (exon-1 ((repeated bf 3) l1) (bf l2))))
        (else 0 )))

;gives the "number of nucleotides of third exon" by comparing the dna nucleotide
;sequence with the amino acid list three by three ;but note that the function 
;should take "the reverse of dna list" as its first argument
(define (exon-3 l1 l2) (cond
        ((equal? l2 '()) 0)
        ((equal? (aa (take-l3 l1)) (last l2))
                 (+ 3 (exon-3 ((repeated bf 3) l1) (bl l2))))
        (else 0 )))

;gives a list of three-nucleotide-lists by grouping all the nucleotides of a 
;list three by three
(define (take-n list) (if (< (count list) 3) list (cons
                    (take-f3 list) (take-n (cdddr list)))))

;gives the "number of nucleotides of first intron" comparing the remaining dna 
;part (int1-exon2-1nt2) with the remaining amino acid part (exon-2) by taking
;slices of equal length from the dna chain (equal to the length of exon-2)
(define (check a b lgth-of-e2)
           (cond
           ((= (count a) lgth-of-e2) 0)
     ((not (equal? b (map aa (take-n ((repeated bl (- (count a) lgth-of-e2))  a)))))                                         (+ 1 (check (bf a) b lgth-of-e2)))
           (else 0 )))


;the cases this program is expected to give "empty sentence":
;not having enough number of nucleotides to synthesize the given protein,
;starting or ending with an intron,not having enough number of nucleotides to
;synthesize exon-2 or not having the exon-2 part at all.

(define (locate_intron dna amino)
        (let ((number1 (count dna))
             (number2 (count amino)))
         (if (< number1 (+ (* number2 3) 2)) '() 

        (let ((n-exon1 (exon-1     dna       amino))
              (n-exon3 (exon-3 (reverse dna) amino)))
         (if (or (= n-exon1 0) (= n-exon3 0)) '() 

        (let ((n-exon2 (- (* number2 3) (+ n-exon1 n-exon3))))
         (if (< n-exon2 3) '()

  (let ((remain_dna ((repeated bf n-exon1) ((repeated bl n-exon3) dna))))
  (let ((n-int1 (check remain_dna                                                  ((repeated bf (/ n-exon1 3))((repeated bl (/ n-exon3 3)) amino))   n-exon2)))
       (if (= n-int1 (- (count remain_dna) n-exon2)) '()

          (list (se (+ n-exon1 1) (+ n-exon1 n-int1)) 
                (se (+ n-exon1 n-int1 n-exon2 1) (- number1 n-exon3))) ))) )) )) )) )