Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Alternating Arrays

An alternating array is a list of any length in which two (not necessarily different) values are alternating. That is to say, all even-indexed items are equal, and all odd-indexed items are equal.

Your task is to write a program or function which, when given a list of positive integers, outputs/returns truthy if it is alternating and falsy otherwise.

This is , so the shortest code (in bytes) wins!

Edge Cases:

[]      ->  True
[1]     ->  True
[1,1]   ->  True
[1,2,1] ->  True

Other Test Cases:

[1,2,1,2]      -> True
[10,5,10,5,10] -> True
[10,11]        -> True
[9,9,9,9,9]    -> True

[5,4,3,5,4,3]   -> False
[3,2,1,2,1,2]   -> False
[1,2,1,2,1,1,2] -> False
[2,2,3,3]       -> False
[2,3,3,2]       -> False

Example

Here is an example you can test your solution against, written in Python 3 (not golfed):

def is_alternating(array):
    for i in range(len(array)):
        if array[i] != array[i%2]:
            return False
    return True
share|improve this question

23 Answers 23

Jelly, 4 bytes

ḣ2ṁ⁼

Try it online!

How it works

ḣ2ṁ⁼  Main link. Argument: A (array)

ḣ2    Head 2; truncate A after its second element. If A has two or less elements,
      this returns A itself.
  ṁ   Mold; cyclically repeat the elements of the previous result to create an
      array that has the same shape/length as A.
   ⁼  Test the result for equality with A.
share|improve this answer
4  
Damn. And changing the 2 to other numbers immediately generalizes the challenge! – Greg Martin 19 hours ago

R, 24 23 bytes

all((a=scan())==a[1:2])

Reads a vector into STDIN, takes the first two elements of that vector, and checks equality. If the lengths of a[1:2] and a don't match, R will loop through a[1:2] to match the length of a. It will give a warning about doing so, but it will work.

Surprisingly this even works for empty input, not sure why, but I'll roll with it.

Saved 1 byte thanks to @MickyT

share|improve this answer
    
you can save yourself a byte with all((a=scan())==a[1:2]) – MickyT 18 hours ago
    
How do you input the data, as vector, list or just single numbers? I've tried typing single numbers on the console but I get the warning: "Warning message: In scan() == a[1:2] : longer object length is not a multiple of shorter object length". Though it works. – skan 13 hours ago
    
By typing single numbers indeed. It will throw a warning if the input length is odd, but it will still give the correct output. – Jarko Dubbeldam 5 hours ago

brainfuck, 34 bytes

,>,>+>,
[
  [<+<<->>>-]
  +<[-<<]
  >[>]
  ,
]
<.

Takes the array as byte values in a string, and outputs \x00 for false and \x01 for true.

Try it online.

This maintains the structure

a b 1 c

on the tape, where c is the current character, b is the previous character, and a is the previous previous character, as long as the array is alternating. If a mismatch is found, the pointer is moved to the left such that a, b, and the 1 flag all become zero, and this situation will continue until all the input is consumed.

share|improve this answer

MATL, 7 6 bytes

2YCs&=

For alternating arrays this outputs a non-empty matrix of ones, which is truthy. For non-alternating arrays the matrix contains at least one zero, and is thus falsy (see here).

Try it online! Or verify all test cases.

Explanation

Let's take [1 2 1 2] as example input.

2YC   % Implicit input. Build matrix whose columns are overlapping blocks of 
      % length 2. If input has size less than 2 this gives an empty array
      % STACK: [1 2 1;
                2 1 2]
s     % Sum of each column. For an empty array this gives 0
      % STACK: [3 3 3]
&=    % Matrix of all pairwise equality comparisons. Implicit display
      % STACK: [1 1 1;
                1 1 1;
                1 1 1]
share|improve this answer
1  
Nice algorithm! This would make a mean Jelly answer. – Dennis 18 hours ago
    
@Dennis Thanks! It was partly inspired by your Jelly approach – Luis Mendo 17 hours ago

