Language detail: Scala

Coverage: 86.80%
number of '+' ratings
contribution for coverage

Unsolved challenges

codes

Feed

Used modules

next >>

文字列で+を表示する (Nested Flatten)
タートルグラフィックで描いてみました。
ちなみに、斜めに描くこともできます。(^^;
              d             d
             u o           u o
            k   u         k   u
           a     k       a     k
          k       a     k       a
         u         k   u         k
        o           u o           u
       d             d             d
        u                         o
         k                       u
          a                     k
           k                   a
            u                 k
             o               u
              d             d
             u               o
            k                 u
           a                   k
          k                     a
         u                       k
        o                         u
       d             d             d
        u           o u           o
         k         u   k         u
          a       k     a       k
           k     a       k     a
            u   k         u   k
             o u           o u
              d             d
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/** キャンバス */
class Canvas(val sizeX:Int, val sizeY:Int) {
    var canvas:Array[StringBuffer] = 
        (for(i <- 0 until sizeY) yield new StringBuffer(" "*sizeX)).toArray
    def set(x:Int, y:Int, ch:Char):Unit = {
        if (0 <= y && y < sizeY && 0 <= x && x < sizeX)
            canvas(y).setCharAt(x, ch)
    }
    override def toString():String = canvas.mkString("\n")
}

/** タートル・グラフィック(^^; */
class Turtle(c:Canvas) {
    var canvas:Canvas = c
    var x:Double = 0.0        // 左上が原点
    var y:Double = 0.0        // 左上が原点
    var th:Double = 0.0        // radian 北が0で右回りが正
    /** 右に t[radian]向く */
    def turn(t:Double):Unit = {
        th += t
    }
    /** 前に進む */
    def go(text:String):Unit = {
        for (i <- 0 until text.length) {
            canvas.set(x.asInstanceOf[Int], y.asInstanceOf[Int], text.charAt(i))
            x += Math.round(Math.sin(th)).asInstanceOf[Int]
            y += Math.round(-Math.cos(th)).asInstanceOf[Int]
        }
    }
    /** 指定位置に進む */
    def setPos(newX:Double, newY:Double):Unit = {
        x = newX
        y = newY
    }
}

/** 文字列で+を表示する */
object Doukaku {
    def main(args:Array[String]):Unit = {
        var canvas = new Canvas(50, 50)        // 固定。多めに取っている
        var turtle = new Turtle(canvas)

        val text = if (args.length > 0) args(0) else "doukaku"

        turtle.setPos(text.length, 0)
        turtle.turn(Math.Pi / 2)

//        turtle.setPos(text.length, 10)    // 斜めに表示する場合は前の2行をコメントにし、
//        turtle.turn(Math.Pi / 3)        // この2行をコメントアウトしてください。

        turtle.go(text)
        turtle.turn(Math.Pi / 2)
        turtle.go(text)
        turtle.turn(-Math.Pi / 2)
        turtle.go(text)
        turtle.turn(Math.Pi / 2)
        turtle.go(text)
        turtle.turn(Math.Pi / 2)
        turtle.go(text)
        turtle.turn(-Math.Pi / 2)
        turtle.go(text)
        turtle.turn(Math.Pi / 2)
        turtle.go(text)
        turtle.turn(Math.Pi / 2)
        turtle.go(text)
        turtle.turn(-Math.Pi / 2)
        turtle.go(text)
        turtle.turn(Math.Pi / 2)
        turtle.go(text)
        turtle.turn(Math.Pi / 2)
        turtle.go(text)
        turtle.turn(-Math.Pi / 2)
        turtle.go(text)

        println(canvas)
    }
}
図形の作り方に多少汎用性を持たせてみました。

結果:
        dounano?d        
        ?       o        
        o       u        
        n       n        
        a       a        
        n       n        
        u       o        
        o       ?        
dounano?d       dounano?d
?                       o
o                       u
n                       n
a                       a
n                       n
u                       o
o                       ?
d?onanuod       d?onanuod
        ?       o        
        o       u        
        n       n        
        a       a        
        n       n        
        u       o        
        o       ?        
        d?onanuod        
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
object StringShape {
    def main(args : Array[String]) : Unit = {
         val target = "dounano?"
        val mover =
            P(1,0) ::
            P(0,1) ::
            P(1,0) ::
            P(0,1) ::
            P(-1,0) ::
            P(0,1) ::
            P(-1,0) ::
            P(0,-1) ::
            P(-1,0) ::
            P(0,-1) ::
            P(1,0) ::
            P(0,-1) ::
            Nil
        val da = new DrawingArea
        var x, y = 0
        mover.foreach { m =>
            target.foreach { c =>
                  da += (P(x,y),c)
                x += m.x
                y += m.y
            }
        }
         for (y <- da.y_min to da.y_max) {
             for (x <- da.x_min to da.x_max) print(da(P(x,y)))
             println()
         }
    }

     case class P(val x:Int, val y:Int)
    class DrawingArea {
        var x_min, y_min, x_max, y_max = 0
        private val area:scala.collection.mutable.Map[P,Char] = new scala.collection.mutable.HashMap()
        def +=(point:P, c:Char) = {
            area += ((point, c))
            x_min = x_min.min(point.x)
            y_min = y_min.min(point.y)
            x_max = x_max.max(point.x)
            y_max = y_max.max(point.y)
        }
        def apply(point:P):Char = {
            area.getOrElse(point,' ')
        }
    }
}
もっとFunctionalに書きたいのですが…。
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
class Cross(val src: String) {

  // 角の凹みの数
  val dent = 1

  // 格子の数
  val grid = dent * 2 + 1

  // 一辺の長さ
  val side = src.length * grid + 1

  // 描画エリア
  val area:Array[Array[char]] = 
    for (row <- ((" " * side +"\n") * side).split("\n"))
      yield row.toCharArray

  // 水平描画が右向き:true/左向き:false
  var hAhead = true

  // 垂直描画が下向き:true/上向き:false
  var vAhead = true

  // 描画開始位置と描画方向を表現するクラス。
  case class Direction(val posX: Int, val posY: Int, val heading: Int)

  // 最初の描画位置、上段、中央の格子から、水平:右向きに描画する。
  val start = Direction(grid / 2, 0, Cross.HeadingRight)

  // 描画開始
  write(start)

  // 描画メソッド
  def write(d: Direction) :Unit = {
    val x = d.posX * src.length
    val y = d.posY * src.length
    
    d.heading match {
      case Cross.HeadingRight =>
       for (i <- x to x + src.length -1) {
         area(y)(i) = src.charAt(i - x)
       }
      case Cross.HeadingBottom =>
       for (i <- y to y + src.length -1) {
         area(i)(x) = src.charAt(i - y)
       }
      case Cross.HeadingLeft =>
       for (i <- (x- src.length + 1 to x).reverse) {
         area(y)(i) = src.charAt(x - i)
       }
      case Cross.HeadingTop =>
       for (i <- (y - src.length +1 to y).reverse) {
         area(i)(x) = src.charAt(y - i)
       }
    }
    var next = this.next(d) 
    if (next != start) {
      write(next)
    }
  }

  // 次の描画開始位置と描画方向を返す。
  def next(d:Direction) = {
    d.heading match {
      case Cross.HeadingRight =>
       if (d.posX + 2 > grid)
         hAhead = false
       Direction(d.posX + 1, d.posY, if (vAhead) Cross.HeadingBottom else Cross.HeadingTop )
      case Cross.HeadingBottom =>
       if (d.posY + 2 > grid)
         vAhead = false
       Direction(d.posX, d.posY + 1, if (hAhead) Cross.HeadingRight else Cross.HeadingLeft)
      case Cross.HeadingLeft =>
       if (d.posX - 2 < 0 )
         hAhead = true
       Direction(d.posX - 1, d.posY, if (vAhead) Cross.HeadingBottom else Cross.HeadingTop)
      case Cross.HeadingTop =>
       if (d.posY - 2 < 0 )
         vAhead = true
       Direction(d.posX, d.posY - 1, if (hAhead) Cross.HeadingRight else Cross.HeadingLeft)
    }
  }

  // コンソールに表示する。
  def show {
    for(row <- area)
      println(new String(row))
  }
}


object Cross {
  val HeadingRight = 0 
  val HeadingBottom = 1
  val HeadingLeft = 2  
  val HeadingTop = 3   
}

object RunCross {
  def main(args: Array[String]): Unit = {
    val src = if (args.length >= 1) args(0) else "doukaku"
    val cross = new Cross(src)
    cross.show
    
  }
}
バイナリクロック (Nested Flatten)
特徴などは特にありませんが、横長にならないようにしてみました。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
object BinClock {
    import java.util._
    def main(args:Array[String]){
        val now = Calendar.getInstance()
        val hour = now.get(Calendar.HOUR_OF_DAY)
        val min = now.get(Calendar.MINUTE)
        val hour_bin = Integer.toBinaryString(hour)
        val min_bin = Integer.toBinaryString(min)
        val hour_shikaku = hour_bin.replace("1","■").replace("0","□")
        val min_shikaku = min_bin.replace("1","■").replace("0","□")
        println(hour_shikaku)
        println(min_shikaku)
    }
}
ラングトンのアリの描画 (Nested Flatten)

Scalaで。春っぽい雰囲気にしてみました!?(季節を無視して)。ScalaどころかSwingアプリとしても拙い作りかもしれません。。。 paintComponent内で結構ぐるぐる回してもいけるもんなんですね。もしかしたら、マシンパワーによっては表示が追いつかないのかもしれません。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import scala.collection.mutable.ListBuffer
import scala.concurrent.ops._
import scala.swing._
import scala.util._
import java.awt.{Graphics, Dimension}

trait AntWorld {
    protected val w:Int
    protected val h:Int
    protected def reflect
     var ants:List[Ant] = Nil
    lazy val table:List[Array[Int]] = List.tabulate(w, {_=>Array.make(h,0)})
    private val r = new Random()
    def ant(c:Int) = new Ant(r.nextInt(w)/2+w/4, r.nextInt(h)/2+h/4, c)
    def antStart() = {
        spawn {
            while(true) {
                ants.foreach {_.move}
                reflect
                Thread.sleep(1)
            }
        }
    }
    class Ant(var x:Int, var y:Int, c:Int) {
        private val rads = List((0,-1), (1,0), (0,1), (-1,0))
        private val (initX, initY) = (x, y)
        private var radi = 0
        def init = { x = initX; y = initY; radi = 0 }
        def move = {
            val v = table(x)(y)
            table(x)(y) = (if (v != 0) 0 else c)
            radi = (radi + (if (v != 0) 1 else 3) ) % 4
            x = (x + rads(radi)._1 + w) % w
            y = (y + rads(radi)._2 + h) % h
        }
    }
}

object LangtonAnt extends SimpleGUIApplication {
    import java.awt.Color
    val aSize = 5
    def top = new MainFrame {
        title = "Langton's Ant"
        val panel = new Panel() with AntWorld {
            def reflect = repaint
            val (w, h) = (100, 100)
            peer.setPreferredSize(new Dimension(w * aSize, h * aSize))
            override def paintComponent(g:Graphics) = {
                super.paintComponent(g)
                for (x <- 0 until w; y <- 0 until h) {
                    table(x)(y) match {
                        case 0 => g.setColor(Color.WHITE)
                        case c => g.setColor(new Color(c))
                    }
                    g.fillRect(x * aSize, y * aSize, aSize, aSize)
                }
            }
            def clear = {
                table.foreach { a => for (i <- 0 until a.length) a(i) = 0 }
            }
            def reset = {
                ants =
                    ant(Color.GREEN.getRGB) ::
                    ant(Color.PINK.getRGB) ::
                    ant(Color.BLUE.getRGB) ::
                    ant(Color.RED.getRGB) ::
                    ant(Color.CYAN.getRGB) ::
                    Nil
                clear
            }
            def replay = {
                this.synchronized {
                    ants.foreach( _.init )
                    clear
                }
            }
            reset
        }
        contents = new BoxPanel(Orientation.Vertical ) {
            contents += new BoxPanel(Orientation.Horizontal ) {
                contents += new Button(Action("Clear"){ panel.clear })
                contents += new Button(Action("Replay"){ panel.replay })
                contents += new Button(Action("Reset"){ panel.reset })
            }
            contents += panel
        }
        panel.antStart
    }
}
居眠り床屋問題 (Nested Flatten)

Scala Actorで実装しました。考え方を理解するのに苦労しましたが、シンプルにできたと思います。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import scala.actors._
import scala.actors.Actor._
import scala.util._

object Log {
    def apply(msg:String, id:Any):Unit = printf("[%d] %s %s\n", currentThread.getId, msg, id)
    def apply(msg:String):Unit = apply(msg, "")
}

object SleepingBarber {
    object Close
    def main(args : Array[String]) : Unit = {
        val barber = self
        var entered = 0
        var result = 0
        var chair = 3
        val owner = actor {
              var sleeping = false
              def wakeup = { sleeping = false; Log("床屋、目覚める ") }
              def sleep = { sleeping = true; Log("床屋、眠る ") }
              sleep
              loop {
                  receive {
                        case id:Int => {
                            if (sleeping) wakeup
                            Log("散髪開始", id)
                            Thread.sleep((Math.random * 300).toInt + 100)
                            Log("散髪完了", id)
                            if (mailboxSize == 0) sleep
                            result += 1
                            reply(id)
                        }
                        case Close => exit
                  }
            }
        }
        val visitors = 1 to 16
        visitors.foreach { id =>
              Thread.sleep(if (id == 9) 1200 else (Math.random * 200).toInt)
              Log("来店", id)
              entered += 1
            if (chair == 0) {
                Log("満席で立ち去る ", id)
                    barber ! id
            } else {
                chair -= 1
                actor {
                    owner !? id
                        chair += 1
                        barber ! id
                }
            }
        }
         visitors.foreach { id => receive { case vid if vid == id => /*join*/ } }
        owner ! Close
        printf("※ %d人のうち %d人を散髪 \n", entered, result)
    }
}
割り算の筆算 (Nested Flatten)
Scalaらしく(?)作ってみました。#過去の課題でこっそり勉強中です。。

-- 実行結果
123456
77
     1603
   ------
77)123456
    77
   ------
    464
    462
   ------
      256
      231
   ------
       25
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
object DivCalc {
    def main(args : Array[String]) : Unit = {
        val n = Console.in.readLine.toLong
        val m = Console.in.readLine.toLong
        Div(n, m).print
      }
}

