加強版題目
有人話,呢題17進制,17個variable,問我知驚未。
ΑΒΓΔ
- ΕΖΗΘ
------
ΙΚΛΜ
+ ΝΞΟΠ
------
ΡΡΡΡΡ
加強版題目解法
我一個鐘搞掂左基本野(好叻叻豬牙),再用少少時間去implement個multiprocessing。
#!/usr/bin/env pypy3
from multiprocessing import Pool, Queue
from contextlib import closing
from itertools import permutations
PPPPP = 88741
CF8Q = Queue()
def check_last_8(i):
if i[0] == 0 or i[4] == 0:
return 0
ΙΚΛΜ, ΝΞΟΠ = i[0] * 4913 + i[1] * 289 + i[2] * 17 + \
i[3], i[4] * 4913 + i[5] * 289 + i[6] * 17 + i[7]
if ΙΚΛΜ + ΝΞΟΠ == PPPPP:
return ΙΚΛΜ
return 0
def check_first_8(i, ΙΚΛΜ):
if i[0] == 0 or i[4] == 0:
return 0
ΑΒΓΔ, ΕΖΗΘ = i[0] * 4913 + i[1] * 289 + i[2] * 17 + \
i[3], i[4] * 4913 + i[5] * 289 + i[6] * 17 + i[7]
if ΑΒΓΔ - ΕΖΗΘ == ΙΚΛΜ:
return 1
def check_first_8_worker(queue):
while 1:
i, ΙΚΛΜ = queue.get()
for j in permutations(set(range(17)) - set(i) - {1}, 8):
if check_first_8(j, ΙΚΛΜ):
print(j, i)
if __name__ == '__main__':
the_pool = closing(Pool(64, check_first_8_worker, (CF8Q,)))
for i in permutations(set(range(17)) - {1}, 8):
ΙΚΛΜ = check_last_8(i)
if ΙΚΛΜ != 0:
CF8Q.put((i, ΙΚΛΜ,))
加強版答案驗證
將上面求一行output入落Digits?
就ok了。
#!/usr/bin/env pypy3
from re import findall
PPPPP = 88741
def baseN(num, b, numerals="0123456789abcdefghijklmnopqrstuvwxyz"):
return ((num == 0) and numerals[0]) or (baseN(num // b, b, numerals).lstrip(numerals[0]) + numerals[num % b])
def verify(i):
ΑΒΓΔ, ΕΖΗΘ = i[0] * 4913 + i[1] * 289 + i[2] * 17 + \
i[3], i[4] * 4913 + i[5] * 289 + i[6] * 17 + i[7]
ΙΚΛΜ, ΝΞΟΠ = i[8] * 4913 + i[9] * 289 + i[10] * 17 + \
i[11], i[12] * 4913 + i[13] * 289 + i[14] * 17 + i[15]
print("{} - {} == {}? {}".format(baseN(ΑΒΓΔ, 17), baseN(ΕΖΗΘ, 17), baseN(ΙΚΛΜ, 17), ΑΒΓΔ - ΕΖΗΘ == ΙΚΛΜ))
print("{} + {} == {}? {}".format(baseN(ΙΚΛΜ, 17), baseN(ΝΞΟΠ, 17), baseN(PPPPP, 17), ΙΚΛΜ + ΝΞΟΠ == PPPPP))
if __name__ == "__main__":
verify([int(i) for i in findall("\d+", input("Digits? "))])
部份答案
(16, 13, 15, 0, 2, 5, 4, 11) (14, 8, 10, 6, 3, 9, 7, 12)
(16, 10, 4, 12, 2, 0, 15, 7) (14, 9, 6, 5, 3, 8, 11, 13)
(16, 15, 4, 0, 2, 5, 13, 11) (14, 9, 7, 6, 3, 8, 10, 12)
(16, 15, 13, 4, 2, 6, 0, 10) (14, 9, 12, 11, 3, 8, 5, 7)
(16, 15, 7, 0, 2, 5, 10, 11) (14, 9, 13, 6, 3, 8, 4, 12)
(16, 11, 5, 4, 2, 0, 13, 15) (14, 10, 8, 6, 3, 7, 9, 12)
(16, 15, 5, 0, 2, 4, 13, 11) (14, 10, 8, 6, 3, 7, 9, 12)
(16, 15, 13, 0, 2, 5, 4, 11) (14, 10, 8, 6, 3, 7, 9, 12)
(16, 15, 13, 0, 2, 4, 7, 9) (14, 11, 5, 8, 3, 6, 12, 10)
(16, 12, 8, 9, 2, 0, 15, 4) (14, 11, 10, 5, 3, 6, 7, 13)
(16, 12, 9, 4, 2, 0, 15, 8) (14, 11, 10, 13, 3, 6, 7, 5)
(16, 12, 5, 15, 2, 0, 9, 7) (14, 11, 13, 8, 3, 6, 4, 10)
./challenge.py 77.75s user 1.51s system 190% cpu 41.515 total
再快d?
- First 8p4 iterations can be reduced to 100 - 1.
- Last iterations may be reduced too.
- Therefore, first 16p8 iterations can be reduced to (10000 - 1) (in b17)
實驗:9字母版
好多string operation,好慢。但check_last_4
同check_first_4
夾埋call得560次。
#!/usr/bin/env python3
from collections import Counter
BASE = 10
WIDTH = 2
PPP = int('111', BASE)
def construct(*args):
digits = 0
for i in args:
digits *= BASE ** WIDTH
digits += i
return digits
def check_last_4(GH):
EF = PPP - GH
c = Counter()
c.update(str(construct(EF, GH)))
for i in c.items():
if i[0] == '1' or i[1] > 1:
return 0
return EF
def check_first_4(AB, EF):
CD = AB - EF
c = Counter()
c.update(str(construct(AB, CD, EF, GH)))
for i in c.items():
if i[0] == '1' or i[1] > 1:
return 0
return CD
if __name__ == '__main__':
for GH in range(20, BASE ** WIDTH):
EF = check_last_4(GH)
if EF == 0:
continue
for AB in range(EF + 20, BASE ** WIDTH):
CD = check_first_4(AB, EF)
if CD != 0 :
print(AB, CD, EF, GH, PPP)
17字母版
淨係改左EF GH果part,AB CD唔識改,同埋我唔識唔經str抽返d千位數百位數出黎,個program因為咁慢左少少。
#!/usr/bin/env pypy3
from string import digits, ascii_letters
from time import sleep
from multiprocessing import Pool, Queue, Lock
from itertools import permutations
from collections import Counter
# Configurable variables
# 32C64T machine runtime, 17: 2.7s, 18: 14s, 19: 2m, 20: 8m
PROCESSES = 128
BASE = 20 # 17 or up
# Don't change anything below this line
WIDTH = 4
BOUND = int('2034', BASE)
PPPPP = int('11111', BASE)
NUMERALS = digits + ascii_letters
CF8Q = Queue()
exit_lock = Lock()
def baseN(num):
return ((num == 0) and NUMERALS[0]) or (baseN(num // BASE).lstrip(NUMERALS[0]) + NUMERALS[num % BASE])
def check_last_8(ΝΞΟΠ):
ΙΚΛΜ = PPPPP - ΝΞΟΠ
c = Counter()
c.update(baseN(ΙΚΛΜ * (BASE ** WIDTH) + ΝΞΟΠ))
for i in c.items():
if i[0] == '1' or i[1] > 1:
return 0
return ΙΚΛΜ
def check_first_8(i, ΙΚΛΜ):
if i[0] == 0 or i[4] == 0:
return 0
ΑΒΓΔ, ΕΖΗΘ = i[0] * (BASE ** 3) + i[1] * (BASE ** 2) + i[2] * BASE + i[3], \
i[4] * (BASE ** 3) + i[5] * (BASE ** 2) + i[6] * BASE + i[7]
if ΑΒΓΔ - ΕΖΗΘ == ΙΚΛΜ:
return 1
def check_first_8_worker(queue):
while 1:
used_digits, ΙΚΛΜ = queue.get()
for j in permutations(set(range(BASE)) - set(used_digits) - {1}, 8):
if check_first_8(j, ΙΚΛΜ):
print(j, used_digits)
if queue.qsize() == 0:
try:
exit_lock.release()
except Exception as e:
pass
if __name__ == '__main__':
for ΝΞΟΠ in range(BOUND, BASE ** WIDTH):
ΙΚΛΜ = check_last_8(ΝΞΟΠ)
if ΙΚΛΜ != 0:
used_digits = [int(i, BASE) for i in baseN(ΙΚΛΜ * (BASE ** WIDTH) + ΝΞΟΠ)]
CF8Q.put((used_digits, ΙΚΛΜ,))
exit_lock.acquire()
pool = Pool(PROCESSES, check_first_8_worker, (CF8Q,))
exit_lock.acquire()
部份結果
(9, 12, 0, 4, 7, 8, 10, 16) [2, 3, 6, 5, 15, 14, 11, 13]
(10, 7, 16, 0, 8, 4, 9, 12) [2, 3, 6, 5, 15, 14, 11, 13]
(9, 16, 6, 4, 7, 13, 0, 11) [2, 3, 5, 10, 15, 14, 12, 8]
(10, 12, 7, 4, 8, 9, 0, 16) [2, 3, 6, 5, 15, 14, 11, 13]
(13, 7, 6, 9, 11, 4, 0, 16) [2, 3, 5, 10, 15, 14, 12, 8]
(8, 9, 0, 10, 6, 5, 12, 16) [2, 3, 4, 11, 15, 14, 13, 7]
(8, 12, 5, 10, 6, 9, 0, 16) [2, 3, 4, 11, 15, 14, 13, 7]
(10, 9, 0, 6, 8, 5, 12, 16) [2, 3, 4, 7, 15, 14, 13, 11]
(10, 12, 5, 6, 8, 9, 0, 16) [2, 3, 4, 7, 15, 14, 13, 11]
pypy3 ./eff.py 37.57s user 4.00s system 1534% cpu 2.708 total