-6
\$\begingroup\$

The challenge

Write a function that returns the nth element of an array even if its out of bound.

function safeGet(index, arr) {
  const safeIndex = ???
  return arr[safeIndex]
}

const arr = ["a", "b", "c"];

safeGet(0, arr) // "a"
safeGet(1, arr) // "b"
safeGet(2, arr) // "c"

safeGet(3, arr) // "a" go back to the beginning
safeGet(4, arr) // "b" all over again
safeGet(5, arr) // "c"

safeGet(30, arr) // "a"
safeGet(400, arr) // "b"
safeGet(5000, arr) // "c"

Negative indices works exactly the same way, but beginning from the end:

safeGet(-1, arr) // "c" begin from the end
safeGet(-2, arr) // "b"
safeGet(-3, arr) // "a"

safeGet(-4, arr) // "c" go back to the end again
safeGet(-20, arr) // "b"
safeGet(-300, arr) // "a"

Visually it looks like this:

// (For 1-element sized arrays, any natural number is a valid index)
//   2
//   1
//   0
// ["a"]
//  -1
//  -2
//  -3


//   6    7    8
//   3    4    5
//   0    1    2
// ["a", "b", "c"]
//  -3   -2   -1
//  -6   -5   -4
//  -9   -8   -7


//   6    7    8    9   10   11
//   0    1    2    3    4    5
// ["a", "b", "c", "d", "e", "f"]
//  -6   -5   -4   -3   -2   -1
// -12  -11  -10   -9   -8   -7

Rules

  • You can't mutate the array.
  • You can't even traverse the array.
  • Any programming languages will be accepted.
  • It's a CodeGolf, meaning the smallest answer wins.
\$\endgroup\$

