Commit my code
This commit is contained in:
commit
28424bf0fd
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
input.txt
|
||||||
|
venv
|
1
README.md
Normal file
1
README.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
Concurrent, user-directed mergesort. See https://git.chromaticdragon.app/kistaro/manual-sort .
|
112
main.py
Normal file
112
main.py
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
import asyncio
|
||||||
|
import contextlib
|
||||||
|
import random
|
||||||
|
|
||||||
|
|
||||||
|
TRUTHY = "y yes 1 t true aye left up top first p".split()
|
||||||
|
FALSEY = "n no 0 2 f false nay right down bottom second nil".split()
|
||||||
|
|
||||||
|
|
||||||
|
def sort(options):
|
||||||
|
loop = asyncio.new_event_loop()
|
||||||
|
postponed_questions = []
|
||||||
|
|
||||||
|
# counter for how many threads can still resume
|
||||||
|
# if it's 0, then we need to ask some questions or else we're deadlocked
|
||||||
|
|
||||||
|
n_active = 0
|
||||||
|
|
||||||
|
@contextlib.asynccontextmanager
|
||||||
|
async def semaphore(amt):
|
||||||
|
nonlocal n_active
|
||||||
|
n_active += amt
|
||||||
|
yield
|
||||||
|
n_active -= amt
|
||||||
|
|
||||||
|
def deadlocked():
|
||||||
|
return n_active == 0
|
||||||
|
|
||||||
|
async def ask(x, y):
|
||||||
|
async with semaphore(-1):
|
||||||
|
future = loop.create_future()
|
||||||
|
|
||||||
|
def ask_question():
|
||||||
|
if random.choice([False, True]):
|
||||||
|
yes_result = True
|
||||||
|
a, b = x, y
|
||||||
|
else:
|
||||||
|
yes_result = False
|
||||||
|
a, b = y, x
|
||||||
|
|
||||||
|
while True:
|
||||||
|
choice = input(f"Is {a} better than {b}? ")
|
||||||
|
if choice in TRUTHY:
|
||||||
|
future.set_result(yes_result)
|
||||||
|
return
|
||||||
|
|
||||||
|
if choice in FALSEY:
|
||||||
|
future.set_result(not yes_result)
|
||||||
|
return
|
||||||
|
|
||||||
|
print(f"Huh? I didn't understand {choice}. Answer \"y\" or \"n\".")
|
||||||
|
|
||||||
|
postponed_questions.append(ask_question)
|
||||||
|
if deadlocked():
|
||||||
|
await ask_questions()
|
||||||
|
|
||||||
|
return await future
|
||||||
|
|
||||||
|
async def merge(xs, ys):
|
||||||
|
async with semaphore(1):
|
||||||
|
xs = xs[:]
|
||||||
|
ys = ys[:]
|
||||||
|
out = []
|
||||||
|
|
||||||
|
while len(xs) > 0 and len(ys) > 0:
|
||||||
|
if await ask(xs[0], ys[0]):
|
||||||
|
out.append(xs.pop(0))
|
||||||
|
else:
|
||||||
|
out.append(ys.pop(0))
|
||||||
|
|
||||||
|
out.extend(xs)
|
||||||
|
out.extend(ys)
|
||||||
|
return out
|
||||||
|
|
||||||
|
async def merge_sort(xs):
|
||||||
|
if len(xs) < 2:
|
||||||
|
return xs[:]
|
||||||
|
|
||||||
|
half = len(xs) // 2
|
||||||
|
|
||||||
|
fst_half, snd_half = await asyncio.gather(
|
||||||
|
merge_sort(xs[:half]),
|
||||||
|
merge_sort(xs[half:])
|
||||||
|
)
|
||||||
|
|
||||||
|
return await merge(fst_half, snd_half)
|
||||||
|
|
||||||
|
async def ask_questions():
|
||||||
|
ppq = postponed_questions[:]
|
||||||
|
postponed_questions.clear()
|
||||||
|
|
||||||
|
random.shuffle(ppq)
|
||||||
|
for q in ppq:
|
||||||
|
q()
|
||||||
|
|
||||||
|
result_future = merge_sort(options)
|
||||||
|
result = loop.run_until_complete(result_future)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
with open("input.txt", "rt") as f_in:
|
||||||
|
lines_in = [i.strip() for i in f_in.split("\n") if i.strip()]
|
||||||
|
|
||||||
|
results = sort(lines_in)
|
||||||
|
|
||||||
|
with open("output.txt", "wt") as f_out:
|
||||||
|
f_out.writelines(results)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
Loading…
Reference in New Issue
Block a user