case class Div(n:Long, m:Long) {
    def print = {
        println( idt + fmt(ans) )
        println( idt + line )
        println( m + ")" + fmt(n) )
        calc.take(1).foreach( x => println( idt + fmt(x._2, x._3) ) )
        calc.drop(1).foreach( x => {
            println( idt + line )
            println( idt + fmt(x._1, x._3) )
            println( idt + fmt(x._2, x._3) )
        })
        if (calc.isEmpty) println( idt + fmt(0) )
        println( idt + line )
        println( idt + fmt(mod) )
    }

    def len(a:Any) = a.toString.length
    def fmt(x:Any):String = fmt(x, 0)
    def fmt(x:Any, i:Int):String = idt(" ", len(n) - len(x) - i) + x
    def line = idt("-", len(n))
    def idt:String = idt(" ", len(m) + 1)
    def idt(c:String, i:Int):String = c * i

    val ans:Long = n / m
    lazy val mod:Long = n % m
    lazy val calc:List[(Long, Long, Int)] = {
        def process(n:Long, m:Long, c:Int):List[(Long, Long, Int)] = {
            val pow = Math.pow(10, c).toLong
            val x = if (pow == 0) { 0L } else { n / pow / m * m }
            (n,m,c,x) match {
                case (_,_,c,_) if (c < 0) => Nil
                case (n,m,c,0) => process(n, m, c-1)
                case (n,m,c,x) => (n / pow, x, c) :: process(n - x * pow, m, c-1)
            }
        }
        process(n, m, len(n))
    }
}
いちばん長いしりとり (Nested Flatten)

 素直に書いてみました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import    java.io.{BufferedReader, FileInputStream, InputStreamReader}
