技術メモ

役に立てる技術的な何か、時々自分用の覚書。幅広く色々なことに興味があります。

直下のファイルを走査し一覧表示する [bash, python]

あるディレクトリの直下のファイルに対して巡回しながら処理したい時
シェルスクリプトpythonでどうするか。

bash

files="./hoge/*"
for filepath in $files; do
  echo $filepath
done

./hoge/1.txt
./hoge/2.txt
のようにディレクトリごと表示される
ファイル名だけ表示したい場合はこう書けば良い

${filepath##*/}

補足

zipファイルの中にzipファイルがあるもの、例えば

  • a.zip
    • nbghuio.zip
    • bghjkoi.zip
  • b.zip
    • bhujiko.zip
    • qvdshjt.zip

こんな感じのものをまとめて解凍したい時

#!/bin/bash
for zipfile `\find . -name '*.zip'` ; do
    unzip -q ${zipfile}
done

for i in "./*" ; do
    for file in `\find $i -name '*.zip'`; do
        unzip -q -o ${file}
    done
done

こんなスクリプトになる。

Python

import os

directory = "./hoge/"
for root, dirs, files in os.walk(directory):
    for file in files:
        print(file)
        print(root+file)

fileだけの場合は
1.txt
のようになる。rootディレクトリの文字列があるので
./hoge/1.txt
のようにしたい場合はroot+fileのように書く

pythonで完全数と友愛数と婚約数を求める

以前の記事の続きとして、せっかくなので友愛数完全数・婚約数を求めてみたい。

約数関数(再掲)

divisor(n)として約数関数を使うので、再掲しておく。
sympyを使う。

import sympy
def divisor(n):
    factors = sympy.factorint(n)
    rst = 1
    for i,j in factors.iteritems():
        rst *= (pow(i,j+1) - 1)/(i-1)
    return rst

完全数

完全数(かんぜんすう,英: perfect number)とは、自分自身を除く正の約数の和に等しくなる自然数のことである。完全数の最初の3個は 6 (= 1 + 2 + 3)、28 (= 1 + 2 + 4 + 7 + 14)、496 (= 1 + 2 + 4 + 8 + 16 + 31 + 62 + 124 + 248) である。「完全数」は「万物は数なり」と考えたピタゴラスが名付けた数の一つであることに由来する[1]が、彼がなぜ「完全」と考えたのかについては何も書き残されていないようである
wikipedia:完全数

max = 100000
rst = []
for n in range(1,max+1):
    if divisor(n) == 2*n:
        rst.append(n)
  • 結果
rst = 
[6, 28, 496, 8128]

友愛数

友愛数(ゆうあいすう、英: amicable numbers)とは、異なる 2 つの自然数の組で、自分自身を除いた約数の和が、互いに他方と等しくなるような数をいう。親和数(しんわすう)とも呼ばれる。
最小の友愛数の組は (220, 284) である。
220 の自分自身を除いた約数は、1, 2, 4, 5, 10, 11, 20, 22, 44, 55, 110 で、和は 284 となる。一方、284 の自分自身を除いた約数は、1, 2, 4, 71, 142 で、和は 220 である。
wikipedia:友愛数

max = 100000
rst = []
for n in range(1,max+1):
    pair = divisor(n) - n
    if n < pair and pair <= max:
        if divisor(pair) - pair == n:
            rst.append([n,pair])
  • 結果
rst = 
[[220, 284],
 [1184, 1210],
 [2620, 2924],
 [5020, 5564],
 [6232, 6368],
 [10744, 10856],
 [12285, 14595],
 [17296, 18416],
 [63020, 76084],
 [66928, 66992],
 [67095, 71145],
 [69615, 87633],
 [79750, 88730]]

婚約数

婚約数(こんやくすう、英: betrothed numbers)とは、異なる 2 つの自然数の組で、1 と自分自身を除いた約数の和が、互いに他方と等しくなるような数をいう。準友愛数(じゅんゆうあいすう、quasi-amicable numbers)とも呼ばれる。
最小の婚約数の組は (48, 75) である。
48 の 1 と自分自身を除いた約数は、2, 3, 4, 6, 8, 12, 16, 24 で、和は 75 となる。一方、75 の 1 と自分自身を除いた約数は、3, 5, 15, 25 で、和は 48 である。
wikipedia:婚約数

max = 100000
rst = []
for n in range(1,max+1):
    pair = divisor(n) - n - 1
    if n < pair and pair <= max:
        if divisor(pair) - pair - 1 == n:
            rst.append([n,pair])
  • 結果
rst = 
[[48, 75],
 [140, 195],
 [1050, 1925],
 [1575, 1648],
 [2024, 2295],
 [5775, 6128],
 [8892, 16587],
 [9504, 20735],
 [62744, 75495]]

sympyで素因数分解ができるからオイラー関数と約数関数を書いてみた

pythonのライブラリの一つsympyを使えば、簡単に素因数分解ができるということを知った。

import sympy
sympy.factorint(1000)
#{2: 3, 5: 3}

ちなみに、因数分解も簡単にできる!!
凄い。

import sympy
x = sympy.Symbol('x')

eqn = x**2 - 3*x + 2
print(sympy.factor(eqn))
# (x - 2)*(x - 1)

これを使って、オイラー関数と約数関数を書いてみた。

オイラー関数

自然数nに対して、n未満でnと互いに素な自然数の個数を\varphi(n)で表し、オイラー関数と呼ぶ。
例えば、12未満で12と互いに素な自然数\{1, 5, 7, 11\}なので\varphi(12) = 4

def euler(n):
    factors = sympy.factorint(n)
    rst = 1
    for i,j in factors.iteritems():
        rst *= (pow(i,j) - pow(i,j-1))
    return rst

約数関数

自然数nの約数の和を\sigma(n)と表し、約数関数と呼ぶ。
例えば、12の約数は\{1,2,3,4,6,12\}なので\sigma(12)=28

def divisor(n):
    factors = sympy.factorint(n)
    rst = 1
    for i,j in factors.iteritems():
        rst *= (pow(i,j+1) - 1)/(i-1)
    return rst

コードの説明

コードだけ見てもちんぷんかんぷんだろうけれど、それぞれ関数のこれらの性質を利用している。

n素因数分解が次のように与えられているとき
 \displaystyle n = \prod_{k=1}^d p_k^{e_k}
オイラー関数、約数関数はそれぞれ次のように求まる
 \displaystyle \phi(n) = \prod_{k=1}^d (p_k^{e_k} - p_k^{e_k-1})
 \displaystyle \sigma(n) = \prod_{k=1}^d \frac{p_k^{e_k+1}-1}{p-1}

数え上げ

n 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
\phi (n) 1 1 2 2 4 2 6 4 6 4 10 4 12 6 8 8 16 6 18
\sigma (n) 1 3 4 7 6 12 8 15 13 18 12 28 14 24 24 31 18 39 20


参考:
wikipedia:オイラー関数
wikipedia:約数関数
オイラー関数に関して:
RSA暗号を実装してみる(理論編) - 技術メモ

関連記事: