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?

【Project Euler】Problem 24: 辞書式順列

Last updated at Posted at 2022-01-13
  • 本記事はProjectEulerの「100番以下の問題の説明は記載可能」という規定に基づいて回答のヒントが書かれていますので、自分である程度考えてみてから読まれることをお勧めします。

問題 24. 辞書式順列

原文 Problem 24: Lexicographic permutations

問題の要約:0123456789を並べ替えたものを辞書式順列にしたとき$10^6$番目を求めよ

安易ですが、itertoolsのpermutationは「 iterable に応じた辞書式順序で出力されます」とのことなのでそのまま使えます。一応"012"で確認します。

import itertools
for n, perm in enumerate(itertools.permutations("012"),1): 
  print(f"{n}: {''.join(perm)}")
#1: 012
#2: 021
#3: 102
#4: 120
#5: 201
#6: 210

確認できたので、$10^6$番目の値を出力します。

import itertools
for n, perm in enumerate(itertools.permutations("0123456789"),1): 
  if n >= 10**6:
    break

print(f"Answer : {''.join(perm)}")

より効率の良い解答

さすがにこれではあまりにも安易なので問題を以下のように変更します。

問題 2.0123456789abcdefを並べ替えたものを16進数の辞書式順列にしたとき$10^{10}$番目を求めよ

こうなるとitertoolsのpermutationでは厳しいので工夫が必要になります。

考え方を最初の問題で説明します。最初の桁を例えば0に固定すると残りは9桁なので順列は$9!=362880$個あります。これを積算すると$10^6$番目は2で始まることが分かります。

従って2を除いた013456789を並べ替えたものを辞書式順列にしたときに$10^6-725760=274240$番目を求めて725760に足せばよいことになります。
これを再帰的に行えば答えが得られます。

最初の桁 順列の数 順列の数(積算)
0 $9!=362880$ $362880$
1 $9!=362880$ $725760$
2 $9!=362880$ $1088640 > 10^6$

以下のプログラムは16進数まで対応できるようにしました。

import math
B = 16
def lexn(N, dig, un):  # Remaing N, digit, Unused number
  result, total = "", 0
  for i in range(B):
    if un[i] == 0: continue
    d = math.factorial(dig-1)
    if total+d >= N:
      un[i] -= 1
      result = hex(i)[2] + lexn(N-total, dig-1, un)
      return result
    total += d
  return result

N = 10**10
print(f"Answer: {lexn(N, B, [1]*B)}")
# 013ae8c5dfb47692

(開発環境:Google Colab)

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?