# Challenge

The task is simple. Given an array and a first and last value: Return the first of the last after the first, and the last of the first before the last.

Or simply: Given an array, var1, var2.

Example Array:

[ var2, , var1, , var2, , var2, var1, var2, ]

Return:

• The index of the first var2 on the right side of the first var1 that appears in the array.

[ var2, , first var1, , first var2, , second var2, var1, third var2, ]

• The index of the first var1 on the left side of the last var2 that appears in the array.

[ var2, , second var1, , var2, , var2, first var1,last var2, ]

# Input

Two distinct positive integers

Array of positive integers

# Rules

The array will contain at least one of each variable (minimum size of 2)

Assume inputs work

Example: 0, 1 [1, 0] or similar would fail

IO is flexible

# Examples

Input
First = 2; Last = 4; [0, 2, 4, 2, 3, 1, 4, 0, 1, 2, 4, 9]

Output
2, 9


Input
First = 4; Last = 2; [0, 2, 4, 2, 3, 1, 4, 0, 1, 2, 4, 9]

Output
3, 6


Input
First = 0; Last = 1; [0, 1]

Output
1, 0

• can var1 be equal to var2?
– ngn
Jul 4 '18 at 8:56
• @ngn No, not necessarily. If they were it would lead to mostly trivial results, so it’s not necessary to handle that case. Jul 4 '18 at 9:08
• Welcome to PPCG! Jul 4 '18 at 12:01
• Can we return the output in reversed order? For example, the test cases would result in 9, 2, 6, 3 and 0, 1 respectively (or plus one if the output is 1-indexed). Jul 4 '18 at 12:31
• Seconding @Jakob, the current wording doesn't match the examples. Jul 7 '18 at 18:51

# Python 2, 72 bytes

def f(x,y,a):i=a.index;j=a[::-1].index;print i(y,i(x)),len(a)+~j(x,j(y))


Try it online!

# APL (Dyalog Classic), 29 27 bytes

⊃{(⊃⍵~⍳⊃⍺),⊃⌽⍺∩⍳⊃⌽⍵}/⍸¨⎕=⊂⎕


Try it online!

prompts for the array and then for var1,var2

# JavaScript (ES6), 63 bytes

(x,y,a)=>a.map(P=(v,i)=>v-y?v-x?0:a=i:1/(p=a)?P=+P||i:0)&&[P,p]


Try it online!

### Commented

(x, y, a) =>          // given the two integers x, y and the array a[]
a.map(P =           // initialize P to a non-numeric value
(v, i) => // for each value v at position i in a[]:
v - y ?           //   if v is not equal to y:
v - x ?         //     if v is not equal to x:
0             //       do nothing
:               //     else (v = x):
a = i         //       save the current position in a
:                 //   else (v = y):
1 / (p = a) ?   //     update p to a (last position of x); if p is numeric (>= 0):
P = +P || i   //       unless P is also already numeric, update it to i
//       (if P is numeric, it's necessarily greater than 0 because
//       we've also seen x before; that's why +P works)
:               //     else:
0             //       do nothing
)                   // end of map()
&& [P, p]           // return [P, p]


### Alternate versions

Using JS built-ins, a more straightforward answer is 79 bytes:

(x,y,a)=>[a.indexOf(y,a.indexOf(x)),a.slice(0,a.lastIndexOf(y)).lastIndexOf(x)]


which can be slightly compressed to 75 bytes:

(x,y,a)=>[a.indexOf(y,a.indexOf(x)),a.slice(0,a[L='lastIndexOf'](y))[L](x)]


Try it online!

Edit: @Neil managed to reduce it to a very nice 67-byte:

(x,y,a,f=s=>a[z=y,y=x,x=z,s+=ndexOf](x,a[s](y)))=>[fi,flastI]


Try it online!

• lastIndexOf takes two parameters, so that reduces the straightforward answer to 70 bytes, and I was able to come up with the following 67-byte version: (x,y,a,f=s=>a[z=y,y=x,x=z,s+=ndexOf](x,a[s](y)))=>[fi,flastI]
– Neil
Jul 4 '18 at 19:56

# Jelly, 17 bytes

ẹⱮṚ>Ƈ<Ƈƭ"1,0ị"\$⁺Ʋ


Try it online!

# Python 3, 97 93 bytes

-4 bytes thanks to ovs

def h(f,l,a,I=list.index):j=I(a,f);i=len(a)+~I(a[::-1],l);print(I(a[j:],l)+j,i-I(a[i::-1],f))


Try it online!

• a-1-b == a + (-b-1) == a + ~b can be used for -1 byte, assigning the index function to a name gets this to 93 bytes
– ovs
Jul 4 '18 at 9:24

# Japt, 2725 24 bytes

Thanks @Shaggy -2 bytes and @ETHproductions -1 byte

I just started with japt so it must be a better way.\

[WsX=WbU)bV +XWsTWaV)aU]


Try it online!

