Last active
November 8, 2020 17:27
-
-
Save chuangzhu/343c82024382b4cdbd7cc22b952f98a3 to your computer and use it in GitHub Desktop.
ustclug-hackergame-2020-write-up
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
inner_op = ['', '+', '-', '*', '//', '%', '^', '&', '|', | |
'*-', '//-', '%-', '+~', '-~', '+~-', '*~', '%~', | |
'^-', '&-', '|-', '//~', '^~', '&~', '|~', | |
'+(', '-(', '*(', '%(', '^(', '&(', '|(', ')', | |
# '+((', '-((', '*((', '//((', '%((', '^((', '&((', '|((', '))', | |
')+(', ')-(', ')*(', ')//(', ')%(', ')^(', ')&(', ')|('] | |
# leading_op = ['', '-', '~', '-(', '-((', '~(', '~((', '(', '(('] | |
leading_op = ['', '-', '~', '-(', '~(', '('] | |
# trailing_op = ['', ')', '))'] | |
trailing_op = ['', ')'] | |
values = {} | |
for i in leading_op: | |
for j in inner_op: | |
for k in inner_op: | |
for l in inner_op: | |
for m in inner_op: | |
for n in inner_op: | |
for o in trailing_op: | |
eq = ''.join([i, '1', j, '1', k, '4', l, '5', m, '1', n, '4', o]) | |
try: | |
va = eval(eq) | |
if (0 < va < 114514) and (va not in values): | |
values[va] = eq | |
print(len(values), eq, end='\r') | |
except: | |
pass | |
import csv | |
f = open('114514.csv', 'w') | |
w = csv.writer(f) | |
w.writerows(sorted(values.items())) | |
f.flush() | |
f.close() | |
import re | |
import copy | |
altv = copy.copy(values) | |
def get_more(): | |
for numdt in range(255): | |
for eq in values.values(): | |
equations = [] | |
splitted = re.split('(\d+)', eq) | |
for non in range(1, len(splitted), 2): | |
temp = splitted.copy() | |
temp[non] = '~-'*numdt + temp[non] | |
equations.append(''.join(temp)) | |
for eq in equations: | |
if len(eq) > 256: | |
continue | |
try: | |
va = eval(eq) | |
if (0 < va < 114514) and (va not in altv): | |
altv[va] = eq | |
print(len(altv), eq, end='\r') | |
except: | |
pass | |
get_more() | |
values = altv | |
altv = copy.copy(values) | |
def get_even_more(): | |
for numdt in range(255): | |
for eq in values.values(): | |
eq1 = '-~'*numdt + '(' + eq + ')' | |
eq2 = '~-'*numdt + '(' + eq + ')' | |
for eq in [eq1, eq2]: | |
if len(eq) > 256: | |
continue | |
try: | |
va = eval(eq) | |
if (0 < va < 114514) and (va not in altv): | |
altv[va] = eq | |
print(len(altv), eq, end='\r') | |
except: | |
pass | |
get_even_more() | |
values = altv | |
f = open('114514-with-tricks.csv', 'w') | |
w = csv.writer(f) | |
w.writerows(sorted(values.items())) | |
f.flush() | |
f.close() |
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
import zbar | |
from PIL import Image | |
import os | |
def decode(filename): | |
scanner = zbar.ImageScanner() | |
scanner.parse_config('enable') | |
pil = Image.open(filename).convert('L') | |
width, height = pil.size | |
raw = pil.tobytes() | |
image = zbar.Image(width, height, 'Y800', raw) | |
result = scanner.scan(image) | |
if result > 1: | |
print('More than one qrcode detected.', file=os.sys.stderr) | |
if not result: | |
return None | |
for symbol in image: | |
return symbol.data | |
import glob | |
qrfiles = glob.glob('./frames/frame-*.png') | |
qrfiles.sort() | |
qrdata = [decode(fn) for fn in qrfiles] | |
# https://github.com/mchehab/zbar/issues/55 | |
qrencoded = [q.encode('ISO8859-1') for q in qrdata] | |
with open('frames.tar', 'wb') as f: | |
f.write(b''.join(qrencoded)) |
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
import requests | |
sess = requests.Session | |
sess.headers.update({'Authorization': 'Bearer ' + YOUR_TOKEN_HERE}) | |
PREFIX = 'http://202.38.93.111:10101/api' | |
def get_state(): | |
"""[{balance, id, type}, ...]""" | |
return sess.get(f'{PREFIX}/user').json()['accounts'] | |
def eat(): | |
sess.post(f'{PREFIX}/eat', json={'account': 2}) | |
def transfer(src, dst, amount): | |
sess.post(f'{PREFIX}/transfer', json={'src': src, 'dst': dst, 'amount': amount}) | |
def apply_debit(): | |
sess.post(f'{PREFIX}/create', json={'type': 'debit'}) | |
def apply_credit(): | |
sess.post(f'{PREFIX}/create', json={'type': 'credit'}) | |
def statistic(state): | |
"""balance, debt, net""" | |
debts = [c['balance'] for c in state if c['type'] == 'credit'] | |
debt = sum(debts) | |
balance = sum([card['balance'] for card in state]) - debt | |
net = balance - debt | |
return [balance, debt, net] | |
# Initialization | |
apply_credit() | |
for _ in range(998): | |
apply_debit() | |
CREDIT = 2 | |
DSTART = 3 | |
DLEN = 998 | |
state = get_state() | |
for dc in range(DSTART, DSTART+DLEN): | |
transfer(CREDIT, dc, 167) | |
# Start earning | |
while (state:=get_state())[1]: | |
print('balance: {}, debt: {}, net: {}'.format(*statistic(state)), end='\r') | |
eat() | |
# 这里甚至不需要还钱,题目算的是净资产 | |
# for dc in range(DSTART, DSTART+DLEN): | |
# transfer(dc, CREDIT, 1) |
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
import csv | |
from cn2an import cn2an | |
cr = csv.reader(open('bills.csv')) | |
next(cr) | |
cl = list(cr) | |
sum_ = 0 | |
for line in cl: | |
rest = line[0] | |
rest.replace('整', '') | |
rest.replace('分', '') | |
yuan, jiao, fen = '零'*3 | |
if '元' in rest: | |
yuan, rest = rest.split('元') | |
if '角' in rest: | |
jiao, rest = rest.split('角') | |
if '分' in rest: | |
fen, _ = rest.split('分') | |
if len(fen) > 1: | |
fen = fen.lstrip('零') | |
price = cn2an(yuan) + cn2an(jiao)*0.1 + cn2an(fen)*0.01 | |
sum_ += price * int(line[1]) | |
print(sum_) |
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
import requests | |
import re | |
import os | |
import sympy | |
from sympy.parsing.latex import parse_latex | |
session = requests.Session() | |
r = re.compile(r'<p> \$(.+)\$</p>') | |
rq = re.compile(r'<h1 class="cover-heading"> (\d+) 题</h1>') | |
session.get('http://202.38.93.111:10190/login?token=' + YOUR_TOKEN_HERE) | |
for q in range(400): | |
res = session.get('http://202.38.93.111:10190/') | |
matched = r.search(res.text).group(1) | |
latex = matched.replace(r'\,', '').replace(r'\left', '').replace(r'\right', '') | |
try: | |
formula = parse_latex(latex) | |
except sympy.parsing.latex.LaTeXParsingError: | |
print('parse_error', file=os.sys.stderr) | |
q += 1 | |
continue | |
ans = formula.evalf() | |
requests.post('http://202.38.93.111:10190/submit', data={'ans': str(ans)}) | |
res = session.get('http://202.38.93.111:10190/') | |
print(res.text) |
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
import os | |
class Board: | |
def __init__(self): | |
self.board = np.zeros((48, 48)) | |
self.xmax = 47 | |
self.ymax = 47 | |
self.blocks = [(5, 45), (5, 46), (6, 45), (6, 46), | |
(25, 45), (25, 46), (26, 45), (26, 46)] | |
for cord in self.blocks: | |
self.set_cell(*cord) | |
def __str__(self): | |
return '\n'.join([''.join(['.O'[int(c)] for c in line]) for line in self.board]) | |
def set_cell(self, x, y): | |
self.board[x][y] = 1 | |
def get_cell(self, cord): | |
x, y = cord | |
return self.board[x][y] | |
def get_cell_neighbours(self, x, y): | |
assert 0 <= x <= self.xmax and 0 <= y <= self.ymax | |
neibours = [(x_, y_) for x_ in (x-1, x, x+1) for y_ in (y-1, y, y+1)] | |
neibours.pop(4) # The cell itself | |
def filterneibour(n): | |
return 0 <= n[0] <= self.xmax and 0 <= n[1] <= self.ymax | |
neibours = filter(filterneibour, neibours) | |
return list(neibours) | |
def get_cell_field(self, x, y): | |
neighbours = self.get_cell_neighbours(x, y) | |
values = map(self.get_cell, neighbours) | |
return sum(values) | |
def field_map(self): | |
return [ | |
[self.get_cell_field(x, y) for y in range(self.ymax+1)] | |
for x in range(self.xmax+1) | |
] | |
def print_fm(self): | |
return '\n'.join([''.join([str(c) for c in line]) for line in self.field_map()]) | |
def cell_next(self, v, f): | |
if v: | |
return 1 if f in (2, 3) else 0 | |
return 1 if f == 3 else 0 | |
def next_(self): | |
fm = self.field_map() | |
for x in range(self.xmax+1): | |
for y in range(self.ymax+1): | |
self.board[x][y] = self.cell_next(self.board[x][y], fm[x][y]) | |
def is_blocks_broken(self): | |
res = list(map(self.get_cell, self.blocks)) | |
print(res, file=os.sys.stderr) | |
return not any(res) | |
def merge_matrix(self, mat): | |
self.board[0:15,0:15] = mat | |
def from_string(self, string): | |
mat = np.matrix([[int(c) for c in line] for line in string.split('\n')]) | |
self.merge_matrix(mat) | |
def glide(board, x, y): | |
delta = [(0, 0), (0, 2), (1, 1), (1, 2), (2, 1)] | |
for _x, _y in delta: | |
board.set_cell(x + _x, y + _y) | |
def lwss(board, x, y): | |
delta = [(0, 0), (0, 3), (1, 4), (2, 0), (2, 4), (3, 1), (3, 2), (3, 3), (3, 4)] | |
for _x, _y in delta: | |
board.set_cell(x + _x, y + _y) | |
if __name__ == '__main__': | |
while True: | |
r = np.random.randint(0, 2, (15, 15)) | |
b = Board() | |
b.merge_matrix(r) | |
for _ in range(200): | |
b.next_() | |
print(b, file=os.sys.stderr) | |
print(file=os.sys.stderr) | |
if b.is_blocks_broken(): | |
print('\n'.join([''.join([str(c) for c in line]) for line in r])) | |
break |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment