前回の続きです。 エクセルの列番号関係では、
・アルファベット "A"-"Z"を 数字 1-26に 変換する
・数字 1-26 をアルファベット "A"-"Z"に 変換する
のが、基本処理ですね。
Iconで、この変換を行うのに どういうやり方があるか を考えてみました。
まず、"A"-"Z" -> 1-26です。
-----^ A2N.ICN ( date:03-10-23 time:23:53 ) ----------------<cut here
####################
# アルファベット -> 数 変換
####################
# 文字 "A"-"Z" を 数 1-26へ変換
# a2n.icn Rev.1.1 2003/10/23 風つかい
# This file is in the public domain.
procedure main()
L := [a2n1,a2n2,a2n3,a2n4,a2n5] # 変換 procedureの list
write("A-Zを 1-26へ変換")
every proc1 := !L do { # 変換 procedureを順に取り出して
writes(image(proc1)[11:0],":") # procedure名を出力
# image例 "procedure a2n1"の 11文字以降
every writes(" ",proc1(!&ucase)) # A-Zの変換出力を順に書き出す
write() # ↑'AB..Z'の文字セット から順に取り出す
}
end
## 1 ##############
# 文字 -> 数 変換関数を使用
####################
procedure a2n1(s)
return ord(s) -ord("A") +1 # アルファベット A-Zはコード上で昇順に
end # 連続配置されている前提
## 2 ##############
# "AB..Z" の文字列を走査し、sの位置を調べる
####################
procedure a2n2(s)
return &ucase ? upto(s) # &ucase中の sの位置を返す
end # 文字セット'AB..Z'は、文字列"AB..Z"と見なされる
## 3 ##############
# 文字置換関数を使う
####################
procedure a2n3(s)
# ↓置換した結果が元の文字と変わっていれば、置換成功
(s ~==:= map(s,"ABCDEFGHIJ","0123456789")) | # いずれかが成功
(s ~==:= map(s,"KLMNOPQRST","0123456789"),s := "1" || s) | # するハズ。
(s ~==:= map(s,"UVWXYZ", "012345") ,s := "2" || s) #
return integer(s) +1 # integer:整数へ変換 "12" -> 12
end
# ~==:= は、左辺と右辺の文字列が異なっていれば、左辺へ右辺を代入する。
# A-Zでは面倒だが、A-J -> 0-9 位の変換には 手軽。
# integer(map(s,"ABCDEFGHIJ","0123456789")) で、見た目に分かりやすい。
## 4 ##############
# tableを使う
####################
procedure a2n4(s)
static Ta2n # 次回に呼ばれた時まで記憶
initial { # 初回だけ実行
Ta2n := table() # table生成
n := 0 # 文字の番号
every ss := !&ucase # 'AB..Z'の文字セット から順に取り出す
do Ta2n[ss] := (n +:= 1) # tableへ登録 例: key:"A" -> value:1
}
return Ta2n[s] # table参照結果
end
## 5 ##############
# 36進数とみなして、数へ変換し補正する
####################
# 36rAは、36進のA (10進の 10)を表す。
# Iconでの数表記には、10進表記と基数表記がある。
# 基数は 2〜36で、数は 0〜9,A-Zを使用。r,A-Zは大文字でも小文字でも構わない。
procedure a2n5(s)
return integer("36r" || s) -9 # integerは整数化関数 少数点以下切り捨て
end # および 10進数表記、基数表記を 数に変換
# "36rA" -> 10 .. "36rZ" -> 35
# BIPL(Icon基本ライブラリ)の convert.icn中の inbase10では こんな風なやり方で、
# 基数表記 -> 数へ変換している。
-----$ A2N.ICN ( lines:74 words:261 ) ----------------------<cut here
結果はこうなります。どれも同じ結果で 面白味は無いですが。
-----^ A2N.1 ( date:03-10-23 time:23:55 ) ------------------<cut here
A-Zを 1-26へ変換
a2n1: 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
a2n2: 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
a2n3: 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
a2n4: 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
a2n5: 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
-----$ A2N.1 ( lines:6 words:137 ) -------------------------<cut here
次は、1-26 -> "A"-"Z"です。
-----^ N2A.ICN ( date:03-10-23 time:23:55 ) ----------------<cut here
####################
# 数 -> アルファベット 変換
####################
# 数 1-26 を "A"-"Z" へ変換
# n2a.icn Rev.1.1 2003/10/23 風つかい
# This file is in the public domain.
procedure main()
L := [n2a1,n2a2,n2a3,n2a4] # 変換 procedureの list
write("1-26を A-Zへ変換")
every proc1 := !L do { # 変換 procedureを順に取り出して
writes(image(proc1)[11:0],":") # procedure名を出力
# image例 "procedure n2a1"の 11文字以降
every writes(" ",proc1(seq() \26)) # 1-26の変換出力を順に書き出す
write() # ↑1 から順に数字を発生する関数(generator)
} # \26は発生数を 26個に限定
end
## 1 ##############
# 数 -> 文字 変換関数を使う
####################
procedure n2a1(n)
return char(ord("A") +n -1) # アルファベット A-Zはコード上で昇順に
end # 連続配置されている前提
## 2 ##############
# "AB..Z" の文字列の n番目指定を使う
####################
procedure n2a2(n)
return &ucase[n]
# ↑英大文字セット
end
## 3 ##############
# 文字置換関数を使う
####################
procedure n2a3(n)
return case (n-1) / 10 of {
0 : map(n -1,"0123456789","ABCDEFGHIJ")
1 : map(n-11,"0123456789","KLMNOPQRST")
2 : map(n-21,"012345" ,"UVWXYZ")
}
end
## 4 ##############
# tableを使う
####################
procedure n2a4(n)
static Tn2a # 次回に呼ばれた時まで記憶
initial { # 初回だけ実行
Tn2a := table() # table生成
nn := 0 # 文字の番号
every s := !&ucase # 'AB..Z'の文字セット から順に取り出す
do Tn2a[nn +:= 1] := s # tableへ登録 例: key:1 -> value:"A"
}
return Tn2a[n] # table参照結果
end
-----$ N2A.ICN ( lines:58 words:184 ) ----------------------<cut here
結果はこうなります。
-----^ N2A.1 ( date:03-10-23 time:23:55 ) ------------------<cut here
1-26を A-Zへ変換
n2a1: 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
n2a2: 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
n2a3: 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
n2a4: 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
-----$ N2A.1 ( lines:5 words:110 ) -------------------------<cut here
Iconは、色んな方式のプログラムが楽しめますので、お試し頂けるとうれしいです。
風つかい(hshinoh@...)
IconのWWWは、 http://www.cs.arizona.edu/icon/
UniconのWWWは、http://unicon.sourceforge.net/index.html
BGM: Battery's not included / 森山威男 & 杉本喜代志