16
\$\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\$
  • \$\begingroup\$ The numbers in the test cases are all positive. Is that always the case? \$\endgroup\$ – Dennis Jun 1 '18 at 20:28
  • \$\begingroup\$ @Dennis No. can be positive and negative numbers. \$\endgroup\$ – Luis felipe De jesus Munoz Jun 1 '18 at 20:30

26 Answers 26

5
\$\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\$
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\$
  • \$\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\$ – guest271314 Dec 21 '18 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\$
  • \$\begingroup\$ Fails for 3rd test (needs some all-equals AND some two-equal triples) \$\endgroup\$ – Jonathan Allan Jun 1 '18 at 20:06
3
\$\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\$
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\$
  • \$\begingroup\$ 0N 3 -> 0N3 (thanks to a parsing oddity in oK) \$\endgroup\$ – ngn Jun 2 '18 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\$
  • 1
    \$\begingroup\$ Possibly porting the Octave answer will be more efficient, but a=!1:2 is a bit shorter. \$\endgroup\$ – Giuseppe Jun 2 '18 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 '18 at 16:07
  • \$\begingroup\$ @Giuseppe : changed approach and saved a lot of bytes :) \$\endgroup\$ – digEmAll Jun 2 '18 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 '18 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 '18 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\$
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\$

Jelly,  9  8 bytes

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

Q3ÐƤẈċⱮ2

Try it online!

\$\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\$

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\$
  • \$\begingroup\$ You can generate the list of triplets shorter as zip(*[iter(a)]*3). \$\endgroup\$ – xnor Jun 2 '18 at 17:25
  • \$\begingroup\$ @xnor: Very nice; I wondered if there was a shorter way... \$\endgroup\$ – Chas Brown Jun 2 '18 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\$
  • \$\begingroup\$ #@~. -> #@= \$\endgroup\$ – cole Jun 2 '18 at 21:53
1
\$\begingroup\$

Japt, 24 19 bytes

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

Try it online!

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

Stax, 14 bytes

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

Run and debug it

\$\endgroup\$
  • \$\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\$ – Luis felipe De jesus Munoz Jun 1 '18 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\$ – Luis felipe De jesus Munoz Jun 1 '18 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\$ – Luis felipe De jesus Munoz Jun 1 '18 at 20:45
  • \$\begingroup\$ @LuisfelipeDejesusMunoz fixed \$\endgroup\$ – wastl Jun 1 '18 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 '18 at 22:22
1
\$\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\$
1
\$\begingroup\$

Wolfram Language (Mathematica), 49 bytes

Saved two bytes thanks to Martin Ender.

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

Try it online!

\$\endgroup\$
1
\$\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\$
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\$
0
\$\begingroup\$

Tcl, 111 bytes

proc S {L a\ 0 e\ 0} {lmap {x y z} $L {expr {$x-$y|$y-$z?$x==$y|$y==$z|$x==$z?[incr e]:0:[incr a]}}
list $a $e}

Try it online!


Tcl, 112 bytes

proc S {L a\ 0 e\ 0} {lmap {x y z} $L {expr {$x-$y||$y-$z?$x==$y|$y==$z|$x==$z?[incr e]:0:[incr a]}}
list $a $e}

Try it online!


Tcl, 114 bytes

proc S {L a\ 0 e\ 0} {lmap {x y z} $L {expr {$x==$y&&$y==$z?[incr a]:$x==$y|$y==$z|$x==$z?[incr e]:0}}
list $a $e}

Try it online!

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

Ruby, 59 bytes

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

Try it online!

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

Tcl, 98 bytes

proc A l {set 1 0;set 2 0
foreach a\ b\ c $l {incr [llength [lsort -u "$a $b $c"]]}
return $1\ $2}

Try it online!

using -unique option of lsort command. I named 1 and 2 my variables for convenience, tough it seems pretty unusual to code set 1 0 :)

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

C# (Visual C# Interactive Compiler), 108 bytes

x=>new[]{1,2}.Select(n=>x.Select((v,i)=>(v,g:i/3)).GroupBy(y=>y.g,y=>y.v).Count(y=>y.Distinct().Count()==n))

Try it online!

Less golfed...

// x is the input list of ints
x=>x
  // 1 distinct number means 3/3 are the same
  // 2 distinct number means 2/3 are the same
  new[]{1,2}
  // iterate over the outer array to get an index
  .Select(n=>x
    // iterate over the whole list with an index
    // and break into groups of size 3
    .Select((v,i)=>v,g:i/3))
    .GroupBy(y=>y.g,y=>y.v)
     // count the distinct values in each group
     // and get the result based on outer array value
    .Count(y=>y.Distinct().Count()==n))
\$\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.