From: David Kerkeslager Date: Fri, 14 Jan 2022 22:02:28 +0000 (-0500) Subject: Commit my random junk X-Git-Url: https://code.kerkeslager.com/?a=commitdiff_plain;h=refs%2Fheads%2Fmaster;p=sandbox Commit my random junk --- diff --git a/async/test.py b/async/test.py new file mode 100644 index 0000000..1b1b014 --- /dev/null +++ b/async/test.py @@ -0,0 +1,71 @@ +import asyncio +import logging +import random +import string +import uuid + +import attr + +logging.basicConfig( + level=logging.INFO, + format='%(asctime)s,%(msecs)d %(levelname)s: %(message)s', + datefmt='%H:%M:%S', +) + +@attr.s +class PubSubMessage: + instance_name = attr.ib() + message_id = attr.ib(repr=False) + hostname = attr.ib(repr=False, init=False) + + def __attrs_post_init__(self): + self.hostname = f'{self.instance_name}.example.net' + + +# simulating an external publisher of events + +async def publish(queue): + choices = string.ascii_lowercase + string.digits + + while True: + msg_id = str(uuid.uuid4()) + host_id = "".join(random.choices(choices, k=4)) + instance_name = f"cattle-{host_id}" + msg = PubSubMessage(message_id=msg_id, instance_name=instance_name) + # publish an item + asyncio.create_task(queue.put(msg)) + logging.info(f"Published message {msg}") + # simulate randomness of publishing messages + await asyncio.sleep(random.random()) + + +async def consume(queue): + while True: + # wait for an item from the publisher + msg = await queue.get() + if msg is None: # publisher is done + break + + # process the msg + logging.info(f'Consumed {msg}') + # unhelpful simulation of i/o work + await asyncio.sleep(random.random()) + + +def main(): + queue = asyncio.Queue() + loop = asyncio.get_event_loop() + + try: + loop.create_task(publish(queue)) + loop.create_task(consume(queue)) + loop.run_forever() + except KeyboardInterrupt: + logging.info("Process interrupted") + finally: + loop.close() + logging.info("Successfully shutdown the Mayhem service.") + + +if __name__ == '__main__': + main() diff --git a/async/test1.py b/async/test1.py new file mode 100644 index 0000000..7b64042 --- /dev/null +++ b/async/test1.py @@ -0,0 +1,100 @@ +import asyncio +import functools +import logging +import random +import signal +import string +import uuid + +import attr + +logging.basicConfig( + level=logging.INFO, + format='%(asctime)s,%(msecs)d %(levelname)s: %(message)s', + datefmt='%H:%M:%S', +) + +@attr.s +class PubSubMessage: + instance_name = attr.ib() + message_id = attr.ib(repr=False) + hostname = attr.ib(repr=False, init=False) + restarted = attr.ib(repr=False, default=False) + saved = attr.ib(repr=False, default=False) + acked = attr.ib(repr=False, default=False) + extended_cnt = attr.ib(repr=False, default=0) + + def __attrs_post_init__(self): + self.hostname = f"{self.instance_name}.example.net" + +async def publish(queue): + choices = string.ascii_lowercase + string.digits + + while True: + msg_id = str(uuid.uuid4()) + host_id = "".join(random.choices(choices, k=4)) + instance_name = f"cattle-{host_id}" + msg = PubSubMessage(message_id=msg_id, instance_name=instance_name) + # publish an item + asyncio.create_task(queue.put(msg)) + logging.debug(f"Published message {msg}") + # simulate randomness of publishing messages + await asyncio.sleep(random.random()) + +async def restart_host(msg): + # unhelpful simulation of i/o work + await asyncio.sleep(random.random()) + msg.restart = True + logging.info(f"Restarted {msg.hostname}") + +async def save(msg): + # unhelpful simulation of i/o work + await asyncio.sleep(random.random()) + msg.save = True + logging.info(f"Saved {msg} into database") + +async def cleanup(msg, event): + # this will block the rest of the coro until `event.set` is called + await event.wait() + # unhelpful simulation of i/o work + await asyncio.sleep(random.random()) + msg.acked = True + logging.info(f"Done. Acked {msg}") + +async def extend(msg, event): + while not event.is_set(): + msg.extended_cnt += 1 + logging.info(f"Extended deadline by 3 seconds for {msg}") + # want to sleep for less than the deadline amount + await asyncio.sleep(2) + +async def handle_message(msg): + event = asyncio.Event() + asyncio.create_task(extend(msg, event)) + asyncio.create_task(cleanup(msg, event)) + + await asyncio.gather(save(msg), restart_host(msg)) + event.set() + +async def consume(queue): + while True: + msg = await queue.get() + logging.info(f"Consumed {msg}") + asyncio.create_task(handle_message(msg)) + +def main(): + queue = asyncio.Queue() + loop = asyncio.get_event_loop() + + try: + loop.create_task(publish(queue)) + loop.create_task(consume(queue)) + loop.run_forever() + except KeyboardInterrupt: + logging.info("Process interrupted") + finally: + loop.close() + logging.info("Successfully shutdown the Mayhem service.") + +if __name__ == "__main__": + main() diff --git a/binarypuzzle/gen.py b/binarypuzzle/gen.py new file mode 100644 index 0000000..2ee7395 --- /dev/null +++ b/binarypuzzle/gen.py @@ -0,0 +1,117 @@ +import itertools, math, re, sys + +size = 4 + +if size % 2 != 0: + raise Exception('Size must be an even number') + +fmt = '{{:0{}b}}'.format(size) + +valid_rows = [] + +num_zeroes = size // 2 + +for i in range(pow(2,size)): + row = fmt.format(i) + + if row.count('0') == num_zeroes and ('000' not in row) and ('111' not in row): + valid_rows.append(row) + +valid_rows_count = len(valid_rows) + +print('{} valid rows of {} digits found.'.format(valid_rows_count, size)) +print('This will generate and test {} boards.'.format(math.prod(range( + valid_rows_count - size + 1, + valid_rows_count + 1, +)))) + +decision = input('Proceed with generation? (y/n) ') + +while decision.lower() not in ('y', 'n'): + decision = input('Proceed with generation? (y/n) ') + +if decision == 'n': + sys.exit(0) + +valid_rows_set = set(valid_rows) + +def rotate(board): + return tuple(''.join(row) for row in zip(*board)) + +def all_rows_valid(board): + return all((row in valid_rows_set) for row in board) + +def all_rows_unique(board): + return not any((r0 == r1) for r0, r1 in itertools.combinations(board, 2)) + +valid_boards = [] + +for board in itertools.permutations(valid_rows, size): + # We know that all the rows are valid and unique but we don't know if the + # columns are. + board = rotate(board) + # Now we know that all the columns are valid and unique but we don't know + # if the rows are. + + if all_rows_valid(board) and all_rows_unique(board): + valid_boards.append(''.join(board)) + print('\n'.join(board) + '\n') + +print('{} valid boards found.'.format(len(valid_boards))) + +decision = input('Proceed with generation? (y/n) ') + +while decision.lower() not in ('y', 'n'): + decision = input('Proceed with generation? (y/n) ') + +if decision == 'n': + sys.exit(0) + +area = size * size +filters = { valid_boards[0]: ['.' * area] } + +for board_count in range(1, len(valid_boards)): + current_board = valid_boards[board_count] + + new_filters = {} + + new_filters[current_board] = set() + + for previous_board in filters: + differences = [i for i in range(size) if previous_board[i] != current_board[i]] + + new_filters[previous_board] = set() + + for old_filter in filters[previous_board]: + if re.match(old_filter, current_board): + for d in differences: + new_filters[previous_board].add( + old_filter[:d] + previous_board[d] + old_filter[d + 1:] + ) + new_filters[current_board].add( + old_filter[:d] + current_board[d] + old_filter[d + 1:] + ) + + else: + new_filters[previous_board].add(old_filter) + + print('Round {} complete, {} filters'.format(board_count, len(new_filters))) + + filters = new_filters + + removed_count = 0 + + for b in filters: + c = filters[b].copy() + + for f0, f1 in itertools.permutations(c, 2): + if re.match(f0, f1): + filters[b].remove(f1) + removed_count += 1 + + print(removed_count) + + +with open('generated.txt', 'w') as gen_file: + for f in filters: + gen_file.write('\n'.join(f[i:i + size] for i in range(0, area, size)) + '\n\n') diff --git a/binarypuzzle/generated.txt b/binarypuzzle/generated.txt new file mode 100644 index 0000000..4c77308 --- /dev/null +++ b/binarypuzzle/generated.txt @@ -0,0 +1,360 @@ +1100 +1010 +0101 +0011 + +1100 +1001 +0110 +0011 + +1100 +1010 +0011 +0101 + +1100 +1001 +0011 +0110 + +1010 +1100 +0101 +0011 + +1001 +1100 +0110 +0011 + +1010 +1100 +0011 +0101 + +1001 +1100 +0011 +0110 + +1010 +1001 +0110 +0101 + +1010 +1001 +0101 +0110 + +1001 +1010 +0110 +0101 + +1001 +1010 +0101 +0110 + +1100 +0110 +1001 +0011 + +1100 +0101 +1010 +0011 + +1100 +0011 +1010 +0101 + +1100 +0011 +1001 +0110 + +1010 +0101 +1100 +0011 + +1001 +0110 +1100 +0011 + +1010 +0110 +1001 +0101 + +1010 +0101 +1001 +0110 + +1001 +0110 +1010 +0101 + +1001 +0101 +1010 +0110 + +1010 +0011 +1100 +0101 + +1001 +0011 +1100 +0110 + +1100 +0110 +0011 +1001 + +1100 +0101 +0011 +1010 + +1100 +0011 +0110 +1001 + +1100 +0011 +0101 +1010 + +1010 +0110 +0101 +1001 + +1010 +0101 +0110 +1001 + +1001 +0110 +0101 +1010 + +1001 +0101 +0110 +1010 + +1010 +0101 +0011 +1100 + +1001 +0110 +0011 +1100 + +1010 +0011 +0101 +1100 + +1001 +0011 +0110 +1100 + +0110 +1100 +1001 +0011 + +0101 +1100 +1010 +0011 + +0110 +1001 +1100 +0011 + +0101 +1010 +1100 +0011 + +0110 +1010 +1001 +0101 + +0110 +1001 +1010 +0101 + +0101 +1010 +1001 +0110 + +0101 +1001 +1010 +0110 + +0011 +1100 +1010 +0101 + +0011 +1100 +1001 +0110 + +0011 +1010 +1100 +0101 + +0011 +1001 +1100 +0110 + +0110 +1100 +0011 +1001 + +0101 +1100 +0011 +1010 + +0110 +1010 +0101 +1001 + +0110 +1001 +0101 +1010 + +0101 +1010 +0110 +1001 + +0101 +1001 +0110 +1010 + +0110 +1001 +0011 +1100 + +0101 +1010 +0011 +1100 + +0011 +1100 +0110 +1001 + +0011 +1100 +0101 +1010 + +0011 +1010 +0101 +1100 + +0011 +1001 +0110 +1100 + +0110 +0101 +1010 +1001 + +0110 +0101 +1001 +1010 + +0101 +0110 +1010 +1001 + +0101 +0110 +1001 +1010 + +0110 +0011 +1100 +1001 + +0101 +0011 +1100 +1010 + +0110 +0011 +1001 +1100 + +0101 +0011 +1010 +1100 + +0011 +0110 +1100 +1001 + +0011 +0101 +1100 +1010 + +0011 +0110 +1001 +1100 + +0011 +0101 +1010 +1100 + diff --git a/binarypuzzle/graph.csv b/binarypuzzle/graph.csv new file mode 100644 index 0000000..fcd635d --- /dev/null +++ b/binarypuzzle/graph.csv @@ -0,0 +1,42 @@ +20, 19609 +21, 22461 +22, 24390 +23, 26881 +24, 30287 +25, 34593 +26, 37834 +27, 42331 +28, 46786 +29, 52063 +30, 58843 +31, 65144 +32, 70762 +33, 77387 +34, 83950 +35, 91087 +36, 95096 +37, 100310 +38, 104217 +39, 108787 +40, 113440 +41, 118336 +42, 125003 +43, 131756 +44, 138756 +45, 145995 +46, 152953 +47, 160377 +48, 170951 +49, 184353 +50, 193999 +51, 204494 +52, 214852 +53, 228348 +54, 239542 +55, 253858 +56, 266775 +57, 281233 +58, 296618 +59, 311858 +60, 323663 +61, 335655 diff --git a/crypto-bot/main.py b/crypto-bot/main.py new file mode 100644 index 0000000..1d815d4 --- /dev/null +++ b/crypto-bot/main.py @@ -0,0 +1,30 @@ +from web3 import Web3 + +# To Connect to Ethereum Mainnet +# w3 = Web3(Web3.HTTPProvider('https://mainnet.infura.io/v3/2981846319d3433d83aecfda7d175554')) + +w3 = Web3(Web3.HTTPProvider('https://polygon-mainnet.infura.io/v3/a6a37efdbfe141a898135c1848d2352b')) + +from web3.middleware import geth_poa_middleware +w3.middleware_onion.inject(geth_poa_middleware, layer=0) + +WEI_PER_ETH = 1000000000000000000 + +balance = w3.eth.get_balance('0x87885F4D036d8BBf56c1721e9975073b81f5Cd9c') + +COIN_CONTRACTS = { + 'CRV': 0x172370d5cd63279efa6d502dab29171933a610af, + 'LINK': 0x53E0bca35eC356BD5ddDFebbD1Fc0fD03FaBad39, + 'NORD': 0xf6f85b3f9fd581c2ee717c404f7684486f057f95, + 'USDC': 0x2791bca1f2de4661ed88a30c99a7a9449aa84174, + 'WETH': 0x7ceb23fd6bc0add59e62ac25578270cff1b9f619, +} + +SUSHISWAP_CONTRACT = w3.eth.contract( + address='0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506', + abi=''' +[{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_WETH","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"amountADesired","type":"uint256"},{"internalType":"uint256","name":"amountBDesired","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amountTokenDesired","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"}],"name":"getAmountIn","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"}],"name":"getAmountOut","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"}],"name":"getAmountsIn","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"}],"name":"getAmountsOut","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"reserveA","type":"uint256"},{"internalType":"uint256","name":"reserveB","type":"uint256"}],"name":"quote","outputs":[{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETHSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityETHWithPermit","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityETHWithPermitSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityWithPermit","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapETHForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETHSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}] + ''', +) + +import ipdb; ipdb.set_trace() diff --git a/crypto-bot/run.sh b/crypto-bot/run.sh new file mode 100755 index 0000000..1a9e849 --- /dev/null +++ b/crypto-bot/run.sh @@ -0,0 +1 @@ +PYTHONWARNINGS=default python main.py diff --git a/cryptopals-python/cryptopals.py b/cryptopals-python/cryptopals.py index ee81112..24392b8 100644 --- a/cryptopals-python/cryptopals.py +++ b/cryptopals-python/cryptopals.py @@ -41,6 +41,19 @@ def encrypt_with_repeating_xor(plaintext, key): (key_bytes * ((len(plaintext_bytes) // len(key_bytes)) + 1))[:len(plaintext_bytes)], ) +def hamming_weight(_bytes): + def hamming_weight_of_byte(b): + count = 0 + while b > 0: + count += 1 + b &= b - 1 + return count + + return sum(hamming_weight_of_byte(b) for b in _bytes) + +def hamming_distance(bytes0, bytes1): + return hamming_weight(xor_bytes(bytes0, bytes1)) + class Set1Challenge1Tests(unittest.TestCase): def test_converts_hex_to_base64(self): expected = 'SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t\n' @@ -127,5 +140,19 @@ class Set1Challenge5Tests(unittest.TestCase): self.assertEqual(expected, actual) +with open('set1challenge6.txt','r') as f: + set1challenge6text = f.read() + +class Set1Challenge6Tests(unittest.TestCase): + def test_hamming_distance(self): + expected = 37 + actual = hamming_distance(b'this is a test', b'wokka wokka!!!') + self.assertEqual(expected, actual) + + def test_find_repeated_xor_keysize(self): + expected = 0 + actual = find_repeated_xor_keysize(set1challenge6text) + self.assertEqual(expected, actual) + if __name__ == '__main__': unittest.main() diff --git a/cryptopals-python/set1challenge6.txt b/cryptopals-python/set1challenge6.txt new file mode 100644 index 0000000..cecdb81 --- /dev/null +++ b/cryptopals-python/set1challenge6.txt @@ -0,0 +1,64 @@ +HUIfTQsPAh9PE048GmllH0kcDk4TAQsHThsBFkU2AB4BSWQgVB0dQzNTTmVS +BgBHVBwNRU0HBAxTEjwMHghJGgkRTxRMIRpHKwAFHUdZEQQJAGQmB1MANxYG +DBoXQR0BUlQwXwAgEwoFR08SSAhFTmU+Fgk4RQYFCBpGB08fWXh+amI2DB0P +QQ1IBlUaGwAdQnQEHgFJGgkRAlJ6f0kASDoAGhNJGk9FSA8dDVMEOgFSGQEL +QRMGAEwxX1NiFQYHCQdUCxdBFBZJeTM1CxsBBQ9GB08dTnhOSCdSBAcMRVhI +CEEATyBUCHQLHRlJAgAOFlwAUjBpZR9JAgJUAAELB04CEFMBJhAVTQIHAh9P +G054MGk2UgoBCVQGBwlTTgIQUwg7EAYFSQ8PEE87ADpfRyscSWQzT1QCEFMa +TwUWEXQMBk0PAg4DQ1JMPU4ALwtJDQhOFw0VVB1PDhxFXigLTRkBEgcKVVN4 +Tk9iBgELR1MdDAAAFwoFHww6Ql5NLgFBIg4cSTRWQWI1Bk9HKn47CE8BGwFT +QjcEBx4MThUcDgYHKxpUKhdJGQZZVCFFVwcDBVMHMUV4LAcKQR0JUlk3TwAm +HQdJEwATARNFTg5JFwQ5C15NHQYEGk94dzBDADsdHE4UVBUaDE5JTwgHRTkA +Umc6AUETCgYAN1xGYlUKDxJTEUgsAA0ABwcXOwlSGQELQQcbE0c9GioWGgwc +AgcHSAtPTgsAABY9C1VNCAINGxgXRHgwaWUfSQcJABkRRU8ZAUkDDTUWF01j +OgkRTxVJKlZJJwFJHQYADUgRSAsWSR8KIgBSAAxOABoLUlQwW1RiGxpOCEtU +YiROCk8gUwY1C1IJCAACEU8QRSxORTBSHQYGTlQJC1lOBAAXRTpCUh0FDxhU +ZXhzLFtHJ1JbTkoNVDEAQU4bARZFOwsXTRAPRlQYE042WwAuGxoaAk5UHAoA +ZCYdVBZ0ChQLSQMYVAcXQTwaUy1SBQsTAAAAAAAMCggHRSQJExRJGgkGAAdH +MBoqER1JJ0dDFQZFRhsBAlMMIEUHHUkPDxBPH0EzXwArBkkdCFUaDEVHAQAN +U29lSEBAWk44G09fDXhxTi0RAk4ITlQbCk0LTx4cCjBFeCsGHEETAB1EeFZV +IRlFTi4AGAEORU4CEFMXPBwfCBpOAAAdHUMxVVUxUmM9ElARGgZBAg4PAQQz +DB4EGhoIFwoKUDFbTCsWBg0OTwEbRSonSARTBDpFFwsPCwIATxNOPBpUKhMd +Th5PAUgGQQBPCxYRdG87TQoPD1QbE0s9GkFiFAUXR0cdGgkADwENUwg1DhdN +AQsTVBgXVHYaKkg7TgNHTB0DAAA9DgQACjpFX0BJPQAZHB1OeE5PYjYMAg5M +FQBFKjoHDAEAcxZSAwZOBREBC0k2HQxiKwYbR0MVBkVUHBZJBwp0DRMDDk5r +NhoGACFVVWUeBU4MRREYRVQcFgAdQnQRHU0OCxVUAgsAK05ZLhdJZChWERpF +QQALSRwTMRdeTRkcABcbG0M9Gk0jGQwdR1ARGgNFDRtJeSchEVIDBhpBHQlS +WTdPBzAXSQ9HTBsJA0UcQUl5bw0KB0oFAkETCgYANlVXKhcbC0sAGgdFUAIO +ChZJdAsdTR0HDBFDUk43GkcrAAUdRyonBwpOTkJEUyo8RR8USSkOEENSSDdX +RSAdDRdLAA0HEAAeHQYRBDYJC00MDxVUZSFQOV1IJwYdB0dXHRwNAA9PGgMK +OwtTTSoBDBFPHU54W04mUhoPHgAdHEQAZGU/OjV6RSQMBwcNGA5SaTtfADsX +GUJHWREYSQAnSARTBjsIGwNOTgkVHRYANFNLJ1IIThVIHQYKAGQmBwcKLAwR +DB0HDxNPAU94Q083UhoaBkcTDRcAAgYCFkU1RQUEBwFBfjwdAChPTikBSR0T +TwRIEVIXBgcURTULFk0OBxMYTwFUN0oAIQAQBwkHVGIzQQAGBR8EdCwRCEkH +ElQcF0w0U05lUggAAwANBxAAHgoGAwkxRRMfDE4DARYbTn8aKmUxCBsURVQf +DVlOGwEWRTIXFwwCHUEVHRcAMlVDKRsHSUdMHQMAAC0dCAkcdCIeGAxOazkA +BEk2HQAjHA1OAFIbBxNJAEhJBxctDBwKSRoOVBwbTj8aQS4dBwlHKjUECQAa +BxscEDMNUhkBC0ETBxdULFUAJQAGARFJGk9FVAYGGlMNMRcXTRoBDxNPeG43 +TQA7HRxJFUVUCQhBFAoNUwctRQYFDE43PT9SUDdJUydcSWRtcwANFVAHAU5T +FjtFGgwbCkEYBhlFeFsABRcbAwZOVCYEWgdPYyARNRcGAQwKQRYWUlQwXwAg +ExoLFAAcARFUBwFOUwImCgcDDU5rIAcXUj0dU2IcBk4TUh0YFUkASEkcC3QI +GwMMQkE9SB8AMk9TNlIOCxNUHQZCAAoAHh1FXjYCDBsFABkOBkk7FgALVQRO +D0EaDwxOSU8dGgI8EVIBAAUEVA5SRjlUQTYbCk5teRsdRVQcDhkDADBFHwhJ +AQ8XClJBNl4AC1IdBghVEwARABoHCAdFXjwdGEkDCBMHBgAwW1YnUgAaRyon +B0VTGgoZUwE7EhxNCAAFVAMXTjwaTSdSEAESUlQNBFJOZU5LXHQMHE0EF0EA +Bh9FeRp5LQdFTkAZREgMU04CEFMcMQQAQ0lkay0ABwcqXwA1FwgFAk4dBkIA +CA4aB0l0PD1MSQ8PEE87ADtbTmIGDAILAB0cRSo3ABwBRTYKFhROHUETCgZU +MVQHYhoGGksABwdJAB0ASTpFNwQcTRoDBBgDUkksGioRHUkKCE5THEVCC08E +EgF0BBwJSQoOGkgGADpfADETDU5tBzcJEFMLTx0bAHQJCx8ADRJUDRdMN1RH +YgYGTi5jMURFeQEaSRAEOkURDAUCQRkKUmQ5XgBIKwYbQFIRSBVJGgwBGgtz +RRNNDwcVWE8BT3hJVCcCSQwGQx9IBE4KTwwdASEXF01jIgQATwZIPRpXKwYK +BkdEGwsRTxxDSToGMUlSCQZOFRwKUkQ5VEMnUh0BR0MBGgAAZDwGUwY7CBdN +HB5BFwMdUz0aQSwWSQoITlMcRUILTxoCEDUXF01jNw4BTwVBNlRBYhAIGhNM +EUgIRU5CRFMkOhwGBAQLTVQOHFkvUkUwF0lkbXkbHUVUBgAcFA0gRQYFCBpB +PU8FQSsaVycTAkJHYhsRSQAXABxUFzFFFggICkEDHR1OPxoqER1JDQhNEUgK +TkJPDAUAJhwQAg0XQRUBFgArU04lUh0GDlNUGwpOCU9jeTY1HFJARE4xGA4L +ACxSQTZSDxsJSw1ICFUdBgpTNjUcXk0OAUEDBxtUPRpCLQtFTgBPVB8NSRoK +SREKLUUVAklkERgOCwAsUkE2Ug8bCUsNSAhVHQYKUyI7RQUFABoEVA0dWXQa +Ry1SHgYOVBFIB08XQ0kUCnRvPgwQTgUbGBwAOVREYhAGAQBJEUgETgpPGR8E +LUUGBQgaQRIaHEshGk03AQANR1QdBAkAFwAcUwE9AFxNY2QxGA4LACxSQTZS +DxsJSw1ICFUdBgpTJjsIF00GAE1ULB1NPRpPLF5JAgJUVAUAAAYKCAFFXjUe +DBBOFRwOBgA+T04pC0kDElMdC0VXBgYdFkU2CgtNEAEUVBwTWXhTVG5SGg8e +AB0cRSo+AwgKRSANExlJCBQaBAsANU9TKxFJL0dMHRwRTAtPBRwQMAAATQcB +FlRlIkw5QwA2GggaR0YBBg5ZTgIcAAw3SVIaAQcVEU8QTyEaYy0fDE4ITlhI +Jk8DCkkcC3hFMQIEC0EbAVIqCFZBO1IdBgZUVA4QTgUWSR4QJwwRTWM= diff --git a/furfur/main.fur b/furfur/main.fur new file mode 100644 index 0000000..0a12cc0 --- /dev/null +++ b/furfur/main.fur @@ -0,0 +1,76 @@ +enum TokenType + CLOSE_BRACE, + CLOSE_BRACKET, + CLOSE_PARENTHESE, + COLON, + COMMA, + DEF, + DO, + END, + ENUM, + EQUALS, + IDENTIFIER, + IF, + OPEN_BRACE, + OPEN_BRACKET, + OPEN_PARENTHESE, + PERIOD, + STRING_LITERAL, + WITH, +end + +struct Token + TokenType tokenType + string lexeme +end + +def scan(source) + SINGLE_CHARACTER_TOKENS = { + '}': TokenType.CLOSE_BRACE, + ']': TokenType.CLOSE_BRACKET, + ')': TokenType.CLOSE_PARENTHESE, + ':': TokenType.COLON, + ',': TokenType.COMMA, + '{': TokenType.OPEN_BRACE, + '[': TokenType.OPEN_BRACKET, + '(': TokenType.OPEN_PARENTHESE, + '.': TokenType.PERIOD, + } + + def match(source) + if source[0] in SINGLE_CHARACTER_TOKENS + Token { + tokenType: SINGLE_CHARACTER_TOKENS[source[0]], + lexeme: source[0] + } + else + end + end +end + +def parse(tokens) +end + +def generate(ast) +end + +def compile(source) + tokens = scan(source) + ast = parse(tokens) + generate(ast) +end + +source_file_path = __arguments__[0] +destination_file_path = __argument__[1] + +with open(source_file_path, 'r') as source_file + source = source_file.read() +end + +c = compile(source) + +with open(destination_file_path, 'w') as destination_file do + destination_file.write(c) +end + + diff --git a/furfur/syntax.fparse b/furfur/syntax.fparse new file mode 100644 index 0000000..356762e --- /dev/null +++ b/furfur/syntax.fparse @@ -0,0 +1,20 @@ +__IGNORE__ = /[ \n\t]*/ + +CLOSE_PARENTHESE = ')' +EQUALS = '=' +OPEN_PARENTHESE = '(' + +DEF = 'def' +END = 'end' + +IDENTIFIER = /[A-Za-z_][A-Za-z_0-9]*/ +NUMBER = /\d+(\.\d+)?/ +STRING = /'(.*?|\\')'|"(.*?|\\")"/ + +expression = + +assignment_statement = IDENTIFIER EQUALS expression +function_definition_statement = DEF IDENTIFIER OPEN_PARENTHESE argument_definition_list CLOSE_PARENTHESE statement_list END +expression_statement = expression + +statement = assignment_statement | function_definition_statement diff --git a/pylox/main.py b/pylox/main.py new file mode 100644 index 0000000..1972baa --- /dev/null +++ b/pylox/main.py @@ -0,0 +1,88 @@ +import enum +import sys + +class TokenType(enum.Enum): + LEFT_PARENTHESE = enum.auto() + RIGHT_PARENTHESE = enum.auto() + LEFT_BRACE = enum.auto() + RIGHT_BRACE = enum.auto() + LEFT_BRACKET = enum.auto() + RIGHT_BRACKET = enum.auo() + COMMA = enum.auto() + DOT = enum.auto() + MINUS = enum.auto() + PLUS = enum.auto() + SLASH = enum.auto() + STAR = enum.auto() + PERCENT = enum.auto() + + BANG = enum.auto() + BANG_EQUALS = enum.auto() + EQUAL = enum.auto() + EQUALS_EQUALS = enum.auto() + LESS_THAN = enum.auto() + LESS_THAN_EQUALS = enum.auto() + GREATER_THAN = enum.auto() + GREATER_THAN_EQUALS = enum.auto() + + IDENTIFIER = enum.auto() + STRING = enum.auto() + NUMBER = enum.auto() + + AND = enum.auto() + ELSE = enum.auto() + END = enum.auto() + FALSE = enum.auto() + FOR = enum.auto() + IF = enum.auto() + NIL = enum.auto() + NOT = enum.auto() + OR = enum.auto() + TRUE = enum.auto() + + +had_error = False + +def error(line, message): + report(line, '', message) + +def report(line, where, message): + print('[line {}] Error {}: {}'.format( + line, + where, + message, + ) + + had_error = True + +def run(source): + tokens = scan_tokens(source) + + for token in tokens: + print(token) + +def run_file(path): + with open(path, 'r') as f: + run(f.read()) + + if had_error: + sys.exit(65) + +def run_prompt(): + while True: + line = input('> ') + if not line: + break + run(line) + had_error = False + +if __name__ == '__main__': + if len(sys.argv) > 2: + print('Usage: pylox [script]') + sys.exit(65) + + elif len(sys.argv) == 2: + run_file(sys.args[1]) + + else: + run_prompt() diff --git a/seive.py b/seive.py new file mode 100644 index 0000000..41ed324 --- /dev/null +++ b/seive.py @@ -0,0 +1,13 @@ +seive = {} +counter = 2 +limit = 1000 + +while counter < limit: + if counter in seive: + for factor in seive[counter]: + seive[counter + factor] = seive.get(counter + factor, []) + [factor] + else: + print(counter) + seive[counter**2] = [counter] + + counter += 1 diff --git a/solidity/contracts/Migrations.sol b/solidity/contracts/Migrations.sol new file mode 100644 index 0000000..9aac975 --- /dev/null +++ b/solidity/contracts/Migrations.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.4.22 <0.9.0; + +contract Migrations { + address public owner = msg.sender; + uint public last_completed_migration; + + modifier restricted() { + require( + msg.sender == owner, + "This function is restricted to the contract's owner" + ); + _; + } + + function setCompleted(uint completed) public restricted { + last_completed_migration = completed; + } +} diff --git a/solidity/migrations/1_initial_migration.js b/solidity/migrations/1_initial_migration.js new file mode 100644 index 0000000..16a7ba5 --- /dev/null +++ b/solidity/migrations/1_initial_migration.js @@ -0,0 +1,5 @@ +const Migrations = artifacts.require("Migrations"); + +module.exports = function (deployer) { + deployer.deploy(Migrations); +}; diff --git a/solidity/test/.gitkeep b/solidity/test/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/solidity/token.sol b/solidity/token.sol new file mode 100644 index 0000000..6a34925 --- /dev/null +++ b/solidity/token.sol @@ -0,0 +1,350 @@ +pragma solidity ^0.8.4; + +pragma solidity ^0.8.0; + +/** + * @dev Interface of the ERC20 standard as defined in the EIP. + */ +interface IERC20 { + /** + * @dev Returns the amount of tokens in existence. + */ + function totalSupply() external view returns (uint256); + + /** + * @dev Returns the amount of tokens owned by `account`. + */ + function balanceOf(address account) external view returns (uint256); + + /** + * @dev Moves `amount` tokens from the caller's account to `recipient`. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transfer(address recipient, uint256 amount) external returns (bool); + + /** + * @dev Returns the remaining number of tokens that `spender` will be + * allowed to spend on behalf of `owner` through {transferFrom}. This is + * zero by default. + * + * This value changes when {approve} or {transferFrom} are called. + */ + function allowance(address owner, address spender) external view returns (uint256); + + /** + * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * IMPORTANT: Beware that changing an allowance with this method brings the risk + * that someone may use both the old and the new allowance by unfortunate + * transaction ordering. One possible solution to mitigate this race + * condition is to first reduce the spender's allowance to 0 and set the + * desired value afterwards: + * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 + * + * Emits an {Approval} event. + */ + function approve(address spender, uint256 amount) external returns (bool); + + /** + * @dev Moves `amount` tokens from `sender` to `recipient` using the + * allowance mechanism. `amount` is then deducted from the caller's + * allowance. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); + + /** + * @dev Emitted when `value` tokens are moved from one account (`from`) to + * another (`to`). + * + * Note that `value` may be zero. + */ + event Transfer(address indexed from, address indexed to, uint256 value); + + /** + * @dev Emitted when the allowance of a `spender` for an `owner` is set by + * a call to {approve}. `value` is the new allowance. + */ + event Approval(address indexed owner, address indexed spender, uint256 value); +} + +contract Token is IERC20 { + mapping (address => uint256) private _balances; + + mapping (address => mapping (address => uint256)) private _allowances; + + uint256 private _totalSupply; + + string private _name; + string private _symbol; + + /** + * @dev Sets the values for {name} and {symbol}. + * + * The defaut value of {decimals} is 18. To select a different value for + * {decimals} you should overload it. + * + * All two of these values are immutable: they can only be set once during + * construction. + */ + constructor (string memory name_, string memory symbol_) { + _name = name_; + _symbol = symbol_; + } + + /** + * @dev Returns the name of the token. + */ + function name() public view virtual override returns (string memory) { + return _name; + } + + /** + * @dev Returns the symbol of the token, usually a shorter version of the + * name. + */ + function symbol() public view virtual override returns (string memory) { + return _symbol; + } + + /** + * @dev Returns the number of decimals used to get its user representation. + * For example, if `decimals` equals `2`, a balance of `505` tokens should + * be displayed to a user as `5,05` (`505 / 10 ** 2`). + * + * Tokens usually opt for a value of 18, imitating the relationship between + * Ether and Wei. This is the value {ERC20} uses, unless this function is + * overridden; + * + * NOTE: This information is only used for _display_ purposes: it in + * no way affects any of the arithmetic of the contract, including + * {IERC20-balanceOf} and {IERC20-transfer}. + */ + function decimals() public view virtual override returns (uint8) { + return 18; + } + + /** + * @dev See {IERC20-totalSupply}. + */ + function totalSupply() public view virtual override returns (uint256) { + return _totalSupply; + } + + /** + * @dev See {IERC20-balanceOf}. + */ + function balanceOf(address account) public view virtual override returns (uint256) { + return _balances[account]; + } + + /** + * @dev See {IERC20-transfer}. + * + * Requirements: + * + * - `recipient` cannot be the zero address. + * - the caller must have a balance of at least `amount`. + */ + function transfer(address recipient, uint256 amount) public virtual override returns (bool) { + _transfer(_msgSender(), recipient, amount); + return true; + } + + /** + * @dev See {IERC20-allowance}. + */ + function allowance(address owner, address spender) public view virtual override returns (uint256) { + return _allowances[owner][spender]; + } + + /** + * @dev See {IERC20-approve}. + * + * Requirements: + * + * - `spender` cannot be the zero address. + */ + function approve(address spender, uint256 amount) public virtual override returns (bool) { + _approve(_msgSender(), spender, amount); + return true; + } + + /** + * @dev See {IERC20-transferFrom}. + * + * Emits an {Approval} event indicating the updated allowance. This is not + * required by the EIP. See the note at the beginning of {ERC20}. + * + * Requirements: + * + * - `sender` and `recipient` cannot be the zero address. + * - `sender` must have a balance of at least `amount`. + * - the caller must have allowance for ``sender``'s tokens of at least + * `amount`. + */ + function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { + _transfer(sender, recipient, amount); + + uint256 currentAllowance = _allowances[sender][_msgSender()]; + require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance"); + _approve(sender, _msgSender(), currentAllowance - amount); + + return true; + } + + /** + * @dev Atomically increases the allowance granted to `spender` by the caller. + * + * This is an alternative to {approve} that can be used as a mitigation for + * problems described in {IERC20-approve}. + * + * Emits an {Approval} event indicating the updated allowance. + * + * Requirements: + * + * - `spender` cannot be the zero address. + */ + function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { + _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue); + return true; + } + + /** + * @dev Atomically decreases the allowance granted to `spender` by the caller. + * + * This is an alternative to {approve} that can be used as a mitigation for + * problems described in {IERC20-approve}. + * + * Emits an {Approval} event indicating the updated allowance. + * + * Requirements: + * + * - `spender` cannot be the zero address. + * - `spender` must have allowance for the caller of at least + * `subtractedValue`. + */ + function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { + uint256 currentAllowance = _allowances[_msgSender()][spender]; + require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); + _approve(_msgSender(), spender, currentAllowance - subtractedValue); + + return true; + } + + /** + * @dev Moves tokens `amount` from `sender` to `recipient`. + * + * This is internal function is equivalent to {transfer}, and can be used to + * e.g. implement automatic token fees, slashing mechanisms, etc. + * + * Emits a {Transfer} event. + * + * Requirements: + * + * - `sender` cannot be the zero address. + * - `recipient` cannot be the zero address. + * - `sender` must have a balance of at least `amount`. + */ + function _transfer(address sender, address recipient, uint256 amount) internal virtual { + require(sender != address(0), "ERC20: transfer from the zero address"); + require(recipient != address(0), "ERC20: transfer to the zero address"); + + _beforeTokenTransfer(sender, recipient, amount); + + uint256 senderBalance = _balances[sender]; + require(senderBalance >= amount, "ERC20: transfer amount exceeds balance"); + _balances[sender] = senderBalance - amount; + _balances[recipient] += amount; + + emit Transfer(sender, recipient, amount); + } + + /** @dev Creates `amount` tokens and assigns them to `account`, increasing + * the total supply. + * + * Emits a {Transfer} event with `from` set to the zero address. + * + * Requirements: + * + * - `to` cannot be the zero address. + */ + function _mint(address account, uint256 amount) internal virtual { + require(account != address(0), "ERC20: mint to the zero address"); + + _beforeTokenTransfer(address(0), account, amount); + + _totalSupply += amount; + _balances[account] += amount; + emit Transfer(address(0), account, amount); + } + + /** + * @dev Destroys `amount` tokens from `account`, reducing the + * total supply. + * + * Emits a {Transfer} event with `to` set to the zero address. + * + * Requirements: + * + * - `account` cannot be the zero address. + * - `account` must have at least `amount` tokens. + */ + function _burn(address account, uint256 amount) internal virtual { + require(account != address(0), "ERC20: burn from the zero address"); + + _beforeTokenTransfer(account, address(0), amount); + + uint256 accountBalance = _balances[account]; + require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); + _balances[account] = accountBalance - amount; + _totalSupply -= amount; + + emit Transfer(account, address(0), amount); + } + + /** + * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. + * + * This internal function is equivalent to `approve`, and can be used to + * e.g. set automatic allowances for certain subsystems, etc. + * + * Emits an {Approval} event. + * + * Requirements: + * + * - `owner` cannot be the zero address. + * - `spender` cannot be the zero address. + */ + function _approve(address owner, address spender, uint256 amount) internal virtual { + require(owner != address(0), "ERC20: approve from the zero address"); + require(spender != address(0), "ERC20: approve to the zero address"); + + _allowances[owner][spender] = amount; + emit Approval(owner, spender, amount); + } + + /** + * @dev Hook that is called before any transfer of tokens. This includes + * minting and burning. + * + * Calling conditions: + * + * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens + * will be to transferred to `to`. + * - when `from` is zero, `amount` tokens will be minted for `to`. + * - when `to` is zero, `amount` of ``from``'s tokens will be burned. + * - `from` and `to` are never both zero. + * + * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. + */ + function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { } +} diff --git a/solidity/truffle-config.js b/solidity/truffle-config.js new file mode 100644 index 0000000..5d3c0e5 --- /dev/null +++ b/solidity/truffle-config.js @@ -0,0 +1,106 @@ +/** + * Use this file to configure your truffle project. It's seeded with some + * common settings for different networks and features like migrations, + * compilation and testing. Uncomment the ones you need or modify + * them to suit your project as necessary. + * + * More information about configuration can be found at: + * + * trufflesuite.com/docs/advanced/configuration + * + * To deploy via Infura you'll need a wallet provider (like @truffle/hdwallet-provider) + * to sign your transactions before they're sent to a remote public node. Infura accounts + * are available for free at: infura.io/register. + * + * You'll also need a mnemonic - the twelve word phrase the wallet uses to generate + * public/private key pairs. If you're publishing your code to GitHub make sure you load this + * phrase from a file you've .gitignored so it doesn't accidentally become public. + * + */ + +// const HDWalletProvider = require('@truffle/hdwallet-provider'); +// const infuraKey = "fj4jll3k....."; +// +// const fs = require('fs'); +// const mnemonic = fs.readFileSync(".secret").toString().trim(); + +module.exports = { + /** + * Networks define how you connect to your ethereum client and let you set the + * defaults web3 uses to send transactions. If you don't specify one truffle + * will spin up a development blockchain for you on port 9545 when you + * run `develop` or `test`. You can ask a truffle command to use a specific + * network from the command line, e.g + * + * $ truffle test --network + */ + + networks: { + // Useful for testing. The `development` name is special - truffle uses it by default + // if it's defined here and no other network is specified at the command line. + // You should run a client (like ganache-cli, geth or parity) in a separate terminal + // tab if you use this network and you must also set the `host`, `port` and `network_id` + // options below to some value. + // + development: { + host: "127.0.0.1", // Localhost (default: none) + port: 8545, // Standard Ethereum port (default: none) + network_id: "*", // Any network (default: none) + }, + // Another network with more advanced options... + // advanced: { + // port: 8777, // Custom port + // network_id: 1342, // Custom network + // gas: 8500000, // Gas sent with each transaction (default: ~6700000) + // gasPrice: 20000000000, // 20 gwei (in wei) (default: 100 gwei) + // from:
, // Account to send txs from (default: accounts[0]) + // websocket: true // Enable EventEmitter interface for web3 (default: false) + // }, + // Useful for deploying to a public network. + // NB: It's important to wrap the provider as a function. + // ropsten: { + // provider: () => new HDWalletProvider(mnemonic, `https://ropsten.infura.io/v3/YOUR-PROJECT-ID`), + // network_id: 3, // Ropsten's id + // gas: 5500000, // Ropsten has a lower block limit than mainnet + // confirmations: 2, // # of confs to wait between deployments. (default: 0) + // timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50) + // skipDryRun: true // Skip dry run before migrations? (default: false for public nets ) + // }, + // Useful for private networks + // private: { + // provider: () => new HDWalletProvider(mnemonic, `https://network.io`), + // network_id: 2111, // This network is yours, in the cloud. + // production: true // Treats this network as if it was a public net. (default: false) + // } + }, + + // Set default mocha options here, use special reporters etc. + mocha: { + // timeout: 100000 + }, + + // Configure your compilers + compilers: { + solc: { + // version: "0.5.1", // Fetch exact version from solc-bin (default: truffle's version) + // docker: true, // Use "0.5.1" you've installed locally with docker (default: false) + // settings: { // See the solidity docs for advice about optimization and evmVersion + // optimizer: { + // enabled: false, + // runs: 200 + // }, + // evmVersion: "byzantium" + // } + } + }, + + // Truffle DB is currently disabled by default; to enable it, change enabled: false to enabled: true + // + // Note: if you migrated your contracts prior to enabling this field in your Truffle project and want + // those previously migrated contracts available in the .db directory, you will need to run the following: + // $ truffle migrate --reset --compile-all + + db: { + enabled: false + } +}; diff --git a/sort2.py b/sort2.py new file mode 100644 index 0000000..c08072d --- /dev/null +++ b/sort2.py @@ -0,0 +1,69 @@ +def merge(x:list, a:int, b:int, c:int): + if b == c: + return + while a < b and x[a] < x[b]: + a += 1 + + if a == b: + return + while b < c and x[b - 1] < x[c - 1]: + c -= 1 + + w = min(b - a, c - b) + + tmp = x[b - w:b] + x[b - w:b] = x[b:b + w] + x[b:b + w] = tmp + + merge(x, a, b - w, b) + merge(x, b, b + w, c) + merge(x, a, b, c) + +def getrun(x:list, a:int, depth:int): + if a == len(x): + return a + + if depth == 0: + b = a + 1 + + while b < len(x) and x[b - 1] < x[b]: + b += 1 + + return b + + b = getrun(x, a, depth - 1) + c = getrun(x, b, depth - 1) + merge(x, a, b, c) + return c + +def sort(x:list): + depth = 0 + a = 0 + b = getrun(x, a, depth) + c = getrun(x, b, depth) + merge(x, a, b, c) + + while c < len(x): + depth += 1 + b = c + c = getrun(x, b, depth) + merge(x, a, b, c) + +def is_sorted(x:list) -> bool: + for i in range(len(x) - 1): + if x[i] >= x[i + 1]: + return False + return True + +if __name__ == '__main__': + import random, unittest + + class SortTests(unittest.TestCase): + def test_sorts(self): + for i in range(100): + x = [i for i in range(25)] + random.shuffle(x) + sort(x) + self.assertTrue(is_sorted(x)) + + unittest.main()