15
\$\begingroup\$

Challenge

enter image description here

Write a program that takes an array of 4 integers (which represents a sequence of numbers generated by a certain algorithm) and returns the next integer that would follow.

We will only be using simple addition, subtraction, multiplication and division algorithms with a constant (i.e non-variable) variation.

For division we will use the floor integer values: 133/4 = 33 and 33/4 = 8

You can assume that there will always be one single valid return value

Test cases

[14,24,34,44] should return 54 (addition Algorithm)

[105,45,-15,-75] should return -135 (subtraction algorithm)

[5,25,125,625] should return 3125 (multiplicative algorithm)

[256,64,16,4] should return 1 (division algorithm)

General rules

\$\endgroup\$
  • 2
    \$\begingroup\$ This is a simplified version of What comes next? and borderline duplicate. \$\endgroup\$ – Peter Taylor Aug 30 '16 at 14:15
  • 7
    \$\begingroup\$ In the future, I recommend you to post in Sandbox before going live so that you can receive other people's comments beforehand. \$\endgroup\$ – Leaky Nun Aug 30 '16 at 14:52
  • 5
    \$\begingroup\$ You should really add some tests cases for integer division. Almost all replies fail to give correct result for [261,65,16,4], [4,2,1,0], or [2,1,0,0] \$\endgroup\$ – Damien Aug 30 '16 at 16:40
  • 5
    \$\begingroup\$ I disagree with the duplicate vote(s). Finding the algorithm is simpler in the sense that there's only one operation to consider, but at the same time, it's harder because integer division has to be accounted for. I don't think there's porting an answer from the other challenge would be substantially easier than writing one from scratch. \$\endgroup\$ – Dennis Aug 30 '16 at 16:57
  • 3
    \$\begingroup\$ You should probably specify non-negative integers, as when a division series is negative there are two interpretations. For example -81/4 is either 21 r 3 or -20 r -1. \$\endgroup\$ – Jonathan Allan Aug 30 '16 at 18:42

15 Answers 15

6
\$\begingroup\$

05AB1E, 18 16 18 bytes

D¥¬QPi`+s-ë`r/s\*î

Explanation

D                   # duplicate
 ¥                  # delta's
  ¬Q                # compare first delta to the other deltas
    P               # product (1 if all deltas are equal, otherwise 0)
     i              # if 1 (we're dealing with addition or subtraction)
      `+s-          # add the difference between the elements to the last element
          ë         # else (we're dealing with multiplication or division)
           `r/      # divide the 2nd element by the 1st
              s\*   # multiply with the 4th element
                 î  # round up

Try it online!

\$\endgroup\$
  • \$\begingroup\$ The output is wrong with [4,2,1,0] ... \$\endgroup\$ – Damien Aug 30 '16 at 16:30
  • \$\begingroup\$ @Damien: Thanks for letting me know. I fixed it and it even saved me a couple of bytes :) \$\endgroup\$ – Emigna Aug 30 '16 at 16:44
  • \$\begingroup\$ Great. Now it validates all my test cases. \$\endgroup\$ – Damien Aug 30 '16 at 16:47
  • \$\begingroup\$ Try edge case for divide by four: [-325, -82, -21, -6] \$\endgroup\$ – Jonathan Allan Aug 30 '16 at 18:32
  • \$\begingroup\$ ...actually I guess the question should either be just for non-negative integers or should specify which convention is to be used. \$\endgroup\$ – Jonathan Allan Aug 30 '16 at 18:40
14
\$\begingroup\$

Javascript (ES6),  44   42  44 bytes (fixed)

(a,b,c,d)=>a-b+d-c?d/(a<b?a/b:a/b|0)|0:d+c-b

Saved 2 bytes, following IsmaelMiguel's advice.
Fixed version for [2,1,0,0] and [1,0,0,0] as suggested by edc65

30 bytes version

For the record, my first attempt was 32 30 bytes but was lacking floor() support for the division. It also fails for special cases such as [2,1,0,0] and [1,0,0,0].

(a,b,c,d)=>c-2*b+a?d*c/b:d+c-b

Demo

var f =
(a,b,c,d)=>a-b+d-c?d/(a<b?a/b:a/b|0)|0:d+c-b

