Find the next number in the pattern

2

Write a program, that takes 5 numbers as input and outputs the next number in the pattern.

Heres a text file with 1835 test patterns, containing 6 numbers separated by commas each line. Using the first 5 numbers calculate the 6th number and then check if it matches. You must get all the test cases correct.

There are 3 types of patterns:

  1. xn = xn-1+k

  2. xn = xn-1*k

  3. xn = xn-1^2

The first x value and k were chosen randomly between a set range to create the pattern sample file.

This is code-golf, lowest number of bytes to get all of the test cases correct wins.

rodolphito

Posted 2014-09-18T05:50:12.523

Reputation: 795

3It seems fairly easy to get 100%. Is there a tiebreak? – xnor – 2014-09-18T05:57:57.893

The tiebreaker should be the length of the code because any solution can easily be O(n) time, i'll edit the question. Well this is just a duplicate of the other question then, should it be closed? – rodolphito – 2014-09-18T06:43:12.837

In that case, why don't you make it code golf and require getting all the test cases right? – xnor – 2014-09-18T06:46:24.003

I wouldn't consider it a duplicate. In the other question, different operations are applied cyclically, which makes it a lot harder than a single operation applied repeatedly in this one. – xnor – 2014-09-18T06:47:59.563

Thanks for the advice, edited. I was considering using doubles and decimals instead of integers for this question, but then I would have to get tangled in all the rounding and accuracy check and such. – rodolphito – 2014-09-18T06:51:57.140

What's the story with 4,16,256,65536,4294967296,0 in the pattern? Is it a bug due to you not using an arbitrary precision type or what? – Will – 2014-09-18T06:54:47.140

Most likely. Sorry about that. I will change the link in a minute. – rodolphito – 2014-09-18T06:57:15.567

Heh, I had used a java long to hold the number, it couldn't fit 2^64... – rodolphito – 2014-09-18T07:03:02.580

We also seem to disagree on what 152587890625 * 152587890625 is. – Will – 2014-09-18T07:10:44.320

Fixed that too, thanks for spotting those. I'll be off to bed now haha its 3am. I will fix anything else that is found when I wake up. Thanks again :) – rodolphito – 2014-09-18T07:19:41.670

Now that code length matters: Is the code required to open the given file and run on the test cases? – xnor – 2014-09-18T07:25:57.013

1Its pretty disappointing there are no trick rows; contestants are getting a perfect score by checking just the first three ints, and there's no divide-by-zeros being thrown either. – Will – 2014-09-18T07:53:06.987

2

-1 for doing big changes in the scoring system. Please use the sandbox the next time

– John Dvorak – 2014-09-18T08:39:55.690

@JanDvorak ok I will use that, thanks for telling me :) (I had no idea it existed haha) – rodolphito – 2014-09-18T14:38:39.357

@Rodolvertice most sandbox questions get a great response on the main site. However, I think some people like to get a head start on questions while they are in the sandbox, so if you want people on an equal footing for whatever reason, you aren't required to post it there. It's a useful tool but not necessary in every case. – hmatt1 – 2014-09-18T20:03:43.267

Answers

4

Python 2: 55 bytes

f=lambda a,b,c,d,e:e+c-d*2and e*e/d**(d*d==e*c)or e*2-d

We check for the three cases as follows:

  1. Check for arithmetic sequence: If e+c==d+d, output e+e-d
  2. Check for geometric sequence: If e*c==d*d, output e*e/d
  3. Otherwise, squared sequence: Output e*e.

Case 3 is used as the else-case to avoid the more-lengthy checking for successive squaring.

Case 1 is checked first, with Boolean short-circuiting to avoid checking Case 2 after a success, as this causes an error when d=0. There's a test case of all zeroes, so we can't cheat this by picking another position in place of d.

Afterwards, we can treat both Cases 2 and 3, since there's no risk of a divide-by-0 error. Noting that the choices are similar (e*e vs e*e/d), we combine them with an arithmetic expression by dividing by either d**1 for Case 3 or d**0 for Case 2. Although this division produces an integer value, we must use Python 2 (or //) to avoid float errors that case the largest-output test case to fail.

Thanks to @Will for inspiration on the code structure and a very-helpful test framework.

xnor

Posted 2014-09-18T05:50:12.523

Reputation: 115 687

Still, like the multiply instead of and :) – Will – 2014-09-21T09:39:53.627

3

Python all right, 72 74 75 chars

