7
\$\begingroup\$

I used to play a game while I was in the car, it consisted in taking the n-1 first numbers of another car plate and use operators and roots on them to get the nth number of the plate.

I could use the following operators and roots :

  • addition (ex: 1 + 1 = 2)
  • subtraction (ex: 2 - 4 = -2)
  • division (ex: 10 / 2 = 5) (Note that the division is only allowed if it returns an integer)
  • multiplication (ex: 7 * 7 = 49)
  • square root (ex : sqrt(36) = 6) (Note : must return an integer to be used)
  • cubic root (ex : cbrt(8) = 2) (Note : must return an integer to be used)
  • multiplication by -1 (ex : 8 * -1 = -8)
  • power 2 (ex : 2² = 4)
  • power 3 (ex : 2^3 = 8)
  • leave the integer as it was (ex : 3 = 3)

The operations must be done in order! Which means you have to do the operations between the first and the second integer before an operation between the second and the third.

Example : you can do (3 + 9) * 4 but not 3 + 9*4 if you have [3,9,4,x,y,z,...] as input

Moreover, you can use a unary operator on an integer before doing an operation.

Example : you can do 3² - 7^3

But powers and roots are only allowed on one integer and not on the results of previous operations.

Example : you're not allowed to do (3+7)²

Note that multiplication and division are done that way : it's the applications of the previous operations that's multiplied or divided. For instance :

[x,y,z,t,h] => (x+y)/z + t

[x,y,z,t,h] => (x-y+z) * t

YOUR TASK

Your code will take as input an array of integers of size n, the n-1 first integers will be the one used to obtain the nth number of the array.

You may use all the operators,roots and powers allowed by the rules above. Remember the integers must stay in the same orders to do the operations!

Your code will output a falsey value or an error if the nth number of the array cannot be obtained with the n-1first numbers of the array. On the other hand, if you can obtain the nth number you have to display the operations that led to it. Your code needs to output only one way of obtaining the nth number.

TEST CASES

(Note that I write square root sqrt and cube root cbrt but you can write it the way you want : x**(1/3) for instance)

[1] => error or 1

[2,8] => 2^3

[3,7,46] => 3*(-1) + 7²

[1,2,3,4] => 1*(-1) + 2 + 3

[0,0,0,0,0,0,0,8] => error

[7,4,3,8,16] => 7 + 4² - 3² + cbrt(8)

[28,4,8,7,5,1] => (28 - 4² - cbrt(8) - 7 ) / 5

This is , thus the shortest answer in bytes wins!

\$\endgroup\$
7
  • 3
    \$\begingroup\$ Please consider using the Sandbox for future cahllenges, \$\endgroup\$
    – steenbergh
    May 5, 2017 at 11:24
  • 1
    \$\begingroup\$ Closely related. Likely not a duplicate, as the addition of unary operators will likely significantly change the approaches required. \$\endgroup\$
    – user62131
    May 5, 2017 at 11:25
  • 1
    \$\begingroup\$ What is "in order" mean? Why 3*(-1) + 7² is allowed? Should it be [3*(-1) + 7]²? \$\endgroup\$
    – tsh
    May 6, 2017 at 5:36
  • 1
    \$\begingroup\$ @tsh like shown in the test cases roots and powers only apply to one number, [3*(-1) + 7]² as you described would be suited for a division or a multiplication but not a unary operator \$\endgroup\$
    – user68509
    May 6, 2017 at 10:17
  • \$\begingroup\$ @tsh I edited the post to make it clearer, thank you for pointing that \$\endgroup\$
    – user68509
    May 6, 2017 at 10:55

1 Answer 1

4
\$\begingroup\$

Python 2, 797 547 527 515 504 503 bytes

s=eval("[('N,'%sN*-1,'(-%s)N*n,'%s^2N**3,'%s^3N**.5,'s(%s)N**(1./3),'c(%s)N+m,'%s+%sN-m,'%s-%sN*1./(m or.1),'(%s)/%sN*m,'(%s)*%s'),]".replace("N","'),(lambda n,m=0:n"))
P=__import__("itertools").product
def f(l):
 r=l.pop();L=len(l)
 for S in P(s[1:7],repeat=L):
	if any(s.index(x)>y<2for x,y in zip(S,l))<1<=L:
	 for D in P(s[7:],repeat=L-1):
		I,J=zip(*map(lambda((a,b),l):(a(l),b%l),zip(S,l)));R=I[0];C=J[0];e=0
		for a,b in D:I,J=I[1:],J[1:];R,C=a(R,I[0]),b%(C,J[0]);e=R%1or e
		if e<(R==r):return C

Try it online!

Returns None or a string with the calculation.

Prints:

  • (-n) for n*-1
  • s(n) for square root
  • c(n) for cube root

Explanation

Works by checking all combinations of unary and binary operators on the input.

Outer loop gets all combinations of unary operations, which are applied to each number in the input list.

The inner loop then applies the binary operations on the result of the previous operation, and the next number.

If the result matches, a string with the calculation is returned.

Short-circuits a little by removing all outer loops where a number is 0 and the unary operator is not n => n, or the number is 1 and the operator is not n => n or n => -n

\$\endgroup\$
2
  • \$\begingroup\$ 503 bytes; using a feature I never thought could come in handy. \$\endgroup\$ Oct 10, 2017 at 20:48
  • \$\begingroup\$ @JonathanFrech Wow thanks, I didn't know about that one \$\endgroup\$
    – TFeld
    Oct 11, 2017 at 7:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy