11
\$\begingroup\$

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

Output

Index of answers, in order

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
\$\endgroup\$
9
  • 3
    \$\begingroup\$ can var1 be equal to var2? \$\endgroup\$
    – ngn
    Commented Jul 4, 2018 at 8:56
  • 1
    \$\begingroup\$ @ngn No, not necessarily. If they were it would lead to mostly trivial results, so it’s not necessary to handle that case. \$\endgroup\$ Commented Jul 4, 2018 at 9:08
  • 3
    \$\begingroup\$ Welcome to PPCG! \$\endgroup\$ Commented Jul 4, 2018 at 12:01
  • 2
    \$\begingroup\$ 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). \$\endgroup\$ Commented Jul 4, 2018 at 12:31
  • 1
    \$\begingroup\$ Seconding @Jakob, the current wording doesn't match the examples. \$\endgroup\$
    – Etheryte
    Commented Jul 7, 2018 at 18:51

13 Answers 13

4
\$\begingroup\$

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!

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

APL (Dyalog Classic), 29 27 bytes

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

Try it online!

prompts for the array and then for var1,var2

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

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)))=>[f`i`,f`lastI`]

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ 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)))=>[f`i`,f`lastI`] \$\endgroup\$
    – Neil
    Commented Jul 4, 2018 at 19:56
3
\$\begingroup\$

Jelly, 17 bytes

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

Try it online!

\$\endgroup\$
3
\$\begingroup\$

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!

\$\endgroup\$
1
  • \$\begingroup\$ 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 \$\endgroup\$
    – ovs
    Commented Jul 4, 2018 at 9:24
2
+50
\$\begingroup\$

Japt, 27 25 24 bytes

Inspired in @Arnauld answer

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!

\$\endgroup\$
4
  • 1
    \$\begingroup\$ Welcome to Japt :) You can replace those double spaces with ) for starters to save 2 bytes. \$\endgroup\$
    – Shaggy
    Commented Jul 4, 2018 at 13:06
  • \$\begingroup\$ @Shaggy Tanks! I did not know abut that \$\endgroup\$ Commented Jul 4, 2018 at 13:25
  • \$\begingroup\$ 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! \$\endgroup\$
    – Shaggy
    Commented Jul 4, 2018 at 13:31
  • \$\begingroup\$ Welcome! You can save one byte by using X=WbU)...+X: Try it online! I'm also struggling to find a shorter method though... \$\endgroup\$ Commented Jul 7, 2018 at 15:59
1
\$\begingroup\$

APL (Dyalog Unicode), 42 bytesSBCS

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

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

Try it online!

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

R, 81 bytes

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

Try it online!

(1-indexed)

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

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

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

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

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

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!

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

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))
\$\endgroup\$
1
  • \$\begingroup\$ 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). \$\endgroup\$
    – Sundar R
    Commented Jul 7, 2018 at 16:57

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.