質問するログイン新規登録
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

4回答

385閲覧

Atcoderの競技プログラミングの鉄則問題A04でのBinary Representation 1の実装方法が分からない

TMYchan

総合スコア0

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2025/09/06 07:25

0

0

実現したいこと

整数を入力した値に対して二進数に変換をしたい。また桁数10になのであまった位には0を追加する

前提

問題文
整数 N が 10 進法表記で与えられます。N を 2 進法に変換した値を出力するプログラムを作成してください。

制約
N は 1 以上 1000 以下の整数

■■な機能を実装中に以下のエラーメッセージが発生しました。

該当のソースコード

python

1N = int(input()) 2count = 10 3ans = [] 4while N != 0: 5 ad = N%2 6 N = N//2 7 ans.insert(0,ad) 8 count -=1 9 print(ans) 10 11for i in range(count): 12 ans.insert(0,0) 13print(ans) 14num = ''.join(map(str, ans)) 15print(num) 16

補足情報(FW/ツールのバージョンなど)

OS 名 Microsoft Windows 11 Home

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hiroki-o

2025/09/06 07:38

仕様通り動いているようですが、競技プログラミングとしての改善点を教えてほしいという質問ですか?
TMYchan

2025/09/12 03:16

返信が遅くなり申し訳ございません。おっしゃる通りです。
guest

回答4

0

整数を入力した値に対して二進数に変換をしたい。
また桁数10なのであまった位には0を追加する

桁数が固定(10桁)なら,for ループを使った方がわかり易いかもしれません。
記述例を下記に示します。

Python

1N = 1000 2digit = 10 3 4n, lst = N, [] 5for i in range(digit): 6 lst.append(n % 2) 7 n //= 2 8 9bin_str = ''.join(str(i) for i in reversed(lst)) 10print(bin_str) 11# 1111101000

投稿2025/09/07 13:32

little_street

総合スコア507

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TMYchan

2025/09/12 03:25

上記の点で一部N=int(input())をして提出したのですが、Atcoderの結果はREになってしましいました。理由はなぜでしょうか?
little_street

2025/09/12 06:34

参考になると良いのですが,「N = int(input())」に変更して「提出」した結果は下記でした。 ----- コード長: 176 Byte 結果: AC 実行時間: 11 ms メモリ: 8744 KiB -----
YellowGreen

2025/09/12 21:56

> 理由はなぜでしょうか? N = int(input()) の次の行に digit = 10 の行がないからではないでしょうか
guest

0

9行目、13行目に、デバッグ出力用のprint(ans)が残っているのが原因ではないでしょうか。これらを削除してみてください。

投稿2025/09/06 21:15

actorbug

総合スコア2546

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TMYchan

2025/09/12 03:26

すみません。こちらのデッバクを変更しても結果はREのままでした。解決策は他にもありますでしょうか?
actorbug

2025/09/12 23:47 編集

REになると言っているのは、こちらの提出結果のことでしょうか。あなたの提出結果で、A04に対しREとなっているのは、こちらしかありませんでした(2025/9/13現在)。 https://atcoder.jp/contests/tessoku-book/submissions/69234512 もしそうなら、元のコードから大幅に修正されており、私の回答を参考に書かれたものとは思えません。
guest

0

Pythonの場合、bin()int.bit_length() が用意されていますので、それらを利用すると以下の様に書くことができます。

python

1N = int(input()) 2count = 10 3bin_str = '0'*(count - N.bit_length()) + bin(N)[2:] 4print(bin_str)

もしくは f-strings を利用します。参考にしてみてください。

python

1N = int(input()) 2print(f'{N:010b}')

投稿2025/09/06 08:12

編集2025/09/06 09:02
melian

総合スコア21449

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TMYchan

2025/09/12 04:00

すみません。今回の問題はなぜ文字列が利用できたのでしょうか?問題のどこかに記載していましたでしょうか? 後メンション機能はどうすればできますでしょうか?
melian

2025/09/12 04:34

問題には記載されていませんが、おそらく出題側は Python に f-strings(フォーマット済み文字列リテラル)があるのを知らないか、もしくは2進数表記用の書式("b")があることを知らなかったのかもしれません。メンション機能に関しては、Teratail には明示的なものはないと思います。(質問者であるTMYchanさんのコメントが付いた旨の通知とメールが届いています)
guest

0

この問題に特化した解はMelian氏が提示した解以上のモノは得られないと思う。

値を出力するプログラム

と言われてる以上、Pythonのファンシーな機能を使って、文字列を生成する以上に上手いテはない。
非常に直接的な解だと思う。

そこでここでは、もうちょっと一般化したユーティリティ作成を紹介しようと思う。

Python

1#!/usr/bin/env python3 2 3class unfoldr(object): 4 def __init__(self, f, seed): 5 self.f = f 6 self.seed = seed 7 def __iter__(self): 8 return self 9 def __next__(self): 10 match self.f(self.seed): 11 case a, b: 12 self.seed = b 13 return a 14 case None: 15 raise StopIteration 16 17if __name__ == '__main__': 18 ans = ''.join(reversed(list(unfoldr(lambda N: None if N == 0 \ 19 else (str(N % 2), N // 2), int(input()))))) 20 print('0' * (10 - len(ans)) + ans) 21 22

ここで作成したイテレータunfoldrは、Python組み込みのイテレータrangeの亜種だ。
と言うより、rangeの上位互換だ。

