Improving a "Four Fours" puzzle solver [closed] - python

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
import itertools
import math
import time
from time import time
from math import factorial
from math import sqrt
def pretty(string):
string=string.replace("(4)","4")
string=string.replace("factorial4","factorial(4)")
string=string.replace("sqrt4","sqrt(4)")
return string
def test(n):
start=time()
fails=0
for i in range(0,n+1):
if(fours(i))!=None:
print(fours(i))
else:
print("Failed: "+str(i))
fails+=1
return("\nFailed "+str(fails)+" out of "+str(n)+"\n\nTotal time: "+str(time()-start)[:4]+"\nAverage time: "+str((time()-start)/n)[:4])
def fours(goal):
operators = ['-','/','+','*','sqrt','^','factorial',"."]
brackets = ["{0}{1}{0}{2}{0}{3}{0}",
"({0}{1}{0}){2}{0}{3}{0}",
"({0}{1}{0}{2}{0}){3}{0}",
"({0}{1}({0}{2}{0})){3}{0}",
"(({0}{1}{0}){2}{0}){3}{0}",
"{0}{1}({0}{2}({0}{3}{0}))",
"{0}{1}(({0}{2}{0}){3}{0})",
"({0}{1}{0}){2}({0}{3}{0})"]
for combination in itertools.product(operators, repeat=3):
for bracket in brackets:
try:
formula = bracket.format("(4)", *combination).replace(".(4","(.4")
except ValueError:
pass
try:
if eval(formula)==goal:
return(pretty((formula + " = " + str(int(eval(formula))))))
except:
pass
print(test(20))
Here is the code for a solver for the "Four Fours"
puzzle.http://en.wikipedia.org/wiki/Four_fours
It basically work, but the problem is that it can only use the + - / * operators, because it can't have two operators in a row(Solutions like this (4-4)/4+factorial(4) aren't allowed because of this "+factorial" part).What I could do(but would be to slow) would be to make pairings like this.
['-', '/', '+', '*', '-sqrt', '-^', '-factorial', '-.', '/sqrt', '/^', '/factorial', '/.', '+sqrt', '+^', '+factorial', '+.', 'sqrt', '^', 'factorial', '.']
This is far too many operators.
What I would like to do, would be to try something like this
formula = bracket.format(["(4)","(4*)","(4-)","(4/)"], *combination).replace(".(4","(.4")
Except this syntax is invalid.
How can I do this?
Or if you have better ideas(which I'm sure some of you do) I am open to suggestions.

You could try converting it into pre or post-fix. You can allow it to use ['!','sqrt','.'] anytime. '^' would only be used if at least one four is still available to be pushed on the stack. And ['+','-','/','*'] would only be pushed if there are more operators than numbers (or something like that).

Related

How to have a function feed another function's input [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I'm making a hangman game and testing how different letter picking algorithms fare, but to do this, the guessing algorithm function has to feed a letter into the hangman function's input('Select a letter').
How do you make it so that a function detects when another function is waiting for an input ?
Assuming you are doing input() in a loop inside your hangman function, you could switch that to a yield and let an external function drive input as needed. In this example I have a hangman function that uses yield to get data. Now its a generator and driving function can use next and the generator's .send method to pump data into it.
def hangman(chances=5):
for i in range(chances):
letter = yield "prompt"
if letter == "quit":
yield "quit"
return
print("letter", letter)
# do all the things
solved = False
if solved:
yield "solved"
yield "failed"
def command_line_prompt_hangman():
feeder = hangman()
state = next(feeder)
while state == "prompt":
state = feeder.send(input("Next letter: "))
def test():
# after years of testing the best algorithm is
test = ['a', 'b', 'c', 'd', 'e', 'f']
feeder = hangman()
assert next(feeder) == "prompt"
for count, letter in enumerate(test, 1):
state = feeder.send(letter)
if state == "solved":
print("did it in ", count, "tries")
break
if state == "failed":
print("exceeded count")
break
command_line_prompt_hangman()
test()
Instead of using the input function, write a custom function to pull an output from whatever algorithm you are using. That would look something like this:
user_input = algo_obj.get_input(game_state)
In this case, algo_obj would be an object storing the current state of the algorithm/generator (if such a state exists, otherwise you can just call the function normally). game_state would be some representation of the game's current state (available letters, the word-form -- ie. blanks & letters).
You can then feed user_input to your Hangman function.
This should be as simple as:
Define both functions.
Pass one function return value to the other one as argument.
This can be done by using input() as according to this
e.g. Define the functions
def first_function():
input_variable = input("Please enter some data")
return input_variable
def second_function(a):
print(a) # Do some calculations here
And use them:
second_function(first_function())
I wouldn't say that this is necessarily the best way to go about but it solves Your problem. If You would like to receive a more detailed answer please provide code samples.

python getting plural of a noun [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
i am trying to make the same functionality using lambda to get the plural of a word, this is my function (i want to write it in lambda form).
import re
def plural(noun):
if re.search("[sxz]$",noun):
return re.sub("$","es",noun)
elif re.search("[^aeioudgkprt]h$",noun):
return re.sub("$","es",noun)
elif re.search("[^aeiou]y$",noun):
return re.sub("y$","ies",noun)
else:
return noun+"s"
i want to make the same function job using lambda ,not sure where to start.
(i am using python 2.7)
import inflect
result = inflect.engine().plural('bike')
import re
rules=((lambda word:re.search('[sxz]$',word),lambda word:re.sub('$','es',word)),
(lambda word: re.search('[^aeioudgkprt]h$', word),lambda word: re.sub('$', 'es', word)),
(lambda word: re.search('[^aeiou]y$', word),lambda word: re.sub('y$', 'ies', word)),
(lambda word: re.search('$', word),lambda word: re.sub('$', 's', word)))
def plural(noun):
for findpattern,rule in rules:
if findpattern(noun):
return rule(noun)
print plural('boy')
This your functions as lambda rules, it will search for pattern if it's true,apply rule

Trying to make a dice rolling script in python [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I'm getting a vague syntax error with the print int(rollval) on line 15.
from random import randint
roll == 0
def diceroll(roll):
def dicenum(userdicenum):
userdicenum = int(raw_input("How many dice would you like to roll?"))
return userdicenum
def dicesides(userdiceside):
userdiceside = int(raw_input("How many sides for each die?"))
return userdiceside
for rollval in range(1,userdicenum):
rollval = randint(1,userdiceside)
print int(rollval)
roll = roll + rollval
return roll
print roll
from random import randint
def diceroll():
def dicenum():
userdicenum = int(input("How many dice would you like to roll?"))
return userdicenum
def dicesides():
userdiceside = int(input("How many sides for each die?"))
return userdiceside
roll = 0
dicesida = dicesides() # so you dont have to re type it =)
for rollval in range(dicenum()):
rollval = randint(1,dicesida)
print(int(rollval))
roll = roll + rollval
return roll
print(diceroll())
is this what you want?
One difference between Python3 and Python2 is that in Python3, the print statement is a function in Python3, but a keyword in Python2. The fact that it is a function means that you have to use it like any other function, which is by putting the arguments within parenthesis.
Use print(int(rollval))
You should also have a look at the second line. roll == 0 should probably be roll = 0. And as mentioned in comments, you should also not use raw_input in Python3. Use input.

I need to sum numbers in a file [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Ok I'm learning read and write files at the moment but I need a little help to sum the numbers in a file.
def main ():
sample = open (r'C:\user\desktop\text.txt','r')
for i in range (the range of int is unknown)
file = sample.read ()
sample.close ()
main ()
You may iterate over the file like this:
for i in sample:
and convert using int() to an integer.
The for loop can be done with map and the sum with sum.
This is the final code:
def main ():
sample = open (r'C:\user\desktop\text.txt','r')
result = sum(map(int, sample))
print(result)
sample.close ()
main ()
What you want is:
for line in sample:
# process the line
If each line just contains an integer, you can simplify it further to sum(map(int, sample)).
To add safety, you should cast your integers with error checking and ensure that the file exists before reading it.
import os
def safecast(newtype, val, default=None):
try:
return newtype(val)
except ValueError:
pass
return default
def sumfile(filename):
if not os.path.isfile(filename):
return None
sum = 0
with open(filename, "r") as file:
for line in file:
sum += safecast(int, line, 0)
return sum
sum = sumfile(r'C:\user\desktop\text.txt')
print(sum)

name.replace xX with y if x exists [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
To be more specific I'd like to figure out how to:
name.replace xX with y if x exists, if not then just replace X
I've searched this forum for an hour now, make it two, and all I find is how to replace one thing with another, which by now is pretty easy.
/a
you can just run:
output = name.replace('xX','y').replace('X','y')
Example:
name = "123xX345X"
output = "123y345y"
Sounds like a job for regular expression x?X:
>>> import re
>>> text = " test xX blabla"
>>> re.sub('x?X', 'y', text)
' test y blabla'
>>> text = " test X blabla"
>>> re.sub('x?X', 'y', text)
' test y blabla'
Quote from docs about ? mark:
The question mark character, ?, matches either once or zero times; you
can think of it as marking something as being optional. For example,
home-?brew matches either homebrew or home-brew.
if 'x' in name:
name = name.replace('xX','y')
else:
name = name.replace('X','y')
From your example above this is a slightly more involved problem. You have to make sure to do your renames in the root namespace or things can get nasty. You also run the risk of renaming parents before children, which will make it hard to get at the children with one call to ls. So:
def replace_with_any_namespace(src, tgt):
cmds.namespace(set=":")
results = {}
xforms = cmds.ls(r=True, tr=True, l=True) # use long paths and recursive to get all namespaces
xforms = [i for i in xforms if src in i] # only work on items with your target pattern
xforms.sort()
xforms.reverse() # sort and reverse means children get renamed before parents
for item in xforms:
path, sep, shortname = item.rpartition("|") # gets only the last name
newname = shortname.replace(src, tgt) # this should be fine even if the namespace is there
results[item] = cmds.ls(cmds.rename ( item, newname), l=True)[0]
# the paths and returns are all long paths so there are no ambiguities
return results
Are you trying to move things out of their namespaces with this? Thats easier:
cmds.namespace(mv = ("R", ":"), force=True)
which moves everything in R:* to the base namespace. This will probably result in some renames, however. You might want to put important nodes into a set before you call this so you can find them.

Categories