20
\$\begingroup\$

Your task today is to write a program or function that takes an array of integers, and counts the number of times, reading it left to right, that the value changes. This is easier to show with an example: [1 1 1 2 2 5 5 5 5 17 3] => [1 1 1 **2** 2 **5** 5 5 5 **17** **3**] => 4

Test case:

Input           |   Output
[]              |   0
[0]             |   0
[0 1]           |   1
[0 0]           |   0
[1 2 3 17]      |   3
[1 1 1 2 2 3]   |   2
[-3 3 3 -3 0]   |   3

This is , fewest bytes wins!

\$\endgroup\$
  • \$\begingroup\$ Is my answer valid if the result is always correctly calculated, but if it's 0, False is printed instead? \$\endgroup\$ – FlipTack Oct 27 '17 at 15:54
  • 1
    \$\begingroup\$ @FlipTack That depends on the language. In general, if I can say 2+False and it errors, that's not fine, but if I get 2, that's fine. \$\endgroup\$ – Pavel Oct 27 '17 at 18:21
  • \$\begingroup\$ @FlipTack By default, this is the consensus. \$\endgroup\$ – totallyhuman Oct 28 '17 at 13:33
  • \$\begingroup\$ Is empty output for 0 acceptable? \$\endgroup\$ – Titus Nov 2 '17 at 21:06
  • \$\begingroup\$ @Titus yes it is. \$\endgroup\$ – Pavel Nov 2 '17 at 22:21

49 Answers 49

1
2
2
\$\begingroup\$

Bash, 17 bytes

Packages: Core Utilities, sed

uniq|sed 1d|wc -l

Takes an input array of one element per line.

How does it work?

The input goes to stdin, one array element per line, to uniq. uniq squeezes multiple consecutive identical lines into one, then sed 1d purges the first line, passing the rest to wc. wc -l simply counts the number of lines and outputs the count.

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

PowerShell, 52 bytes

param($a)if($a){($a|?{$l-ne$_;$l=$_}).count-1;exit}0

Try it online!

Lots of bytes to account for special case of empty array input @(), but otherwise pretty straightforward. Takes the elements of $a where the $last-seen element is -notequal to the current element $_ and the .count thereof.

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Pyth, 8 bytes

ssmndZ.+

Try it online!

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Ruby, 36 bytes

->a{a.each_cons(2).count{|x,y|x!=y}}

Try it online!

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Didn't know about #each_cons! Well played. Do you mind if I translate this into a J-uby answer? \$\endgroup\$ – Cyoce Nov 2 '17 at 19:37
  • \$\begingroup\$ @Cyoce sure, go ahead \$\endgroup\$ – daniero Nov 2 '17 at 20:16
  • \$\begingroup\$ You can find it here \$\endgroup\$ – Cyoce Nov 2 '17 at 20:20
  • \$\begingroup\$ @Cyoce Hey, that's a nice language :) It made me think of an old project of mine. It's basically a bunch of monkey patches on the most common classes used for golfing in Ruby -- String, Array, Enumerable etc. The goal was to make all operators such a +, -, *, / etc, work on any combination of these classes, and it has a few nice convenience methods and higher order functions. I never even bothered pushing it to Github but, looking at it now, it really has a lot going on. I think in combination with J-uby it could become really powerful. \$\endgroup\$ – daniero Nov 4 '17 at 13:44
  • \$\begingroup\$ @Cyoce I pushed it to Github if you wanna look at it: github.com/daniero/rewb. the interesting parts are in lib/rewb. It even has unit tests to demonstrate how all the stuff works. It think it J-uby/rewb could become a nice combo :D \$\endgroup\$ – daniero Nov 4 '17 at 13:48
1
\$\begingroup\$

C# (.NET Core), 94 bytes

using System.Linq;
n=>{int?i=0,a=n.FirstOrDefault();n.ForEach(x=>{i+=x==a?0:1;a=x;});return i;}

Try it online!

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Japt, 6 bytes

ä- è¦0

Try it online!

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ ä- è works for 4 bytes. \$\endgroup\$ – Shaggy Oct 27 '17 at 7:25
1
\$\begingroup\$

Pyth, 4 bytes

ltr8

Test suite

"literate"

The number of changes is equal to the number of runs, ignoring the first run if any. r8 run length encodes the input, t removes the first element if any, and l finds the length of the resulting list.

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Octave, 16 bytes

@(x)nnz(diff(x))

Verify all test cases here!

Quite short, seeing that Octave is a conventional language.

Explanation:

@(x)               % Anonymous function that takes x as input
    nnz(       )   % Count the number of non-zero ...
        diff(x)    % ... differences between elements
| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

PHP, 63 bytes

foreach($_GET as$g){$c+=$g!=$l?isset($l)?1:0:0;$l=$g;}echo$c*1;

