# Levi-Civita symbol

The three-dimensional Levi-Civita symbol is a function f taking triples of numbers (i,j,k) each in {1,2,3}, to {-1,0,1}, defined as:

• f(i,j,k) = 0 when i,j,k are not distinct, i.e. i=j or j=k or k=i
• f(i,j,k) = 1 when (i,j,k) is a cyclic shift of (1,2,3), that is one of (1,2,3), (2,3,1), (3,1,2).
• f(i,j,k) = -1 when (i,j,k) is a cyclic shift of (3,2,1), that is one of (3,2,1), (2,1,3), (1,3,2).

The result is the sign of a permutation of (1,2,3), with non-permutations giving 0. Alternatively, if we associate the values 1,2,3 with orthogonal unit basis vectors e_1, e_2, e_3, then f(i,j,k) is the determinant of the 3x3 matrix with columns e_i, e_j, e_k.

Input

Three numbers each from {1,2,3} in order. Or, you may choose to use zero-indexed {0,1,2}.

Output

Their Levi-Civita function value from {-1,0,1}. This is code golf.

Test cases

There are 27 possible inputs.

(1, 1, 1) => 0
(1, 1, 2) => 0
(1, 1, 3) => 0
(1, 2, 1) => 0
(1, 2, 2) => 0
(1, 2, 3) => 1
(1, 3, 1) => 0
(1, 3, 2) => -1
(1, 3, 3) => 0
(2, 1, 1) => 0
(2, 1, 2) => 0
(2, 1, 3) => -1
(2, 2, 1) => 0
(2, 2, 2) => 0
(2, 2, 3) => 0
(2, 3, 1) => 1
(2, 3, 2) => 0
(2, 3, 3) => 0
(3, 1, 1) => 0
(3, 1, 2) => 1
(3, 1, 3) => 0
(3, 2, 1) => -1
(3, 2, 2) => 0
(3, 2, 3) => 0
(3, 3, 1) => 0
(3, 3, 2) => 0
(3, 3, 3) => 0

• Related. Mar 26, 2018 at 22:24

# Jelly, 5 bytes

ṁ4IṠS


Try it online!

### Algorithm

Let's consider the differences j-i, k-j, i-k.

• If (i, j, k) is a rotation of (1, 2, 3), the differences are a rotation of (1, 1, -2). Taking the sum of the signs, we get 1 + 1 + (-1) = 1.

• If (i, j, k) is a rotation of (3, 2, 1), the differences are a rotation of (-1, -1, 2). Taking the sum of the signs, we get (-1) + (-1) + 1 = -1.

• For (i, i, j) (or a rotation), where i and j may be equal, the differences are (0, j-i, i-j). The signs of j-i and i-j are opposite, so the sum of the signs is 0 + 0 = 0.

### Code

ṁ4IṠS  Main link. Argument: [i, j, k]

ṁ4     Mold 4; yield [i, j, k, i].
I    Increments; yield [j-i, k-j, i-k].
Ṡ   Take the signs, replacing 2 and -2 with 1 and -1 (resp.).
S  Take the sum.

• Beautiful--surely this was xnor's intended algorithm. Mar 27, 2018 at 0:24

# Python 2, 32 bytes

lambda i,j,k:(i-j)*(j-k)*(k-i)/2


Try it online!

### Algorithm

Let's consider the differences i-j, j-k, k-i.

• If (i, j, k) is a rotation of (1, 2, 3), the differences are a rotation of (-1, -1, 2). Taking the product, we get (-1) × (-1) × 2 = 2.

• If (i, j, k) is a rotation of (3, 2, 1), the differences are a rotation of (1, 1, -2). Taking the product, we get 1 × 1 × (-2) = -2.

• For (i, i, j) (or a rotation), where i and j may be equal, the differences are (0, i-j, j-i). Taking the product, we get 0 × (i-j) × (j-i) = 0.

Thus, dividing the product of the differences by 2 yields the desired result.

# x86, 15 bytes

Takes arguments in %al, %dl, %bl, returns in %al. Straightforward implementation using Dennis's formula.

 6: 88 c1                   mov    %al,%cl
8: 28 d0                   sub    %dl,%al
a: 28 da                   sub    %bl,%dl
c: 28 cb                   sub    %cl,%bl
e: f6 e3                   mul    %bl
10: f6 e2                   mul    %dl
12: d0 f8                   sar    %al
14: c3                      retq


Aside: I think I understand why %eax is the "accumulator" now...

• I think you meant sar not shr. Mar 28, 2018 at 13:08
• @Jester good catch. fixed
– qwr
Mar 28, 2018 at 15:21

# Octave, 20 bytes

@(v)det(eye(3)(:,v))


Pretty direct implementation of the determinant formula. Permutes the columns of the identity matrix then takes the determinant.

# Wolfram Language (Mathematica), 9 bytes

Signature


Try it online!

