Language detail: Scala
Coverage: 86.80%
|
number of '+' ratings |
contribution for coverage |
Unsolved challenges
- 年賀はがきの当せん番号 (Nested Flatten)
- 箱詰めパズルの判定 (Nested Flatten)
- 関数やメソッドのソースの平均行数 (Nested Flatten)
- コレクションの実装 (Nested Flatten)
- 化学反応式の完成 (Nested Flatten)
codes
文字列で+を表示する
(Nested
Flatten)
図形の作り方に多少汎用性を持たせてみました。
結果:
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
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メソッドを持つオブジェクトを対象にします。
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)
next >>
メモリマップを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
}
}
}
|






a_san #10312() [ Scala ] Rating0/0=0.00
タートルグラフィックで描いてみました。 ちなみに、斜めに描くこともできます。(^^; 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/** キャンバス */ 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) } }Rating0/0=0.00-0+
[ reply ]