Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View 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")

View 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()

View 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)}")