pass the sequence as a get query with any indexes, or Try it online!

my attempt, not the shortest, but it's something

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Stacked, 26 bytes

[2 infixes 0\[...!=+]fold]

Try it online!

Explanation

[2 infixes 0\[...!=+]fold]
[                        ]   anonymous function; argument = arr
 2 infixes                   generate infixes of length 2
           0\[      ]fold    fold the inside function over the infixes (starting = 0)
                               when iterating, stack looks like: (acc (a0 a1))
              ...              merge (a0 a1) into the stack      (acc a0 a1)
                 !=            check for inequality              (acc a0!=a1)
                   +           add to accumulator                (acc+(a0!=a1))

This gives the number of unequal infixes in the array, equivalent to the given problem.

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Ruby, 44 Bytes

->a{a.zip(a.rotate)[0..-2].count{|x,y|x!=y}}

Takes the array, and zips the elements with the array rotated one place. This gives pairs of [a[0],a[1]], [a[1],a[2]], [a[2],a[3]], ...

Then we cut off the last element because that's a[-1],a[0], which we don't need here.

Finally, we count the number of pairs with inequal first and second elements (or spaces in between items of the array which change).

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

AWK, 35 bytes

{for(i=1;i<NF;)s+=$i!=$++i;$0=s+0}1

Try it online!

This requires at least 1 character as input (the character can be a space).

A version without this restriction but with several more bytes is:

BEGIN{RS=" "}{s+=NR>1&&p!=$1;p=$1}END{print s+0}

Try it online!

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

GNU sed, 30 23 + 3 = 26 bytes

+3 bytes for -r flag. Output is in unary.

s/(\S+)( \1)*//g
y/ /;/

Try it online!

Technically I could drop the second line and say each space is a unary digit for -7 bytes, but I don't want to push it.

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Pyke, 4 bytes

$0-l

Try it here!

$    -   delta(input)
 0-  -  ^.remove(0)
   l - len(^)
| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Common Lisp, 56 bytes

(loop as(x y)on(coerce(read)'list)while y count(/= x y))

Try it online!

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Python 3, 31 bytes

f=lambda y:sum(y[1:]-y[:-1]!=0)        

Try it online!

| improve this answer | |
\$\endgroup\$
  • 2
    \$\begingroup\$ Since this seems to only work on numpy arrays I think you are going to need to pay the bytes to import numpy. (or you should at least add a disclaimer) \$\endgroup\$ – Ad Hoc Garf Hunter Oct 30 '17 at 6:35
  • \$\begingroup\$ @WheatWizard Does that still apply when the question specifically says "an array of integers"? \$\endgroup\$ – user75646 Oct 30 '17 at 22:34
  • 1
    \$\begingroup\$ To be honest I'm really not going off of a hard rule in this case, just kind of my opinion, if you would like a hard rule you should ask about it on the meta. \$\endgroup\$ – Ad Hoc Garf Hunter Oct 30 '17 at 23:40
1
\$\begingroup\$

PHP, 48 47 bytes

<?foreach($_GET[a]as$a)$n+=$_GET[b]!=$a;echo$n;

Run with arrays a and b as GET parameters.

empty output for 0.

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

J-uby, 37 bytes

:zip%:rotate|~:[]&(0..-2)|:count++:!=

More "readable":

(:zip % :rotate) | (~:[] & (0..-2)) | (:count + +:!=)

Explanation:

:zip%:rotate                        # zip a with itself, rotated by one position. this yields [[a[0], a[1]], [a[1], a[2]], [a[2], a[3]], ...]
           |~:[]&(0..-2)            # discard the last pair, as that's [a[-1], a[0]], not one of our changes
                       |:count++:!= # count the pairs with unequal first and second elements (those are changes)

25 bytes (conversion of @daniero's Ruby answer)

~:each_cons&2|:count++:!=

Explanation

~:each_cons&2            # for every pair [a[i],a[i+1]] in a:
            |:count++:!= # count the number of pairs with unequal first and second elements
| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ Why is this non-competing? \$\endgroup\$ – Pavel Nov 2 '17 at 22:22
  • \$\begingroup\$ @Pavel Language version post-dates the challenge. \$\endgroup\$ – Cyoce Nov 2 '17 at 22:36
  • \$\begingroup\$ @Cyoce non-competing isn't a thing anymore \$\endgroup\$ – dzaima Nov 5 '17 at 18:09
1
\$\begingroup\$

Jq 1.5, 51 bytes

[range(1;length)as$i|select(.[$i]!=.[$i-1])]|length

Expanded

[                              # create an array containing
    range(1;length) as $i      # a copy of the input for
  | select(.[$i]!=.[$i-1])     # each successive element difference
] 
| length                       # length of final array

Try it online!

| improve this answer | |
\$\endgroup\$
1
2

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.