Skip to content

Instantly share code, notes, and snippets.

@tompng
tompng / repro_1788.rb
Created August 27, 2026 18:32
rdoc/pull/1788 reproduction code generated by claude
# Reproduces the generator-swap issue in PR #1788.
#
# RDoc::RubyGemsHook parses once (with the generator taken from the gem's
# rdoc_options) and then generates ri AND rdoc from the same store.
# If the gem's rdoc_options contain --format=ri, method source tokens are
# skipped at parse time and the later aliki generation is affected.
#
# Usage: ruby -Ilib repro_1788.rb
# master: ">>> aliki HTML: method source PRESENT"
# PR branch: raises RDoc::Error "method source for Dummy#foo was not stored"

方向性ぼかし草原システム (Ripmap草) — 設計概要

遠景〜中景の草原を、ジオメトリを一切使わず地形フラグメントシェーダーの テクスチャ参照数回で描くシステム。実装は grass.js(WebGPU/WGSL、単一ファイル)。

核となるアイデア

草を「一様色・一定長・鉛直の棒」とみなすと、遮蔽の順序が意味を失い、 1本のレイが受ける草の遮蔽量は 地面密度場 ρ をレイ足元の線分で積分したスカラー τ に潰れる。厳密積分の代わりに、**固定長の方向性ぼかし(= 定方向の Line Integral

BigMath.gamma の計算法: 旧実装・新実装・既存手法・その先

任意精度のガンマ関数 BigMath.gamma(x, prec) / BigMath.lgamma(x, prec) の計算法についてのまとめ。 このドキュメントは単体で読めるように書いてある(コードや diff を参照しなくても完結する)。

記法: p = 要求精度(10進桁数)。乗算コストは断りのない限り準線形 M(n) = O(n log n) モデルで数え、 大きい数×小さい数の積は M(m, n) = (n/m)·M(m) = O(n·log m)(小さい方のサイズでブロック化)と数える。

1. 問題の構造

x = x0 = BigDecimal('1100000000000000087944964434022145632029003198634030825446485394267219165647576318369821312487531766087629873357328440099001976504255934373246955159552')
def to_f(x0)
6.times do |shift|
prec = 27 << shift
exp = 0
x = x0r = x0.mult(1, prec)
[59, 16, 4, 1].each do |bit|
while bit == 1 ? x >= 2**53 : x.exponent - 1 >= (53 + bit)*0.30104
x = x.div(2**bit, prec)
exp += bit
@tompng
tompng / continuable_checker.rb
Created March 3, 2026 18:12
Originally a code to check`IRB::RubyLex#code_terminated?`
require 'prism'
# Collect syntax-valid code snippets from the given directory
def each_snippet(dir, max_size)
files = Dir.glob("#{dir.delete_suffix('/')}/**/*.rb")
snippets = Set.new
handle_snippet = ->(code) {
return if snippets.include?(code)
snippets << code
yield code
@tompng
tompng / rubykaigi2026logo.html
Created January 19, 2026 15:47
Render RubyKaigi 2026 logo to canvas
<canvas width="1600" height="1600" style="background:black"></canvas>
<script>
const canvas = document.querySelector('canvas')
const ctx = canvas.getContext('2d')
const outer = [...new Array(30)].map((_, i) => {
const rot = 0.00
const th1 = Math.PI * 2 * (i - i % 6) / 30 + rot
const th2 = th1 + Math.PI * 2 / 5
const th = th1 + [0, 0.335, 0.34, 0.5, 0.66, 0.665][i % 6] * (th2 - th1)
const r = [1, 0.71, 0.62, 0.65, 0.62, 0.71][i % 6]
require 'prism'
require 'irb'
# Collect syntax-valid code snippets from the given directory
def each_snippet(dir, max_size)
files = Dir.glob("#{dir.delete_suffix('/')}/**/*.rb")
snippets = Set.new
handle_snippet = ->(code) {
return if snippets.include?(code)
snippets << code
@tompng
tompng / prism_parsey_fuzz.rb
Created November 26, 2025 17:38
Find parse inconsistency of Prism and parse.y
# Found inconsistencies
# a b do end.()
# begin a => a: end; a in a: if 1; case a; in a: end
# def a = a b do 1 end
# a rescue b = *c
# p(not a)
# x = a b and c
# def x = a b and c
# a(a 1 do end)
# a.(a 1 do end)
@tompng
tompng / log2_log10_bs.rb
Last active September 24, 2025 15:10
log2 log10 asymptotic binary splitting
# log(10): [[(1/8), 10], [(1/15), 13], [(1/24), 7]]
# log(2): [[(1/8), 3], [(1/15), 4], [(1/24), 2]]
def print_logn_params(base)
value_factors = {}
(8..30).each do |n|
num = (1+1r/n)
(0..30).each do |exp|
v = num ** exp
break if v > 2 * base
@tompng
tompng / faster_exp.rb
Last active September 15, 2025 12:33
def exp_bs(x, prec)
# Taylor series of exp can be converted to continued fraction as:
# exp(x)-1 = x*(1+x/2*(1+x/3*(1+x/4*(1+x/5*(1+...)))))
# Binary splitting can be applied to this continued fraction as:
# (1 + a0/a1 + x/a1 * (1 + b0/b1 + x/b1 * rest))
# (1 + ((a0+x)*b1+x*b0)/(a1*b1) + (x*x)/(a1*b1) * rest)
x = BigDecimal(x)
step = (1..).bsearch { |k| Math.lgamma(k)[0] / Math.log(10) - k * x.exponent > prec }
ms = (1..step).map { [0, BigDecimal(it)] }
while ms.size > 1