Last active
August 29, 2015 13:55
-
-
Save pnlybubbles/8779040 to your computer and use it in GitHub Desktop.
わたしのメイドちゃん
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# encoding: utf-8 | |
Encoding.default_external = Encoding::UTF_8 | |
$VERBOSE = nil # instead of -W0 | |
require "timeout" | |
require "date" | |
require "cgi" | |
# require "pry" | |
# require_relative "./wac/lib/wac.rb" | |
require_relative "./bot-2.rb" | |
module MyBot | |
class App | |
ASSIGN = { | |
"オナニー" => "0721", | |
"おなにー" => "0721", | |
"シコシコ" => "4545", | |
"しこしこ" => "4545", | |
"イムヤ" => "168", | |
"いむや" => "168", | |
"ゴーヤ" => "58", | |
"ごーや" => "58", | |
"イク" => "19", | |
"いく" => "19", | |
"いおな" => "401", | |
"イオナ" => "401", | |
"しおい" => "401", | |
"シオイ" => "401", | |
"やじゅう" => "810", | |
"ヤジュウ" => "810", | |
"野獣" => "810", | |
"いいよこいよ" => "114514", | |
"イイヨコイヨ" => "114514", | |
"良いよ来いよ" => "114514", | |
"いいよ来いよ" => "114514", | |
"いいよ!来いよ!" => "114514", | |
"TNOK" => "893", | |
"やくざ" => "893", | |
"ヤクザ" => "893", | |
"タニオカ" => "893", | |
"たにおか" => "893", | |
"くさい" => "931", | |
"クサイ" => "931", | |
"臭い" => "931", | |
"あくしろよ" => "889464", | |
"早くしろよ" => "889464", | |
"はやくしろよ" => "889464", | |
"見ろよ" => "364", | |
"みろよ" => "364" | |
} | |
def initialize | |
@app = Bot::Client.new("./oauth_keys.yaml") | |
@api = @app.api | |
@mydata = @app.mydata | |
@update_name_log = [] | |
load_update_name_log() | |
p @update_name_log | |
setup() | |
end | |
def run | |
@app.run(true, false) | |
end | |
def update_name(new_name, res) | |
new_name = CGI.unescape(new_name) | |
if new_name.length <= 20 | |
@app.say("UpdateName: #{res.user.screen_name}: #{new_name}") | |
begin | |
save_update_name_log(new_name) | |
@api.update_profile({:name => new_name}) | |
@api.update("@#{res.user.screen_name} さんによって\"#{new_name}\"になりました。", {:in_reply_to_status_id => res.id}) | |
rescue Exception => e | |
@app.say("UpdateName Error: #{e}", "e") | |
end | |
else | |
begin | |
@api.update("@#{res.user.screen_name} 変更に失敗しました。", {:in_reply_to_status_id => res.id}) | |
rescue Exception => e | |
@app.say("UpdateName Error: #{e}", "e") | |
end | |
end | |
end | |
def save_update_name_log(name) | |
unless @update_name_log.index(name) | |
@update_name_log << name | |
f = File.open("update_name.log", "a:utf-8") | |
f.puts(name) | |
f.close | |
end | |
end | |
def load_update_name_log | |
if File.exist?("update_name.log") | |
@update_name_log = File.read("update_name.log").strip.split("\n") | |
end | |
end | |
def setup | |
@app.new_event(:text) { |res| | |
# puts "#{res.created_at} #{res.user.screen_name}: #{res.text}" | |
} | |
@app.new_event(:reply, {:exclude_retweet => true}) { |res| | |
text = res.text.gsub(Regexp.union(ASSIGN.keys), ASSIGN) | |
text = text.strip.gsub(/^@\w+\s*/, "").to_s | |
meth = text[/[mprw]/] | |
# meth = "r" | |
meth_name = nil | |
text = text.gsub(/[mprw]/, "") | |
if text =~ /^[0-9]+$/ | |
int = text.to_i | |
if int != 0 && int != 1 | |
@app.say("Check Prime Number: #{int}") | |
check_prime = CheckPrime.new | |
case meth | |
when /p/ | |
result, factor = check_prime.factor_pm1_perl(int) | |
meth_name = "p-1(perl)" | |
when /r/ | |
result, factor = check_prime.factor_pm1_ruby(int) | |
meth_name = "p-1(ruby)" | |
when /w/ | |
result, factor = check_prime.factor_wac(int) | |
meth_name = "wolframalpha" | |
when /m/ | |
result, factor = check_prime.factor_msieve(int) | |
meth_name = int.to_s.length <= 80 ? "MPQS" : "GNFS" | |
else | |
result, factor = check_prime.factor_msieve(int) | |
meth_name = int.to_s.length <= 80 ? "MPQS" : "GNFS" | |
end | |
puts "meth: #{meth_name}" | |
@app.say("Factorization: #{factor}") | |
case result | |
when true | |
return_text = "\"#{int}\"は素数だよっ(ノ)・ω・(ヾ)" | |
when false | |
return_text = "\"#{int}\"は素数じゃないよっ(>﹏<。)(#{factor})" | |
else | |
return_text = "\"#{int}\"は桁数が大きすぎるのっ(>﹏<。)" | |
end | |
if factor && factor.empty? | |
return_text = "エラーが発生したのっ(>﹏<。)" | |
end | |
return_text += " [#{meth_name}]" if meth | |
else | |
return_text = "\"#{int}\"は素数じゃないよ...(´・д・ `) (#{int})" | |
end | |
begin | |
@app.update_long(return_text ,"@#{res.user.screen_name} %msg", res.id) | |
rescue Exception => e | |
@app.say("Post Error: #{e}", "e") | |
end | |
end | |
} | |
@app.new_event(:text, {:match => /あわあわ|pnly|pn1y/, :exclude_match => /@pn1y/, :exclude_user => :me}) { |res| | |
@app.say("Match: #{res.user.screen_name}: #{res.text}") | |
Thread.new(res) { |res_| | |
sleep(rand(600)) | |
begin | |
@api.favorite(res_) | |
rescue Exception => e | |
@app.say("Favorite Error: #{e}", "e") | |
end | |
} | |
} | |
@app.new_event(:text, {:match => /#(?<time>[0-9]+)(?<unit>[hms])/, :include_user => :me, :exclude_retweet => true}) { |res, match| | |
@app.say("Limited time tweet (#{match[:time] + match[:unit]}): #{res.user.screen_name}: #{res.text}") | |
Thread.new(res) { |res_| | |
sleep(match[:time].to_i * match[:unit].gsub(/[hms]/, {"h" => "3600", "m" => "60", "s" => "1"}).to_i) | |
@api.destroy_status(res_) | |
} | |
} | |
@app.new_event(:text, {:match => /#(count_in_|vote_in_)(?<time>[0-9]+)(?<unit>[hms])/, :include_user => :me, :exclude_retweet => true}) { |res, match| | |
@app.say("Count in (#{match[:time] + match[:unit]}): #{res.user.screen_name}: #{res.text}") | |
unit = match[:unit] == "h" ? "時" : (match[:unit] == "m" ? "分" : "秒") | |
Thread.new(res) { |res_| | |
sleep(match[:time].to_i * match[:unit].gsub(/[hms]/, {"h" => "3600", "m" => "60", "s" => "1"}).to_i) | |
new_res = @api.status(res_) | |
@api.update("@#{@mydata.screen_name} #{match[:time]}#{unit}間での集計結果です。リツイート:#{new_res.retweet_count} お気に入り:#{new_res.favorite_count} (#{new_res.url.to_s})", {:in_reply_to_status_id => new_res.id}) | |
} | |
} | |
@app.new_event(:unfavorite, {:exclude_user => :me, :only_followers => true}) { |res| | |
@app.say("Unfavorite: #{res.source.screen_name}: #{res.target_object.text}") | |
cnt = 0 | |
begin | |
@api.update("@#{res.source.screen_name} ふぇ...あんふぁぼされたのです...(´;ω;`)" + (" " * rand(3))) | |
rescue Exception => e | |
@app.say("Post Error: #{e}", "e") | |
cnt += 1 | |
retry if cnt <= 2 | |
end | |
} | |
# @app.new_event(:favorite) { |res| | |
# @app.say("Favorite: #{res.source.screen_name}: #{res.target_object.text}") | |
# } | |
@app.new_event(:reply, {:match => /update_name\s+("(?<new_name>.+)"|(?<new_name>[^\s]+))/, :exclude_retweet => true}) { |res, match| | |
update_name(match[:new_name], res) | |
} | |
@app.new_event(:reply, {:match => /update_random/, :exclude_retweet => true}) { |res| | |
new_name = @update_name_log.sample | |
update_name(new_name, res) if new_name | |
} | |
@app.new_event(:reply, {:match => /(?<new_name>.+?)\s*(\(|()\s*(@|@)#{@mydata.screen_name}\s*(\)|))/, :exclude_retweet => true}) { |res, match| | |
update_name(match[:new_name], res) | |
} | |
# @app.new_event(:reply, {:match => /test/, :only_followers => true}) { |res| | |
# begin | |
# @api.update("@#{res.user.screen_name} :only_followers (#{DateTime.now})", {:in_reply_to_status_id => res.id}) | |
# rescue Exception => e | |
# @app.say("Post Error: #{e}", "e") | |
# end | |
# } | |
# @app.new_event(:reply, {:match => /test/, :only_friends => true}) { |res| | |
# begin | |
# @api.update("@#{res.user.screen_name} :only_friends (#{DateTime.now})", {:in_reply_to_status_id => res.id}) | |
# rescue Exception => e | |
# @app.say("Post Error: #{e}", "e") | |
# end | |
# } | |
# @app.new_event(:reply, {:match => /test/, :only_ff => true}) { |res| | |
# begin | |
# @api.update("@#{res.user.screen_name} :only_ff (#{DateTime.now})", {:in_reply_to_status_id => res.id}) | |
# rescue Exception => e | |
# @app.say("Post Error: #{e}", "e") | |
# end | |
# } | |
end | |
end | |
class CheckPrime | |
def initialize | |
# Wac.appid = "A3WYQ5-PAGWYGAEPW" | |
end | |
def powm(base, power, mod) | |
ret = 1 | |
until power == 0 | |
ret = ret * base % mod if power & 1 == 1 | |
base = base * base % mod | |
power >>= 1 | |
end | |
ret | |
end | |
def probab_prime(n, k) | |
return true if n == 2 | |
return false if n == 1 || n & 1 == 0 | |
d = n - 1 | |
d >>= 1 while d & 1 == 0 | |
k.times do | |
y = powm(rand(n - 2) + 1, d, n) | |
t = d | |
until t == n - 1 || y == 1 || y == n - 1 | |
y = y * y % n | |
t <<= 1 | |
end | |
return false if y != n - 1 && t & 1 == 0 | |
end | |
return true | |
end | |
def next_prime(p) | |
n = p + 1 | |
n += 1 while !probab_prime(n, 10) | |
return n | |
end | |
def factor_pm1(n0) | |
pa = [] | |
ca = [] | |
if probab_prime(n0, 10) | |
pa << n0 | |
else | |
ca << n0 | |
end | |
while !ca.empty? | |
n = ca.shift | |
m = 3 | |
p = 2 | |
while n % (f = p) != 0 | |
f *= f while f < 1000 | |
m = powm(m, f, n) | |
f = n.gcd(m - 1) | |
break if f > 1 && f < n | |
p = next_prime(p) | |
end | |
if probab_prime(f, 10) | |
pa << f | |
else | |
ca << f | |
end | |
if f < n | |
f = n / f | |
if probab_prime(f, 10) | |
pa << f | |
else | |
ca << f | |
end | |
end | |
end | |
return pa.sort | |
end | |
def factor_array_to_str(f) | |
result = nil | |
factor = "" | |
if f.length == 1 | |
factor = nil | |
result = true | |
else | |
p = nil | |
c = 1 | |
f.each_with_index { |v, i| | |
if p == v | |
c += 1 | |
next if i + 1 != f.length | |
elsif p | |
factor << "#{factor.empty? ? '' : '*'}#{p}#{c == 1 ? '' : '^' + c.to_s}" | |
c = 1 | |
end | |
p = v | |
if i + 1 == f.length | |
factor << "#{factor.empty? ? '' : '*'}#{p}#{c == 1 ? '' : '^' + c.to_s}" | |
end | |
} | |
result = false | |
end | |
return result, factor | |
end | |
def factor_pm1_ruby(int) | |
begin | |
f = nil | |
timeout(60) { | |
f = factor_pm1(int) | |
} | |
p f | |
return factor_array_to_str(f) | |
rescue TimeoutError => e | |
puts "==== timeout: #{e}" | |
return nil, nil | |
rescue Exception => e | |
say("CHECK PRIME ERROR: #{e}", "e") | |
end | |
end | |
def factor_pm1_perl(int) | |
begin | |
io = nil | |
f = nil | |
timeout(60) { | |
io = IO.popen("perl ./pm1.pl #{int}") | |
f = io.read.strip.split("*") | |
} | |
p f | |
return factor_array_to_str(f) | |
rescue TimeoutError => e | |
puts "==== timeout: #{e}" | |
puts "==== pid: #{io.pid}" | |
Process.kill('INT', io.pid) | |
return nil, nil | |
rescue Exception => e | |
say("CHECK PRIME ERROR: #{e}", "e") | |
end | |
end | |
def factor_wac(int) | |
begin | |
r = Wac.fetch("factor #{int}") | |
p r | |
factor = nil | |
if r[1].to_s !~ /Prime\sfactorization/ | |
result = nil | |
else | |
if r[1].to_s =~ /prime\snumber/ | |
result = true | |
else | |
result = false | |
end | |
factor = r[1].to_s.gsub(/×/, "*").match(/factorization:\s+(?<factor>[0-9^\*]+)/)[:factor] | |
end | |
return result, factor | |
rescue Exception => e | |
say("CHECK PRIME ERROR: #{e}", "e") | |
end | |
end | |
def factor_msieve(int) | |
begin | |
io = nil | |
f = nil | |
timeout(60) { | |
system("echo \"#{int}\" > worktodo.ini") | |
io = IO.popen("msieve -e -p -q -n") | |
f = io.read.scan(/(?<=:\s)[0-9]+/).map { |n| n.to_i }.sort | |
} | |
p f | |
return factor_array_to_str(f) | |
rescue TimeoutError => e | |
puts "==== timeout: #{e}" | |
puts "==== pid: #{io.pid}" | |
Process.kill('INT', io.pid) | |
return nil, nil | |
rescue Exception => e | |
say("CHECK PRIME ERROR: #{e}", "e") | |
end | |
end | |
end | |
end | |
# --- ui --- | |
MyBot::App.new.run |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment