関数の定義

これも let式を使う。

# let area_of_circle r = r *. r *. pi;;
val area_of_circle : float -> float = <fun>
# area_of_circle 1.0;;
- : float = 3.141529

引数の型を間違えないこと。

# area_of_circle 1;;
Characters 15-16:
area_of_circle 1;;
^
This expression has type int but is here used with type float

tracをインストールしてみた

インタアクトによってローカライズされた trac-ja を使う。

必要なもの

Python が最新の2.5でないのは ClearSilver が対応していないから。

PySQLite は 2.4.0 が最新版だけど trac-admin コマンドを実行したときにエラーが出た。以前にダウンロードした 2.3.3 を試してみたら大丈夫だったので,こちらを使うことにした。

インストール

Subversion はインストール済みだったけど,ついでにアップデート。やり方は省略。

Python, PySQLite, subversion python binding, CleasSilver

インストーラだからダブルクリックしてインストールするだけ。

Python は C:\usr\python24 にインストールした。パスを通すのを忘れずに。

DocUtils

ファイルを展開して:

^o^ >cd docutils-0.4
^o^ >python setup.py install
trac

これも同様。ファイルを展開して:

^o^ >cd trac-0.10.4-ja-1
^o^ >python setup.py install

Thank you for choosing Trac 0.10.4. Enjoy your stay! と出たので無事完了。

trac の設定

まずはリポジトリを作っておく。

^o^ >svnadmin create D:/svn/sample

tracの設定には trac-admin コマンドを使う。

^o^ >python C:\usr\python24\scripts\trac-admin D:/www/trac/sample initenv
Creating a new Trac environment at D:\www\trac\sample
Trac will first ask a few questions about your environment
in order to initalize and prepare the project database.
Please enter the name of your project.
This name will be used in page titles and descriptions.
Project Name [My Project]> Sample Project
Please specify the connection string for the database to use.
By default, a local SQLite database is created in the environment
directory. It is also possible to use an already existing
PostgreSQL database (check the Trac documentation for the exact
connection string syntax).
Database connection string [sqlite:db/trac.db]>
Please specify the type of version control system,
By default, it will be svn.
If you don't want to use Trac with version control integration,
choose the default here and don't specify a repository directory.
in the next question.
Repository type [svn]>
Please specify the absolute path to the version control
repository, or leave it blank to use Trac without a repository.
You can also set the repository location later.
Path to repository [/path/to/repos]> d:/svn/sample
Please enter location of Trac page templates.
Default is the location of the site-wide templates installed with Trac.
Templates directory [C:\usr\python24\share\trac\templates]>
Creating and Initializing Project
Installing default wiki pages
C:\usr\python24\share\trac\wiki-default\CamelCase => CamelCase
C:\usr\python24\share\trac\wiki-default\checkwiki.py => checkwiki.py
C:\usr\python24\share\trac\wiki-default\InterMapTxt => InterMapTxt
(snip)
C:\usr\python24\share\trac\wiki-default\WikiPageNames => WikiPageNames
C:\usr\python24\share\trac\wiki-default\WikiProcessors => WikiProcessors
C:\usr\python24\share\trac\wiki-default\WikiRestructuredText => WikiRestructur e
dText
C:\usr\python24\share\trac\wiki-default\WikiRestructuredTextLinks => WikiRestr u
cturedTextLinks
C:\usr\python24\share\trac\wiki-default\WikiStart => WikiStart
Indexing repository
---------------------------------------------------------------------
Project environment for 'Sample Project' created.
You may now configure the environment by editing the file:
D:\www\trac\sample\conf\trac.ini
If you'd like to take this new project environment for a test drive,
try running the Trac standalone web server `tracd`:
tracd --port 8000 D:\www\trac\sample
Then point your browser to http://localhost:8000/sample.
There you can also browse the documentation for your installed
version of Trac, including information on further setup (such as
deploying Trac to a real web server).
The latest documentation can also always be found on the project
website:
http://trac.edgewall.org/
Congratulations!

D:\www\trac\wample\conf\trac.ini ファイルを編集:文字コードだけ。

:
[trac]
:
default_charset = japanese.shift_jis
:

tracd

trac にはスタンドアロンのサーバがついている:

^o^ >python c:/usr/python24/scripts/tracd --port 8000 d:/www/trac/sample

これでブラウザから http://localhost:8000/ にアクセスすれば,プロジェクトの一覧が表示される。

ダブル完全数

cf. どう書く?.org – ダブル完全数

HaskellのほうがRubyよりすっきりしてるな。

divisors n = filter ((==0).mod n) [1..(n `div` 2 + 1)]

isDoublePerfectNumber n = (sum.divisors) n == (n*2)

main = mapM_ (putStrLn.show) $ filter isDoublePerfectNumber [1..10000]
def divisors(n)
  (1..(n/2+1)).to_a.select{|x| n % x == 0 }
end

def double_complete_number?(n)
  divisors(n).inject(0){|a,b| a+b } == 2 * n
end

(1..10000).to_a.each do |n|
  puts n if double_complete_number?(n)
end

結果は同じ(あたりまえ)だけど,Rubyのほうが速かった。

^o^ >runhaskell dpn.hs
120
672
^o^ >ruby dpn.rb
120
672

長方形の交差判定

cf. どう書く?.org – 長方形の交差判定

問題文中の top < bottom は間違いじゃないかと書いたら,グラフィックイメージの座標だと考えればOKだとコメントをもらった。なるほど。

判定方法は,要するに一方の長方形の4つある頂点のどれかか,もう一方の長方形の内部にあれば重なってると判定していいわけだ。