• Welcome to Japt :) You can replace those double spaces with ) for starters to save 2 bytes. Jul 4 '18 at 13:06
• @Shaggy Tanks! I did not know abut that Jul 4 '18 at 13:25
• Like you, I'm convinced there's a shorter method. Don't have the brainspace to try to figure it out at the moment, though! Jul 4 '18 at 13:31
• Welcome! You can save one byte by using X=WbU)...+X: Try it online! I'm also struggling to find a shorter method though... Jul 7 '18 at 15:59

# APL (Dyalog Unicode), 42 bytesSBCS

Anonymous tacit infix function. Takes var1,var2 as left argument and the array as right argument.

{⍸<\(⍵=⊃⌽⍺)∧∨\⍵=⊃⍺},{⍸⌽<\(⍵=⊃⍺)∧∨\⍵=⊃⌽⍺}∘⌽


Try it online!

# R, 81 bytes

function(a,b,v,x=which(v==b),y=which(v==a))c(x[x>y],tail(y[y<tail(x,1)],1))


Try it online!

(1-indexed)

# MATL, 27 bytes

y=Y>/ti=PY>P/t3G=f1)w2G=f0)


Try it online!

Alternately for the same bytecount:

### 27 bytes

y=Y>yi=*f1)y3G=PY>Pb2G=*f0)


Try it online!

The second one is easier to explain:

y   % implicitly get the first two inputs (the array and var1),
%  and duplicate the first input
%  stack: [[0 2 4 2 3 1 4 0 1 2 4 9] 2 [0 2 4 2 3 1 4 0 1 2 4 9]]
=   % compare and return logical (boolean) array
%  stack: [[0 2 4 2 3 1 4 0 1 2 4 9] [0 1 0 1 0 0 0 0 0 1 0 0]]
Y>  % cumulative maximum - make all values after the first 1 also 1s
%  stack: [[0 2 4 2 3 1 4 0 1 2 4 9] [0 1 1 1 1 1 1 1 1 1 1 1]]
%  now we have 1s in positions at and after the first time var1 appears
y   % duplicate 2nd element in stack
%  stack: [[0 2 4 2 3 1 4 0 1 2 4 9] [0 1 1 1 1 1 1 1 1 1 1 1] [0 2 4 2 3 1 4 0 1 2 4 9]]
i=  % compare with the next input (var2), returning a boolean array
% stack: [[0 2 4 2 3 1 4 0 1 2 4 9] [0 1 1 1 1 1 1 1 1 1 1 1] [0 0 1 0 0 0 1 0 0 0 1 0]]
*   % multiply the two boolean arrays - so we'll have 1s only where var2 was present after the first occurrence of var1
% stack: [[0 2 4 2 3 1 4 0 1 2 4 9] [0 0 1 0 0 0 1 0 0 0 1 0]]
f1) % find the index of the first 1 in that (this is our first result value)


The second part of the code does the same thing, except for these changes:

• use 2G for second input (var1) and 3G first 3rd input (var2) instead of implicit input or i, since those have been consumed
• use PY>P (flip array left-to-right, get cumulative maximum, flip back) instead of Y>, to get 1s before the last occurrence instead of after the first occurrence
• use f0) to get last place where both conditions are true, instead of first place (works because MATL uses modular indexing, so 0 is taken to refer to the last index of the array)

## MATLAB (80 bytes)

Input is x, y, and a. Since MATLAB is 1-indexed, you should add 1 to test cases.

xi=find(a==x);
yi=find(a==y);
yi(find(yi>xi(1),1))
xi(find(xi<yi(end),1,'last'))


Test case:

x=4
y=2
a =  [0, 2, 4, 2, 3, 1, 4, 0, 1, 2, 4, 9]

%
xi=find(a==x);
yi=find(a==y);
yi(find(yi>xi(1),1))
xi(find(xi<yi(end),1,'last'))

ans =

4

ans =

7


# Java 8, 114 bytes

A lambda taking a java.util.List<Integer> and two ints (var1, var2) and returning a comma-separated pair.

(a,f,l)->a.indexOf(f)+a.subList(a.indexOf(f),a.size()).indexOf(l)+","+a.subList(0,a.lastIndexOf(l)).lastIndexOf(f)


Try It Online

# Kotlin, 132 bytes

{f:Int,l:Int,a:Array<Int>->{var p=a.indexOfFirst{it==f}
while(a[p]!=l)p++
var i=a.indexOfLast{it==l}
while(a[i]!=f)i--
Pair(p,i)}()}


Try it online!

# Julia, 71 64 bytes

thanks to sundar and his find(A.==x)[] instead of findfirst(A,x)).

.

(A,x,y)->findnext(A,y,find(A.==x)[]),findprev(A,x,findlast(A,y))

• You can return a 1-based index if your language is 1-based (that's the usual consensus here), so no need for the -1s. Also, you can save another byte by using find(A.==x)[] instead of findfirst(A,x). Jul 7 '18 at 16:57