LoginSignup
1
1

More than 5 years have passed since last update.

エレベータに乗る

Last updated at Posted at 2015-02-15

前説

鍋谷さんのpplogより。
※pplogは最終記事しか読めない仕様のため、パーマリンクを記載することは不可能です。

(前略)
ソスウノカイニハトマリマセンノデ、ツウカシマス」

「ナオ」
「ルイジョウスウノカイニハトマリマセン」
「コウドゴウセイスウノカイニハトマリマセン」
「カジョウスウノカイニハトマリマセン」
「ハンソスウノカイニハトマリマセン」
「カンゼンスウノカイニハトマリマセン」

次に止まる階はどこだか考える。
半素数ってなんだっけ。

コード

とりあえず、 止まる階を下から5つ求めると、675, 1125, 1323, 2312, 2888階だそうです。寒気しかしません。
求めると、44, 45, 50, 52, 63, 68, 75, 76, 92, 98のようになるようです。かなりバグっていてすみませんでした。おかしいとは思ったんですよね…。

nabetani_elevator.rb
#!/usr/bin/ruby
require 'prime'
class Integer
    def check(m)
        a=self.prime_division
        return :prime if a.size==1 && a[0][1]==1
        return :half_prime if a.size==2 && a[0][1]==1 && a[1][1]==1
        divisornum=a.reduce(1){|s,(n,p)|s*(p+1)}
        return divisornum if divisornum>m
        divisorsum=a.reduce(1){|s,(n,p)|s*(n**(p+1)-1)/(n-1)}
        return :perfect_number if divisorsum==self*2
        return :abundant_number if divisorsum>self*2
        power_min=a.select{|n,p|p>1}.map{|n,p|p}.min
        return :perfect_power if power_min && a.all?{|n,p|p%power_min==0}
        return nil
    end
end
p Enumerator.new{|y|
    m=0
    i=2
    loop{
        r=i.check(m)
        m=[m,r].max if r.is_a?(Integer)
        y<<i unless r
        i+=1
    }
}.take(10) # [44, 45, 50, 52, 63, 68, 75, 76, 92, 98]

ところで、chan gemは(golangと同様)read onlyなchanの作成ができるので、Enumerator.new{...}Chan.new{...}.gen_enum(Enumerator.new{})と変形できることになりますが、特に意味はないですね--;

perfect_powerについて

私の最初の実装は

power_min=a.map{|n,p|p}.min
a.all?{|n,p|p%power_min==0}

だった。これは勿論

power_min=a.select{|n,p|p>1}.map{|n,p|p}.min
power_min && a.all?{|n,p|p%power_min==0}

の間違いなのだが(現在は訂正済み)。
鍋谷さんが

a.inject(a[0][1]){|acc,x|acc.gcd(x[1])}>1

なる実装を提案してくださった。これならpower_minは不要になりますが…。パフォーマンス的にはどちらが良いのでしょうね。

1
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1