# Wolfram Language (Mathematica), 18 bytes

Saved 2 bytes thanks to Martin Ender.

Det@{#^0,#,#^2}/2&


Try it online!

• builtins are no fun
– qwr
Mar 27, 2018 at 5:56
• The Vandermonde determinant is nice. There's also Det@IdentityMatrix[3][[#]]& (longer, but fewer tokens). Mar 27, 2018 at 18:48
• #^1 is just # ;) Mar 28, 2018 at 10:55

# Haskell, 26 bytes

(x#y)z=(x-y)*(y-z)*(z-x)/2


Try it online!

Nasty IEEE floats...

# JavaScript (ES6), 38 bytes

Overcomplicated but fun:

(a,b,c,k=(a+b*7+c*13)%18)=>k-12?+!k:-1


Try it online!

# JavaScript (ES6), 28 bytes

Using the standard formula:

(a,b,c)=>(a-b)*(b-c)*(c-a)/2


Try it online!

# 05AB1E, 7 5 bytes

1 byte saved thanks to @Emigna

ĆR¥P;


Try it online!

• Ć instead of 4∍ saves a byte. Mar 27, 2018 at 8:36

# APL (Dyalog), 11 9 bytes

2 bytes saved thanks to @ngn

+/×2-/4⍴⎕


Try it online!

• as a complete program it's 9 bytes: +/×2-/4⍴⎕
– ngn
Mar 28, 2018 at 16:10

# Ruby, 28 bytes

->a,b,c{(a-b)*(b-c)*(c-a)/2}


Try it online!

1q~{)1$f-@+:*\}h  Online demo. Note that this is based on a previous answer of mine which uses the Levi-Civita symbol to calculate the Jacobi symbol. # Ruby, 56 bytes ->t{t.uniq!? 0:(0..2).any?{|r|t.sort==t.rotate(r)}?1:-1}  Try it online! Once we rule out cases where the values of the triplet are not unique, t.sort is equivalent to (and shorter than) [1,2,3] or [*1..3] ->t{ t.uniq! ? 0 # If applying uniq modifies the input, return 0 : (0..2).any?{|r| # Check r from 0 to 2: t.sort==t.rotate(r) # If rotating the input r times gives [1,2,3], } ? 1 # return 1; :-1 # else return -1 }  # Husk, 7 bytes ṁ±Ẋ-S:←  Try it online! # Explanation Straight port of Dennis's Jelly answer. S:← copies the head of the list to the end, Ẋ- takes adjacent differences, and ṁ± takes the sign of each element and sums the result. # Jelly, 8 bytes ⁼QȧIḂÐfḢ  Try it online! Seems too ungolfed. :( # Add++, 13 bytes L,@dV@GÑ_@€?s  Try it online! SHELL, 44 Bytes  F(){ bc<<<$$2-1$$*$$3-1$$*$$3-2$$/2;}  tests :  F 1 2 3 1 F 1 1 2 0 F 2 3 1 1 F 3 1 2 1 F 3 2 1 -1 F 2 1 3 -1 F 1 3 2 -1 F 1 3 1 0  Explanation :  The formula is : ((j - i)*(k - i)*(k - j))/2  BC, 42 Bytes  define f(i,j,k){return(j-i)*(k-i)*(k-j)/2}  tests:  f(3,2,1) -1 f(1,2,3) 1 f(1,2,1) 0  • Is it possible just to claim the language as bc to avoid the extraneous call/function declaration? Mar 27, 2018 at 0:10 • In which shell does this work? Mar 27, 2018 at 1:30 # Stax, 8 bytes äN§lüy²Å  Run and debug it Translates to -(b-a)(c-b)(a-c)/2. # J, 12 bytes 1#.2*@-/\4$]


Try it online!

Direct translation of Uriel's APL solution into J.

## Explanation:

4\$] Extends the list with its first item

2 /\ do the following for all the overlapping pairs in the list:

*@- find the sign of their difference

1#. add up

• I'll leave this Vandermonde-determinant-based solution here as a comment in case anyone can figure out how to golf it down: (-/ .*)@:(^&(i.3)"0)%2: Mar 27, 2018 at 18:56

# Japt, 7 bytes

änUÌ xg


Try it

## Explanation

            :Implicit input of array U
ä           :Get each consecutive pair of elements
n          :Reduce by subtracting the first from the last
UÌ        :But, before doing that, prepend the last element in U
g      :Get the signs
x       :Reduce by addition


## Alternative

Takes input as individual integers.

NänW ×z


Try it

# Java 8, 28 bytes

(i,j,k)->(i-j)*(j-k)*(k-i)/2


Port of @Dennis' Python 2 answer.

Try it online.

# Python, 33 bytes

lambda i,j,k:(i^j!=k or-~j-i)%3-1


Try it online!

I tried for a while to beat the product-of-differences approach, but the best I got was 1 byte longer.