src/problems/lcsq.lisp @ 7fcd748a4f00
LCSQ, PRSM
author |
Steve Losh <steve@stevelosh.com> |
date |
Mon, 08 Aug 2022 19:00:58 -0400 |
parents |
(none) |
children |
(none) |
(defpackage :rosalind/lcsq (:use :cl :rosalind :losh :iterate))
(in-package :rosalind/lcsq)
(defparameter *input* ">Rosalind_23
AACCTTGG
>Rosalind_64
ACACTGTGA")
(defparameter *output* "AACTTG")
(defun print-2d-array (array)
(check-type array (array * (* *)))
;; This will cons a lot.
(iterate
(with strings = (make-array (array-dimensions array)))
(for el :across-flat-array array :with-index i)
(for s = (princ-to-string el))
(setf (row-major-aref strings i) (princ-to-string el))
(maximizing (length s) :into len)
(finally (dotimes (row (array-dimension strings 0))
(dotimes (col (array-dimension strings 1))
(format t " ~V@A" len (aref strings row col)))
(terpri))))
array)
(defun build-table (a b)
;; From CLRS 15.4
(iterate
(with-result table = (make-array (list (1+ (length a))
(1+ (length b)))
:initial-element 0))
(for ca :in-string a)
(for i :from 1)
(iterate
(for cb :in-string b)
(for j :from 1)
(for up = (aref table (1- i) j))
(for left = (aref table i (1- j)))
(for upleft = (aref table (1- i) (1- j)))
(setf (aref table i j)
(cond ((char= ca cb) (1+ upleft))
((>= up left) up)
(t left))))))
(defun reconstruct-lcs-from-table (a b table)
(nreverse
(iterate
(with i = (length a))
(with j = (length b))
(until (or (zerop i) (zerop j)))
(for ca = (aref a (1- i)))
(for cb = (aref b (1- j)))
(for up = (aref table (1- i) j))
(for left = (aref table i (1- j)))
(cond ((char= ca cb) (progn (collect ca :result-type string)
(decf i)
(decf j)))
((>= up left) (decf i))
(t (decf j))))))
(defun least-common-subsequence (a b)
(check-type a string)
(check-type b string)
(reconstruct-lcs-from-table a b (build-table a b)))
(define-problem lcsq (data stream) *input* *output*
(destructuring-bind (a b) (mapcar #'cdr (u:read-fasta-into-alist data))
(least-common-subsequence a b)))
#; Scratch --------------------------------------------------------------------