読者です 読者をやめる 読者になる 読者になる

bitterharvest’s diary

A Bitter Harvestは小説の題名。作者は豪州のPeter Yeldham。苦闘の末に勝ちえた偏見からの解放は命との引換になったという悲しい物語

接着関数-路線網(乗換駅)

1.乗換駅

三つの路線だけだが路線網を求めることができた。そこで、この路線図を利用して乗換駅を求めることにする。

乗換数ごとに関数を作ることとし、入力は乗車で用いる路線line1、下車で用いる路線line2、さらに路線網networkを入力し、乗換駅のリストが出力されるようにする。

この手のプログラムを手続き型の言語で書こうとすると、とても面倒くさいことになるが、Haskellではいとも簡単に出来上がるのが嬉しい。

それでは一回乗り換えの場合を考える。これはlie1からline2への乗換駅を求めればよい。即ちattached networkから上記の条件を満たすものを求めればよいので次のようになる。

trans1 :: Line -> Line -> Network -> [Transfer]
trans1 line1 line2 network 
  | line1 == line2 = error "use different line names."
  | otherwise      = [ x | x <- attached network, (fst (fst x) == line1 &&  fst (snd x) == line2) || (fst (fst x) == line2 && fst (snd x) == line1)]

実行結果を以下に示す。なお、以下では三路線の路線網の名はnetwork2となっている。
f:id:bitterharvest:20141011141905p:plain

次に二回乗り換えの場合を示す。これは一回乗り換えの関数を利用することで実現できる。即ち、①乗車する路線line1から別の路線line3に乗り換える。②別の路線line3から下車する路線line2に乗り換える。この時、別の路線は、乗車する路線とも下車する路線とも異なるものとする。これを関数trans2で表すと以下のようになる。

trans2 :: Line -> Line -> Network -> [(Transfer, Transfer)]
trans2 line1 line2 network 
  | line1 == line2 = error "use different line names."
  | otherwise      = [ (x, y) | line3 <- names network, line3 /= line1 && line3 /= line2, x <- trans1 line1 line3 network, y <- trans1 line2 line3 network]

実行結果を示したのが下図である。
f:id:bitterharvest:20141011142944p:plain
それぞれ乗換駅を対で示してある。半蔵門線から有楽町線へは二通り、半蔵門線から大江戸線へは一通りである。