JavaScript (ES6), 27 bytes

a=>!a.some((v,i)=>a[i&1]-v)

Test cases

let f =

a=>!a.some((v,i)=>a[i&1]-v)

console.log(f([]));              // -> True
console.log(f([1]));             // -> True
console.log(f([1,1]));           // -> True
console.log(f([1,2,1]));         // -> True
console.log(f([1,2,1,2]));       // -> True
console.log(f([10,5,10,5,10]));  // -> True
console.log(f([10,11]));         // -> True
console.log(f([9,9,9,9,9]));     // -> True
console.log(f([5,4,3,5,4,3]));   // -> False
console.log(f([3,2,1,2,1,2]));   // -> False
console.log(f([1,2,1,2,1,1,2])); // -> False
console.log(f([2,2,3,3]));       // -> False
console.log(f([2,3,3,2]));       // -> False

share|improve this answer

Mathematica, 29 bytes

#=={}||Equal@@(Most@#+Rest@#)&

A port of Luis Mendo's MATL algorithm. Unnamed function taking a list of numbers (or even more general objects) and returning True or False. Tests whether sums of consecutive elements are all equal. Unfortunately Most and Rest choke on the empty list, so that has to be tested separately.

Mathematica, 33 bytes

Differences[#,1,2]~MatchQ~{0...}&

Unnamed function taking a list of numbers (or even more general objects) and returning True or False. The function Differences[#,1,2] takes the differences, not of consecutive pairs of integers, but pairs of integers at distance two apart. Then we just check whether the resulting list has nothing other than zeros in it.

As a bonus, for one more byte (change the 2 to #2), we get a function that inputs a list of integers and another positive integer #2, and checks whether the input list is the result of interleaving #2 constant sequences periodically with one another. For example,

Differences[#,1,#2]~MatchQ~{0...}&[{1,2,3,4,5,1,2,3,4,5,1,2},5]

evaluates to True.

share|improve this answer

Retina, 25 bytes

M`\b(\d+),\d+,(?!\1\b)
^0

Try it online!

Instead of matching an input with alternating values (which leads to some annoying edge effects in a regex), I'm matching inputs that aren't valid and then negate the result afterwards.

The benefit of matching an invalid input is that this is a property can be checked locally, and it doesn't need to treat empty or short input specially: any input is invalid if it contains two distinct values that are one position apart.

So the first stage counts the number of matches of \b(\d+),\d+,(?!\1\b) which matches and captures one value, then matches the next value, and then asserts that the third value in sequence is different. This gives zero for valid inputs and something positive for invalid values.

The second stage simply counts the number of matches of ^0 which is 1 if the first stage returned 0 and 1 otherwise.

share|improve this answer

Pyth, 9 bytes

q<*<Q2lQl

Explanation

q<*<Q2lQlQQ   Implicitly add enough Qs to make the code run

   <Q2        Take the first two elements of the input
  *   lQ      Repeat those len(input) times
 <      lQ    Take the first len(input) elements
q         Q   Check if those are equal to the input
share|improve this answer

Retina, 39 32 bytes

^((\d+)(,(\d+)(,\2(,\4|$))*)?)?$

Try it online!

Saved 7 bytes thanks to Martin!

We optionally match a number that occupies the entire input, any pair of numbers, or any pair of numbers followed by the same pair any number of times and optionally not including the second number at the very end. Could save 2 bytes if the input was in unary.

share|improve this answer
1  
I think you can use \d* instead of the big optional group: ^(\d*)(,(\d+)(,\1(,\3|$))*)?$ (29). It would also match ,1,,1, but I think that's OK ("given a list of positive integers"). – Kobi 8 hours ago
    
Another ^(\d+)?(.\d+)?(.\1\2)*(.\1)?$ 29 byte alternative. This does not match ,1,,1. – Kritixi Lithos 2 hours ago

Haskell, 27 26 bytes

and.(zipWith(==)=<<drop 2)

This evaluates to an anonymous function that solves the challenge. The idea is to drop the first two numbers from the list, zip with the original list using equality, and check that the result only contains Trues. Try it online!

Thanks to nimi for 1 byte!

share|improve this answer
    
@Flp.Tkc It just needs a type hint – Zgarb 17 hours ago
1  
Nice. and.(zipWith(==)=<<drop 2) saves a byte. – nimi 16 hours ago
    
@nimi So it does, thanks. – Zgarb 16 hours ago

Brachylog, 15 bytes

:{~c#Tbh#Co}f#=

Try it online!

Explanation

:{         }f       Find all results of the predicate below
             #=     They must all be equal

  ~c#T              Deconcatenate the input into three lists
      bh#C          The middle list has two elements
        #Co         Order that couple of elements as the output
share|improve this answer

APL, 7 bytes

⊢≡⍴⍴2⍴⊢

Explanation:

  • 2⍴⊢: reshape the input array by 2
  • ⍴⍴: reshape the result by the original size of the input, repeating elements
  • ⊢≡: see if the result of that is equal to the original input

Test cases:

      true←(1 2 1 2)(10 5 10 5 10)(10 11)(9 9 9 9 9)
      false←(5 4 3 5 4 3)(3 2 1 2 1 2)(1 2 1 2 1 1 2)(2 2 3 3)(2 3 3 2)
      ( ⊢≡⍴⍴2⍴⊢ ) ¨ true
1 1 1 1
      ( ⊢≡⍴⍴2⍴⊢ ) ¨ false
0 0 0 0 0
share|improve this answer

Python 2, 35 bytes

lambda x:(x[:2]*len(x))[:len(x)]==x

Try it online!

share|improve this answer

Perl 6,  49  43 bytes

{!grep {![==] @_},roundrobin |.rotor: 2,:partial}

Try it

{!.grep: ->\a,\b=$_[1] {sum .[0,1]Z!==a,b}}

Try it

Expanded:

{
  !              # invert

  .grep:         # find any mismatches

  ->
    \a,
    \b = $_[1]   # optional second parameter with default
  {
    sum          # count up the values that don't match

    .[ 0, 1 ]    # the first two values from the input
    Z[![==]]     # zip not equal
    a, b         # the current two values under test.
  }
}
share|improve this answer

Java 8, 63 bytes

i->{int r=0,x=1;for(;++x<i.length;)r|=i[x]-i[x-2];return r==0;}

This is a lambda expression for a Predicate< int[ ] >

Explanation: initialize the result to 0. For each element, Biteise OR the result with the difference between the current element and the element 2 indicies earlier. return true if the result equals 0. Otherwise return false

share|improve this answer

bash, 56 bytes

[ -z $3 ]&&echo T||([ $1 != $3 ]&&echo F||(shift;$0 $*))

Save this as a script, and pass the list of numbers as arguments (for an n-element list, you'll pass n arguments). The output is T if the list is alternating, and F otherwise.

This works recursively:

  • If the list has fewer than 3 elements, then print T;
  • else if the 1st element != the 3rd element, then print F;
  • else run the program recursively on the list with the first element removed.
share|improve this answer

Haskell, 33 32 bytes

f(a:x@(_:b:_))=a==b&&f x
f a=1<3

Try it online! or Verify the testcases. -1 byte thanks to Zgarb.

share|improve this answer
    
@Dennis The function works for [], but for some reason ghc cannot infer the correct type for []. It works if tested together with the other test case, see Verify the testcases. – Laikoni 18 hours ago
    
Right, I don't know Haskell that well. – Dennis 18 hours ago
    
Save a byte with f(a:x@(_:b:_))=a==b&&f x – Zgarb 17 hours ago

J, 8 bytes

-:$$2&{.

Explanation

-:$$2&{.  input: (y)
    2&{.  the first two elements of y
   $      shaped like
  $       the shape of y
-:        and check if they match

Test cases

   f =: -:$$2&{.
   ]true =: '' ; 1 ; 1 1 ; 1 2 1 ; 1 2 1 2 ; 10 5 10 5 10 ; 10 11 ; 9 9 9 9 9
++-+---+-----+-------+------------+-----+---------+
||1|1 1|1 2 1|1 2 1 2|10 5 10 5 10|10 11|9 9 9 9 9|
++-+---+-----+-------+------------+-----+---------+
   f each true
+-+-+-+-+-+-+-+-+
|1|1|1|1|1|1|1|1|
+-+-+-+-+-+-+-+-+
   ]false =: 5 4 3 5 4 3 ; 3 2 1 2 1 2 ; 1 2 1 2 1 1 2 ; 2 2 3 3 ; 2 3 3 2
+-----------+-----------+-------------+-------+-------+
|5 4 3 5 4 3|3 2 1 2 1 2|1 2 1 2 1 1 2|2 2 3 3|2 3 3 2|
+-----------+-----------+-------------+-------+-------+
   f each false
+-+-+-+-+-+
|0|0|0|0|0|
+-+-+-+-+-+
share|improve this answer

Python 2.7, 38 bytes

>> i=lambda a:(a[:2]*len(a))[0:len(a)]==a

Test Cases:

>> print i([1,2,1,2])
>> True
>> print i([10,5,10,5,10]
>> True
>> print i([5,4,3,5,4,3])
>> False
>> print i([3,2,1,2,1,2])
>> False
share|improve this answer

C#, 66 bytes

a=>{int r=1,i=0;for(;i<a.Length;)if(a[i]!=a[i++%2])r=0;return r;};

Anonymous function which receives an integer array and returns 1 if array is alternating and 0 otherwise.

Full program with ungolfed function and test cases:

using System;

public class Program
{
    public static void Main()
    {
        Func<int[], int> f =
        a =>
        {
            int r = 1,  // return value. 1 is true, by default
                i = 0;  // iterator
            for ( ; i<a.Length ; )  // for each array element
                if ( a[i] != a[i++%2] ) // if the even (or odd) elements are not the same
                    r = 0;      // a falsy (0) value will be assigned to the return element
            return r;       // returning if the array is alternating or not
        };

        // test cases:
        Console.WriteLine("Edge cases (all TRUE):");
        Console.WriteLine(f(new int[]{}));      //  True
        Console.WriteLine(f(new int[]{1}));     //  True
        Console.WriteLine(f(new int[]{1,1}));   //  True
        Console.WriteLine(f(new int[]{1,2,1})); //  True

        Console.WriteLine("Some other TRUE test cases:");
        Console.WriteLine(f(new int[]{1,2,1,2}));      // True
        Console.WriteLine(f(new int[]{10,5,10,5,10})); // True
        Console.WriteLine(f(new int[]{10,11}));        // True
        Console.WriteLine(f(new int[]{9,9,9,9,9}));    // True

        Console.WriteLine("Some FALSE test cases:");
        Console.WriteLine(f(new int[]{5,4,3,5,4,3}));   // False
        Console.WriteLine(f(new int[]{3,2,1,2,1,2}));   // False
        Console.WriteLine(f(new int[]{1,2,1,2,1,1,2})); // False
        Console.WriteLine(f(new int[]{2,2,3,3}));       // False
        Console.WriteLine(f(new int[]{2,3,3,2}));       // False
    }
}
share|improve this answer

Octave, 51 bytes

@(L)numel(L)<3||(f=@(n)isequal(L{n:2:end}))(1)&f(2)

Input is a cell array of positive integers.

Try it online!

share|improve this answer

Clojure, 70 bytes

(fn[c](let[n #(max(count(set(take-nth 2 %)))1)](=(n c)(n(rest c))1))))

Checks that the distinct count of every 2nd item is 1, and handles empty collections as a special case. Also tried many approaches based on reduce and group-by but not much luck there.

share|improve this answer

Another option with R: 36 bytes.

all(rep_len(head(x,2),length(x))==x)

And I think I've found a much shorter version: 15 bytes

all(!diff(x,2))
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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