import    scala.collection.immutable.HashMap

class WordchainGame(var p:String) {
    var    d:List[String] = null
    def initialize:WordchainGame = {
        def loop(r:BufferedReader):List[String] = r.readLine match {
                case null => List[String]()
                case l:String => l.split("\t").toList ++ loop(r)
            }
        d = loop(new BufferedReader(new InputStreamReader(new FileInputStream(p),"Shift_JIS"))).map(_.takeWhile(_ != '*').mkString).filter(_.length > 0)
        this
    }
    def play:List[List[String]] = {
        val    r:Map[Char,Char] = HashMap(('ァ','ア'),('ィ','イ'),('ゥ','ウ'),('ェ','エ'),('ォ','オ'),('ッ','ツ'),('ャ','ヤ'),('ュ','ユ'),('ョ','ヨ'))
        def loop(g:List[String], l:List[String]):List[List[String]] = l match {
                case List() => List(g)
                case _ =>(
                        g match {
                                case List() => l
                                case _ => {
                                    val    t:Char = if (r.contains(g.first.last)) r(g.first.last) else g.first.last
                                    l.filter(_.first == t)
                                }
                            }
                    ).flatMap((w) => w.last match {
                                case 'ン' => List(w::g)
                                case _ => loop(w::g, l.filter(_ != w))
                            }
                        )
            }
        loop(List[String](), d)
    }
}

object WordchainCombination {
    def main(args:Array[String]):Unit =
        if (args.length != 1)
            println("usage: WordchainCombination WORDLIST_FILE")
        else
            try {
                println(new WordchainGame(args.first).initialize.play.sort(_.length > _.length).first.reverse.mkString("->"))
            } catch {
                case ex => ex.printStackTrace 
            }
}
シードを固定した乱数 (Nested Flatten)

 scalaで。

1
2
3
4
5
6
7
8
import    scala.util.Random

