読者です 読者をやめる 読者になる 読者になる
無料で使えるシステムトレードフレームワーク「Jiji」 をリリースしました!

・OANDA Trade APIを利用した、オープンソースのシステムトレードフレームワークです。
・自分だけの取引アルゴリズムで、誰でも、いますぐ、かんたんに、自動取引を開始できます。

世界のナベアツに Scala で挑戦する

Scala

今更ですが、世界のナベアツScala で挑戦してみました。
Scalaだと、

<レシーバ> <メソッド> <引数>

メソッドを呼び出したりできるので、「.」とか「()」とかを排除できてやばいことになるんじゃね!と思って始めたのだけど、0にするのは無理でした。

import scala.collection.mutable.HashMap
import scala.util.matching._

object Nabeatu extends Conversions {
  def main(args: Array[String]) {

    1 から 40 まで数えて ( 
        3 の 倍数 と ( 3 の つく数字 ) のとき アホ に ( 
        5 の 倍数 のとき 犬 ) に ( 
        8 の 倍数 のとき 気持ちよく ) なります
    )
    
  }
    
  def 犬:(IntEx)=>Unit = {
    def x(i:IntEx) = {
      println(i.の読み + "バフッ")
    }
    x _
  }
  
  val ahoMap = HashMap.apply( 
    ( "な$", "ぁ〜〜ッ" ),
    ( "[ちに]$", "ぃ〜〜ッ" ), 
    ( "[くうッ]$", "ぅ〜〜ッ" ),
    ( "[ご]$", "ぉ〜〜ッ" )
  )
  def アホ:(IntEx)=>Unit = {
    def x(i:IntEx) = {
      var y = i.の読み
      val result = ahoMap.find( e =>
        new Regex(e._1).findFirstIn(y) != None
      )
      if ( result == None ) 
        println(i.の読み+"〜〜ッ")
      else {
        var e = result.get
        println(i.の読み + e._2)
      }
    }  
    x _
  }
  
  def 気持ちよく:(IntEx)=>Unit = {
    def x(i:IntEx) = {
      println(i.の読み)
    }  
    x _
  }
  
  def 倍数:(IntEx,Int)=>Boolean = {
    def x(i:IntEx, x:Int):Boolean = {
      i.org % x == 0
    }  
    x _
  }
  def つく数字:(IntEx,Int)=>Boolean = {
    def x(i:IntEx, x:Int):Boolean = 
      i.org.toString.indexOf(x.toString) >= 0
    x _
  }
}

trait Conversions {
  implicit def toEx(i:Int):IntEx = new IntEx(i)
}
trait Condition {
  def matches(i:IntEx):Boolean
  def と( c:Condition ):Condition = new Or( this, c )
  def のとき(action:IntEx=>Unit):If = new If( this, action )
}
class ConditionImpl( e:(IntEx)=>Boolean ) extends Condition {
  override def matches(i:IntEx):Boolean = e.apply( i )
}
class And( a:Condition, b:Condition ) extends Condition {
  override def matches(i:IntEx):Boolean = a.matches(i) && b.matches(i)
}
class Or( a:Condition, b:Condition ) extends Condition {
  override def matches(i:IntEx):Boolean = a.matches(i) || b.matches(i)
}

class If( condition:Condition, action:IntEx=>Unit ) {
  var next:If = null
  var prev:If = null
  def に(next:If):If = {
    this.next = next
    next.prev = this
    return next
  }
  def first:If = 
    if ( prev != null ) prev.first else this
  def run( i:IntEx ) {
    if (condition.matches(i)) action.apply( i ) 
    else if (next != null) next.run(i)
    else println(i.org)
  }
  def なります:(IntEx)=>Unit = {
    def x(i:IntEx) = {
      first.run( i )
    }  
    x _
  }
}

class IntEx(i:Int) {
  def org:Int = i
  def から(x:IntEx):RangeEx = new RangeEx(this,x)
  
  val KazuYomi = Array("", "いち", "に", "さん", "よん", "ご", "ろく", "なな", "はち", "きゅう")
  val KetaYomi = Array("", "じゅう", "ひゃく", "せん")
  
  def の読み:String = {
    def toS(i:Int, str:String, k:Int):String = {
      var s:String = if ( i%10 != 1 || k == 0) KazuYomi(i%10) else ""
      if ( k >= 1 ) s = s+KetaYomi(k)
      if (i >= 10) toS( i/10, s+str, k+1 ) else s+str
    }
    toS( i, "", 0 )
  }
  
  def の( e:(IntEx,Int)=>Boolean ):Condition = new ConditionImpl( x => e.apply( x, i ) )
}
class RangeEx(from:IntEx, to:IntEx) extends Conversions {
  def まで数えて( block: (IntEx)=>Unit) {
     from.org to to.org foreach( i=> block.apply( i ) )
  }
}

実行結果です。

1
2
さん〜〜ッ
4
ごバフッ
ろくぅ〜〜ッ
7
はち
きゅうぅ〜〜ッ
じゅうバフッ
11
じゅうにぃ〜〜ッ
じゅうさん〜〜ッ
14
じゅうごぉ〜〜ッ
じゅうろく
17
じゅうはちぃ〜〜ッ
19
にじゅうバフッ
にじゅういちぃ〜〜ッ
22
にじゅうさん〜〜ッ
にじゅうよん〜〜ッ
にじゅうごバフッ
26
にじゅうななぁ〜〜ッ
28
29
さんじゅうぅ〜〜ッ
さんじゅういちぃ〜〜ッ
さんじゅうにぃ〜〜ッ
さんじゅうさん〜〜ッ
さんじゅうよん〜〜ッ
さんじゅうごぉ〜〜ッ
さんじゅうろくぅ〜〜ッ
さんじゅうななぁ〜〜ッ
さんじゅうはちぃ〜〜ッ
さんじゅうきゅうぅ〜〜ッ
よんじゅうバフッ

元ネタはこちら。