var test = [
  [ 14, 24, 34, 44 ],     // should return 54 (addition Algorithm)
  [ 105, 45, -15, -75 ],  // should return -135 (subtraction algorithm)
  [ 5, 25, 125, 625 ],    // should return 3125 (multiplicative algorithm)
  [ 256, 64, 16, 4 ],     // should return 1 (division algorithm)
  [ 260, 65, 16, 4 ],     // should return 1 (division algorithm with floor())
  [ 2, 1, 0, 0 ],         // should return 0 (special case of division algorithm)
  [ 1, 0, 0, 0 ]          // should return 0 (special case of division algorithm)
];

test.forEach(l => console.log('[' + l.join`, `+ '] => ' + f(...l)));

\$\endgroup\$
  • \$\begingroup\$ Wow, I didn't know that js has pattern matching. \$\endgroup\$ – Leaky Nun Aug 30 '16 at 14:13
  • \$\begingroup\$ @LeakyNun - Destructuring assignment was indeed introduced in ES6. Note that you can't do [a,b]=> for function parameters. The parentheses are required. \$\endgroup\$ – Arnauld Aug 30 '16 at 14:22
  • \$\begingroup\$ Nice, but you should handle integer division: [260, 65, 16, 4] => 0.9846153846153847. It should give 1 \$\endgroup\$ – Damien Aug 30 '16 at 14:30
  • \$\begingroup\$ @Damien - Ah well... I knew someone would notice. ;-) That's fixed. \$\endgroup\$ – Arnauld Aug 30 '16 at 14:57
  • \$\begingroup\$ What about [2,1,0,0] ? Should give 0. I think it's the only counter example for b*2==c+a <=> addition/substraction algorithm \$\endgroup\$ – Damien Aug 30 '16 at 16:26
11
\$\begingroup\$

Brachylog, 37 33 27 bytes

b:[E]cL,?:Iz{:+a|:*a|:/a}Lt

Try it online! or verify all test cases.

Saved 10 bytes thanks to @LeakyNun.

Explanation

Input = [A:B:C:D]

b:[E]cL,     L = [B:C:D:E]
?:Iz         Create the list [[B:I]:[C:I]:[D:I]:[E:I]]
{            Either…
    :+a          Sum all couples of that list
|            or…
    :*a          Multiply all couples of that list
|            or…
    :/a          Integer divide all couples of that list
}L          The result is L
t           Output is the last element of L

As LeakyNun pointed out, we don't need the subtraction case because I can be any integer.

\$\endgroup\$
  • 4
    \$\begingroup\$ wow, brachylog(& prolog) are awesome \$\endgroup\$ – Maltysen Aug 30 '16 at 14:19
  • 2
    \$\begingroup\$ Addition and subtraction is the same \$\endgroup\$ – Leaky Nun Aug 30 '16 at 14:22
  • 1
    \$\begingroup\$ @LeakyNun Correct, thanks! \$\endgroup\$ – Fatalize Aug 30 '16 at 14:25
  • 3
    \$\begingroup\$ 29 bytes \$\endgroup\$ – Leaky Nun Aug 30 '16 at 14:31
  • 3
    \$\begingroup\$ 27 bytes \$\endgroup\$ – Leaky Nun Aug 30 '16 at 14:31
6
\$\begingroup\$

Haskell, 65 bytes

f l@[a,b,c,d]|[a,b..d]==l=d+b-a|z<-b+0^b=div(d*b)$a-mod(max b a)z
\$\endgroup\$
5
\$\begingroup\$

Python 2, 40 bytes

lambda(a,b,c,d):[d+c-b,d*c/b][c-2*b+a>0]

It's literally the JS answer ported into Python (thanks @LeakyNun!). My previous approach was ridiculously long, but here it is:

Python 2, 169 166 bytes

The second and third levels are a raw tab and a raw tab plus a space, respectively, which plays really badly with Markdown, so the tabs have been replaced by 2 spaces.

x=input()
q='%d%s%d'
for i in range(max(x)):
 for o in'+-*/':
  a=1
  for e,n in zip(x,x[1:]):
   try:1/(eval(q%(e,o,i))==n)
   except:a=0
  if a:print eval(q%(x[-1],o,i))

Pretty simple; tries every constant and operator it thinks could be the constant, then if the constant/operator combination works for every element in the list (using a try/except pair to avoid ZeroDivisionErrors), it prints the result for the last element in the list.

