Parasitic number (寄生数) について

Parasitic number (寄生数) あるいは Dyson numbers (ダイソン数) という言葉を目にしたことがありますか？
この記事では，以下のページで紹介されている寄生数とダイソン数を日本語で紹介します．

https://en.wikipedia.org/wiki/Parasitic_number

2025年1月現在，寄生数に言及した日本語の記事は，以下の1件しか見つかりませんでした．

https://qiita.com/gushwell/items/914304c054ad7bbef048

この記事は，日本語で寄生数について言及した2件目の記事，ダイソン数について言及した初の記事ではないかと考えています．
日本語で書かれた論文やwebページ，書籍等の情報をお持ちでしたら，コメントにてお知らせください．

# Parasitic number (寄生数) の定義
ある正の整数$x$を$N$倍した値と，$x$を右へ1桁循環シフトした値が等しいとき，$x$を「N-Parastic Number」という．ただし，$N$は，1から9までの整数とする．

これが，寄生数の基本定義です．
10進数以外に拡張して適用できますが，ここでは考えません．
$x$を正の整数，$N$を1から9までの整数に限定して，議論を進めます．

例を挙げます．$x=128205$は，4-Parastic Numberです．
何故なら，$4\times128205=512820$であり，`circshift(128205, 1)` ⇒ $512820$となるからです．

一方で，ほとんどの数学者は，先頭の$0$の使用を認めていません．
そのため，一般に$x=25641$は，4-Parastic Number**ではありません**．
（$4\times025641=102564$，`circshift(025641, 1)` ⇒ $102564$は認めない）

