普通に書いたら何の面白味もないので,ひねくれた書き方をしてみる。
追記:何点か(たくさん)修正しました(赤字の部分)。2021/08/26
お題
整数値をとる引数が,1〜125 なら 1,126〜211 なら 2,212〜214 なら 3 を返す関数を定義せよ。
まともな解答??
function f1(N::Int64)
if 1 <= N <= 125
return 1
elseif 126 <= N <= 211
return 2
elseif 212 <= N <= 214
return 3
else
return "error"
end
end
f1(215) # "error" という文字列を返す
f1(3.5) # Julia から "MethodError: no method matching f1(::Float64)" を返す
ひねくれ者の解答
1〜214 のときに返す値のベクトルを用意しておいて,整数引数を添え字として値を返す。
添え字範囲を超えると Julia が BoundsError を返す
function f2(N::Int64)
return vcat(fill(1, 125), fill(2, 86), fill(3, 3))[N]
end
一行で書くならば,
f3(N::Int64) = vcat(fill(1, 125), fill(2, 86), fill(3, 3))[N]
多項式近似して
f4(N::Int64) = round(Int, sum([1.15683106318897e+00, -3.85131039015425e-02, 2.25503374685424e-03, -5.10900952943894e-05, 5.19543217094899e-07, -2.36769347431069e-09, 3.95939127643363e-12] .* (N.^(0:6))))
というのもありか。
追記
中澤さんからのコメントで,新たなアルゴリズムが提示されました。
Rだと
f5 <- function(N) { (N %/% 1 > 0) + (N %/% 126 > 0) + (N %/% 211 > 0) }
それに基づいて,なるべくちゃんとした結果を返す Julia プログラムを書いてみました。
f5(N::Int) = 0 < N < 215 ? 1 + (N ÷ 126 > 0) + (N ÷ 212 > 0) : "error"
f5(1) # 1
f5(125) # 1
f5(126) # 2
f5(211) # 2
f5(212) # 3
f5(214) # 3
f5(215) # "error"
f5(1.3) # MethodError
f5(0) # "error"
f5(-1) # "error"
ちゃんとした結果を返すプログラムを書くのは,けっこう大変ですね。
(2) 2番目の関数はfill(3,4)では?
Juliaが配列の未定義の添え字を与えたときにどう動作するのかはわかりませんが
(3) Juliaでどう書くのかわかりませんが、整数型割り算(実は単なる割り算でもOK)の商が正であるという論理式の和にするとか? それでも215以上でも3が返りますが。Rだと
f5 <- function(N) { (N %/% 1 > 0) + (N %/% 126 > 0) + (N %/% 211 > 0) }