closed as unclear what you're asking by caird coinheringaahing, Sriotchilism O'Zaic, Jo King, mbomb007, xnor Sep 8 at 12:40

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 5
    \$\begingroup\$ First, this behavior is (mostly) built into some languages already (*cough* python). Second, your restrictions don't make much sense. What do you mean by transversing an array? Are languages that use linked lists as arrays excluded? For example, in Java, new LinkedList<>().get(2) transverses over the array to get the element at index 2. Coming back to python: lambda a,n:a[n%len(a)] should do the trick. \$\endgroup\$ – Benjamin Urquhart Sep 8 at 0:38
  • \$\begingroup\$ Sorry I thought it would be clear that by not allowing array traversing, I meant explicitly, and not internally by the language. Of course new LinkedList<>().get(2) traverses the array, but you, as a developer, are not iterating over the list (with a for-loop for example, that's what I meant). And yes, python does this built-in, maybe I should add that you have to implement MATHMATICALLY (using the modulo operator to get the remainder, just like you did). The python answer you made is correct, but isn't eligible as a commentary, I'm sorry. Also you must be fun at parties. @BenjaminUrquhart \$\endgroup\$ – BernaMariano Sep 8 at 0:51
  • 4
    \$\begingroup\$ What is the rationale for not allowing explicit traversal? If there's some language where that's shorter than indexing mod the length, I'd personally be quite glad to see that approach taken \$\endgroup\$ – Unrelated String Sep 8 at 1:01
  • 5
    \$\begingroup\$ Your restrictions are intending to make an easy task more difficult, but they seem to be unobservable requirements. Consider making a harder or more creative challenge. \$\endgroup\$ – mbomb007 Sep 8 at 4:27
  • 4
    \$\begingroup\$ The You can't even traverse the array. is rather unobservable in most languages. Since it doesn't really seem to add anything to the challenge and is rather confusing, I'd recommend removing it. I'd also suggest removing the You can't mutate the array., because that only really makes sense for languages with pointers, and even then, it's a weird restriction \$\endgroup\$ – Jo King Sep 8 at 4:33

11 Answers 11

5
\$\begingroup\$

Python, 22 21 bytes

-1 byte thanks to ovs
This does not mutate the given array. Rather, it makes a n^2 larger copy of it. There's also no explicit iteration being done here.

lambda a,n:(n*n*a)[n]

TIO (updated test array)

\$\endgroup\$
  • 1
    \$\begingroup\$ lambda a,n:(n*n*a)[n] (21 bytes) technically complies with all the rules in the challenge as it creates a copy of the given list. \$\endgroup\$ – ovs Sep 8 at 10:01
  • \$\begingroup\$ @ovs I didn't think of that. Thanks. \$\endgroup\$ – Benjamin Urquhart Sep 8 at 14:40
4
\$\begingroup\$

Stax, 1 bytes

@

Run and debug it

@ is the array indexing instruction in stax. It works exactly as specified.

\$\endgroup\$
2
\$\begingroup\$

Perl 6, 12 bytes

*[0]o&rotate

Try it online!

Works differently from guifa's answer in that it first rotates the array by the given amount, then takes the first element.

\$\endgroup\$
2
\$\begingroup\$

Perl 6, 17 9 bytes

{*[$_%*]}

Explanation

{*[$_%*]}($idx)(@arr)     # curried input
*[$idx % *](@arr)         # $_ takes the $index
@arr[$idx % *]            # first * takes @array
@arr[$idx % @arr.elems]   # * in [] is number of elems

Try it online!

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

Zsh, 27 24 bytes

<<<${@[(`<&0`%#+#)%#+1]}

Turned out a bit more interesting than I thought. Takes array as arguments, index on stdin.

Try it online! Try it online!

Arrays in zsh are one-indexed, and $a[0] is empty. Negative indexing works as expected for -1, -2, ..., -n.

New strategy: While negative indexing seems useful, the empty zero-index makes it less so. So, we just "mod n, add n, mod n" to make everything in the range [0,n-1], then add one.


Old strategy:

  • take the index % length, leaving us something in the range [-n+1,n-1].
  • if that is non-negative, add 1.
\$\endgroup\$
1
\$\begingroup\$

Charcoal, 1 byte

§

Try it online! This is Charcoal's AtIndex operator, but as a full program, it automatically accepts array and integer parameter inputs.

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

Japt, 2 bytes

0-indexed. Input order is irrelevant.

gV

Try it

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

C (gcc), 53 32 31 bytes

a(b,c,d)int*b;{b=b[(d%c+c)%c];}

Thanks to wastl for 31 bytes

Try it online!

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

Javascript, 28 bytes

a=>i=>a[(i<0?-i:i)%a.length]
\$\endgroup\$
  • \$\begingroup\$ That looks like 28 bytes to me, without counting the space \$\endgroup\$ – Embodiment of Ignorance Sep 8 at 2:12
  • \$\begingroup\$ Thanks. I can't count :( \$\endgroup\$ – vityavv Sep 8 at 2:13
  • 2
    \$\begingroup\$ -1 is supposed to count back from the end... \$\endgroup\$ – Neil Sep 8 at 8:28
0
\$\begingroup\$

PHP, 53 bytes

function($i,$a){return$a[(($c=count($a))+$i%$c)%$c];}

Try it online!

  • $i is the requested index.
  • $a is the array.
  • $c is count of array items.

PHP doesn't support negative array indexes to get items from the end (as you can actually have negative indexes in PHP arrays like this: [-1 => 'X', -2 => 'Y']).

So I'm always returning the array item at this position: (($i % $c) + $c) % $c

  • The above formula for $i=0 is always 0.
  • For $i>0 (positive index) it is same as $i % $c, since we add the $c to the result once and then get mod of it by $c again. For example, for $c=3 and $i=5 the resulting position will be 2.
  • For $i<0 (negative index) it will get the reversed position as a positive number (which is like getting the position from the end of the array). For example, for $c=3 and $i=-5 it will be ((-5%3)+3)%3 = (-2+3)%3 = 1%3 = 1.

    If we change $i from -5 to -6, the resulting position should be reduced by 1, it will be ((-6%3)+3)%3 = (0+3)%3 = 3%3 = 0

    If we change $i from -5 to -4, the resulting position should be added by 1, it will be ((-4%3)+3)%3 = (-1+3)%3 = 2%3 = 2

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

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

a=>b=>b[(a%(a=b.Count)+a)%a]

Try it online!

\$\endgroup\$
  • \$\begingroup\$ This isn't working as specified. The -1 index should return the last array element (a.k.a. 1st element from the end) which is "c" in the given example, but yours is printing "b" instead. Same goes for any other negative indexes. \$\endgroup\$ – Night2 Sep 8 at 11:20

Not the answer you're looking for? Browse other questions tagged or ask your own question.