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?

【Python3】解説【電脳少女プログラミング2088 ─壊レタ君を再構築─】「廃マンションの一室」

Posted at

paizaの新作プログラミングゲーム【電脳少女プログラミング2088 ─壊レタ君を再構築─】廃マンションの一室(paizaランク:C相当)をPython3で実装しました。

数学苦手な僕が数学苦手な方のために解説しようとおもいます。


問題

こういう問題

image.png
ということです。

と…特殊な三進法??

通常の三進法 特殊な三進法
[0, 1, 2] [-1, 0, 1]

特殊な三進法では2の代わりに-1を使います。

10進法→通常の3進法

割り算と余りを使って商が3で割り切れなくなるまで繰り返します。
で、割り切れなくなったら余り部分を下から上に読んでいきます。

例:157(問題で入力される値なので)
image.png

計算 余り (3進数の桁)
157 ÷ 3 = 52 ... 1 52 1
52 ÷ 3 = 17 ... 1 17 1
17 ÷ 3 = 5 ... 2 5 2
5 ÷ 3 = 1 ... 2 1 2
1 ÷ 3 = 0 ... 1 0 1 ここから上に読んでいく

答え:12211

となります。

3進法→10進法に直すときは?

各桁の値を3のn乗したものを足していきます。(^は累乗を表します。)

桁の値 対応する指数 (n) 計算式 結果
1 4 1 × 3^4 = 81 81
2 3 2 × 3^3 = 54 54
2 2 2 × 3^2 = 18 18
1 1 1 × 3^1 = 3 3
1 0 1 × 3^0 = 1 1
合計 157

10進法→特殊な三進法は?

まずは計算の流れから

計算 余り バランス3進法の桁 繰り上げ調整 最終桁(余り)
157 ÷ 3 = 52 ... 1 52 1 1 なし 1
52 ÷ 3 = 17 ... 1 17 1 1 なし 1
17 ÷ 3 = 5 ... 2 5 2 -1     商+1 (6) 2
6 ÷ 3 = 2 ... 0 2 0 0 なし 0
2 ÷ 3 = 0 ... 2 0 2 -1     商+1 (1) 2
1 ÷ 3 = 0 ... 1 0 1 1 なし 1

考え方:
余りが2(-1として扱う)の場合に、マイナスされた分を
次に計算される商に+1(余りを1増やす)をして差分を埋めます。

何を言ってるかというと...

2の表し方って 2 = 3 + (-1) も同じだよね?ってことです。
5の表し方って 5 = 3 + 2 = 9 + (-3) + (-1) も同じだよね?ってことです。

マイナスされた桁は次の桁で取り返す!!

5(10進数)の計算 余り(特殊な3進数表記) 10進数表記 繰り上げ
5 ÷ 3 = 1 ... 2 1 2 -1 余り2なので商に+1をして2にする
2 ÷ 3 = 0 ... 2 0 2 -3 余り2なので商に+10にして1にする
1 ÷ 3 = 0 ... 1 0 1 9

なんとなくわかってきました?

なので今回やりたいことは

通常の10進法→3進法の処理をしていく中で、余りが2(-1として扱う)の場合に、次の商を+1するようにコードを書いてみよう!

・通常の10進法→3進法の処理
・余りが2の場合、商を+1する

一旦ここで読むのを止めて実装してみてください。
実装できれば...
image.png
^^

どうしても分からない方は下にコードを示すので、正解を基に落とし込んでください。

通常の10進法→3進法の処理

N = int(input())

mod_list = []
while N :
    mod_num = N % 3
    mod_list.insert(0, mod_num) 
    if mod_num == 2:
        N += 1
    N //= 3
print("".join(map(str ,mod_list)))

余りが2の場合、商を+1する

if mod_num == 2:
    N += 1

がっちゃんこコード

N = int(input()) #入力値

mod_list = [] #余りを入れる用
while N : #Nが0になるまでループ
    mod_num = N % 3 #ここで余りを出す
    mod_list.insert(0, mod_num) #mod_listの先頭に余りを入れる(余りは下から上に読むため)
    if mod_num == 2: #もし余りが2なら
        N += 1 #商を+1します
    N //= 3 ##小数点切り捨てる割り算をする
print("".join(map(str ,mod_list)))

まとめ

Cランクというから安易に手を出したけど、
初めは分からな過ぎてAランクぐらいあるだろうって思ってましたけど
考え方のところさえクリアできればコーディング内容自体はCランクで妥当なのかなって思います。
10進数から2進数の変換方法すら分からなかったので調べましたし....

適当な理解で済ませたくない方は、平衡三進法と呼ばれるものらしいので調べてみてください。

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?