今日はRubyで書いた。

class Rect
def initialize(left, top, right, bottom)
@left = left
@top = top
@right = right
@bottom = bottom
end
def vertexes
[ [@left, @top],
[@left, @bottom],
[@right, @bottom],
[@right, @top] ]
end
def inner?(x,y)
(@left < x && x < @right) && (@top < y && y < @bottom)
end
def overlap?(rect)
rect.vertexes.any?{|x,y| inner?(x,y) }
end
end
r1 = Rect.new(  0,   0, 100, 100)
r2 = Rect.new(100,   0, 200, 100)
r3 = Rect.new( 50,  50, 150, 100)
p r1.overlap?(r2)                   # => false
p r1.overlap?(r3)                   # => true
p r2.overlap?(r3)                   # => true

追記:

このコードだと長方形がX方向とY方向の両方にずれていないと正しく判定できないことに気づいた。極端な話,ぴったりと重なっている長方形が「重なっていない」判定になる。

irb(main):001:0> r1 = Rect.new(0,0,100,100)
=> #<Rect:0x499f9f4 @top=0, @left=0, @bottom=100, @right=100>
irb(main):002:0> r1.overlap?(r1)
=> false

なんてこったい。

アルファベットの繰り上がり

cf. どう書く?.org – アルファベットの繰り上がり

succ でいいじゃん,と思ったらダメだった。

Prelude> succ 'A'
'B'
Prelude> succ 'Z'
'['

Ruby の String#succ はうまくやってくれるのに。

なら,26進数だと考えて素直に繰り上がりを処理すればいいか……と思ったけどこれもダメ。’A’ は 0 じゃない。要するに 0 が無いんだな。結局繰り上がりのところで汚いコードになってしまった。

module Main ( main ) where

import Data.Char ( ord, chr )
import Data.List ( mapAccumR, intersperse )

succS :: [Char] -> Int -> [Char]
succS s n = map intToAlpha $ g $ mapAccumR f n $ map alphaToInt s
  where
    alphaToInt c = (ord c ) - 64
    intToAlpha i = chr (i + 64)
    f acc x = let (d,m) = (acc+x) `divMod` 26
    in if m == 0 then (d-1,26) else (d,m)
    g (0,b) = b
    g (a,b) = a:b

main :: IO ()
main = putStr $ concat $ intersperse "," $ take 100 $ iterate (flip succS 1) "A"

実行:

^o^ >runhaskell succS.hs
A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,AA,AB,AC,AD,AE,AF,AG,AH,AI,A
J,AK,AL,AM,AN,AO,AP,AQ,AR,AS,AT,AU,AV,AW,AX,AY,AZ,BA,BB,BC,BD,BE,BF,BG,BH,BI,BJ,
BK,BL,BM,BN,BO,BP,BQ,BR,BS,BT,BU,BV,BW,BX,BY,BZ,CA,CB,CC,CD,CE,CF,CG,CH,CI,CJ,CK
,CL,CM,CN,CO,CP,CQ,CR,CS,CT,CU,CV

倍数になる13進数

cf. どう書く?.org – 倍数になる13進数

module Main (main) where

fromDecimal :: (Integral a) => a -> a -> a
fromDecimal n x = f 0 x 1
  where
    f r 0 _ = r
    f r y z = f (r + (y `mod` 10) * z) (y `div` 10) (z * n)

main :: IO ()
main = putStr $ show $ head $ filter (\x -> fromDecimal 13 x `mod` x == 0) [10..]

実行。

^o^ >runhaskell multiple13.hs
1557

/*コメント*/を取り除く

cf. どう書く?.org – /*コメント*/を取り除く

正規表現の最短一致を使ってこれでいいはず……だと思うんだけど。

def remove_comment(str)
str.gsub(/\/\*.*?(\*\/|\z)/,"")
end
samples = %w( AAA
               AAA/*BBB*/
               AAA/*BBB
               AAA/*BBB*/CCC
               AAA/*BBB/*CCC*/DDD*/EEE
               AAA/a//*BB*B**/CCC
            )
samples.each do |str|
puts str
puts " => #{remove_comment(str)}"
end

実行。

^o^ >ruby remove_comment.rb
AAA
=> AAA
AAA/*BBB*/
=> AAA
AAA/*BBB
=> AAA
AAA/*BBB*/CCC
=> AAACCC
AAA/*BBB/*CCC*/DDD*/EEE
=> AAADDD*/EEE
AAA/a//*BB*B**/CCC
=> AAA/a/CCC

アレイのuniq

cf. どう書く?.org – アレイのuniq

再帰で

uniq [] = []
uniq (x:xs) = x:uniq (filter (/=x) xs)

と書いてから,こんな関数ありそうだなぁと思ったらやっぱりあった。

Data.List nub

高階関数版:

uniq2 :: (Eq a) => [a] -> [a]
uniq2 = foldl (\a e -> if (elem e a) then a else a ++ [e]) []

型を明示しないとダメ。

Prelude> :l uniq2.hs
[1 of 1] Compiling Main             ( uniq2.hs, interpreted )

uniq2.hs:2:27:
    Ambiguous type variable `b' in the constraint:
      `Eq b' arising from use of `elem' at uniq2.hs:2:27-34
    Possible cause: the monomorphism restriction applied to the following:
      uniq2 :: [b] -> [b] (bound at uniq2.hs:2:0)
    Probable fix: give these definition(s) an explicit type signature
                  or use -fno-monomorphism-restriction
Failed, modules loaded: none.