Skip to content

Instantly share code, notes, and snippets.

@pnlybubbles
Last active August 29, 2015 13:55
Show Gist options
  • Save pnlybubbles/8779040 to your computer and use it in GitHub Desktop.
Save pnlybubbles/8779040 to your computer and use it in GitHub Desktop.
わたしのメイドちゃん
# 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