最終更新: 2011-02-13T04:35+0900
7500の正の約数は何個あるか。
素因数の数を数えてしまってた。その間違いに気づいたら今度は、1って約数に数えるの?その数自身も約数のうち?なんて、約数の定義が消えかかってる。(補足。素数の定義を思い出せば疑問は解ける)
復習~。
5^i × 3^j × 2^k
(i=0,1,2,3,4, j=0,1, k=0,1,2) で表される。(0乗が 1とか、0の階乗が 1とか、何気に落とし穴)コメントに↑そのまんま書いてあった(変数名まで一緒)。無駄なエントリになってしまった。
最終更新: 2012-12-12T02:17+0900
適当にカスタマイズして設置した。
XHTML化キットの存在は投稿されたアナウンスを読んで知ってたんだけど、XHTML好きにもかかわらず今まで導入してなかったのは、日記に数式を書く機会がなかったのと、出力段階での文字列置換による XHTML化が乱暴に思えたから。結局、他に方法がないので目をつぶったが。
閲覧不可能になった日記がないか月別表示で全日記を表示してみたら 10か所くらい見つかった。パターンは以下の通り。
<script>タグの中であっても & は & と書かなければいけない。不等号も。でも if(a && b) {}
とか置換してしまったらアホだ。CDATAセクションを使う。
scriptタグが解釈できないブラウザなんて PCを手に入れた当時から持ってなかったので
<script><!-- --></script>
なんて最初から書かなかったし、XHTMLを知ってからは下のように書くことにしてる。
<script>/*<![CDATA[*/ /*]]>*/</script>
コメントで囲うのは JavaScriptとして正しくあるため。より字数の少ない行コメントにしないのは、なにかでエラーになったから。MSがリリースしてた JavaScriptを暗号化(難読化)するツールに <script>タグを含んだ HTMLファイルを通したときだったか……。
但し書きを付けても無駄。HTMLと日本語は混ぜるな危険。中途半端な HTMLの隠蔽は悪。tDiaryスタイルと etDiaryスタイルより Wikiスタイル。
自業自得。さすがに、タグに挟まれた部分に & や <, > を放置してたわけではない。
<a href="ttp://hoge/script.cgi?a=b&c=d"> <img src="ttp://hoge/script.cgi?a=b&c=d">
すべてこの形の & がエラーになっていた。HTMLを出力するスクリプトでは、属性値は機械的に必ず HTMLエスケープするようにしてるんだけど、手書きだと上のような (X)HTMLは正しく見えてしまうのか、忘れられてた。こんなことがあるとやっぱりセミコロンで区切りたいねえ。
それにしても、ちらちら目に入る古い日記が恥ずかしくて死ねる。読む人間も、そもそも読める内容もないのであえて気づかぬふりで放置するけども。
最終更新: 2011-02-12T22:42+0900
Bignumはできれば使いたくない。aが 100未満なので 8桁ずつ。
answer = [0, 0, 0] # sum, a, b 1.upto(99){|a| digits = "1" 1.upto(99){|b| sum = 0 carry = 0 0.step(digits.size-1, 8) {|i| l, r = [0, digits.size-i-8].max, digits.size-i carry, digits8 = (digits[l...r].to_i * a + carry).divmod(100000000) digits8 = "00000000#{digits8}"[-8,8] digits[l...r] = digits8 digits8.each_byte{|byte| sum += byte - ?0 } } if carry != 0 digits8 = carry.to_s digits = digits8 + digits digits8.each_byte{|byte| sum += byte - ?0 } end if answer[0] < sum *answer = sum, a, b end } } p answer
とかいいながら Bignum。
count = 0 numer, denom = 1, 1 1000.times{ numer, denom = numer + denom + denom, numer + denom count += 1 if numer.to_s.length != denom.to_s.length } p count
最終更新: 2011-02-10T23:58+0900
経過 | 荷物受付 | 02/10 | 12:36 | 金沢物流システム支店 |
経過 | 発送 | 02/10 | 12:36 | 金沢物流システム支店 |
最新 | 配達完了 | 02/10 | 12:06 | ○○センター |
受付は昨日のはずだ。このせいで一切のトラッキングができなくて、今日着くのか明日着くのかがわからなかった。時間帯指定で不在はくらいたくないでしょうに。
最終更新: 2011-02-11T00:59+0900
Fix: 検索(ツールバー)を使うとプラグインコマンドが実行される(2)
検索ボックスのコードをほとんどコピーした自作ツールバーボタンもやばい気がするものの、CBN_SELCHANGEはツールバーボタンで処理してるんだよね。処理しなかったメッセージが誤った取り扱いを受ける、ということなんだろうか。わからないよん。
最終更新: 2011-02-10T04:56+0900
ただただ、手と CPUを動かすだけで精一杯。(頭は役に立ってないよ)
primes = [2] is_prime = lambda{|x| result = true primes.each{|prime| quo, rem = x.divmod(prime) if rem == 0 result = false break end break if quo < prime } return result } # replace 2 digits or 3 digits. キ・メ・ウ・チ def find_8_prime_family(a) return [] if a.size < 8 a.map!{|x| x.to_s } h = Hash.new{|h,k| h[k] = [] } # 2 digits 0.upto(a.first.size-3){|i| (i+1).upto(a.first.size-2){|j| h.clear a.each do |prime| if prime[i] == prime[j] h[prime[0...i]+prime[(i+1)...j]+prime[(j+1)...(prime.size)]].push prime end end h.each do |_,v| return v if v.size == 8 end } } # 3 digits 0.upto(a.first.size-4){|i| (i+1).upto(a.first.size-3){|j| (j+1).upto(a.first.size-2){|k| h.clear a.each do |prime| if prime[i] == prime[j] and prime[j] == prime[k] h[prime[0...i]+prime[(i+1)...j]+prime[(j+1)...k]+prime[(k+1)...(prime.size)]].push prime end end h.each do |_,v| return v if v.size == 8 end } } } return [] end x = 1 start = 0 # start of primes of a width. loop { x += 2 next unless is_prime.call x print "#{x}\r" if primes[start].to_s.length != x.to_s.length a = find_8_prime_family primes.last(primes.size-start) if ! a.empty? puts a.sort.join(" ") exit end start = primes.size end primes.push x }
桁数ごとに探索範囲を決めて、総当たり。
問題が xについても同じ数の組み合わせであることを求めてると思わなくてチェックしてないけど、結果的に xも 2x,3xなんかと同じ数字で構成されてた。
digits = 10 loop { digits *= 10 (digits/2).upto((digits*10-1)/6){|x| print "#{x}\r" x2 = (x*2).to_s.split(//).sort if [3,4,5,6].all?{|n| x2 == (x*n).to_s.split(//).sort } then puts [1,2,3,4,5,6].map{|n| x*n }.join(" ") exit end } }
浮動小数点数なんてファジーなものを使っちゃったよ。Math.sqrtの使用をこれまで頑なに避けてたのも、結果が Floatになるからだったり。
count = 0 23.upto(100){|n| cmb = 1.0 1.upto(n/2){|r| cmb /= r cmb *= (n-r+1) count += (n-r == r) ? 1 : 2 if 1_000_000 < cmb } } p count
問題文が難しかった。3割ぐらいは推測。
あっけなく答えが出たので to_s.reverse.to_i
みたいなのをなくすべく、Integer#reverse
を自作してみたら、かえって遅くなったし。
class Integer # 負数については考えてない。 def reverse x = 0 this = self begin this, rem = this.divmod(10) x = 10*x + rem end while 0 < this x end end count = 0 10.upto(10_000-1){|x| is_lychrel = true 50.times{ x = x + x.reverse if x == x.reverse is_lychrel = false break end } count += 1 if is_lychrel } p count
最終更新: 2011-02-09T20:16+0900
時間がかかるので逐一進捗を表示してる。この問題に魔法の一手なんてあるのかね。
primes = [] is_prime = lambda{|x| result = true primes.each{|prime| quotient, remainder = x.divmod(prime) if remainder == 0 result = false break end break if quotient < prime } return result } 2.upto(999_999){|x| primes.push x if is_prime.call x } puts "#{primes.size} primes under 1 million." work = primes.dup step = 0 primes_found = [] live_elements = work.size while 0 < live_elements step += 1 primes_found.clear live_elements = 0 print "step #{step}\r" 0.upto(work.size-1-step){|i| work[i] += primes[i+step] if work[i] < 1_000_000 live_elements += 1 primes_found.push work[i] if is_prime.call work[i] end } if primes_found.empty? elsif primes_found.size < 10 puts "step #{step}: #{primes_found.join ' '}" else puts "step #{step}: #{primes_found.size} primes" end end
魔法の一手はなくても……
答えを出した後でググるのが楽しい。フォーラムは読んでないけど、多分これ以上ないっていうような答えが書いてありそうで、面白くなさそうな気がしてる。(理解できない数学的知識が使われてたら、print XXXXXXX(answer); って書かれてるのと変わらないから)
最終更新: 2011-02-09T01:05+0900
昨日よりちょっとはマシになったかと。アホすぎた素数判定を、素因数の数を数える処理と一体化した。でも 10秒以上かかります。
primes = [2] have4primefactors = [] num_of_factors = lambda{|x| prime_factors = 0 primes.each{|prime| quotient, remainder = x.divmod(prime) if quotient < prime prime_factors += 1 break end if remainder == 0 prime_factors += 1 break if 4 < prime_factors x /= prime while x % prime == 0 break if x == 1 end } return prime_factors } x = 2 loop { x += 1 print "#{x}\r" case num_of_factors.call(x) when 1 primes.push x have4primefactors.clear when 4 have4primefactors.push x p have4primefactors.first if have4primefactors.length == 4 else have4primefactors.clear end }
恥ずかしいほどまっすぐで乱暴なスクリプトだけど、コンソールの表示も待てないくらいノーウェイトで答えが出るんだから仕方がない。
p (1..1000).inject(0){|sum,x| sum + x**x }
10秒くらいかかります。
primes = [] is_prime = lambda{|x| result = true primes.each{|prime| quotient, remainder = x.divmod(prime) if remainder == 0 result = false break end break if quotient < prime } return result } 2.upto(9999){|x| primes.push x if is_prime.call x } primes_4digit = primes.last(primes.length - primes.rindex{|x| x < 1000 } - 1) 0.upto(primes_4digit.size-1){|i| p = primes_4digit[i] # next if p == 1487 (i+1).upto(primes_4digit.size-1){|j| q = primes_4digit[j] r = q + q - p next if p.to_s.split(//).sort != q.to_s.split(//).sort or q.to_s.split(//).sort != r.to_s.split(//).sort k = nil (j+1).upto(primes_4digit.size-1){|_k| if r == primes_4digit[_k] k = _k break elsif r < primes_4digit[_k] break end } if k puts "#{p} #{q} #{r}" # exit end } }
最終更新: 2011-02-07T05:28+0900
squares[]はソート済みなのに .include?()でそれを活かせないのが不満。
primes = [] # Omit 2. Even prime is not needed. squares = [1] def prime?(n) return false if 0 == n%2 3.step(n/2, 2) {|x| return false if 0 == n%x } return true end x = 1 loop { x += 2 squares.push((squares.size+1)**2) if squares.last < x if prime?(x) primes.push x next end print "#{x}\r" next if primes.any?{|prime| prime < x and squares.include?((x-prime)/2) } p x # answer break }
何の工夫もないのですんごく時間がかかる。
def prime_gt2?(n) return false if 0 == n%2 x, upper_bound = 3, n/2 while x <= upper_bound upper_bound, remainder = n.divmod(x) return false if 0 == remainder x += 1 end return true end primes = [2] have4primefactors = [] have4primefactor = lambda{|x| num_of_factors = 0 primes.each{|prime| if x % prime == 0 num_of_factors += 1 break if 4 < num_of_factors x /= prime while x % prime == 0 end } return num_of_factors == 4 } x = 2 loop { x += 1 print "#{x}\r" if prime_gt2? x primes.push x have4primefactors.clear elsif have4primefactor.call(x) have4primefactors.push x p have4primefactors.first if have4primefactors.length == 4 else have4primefactors.clear end }
最終更新: 2011-02-05T10:26+0900
ちょっと前の日記から……
Q14
この漸化式は『珠玉のプログラミング』で見た。どうして収束するのかわからなかった。
見たっていうのはコラム4の問題で。
4.6問題
5.入力xが正の整数であるとき、以下のループが終了することを示してください。
while x != 1 do if xが偶数なら x = x/2 else x = 3*x+1
これがまんま「コラッツの問題 - Wikipedia)」と呼ばれる未解決の問題だということに、今日「d.y.d.」を読んでいて気がついた。本の巻末のヒントを読み直してみたらこんなことが書いてあるし。
もし、この問題が解けたら、近くの大学の数学科に急いで行って、博士号を申請しましょう。
ひどい(笑)。わからなくて当然だ。遅刻学生が黒板の問題を宿題だと思って解いて提出したら、それは未解決問題だったとかいうのは、お話の世界なんだから。
最終更新: 2011-02-05T05:33+0900
無駄にこったねえ。一瞬 JavaScriptで書こうとしたしたせいか、lambda多用。
generators = [ lambda { n, tn = 1, 1 lambda { n+=1; tn+=n; tn } # triangle numbers generator }.call, lambda { n, pn = 1, 1 lambda { pn+=3*n+1; n+=1; pn } # pentagonal numbers generator }.call, lambda { n, hn = 1, 1 lambda { hn+=4*n+1; n+=1; hn } # hexagonal numbers generator }.call ] numbers = [1, 1, 1] # Ti, Pj, Hk relations = "===" # Ti?Pj, Pj?Hk, Hk?Ti actions = lambda { relation = lambda {|a,b| a==b ? '=' : a>b ? '>' : '<' } when_Nth_is_the_smallest = lambda {|i| lambda { numbers[i] = generators[i].call relations[i] = relation.call(numbers[i], numbers[(i+1)%numbers.size]) j = (i-1) % relations.size relations[j] = relation.call(numbers[j], numbers[(j+1)%numbers.size]) print "#{numbers[i]}\r" } } (0..2).map{|i| when_Nth_is_the_smallest.call(i) } }.call action_table = Hash.new {|h,rel| raise "missing action for '#{rel}'" } [ ["<<>", "<>>", "<=>", "=<>", "<>="], # when Ti is the smallest ["><<", "><>", ">=<", "><="], # when Pj is the smallest (and Ti not) [">><", "<><", "=><"], # when Hk is the smallest (and the other not) ].each_with_index {|rels, i| rels.each {|rel| action_table[rel] = actions[i] } } action_table["==="] = lambda { puts numbers[0] # answer actions[0].call } loop { action_table[relations].call }
相当な時間をかけて(求められていない)三番目の数字が出た。>57722156241751
六角数は三角数なので、三角数は無視できる。五角数と六角数を並べて比較していくだけ。
それがわからない。
チート。
Hn = n(2n-1) = (2n-1)(2n)/2 = m(m+1)/2 = Tm (m = 2n-1)
nは自然数だから、mは正の奇数になる。Triangle Numbersの奇数番目が Hexagonal Numbers.(逆も真) 言われたらそうかもね。それぞれの数列を眺めてたら気付くかもね。(それが無理なのはわかってる)
最終更新: 2011-02-03T09:33+0900
愚直に。
divisors = [17, 13, 11, 7, 5, 3, 2, 1] candidates = [] div = divisors.shift div.step(999, div){|x| triplet = [x/100, x/10%10, x%10] candidates.push triplet if triplet.uniq!.nil? } until divisors.empty? div = divisors.shift candidates.size.times{ candidate = candidates.shift (0..9).each{|d| if ! candidate.include?(d) && 0 == (100*d + 10*candidate[0] + candidate[1]) % div candidates.push [d] + candidate end } } end candidates.reject!{|c| c[0] == 0 } p candidates.inject(0){|sum,c| sum + c.join("").to_i }
最初に出てきた数字を書いたら通ったけど……。pentagonal numbersの名前の由来もわからんもんね。
_5 = [1] # [P1, P2,...] _5_index = {1=>0} # 逆引き(Pn=>n-1)辞書 loop{ i = _5.size _5.push(_5.last + 3*i + 1) _5_index[_5[i]] = i print "." (i-1).downto(0){|j| diff = _5[i] - _5[j] break if diff > _5[j] k = _5_index[diff] next unless k diff2 = _5[j] - _5[k] l = _5_index[diff2] next unless l puts puts "D=#{_5[j]-_5[k]}" puts "#{_5[j]-_5[k]} = P#{j+1}-P#{k+1}" puts "#{_5[l]} = P#{l+1}" puts "#{_5[j]+_5[k]} = P#{j+1}+P#{k+1}" print "#{_5[i]} = P#{i+1}" gets } }
最終更新: 2011-04-09T19:20+0900
今のサクラエディタはユーザーが入力したパターンに細工を施している。>「正規表現を使った検索・置換で、改行の意味を LFのみから CRも含むように。」
サクラエディタでは改行をまたいだ検索ができないけど、将来できるようになると問題が生じる。(その根拠は20100709p01の実験による)
^
(改行文字の直後にマッチ)が CR直後(かつLF直前でないことが望ましい)にマッチしないことが露見する。$
を (?<![\r\n])(?=\r|$)
に置き換える現在の細工では、連続する改行と改行の間にマッチできない。^
は (?:(?<=^|\n)(?=[\s\S])|(?<=\r)(?=[^\n]))
に、$
は (?=\r\n?|(?<!\r)\n|(?<![\r\n])$)
に置き換えるのでいいかなあ。用意した入力が期待した結果になるのは確認したけど、予期しない入力が予期しない結果になる可能性はやっぱりある。
戻り読みの中に ^ や $ を置けなくなる。複数行検索ができるようになったときには、戻り読みの中で行末を検知したくなることもあるかもしれないね。でも、できないね。