Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
44
Task/24-game-Solve/Python/24-game-solve-1.py
Normal file
44
Task/24-game-Solve/Python/24-game-solve-1.py
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Python 3
|
||||
from operator import mul, sub, add
|
||||
|
||||
|
||||
def div(a, b):
|
||||
if b == 0:
|
||||
return 999999.0
|
||||
return a / b
|
||||
|
||||
ops = {mul: '*', div: '/', sub: '-', add: '+'}
|
||||
|
||||
def solve24(num, how, target):
|
||||
if len(num) == 1:
|
||||
if round(num[0], 5) == round(target, 5):
|
||||
yield str(how[0]).replace(',', '').replace("'", '')
|
||||
else:
|
||||
for i, n1 in enumerate(num):
|
||||
for j, n2 in enumerate(num):
|
||||
if i != j:
|
||||
for op in ops:
|
||||
new_num = [n for k, n in enumerate(num) if k != i and k != j] + [op(n1, n2)]
|
||||
new_how = [h for k, h in enumerate(how) if k != i and k != j] + [(how[i], ops[op], how[j])]
|
||||
yield from solve24(new_num, new_how, target)
|
||||
|
||||
tests = [
|
||||
[1, 7, 2, 7],
|
||||
[5, 7, 5, 4],
|
||||
[1, 4, 6, 6],
|
||||
[2, 3, 7, 3],
|
||||
[1, 6, 2, 6],
|
||||
[7, 9, 4, 1],
|
||||
[6, 4, 2, 2],
|
||||
[5, 7, 9, 7],
|
||||
[3, 3, 8, 8], # Difficult case requiring precise division
|
||||
[8, 7, 9, 7], # No solution
|
||||
[9, 4, 4, 5], # No solution
|
||||
]
|
||||
for nums in tests:
|
||||
print(nums, end=' : ')
|
||||
try:
|
||||
print(next(solve24(nums, nums, 24)))
|
||||
except StopIteration:
|
||||
print("No solution found")
|
||||
359
Task/24-game-Solve/Python/24-game-solve-2.py
Normal file
359
Task/24-game-Solve/Python/24-game-solve-2.py
Normal file
|
|
@ -0,0 +1,359 @@
|
|||
''' Python 3.6.5 code using Tkinter graphical user interface.
|
||||
Combination of '24 game' and '24 game/Solve'
|
||||
allowing user or random selection of 4-digit number
|
||||
and user or computer solution.
|
||||
Note that all computer solutions are displayed'''
|
||||
|
||||
from tkinter import *
|
||||
from tkinter import messagebox
|
||||
from tkinter.scrolledtext import ScrolledText
|
||||
# 'from tkinter import scrolledtext' in later versions?
|
||||
import random
|
||||
import itertools
|
||||
|
||||
# ************************************************
|
||||
|
||||
class Game:
|
||||
def __init__(self, gw):
|
||||
self.window = gw
|
||||
self.digits = '0000'
|
||||
|
||||
a1 = "(Enter '4 Digits' & click 'My Digits'"
|
||||
a2 = "or click 'Random Digits')"
|
||||
self.msga = a1 + '\n' + a2
|
||||
|
||||
b1 = "(Enter 'Solution' & click 'Check Solution'"
|
||||
b2 = "or click 'Show Solutions')"
|
||||
self.msgb = b1 + '\n' + b2
|
||||
|
||||
# top frame:
|
||||
self.top_fr = Frame(gw,
|
||||
width=600,
|
||||
height=100,
|
||||
bg='dodger blue')
|
||||
self.top_fr.pack(fill=X)
|
||||
|
||||
self.hdg = Label(self.top_fr,
|
||||
text=' 24 Game ',
|
||||
font='arial 22 bold',
|
||||
fg='navy',
|
||||
bg='lemon chiffon')
|
||||
self.hdg.place(relx=0.5, rely=0.5,
|
||||
anchor=CENTER)
|
||||
|
||||
self.close_btn = Button(self.top_fr,
|
||||
text='Quit',
|
||||
bd=5,
|
||||
bg='navy',
|
||||
fg='lemon chiffon',
|
||||
font='arial 12 bold',
|
||||
command=self.close_window)
|
||||
self.close_btn.place(relx=0.07, rely=0.5,
|
||||
anchor=W)
|
||||
|
||||
self.clear_btn = Button(self.top_fr,
|
||||
text='Clear',
|
||||
bd=5,
|
||||
bg='navy',
|
||||
fg='lemon chiffon',
|
||||
font='arial 12 bold',
|
||||
command=self.clear_screen)
|
||||
self.clear_btn.place(relx=0.92, rely=0.5,
|
||||
anchor=E)
|
||||
|
||||
# bottom frame:
|
||||
self.btm_fr = Frame(gw,
|
||||
width=600,
|
||||
height=500,
|
||||
bg='lemon chiffon')
|
||||
self.btm_fr.pack(fill=X)
|
||||
|
||||
self.msg = Label(self.btm_fr,
|
||||
text=self.msga,
|
||||
font='arial 16 bold',
|
||||
fg='navy',
|
||||
bg='lemon chiffon')
|
||||
self.msg.place(relx=0.5, rely=0.1,
|
||||
anchor=CENTER)
|
||||
|
||||
self.user_dgt_btn = Button(self.btm_fr,
|
||||
text='My Digits',
|
||||
width=12,
|
||||
bd=5,
|
||||
bg='navy',
|
||||
fg='lemon chiffon',
|
||||
font='arial 12 bold',
|
||||
command=self.get_digits)
|
||||
self.user_dgt_btn.place(relx=0.07, rely=0.2,
|
||||
anchor=W)
|
||||
|
||||
self.rdm_dgt_btn = Button(self.btm_fr,
|
||||
text='Random Digits',
|
||||
width=12,
|
||||
bd=5,
|
||||
bg='navy',
|
||||
fg='lemon chiffon',
|
||||
font='arial 12 bold',
|
||||
command=self.gen_digits)
|
||||
self.rdm_dgt_btn.place(relx=0.92, rely=0.2,
|
||||
anchor=E)
|
||||
|
||||
self.dgt_fr = LabelFrame(self.btm_fr,
|
||||
text=' 4 Digits ',
|
||||
bg='dodger blue',
|
||||
fg='navy',
|
||||
bd=4,
|
||||
relief=RIDGE,
|
||||
font='arial 12 bold')
|
||||
self.dgt_fr.place(relx=0.5, rely=0.27,
|
||||
anchor=CENTER)
|
||||
|
||||
self.digit_ent = Entry(self.dgt_fr,
|
||||
justify='center',
|
||||
font='arial 16 bold',
|
||||
fg='navy',
|
||||
disabledforeground='navy',
|
||||
bg='lemon chiffon',
|
||||
disabledbackground='lemon chiffon',
|
||||
bd=4,
|
||||
width=6)
|
||||
self.digit_ent.grid(row=0, column=0,
|
||||
padx=(8,8),
|
||||
pady=(8,8))
|
||||
|
||||
self.chk_soln_btn = Button(self.btm_fr,
|
||||
text='Check Solution',
|
||||
state='disabled',
|
||||
width=14,
|
||||
bd=5,
|
||||
bg='navy',
|
||||
fg='lemon chiffon',
|
||||
font='arial 12 bold',
|
||||
command=self.check_soln)
|
||||
self.chk_soln_btn.place(relx=0.07, rely=.42,
|
||||
anchor=W)
|
||||
|
||||
self.show_soln_btn = Button(self.btm_fr,
|
||||
text='Show Solutions',
|
||||
state='disabled',
|
||||
width=14,
|
||||
bd=5,
|
||||
bg='navy',
|
||||
fg='lemon chiffon',
|
||||
font='arial 12 bold',
|
||||
command=self.show_soln)
|
||||
self.show_soln_btn.place(relx=0.92, rely=.42,
|
||||
anchor=E)
|
||||
|
||||
self.soln_fr = LabelFrame(self.btm_fr,
|
||||
text=' Solution ',
|
||||
bg='dodger blue',
|
||||
fg='navy',
|
||||
bd=4,
|
||||
relief=RIDGE,
|
||||
font='arial 12 bold')
|
||||
self.soln_fr.place(relx=0.07, rely=0.58,
|
||||
anchor=W)
|
||||
|
||||
self.soln_ent = Entry(self.soln_fr,
|
||||
justify='center',
|
||||
font='arial 16 bold',
|
||||
fg='navy',
|
||||
disabledforeground='navy',
|
||||
bg='lemon chiffon',
|
||||
disabledbackground='lemon chiffon',
|
||||
state='disabled',
|
||||
bd=4,
|
||||
width=15)
|
||||
self.soln_ent.grid(row=0, column=0,
|
||||
padx=(8,8), pady=(8,8))
|
||||
|
||||
self.solns_fr = LabelFrame(self.btm_fr,
|
||||
text=' Solutions ',
|
||||
bg='dodger blue',
|
||||
fg='navy',
|
||||
bd=4,
|
||||
relief=RIDGE,
|
||||
font='arial 12 bold')
|
||||
self.solns_fr.place(relx=0.92, rely=0.5,
|
||||
anchor='ne')
|
||||
|
||||
self.solns_all = ScrolledText(self.solns_fr,
|
||||
font='courier 14 bold',
|
||||
state='disabled',
|
||||
fg='navy',
|
||||
bg='lemon chiffon',
|
||||
height=8,
|
||||
width=14)
|
||||
self.solns_all.grid(row=0, column=0,
|
||||
padx=(8,8), pady=(8,8))
|
||||
|
||||
# validate '4 Digits' entry.
|
||||
# save if valid and switch screen to solution mode.
|
||||
def get_digits(self):
|
||||
txt = self.digit_ent.get()
|
||||
if not(len(txt) == 4 and txt.isdigit()):
|
||||
self.err_msg('Please enter 4 digits (eg 1357)')
|
||||
return
|
||||
self.digits = txt # save
|
||||
self.reset_one() # to solution mode
|
||||
return
|
||||
|
||||
# generate 4 random digits, display them,
|
||||
# save them, and switch screen to solution mode.
|
||||
def gen_digits(self):
|
||||
self.digit_ent.delete(0, 'end')
|
||||
self.digits = ''.join([random.choice('123456789')
|
||||
for i in range(4)])
|
||||
self.digit_ent.insert(0, self.digits) # display
|
||||
self.reset_one() # to solution mode
|
||||
return
|
||||
|
||||
# switch screen from get digits to solution mode:
|
||||
def reset_one(self):
|
||||
self.digit_ent.config(state='disabled')
|
||||
self.user_dgt_btn.config(state='disabled')
|
||||
self.rdm_dgt_btn.config(state='disabled')
|
||||
self.msg.config(text=self.msgb)
|
||||
self.chk_soln_btn.config(state='normal')
|
||||
self.show_soln_btn.config(state='normal')
|
||||
self.soln_ent.config(state='normal')
|
||||
return
|
||||
|
||||
# edit user's solution:
|
||||
def check_soln(self):
|
||||
txt = self.soln_ent.get() # user's expression
|
||||
d = '' # save digits in expression
|
||||
dgt_op = 'd' # expecting d:digit or o:operation
|
||||
for t in txt:
|
||||
if t not in '123456789+-*/() ':
|
||||
self.err_msg('Invalid character found: ' + t)
|
||||
return
|
||||
if t.isdigit():
|
||||
if dgt_op == 'd':
|
||||
d += t
|
||||
dgt_op = 'o'
|
||||
else:
|
||||
self.err_msg('Need operator between digits')
|
||||
return
|
||||
if t in '+-*/':
|
||||
if dgt_op == 'o':
|
||||
dgt_op = 'd'
|
||||
else:
|
||||
self.err_msg('Need digit befor operator')
|
||||
return
|
||||
if sorted(d) != sorted(self.digits):
|
||||
self.err_msg("Use each digit in '4 Digits' once")
|
||||
return
|
||||
try:
|
||||
# round covers up Python's
|
||||
# representation of floats
|
||||
if round(eval(txt),5) == 24:
|
||||
messagebox.showinfo(
|
||||
'Success',
|
||||
'YOUR SOLUTION IS VADLID!')
|
||||
self.show_soln() # show all solutions
|
||||
return
|
||||
except:
|
||||
self.err_msg('Invalid arithmetic expression')
|
||||
return
|
||||
messagebox.showinfo(
|
||||
'Failure',
|
||||
'Your expression does not yield 24')
|
||||
return
|
||||
|
||||
# show all solutions:
|
||||
def show_soln(self):
|
||||
# get all sets of 3 operands: ('+', '+', '*'), ...)
|
||||
ops = ['+-*/', '+-*/', '+-*/']
|
||||
combs = [p for p in itertools.product(*ops)]
|
||||
|
||||
# get unique permutations for requested 4 digits:
|
||||
d = self.digits
|
||||
perms = set([''.join(p) for p in itertools.permutations(d)])
|
||||
|
||||
# list of all (hopefully) expressions for
|
||||
# 4 operands and 3 operations:
|
||||
formats = ['Aop1Bop2Cop3D',
|
||||
'(Aop1Bop2C)op3D',
|
||||
'((Aop1B)op2C)op3D',
|
||||
'(Aop1(Bop2C))op3D',
|
||||
'Aop1Bop2(Cop3D)',
|
||||
'Aop1(Bop2C)op3D',
|
||||
'(Aop1B)op2Cop3D',
|
||||
'(Aop1B)op2(Cop3D)',
|
||||
'Aop1(Bop2Cop3D)',
|
||||
'Aop1((Bop2C)op3D)',
|
||||
'Aop1(Bop2(Cop3D))']
|
||||
|
||||
lox = [] # list of valid expressions
|
||||
|
||||
for fm in formats: # pick a format
|
||||
for c in combs: # plug in 3 ops
|
||||
f = fm.replace('op1', c[0])
|
||||
f = f.replace('op2', c[1])
|
||||
f = f.replace('op3', c[2])
|
||||
for A, B, C, D in perms: # plug in 4 digits
|
||||
x = f.replace('A', A)
|
||||
x = x.replace('B', B)
|
||||
x = x.replace('C', C)
|
||||
x = x.replace('D', D)
|
||||
try: # evaluate expression
|
||||
# round covers up Python's
|
||||
# representation of floats
|
||||
if round(eval(x),5) == 24:
|
||||
lox.append(' ' + x)
|
||||
except ZeroDivisionError: # can ignore these
|
||||
continue
|
||||
if lox:
|
||||
txt = '\n'.join(x for x in lox)
|
||||
else:
|
||||
txt =' No Solution'
|
||||
self.solns_all.config(state='normal')
|
||||
self.solns_all.insert('end', txt) # show solutions
|
||||
self.solns_all.config(state='disabled')
|
||||
|
||||
self.chk_soln_btn.config(state='disabled')
|
||||
self.show_soln_btn.config(state='disabled')
|
||||
self.soln_ent.config(state='disabled')
|
||||
return
|
||||
|
||||
def err_msg(self, msg):
|
||||
messagebox.showerror('Error Message', msg)
|
||||
return
|
||||
|
||||
# restore screen to it's 'initial' state:
|
||||
def clear_screen(self):
|
||||
self.digits = ''
|
||||
self.digit_ent.config(state='normal')
|
||||
self.user_dgt_btn.config(state='normal')
|
||||
self.rdm_dgt_btn.config(state='normal')
|
||||
self.digit_ent.delete(0, 'end')
|
||||
self.chk_soln_btn.config(state='disabled')
|
||||
self.show_soln_btn.config(state='disabled')
|
||||
self.soln_ent.config(state='normal')
|
||||
self.soln_ent.delete(0, 'end')
|
||||
self.soln_ent.config(state='disabled')
|
||||
self.msg.config(text=self.msga)
|
||||
self.clear_solns_all()
|
||||
return
|
||||
|
||||
# clear the 'Solutions' frame.
|
||||
# note: state must be 'normal' to change data
|
||||
def clear_solns_all(self):
|
||||
self.solns_all.config(state='normal')
|
||||
self.solns_all.delete(1.0, 'end')
|
||||
self.solns_all.config(state='disabled')
|
||||
return
|
||||
|
||||
def close_window(self):
|
||||
self.window.destroy()
|
||||
|
||||
# ************************************************
|
||||
|
||||
root = Tk()
|
||||
root.title('24 Game')
|
||||
root.geometry('600x600+100+50')
|
||||
root.resizable(False, False)
|
||||
g = Game(root)
|
||||
root.mainloop()
|
||||
39
Task/24-game-Solve/Python/24-game-solve.py
Normal file
39
Task/24-game-Solve/Python/24-game-solve.py
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import operator
|
||||
from itertools import product, permutations
|
||||
|
||||
def mydiv(n, d):
|
||||
return n / d if d != 0 else 9999999
|
||||
|
||||
syms = [operator.add, operator.sub, operator.mul, mydiv]
|
||||
op = {sym: ch for sym, ch in zip(syms, '+-*/')}
|
||||
|
||||
def solve24(nums):
|
||||
for x, y, z in product(syms, repeat=3):
|
||||
for a, b, c, d in permutations(nums):
|
||||
if round(x(y(a,b),z(c,d)),5) == 24:
|
||||
return f"({a} {op[y]} {b}) {op[x]} ({c} {op[z]} {d})"
|
||||
elif round(x(a,y(b,z(c,d))),5) == 24:
|
||||
return f"{a} {op[x]} ({b} {op[y]} ({c} {op[z]} {d}))"
|
||||
elif round(x(y(z(c,d),b),a),5) == 24:
|
||||
return f"(({c} {op[z]} {d}) {op[y]} {b}) {op[x]} {a}"
|
||||
elif round(x(y(b,z(c,d)),a),5) == 24:
|
||||
return f"({b} {op[y]} ({c} {op[z]} {d})) {op[x]} {a}"
|
||||
return '--Not Found--'
|
||||
|
||||
if __name__ == '__main__':
|
||||
#nums = eval(input('Four integers in the range 1:9 inclusive, separated by commas: '))
|
||||
for nums in [
|
||||
[9,4,4,5],
|
||||
[1,7,2,7],
|
||||
[5,7,5,4],
|
||||
[1,4,6,6],
|
||||
[2,3,7,3],
|
||||
[8,7,9,7],
|
||||
[1,6,2,6],
|
||||
[7,9,4,1],
|
||||
[6,4,2,2],
|
||||
[5,7,9,7],
|
||||
[3,3,8,8], # Difficult case requiring precise division
|
||||
]:
|
||||
print(f"solve24({nums}) -> {solve24(nums)}")
|
||||
Loading…
Add table
Add a link
Reference in a new issue