Top Level Namespace

Defined Under Namespace

Modules: VivlioStarter

Constant Summary collapse

SPEED_OF_LIGHT =

万有引力定数 [m³/kg/s²]

2.99792458e8
M =
VivlioStarter::CLI::Masking
S =
VivlioStarter::CLI::Lint::MazegakiScanner
FILES =
{ 'contents' => Dir['contents/*.md'], 'docs' => Dir['docs/**/*.md'], 'ルート' => Dir['*.md'] }.freeze
D =
VivlioStarter::CLI::Lint::MazegakiDictionary
DEST =

出荷用データを書き出す。lib/ に置くのは docs/ が gem に入らないため (gemspec の spec.files は bin,lib/**/* のみ)。

File.expand_path('mazegaki.tsv', __dir__)
G =

万有引力定数 G 6.67430(15) (15) は末尾2桁の不確かさを示す:6.67430 ± 0.00015

6.67430e-11
SOLAR_MASS =

光速 [m/s]

1.9884e30
SOLAR_RADIUS =

太陽の質量 [kg]

6.957e8

Instance Method Summary collapse

Instance Method Details

#brownian_motion(steps:, delta: 1.0) ⇒ Array<Array<Float>>

ブラウン運動の軌跡を生成する 各ステップでランダムな方向に delta だけ移動する2次元ランダムウォーク

Parameters:

  • steps (Integer)

    シミュレーションのステップ数

  • delta (Float) (defaults to: 1.0)

    1ステップあたりの移動距離(デフォルト: 1.0)

Returns:

  • (Array<Array<Float>>)

    各ステップの座標 [[x, y], ...] の配列



10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/project_scaffold/codes/brownian_motion.rb', line 10

def brownian_motion(steps:, delta: 1.0)
  x, y = 0.0, 0.0
  trajectory = [[x, y]]

  steps.times do
    angle = rand * 2 * Math::PI
    x += delta * Math.cos(angle)
    y += delta * Math.sin(angle)
    trajectory << [x.round(4), y.round(4)]
  end

  trajectory
end

#energy_from_mass(mass_kg) ⇒ Float

質量からエネルギーを計算する(E = mc²)

Parameters:

  • mass_kg (Float)

    質量 [kg]

Returns:

  • (Float)

    エネルギー [J]



9
10
11
# File 'lib/project_scaffold/codes/mass_energy.rb', line 9

def energy_from_mass(mass_kg)
  mass_kg * SPEED_OF_LIGHT**2
end

#gravitational_deflection(mass_kg, radius_m) ⇒ Float

重力による光の曲がり角をラジアンで返す(一般相対性理論)

Parameters:

  • mass_kg (Float)

    天体の質量 [kg]

  • radius_m (Float)

    光が最接近する距離(天体の半径など)[m]

Returns:

  • (Float)

    曲がり角 [ラジアン]



16
17
18
# File 'lib/project_scaffold/codes/gravitational_lensing.rb', line 16

def gravitational_deflection(mass_kg, radius_m)
  4 * G * mass_kg / (SPEED_OF_LIGHT**2 * radius_m)
end

#greet(name) ⇒ Object

サンプルコード: include 記法のデモ用 このファイルは codes/sample.rb として原稿から参照されます



4
5
6
# File 'lib/project_scaffold/codes/sample.rb', line 4

def greet(name)
  puts "こんにちは、#{name}さん!"
end

#kata(s) ⇒ Object



69
# File 'lib/vivlio_starter/cli/lint/data/filter.rb', line 69

def kata(s) = s.tr('ぁ-ゖ', 'ァ-ヶ')

#lorentz_factor(velocity_ratio) ⇒ Float

ローレンツ因子 γ を計算する 速度が光速に近づくほど γ は大きくなり、時間の遅れが顕著になる

Parameters:

  • velocity_ratio (Float)

    光速を1としたときの速度(例: 0.9 = 光速の90%)

Returns:

  • (Float)

    ローレンツ因子 γ(常に1以上)



10
11
12
# File 'lib/project_scaffold/codes/time_dilation.rb', line 10

def lorentz_factor(velocity_ratio)
  1.0 / Math.sqrt(1 - velocity_ratio**2)
end

#mean_square_displacement(trajectory) ⇒ Float