I'm sure there's a better method here, this is the naive method.

\$\endgroup\$
  • \$\begingroup\$ You'd better just port the js answer into Python \$\endgroup\$ – Leaky Nun Aug 30 '16 at 14:24
  • \$\begingroup\$ Breaks for [1,0,0,0] which should output 0 \$\endgroup\$ – Jonathan Allan Aug 30 '16 at 18:35
3
\$\begingroup\$

TSQL, 55 bytes

This script is trying adding and subtraction in the same check, then it tries to multiply, if that fails, it must be division.

DECLARE 
@1 INT=6561,
@2 INT=729,
@3 INT=81,
@  INT=9

PRINT IIF(@2-@1=@-@3,@*2-@3,IIF(@1*@2=@3,@*@1,sqrt(@)))

Fiddle

\$\endgroup\$
3
\$\begingroup\$

C#, 63 bytes

int f(int[]x)=>2*x[1]-x[0]==x[2]?x[3]+x[1]-x[0]:x[3]*x[1]/x[0];

Checks whether the difference between the first and second element is the same as the difference between the second and third element. If so, it does addition/subtraction, otherwise it does multiplication/division.

\$\endgroup\$
2
\$\begingroup\$

JavaScript, 73 bytes

(a,b,c,d)=>(x=b-a,c-b==x&&d-c==x)?d+x:(x=b/a,b*x|0==c&&c*x|0==d)?d*x|0:-1

Tests:

console.log(s.apply(null,[14,24,34,44]), 54);
console.log(s.apply(null,[105,45,-15,-75]), -135);
console.log(s.apply(null,[5,25,125,625]), 3125);
console.log(s.apply(null,[256,64,16,4]), 1);

console.log(s.apply(null,[2,1,0,0]),0);
console.log(s.apply(null,[1,0,0,0]),0);
console.log(s.apply(null,[-325,-82,-21,-6]),-1);

console.log(s.apply(null,[-1,-1,-1,-1]),-1);
console.log(s.apply(null,[0,0,0,0]),0);

Works for them all.

\$\endgroup\$
  • 1
    \$\begingroup\$ Wasn't sure about the etiquette here. I know there's already another JS answer, but it doesn't address the edge cases. Mine is longer, but handles all those. Let me know if I didn't do this right. \$\endgroup\$ – Whothehellisthat Aug 31 '16 at 14:13
  • 1
    \$\begingroup\$ There's nothing wrong with posting an answer in the same language as another answer, especially if your answer is correct and the other one is not. I don't know if you have enough rep to do so, but you might also want to comment on that answer to let them know which edge cases they are missing. \$\endgroup\$ – DJMcMayhem Aug 31 '16 at 14:29
  • \$\begingroup\$ I actually took the edge cases from that other post, but they haven't solved the issue. ;P \$\endgroup\$ – Whothehellisthat Aug 31 '16 at 14:30
2
\$\begingroup\$

GameMaker Language, 70 bytes

a=argument0;If a[3]+a[1]=a[2]*2return a[4]*2-a[3]return a[4]*a[4]/a[3]
\$\endgroup\$
2
\$\begingroup\$

R, 68 74

Array: 68 bytes

function(x)if(x[2]-x[1]==x[3]-x[2])x[4]+x[2]-x[1]else x[4]%/%(x[1]%/%x[2])

> (function(x)if(x[2]-x[1]==x[3]-x[2])x[4]+x[2]-x[1]else x[4]*x[2]/x[1])(c(14,24,34,44))
[1] 54

4 inputs: 45 bytes

function(a,b,c,d)if(b-a==c-b)d+b-a else d*b/a

Bonus solution with log, exp, var, 71 bytes

if(var(v<-diff(x<-scan(,1)))==0)x[4]+v[1]else x[4]*exp(diff(log(x)))[1]

update: integer division

