diff options
Diffstat (limited to 'test/pending/shootout/revcomp.scala-3.scala')
-rw-r--r-- | test/pending/shootout/revcomp.scala-3.scala | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/test/pending/shootout/revcomp.scala-3.scala b/test/pending/shootout/revcomp.scala-3.scala new file mode 100644 index 0000000000..ae12f0499b --- /dev/null +++ b/test/pending/shootout/revcomp.scala-3.scala @@ -0,0 +1,147 @@ +/* The Computer Language Shootout + http://shootout.alioth.debian.org/ + contributed by Isaac Gouy +*/ + +import java.io._ +import scala.collection.mutable.Stack + +object revcomp { + def main(args: Array[String]) = { + val out = new FastaOutputStream(System.out) + val in = new FastaInputStream(System.in) + + out.writeReverseComplement( in.readSequenceStack ) + out.writeReverseComplement( in.readSequenceStack ) + out.writeReverseComplement( in.readSequenceStack ) + + in.close + out.close + } +} + + +trait FastaByteStream { + val nl = '\n'.toByte + + type Line = Array[Byte] + type LineStack = Stack[Line] +} + + +// extend the Java BufferedInputStream class + +final class FastaInputStream(in: InputStream) + extends BufferedInputStream(in) with FastaByteStream { + + val gt = '>'.toByte + val sc = ';'.toByte + + def readSequenceStack(): Pair[Line,LineStack] = { + var header: Line = null + val lines: LineStack = new Stack + + var line = readLine() + while (line != null) { + val c = line(0) + if (c == gt){ // '>' + if (header == null){ + header = line + } else { + pos = pos - line.length - 1 // reposition to start of line + return Pair(header,lines) + } + } else { + if (c != sc) lines push line // ';' + } + line = readLine() + } + return Pair(header,lines) + } + + def readLine() = { + var bytes: Line = null + if (in == null) bytes + else { + mark(128) // mark the start of the line + if (count == 0) read() // fill buffer + + var i = markpos + while (i < count && buf(i) != nl) i = i + 1 + + if (i >= count){ // line extends past end of buffer + pos = i; read(); i = pos; // fill buffer again + while (i < count && buf(i) != nl) i = i + 1 + } + + if (i < count){ + bytes = new Array(i - markpos) + System.arraycopy(buf, markpos, bytes, 0, i - markpos); + pos = i+1 + } + } + bytes + } +} + + +// extend the Java BufferedOutputStream class + +final class FastaOutputStream(in: OutputStream) + extends BufferedOutputStream(in) with FastaByteStream { + + private val IUB = IUBCodeComplements + + private def IUBCodeComplements() = { + val code = "ABCDGHKMNRSTVWYabcdghkmnrstvwy".getBytes + val comp = "TVGHCDMKNYSABWRTVGHCDMKNYSABWR".getBytes + val iub: Array[Byte] = new Array( 'z'.toByte ) + + for (indexValue <- code zip comp) + indexValue match { case Pair(i,v) => iub(i) = v } + + iub + } + + def writeReverseComplement(sequence: Pair[Line,LineStack]) = { + + def inplaceComplementReverse(b: Array[Byte]) = { + var i = 0 + var j = b.length - 1 + while (i < j){ + val swap = b(i) + b(i) = IUB( b(j) ) + b(j) = IUB( swap ) + i = i + 1 + j = j - 1 + } + if (i == j) b(i) = IUB( b(i) ) + } + + sequence match { + case Pair(header,lines) => { + + write(header); write(nl) + + val k = if (lines.isEmpty) 0 else lines.top.length + val LineLength = 60 + val isSplitLine = k < LineLength + var isFirstLine = true + + while (!lines.isEmpty) { + val line = lines.pop + inplaceComplementReverse(line) + + if (isSplitLine){ + if (isFirstLine){ write(line); isFirstLine = false } + else { write(line,0,LineLength-k); write(nl); write(line,LineLength-k,k) } + } + else { write(line); write(nl) } + } + + if (isSplitLine && !isFirstLine) write(nl) + } + } + } + +} |