Open8

IDの下一桁の判定

MzRyuKaMzRyuKa

任意の値の下一桁を取り出し、その値が「アタリ/ハズレ」を判定するようなプログラムを書いてみる。
前提条件:

  • 任意の値は「数字(0-9)」で成立する
  • アタリ/ハズレの数値は、都度変更が発生するので、引数で渡す
  • アタリ:true、ハズレ:false
MzRyuKaMzRyuKa

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]
MzRyuKaMzRyuKa

というか、アタリの数字は文字列で持っているから、わざわざ配列にしないで文字列中に含まれているかどうかで判断すれば良いか。
こっちの場合は、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]

MzRyuKaMzRyuKa

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]" 
MzRyuKaMzRyuKa

そういえば、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]" 
MzRyuKaMzRyuKa

// 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
}

MzRyuKaMzRyuKa

Gleamでgleam/erlang/osを使うには、gleam_erlangのaddが必要。(デフォルトで使えないんかー)

gleam add gleam_erlang