Python

1>>> [i for i in range(3)] 2[0, 1, 2] 3>>> [i for i in unfoldr(lambda x: None if x == 3 else (x, x + 1), 0)] 4[0, 1, 2] 5

従って、単純には、rangeunfoldrを利用すると次のように書ける。

Python

1def range(*args): 2 match args: 3 case stop,: 4 return unfoldr(lambda x: None if x >= stop else (x, x + 1), 0) 5 case start, stop: 6 return unfoldr(lambda x: None if x >= stop else (x, x + 1), start) 7 case start, stop, step: 8 return unfoldr(lambda x: None if x >= stop else (x, x + step), start) 9

unfoldrrangeの上位互換な故、unfoldrの機能を制限する事でrangeが書けるわけだ。

unfoldrHaskellと言うプログラミング言語のunfoldrをPython向けに移植したモノだ。
unfoldrは引数を2つ取り、第一引数は関数、第二引数に「シード」と呼ばれる単一の値(データ)を取る。
ここで第一引数で取る関数のカタチが特徴的だ。ここではラムダ式を使うが、作成すべき関数は次のルールに従う。

Python

1lambda x: None if 終了条件 else (取り出す値, 次のシード)

何らかの終了条件を満たせばNoneを返すようにすること。そうじゃなければタプルを返すように書く。
そのタプルは2要素のタプルで、第一要素は生成するリストの要素、第二要素は「シードをどう加工してゆくか」の情報になっている。
結果、unfoldrは初期値として与えられたシードから粛々とリストの要素を生成していって、最終的にリスト(このコードだと正確にはリストを生成するイテラブル)を返すわけだ。

Python

1## 2 乗のリスト 1^2 ... 10^2 2>>> list(unfoldr(lambda x: None if x > 10 else (x * x, x + 1), 1)) 3[1, 4, 9, 16, 25, 36, 49, 64, 81, 100] 4

見方によっては、unfoldrリスト内包表記/maprangeの合わせ技を一つでやり抜く為のイテレータに見えるだろう。

Python

1>>> [i ** 2 for i in range(1, 11)] 2[1, 4, 9, 16, 25, 36, 49, 64, 81, 100] 3>>> list(map(lambda x: x ** 2, range(1, 11))) 4[1, 4, 9, 16, 25, 36, 49, 64, 81, 100] 5

いずれにせよ、unfoldrはかなり便利な汎用的なユーティリティとなる。
例えば題意に沿うと、基本的には次のように一行で書いて結果のリストを得る。

Python

1>>> list(unfoldr(lambda x: None if x == 0 else (x % 2, x // 2), 13)) 2[1, 0, 1, 1] 3>>> list(unfoldr(lambda x: None if x == 0 else (x % 2, x // 2), 37)) 4[1, 0, 1, 0, 0, 1] 5>>> list(unfoldr(lambda x: None if x == 0 else (x % 2, x // 2), 1000)) 6[0, 0, 0, 1, 0, 1, 1, 1, 1, 1] 7

これらは「逆順のリストになる」んで、ちょっとしたデータ変換で文字列を得ることが出来るだろう。

Python

1>>> ''.join(reversed(list(unfoldr(lambda x: None if x == 0 else (str(x % 2), x // 2), 13)))) 2'1101' 3>>> ''.join(reversed(list(unfoldr(lambda x: None if x == 0 else (str(x % 2), x // 2), 37)))) 4'100101' 5>>> ''.join(reversed(list(unfoldr(lambda x: None if x == 0 else (str(x % 2), x // 2), 1000)))) 6'1111101000' 7

このunfoldrの実装はrangeと同様のイテレータだが、rangeと違って直接reversed出来ない。
結果、list化した上でreversedして更に・・・とひと手間かかる。
人によっては「そもそもunfoldrイテレータに__reversed__特殊メソッドを組み込むべきじゃない?」って言うだろう。
ただし、unfoldrは第一引数に与える関数が終了条件を持たない場合、無限長リスト(要はこれもイテラブル)を返すようになっている。無限長リストが返る可能性があるなら、直接reversedが出来るのは危険だ。
よって、手間でも、キチンと有限長になる事を確認してからlist化してreversedした方が安全だろう。

Python

1#!/usr/bin/env python3 2 3import sys 4from itertools import islice 5 6class unfoldr(object): 7 def __init__(self, f, seed): 8 self.f = f 9 self.seed = seed 10 def __iter__(self): 11 return self 12 def __next__(self): 13 match self.f(self.seed): 14 case a, b: 15 self.seed = b 16 return a 17 case None: 18 raise StopIteration 19 20# わざと終了条件を与えず、無限長の素数列を得る例 21def primes(): 22 yield 2 23 for p in unfoldr(isPrime, 3): 24 yield p 25 26def isPrime(n): 27 while True: 28 for p in primes(): 29 if p ** 2 > n: 30 return n, n + 2 31 elif n % p == 0: 32 n += 2 33 break 34 35 36if __name__ == '__main__': 37 print(list(islice(primes(), int(sys.argv[1])))) 38

いずれにせよ、Pythonにunfoldrと言うユーティリティを備えとけば色々と便利だし、ある種、汎用アルゴリズムらしい抽象的アルゴリズムだ。

そんなカンジかな。
以上。

投稿2025/09/07 17:56

編集2025/09/08 22:38
cametan

総合スコア209

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.30%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問