forked from zgrep/happybot
Numbers and files, oh my!
This commit is contained in:
parent
f182fb24bf
commit
855375ea18
2 changed files with 180 additions and 0 deletions
144
fractran.py
Executable file
144
fractran.py
Executable file
|
@ -0,0 +1,144 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from subprocess import Popen, PIPE
|
||||
import re
|
||||
|
||||
def cmd(args):
|
||||
proc = Popen(args, stdout=PIPE)
|
||||
while True:
|
||||
line = proc.stdout.readline()
|
||||
if line:
|
||||
try:
|
||||
yield str(line[:-1], 'utf-8', 'ignore')
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
break
|
||||
|
||||
def irc(chan):
|
||||
global trigger
|
||||
fdir = '/home/zgrep/offtopiabday/irc.freenode.net/' + chan
|
||||
fin = fdir + '/in'
|
||||
fout = fdir + '/out'
|
||||
|
||||
for line in cmd(['tail', '-n', '0', '-f', fout]):
|
||||
date, time, nick, line = line.split(' ', 3)
|
||||
print(line)
|
||||
m = re.match(r'(?i)(?:happy|hate)bot[:,]\s+([0-9]+)\s+(fractrand?)\s+([0-9]+/[0-9]+(?:,?\s+[0-9]+/[0-9]+)*)$', line)
|
||||
if m:
|
||||
n, f, fs = m.group(1), m.group(2), m.group(3)
|
||||
print('Matched!', n, f, fs)
|
||||
trigger = True
|
||||
r = doit(f, n, fs)
|
||||
trigger = False
|
||||
r = '\u200b' + r
|
||||
print('Result!', r)
|
||||
with open(fin, 'w') as fh:
|
||||
fh.write(r + '\n')
|
||||
|
||||
from fractions import Fraction
|
||||
from random import choice
|
||||
import signal
|
||||
|
||||
trigger = False
|
||||
|
||||
class TimeoutException(Exception): pass
|
||||
def signal_handler(signum, frame):
|
||||
global trigger
|
||||
if trigger:
|
||||
raise TimeoutException("Timed out!")
|
||||
|
||||
def fractran(n, fracs):
|
||||
vals = [n]
|
||||
signal.alarm(1)
|
||||
try:
|
||||
while True:
|
||||
for frac in fracs:
|
||||
n2 = n*frac
|
||||
if n2.denominator == 1:
|
||||
n = n2.numerator
|
||||
if n in vals:
|
||||
i = vals.index(n)
|
||||
return 'Infinite loop: ..., ' + ', '.join(map(str, vals[i:]))
|
||||
vals.append(n)
|
||||
break
|
||||
else:
|
||||
if len(vals) > 12:
|
||||
beg = ', '.join(map(str, vals[:2]))
|
||||
end = ', '.join(map(str, vals[-10:]))
|
||||
return f'{beg}, ..., {end}'
|
||||
else:
|
||||
return ', '.join(map(str, vals))
|
||||
except TimeoutException:
|
||||
if len(vals) > 12:
|
||||
beg = ', '.join(map(str, vals[:10]))
|
||||
end = ', '.join(map(str, vals[-2:]))
|
||||
return f'Timed out: {beg}, ..., {end}, ...'
|
||||
else:
|
||||
return 'Timed out: ', + ', '.join(map(str, vals))
|
||||
|
||||
def random_unordered_fractran(n, fracs):
|
||||
vals = [n]
|
||||
signal.alarm(1)
|
||||
try:
|
||||
while True:
|
||||
ns = [ n * frac for frac in fracs ]
|
||||
ns = [ m for m in ns if m.denominator == 1 ]
|
||||
if not ns:
|
||||
if len(vals) > 12:
|
||||
beg = ', '.join(map(str, vals[:2]))
|
||||
end = ', '.join(map(str, vals[-10:]))
|
||||
return f'{beg}, ..., {end}'
|
||||
else:
|
||||
return ', '.join(map(str, vals))
|
||||
n = choice(ns)
|
||||
vals.append(n)
|
||||
except TimeoutException:
|
||||
if len(vals) > 12:
|
||||
beg = ', '.join(map(str, vals[:10]))
|
||||
end = ', '.join(map(str, vals[-2:]))
|
||||
return f'Timed out: {beg}, ..., {end}, ...'
|
||||
else:
|
||||
return 'Timed out: ', + ', '.join(map(str, vals))
|
||||
|
||||
def main():
|
||||
from sys import argv
|
||||
if len(argv) == 2:
|
||||
# IRC mode.
|
||||
irc(argv[1])
|
||||
elif len(argv) == 4:
|
||||
# cli mode.
|
||||
print(doit(argv[1], argv[2], argv[3]))
|
||||
else:
|
||||
print('Wrong number of arguments.')
|
||||
exit(1)
|
||||
|
||||
def doit(func, inp, args):
|
||||
n, fracs = None, None
|
||||
try:
|
||||
n = int(inp)
|
||||
except:
|
||||
return 'Input is not an integer?'
|
||||
try:
|
||||
fracs = [Fraction(*map(int, x.split('/', 1))) for x in args.replace(',', '').split()]
|
||||
except:
|
||||
return 'Could not parse fraction list.'
|
||||
|
||||
if func == 'fractran':
|
||||
func = fractran
|
||||
elif func == 'fractrand':
|
||||
func = random_unordered_fractran
|
||||
else:
|
||||
return f'Invalid function: {func}'
|
||||
|
||||
signal.signal(signal.SIGALRM, signal_handler)
|
||||
try:
|
||||
return func(n, fracs)
|
||||
except TimeoutException:
|
||||
return 'Timed out.'
|
||||
except Exception as e:
|
||||
return 'Some error occurred: ' + str (e)
|
||||
return 'Something went wrong.'
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -77,3 +77,39 @@ rand() {
|
|||
person() {
|
||||
shuf -n100 "$serv/$chan/out" | grep -v -- '-!-' | rand | awk '{print$3}' | sed 's/^<\|>$//g';
|
||||
}
|
||||
|
||||
kvnum() {
|
||||
(
|
||||
flock -s 200
|
||||
sed 's/ .*//' "$1" | grep -Fnx -e "$2" | sed 's/:.*//'
|
||||
) 200>"$1.lock"
|
||||
}
|
||||
|
||||
kvget() {
|
||||
num="$(kvnum "$1" "$2")"
|
||||
if ! [ -z "$num" ]; then
|
||||
sed -n "$num"'s/^\([^ ]* \)* //p' "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
kvset() {
|
||||
num="$(kvnum "$1" "$2")"
|
||||
if [ -z "$num" ]; then
|
||||
var "$2 $3" >> "$1"
|
||||
else
|
||||
printf '' > "$1.new"
|
||||
if [ "$num" != "1" ]; then
|
||||
sed -n '1,'"$(($num - 1))"'p' "$1" >> "$1.new"
|
||||
fi
|
||||
var "$2 $3" >> "$1.new"
|
||||
sed -n "$(($num + 1))"',$p' "$1" >> "$1.new"
|
||||
mv -f "$1.new" "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
kvdel() {
|
||||
num="$(kvnum "$1" "$2")"
|
||||
if ! [ -z "$num" ]; then
|
||||
sed -i "$num"'d' "$1"
|
||||
fi
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue