22
\$\begingroup\$

Given an array of numbers with length >=3 and length % 3 == 0

[1, 2, 3, 4, ...]

You will split it in sub-arrays of length 3

[[1, 2, 3], [4, 5, ...], [...

And return an array with

  • [0] => The amount of cases in the sub-array where all numbers are equal
  • [1] => In case all numbers in sub-array are not equal, the amount of cases in the sub-array where only 2 numbers are equal

Example and test cases:

  • Input: [2, 4, 2, 5, 5, 5, 4, 2, 1, 3, 3, 1] output [1, 2]

This is because

[[2, 4, 2], [5, 5, 5], [4, 2, 1], [3, 3, 1]]
  ^     ^    ^  ^  ^               ^  ^ 
   equal    all equal              equal   

so 2 equal and 1 all equal

  • [3,5,6,5,5,7,6,6,8,7,7,7,3,4,2,4,4,3] => [1, 3]
  • [3,3,3,4,4,4,5,5,5,6,6,6,5,4,3] => [4, 0]
  • [3,4,5,6,7,8,9,8,7,6,5,4,3,2,1] => [0, 0]

This is , so the shortest answer in bytes win.


PD: Apologies for my English.

\$\endgroup\$
2
  • \$\begingroup\$ The numbers in the test cases are all positive. Is that always the case? \$\endgroup\$
    – Dennis
    Jun 1, 2018 at 20:28
  • \$\begingroup\$ @Dennis No. can be positive and negative numbers. \$\endgroup\$ Jun 1, 2018 at 20:30

46 Answers 46

6
\$\begingroup\$

Octave, 60 52 50 bytes

@(x)sum(sum(~diff(sort(reshape(x,3,[]))))'==[2 1])

Try it online!

Saved 8 bytes thanks to Luis!

Explanation:

Reshapes the input into a matrix with 3 rows, and the appropriate amount of columns. It then sorts each of the columns, and calculates the difference between the elements on different rows. This gives a matrix with two rows, where identical numbers will have a zero, and different numbers will have a positive number. This is negated, so that all equal elements are 1, and all unequal are 0. We then sum each of those columns, giving us one of the three alternatives: 0 = All elements are unequal, 1 = Two elements are equal and 2 = All elements are equal. We then check how many are >1, and how many are exactly ==1.

\$\endgroup\$
0
4
\$\begingroup\$

Jelly,  9  8 bytes

-1 thanks to Dennis (use a new alias for L€, )

Q3ÐƤẈċⱮ2

Try it online!

\$\endgroup\$
0
4
\$\begingroup\$

05AB1E, 10 bytes

3ôεÙg}12S¢

Try it online!

Explanation

3ô          # split input into groups of 3
  ε  }      # for each triple
   Ù        # remove duplicates
    g       # and get the length
      12S¢  # count the number of 1s and 2s in the result
\$\endgroup\$
4
\$\begingroup\$

JavaScript (ES6), 70 bytes

f=([a,b,c,...d],t=p=0)=>1/a?f(d,t+!(a-b&&a-c?b-c||++p:b-c&&++p)):[t,p]

Try it online!

How?

We recursively extract each triplet [a,b,c] from the input array and update two counters t (three-of-a-kind) and p (pair), using the following formula:

t =
t + !(a - b && a - c ? b - c || ++p : b - c && ++p)

There are 5 possible cases which are detailed below, from 'all equal' to 'all distinct'.

a b c | a-b && a-c | b-c | b-c || ++p | b-c && ++p | t +=
------+------------+-----+------------+------------+------------
4 4 4 | false      | 0   | n/a        | 0          | !0    --> 1
4 4 5 | false      | ≠0  | n/a        | ++p        | !++p  --> 0
4 5 4 | false      | ≠0  | n/a        | ++p        | !++p  --> 0
5 4 4 | true       | 0   | ++p        | n/a        | !++p  --> 0
4 5 6 | true       | ≠0  | ≠0         | n/a        | !(≠0) --> 0
\$\endgroup\$
1
  • \$\begingroup\$ If output can have more than only [0] and [1] indexes "Note: returns a 3-elements array with [0] and [1] returning th appropriate values, and [2] returning a dummy value (the number of 3-lists without any elements in common) . This is totally valid according to the current rules." codegolf.stackexchange.com/a/166082/31257 62 bytes a=>a.map(_=>++r[--new Set(a.slice(i,i+=3)).size],r=[i=0,i])&&r \$\endgroup\$ Dec 21, 2018 at 5:52
3
\$\begingroup\$

Pyth, 13 14 12 11 bytes

/Lml{kcQ3S2

Try it here

Explanation

/Lml{kcQ3S2
      cQ3        Split the input into groups of 3.
  ml{k           Deduplicate and get the length of each.
/L               Count the number...
         S2      ... of 1s and 2s.
\$\endgroup\$
1
  • \$\begingroup\$ Fails for 3rd test (needs some all-equals AND some two-equal triples) \$\endgroup\$ Jun 1, 2018 at 20:06
3
\$\begingroup\$

oK, 17 16 bytes

+/(1 2=#=:)'0N3#

Try it online!

            0N3# /reshape into groups of 3 (see ngn's comment)
  (       )'     /for each group:
        =:       /    make a map from number -> indices
       #         /    count number of keys/values
   1 2=          /    check if the count is equal to 1 or 2 
+/               /sum together the columns

For k, the 17 byte version is: +/(1 2=#=:)'0N 3#.

\$\endgroup\$
1
  • \$\begingroup\$ 0N 3 -> 0N3 (thanks to a parsing oddity in oK) \$\endgroup\$
    – ngn
    Jun 2, 2018 at 2:31
3
\$\begingroup\$

R, 70 bytes

function(v,x=lengths(by(v,seq(0,a=v)%/%3,table)))c(sum(x<2),sum(x==2))

Try it online!

Previous versions :

R, 82 bytes

function(v,a=!1:2){for(i in lengths(by(v,seq(0,a=v)%/%3,table)))a[i]=a[i]+1;a[-3]}

Try it online!


R, 93 bytes

function(v,a=table(lengths(by(v,0:(length(v)-1)%/%3,unique)))[c('1','2')])`[<-`(a,is.na(a),0)

Try it online!

\$\endgroup\$
5
  • 1
    \$\begingroup\$ Possibly porting the Octave answer will be more efficient, but a=!1:2 is a bit shorter. \$\endgroup\$
    – Giuseppe
    Jun 2, 2018 at 15:53
  • \$\begingroup\$ @Giuseppe: thanks, and saved other 5 bytes using seq(0,a=v) instead of 0:(length(v)-1) ;) Unfortunately I don't know octave so I cannot read that answer easily... \$\endgroup\$
    – digEmAll
    Jun 2, 2018 at 16:07
  • \$\begingroup\$ @Giuseppe : changed approach and saved a lot of bytes :) \$\endgroup\$
    – digEmAll
    Jun 2, 2018 at 16:37
  • \$\begingroup\$ Great approach! I had something shorter by applying unique but it fails for the third test case. Your by approach is safer \$\endgroup\$
    – JayCe
    Jun 2, 2018 at 22:51
  • \$\begingroup\$ @JayCe: fortunately R 3.2.0 introduced lengths function that saves a lot of bytes... but they should introduce a shorted lambda functions definition in R, in order to be more competitive in code golf :D \$\endgroup\$
    – digEmAll
    Jun 3, 2018 at 7:50
3
\$\begingroup\$

Java (JDK 10), 116 bytes

l->{int r[]={0,0,0},i=0,a,b,c;for(;i<l.length;b=l[i++],c=l[i++],r[a==b?b==c?0:1:b==c|a==c?1:2]++)a=l[i++];return r;}

Try it online!

Note: returns a 3-elements array with [0] and [1] returning th appropriate values, and [2] returning a dummy value (the number of 3-lists without any elements in common) . This is totally valid according to the current rules.

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

PowerShell, 106 bytes

param($a)for(;$a){$x,$y,$z,$a=$a;if($x-eq$y-and$y-eq$z){$i++}else{$j+=$x-eq$y-or$y-eq$z-or$z-eq$x}}+$i,+$j

Try it online!

Exactly what it says on the tin. Loops over input $a. Each iteration, peels off $x,$y,$z as the next three elements. Tests if they're all equal and if so, increments $i. Else, increments $j if at least one pair is equal. Once the loop is complete, output $i and $j as integers.

So ... many ... dollars ...

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

Retina 0.8.2, 68 bytes

(.+)¶(.+)¶(.+)
;$1;$2;$3;$1;
%M`(;\d+)(?=\1;)
s`((1)|(3)|.)+
$#3 $#2

Try it online! Link includes test cases with header to convert to desired format of one value per line. Explanation:

(.+)¶(.+)¶(.+)
;$1;$2;$3;$1;

Collect three values onto each line with separators and duplicate the first one at the end.

%M`(;\d+)(?=\1;)

Count the number of pairs of duplicates.

s`((1)|(3)|.)+
$#3 $#2

Count the number of 3s and 1s.

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

Stax, 8 bytes

íUÖ←#"ë╕

Run and debug it

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

Common Lisp, 113 bytes

(lambda(l &aux(a 0)(b 0))(loop for(x y z)on l by #'cdddr do(if(= x y z)(incf a)(if(/= x y z)()(incf b))))`(,a,b))

Try it online!

Used the fact that in Common Lisp (= x y z) gives true if all the three elements are equal, and (/= x y z) gives true if no pair of numbers is equal.

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

Japt, 14 13 bytes

2õ@ò3 x_â ʶX

Try it


Explanation

2õ                :Range [1,2]
  @               :Pass each X through a function
   ò3             :  Split input to arrays of length 3
       _          :  Pass each through a function
        â         :    Remove duplicates
          Ê       :    Get length
           ¶X     :    Test for equality with X
      x           :  Reduce by addition
\$\endgroup\$
2
\$\begingroup\$

Haskell, 90 bytes

g[]=[]
g(a:b:c:x)=(sum$map fromEnum[a==b,a==c,b==c]):g x
f x=[sum[1|y<-g x,y==n]|n<-[3,1]]

Try it online!

Looks a bit awkward...

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

Python 2, 77 72 65 bytes

lambda a:map([len(set(t))for t in zip(*[iter(a)]*3)].count,(1,2))

Try it online!

7 bytes saved via a clever trick from xnor

\$\endgroup\$
2
  • \$\begingroup\$ You can generate the list of triplets shorter as zip(*[iter(a)]*3). \$\endgroup\$
    – xnor
    Jun 2, 2018 at 17:25
  • \$\begingroup\$ @xnor: Very nice; I wondered if there was a shorter way... \$\endgroup\$
    – Chas Brown
    Jun 2, 2018 at 18:41
2
\$\begingroup\$

Retina, 23 bytes

S2,3,` 
%Cq`\S+
*\C`1
2

Try it online!

Explanation

S2,3,` 

Split the input at every 3rd space starting at the (0-based) 2nd, i.e. split the input into groups of three.

%Cq`\S+

On each line (%) count the number (C) of unique (q) values (\S+).

*\C`1

Count the number of 1s and print them with a trailing linefeed (\), but do so in a dry-run (*) so that we don't lose the previous result.

2

Count the number of 2s (and print them automatically).

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

J, 16 15 bytes

-1 byte thanks to cole!

1#.1 2=/_3#@=\]

Try it online!

Pretty much the same approach as the majority of solutions.

Explanation:

        _3    \]  - split the input into sublists of lenght 3
          #@~.    - for each triplet remove duplicates and take the length 
   1 2=/          - compare with 1 and 2
1#.               - add up
\$\endgroup\$
1
  • \$\begingroup\$ #@~. -> #@= \$\endgroup\$
    – cole
    Jun 2, 2018 at 21:53
2
\$\begingroup\$

Wolfram Language (Mathematica), 49 bytes

Saved two bytes thanks to Martin Ender.

{#~Count~{_},#~Count~{_,_}}&@BlockMap[Union,#,3]&

Try it online!

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

Elixir, 92 bytes

fn a->import Enum;c=map chunk(a,3),&(length uniq&1);{count(c,&(&1==1)),count(c,&(&1==2))}end

First, chunks the list into size length 3 chunk(a,3)

Secondly, it converts finds the length of each element, uniqified; map chunk(a,3),&(length uniq&1).

Finally, it returns an array consisting of the number of times the resulting list is equal to one count(c,&(&1==1)) and the number of times the resulting list is equal to two count(c,&(&1==2)).

Try it online!

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

Ruby, 59 bytes

->a{[1,2].map{|x|a.each_slice(3).count{|y|x==y.uniq.size}}}

Try it online!

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

Japt, 24 19 bytes

ò3 ®â l
[Uè¥1 Uè¥2]

Try it online!

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

Stax, 14 bytes

ü┬─*HTÜ╫\Ä╢qm♥

Run and debug it

\$\endgroup\$
6
  • \$\begingroup\$ [3,5,6,5,5,7,6,6,8,7,7,7,3,4,2,4,4,3] outputs [2,3] instead [1,3] \$\endgroup\$ Jun 1, 2018 at 20:44
  • \$\begingroup\$ [3,3,3,4,4,4,5,5,5,6,6,6,5,4,3] outputs [1,0] instead [4,0] \$\endgroup\$ Jun 1, 2018 at 20:44
  • \$\begingroup\$ [3,4,5,6,7,8,9,8,7,6,5,4,3,2,1] outputs [5,0] instead [0,0] \$\endgroup\$ Jun 1, 2018 at 20:45
  • \$\begingroup\$ @LuisfelipeDejesusMunoz fixed \$\endgroup\$
    – wastl
    Jun 1, 2018 at 20:50
  • \$\begingroup\$ It doesn't currently show any output for [1,1,1]. If you use 2( instead of 1T it will always trim/pad to exactly size 2. \$\endgroup\$
    – recursive
    Jun 1, 2018 at 22:22
1
\$\begingroup\$

Prolog (SWI), 80 bytes

[A,B,C|T]-X/Y:-T-M/N,(A=B,B=C,X is M+1,Y=N;X=M,(A\=B,B\=C,Y=N;Y is N+1)).
_-0/0.

Try it online!

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

Factor + pair-rocket, 58 bytes

[ 3 group 1 => 2 [ '[ cardinality _ = ] count ] with map ]

Try it online!

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

Desmos, 84 bytes

l(r)=r.length
b=[l(k[3x-2...3x].unique)forx=[1...l(k)/3]]
f(k)=[l(b[b=1]),l(b[b=2])]

Try it on Desmos!

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

Vyxal 14 13 bytes

3ẇƛ∪L;:1O$2Ox

Try it online!

Explanation:

3ẇ             # 3-partition
  ƛ            # Open lambda map
   ∪L          # Length of sublist union
     ;         # Close lambda map
      :        # Duplicate for next operation
       1O      # Count 1
         $     # Swap
          2O   # Count 2
            x  # Print stack as list
\$\endgroup\$
1
\$\begingroup\$

C (GCC), 135 128 117 bytes

-7 bytes thanks to @ceilingcat

-11 more, again thanks to @ceilingcat

This is basically @ceilingcat's answer now, since he's improved it by more than 13 percent.

#define E(k)v[k-~i]==v[i
a;b;i;f(v,l)int*v;{for(a=b=i=0;i<l;i+=3)E()]&E(1)]?++a:E()]|E(1)]|E(1)+1]&&++b;*v=a;v[1]=b;}

Try It Online!

Unfortunately, I'm too lazy to write a new explanation for the most recent answer, but it's quite similar to the previous 128-byte one:

#define E(j,k)v[j+i]==v[k-~i]
a;b;i;f(v,l)int*v;{for(a=b=i=0;i<l;i+=3)E(,)&&E(,1)&&++a||(E(,)||E(,1)||E(1,1))&&++b;*v=a;v[1]=b;}

Try It Online!

f takes a vector (v) and its length (l) as arguments, and return its values in the first two elements of that vector. Explanation:

#define E(j,k)v[j+i]==v[k-~i] // k-~i == k-(-i-1) == k+i+1. an empty first argument equals +i, and an empty second argument equals -~i == i+1
a;b;i;
f(v,l)int*v;
{
    for(a=b=i=0;i<l;i+=3)
        E(,)&&E(,1)&&++a // if element i, i+1 and i+2 are all equal, increment a
        ||(E(,)||E(,1)||E(1,1))&&++b; // otherwise, if any two elements are equal, increment b
    *v=a; // set the first element in v to a
    v[1]=b; // set the second one to b
}
\$\endgroup\$
0
1
\$\begingroup\$

Nibbles, 9 bytes

.,2,`?.`/3@,`$$@

Attempt This Online!

Explanation

.    Map
,2    [1,2]
,     length of
`?     find indices in
.       map
`/ 3     split into chunks of 3
@         input
,        length of
`$        deduplicate
$          the chunk
@       of the number (1 or 2)
\$\endgroup\$
1
+50
\$\begingroup\$

Elm, 108 106 bytes

import List.Extra as E
m=List.map
f x=m(\j->E.count((==)j)<|m(List.length<<E.unique)<|E.groupsOf 3 x)[1,2]

Try it on Ellie

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

Raku, 30 bytes

(+«*.rotor(3)».Set).Bag{1,2}

Try it online!

  • *.rotor(3) breaks up the input list into groups of three elements.
  • ».Set converts each of those groups into a Set.
  • converts each of those sets into its size.
  • .Bag makes a Bag (a set with multiplicity) out of those sizes.
  • {1, 2} looks up in that Bag the number of times sets with sizes of 1 and 2 were present.
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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