軌跡の平均二乗変位(MSD)を計算する MSD は粒子の拡散の広がりを示す指標で、ステップ数に比例して増加する

Parameters:

  • trajectory (Array<Array<Float>>)

    brownian_motion が返す座標の配列

Returns:

  • (Float)

    平均二乗変位



28
29
30
# File 'lib/project_scaffold/codes/brownian_motion.rb', line 28

def mean_square_displacement(trajectory)
  trajectory.map { |x, y| x**2 + y**2 }.sum / trajectory.size
end

#other_word?(mecab, m, yomi) ⇒ Boolean

Returns:

  • (Boolean)


70
71
72
73
74
75
# File 'lib/vivlio_starter/cli/lint/data/filter.rb', line 70

def other_word?(mecab, m, yomi)
  ns = mecab.enum_parse(m).reject { it.surface.to_s.empty? }.to_a
  return false unless ns.size == 1 && ns[0].stat.zero?
  r = ns[0].feature.split(',')[7]
  !r.nil? && r != kata(yomi)
end

#prime?(n) ⇒ Boolean

与えられた整数が素数かどうかを判定する

Parameters:

  • n (Integer)

    判定対象の自然数

Returns:

  • (Boolean)

    素数なら true



7
8
9
10
11
12
# File 'lib/project_scaffold/codes/prime.rb', line 7

def prime?(n)
  return false if n < 2
  return true if n < 4

  (2..Math.sqrt(n).to_i).none? { n % it == 0 }
end

#scan(table) ⇒ Object

判定は本番と同じコードを使う。 ここで独自に境界判定を書くと、 測った数字と実際の lint の振る舞いが静かに食い違う。 MazegakiScanner の辞書だけ候補で差し替えて、判定はあちらに任せる。



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/vivlio_starter/cli/lint/data/filter.rb', line 49

def scan(table)
  S.instance_variable_set(:@table, table)
  S.instance_variable_set(:@max_length, nil)
  hits = Hash.new { |h, k| h[k] = [] }
  FILES.each_value do |files|
    files.each do |path|
      M.each_prose_line(File.read(path, encoding: 'UTF-8')) do |raw, lineno|
        line = raw.tr("\0", ' ')          # NUL を含む行がある。長さは変えない
        protected_line, = M.protect_code(line)
        plain, = M.strip_emphasis(protected_line)
        S.scan(plain).each do |found, _expected, offset, _finish|
          hits[found] << "#{path}:#{lineno}\u3000…#{plain.strip[[offset - 14, 0].max, 34]}"
        end
      end
    end
  end
  hits
end

#sieve_of_eratosthenes(n) ⇒ Array<Integer>

エラトステネスの篩で n 以下の素数を列挙する

Parameters:

  • n (Integer)

    上限値

Returns:

  • (Array<Integer>)

    素数の配列



7
8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/project_scaffold/codes/prime2.rb', line 7

def sieve_of_eratosthenes(n)
  return [] if n < 2

  is_prime = Array.new(n + 1, true)
  is_prime[0] = is_prime[1] = false

  (2..Math.sqrt(n).to_i).each do |i|
    next unless is_prime[i]

    (i * i..n).step(i) { is_prime[it] = false }
  end

  is_prime.each_index.select { is_prime[it] }
end

#time_dilation(proper_time, velocity_ratio) ⇒ Float

時間の遅れを計算する(特殊相対性理論) 高速で移動する系では、静止系から見て時間の進みが遅くなる

Parameters:

  • proper_time (Float)

    移動する系での経過時間(固有時間)

  • velocity_ratio (Float)

    光速を1としたときの速度

Returns:

  • (Float)

    静止系(地球)から見た経過時間



19
20
21
# File 'lib/project_scaffold/codes/time_dilation.rb', line 19

def time_dilation(proper_time, velocity_ratio)
  proper_time * lorentz_factor(velocity_ratio)
end

#to_arcseconds(radians) ⇒ Float

ラジアンを秒角(arcseconds)に変換する 天文学では微小な角度を秒角で表すことが多い(1度 = 3600秒角)

Parameters:

  • radians (Float)

    角度 [ラジアン]

Returns:

  • (Float)

    角度 [秒角]



24
25
26
# File 'lib/project_scaffold/codes/gravitational_lensing.rb', line 24

def to_arcseconds(radians)
  radians * (180.0 / Math::PI) * 3600
end