revcomp.scm 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. #|
  2. The Computer Language Benchmarks Game
  3. http://shootout.alioth.debian.org/
  4. Contributed by Per Bothner
  5. Loosely based on Java version contributed by Anthony Donnefort
  6. and slightly modified to read 82 bytes at a time by Razii.
  7. |#
  8. (define-constant output-buffer-size :: int 8192)
  9. (define-constant cmp :: byte[]
  10. (let* ((c (byte[] length: 128))
  11. (from "TAGCVHRMYKBDU")
  12. (to "ATCGBDYKRMVHA")
  13. (i :: int (string-length from)))
  14. (do ((i :: int 0 (+ i 1))) ((>= i 128))
  15. (set! (c i) i))
  16. (let loop ()
  17. (set! i (- i 1))
  18. (let ((f (char->integer (string-ref from i)))
  19. (t (char->integer (string-ref to i))))
  20. (set! (c f) t)
  21. (set! (c (+ f 32)) t))
  22. (if (> i 0)
  23. (loop)))
  24. c))
  25. (define (revcomp (in :: java.io.InputStream)) :: void
  26. (let* ((line (byte[] length: 82))
  27. (i :: int 0) ;; index in line
  28. (read :: int 0) ;; used size of line
  29. (last :: int 0) ;; line[j], j<last, has been copied to buf
  30. (bsize :: int output-buffer-size)
  31. (bcount :: int 0) ;; used amount in buf
  32. (buf :: byte[] (byte[] length: bsize))
  33. (GT :: int (char->integer #\>))
  34. (NL :: int (char->integer #\NewLine)))
  35. (let loop ()
  36. (let ((copy-needed :: boolean
  37. (or (= i read) (= (line i) GT))))
  38. (if copy-needed
  39. (let* ((added (- i last))
  40. (needed (+ bcount added)))
  41. (if (> needed bsize)
  42. (let* ((newsize (+ needed bsize))
  43. (newbuf (byte[] length: newsize)))
  44. (java.lang.System:arraycopy buf 0 newbuf 0 bcount)
  45. (set! bsize newsize)
  46. (set! buf newbuf)))
  47. (java.lang.System:arraycopy line last buf bcount added)
  48. (set! bcount (+ bcount added))
  49. (set! last i)))
  50. (cond ((= i read)
  51. (set! read (in:read line))
  52. (set! i -1)
  53. (set! copy-needed #f)
  54. (set! last 0)))
  55. (cond ((and (or (< read 0) copy-needed)
  56. (> bcount 0))
  57. ;; do the reverse ...
  58. (let ((j :: int 0) (k :: int (- bcount 1)))
  59. (do ()
  60. ((let ((b :: int (buf j)))
  61. (set! j (+ j 1))
  62. (= b NL))))
  63. (do () ((> j k))
  64. (if (= (buf j) NL)
  65. (set! j (+ j 1)))
  66. (if (= (buf k) NL)
  67. (set! k (- k 1)))
  68. (if (<= j k)
  69. (let ((tmp (buf j)))
  70. (set! (buf j) (cmp (buf k)))
  71. (set! (buf k) (cmp tmp))
  72. (set! j (+ j 1))
  73. (set! k (- k 1))))))
  74. (java.lang.System:out:write buf 0 bcount)
  75. (set! bcount 0)))
  76. (set! i (+ i 1))
  77. (if (>= read 0)
  78. (loop))))))
  79. (revcomp java.lang.System:in)