# Dyson numbers (ダイソン数) 
無限個ある寄生数の内，最小の$N$-Parastic Numberをダイソン数と言います．
[フリーマン・ダイソン](https://ja.wikipedia.org/wiki/%E3%83%95%E3%83%AA%E3%83%BC%E3%83%9E%E3%83%B3%E3%83%BB%E3%83%80%E3%82%A4%E3%82%BD%E3%83%B3)が名前の由来であり，合計で9個存在します．

|$n$|ダイソン数（最小の$N$-Parastic Number）|桁数|
|:-|:-|-:|
|1|1|1|
|2|105263157894736842|18|
|3|1034482758620689655172413793|28|
|4|102564|6|
|5|142857|6|
|6|1016949152542372881355932203389830508474576271186440677966|58|
|7|1014492753623188405797|22|
|8|1012658227848|13|
|9|10112359550561797752808988764044943820224719|44|

$N=6$のダイソン数は，101.7阿僧祗（あそうぎ）という，とても大きな値になります．

# N-寄生数の判定
プログラムで$N$-寄生数を判定する方法ですが，数字が小さい場合は，難しくありません．
MATLABなら，数字を文字列に変換したうえで，[circshift](https://jp.mathworks.com/help/matlab/ref/circshift.html) 関数を使えば良いです．

```MATLAB:isParasitic.m
function tf = isParasitic(x, n)
    tf = n * x == str2num(circshift(num2str(x), 1));
%   tf = strcmp(num2str(n * x), circshift(num2str(x), 1));
end
```
2つの値が一致するか判定するには，値を数字もしくは文字列として揃える必要があります．

$N=6$のダイソン数のような大きな値は，一般に文字列として与えられ，そのままでは数値に変換できません．
そのため，文字列の一部分を数値に変換して計算する処理を繰り返す必要があります．

```MATLAB:isParasitic2.m
function tf = parasitic2(x_str,n)
    result = []; % 計算結果
    carry = 0;   % 繰り上がり用変数

    for i = length(x_str) : -1 : 1
        v = n * str2num(x_str(i)) + carry;
        result = [mod(v, 10), result];
        carry = floor(v / 10); % 繰り上がり更新
    end
    tf = all(result == circshift(x_str, 1) - '0');
end
```

最初に循環シフトした結果を用意しておき，各桁で値の一致を確認する方法もあります．

```MATLAB:isParasitic3.m
function tf = parasitic3(x_str,n)
    tf = false;
    a = circshift(x_str, 1) - '0'; % 循環シフトした結果
    carry = 0;                     % 繰り上がり用変数

    for i = length(x_str) : -1 : 1
        v = n * str2num(x_str(i)) + carry;
        if mod(v, 10) ~= a(i) % i桁目の一致確認
            return;
        end
        carry = floor(v / 10); % 繰り上がり更新
    end
    tf = true;
end
```

# N-寄生数の生成
$N$と寄生数の1桁目(右端)の値$k$を指定することで，$N$-寄生数を生成できます．
MATLABでは，以下のプログラムで$N$-寄生数を生成できます．

```MATLAB:generateParasitic.m
function y = generateParasitic(k, n)
    y = num2str(k); % 初期値
    carry = n * k;  % 繰り上がり用変数
    while carry ~= k
        y = [num2str(mod(carry, 10)), y];              % 新しい桁を追加
        carry = n * str2num(y(1)) + floor(carry / 10); % 繰り上がり更新
    end
end
```

$N$と$k$に対応する寄生数を表にまとめると，以下のようになります．

|$N$|$k=1$|$k=2$|$k=3$|$k=4$|$k=5$|$k=6$|$k=7$|$k=8$|$k=9$|
|:-:|-:|-:|-:|-:|-:|-:|-:|-:|-:|
|1|1|2|3|4|5|6|7|8|9|
|2|052631578947368421|105263157894736842|157894736842105263|210526315789473684|263157894736842105|315789473684210526|368421052631578947|421052631578947368|473684210526315789|
|3|0344827586206896551724137931|0689655172413793103448275862|1034482758620689655172413793|1379310344827586206896551724|1724137931034482758620689655|2068965517241379310344827586|2413793103448275862068965517|2758620689655172413793103448|3103448275862068965517241379|
|4|025641|051282|076923|102564|128205|153846|179487|205128|230769|
|5|020408163265306122448979591836734693877551|040816326530612244897959183673469387755102|061224489795918367346938775510204081632653|081632653061224489795918367346938775510204|102040816326530612244897959183673469387755|122448979591836734693877551020408163265306|142857|163265306122448979591836734693877551020408|183673469387755102040816326530612244897959|
|6|0169491525423728813559322033898305084745762711864406779661|0338983050847457627118644067796610169491525423728813559322|0508474576271186440677966101694915254237288135593220338983|0677966101694915254237288135593220338983050847457627118644|0847457627118644067796610169491525423728813559322033898305|1016949152542372881355932203389830508474576271186440677966|1186440677966101694915254237288135593220338983050847457627|1355932203389830508474576271186440677966101694915254237288|1525423728813559322033898305084745762711864406779661016949|
|7|0144927536231884057971|0289855072463768115942|0434782608695652173913|0579710144927536231884|0724637681159420289855|0869565217391304347826|1014492753623188405797|1159420289855072463768|1304347826086956521739|
|8|0126582278481|0253164556962|0379746835443|0506329113924|0632911392405|0759493670886|0886075949367|1012658227848|1139240506329|
|9|01123595505617977528089887640449438202247191|02247191011235955056179775280898876404494382|03370786516853932584269662921348314606741573|04494382022471910112359550561797752808988764|05617977528089887640449438202247191011235955|06741573033707865168539325842696629213483146|07865168539325842696629213483146067415730337|08988764044943820224719101123595505617977528|10112359550561797752808988764044943820224719|

$N=5$以外の場合，$k=N$を指定すると，ダイソン数（最小の$N$-寄生数）が生成されます．
$N=5$の場合，$k=7$を指定すると，ダイソン数 $142857$ が生成されます．

$k<N$の場合，出力される数字の先頭は$0$になります．
そのため，一般に$k<N$を満たす寄生数は存在しないと言われます．

寄生数を連結した数も寄生数になります．
そのため，11，111，128205128205，142857142857なども寄生数になります．

# N-寄生数の手計算（入試問題？）
寄生数という言葉を使わず，小学校までの算数知識で解ける問題を考えてみました．
以下のような問題が中学，高校，大学入試で出題されている可能性があるなと思いました．
入試問題風に$N$-寄生数の手計算をしてみます．

## 問題
ある正の整数$x$について，以下がわかっている．
* $x$の1桁目の数字は7である
* $x$を$N$倍した値 ($N\times x$) は，$x$を右へ1桁循環シフトした値に等しい

例）$N=5$の時，$x=142857$である．
($5\times142857=714285$，142857 ⇒ 14285 7 ⇒ 7 14285 ⇒ 714285)

$N=4$の時，$x$を求めよ．

## 解答
$x$を$N=4$倍した数を考えると，その1桁目の値は8になる． ($4\times7=28$)
そのため，$x$の2桁目の値も同様に8となる． (右へ1桁循環シフトした時の1桁目の値が8のため)
$x$の下2桁の値が$87$となるため，$x$を$N=4$倍した数の下2桁は$48$になる． ($4\times87=348$)
以上の処理を同様に繰り返すと，以下のような計算ができる．

```
 (1)  4 * ______7 = ______8
 (2)  4 * _____87 = ______8
 (3)  4 * _____87 = _____48
 (4)  4 * ____487 = _____48
 (5)  4 * ____487 = ____948
 (6)  4 * ___9487 = ____948
 (7)  4 * ___9487 = ___7948
 (8)  4 * __79487 = ___7948
 (9)  4 * __79487 = __17948
(10)  4 * _179487 = __17948
(11)  4 * _179487 = _717948
```
ここで，$717948$は$179487$を右へ1桁循環シフトした値に等しい．
以上より，**A. $x=179487$.**

# 終わりに
Parasitic number (寄生数)とDyson numbers (ダイソン数)について紹介しました．
日本語の記事が全然ヒットしなかったので，使命感に駆られて本記事を執筆しました．
日本人は数字パズルを好きな人が多いイメージを持っています．
そのため，寄生数という言葉を使わずに入試やパズルで寄生数を扱っている場合があると疑っています．

ところで，この記事の内容を理解するとCodyの[問題156](https://jp.mathworks.com/matlabcentral/cody/problems/156)と[問題1742](https://jp.mathworks.com/matlabcentral/cody/problems/1742)が解けます．
どちらも問題集[Magic Numbers](https://jp.mathworks.com/matlabcentral/cody/groups/8)と[Number theory](https://jp.mathworks.com/matlabcentral/cody/groups/2001)に属する，比較的価値の高い問題です．
是非，問題に挑戦してみてください．