【ゆる募】1~100までの整数が奇数かどうかを判定するプログラム大喜利を開催します☺ 言語不問✨ https://x.com/arith_rose/status/1899300131658510802
とのことで、Rで書いてみましょう。模範解答……?ナニソレオイシイノ?
まずは解答例に近い感じで!
matchがないならswitchすればいいじゃない!
解答例はPythonでmatch文を使ってますが、Rで近しいswitch
関数を使うとこんな感じでしょうか。冗長さもさることながら、Rのswitch
関数は文字列一致判定をすること、ベクトル化されていないことなど、イマイチ感爆発でステキです!
is_odd <- function(x) {
switch(as.character(x),
"1" = TRUE,
"3" = TRUE,
"5" = TRUE,
"7" = TRUE,
"9" = TRUE,
"11" = TRUE,
"13" = TRUE,
"15" = TRUE,
"17" = TRUE,
"19" = TRUE,
"21" = TRUE,
"23" = TRUE,
"25" = TRUE,
"27" = TRUE,
"29" = TRUE,
"31" = TRUE,
"33" = TRUE,
"35" = TRUE,
"37" = TRUE,
"39" = TRUE,
"41" = TRUE,
"43" = TRUE,
"45" = TRUE,
"47" = TRUE,
"49" = TRUE,
"51" = TRUE,
"53" = TRUE,
"55" = TRUE,
"57" = TRUE,
"59" = TRUE,
"61" = TRUE,
"63" = TRUE,
"65" = TRUE,
"67" = TRUE,
"69" = TRUE,
"71" = TRUE,
"73" = TRUE,
"75" = TRUE,
"77" = TRUE,
"79" = TRUE,
"81" = TRUE,
"83" = TRUE,
"85" = TRUE,
"87" = TRUE,
"89" = TRUE,
"91" = TRUE,
"93" = TRUE,
"95" = TRUE,
"97" = TRUE,
"99" = TRUE,
FALSE
)
}
is_odd(1)
#> [1] TRUE
is_odd(2)
#> [1] FALSE
ベクトルの要素を取り出すと簡単にcaseっぽいことできるんだぜ?
これならベクトル化もしてるしなと、Rチョトワカル風を漂わせていていいですね。
100より大きな数値を与えるとNA
を返すのでいけてる実装かも……?と思いきや、is_odd(-1)
やis_odd(1.1)
するとたいへんにバグりちらかしております。
is_odd <- function(x) {
yes <- c(
TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
)
yes[x]
}
is_odd(1:10)
#> [1] TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE
is_odd(101)
#> [1] NA
is_odd(1.1)
#> [1] TRUE
is_odd(-1) # 長さ99のベクトルになる
#> [1] FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE
#> [13] FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE
#> [25] FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE
#> [37] FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE
#> [49] FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE
#> [61] FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE
#> [73] FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE
#> [85] FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE
#> [97] FALSE TRUE FALSE
もう少し短かく書くなら、rep
を使うといいでしょう。
is_odd <- function(x) {
rep(c(TRUE, FALSE), 50)[x]
}
Rらしく書いてみよう
奇数の集合のいずれかに一致するか見ればいいよね!
ここらで解答例から離れて遊んでみましょう。
1:100までの整数を2行に並べたら、1行目は奇数になるので、それと一致するかどうかを見ればいいですね。よく考えているようで、any
を使っているせいで、x
に長さ1以外のベクトルを使うとバグります。
is_odd <- function(x) {
any(x == matrix(1:100, nrow = 2)[1, ])
}
is_odd(1)
#> [1] TRUE
is_odd(c(1, 2))
#> [1] TRUE
奇数の集合に含まれるか見ればいいよね!
さっきよりもスマート。
seq
を使うことで、余計なデータを発生させず、%in%
を使うことでx
に長さ1以外のベクトルを使っても大丈夫です。
is_odd <- function(x) {
return(x %in% seq(1, 100, by = 2))
}
is_odd(1)
#> [1] TRUE
is_odd(1:10)
#> [1] TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE
問題文をよく読もう!
真っ当な実装!だけど忠実すぎるぜ!
奇数かどうかの判定なら、2で割った余りが1かどうか見ればOKですね。真っ当な実装です。
ところが、問題文に従って、x
の要素が1つでも1~100の整数という条件に従わない時にエラーを出しています。忠実すぎて余計なお世話ですね。
is_odd
という関数名としては余計なお世話ですが、実際のプロダクトでは要件次第で入りうるバリデーションでもあります。
is_oidd <- function(x) {
if (any(x < 1 | x > 100 | floor(x) != x)) {
stop("1~100の整数を入力してください")
}
return(x %% 2 == 1)
}
is_odd(1)
#> [1] TRUE
is_odd(c(-1, 1))
#> [1] FALSE TRUE
is_odd(c(1, 101))
#> [1] TRUE FALSE
is_odd(0.1)
#> [1] FALSE
判定しろとは言うが、形式は指定してないよな!
ひたすら文字列をprint
してお知らせします。使いにくいわ!
is_odd <- function(x) {
for (ok in x %% 2 == 1) {
if (ok) {
print("そうだよ")
} else {
print("ちがうよ")
}
}
}
is_odd(1:10)
#> [1] "そうだよ"
#> [1] "ちがうよ"
#> [1] "そうだよ"
#> [1] "ちがうよ"
#> [1] "そうだよ"
#> [1] "ちがうよ"
#> [1] "そうだよ"
#> [1] "ちがうよ"
#> [1] "そうだよ"
#> [1] "ちがうよ"
ENJOY!!
たまにこうして遊ぶと、Rの楽しさを再認識しますね!
たいへんにoddなコードをたくさん書けて楽しかったです!
ふざけてはいるのですが、テストケースの考えかたや、要件の整理など、プログラミングに重要な要素がいっぱい詰まった良問と思いました!