Мое решение конкурса по ФП за август 2014 на Scala

8 августа 2014

Разгребал сегодня RSS-читалку и наткнулся на объявление о проведении очередного конкурса по ФП от Романа Душкина. Задачка на этот раз оказалась довольно простой. Вот я и подумал, а почему бы мне не воспользоваться случаем и не попрактиковаться лишний раз в программировании на Scala?

Задача формулируется так. Дан большой файл из ноликов и единичек и способ кодирования цифр при помощи матриц 3×5. Нужно взять входной файл и вывести координаты спрятанных в нем цифр, а также распознать эти самые цифры. Поколдовав от силы минут 20 в IntelliJ IDEA у меня получилось такое решение:

import scala.io.Source
import java.io.File

object FPPochtaRossii extends App {
  if(args.isEmpty) {
    println("Usage: fp-pochta-rossii matrix.txt")
    System.exit(1)
  }

  val inputFile = new File(args(0))
  val lines = Source.fromFile(inputFile).getLines().toArray
  val height = lines.length
  val width = lines(0).length

  for(x <- 0 until width - 3)
    for (y <- 0 until height - 5) {
      val image = for(ln <- 0 until 5)
                    yield lines(y + ln).substring(x, x+3)
      recognize(image) match {
        case Some(i) => println(s"x = ${x}, y = ${y}, number = ${i}")
        case None => ; // do nothing
      }
    }

  def recognize(lines : Seq[String]) : Option[Int] = {
    lines match {
      case Seq("111","101","101","101","111") => Some(0)
      case Seq("110","010","010","010","111") => Some(1)
      case Seq("111","001","111","100","111") => Some(2)
      case Seq("111","001","111","001","111") => Some(3)
      case Seq("101","101","111","001","001") => Some(4)
      case Seq("111","100","111","001","111") => Some(5)
      case Seq("111","100","111","101","111") => Some(6)
      case Seq("111","001","011","010","010") => Some(7)
      case Seq("111","101","111","101","111") => Some(8)
      case Seq("111","101","111","001","111") => Some(9)
      case _ => None
    }
  }
}

Компиляция и запуск:

scalac proc.scala
java -cp . FPPochtaRossii matrix.txt

Решение, как видите, «в лоб». Уж не знаю, насколько хорошо оно будет работать на больший файлах, но на моем ноутике для заданного в условиях файла программа отрабатывает за 0.4 секунды с учетом накладных расходов на запуск JVM. Очевидно также, что задача прекрасно распараллеливается.

Вот что здорово в Scala — говнекается быстро, код получается довольно сносным, и работает он при этом достаточно быстро. Синтаксис языка, даже если ты его толком не помнишь, довольно очевиден. И, надо отметить, наличие нормальной IDE вовсе не препятствует разработке, а только всячески помогает ей. Ведь по сути IDE — это такой мощный текстовый редактор с парой крутых фичей, которых нет в Vim. Например, подсказками по аргументам функций, подсветкой синтаксических ошибок еще перед компиляцией, или рефакторингами типа переименования переменной всюду, где она встречается. При программировании на Haskell, к примеру, мне действительно не хватает нормальной IDE.

Ну а что касается конкурсов по программированию, я считаю, что задачи именно такими и должны быть. Маленькими, простыми, не шаблонными, дескать берем поиск на графах и вперед. Так держать!

Метки: , .


Вы можете прислать свой комментарий мне на почту, или воспользоваться комментариями в Telegram-группе.