Make a math equation from the date

19

2

In my Economics class, my friends and I like to come up with ways to rearrange the digits in the date (in MM/DD/YY) format to create a valid mathematical equation. For the most part, we are allowed to use addition, subtraction, multiplication, division, parentheses, and exponentiation in addition to concatenation.

Your program should do something similar. The program should import the current date and insert operators to print an expression according to the following rules.

  • The digits MUST be used in order. Rearrangement of digits is not allowed.
  • The resulting expression must be mathematically accurate.
  • Addition, subtraction, multiplication, division, exponentiation, and use of parentheses is allowed. So is concatenation of digits. However, not all operations are necessary. You cannot use a subtraction sign to make a digit negative (like -1+1+11=10 on November 11, 2010).
  • The program must run in 60 seconds on a standard machine.

For example, this challenge was written on November 10, 2015. The program would interpret this as 11/10/15. A sample output would be (1+1)/10=1/5.


Bonuses

You may multiply the number of bytes in your code by 0.9 for each one of the following your program supports.

  • The program prints all possible expressions that can be formed, separated by newlines. Multiply by an additional 0.95 if the expressions are listed in increasing order of additional symbols.
  • The program also works for MM/DD/YYYY dates, printing a possibility with the first two digits of the year in addition to the possibility without. If this bonus is combined with the first bonus, all possibilities with the first two digits of the year must be printed.
  • The program also prints an equation for when there are multiple equalities (for example, on November 11, 2011, 1=1=1=1=1=1 would be printed, in addition to possibilities such as 1*1=1=1=1=1, 1*1*1=1=1=1, and 1*1*1*1=1=1. All such cases must be printed for the first bonus to be achieved.
  • The program supports conversion to bases between 2 and 16. Note that if the base is not 10, all numbers in the expression must be written in the same base, and (Base b) must be written after the expression (with b replaced accordingly).

This is code golf, so standard rules apply. Shortest code in bytes wins.

Arcturus

Posted 2015-11-10T17:28:32.623

Reputation: 6 537

1What operations are allowed? – anOKsquirrel – 2015-11-10T17:29:07.387

Related – FryAmTheEggman – 2015-11-10T17:30:10.547

1@FryAmTheEggman Is there enough similarity to call this a duplicate? I didn't think so because this challenge doesn't use exclusively one digit and does not have a specific RHS in mind (only equality). – Arcturus – 2015-11-10T17:38:40.377

I would have said duplicate and voted to close if I thought they were dupes :P Some of the approach can be quite similar, so I pointed people trying to answer the question well to another similar question, is all. – FryAmTheEggman – 2015-11-10T17:44:06.467

Ok, thanks. I'll keep the question up. – Arcturus – 2015-11-10T17:51:14.813

17DD/MM/YYYY > MM/DD/YYYY. – orlp – 2015-11-10T18:09:02.197

Is 05/01/2015 valid or do you want 5/1/2015? – Blue – 2015-11-10T18:24:36.467

@muddyfish MM/DD/YYYY would use 05/01/2015. – Arcturus – 2015-11-10T18:55:58.990

3I think you want to use equation in your question where you wrote expression (an expression is just one side of the equation, and then your question doesn't really make sense). – Paŭlo Ebermann – 2015-11-10T19:36:52.327

Similar? – MickyT – 2015-11-10T19:54:14.333

Can we use == in place of =? – ETHproductions – 2015-11-10T21:03:44.220

Also, can we use multiple equals signs (e.g. 110110 => 1-1=0^1=1*0) – ETHproductions – 2015-11-10T22:35:47.730

@ETHproductions Good idea, multiple equals signs in the expression seems like a good bonus. However, == isn't something that should occur. – Arcturus – 2015-11-11T03:09:18.820

1Is this proven possible for any given date? – Zach Gates – 2016-04-04T05:08:52.873

Where is the input from? – Leaky Nun – 2016-04-23T10:23:07.753

Answers

6

Python 3, 424 420 369 363 bytes

import time as t
r=range
x=len
d=list(t.strftime('%m%d%y'))
o=([[x,x+'(',x+')']for x in ['']+"+ - == * / **".split()])
n=[]
for l in o:
    n=l+n
o=n
for p in r(x(o)**(x(d)-1)):
    e=''
    for i in r(x(d)-1):
        e+=str(d[i])+o[(p//(x(o)**i))%x(o)]
    e+=str(d[-1])
    try:
        if eval(e)and e.find('=')!=-1:
            print(e.replace('==','=').replace('**','^'))
            break
    except:pass

Brute-forces all possible combinations of operations in the numbers and stops when it finds one.

EDIT: Saved 4 bytes thanks to @NoOneIsHere

EDIT 2: Saved 51(!) bytes thanks to @ValueInk

Theo

Posted 2015-11-10T17:28:32.623

Reputation: 348

1Hello, and welcome to PPCG! You can inline the except:pass, and remove the space in [ (p//(len(o)**i))%len(o)]. – NoOneIsHere – 2016-08-05T20:24:07.263

If you're importing division from __future__, would upgrading to Python 3 work better for your situation? Also, I don't understand why you reverse o when you're building that list of operators-with-parens you have. – Value Ink – 2016-08-06T03:02:23.590

@ValueInk Yeah, I could probably change it to python 3 and save quite a few bytes. When I started doing the challenge, I wasn't focused on golfing it at all, so it can definitely still be made shorter. Also, since the program is brute forcing all combinations until it finds one, speed is an issue, and I found that it tends to work faster if you use the reverse of o. I'll probably golf this down a bit more to make it a serious contender. – Theo – 2016-08-06T03:08:36.723

o=([[x,x+'(',x+')']for x in",+,-,==,*,/,**".split(',')]) for 2 bytes – Jonathan Allan – 2016-08-07T20:58:33.967

I noticed something else: some dates might not be solvable. An example may be Jul 28th '79: 072879 - in this case the code blows up in memory (I have not looked but probably power-tower related), I added a random shuffle to n to see if I could find a solution for that specific date and got a result of "0=7/2^8^79", but that is only evaluated as true due to floating point rounding of `7/28*7to0.0`. – Jonathan Allan – 2016-08-07T23:47:49.753

Sorry, slightly confused: are you saying that date has no answer, or are you saying it does and my code doesn't find it? – Theo – 2016-08-07T23:57:00.510

Didn't see this very soon due to lack of "@" - If you run your code against that date (import datetime and d=list(t.strftime('%m%d%y', datetime.date(2079,7,28).timetuple())) you will notice it spins and consumes memory. If you change the order of operations it tries you may find a "solution" which is not valid (like 0=7/2^8^79). I don't know if there is no solution to that date (but I can't think of an obvious one, can you?) - EDIT - if we remove the power operation it returns pretty quickly with what should have been an obvious "0/7+28=7+9" – Jonathan Allan – 2016-08-08T02:00:06.153

oops it actually gives, with removal of power operation: "0/7+2*8-7=9", but same difference (forgot to remove the random shuffle) – Jonathan Allan – 2016-08-08T02:09:47.110

@JonathanAllan Any suggestions for fixing that floating point bug? – Theo – 2016-08-08T02:19:37.403

Only thing I can think of straight away is to use the Fractionclass and perform power operations on the integer numerators and denominators (or do the same manually). It may be worth moving all the entries of n containing power operations so they come last as most dates seem to have solutions without power operations (an example of one that does not would be 19-Jan-78 (011978) - which does, however have a solution using powers of 0+1=1^9^7^8. – Jonathan Allan – 2016-08-08T02:26:50.530

Taking the power operation out I also noticed it does not solve 111116 but that should then solve as (1+1+1)*(1+1)=6 – Jonathan Allan – 2016-08-08T03:02:19.423

1@JonathanAllan Huh. Thanks for pointing these out. Ill do a rework of the code when I have time (probably tomorrow) – Theo – 2016-08-08T03:03:29.913

You can also inline for l in o:n=l+n. – NoOneIsHere – 2016-10-03T18:34:35.973

You can change except:pass to except:0 – FlipTack – 2017-03-12T14:37:37.773