Source

ScalaEuler / src / com / mklinke / euler / Problem42.scala

/**
 * *
 *  Copyright 2012 Martin Klinke, http://www.martinklinke.com.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.mklinke.euler

import scala.io.Source

/**
 * @author Martin Klinke
 *
 */
object Problem42 {
  def main(args: Array[String]) {
    val start = System.currentTimeMillis;
    val wordFile = Source.fromInputStream(Problem42.getClass().getResourceAsStream("/words.txt"))
    val words = wordFile.getLines.next.split(',').map(w => w.replace("\"", "").toLowerCase())
    val stream = triangleNumbers
    println("Number of triangle words: " + words.filter(word => isInStream(wordToNumber(word), stream)).length)
    println("Duration: " + (System.currentTimeMillis - start) + " ms");
  }

  def wordToNumber(word: String): Int = {
    val num = word.toList.map(c => c - 96).sum
    num
  }

  def triangleNumbers(): Stream[Int] = {
    def loop(n: Int): Stream[Int] = {
      (n * (n + 1) / 2) #:: loop(n + 1)
    }
    loop(1)
  }

  def isInStream(n: Int, stream: Stream[Int]): Boolean = {
    val it = stream.iterator
    findInStream(n, it)
  }

  def findInStream(n: Int, it: Iterator[Int]): Boolean = {
    val current = it.next
    if (current == n)
      true
    else if (current < n)
      findInStream(n, it)
    else
      false
  }
}