try {
    val    r:Random = new Random(args.first.toInt)
    1.to(10).foreach((_) => println(r.nextInt.toString))
} catch {
    case ex => ex.printStackTrace
}
手作業Grep (Nested Flatten)

 scalaがまだの様なので。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import    scala.swing.{BorderPanel, Button, ListView, FlowPanel, MainFrame, Menu, MenuBar, MenuItem, ScrollPane, SimpleGUIApplication}
import    scala.swing.event.{ActionEvent, ButtonClicked}

class HandGrepFrame(var lines:List[String]) extends MainFrame {
    
    title = "Hand Grep"
    
    menuBar = new MenuBar
    
    val    menu:Menu = new Menu("file")
    val    quitMenu:MenuItem = new MenuItem("quit")
    
    menu.contents += quitMenu
    menuBar.contents += menu
    
    val    list:ListView[String] = new ListView(lines)
    val    quit:Button = new Button("quit")
    
    contents = new BorderPanel {
        
        import BorderPanel.Position._
        
        layout(new ScrollPane(list)) = Center
        layout(new FlowPanel(FlowPanel.Alignment.Right) { contents += quit }) = South
    }
    
    listenTo(quitMenu, quit)
    reactions += {
        case ActionEvent(`quitMenu`) | ButtonClicked(`quit`) => quitHandler
    }
    
    preferredSize = (600, 480)
    pack
    
    def quitHandler:Unit = {
        list.selection.items.foreach(Console.println)
        System.exit(0)
    }
}

object HandGrep extends SimpleGUIApplication {
    val    lines:List[String] = readLines
    def readLines:List[String] = Console.in.ready match {
            case false => List[String]()
            case _ => Console.readLine :: readLines
        }
    def top = new HandGrepFrame(lines)
}
メソッド数の多い組み込みクラスを列挙 (Nested Flatten)
 scala-library.jarとscala-swing.jarについて調べてみました。Java側のリフレクションを使って調べているので,ソースコード上の値とはずれがあります。

total:  3173
scala.swing.Key:        206
scala.collection.jcl.Buffer$Projection: 166
scala.collection.jcl.ArrayList: 158
scala.collection.jcl.LinkedList:        158
scala.collection.jcl.Buffer$$anon$2:    155
scala.collection.jcl.SortedMap$$anon$1: 153
scala.collection.jcl.TreeMap:   153
scala.collection.jcl.SortedMap$$anon$2: 151
scala.collection.jcl.Buffer$Range:      150
scala.collection.jcl.TreeSet:   146
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import scala.collection.jcl.Conversions
import java.io.File
import java.util.Collections
import java.util.jar.{JarEntry,JarFile}

object MethodCount {
    def getClassInformations(l:List[String]):List[Pair[String,Int]] = {
        def getInfo(n:String):Pair[String,Int] =
            try { (n, Class.forName(n).getDeclaredMethods.size) } catch { case _ => (n, -1) }
        def isClass(n:String):Boolean = n.endsWith(".class") && !n.matches("\\$\\$anonfun\\$")
        def getClassName(n:String):String = n.substring(0, n.length - 6).replace('/', '.')
        def getJarEntries(f:File):List[JarEntry] =
            Conversions.convertList(Collections.list((new JarFile(f)).entries)).toList
        def getFiles(l:List[String]):List[File] =
            l.map(new File(System.getProperty("scala.home"), _)).filter(_.exists)
        getFiles(l).map(getJarEntries).flatten(identity(_)).map(_.getName).filter(isClass).map(getClassName).map(getInfo)
    }
    def main(args:Array[String]):Unit = {
        val l:List[Pair[String,Int]] = getClassInformations(List("lib/scala-library.jar", "lib/scala-swing.jar"))
        Console.printf("total:\t%d\n", l.size)
        l.sort(_._2 > _._2).take(10).foreach((i) => Console.printf("%s:\t%d\n", i._1, i._2))
    }
}
HTTPでGET その2 (Nested Flatten)

プロパティをいじる方法で、Sourceを使ってみました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import scala.io.Source

System.setProperty("http.proxyHost","proxy.server.jp")
System.setProperty("http.proxyPort","8080")

println(
  Source.fromURL("http://ja.doukaku.org/feeds/comments/")
        .getLines
        .mkString
       )
printf書式変換 (Nested Flatten)

