2
1

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 1 year has passed since last update.

ABC285 C問題:ゼロを使わないN進法についてのメモ

Last updated at Posted at 2023-01-16

上の問題で、表計算ソフトの列番号によくある A, B, … , Z, AA, … といった文字列が何番目を指すのかを問われた。

何となく A → 1, B → 2, … , Z → 26 と「ゼロを抜いて各文字に番号を振った」うえで「普通の26進法と同じ計算をした」ところ正答できた(試していたらできそうに見えただけで、何も証明していない)。しかし、普通は十進法なら 0 ~ 9 というようにゼロを入れて N は入れないはずで、この解き方はN進法のルールを破ってしまっている気がする。

convert.rb
def str2num(str)  # str = "BRUTMHYHIIZP"
	digits = str.bytes.map { |b| b - 0x40 }  #=> [2, 18, 21, 20, 13, 8, 25, 8, 9, 9, 26, 16]
	digits.inject(0) { |s, d| s * 26 + d }   #=> 10000000000000000
end

# おまけ:逆方向の変換
def num2str(num)  # num = 10000000000000000
	digits = []
	while num > 0
		num, d = (num - 1).divmod(26)
		digits << d + 1
	end
	digits = digits.reverse                 #=> [2, 18, 21, 20, 13, 8, 25, 8, 9, 9, 26, 16]
	digits.map { |d| d + 0x40 }.pack("C*")  #=> "BRUTMHYHIIZP"
end

調べたところ、各桁で 0 を使わず 1 ~ N を割り当てるようなN進法(位取り記数法)は "bijective base-N numeration" としてきちんとあるらしい。

  • 任意の自然数と文字列とが1対1対応する。(だから名前に「全単射」とある)
    • それに対して通常のN進法だと、ゼロ埋めしても同じ数値になるため1対1でない。
    • 同じ最大桁数であれば通常のN進法より多くの数値を表せる。
    • 空文字列を認めれば、数値のゼロも文字列で表せる。
  • 文字列から数値への変換は、通常のN進法と同じ式。
    • したがって表記中に 0 や N を含まない数は、通常版でも全単射版でも同じ数値を表す。
    • 数値から文字列への変換も、通常版の方法を僅かに変更すればできる。
  • 加算や乗算も、通常のN進法と同じ要領で筆算できる。(繰り上がりの処理でゼロの桁を作らないようにだけ注意)

証明にはならないが、十進法で実際に試してみれば妥当な雰囲気が掴める。


冒頭の問題が26進法でいけそうに見えたのは、 Z を含んでいないものは本当に通常の26進法と数値が一致するからかもしれない。

2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?