p=lambda i,j,k,l,m:j-i!=k-j and(k==j*j==j*i*i and m*m or m*l/k)or m+j-i

Thx to xnor for showing me the if/else to and/or trick and golfing off a char :)

Thx to flornquake for fixing the k==j*j==j*i*i and saving another two chars :)

Actually, it gets one wrong... but that's a bug in the test patterns which was acknowledged yesterday but still not fixed.

Testing code, hopefully useful for all competitors to test with:

def check(func,title):
    right = 0
    print "===", title, "==="
    for i,test in enumerate(open('patterns.txt')):
        test = map(int,test.split(','))
        try:
            got, expected = func(*test[:5]), test[5]
        except Exception as e:
            got = e
        if got != expected:
            print "ERROR on line %d: %s != %d" % (i, got, expected)
            print " test :", ", ".join(map(str,test))
            plus = multi = cube = str(test[0])
            for i in range(1, 6):
                plus += ", %d" % (test[i-1]+(test[1]-test[0]))
                multi += ", %s" % ((test[i-1]*(test[1]/test[0])) if test[0] else "DivZero")
                cube += ", %d" % (test[i-1]**2)
            print " as + :", plus
            print " as * :", multi
            print " as ^2:", cube 
        else:
            right += 1
    print right, "out of", i+1, "right!"

says:

ERROR on line 19: 23283064365386962890625 != 3273344365508751233
 test : 5, 25, 625, 390625, 152587890625, 3273344365508751233
 as + : 5, 25, 45, 645, 390645, 152587890645
 as * : 5, 25, 125, 3125, 1953125, 762939453125
 as ^2: 5, 25, 625, 390625, 152587890625, 23283064365386962890625
1834 out of 1835 right!

Will

Posted 2014-09-18T05:50:12.523

Reputation: 1 143

You can usually save chars from the if/else ternany operator using the and/or trick: http://codegolf.stackexchange.com/a/57/20260

– xnor – 2014-09-19T08:33:59.080

I had deleted my suggestion of k==j*j==i**4 on realizing it fails for 1, -1, 1, -1, 1, -1, but it turns out you can dodge it by using j,k,l instead, which changes the parity. I assume it's allowed to take advantage of a coincidental hole in the test cases? – xnor – 2014-09-19T08:56:53.750

@xnor thx for the encouragement and leads :) I don't really want to take advantage of holes in the test cases. And the I didn't know that neat and/or trick! But its not applicable for this particular problem because the correct prediction may be falsy, e.g. -10, -8, -6, -4, -2, 0. Still neat to learn. – Will – 2014-09-19T08:59:35.493

Hmm, I think and/or should just work, independent of the truthiness of the output. Let's try to fix it. Can you check that you converted a if b else c to b and a or c? And also that the two of it are nested right and perhaps parenthesized to parse right? If it still doesn't work, could you please tell me what you have. – xnor – 2014-09-19T09:04:03.323

@xnor q=lambda i,j,k,l,m:j-i==k-j and m+j-i or(j==i*i)&(k==j*j)and m*m or m*l/k is how I wrote it. – Will – 2014-09-19T09:05:11.227

Weird, that seems totally right, I have no idea why the behavior changes. I'll have to figure that out. The switched version works though: q=lambda i,j,k,l,m:j-i!=k-j and((j==i*i)&(k==j*j)and m*m or m*l/k)or m+j-i – xnor – 2014-09-19T09:11:30.303

@xnor thx that was neat :) – Will – 2014-09-19T09:18:07.767

@xnor It doesn't work because the a if b else c-to-b and a or c trick relies on a being truthy. – flornquake – 2014-09-19T10:43:59.640

It think k==j*j==j*i*i should work in place of (j==i*i)&(k==j*j). – flornquake – 2014-09-19T10:48:17.787

@flornquake oooh thx of course! – Will – 2014-09-19T10:56:43.850

@flornquake Thanks, I see. To be more specific, the if/else to and/or conversion always gives the same value if it evaluates, but has slightly different short-circuiting behavior. When b is Truthy and a is Falsey, c is evaluated though its value doesn't matter. – xnor – 2014-09-19T20:01:31.293

2

Python 3 -1833

Length 198 chars

Now updated to conform to the rules.

m=0
for i in open('s'):
 if','in i:
  i,j,k,l=list(map(int,i.split(',')[2:]))
  if j-i==k-j:
   if k+(j-i)==l:m+=1
  elif j/i==k/j:
   if k*(j/i)==l:m+=1
  elif i**2==j:
   if k**2==l:m+=1
print(m)

Beta Decay

Posted 2014-09-18T05:50:12.523

Reputation: 21 478

You can golf this a lot (the rules are changing under us and code size is now important) e.g. for i in open('s.txt'): and unpacking the first three ints in the split etc. – Will – 2014-09-18T06:56:29.490

1

here's a 112 byte version, but I miss tricks: https://gist.github.com/williame/f8ae068ff7e658cde28f

– Will – 2014-09-18T07:05:38.240

@Will Thanks, what do you mean by tricks? – Beta Decay – 2014-09-18T07:30:04.543

Here's an alternative one-liner at 112 chars that copes with the first or second int being 0: print sum((lambda i,j,k:j-i==k-j or(i*j and j/i==k/j)or i**2==j)(*map(int,s.split(',')[:3]))for s in open('s')) – Will – 2014-09-18T07:50:03.013

1I know this has been accepted by the poster, so must meet their criteria of correctness, but it seems to be overlooking the requirement Using the first 5 numbers calculate the 6th number and then check if it matches? – Will – 2014-09-18T08:11:49.003

4i**2 is longer than i*i. – Rainbolt – 2014-09-18T15:19:20.687

4Python can read from files without a .txt extension (I just tested this). The name of the file was not specified in the problem, so you should shave off four characters by naming it a single letter. for i in open('s'):, assuming the file was named "s". – Rainbolt – 2014-09-18T15:24:43.607

This seems to be reading the file and giving itself a point for each row it would have gotten right. What I thought was asked for is a function that takes five numbers and gives the sixth, with the file not part of the code, but a check for scoring. But it's up to OP I guess. – xnor – 2014-09-18T19:24:35.790

You are right, I'm sorry i'm taking so long to respond and fix stuff (school), the program/function is only required to take 5 inputs of numbers and output the next number in the sequence. (first line in the challenge question). You can then test it on all the test cases. – rodolphito – 2014-09-19T05:35:02.993

Checking the third and forth items because I said the first two may contain zeros does not solve the divide by zero problem ;) – Will – 2014-09-19T07:50:44.633

the program should only take 5 numbers as input and output the sixth. The testing program is different. – rodolphito – 2014-09-19T22:16:28.437

2

C# - 1835

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace pattern
{
    class Program
    {
         static void Main(string[] args)
         {
            string[] lines = File.ReadAllLines("in.txt");
            int matches = 0;
            for(int i = 0; i < lines.Length; i++)
            {   
                long[] numbers = lines[i].Split(',').Select(a=>long.Parse(a)).ToArray();

                long nextnum = 0;
                if(numbers[1]-numbers[0]==numbers[2]-numbers[1])
                nextnum = numbers[numbers.Length-2]+(numbers[1]-numbers[0]);
            else if(numbers[1]/numbers[0]==numbers[2]/numbers[1])
                nextnum = numbers[numbers.Length-2]*(numbers[1]/numbers[0]);
            else if(numbers[1] == numbers[0]*numbers[0])
                nextnum = numbers[numbers.Length-2]*numbers[numbers.Length-2];
            if(nextnum == numbers[numbers.Length-1])
                matches++;
        }
        Console.WriteLine(matches + " matches found!");
        Console.ReadLine();
    }
}
}

This is obviously not golfed at all, but it finds all numbers eventually. It just prints how many matches it found, but you could potentially display all found numbers, only non-matches, etc...

(This is conceptually very similar to Beta Decay's answer, just a little bit more complicated)

Christoph Böhmwalder

Posted 2014-09-18T05:50:12.523

Reputation: 681

I love C#, it is like a mixture of everything, it has lambdas, anonymous delegates, LINQ, and a bunch of other features haha, not exactly fit for golfing though :P – rodolphito – 2014-09-18T06:47:28.243

Yeah, C# is great for some purposes. Well, like I said, I didn't golf this a whole lot :P – Christoph Böhmwalder – 2014-09-18T07:37:31.293

1

TI-BASIC, 120 117 136

Prompts for input and returns the output.

Input L1:0:If not(L1(5:Stop
If L1(5)-L1(4)=L1(4)-L1(3:L1(5)+(L1(5)-L1(4
If L1(5)/L1(4)=L1(4)/L1(3:L1(5)(L1(5)/L1(4
If L1(4)²=L1(5:L1(5)²

Edit: Fixed divide by zero error.

Timtech

Posted 2014-09-18T05:50:12.523

Reputation: 12 038