完成度低めですが、ErlangとCの書式変換など。 はじめ、Erlangで書こうとしたが挫折。 ScalaのExtractorで実装しはじめたものの、 Erlangの書式の柔軟さに負けた感のある今日この頃。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// printf書式文字列変換(お題 : http://ja.doukaku.org/259/)
// 
// Erlangの書式文字文字列  <--> C言語の書式文字列
// コマンドラインargs先頭で処理を指定、残りの引数で書式指定
// c2e : C --> Erlang
// e2c : Erlang --> C
// 例)
//    c2e %f  %020d  %.20d %+20.10d  %-20f %-20.10f
//    e2c ~f  ~20.0p ~.20p ~20.10p   ~-20f ~-20.10f
//    e2c ~10s ~-10s ~10.3.+s ~10.10.+s ~10.7.+s
//    ( ~10.3.+s ~10.10.+s ~10.7.+s はCの書式では正確に対応できません )
object Main {
  def main(args : Array[String]) : Unit = {
    args.toList match {
      case "e2c" :: xs =>
        for(x<-xs ; ErlFormatTerm(flag,termF,termP,termPad,termMod,termC) = x ) {
          //println(flag,termF,termP,termPad,termMod,termC)
          print (x + " ---> ")
          val flags = (flag,termPad) match{
            case ("-","" ) => "-"
            case ("-"," ") => "-"
            case ("-","0") => "-"
            case ("" ," ") => " "
            case ("" ,"0") => "0"
            case _ => ""
          }
          
          termC match {
            case "B" if termP=="8"  => println ( CFormatTerm(flags,termF,   "","o") )
            case "B" if termP=="16" => println ( CFormatTerm(flags,termF,   "","x") )
            case "c"                => println ( CFormatTerm(flags,termF,termP,"c") )
            case "s"                => println ( CFormatTerm(flags,termF,termP,"s") )
            case "f"                => println ( CFormatTerm(flags,termF,termP,"f") )
            case "e"                => println ( CFormatTerm(flags,termF,termP,"e") )
            case "g"                => println ( CFormatTerm(flags,termF,termP,"g") )
            //
            case _                  => println ( "未対応" )
          }
        }
      case "c2e" :: xs =>
        for(x<-xs ; CFormatTerm(flags,fieldWidth,precision,specifier) = x ) {
          print (x + " ---> ")
          val pad = flags match{
            case "+" => ""
            case "-" => ""
            case " " => ""
            case "0" => "0"
            case _ => ""
          }
          val flag = flags match{
            case "-" => "-"
            //
            case "+" => ""
            case " " => ""
            case "0" => ""
            case _   => ""
          }
          specifier match{    // F P Pad Mod C
            case "d" | "i" => println ( ErlFormatTerm(flag,fieldWidth,precision,pad,"","p") )
            case "u"       => println ( ErlFormatTerm(flag,fieldWidth,precision,pad,"","p") )
            case "o"       => println ( ErlFormatTerm(flag,fieldWidth,      "8", "","","B") )
            case "x"       => println ( ErlFormatTerm(flag,fieldWidth,     "16", "","","B") )
            case "X"       => println ( ErlFormatTerm(flag,fieldWidth,     "16", "","","B") )
            case "f"       => println ( ErlFormatTerm(flag,fieldWidth,precision, "","","f") )
            case "e" | "E" => println ( ErlFormatTerm(flag,fieldWidth,precision, "","","e") )
            case "a" | "A" => println ( ErlFormatTerm(flag,fieldWidth,precision, "","","p") )
            case "g" | "G" => println ( ErlFormatTerm(flag,fieldWidth,precision, "","","g") )
            case "c"       => println ( ErlFormatTerm(flag,fieldWidth,precision,pad,"","c") )
            case "s"       => println ( ErlFormatTerm(flag,fieldWidth,precision,pad,"","s") )
            case "N"       => println ( ErlFormatTerm(flag,fieldWidth,precision, "","","p") )
            case "p"       => println ( ErlFormatTerm(flag,fieldWidth,     "16","0","","B") )
            //case "%"       => 
            case _         => println ( "未対応" )
          }
       }
       case Nil =>
       case _ =>
    }
    ()
  }
}

object ErlFormatTerm{
  // F.P.PadModC
  def apply(flag :String   ,
            termF:String   , 
            termP:String   , 
            termPad:String , 
            termMod:String , 
            termC:String) : String = {
    val tail = termMod+termC
    (termF,termP,termPad) match {
      // fmt0
      case ("" ,"",_)  => "~"+tail
      //
      // fmt1
      case (f  ,"", "") if f != "" => "~" + flag + f + tail
      // fmt2
      case (f  ,"",pad) if f != "" => "~" + flag + f +"."+pad+ tail
      //
      // fmt3
      case ("" , p,  _) if p != "" => "~."+p + tail
      //
      // fmt4
      case (f  , p, "")            => "~"+ flag + f+"."+p        +tail
      // fmt5
      case (f  , p,pad)            => "~"+ flag + f+"."+p+"."+pad+tail
    }
  }
  //
  def unapply(format:String) : Option[(String,String,String,String,String,String)] ={
    if ( format(0) != '~' ) return None
    val reFmt0 = """~([^.\d])""".r                     // ~s
    val reFmt1 = """~(-?)(\d+)([^.\d])""".r              // ~10s , ~-10s
    val reFmt2 = """~(-?)(\d+)\.(.)([^.\d])""".r         // ~10.+s
    val reFmt3 = """~\.(\d+)([^.\d])""".r              // ~.5s
    val reFmt4 = """~(-?)(\d+)\.(\d+)([^.\d])""".r      // ~-10.5s
    val reFmt5 = """~(-?)(\d+)\.(\d+)\.(.)([^.\d])""".r // ~-10.5.+s
    //
    format match {
      case reFmt0(                    termC)      => Some(""  ,   "","",        "","",termC)
      case reFmt1(flag,termF         ,termC)      => Some(flag,termF,"",        "","",termC)
      case reFmt2(flag,termF,termPad ,termC)      => Some(flag,termF,"",   termPad,"",termC)
      case reFmt3(           termP        ,termC) => Some(""  ,   "","",        "","",termC)
      case reFmt4(flag,termF,termP        ,termC) => Some(flag,termF,termP,     "","",termC)
      case reFmt5(flag,termF,termP,termPad,termC) => Some(flag,termF,termP,termPad,"",termC)
      case _ => None
    }
  }
}

object CFormatTerm{
  // %[flags][fieldWidth][.precision]specifier
  def apply(flags:String     , 
            fieldWidth:String, 
            precision:String , 
            specifier:String ) : String = {
    "%"+flags+fieldWidth + {if(precision!="") "."+ precision else ""} +specifier
  }
  //
  def unapply(format:String) : Option[(String,String,String,String)] ={
    if ( format(0) != '%' ) return None
    //
    val reFmt0 = """%([a-zA-Z])""".r
    val reFmt1 = """%([-+ 0#])([\d*]+)([a-zA-Z])""".r
    val reFmt2 = """%([\d*]+)([a-zA-Z])""".r
    val reFmt3 = """%([-+ 0#])([\d*]+)\.([\d*]+)([a-zA-Z])""".r
    val reFmt4 = """%([\d*]+)\.([\d*]+)([a-zA-Z])""".r
    val reFmt5 = """%\.([\d*]+)([a-zA-Z])""".r
    format match {
      case reFmt0(                           specifier) => Some(   "",        "",       "",specifier)
      case reFmt1(flags,fieldWidth,          specifier) => Some(flags,fieldWidth,       "",specifier)
      case reFmt2(      fieldWidth,          specifier) => Some(   "",fieldWidth,       "",specifier)
      case reFmt3(flags,fieldWidth,precision,specifier) => Some(flags,fieldWidth,precision,specifier)
      case reFmt4(      fieldWidth,precision,specifier) => Some(   "",fieldWidth,precision,specifier)
      case reFmt5(                 precision,specifier) => Some(   "",        "",precision,specifier)
      case _ => None
    }
  }
}
loan patternのサンプル (Nested Flatten)

