39
\$\begingroup\$

Based on this question from Code Review.

Given precisely three positive integers, return the product of all of the distinct inputs. If none of the inputs are distinct, return 1. That is, implement the function:

\$ f(a,b,c) = \cases{1 & $a = b = c $ \\ a & $ b = c $ \\ b & $ a = c $ \\ c & $ a = b $ \\ a b c & otherwise } \$

Shortest code in each language wins.

Test cases

a, b, c -> f(a,b,c)
7, 7, 7 -> 1
3, 3, 5 -> 5
2, 6, 6 -> 2
3, 4, 3 -> 4
1, 2, 3 -> 6
12, 9, 16 -> 1728
\$\endgroup\$
0

44 Answers 44

1
2
1
\$\begingroup\$

Japt, 9 6 bytes

ü l1 ×

Try it

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

Zsh, 39 bytes

(){i=1
for n;((i*=${(M)#@:#$n}>1?1:n))}

Try it online!

For the first time, I can say that a zsh math function actually won out over a normal program! I knew there was potential when I got a tie a while back, here's the relevant meta post if you want to know more about them.

The meat of this is the loop where we test for distinctness:

${(M)#@:#$n}
${   #     }    # count
${(M)      }    # matches
${    @:#  }    # on the positional parameters.
${       $n}    # against $n
            >1  # more than 1 (not distinct)

We use a ternary to decide to multiply by 1 or n.

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

Ruby, 38 bytes

->*a{r=1;a.map{|w|(a-[w])[1]&&r*=w};r}

Try it online!

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

Whitespace, 178 bytes

[S S S N
_Push_0][S N
S _Dupe_0][T    N
T   T   _Read_STDIN_as_integer][T   T   T   _Retrieve_input_A][S N
S _Dupe_input_A][S N
S _Dupe_input_A][T  N
T   T   _Read_STDIN_as_integer][T   T   T   _Retrieve_input_B][S N
S _Dupe_input_B][S N
S _Dupe_input_B][T  N
T   T   _Read_STDIN_as_integer][T   T   T   _Retrieve_input_C][S N
S _Dupe_input_C][S T    S S T   S N
_Copy_0-based_2nd_input_B][T    S S T   _Subtract][N
T   S S N
_If_0_Jump_to_Label_C==B][S N
S _Dupe_input_C][S T    S S T   T   N
_Copy_0-based_3rd_input_A][T    S S T   _Subtract][N
T   S T N
_If_0_Jump_to_Label_C!=B&&C==A][S T S S T   S N
_Push_0-based_2nd_input_A][S T  S S T   S N
_Push_0-based_2nd_input_B][T    S S T   _Subtract][N
T   S N
_If_0_Jump_to_Label_PRINT][T    S S N
_Multiply][T    S S N
_Multiply][N
S N
N
_Jump_to_Label_PRINT][N
S S T   N
_Create_Label_C!=B&&C==A][S N
N
_Discard_input_C][N
S N
N
_Jump_to_Label_PRINT][N
S S S N
_Create_Label_C==B][S N
S _Dupe_input_C][S T    S S T   T   N
_Copy_0-based_3rd_input_A][T    S S T   _Subtract][N
T   S T T   N
_If_0_Jump_to_Label_C==B&&C==A][S N
N
_Discard_input_C][S N
N
_Discard_input_B][N
S N
N
_Jump_to_Label_PRINT][N
S S T   T   N
_Create_Label_C==B&&C==A][S S S T   N
_Push_1][N
S S N
_Create_Label_PRINT][T  N
S T _Print_as_integer]

Letters S (space), T (tab), and N (new-line) added as highlighting only.
[..._some_action] added as explanation only.

Try it online (with raw spaces, tabs and new-lines only).

Whitespace work-flow:

Integer A = STDIN as integer
Integer B = STDIN as integer
Integer C = STDIN as integer                   (the stack now contains [A,B,C])
If(C==B): Jump to Label C==B
If(C==A): Jump to Label C!=B&&C==A
If(A==B): Jump to Label PRINT                  (top of the stack is here C)
Multiply top two
Multiply top two
Jump to Label PRINT                            (top of the stack is here A*B*C)

Label C!=B&&C==A:
  Discard top (C)
  Jump to Label PRINT                          (top of the stack is here B)
Label C==B:
  If(C==A): Jump to Label C==B&&C==A
  Discard top (C)
  Discard top (B)
  Jump to Label PRINT                          (top of the stack is here A)

Label C==B&C==A
  Push 1                                       (top of the stack is here 1)
Label PRINT
  Print top of the stack as integer to STDOUT

Since the inputs are guaranteed to be positive, it uses heap-address 0 for input A; heap-address A for input B; and heap-address B for input C.

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

Kotlin, 52 51 43 bytes

filter{z->count{z==it}<2}.fold(1){s,c->s*c}

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Not sure if defining the function in the header like I did is allowed, if it isn't i'll have to go back to the 51 byte answer \$\endgroup\$
    – Quinn
    Feb 12 '20 at 19:23
1
\$\begingroup\$

Stax, 11 bytes

äùóq◘0Jg•UÜ

Run and debug it

This one works for all testcases, and shorter! Uses Unrelated String's idea.

Explanation

o{}/{Dz_?m$:*
o             order the array
 {}/          group equal adjacent values
    {    m    map to the following:
        ?     if:
     D        deleting the first element
              makes the array empty, then:
       _       push it again
      z        otherwise push an empty list
          $   flatten the result
           :* take the product 
\$\endgroup\$
1
\$\begingroup\$

Factor + sets.extras math.unicode, 20 bytes

[ non-repeating Π ]

Try it online!

Factor has a word non-repeating that gives you every element of a sequence that doesn't repeat. Turns out the answer to this question is just taking the product of this.

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

Scala, 39 bytes

f=>f.filter(i=>f.count(_==i)<2).product

Try it online!

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

Vyxal, 10 bytes

Ċ't1=;f1JΠ

Try it Online!

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

Racket, 74 bytes

λ(n)(apply *(map(λ(x)(if(=(length x)1)(car x)1))(group-by identity n))))

Try it online!

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

Excel, 60 bytes

=IF(A1=B1,IF(A1=C1,1,C1),IF(B1=C1,A1,IF(A1=C1,B1,A1*B1*C1)))

Does not use features like FILTER, only available to Office Insiders.

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

SQL, 245 155 bytes

 DECLARE @a INT=2,@b INT=4,@c INT=8;WITH v AS(SELECT x FROM(VALUES(@a),(@b),(@c))t(x) GROUP BY x HAVING COUNT(*)=1)SELECT ISNULL(EXP(SUM(LOG(x))), 1) FROM v

Expanded:

DECLARE @a INT=2,
        @b INT=4,
        @c INT=8;

WITH v
     AS (SELECT x
           FROM(VALUES(@a),
                      (@b),
                      (@c))t(x)
          GROUP BY x
         HAVING COUNT(*) = 1)
SELECT ISNULL(EXP(SUM(LOG(x))), 1)
  FROM v

The straightforward solution is only 150 .. but it is boring. :)

DECLARE @a INT=2,@b INT=4,@c INT=2;SELECT CASE WHEN @a=@b AND @a=@c THEN 1 WHEN @a=@b THEN @c WHEN @b=@c THEN @a WHEN @a=@c THEN @b ELSE @a*@b*@c END
DECLARE @a INT=2,
        @b INT=4,
        @c INT=2;

SELECT CASE
         WHEN @a = @b
              AND @a = @c THEN 1
         WHEN @a = @b THEN @c
         WHEN @b = @c THEN @a
         WHEN @a = @c THEN @b
         ELSE @a * @b * @c
       END 
\$\endgroup\$
2
  • \$\begingroup\$ I'm not too familiar with SQL golfing, but the DECLARE statement seems out of place. I feel as though it either shouldn't be part of the answer, or what you've written isn't precisely reusable? I could easily be wrong - I'm just stating my current understanding. \$\endgroup\$ Feb 13 '20 at 4:55
  • \$\begingroup\$ Fair point - I am uncertain as well.. I can "assume" the @a, @b, and @c are the parameters passed into a function whose body is the SELECT statement, but is that correct? I could use some guidance there as well. \$\endgroup\$
    – Forty3
    Feb 14 '20 at 2:59
0
\$\begingroup\$

Stax, 13 bytes

üΩ1↑♂Åò←3♠'W▐

Run and debug it

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Thanks for your post! Unfortunately this doesn't seem to meet the requirements for the case where two of the numbers are the same (i.e. for 5 5 7 this returns 35 when it should return 7). Since I don't understand Stax myself, it would also be great if you could include an explanation of what approach your code is using. \$\endgroup\$ Feb 20 '20 at 18:47
0
\$\begingroup\$

C (clang), 199 100 bytes

a,b;main(c){scanf("%i%i%i",&a,&b,&c);printf("%i",a-b|b-c?a-b|b==c?b-c|c==a?a-c|c==b?a*b*c:b:a:c:1);}

Try it online!

Don't know C? Here's how it works. We initialize 3 integers, give them input, then proceeds to multiple if-statements to check whether or not they're equal.

Thanks to ceilingcat for golfing a whopping 99 bytes.

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