\$\endgroup\$
  • \$\begingroup\$ Isn't this taking four variables rather than an array? If not you can get rid of the parentheses around b-a to save a byte though (and I note that your example calls are adding spaces back in). \$\endgroup\$ – Jonathan Allan Aug 30 '16 at 20:32
  • \$\begingroup\$ @JonathanAllan You are right. It does not take an array. The byte count has been updated. The parenthesis are needed due to else, but we can save a byte by adding a space instead. The calls don't need the additional spaces. \$\endgroup\$ – Vlo Aug 30 '16 at 21:16
  • \$\begingroup\$ Yep, that's why I said you could save 1 byte rather than 2 \$\endgroup\$ – Jonathan Allan Aug 30 '16 at 21:34
  • \$\begingroup\$ Note, it does not currently handle the integer division requirement fully, e.g. 261,65,16,4 returns 0.9961686 rather than 1 (of course there should be a test case for this in the question). \$\endgroup\$ – Jonathan Allan Sep 1 '16 at 11:09
  • 1
    \$\begingroup\$ @JonathanAllan function(x)if(x[2]-x[1]==x[3]-x[2])x[4]+x[2]-x[1]else x[4]%/%(x[1]%/%x[2]) \$\endgroup\$ – Vlo Sep 1 '16 at 14:09
1
\$\begingroup\$

Java, 125 123 bytes

Golfed:

int m(int[]a){int r=(a[1]>a[0])?a[1]/a[0]:a[0]/a[1];return(a[0]-a[1]==a[1]-a[2])?a[3]-a[0]+a[1]:(a[0]<a[1])?a[3]*r:a[3]/r;}

Ungolfed:

int m(int[] a)
{
    int r = (a[1] > a[0]) ? a[1] / a[0] : a[0] / a[1];
    return (a[0] - a[1] == a[1] - a[2]) ? a[3] - a[0] + a[1] : (a[0] < a[1]) ? a[3] * r : a[3] / r;
}

This code surely has some issues since it doesn't handle division by zero and such things. It also won't work of course if there are more (or less) than 4 integers in the input array a. Which makes it beyond stupid, but I had fun :)

Try it out: https://ideone.com/nELH5I

\$\endgroup\$
1
\$\begingroup\$

TI-Basic, 37 bytes

Works on any TI-83/84 calculator

Input L1                     gets input into an array
L1(4)²/L1(3                  calculate the fifth number in a geometric series
If not(sum(ΔList(ΔList(L1    if ΔList(ΔList(L1)) yields an array of all zeroes
L1(4)2-L1(3                  calculate the fifth number in an arithmetic series
                             Ans is implicitly returned
\$\endgroup\$
1
\$\begingroup\$

Python 2, 75 66 65 61 bytes

lambda(a,b,c,d):d*2-c if d-c==b-a else d*b/a or b and d/(a/b)

Much longer than my previous 38 byte entry which did not cater for the division series correctly (just as most others didn't).

Test cases and more edge cases are on ideone

Note: integer division for a negative here is defined as having a remainder with the same sign as the divisor, so -81/4 would be -21 with a remainder of 3 and -81/-4 would be 20 with a remainder of -1.

\$\endgroup\$
  • 1
    \$\begingroup\$ negative number divided by negative number is positive... -81/-4 != -21 \$\endgroup\$ – Destructible Lemon Aug 31 '16 at 23:15
  • \$\begingroup\$ @DestructibleWatermelon Indeed it is. I have edited that and added the test case [325,-82,20,-5]. \$\endgroup\$ – Jonathan Allan Sep 1 '16 at 10:20
1
\$\begingroup\$

Jelly, 14 bytes

ṪḤ_ṪµṪ²:ṪµIE$?

Try it online!

ṪḤ_ṪµṪ²:ṪµIE$?  Main Link =
             ?  If
          IE$   [condition]
          I     The differences between consecutive elements
           E    Is equal
ṪḤ_Ṫ            [then]
Ṫ               The last element
 Ḥ              Doubled
  _             Minus
   Ṫ            The last element (second-last of original list)
    µṪ²:Ṫµ      [else]
     Ṫ          The last element
      ²         Squared
       :        Divided by
        Ṫ       The last element (second-last of original list)
\$\endgroup\$
0
\$\begingroup\$

Pyth, 18 Bytes

?-+vzJEyQ/^E2J-yEJ

Accepts input as a newline-separated list of values.

Try it online!

Explanation:

?                         If
 -                          the following are not equal:
  +vzJE                      the sum of first and third values (and call the third value J)
       yQ                    and the second value * 2;
                            (i.e. if it is not an additive or subtractive formula)
          ^E2             Then: square the fourth value
         /   J              and divide by the third
?                         Else:
               yE           double the fourth value
              -  J          and subtract the third
\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.