0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Go で ABC126 B - YYMM or MMYY を解いてみた

Posted at

Go で ABC126 B - YYMM or MMYY を解いてみました。

問題

問題文

長さ 4 の数字列 S が与えられます。あなたは、この数字列が以下のフォーマットのどちらであるか気になっています。

  • YYMM フォーマット: 西暦年の下 2 桁と、月を 2 桁で表したもの (例えば 1 月なら 01) をこの順に並べたもの
  • MMYY フォーマット: 月を 2 桁で表したもの (例えば 1 月なら 01) と、西暦年の下 2 桁をこの順に並べたもの
    与えられた数字列のフォーマットとして考えられるものが YYMM フォーマットのみである場合 YYMM を、 MMYY フォーマットのみである場合 MMYY を、 YYMM フォーマット と MMYY フォーマットのどちらの可能性もある場合 AMBIGUOUS を、 どちらの可能性もない場合 NA を出力してください。

制約

S は長さ 4 の数字列

( https://atcoder.jp/contests/abc126/tasks/abc126_b より引用)

考え方

問題文にあるとおりの条件式を書いて判定するだけですが、コンテスト本番で2回WAを出してしまいました(条件式の構成は苦手です)。

上位2桁と下位2にわけて考えると、まず、それぞれの2桁がYYになりうるか、MMになりうるか、を判定する必要があります。

  • YYについては、2桁のすべての組み合わせ、 00 から 99 まで、YY として正しいYY表記である。
  • MM については文字列ではなく数値として解釈した場合に、 $ 1 \le MM \le 12 $ を満たしているときのみ正しいMM表記であり、満たさない場合、つまり 0 および $ 13 \le M $ の場合には MM 表記としては不正。

よって、 2つの2桁について、MM の場合のみ判定すればOKです。

さらに、最終的な答えを出すには YYMM 表記なのか MMYY 表記なのか、 どちらにもなりうる(AMBIGUOUS)のか、どちらもありえないのか(NA) の4パターンで判定する必要があります。

愚直に上位2桁がMMになりうるかを見て、下位2桁がMMになりうるか/そうでないか、……とやると、次のようなコードになります。

func main() {
	defer stdout.Flush()
	S := readInt()
	H := S / 100
	L := S % 100

	if mm(H) {
		if mm(L) {
			println("AMBIGUOUS")
		} else {
			println("MMYY")
		}
	} else {
		if mm(L) {
			println("YYMM")
		} else {
			println("NA")
		}
	}
}

func mm(a int) bool {
	if 1 <= a && a <= 12 {
		return true
	}
	return false
}

ですが、ここでは次のコードのように、「どちらにもなりうる(AMBIGUOUS)」のパターン、つまり上位下位どちらもMMになりうる場合をまず判定してしまうことで、ネストが減って少しだけ見通しがよくなります(条件判定部分のみ抜粋)。

	if mm(H) && mm(L) {
		println("AMBIGUOUS")
		return
	}
	if mm(L) {
		println("YYMM")
		return
	}
	if mm(H) {
		println("MMYY")
		return
	}
	println("NA")

提出コード

コンテストでは次のようなコードを書きました(抜粋)。全体はこちら
(コンテストでは↑のようなことをちゃんと考えて書けばよかったんですが、適当に書いた結果 1WA, サンプルを誤読して、 「00 だと YY 判定NG」と、ホントかよと思いつつ勘違いしてしまい1WAを食らってしまいました。提出コードには、その試行錯誤した痕跡が見られます。)

func main() {
	defer stdout.Flush()
	S := readInt()
	x := S / 100
	y := S % 100
	//eprintln(x, y)
 
	if mm(x) && yy(y) && yy(x) && mm(y) {
		println("AMBIGUOUS")
		return
	}
	if yy(x) && mm(y) {
		println("YYMM")
		return
	}
	if mm(x) && yy(y) {
		println("MMYY")
		return
	}
	println("NA")
}
 
func mm(a int) bool {
	if 1 <= a && a <= 12 {
		return true
	}
	return false
}
 
func yy(a int) bool {
	return true
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?