Java版(#9162)をScalaに移植しました。 これはこれで味わい深いです。 ありがとうございました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Java版#9162を移植
import java.io._

case class WithResource[T<:Closeable]( resource:T ) {
    def using[F<:Runnable](f:F) : Unit= {
        try {
            f.run();
        } finally {
            resource.close();
        }
    }
}

object Main{
    def main(args:Array[String]) : Unit = {
        val wr = WithResource(  new PrintWriter(
                                new BufferedWriter(
                                new OutputStreamWriter(System.out))))
        wr.using(new Runnable{
                    override def run():Unit = {
                        wr.resource.print("この文字列はflushしないと書き出されない");
                        wr.resource.print("(closeし忘れは良くある間違い)。");
                    } } )
    }
}
複素数 (Nested Flatten)

#8851をパラメタ付に改造してみました。 Complex[Int],Complex[Double]

もう、ぐだぐだ。

制限事項 整数と実数の混合ができない orz

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// 複素数(お題:http://ja.doukaku.org/247/)
// http://ja.doukaku.org/comment/----/
// snaさん作を改変( : http://ja.doukaku.org/comment/8851/)
// 参考 : http://en.literateprograms.org/Complex_numbers_(Scala)

trait Arithmetic[T<:AnyVal]{
  def unary_+ : T
  def unary_- : T
  def + (that:T):T
  def - (that:T):T
  def * (that:T):T
  def / (that:T):T
  def abs : T
  //
  def lt0 : Boolean  // >   0
  def gt0 : Boolean  // <   0
  def eq0 : Boolean  // ==  0
  //
  def eqp1 : Boolean // ==  1
  def eqm1 : Boolean // == -1
  //
}

case class Complex[ T<%Arithmetic[T] ](real:T, imag:T) {
  // +(a + bi) = (a + bi)
  def unary_+ = this
  
  // -(a + bi) = (-a - bi)
  def unary_- = Complex[T](-real, -imag)
  
  // (a + bi) + (c + di) = (a + c) + (b + d)i
  def + (that: Complex[T]) = Complex(this.real + that.real, this.imag + that.imag)
  
  // (a + bi) - (c + di) = (a - c) + (b - d)i
  def - (that: Complex[T]) = Complex(this.real - that.real, this.imag - that.imag)
  
  // (a + bi) * (c + di) = (ac - bd) + (bc + ad)i
  def * (that: Complex[T]) = {
    val Complex(a, b) = this
    val Complex(c, d) = that
    Complex(a*c - b*d, b*c + a*d)
  }
  
  // (a + bi) / (c + di) = (ac + bd) / (c^2 + d^2) + (bc - ad) / (c^2 + d^2)
  def / (that: Complex[T]) = {
    val Complex(a, b) = this
    val Complex(c, d) = that
    val deno = c*c + d*d
    Complex((a*c + b*d) / deno, (b*c - a*d) / deno)
  }
  
  // Conjugate
  def conjugate() : Complex[T] = Complex(real,-imag)
  
  override def toString = this match {
    case Complex(re, im) if im.eq0            => re.toString
    case Complex(re, im) if re.eq0 && im.eqp1 => "i"
    case Complex(re, im) if re.eq0 && im.eqm1 => "-i"
    case Complex(re, im) if re.eq0            => im.toString + "i"
    case Complex(re, im) if           im.eqp1 => re.toString + " + i"
    case Complex(re, im) if           im.eqm1 => re.toString + " - i"
    case Complex(re, im) if           im.gt0  => re.toString + " + " + im.toString + "i"
    case Complex(re, im) if           im.lt0  => re.toString + " - " + im.abs.toString + "i"
  }

}

object test{
  implicit def int2Arithmeic(n:Int) : Arithmetic[Int] = 
                    new Arithmetic[Int]{
                         def unary_+ : Int  = n.unary_+
                         def unary_- : Int  = n.unary_-
                         def + (that:Int):Int = n+that
                         def - (that:Int):Int = n-that
                         def * (that:Int):Int = n*that
                         def / (that:Int):Int = n/that
                         def abs = Math.abs(n)
                         //
                         def lt0 = n<0
                         def gt0 = n>0
                         def eq0 = n==0
                         //
                         def eqp1 = n==1 
                         def eqm1 = n== -1  }
  
  implicit def double2Arithmeic(n:Double) : Arithmetic[Double] = 
                    new Arithmetic[Double]{
                         def unary_+ : Double  = n.unary_+
                         def unary_- : Double  = n.unary_-
                         def + (that:Double):Double = n+that
                         def - (that:Double):Double = n-that
                         def * (that:Double):Double = n*that
                         def / (that:Double):Double = n/that
                         def abs = Math.abs(n)
                         //
                         def lt0 = n<0
                         def gt0 = n>0
                         def eq0 = n==0
                         //
                         def eqp1 = n==1 
                         def eqm1 = n== -1  }
  
  implicit def int2Complex   (n:Int   ):Complex[Int   ] = Complex(n,0)
  implicit def double2Complex(n:Double):Complex[Double] = Complex(n,0)
  implicit def icomp2dcomp   (z:Complex[Int]):Complex[Double] = Complex(z.real,z.imag)
  
  implicit def dcomp2richer  (z:Complex[Double]) = new Proxy{
       val self=z
       def abs = self match {
         case Complex(re, im) => Math.sqrt(re*re + im*im)
       }
    }
  
  implicit def icomp2richer  (z:Complex[int]) = new Proxy{
       val self=z
       def abs = self match {
         case Complex(re, im) => Math.sqrt(re*re + im*im)
       }
    }
  
  
  def main( args:Array[String] ) : Unit = {
    {
      val i = Complex(0,1)
      println( (3 + i  ) + (4 - i  ) )
      println( (5 - 9*i) - (2 + 6*i) )
      println( (5 + 3*i) * (5 + 8*i) )
      println( (9 - 7*i) / (9 - 3*i) )
      println( (2 + 3*i).abs         )
    }
    
    {
      val i = Complex(0.,1.)
      println( (3. + i  ) + (4. - i  ) )
      println( (5. - 9.*i) - (2. + 6.*i) )
      println( (5. + 3.*i) * (5. + 8.*i) )
      println( (9. - 7.*i) / (9. - 3.*i) )
      println( (2. + 3.*i).abs         )
    }
  }
}
ポリゴンを表示するプログラム (Nested Flatten)

#6023をscalaに移植しました。 またしても、java-->scala移植の暗黒面に・・・

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import scala.swing._

import javax.media.j3d._
import javax.vecmath._
import com.sun.j3d.utils.universe._
import com.sun.j3d.utils.geometry.ColorCube

@SuppressWarnings(Array("serial"))
object Sample3D {
    def createSceneGraph() :BranchGroup = {
        val objRoot = new BranchGroup();

        val objTrans = new TransformGroup();
        objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        objRoot.addChild(objTrans);

        val axis = new Transform3D();
        axis.rotZ(Math.Pi / 2);
        val bounds = new BoundingSphere(new Point3d(), 100.0);
        
        var rotator = new RotationInterpolator(
                new Alpha(-1,20 * 4000) , 
                objTrans , 
                axis     , 
                0.0F     , 
                (Math.Pi * 2.0).toFloat);
        rotator.setSchedulingBounds(bounds);
        objRoot.addChild(rotator);

        val objTrans2 = new TransformGroup();
        objTrans2.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        objTrans.addChild(objTrans2);
        rotator = new RotationInterpolator(new Alpha(-1, 4000), objTrans2);
        rotator.setSchedulingBounds(bounds);
        objRoot.addChild(rotator);

        objTrans2.addChild(new ColorCube(0.4));
        objRoot.compile();
        return objRoot;
    }
}

object Main extends SimpleGUIApplication {
    val config = SimpleUniverse.getPreferredConfiguration();
    val canvas = new Canvas3D(config);
    
    //create frame window
    def top=new MainFrame{
      peer.setBounds(10, 10, 480, 480)
      //caption
      title = "Sample3D with Scala/Java3D"
      
      val contentPane = peer.getContentPane()
      contentPane.setLayout(new java.awt.BorderLayout());
      contentPane.add(canvas,java.awt.BorderLayout.CENTER)
      
    } // end of MainFrame
    
    val scene = Sample3D.createSceneGraph();
    val universe = new SimpleUniverse(canvas);
    universe.getViewingPlatform().setNominalViewingTransform();
    universe.addBranchGraph(scene);
    
}
2次元ランダムウォーク (Nested Flatten)

scala.swingに移植してみました。

GUI以外の変更点 ・saveのprintfのArrayを可変引数に。 ・基本型の名前をscalaっぽく :)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
// 2次元ランダムウォーク(お題:http://ja.doukaku.org/193/)
// scala.swing版
// (lunlumoさん作を改変 http://ja.doukaku.org/comment/7012/)

import swing._
import swing.event._

import  java.awt.Color
import  java.awt.Dimension
import  java.awt.FlowLayout
import  java.awt.Graphics
import  java.awt.Point

import  java.io.BufferedWriter
import  java.io.File
import  java.io.FileOutputStream
import  java.io.OutputStreamWriter
import  java.io.PrintWriter
import  java.util.Random

class RandomWalk(step:Int) {
    private var _trace:List[Point] = null
    private val rand:Random = new Random
    
    def walk:RandomWalk = {
        var p = new Point(0,0)
        trace = (new Range(1,step,1)).map[Point] { i => p = move(p); p }.toList
        this
    }
    
    private def move(p:Point):Point = rand.nextInt(4) match {
        case 0 => new Point(p.x + 1, p.y)
        case 1 => new Point(p.x - 1, p.y)
        case 2 => new Point(p.x, p.y + 1)
        case 3 => new Point(p.x, p.y - 1)
        case _ => p
    }
    
    def trace_=(trace:List[Point]) = { _trace = trace }
    def trace = _trace
}


class RWPanel extends Panel {
    var _trace:List[Point] = null
    
    def trace_=(trace:List[Point]) = { _trace = trace }
    def trace = _trace
    
    override def paint(g:Graphics):Unit = {
        val max:Int = trace.foldLeft(0) { (m,p) => List(p.x,p.y).foldLeft(m) { (m,l) => Math.max(m,Math.abs(l)) } }
        val pitch:Double = peer.getWidth.asInstanceOf[Double] / (max * 2)
        
        def drawLine(c:Point,trace:List[Point]):Unit = {
            trace match {
                case List() => ()
                case (p::rest) => {
                    g.drawLine(
                            (c.x * pitch).asInstanceOf[Int] + peer.getWidth / 2,
                            peer.getWidth / 2 - (c.y * pitch).asInstanceOf[Int],
                            (p.x * pitch).asInstanceOf[Int] + peer.getWidth / 2,
                            peer.getWidth / 2 - (p.y * pitch).asInstanceOf[Int]
                        )
                    drawLine(p,rest)
                }
            }
        }
        
        g.clearRect(0,0,peer.getWidth,peer.getHeight)
        g.setColor(Color.BLACK)
        
        drawLine(new Point(0,0),trace)
    }
}

class Plotter(title:String,step:Int) extends Panel {
    
    var walker = (new RandomWalk(step)).walk
    var _panel:RWPanel = null
    
    def panel_=(panel:RWPanel) = { _panel = panel }
    def panel = _panel
    
    def walk:Unit = {
        walker.walk
        panel.trace = walker.trace
    }
    def do_walk:Unit = {
        walk
        panel.repaint()
    }
    def save:Unit = {
        val fc = new FileChooser()
        
        try {
            if (fc.showSaveDialog( this ) == FileChooser.Result.Approve) {
                val f= fc.peer.getSelectedFile
                val w = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f))))
                
                def writeTrace(trace:List[(int,Point)]):Unit = {
                    trace match {
                        case List() => ()
                        case (i::rest) => {
                            w.printf("%d\t%d\t%d\n",Integer.valueOf(i._1),Integer.valueOf(i._2.x),Integer.valueOf(i._2.y))
                            writeTrace(rest)
                        }
                    }
                }
                
                writeTrace((new Range(1,walker.trace.size,1)).toList.zip(walker.trace))
                w.close
            }
        } catch {
            case e => e.printStackTrace
        }
    }
    def quit:Unit = {
        System.exit(0)
    }
}

object Main extends SimpleGUIApplication{
    var p = new Plotter("random walk",10000)
    val pp = new RWPanel{
      peer.setPreferredSize(new Dimension(300,300))
    }
    p.panel = pp
    
    //create frame window
    def top=new MainFrame{
      peer.setResizable(false)
      //--------------------------------------------------------------
      // caption
      title = "Random walk"
      //--------------------------------------------------------------
      // menu bar
      menuBar = new MenuBar{
        //--------------------------------
        // file menu
        contents += new Menu("file"){
          contents += new MenuItem( Action("save"){p.save} )
          contents += new MenuItem( Action("quit"){p.quit} )
        }// end of file-menu
        //--------------------------------
          
        //--------------------------------
        // file menu
        contents += new Menu("walk"){
          contents += new MenuItem( Action("walk"){p.do_walk} )
        }
      } // enf of menu
      contents = new BorderPanel{
        add(pp,BorderPanel.Position.Center)
        add(new FlowPanel{
              contents += new Button(Action("walk"){ p.do_walk })
              contents += new Button(Action("save"){ p.save })
            }// 
        ,BorderPanel.Position.South)
      } // end of contents(BorderPanel)
    } // end of MainFrame
    p.walk
}
loan patternのサンプル (Nested Flatten)
C#/VB.NETのusingに憧れて作った、Scala用のusing構文です。
IDisposableのような統一的な解放インターフェースが無いので、closeメソッドやdisposeメソッドを持つオブジェクトを対象にします。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import java.io._

object UsingSyntax {
  
  trait Disposing[-A] extends (A => Unit)
  
  // closeメソッドを持つオブジェクトの解放方法を定義
  implicit val closeDefinedDisposing = new Disposing[{def close(): Unit}] {
    def apply(target: {def close(): Unit}) = target.close()
  }
  // disposeメソッドを持つオブジェクトの解放方法を定義
  implicit val disposeDefinedDisposing = new Disposing[{def dispose(): Unit}] {
    def apply(target: {def dispose(): Unit}) = target.dispose()
  }
  // 自分で解放方法を指定する場合の変換
  // using (obj) { 処理... } { (_: MyDisposable).myDispose() }
  implicit def functionToDisposing[A](f: A => Any): Disposing[A] =
  new Disposing[A] {
    def apply(target: A): Unit = f(target)
  }
  
  def using[A, R](a: A)(block: A => R)(implicit disposing: Disposing[A]): R = {
    try {
      block(a)
    }
    finally {
      disposing(a)
    }
  }
  
}

object Doukaku258 {
  import UsingSyntax._
  
  def main(args: Array[String]): Unit = {
    
    // ファイルからテキストを読み込んで全部表示
    // 使い終わったらファイルを閉じる
    using (new FileInputStream("test.txt")) { in =>
      using (new InputStreamReader(in, "UTF-8")) { rd =>
        
        val buf = new Array[Char](512)
        var n = 0
        while ({n = rd.read(buf); n > 0}) {
          print(buf.take(n).mkString)
        }
        
        // 処理中に例外が発生してもファイルは閉じる
        throw new Exception()
        
      }
    }
    
  }
  
}
与えられた文字列でピラミッド (Nested Flatten)

文字列をリストに変換せずにやってみた。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
object MojiPira {
  def main(args : Array[String]) : Unit = {
    pyramid(args(0))
  }
  def pyramid(moji:String) = {
    val m    = moji.length
    mojiPira(" "*(m-1),"",moji.reverse){print _}
  }
  def mojiPira(mergin:String,prevPrn:String,s:String)(prn:String=>Unit) : Unit = {
      val prnStr = if (prevPrn=="") ""+s(0) else s(0) + " " + prevPrn
      prn(mergin + prnStr + mergin + "\n")
      if( mergin!="" )
        mojiPira(mergin.substring(1),prnStr,s.substring(1))(prn)
  }
}
loan patternのサンプル (Nested Flatten)

メモリマップをFileダンプにつかってみました。 (バッファをloanする)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import java.io._
import java.nio._
import java.nio.channels._

object LoanSample{
  def main(args : Array[String]) : Unit = {
    FileLoan.viewFileAsBuffer(args(0)){ byteBuffer =>
        //      "012345678:---
        val maxPos  = byteBuffer.limit()
        var viewLine=""
        println("          0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F")
        for{ i <-0 until byteBuffer.limit() by 16
             j <-0 until 16
             pos = i + j }{
          if(j== 0){
            print(pos.formatted("%08X: "))
            viewLine = ""
          }
          if( pos<byteBuffer.limit() ){
            val b = byteBuffer.get(pos)
            val c = b.toChar
            print( b.formatted("%02X ") )
            viewLine += (if( c.isControl ) "." else ""+c)
          }else{
            print(                                "    "  )
            viewLine += " "
          }
          if(j==15){
            println( viewLine )
            viewLine = ""
          }
        }
        ()
    }
  }
}

object FileLoan{
  def viewFileAsBuffer(fileName:String)(op:ByteBuffer=>Unit) : Unit = {
    var channel:FileChannel = null
    var buffer :ByteBuffer  = null
    try{
      channel = new FileInputStream(fileName).getChannel()
      buffer  = channel.map(FileChannel.MapMode.READ_ONLY , 0 , channel.size())
      op( buffer )
    }catch{
      case e:Exception =>{
          println(channel,buffer)
          println(e)
        }
      case _ =>
    }finally{
      buffer  = null
      channel = null
    }
  }
}
next >>

Index

Feed

Other

Link

Pathtraq

loading...