Skip to content

Instantly share code, notes, and snippets.

@pathikrit
Last active June 5, 2017 15:47
Show Gist options
  • Save pathikrit/46a9e2dbbbf0b59de222 to your computer and use it in GitHub Desktop.
Save pathikrit/46a9e2dbbbf0b59de222 to your computer and use it in GitHub Desktop.
Scala Scanner
import java.io._
import java.nio.file.{Files, Path}
import java.util.StringTokenizer
import scala.io.Codec
/**
* Scala implementation of a faster java.util.Scanner
* See: http://codeforces.com/blog/entry/21125
* All next methods throw NoSuchElementException when !hasNext
*/
class Scanner(reader: LineNumberReader) extends Iterator[String] with AutoCloseable {
def this(reader: BufferedReader) = this(new LineNumberReader(reader))
def this(reader: Reader) = this(new BufferedReader(reader))
def this(inputStream: InputStream)(implicit codec: Codec) = this(new InputStreamReader(inputStream, codec.charSet))
def this(path: Path)(implicit codec: Codec) = this(Files.newBufferedReader(path, codec.charSet))
def this(file: File)(implicit codec: Codec) = this(file.toPath)(codec)
def this(str: String) = this(new StringReader(str))
val lines = Iterator.continually(reader.readLine()).takeWhile(_ != null)
private[this] val tokenizers = lines.map(new StringTokenizer(_)).filter(_.hasMoreTokens)
private[this] var current: Option[StringTokenizer] = None
@inline private[this] def tokenizer(): Option[StringTokenizer] = current.find(_.hasMoreTokens) orElse {
current = if (tokenizers.hasNext) Some(tokenizers.next()) else None
current
}
/**
* Unlike Java's scanner which returns till end of current line, this actually returns the next line
* @see tillEndOfLine() if you want the Java behaviour
*/
def nextLine(): String = {
current = None // reset
lines.next()
}
def lineNumber(): Int = reader.getLineNumber
def till(delim: String): String = tokenizer().get.nextToken(delim)
def tillEndOfLine() = till("\n\r")
def nextString(): String = next()
def nextChar(): Char = next().ensuring(_.length == 1).head
def nextBoolean(): Boolean = next().toBoolean
def nextByte(radix: Int = 10): Byte = java.lang.Byte.parseByte(next(), radix)
def nextShort(radix: Int = 10): Short = java.lang.Short.parseShort(next(), radix)
def nextInt(radix: Int = 10): Int = java.lang.Integer.parseInt(next(), radix)
def nextLong(radix: Int = 10): Long = java.lang.Long.parseLong(next(), radix)
def nextBigInt(radix: Int = 10): BigInt = BigInt(next(), radix)
def nextFloat(): Float = next().toFloat
def nextDouble(): Double = next().toDouble
def nextBigDecimal(): BigDecimal = BigDecimal(next())
override def next() = tokenizer().get.nextToken()
override def hasNext = tokenizer().nonEmpty
override def close() = reader.close()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment