IDの下一桁の判定
任意の値の下一桁を取り出し、その値が「アタリ/ハズレ」を判定するようなプログラムを書いてみる。
前提条件:
- 任意の値は「数字(0-9)」で成立する
- アタリ/ハズレの数値は、都度変更が発生するので、引数で渡す
- アタリ:true、ハズレ:false
Golangで書いてみる。
パッと思いついたのが、こんな感じ。
アタリの数字は文字列にしたが、環境変数や設定ファイルから読み込んだから、という想定のため。
そして、ありそうでなかった配列の要素に含まれているかの処理。
package main
import (
"fmt"
"strings"
"strconv"
)
const (
// カンマ区切りでアタリの数字を入れている
WINNING_NUMS_STR = "1,2,3,4,5"
)
func main() {
cardIdList := []int{12300, 12301, 12302, 12303, 12304, 12305, 12306, 12307, 12308, 12309}
for _, cardId := range cardIdList {
result := canWin(cardId, WINNING_NUMS_STR)
fmt.Printf("Can I win with this cardId [%v] ? : [%v]\n", cardId, result)
}
}
func canWin(cardId int, winningNums string) bool {
num := int(cardId % 10)
numStr := strconv.Itoa(num)
numStrList := strings.Split(winningNums, ",")
// カンマ区切りにアタリの数字が入っているため、カンマで区切って配列にする
// Golangではこの値が配列に含まれているか、を判定するメソッドがないのでforで回して判定
for _, n := range numStrList {
if numStr == n {
return true
}
}
return false
}
実行結果は以下
Can I win with this cardId [12300] ? : [false]
Can I win with this cardId [12301] ? : [true]
Can I win with this cardId [12302] ? : [true]
Can I win with this cardId [12303] ? : [true]
Can I win with this cardId [12304] ? : [true]
Can I win with this cardId [12305] ? : [true]
Can I win with this cardId [12306] ? : [false]
Can I win with this cardId [12307] ? : [false]
Can I win with this cardId [12308] ? : [false]
Can I win with this cardId [12309] ? : [false]
というか、アタリの数字は文字列で持っているから、わざわざ配列にしないで文字列中に含まれているかどうかで判断すれば良いか。
こっちの場合は、strings.Contains(確認する文字列, 含まれているか調べる文字列)
で、含まれていればtrue
、含まれていなければfalse
が得られる。
だから、こんな感じか。
package main
import (
"fmt"
"strings"
"strconv"
)
const (
WINNING_NUMS_STR = "1,2,3,4,5"
)
func main() {
cardIdList := []int{12300, 12301, 12302, 12303, 12304, 12305, 12306, 12307, 12308, 12309}
for _, cardId := range cardIdList {
result := canWin(cardId, WINNING_NUMS_STR)
fmt.Printf("Can I win with this cardId [%v] ? : [%v]\n", cardId, result)
}
}
func canWin(cardId int, winningNums string) bool {
num := int(cardId % 10)
contains := strings.Contains(winningNums, strconv.Itoa(num))
return contains
}
結果は同じ
Can I win with this cardId [12300] ? : [false]
Can I win with this cardId [12301] ? : [true]
Can I win with this cardId [12302] ? : [true]
Can I win with this cardId [12303] ? : [true]
Can I win with this cardId [12304] ? : [true]
Can I win with this cardId [12305] ? : [true]
Can I win with this cardId [12306] ? : [false]
Can I win with this cardId [12307] ? : [false]
Can I win with this cardId [12308] ? : [false]
Can I win with this cardId [12309] ? : [false]
Gleamで書いてみる。
なお、Gleam Playground上で実施したので、最新版で実施したのなら、もう少し簡単にできるのかも。
import gleam/io
import gleam/bool
import gleam/int
import gleam/string
import gleam/list
pub fn main() {
let winning_nums = "1,2,3,4,5"
let card_id_list = [12300, 12301, 12302, 12303, 12304, 12305, 12306, 12307, 12308, 12309]
let results = card_id_list |> list.map(can_win(_, winning_nums))
results
}
pub fn can_win(card_id: Int, winning_nums: String) -> Bool{
let num = card_id % 10
let num_s = int.to_string(num)
let result = string.contains(does: winning_nums, contain: num_s)
// PlayGroundのバージョンだと、bool.to_stringがないため、to_intで代わり
let result_str = int.to_string(bool.to_int(result))
let msg = string.concat(["Can I win with this cardId [", int.to_string(num), "] ? : [", result_str, "]"])
io.debug(msg)
result
}
実行結果がこっち。
ちなみに、True/Falseは数字変換すると1/0となる。
"Can I win with this cardId [0] ? : [0]"
"Can I win with this cardId [1] ? : [1]"
"Can I win with this cardId [2] ? : [1]"
"Can I win with this cardId [3] ? : [1]"
"Can I win with this cardId [4] ? : [1]"
"Can I win with this cardId [5] ? : [1]"
"Can I win with this cardId [6] ? : [0]"
"Can I win with this cardId [7] ? : [0]"
"Can I win with this cardId [8] ? : [0]"
"Can I win with this cardId [9] ? : [0]"
そういえば、Gleamのパイプ演算子の個々の部分でm
card_id_list |> list.map(can_win(_, winning_nums))
mapから渡される値を「_
」で表現しているのかな?
※ruby で言うところの、|card_id|
の部分。
card_id_list.map do |card_id|
can_win(card_id, winning_nums)
end
試しに、関数can_win
の第一引数と第二引数を入れ替えてみた。
pub fn can_win(winning_nums: String, card_id: Int) -> Bool{
呼び出し元も修正
let results = card_id_list |> list.map(can_win(winning_nums, _))
実行してみると、うまく行った様子
"Can I win with this cardId [0] ? : [0]"
"Can I win with this cardId [1] ? : [1]"
"Can I win with this cardId [2] ? : [1]"
"Can I win with this cardId [3] ? : [1]"
"Can I win with this cardId [4] ? : [1]"
"Can I win with this cardId [5] ? : [1]"
"Can I win with this cardId [6] ? : [0]"
"Can I win with this cardId [7] ? : [0]"
"Can I win with this cardId [8] ? : [0]"
"Can I win with this cardId [9] ? : [0]"
// PlayGroundのバージョンだと、bool.to_stringがないため、to_intで代わり
ローカル環境で、2022/5/29の最新v.0.21.0
で確認してみた。
結果、bool.to_string
が使えたので、関数can_win
は以下のようにできる。
pub fn can_win(card_id: Int, winning_nums: String) -> Bool {
let num = card_id % 10
let num_s = int.to_string(num)
let result = string.contains(does: winning_nums, contain: num_s)
// v0.21.0なら、bool.to_stringが使える
let result_str = bool.to_string(result)
let msg =string.concat([ "Can I win with this cardId [",int.to_string(num),"] ? : [",result_str,"]",])
io.debug(msg)
result
}
Gleamで環境変数を取るときはこれか。
値が無効な場合のデフォルト値としてresult.unwrap
を利用するので、メモx2
gleam/erlang/os
となっているから、erlang
に依存しているのね。
let port =
os.get_env("PORT")
|> result.then(int.parse)
|> result.unwrap(3000)
Gleamでgleam/erlang/os
を使うには、gleam_erlang
のaddが必要。(デフォルトで使えないんかー)
gleam add gleam_erlang