Solution of Aleks Aris
(define 3rd caddr) ;only to understand 'acid' better
;-----------acid FINDS THE CORRESPONDING ACID FOR A rna-CODON
(define (acid ls) ;----it takes a list with 3 items
(let ( (1st (car ls)) (2nd (cadr ls)) )
(cond ((equal? 1st 'u)
(cond ((equal? 2nd 'u)
(if (member? (3rd ls) 'uc) 'phe 'leu))
((equal? 2nd 'c) 'ser)
((equal? 2nd 'a)
(if (member? (3rd ls) 'uc) 'tyr 'stop))
( (member? (3rd ls) 'uc) 'cys )
( (equal? (3rd ls) 'a) 'stop )
(else 'trp) ))
((equal? 1st 'c)
(cond ((equal? 2nd 'u) 'leu)
((equal? 2nd 'c) 'pro)
((equal? 2nd 'g) 'arg)
( (member? (3rd ls) 'uc) 'his)
(else 'gln) ))
((equal? 1st 'a)
(cond ((equal? 2nd 'u)
(if (equal? (3rd ls) 'g) 'met 'ile))
((equal? 2nd 'c) 'thr)
((equal? 2nd 'a)
(if (member? (3rd ls) 'uc) 'asn 'lys))
( (member? (3rd ls) 'uc) 'ser)
(else 'arg) ))
( (equal? 2nd 'u) 'val)
( (equal? 2nd 'c) 'ala)
( (equal? 2nd 'g) 'gly)
( (member? (3rd ls) 'uc) 'asp)
(else 'glu) )))
;---STARTS THE PROCESS
(define (locate_intron gen acids)
(dna-to-rna gen acids))
;--------d-to-r FINDS THE CORRESPONDING RNA-NUCL. FOR A DNA-NUCL.
(define (d-to-r n) ;;;#### "n" stands for "nucleotid"
(cond ((equal? n 'a) 'u)
((equal? n 't) 'a)
((equal? n 'g) 'c)
(else 'g)))
;---CONVERTS THE WHOLE GEN LIST INTO THE rna-REPRESENTATION
(define (dna-to-rna gen acids)
(control@ (map d-to-r gen) acids))
;========= HELPER DEFINITIONS ==============================================
(define (first3 sent) ;---gives the first 3 items of a list
(if (<3? sent) '() ;---as a list
(list (car sent) (cadr sent) (caddr sent)) ))
(define (last3 sent) ;---gives the last 3 items of a list
(if (<3? sent) '() ;---as a list
(last3! sent) ))
(define (last1 lst) ;---gives the last item of a list
( if (null? (cdr lst)) lst (last1 (cdr lst)) ))
(define (last3! lst) ;---assumes that the list is longer than 3 items
( if (null? (cdddr lst)) lst (last3 (cdr lst)) ))
(define (l-bl lst) ;---the same as 'bl' only for lists
( if (null? (cdr lst)) '()
(cons (car lst) (l-bl (cdr lst))) ))
(define (l-3bl lst) ;---throws out the last 3 items of a list
( if (null? (cdddr lst)) '()
(cons (car lst) (l-3bl (cdr lst))) ))
(define (<3? lst) ;---finds if a list contains less than 3 items
( or (null? lst) (null? (cdr lst)) (null? (cddr lst)) ))
(define ( lst num) ;---finds if the list contains less
(? lst num 0)) ;---than 'num' items
(define (? lst num i)
(cond ( (= i num) #f)
( (null? lst) #t)
( else (? (cdr lst) num (+ i 1)) ) ))
;========= *END* OF HELPER DEFINITIONS ========================================
;---control CHECKS only IF THE GEN IS SUITABLE FOR
;--- Exon-Intron-Exon-Intron-Exon PATTERN
(define (control@ gen@ acids@)
( if ( and
(not(<3? acids@))
(not( gen@ 11))
(equal? (acid (first3 gen@)) (first acids@))
(equal? (acid (last3 gen@)) (last acids@)) )
(center! gen@ acids@ 1 (length gen@) 0)
'() ))
;---center! IS A CRUCIAL FUNCTION THAT ENABLES TO FIND
;---<3 EXON-2 INTRON> PATTERN WHATEVER THE LOCATION OF THEM IS
;--- {if there can exist of course}
(define (center! gen! acids! head! end! i!)
( if (= 2 i!) '()
(let ( (soln ((if (zero? i!) exon1 exon3) gen! acids! head! end! i!)) )
( cond
( (null? soln)
(center! gen! acids! head! end! (+ i! 1)) )
( else soln ) )) ))
;---FINDS WHERE INTRON1 STARTS
(define (exon1 gen acids head end i)
(cond
( (<3? gen) '())
( (zero? i) ;************* BEFORE EXON3 i=0
(cond( (null? (cddr acids))
(exon3 gen acids head end i) )
( (equal? (acid (first3 gen)) (car acids))
(exon1 (cdddr gen) (cdr acids) (+ head 3) end i) )
( else (exon3 gen acids head end i) )) )
( (null? (cdr acids)) ;************* AFTER EXON3 i=1
(exon2 gen acids head end) )
( (equal? (acid (first3 gen)) (car acids))
(exon1 (cdddr gen) (cdr acids) (+ head 3) end i) )
( else (exon2 gen acids head end) ) ))
;---FINDS WHERE INTRON2 ENDS
(define (exon3 gen acids head end i)
(cond
( (<3? gen) '())
( (zero? i) ;************* AFTER EXON1 i=0
(cond( (null? (cdr acids))
(exon2 gen acids head end) )
( (equal? (acid (last3 gen)) (last acids))
(exon3 (l-3bl gen) (l-bl acids) head (- end 3) i) )
( else (exon2 gen acids head end) )) )
( (null? (cddr acids)) ;************* BEFORE EXON1 i=1
(exon1 gen acids head end i) )
( (equal? (acid (last3 gen)) (last acids))
(exon3 (l-3bl gen) (l-bl acids) head (- end 3) i) )
( else (exon1 gen acids head end i) ) ))
;---INVOKES scrutinize WITH NECESSARY ARGUMENTS
(define (exon2 gen acids head end)
(scrutinize gen acids (* 3 (length acids)) head head end) )
;---SEARCHES EXON2 OVER THE REMAINING GEN
(define (scrutinize gen acids exon2l head1 end1+ end2)
(cond ;;### exon2l stands for "EXON2 Length"
( ( gen exon2l) '())
( (same-acids? gen acids)
( let ( (end1 (- end1+ 1)) ;--LET is used for clarity
(head2 (+ end1+ exon2l)) ;--and readabliness
(end2+ (+ end2 1)) )
(if (or (= head1 end1+) (= head2 end2+))
(scrutinize (cdr gen) acids exon2l
head1 (+ end1+ 1) end2)
(list (list head1 end1) (list head2 end2))) ) )
( else (scrutinize (cdr gen) acids exon2l
head1 (+ end1+ 1) end2)) ))
;---{HELPS scrutinize} FINDS IF AMINOS CAN BE SYNTHESED
; FROM NUCLIST'S !first! NUCLEOTIDS
(define (same-acids? nuclist aminos)
(cond ( (null? aminos) #t)
( (equal? (acid(first3 nuclist)) (car aminos))
(same-acids? (cdddr nuclist) (cdr aminos)))
( else #f) ))
(define l_i locate_intron) ; defined only for less typing