Slice, Slice, Maybe

6

Everyone loves slicing in python, as in array[5] to access the fifth element or array[:5] to access the zero through fourth element or array[::-1] to reverse an array. However, these all have seemingly distinct notations. When and where should the colons and integers be placed?

Task

Your task is to change any valid slice syntax into a slice with as many colons and integers as possible. To help with that, we will make some definitions. Valid slice syntax is anything directly after "Given a slice" in this section.

Define <POS> to be any positive integer, that is any digit 1-9 followed by any amount of digits 0-9.

Define <NEG> to be any negative integer, that is a - followed by <POS>

Define <INT> to be <POS>, <NEG>, or <ZERO>

Define sgn(a) to be the sign of a: 1 for positive a, -1 for negative a, and 0 for a=0.

For all of the following, a and b are <INT> and c is <POS> or <NEG> unless otherwise specified.

  • Given a slice [], your program may have undefined behavior.
  • Given a slice [a], your program or function must return [a:a+k:c] for some <POS> or <NEG> value of c and 0 < abs(k) <= abs(c) and (a+k < 0 if c < 0) and (a+b > 0 if c > 0)
  • Given a slice [:], your program must return [0::1].
  • Given a slice [a:], your program must return [a::1].
  • Given a slice [:b], your program must return [0:b:1].
  • Given a slice [a:b] where a < b and sgn(a)+sgn(b) != 0 your program must return [a:b:1].
  • Given a slice [::], your program must return [0::1].
  • Given a slice [a::], your program must return [a::1].
  • Given a slice [:b:], your program must return [0:b:1].
  • Given a slice [::c], your program must return [0::c] if c is <POS> and [-1::c] otherwise.
  • Given a slice [a:b:] where a < b and sgn(a)+sgn(b) != 0, your program must return [a:b:1].
  • Given a slice [a::c], your program must return [a::c].
  • Given a slice [:b:c], your program must return [0:b:c] if c is <POS> and [-1:b:c] otherwise.
  • Given a slice [a:b:c] your program must return [a:b:c].

Example

The "slice" [5] gives the fifth element of an array.

Your program or function can output [5:6:1] or [5:7:2] or [5:1000:1000] or [5:4:-1] or [5:0:-5].

The program cannot output [5:7:1] or [5:-6:1] or [5:-6:-1] or [5:6:-1].

Test Cases

Input     Output
[1]       [1:2:1]     [Output may vary]
[-1]      [-1:-2:-1]  [Output may vary]
[:]       [0::1]
[1:]      [1::1]
[-1:]     [-1::1]
[0:3]     [0:3:1]
[-3:-1]   [-3:-1:1]
[::]      [0::1]
[0::]     [0::1]
[:5:]     [0:5:1]
[::2]     [0::2]
[::-2]    [-1::-2]
[2:4:]    [2:4:1]
[2::3]    [2::3]
[:2:1]    [0:2:1]
[:2:-1]   [-1:2:-1]
[1:2:3]   [1:2:3]

Rules

  • You do not have to do any input validation.
  • The output and input may include or exclude the brackets [].
  • The output and input may be a 3-tuple instead of a :-delimited string.
  • This is , so shortest code in each language wins.

fireflame241

Posted 2017-08-28T14:50:07.170

Reputation: 7 021

3Did anyone else read the title in the same way you'd say "Ice, Ice, Baby!" – Kevin Cruijssen – 2017-08-29T11:41:10.303

3@KevinCruijssen That was my intention :) – fireflame241 – 2017-08-29T16:34:25.860

Although you haven't logged on since September, I am wondering how exactly the 3-tuple I/O option is supposed to work... are blanks before/after colons represented by arbitrary non-integer elements, or does everything have to be a string? Are missing colons represented by a different arbitrary non-integer element, or can input tuples have less than three elements? – Unrelated String – 2019-05-06T03:17:56.553

@UnrelatedString generally, I/O here is permissive, so the answer to your first question is: you can do anything that works for you. On your second question, having an tuple with less than 3 elements would be ambiguous. For example, [a:] and [:b] have different behavior despite having the same elements. – fireflame241 – 2019-05-06T03:37:46.037

Thanks for the quick response, and welcome back! The ambiguity shouldn't be an issue with an element (I'll call it e) that would represent an empty slot, since [a:] would be (a,e) and [:b] would be (e,b), so if that's the only reason not to use variable-size tuples (or nested tuples) then I'll go ahead and do it unless I can think of a more convenient encoding. – Unrelated String – 2019-05-06T04:46:47.420

Answers

2

Python 2, 101 96 90 85 82 bytes

def f(r):l=len(r);b=r[l>1]+'1'*(l<2);c=(r+[0,b])[2]or'1';print r[0]or~-('.'<c),b,c

Try it online!

Explanation:

Basically a golfed version of:

f(r):
 if len(r)==1:return [r[0],r[0]+'1',r[0]+'1']            # [a, a1, a1] where a1 is further from 0 than a
 if len(r)==2:return [r[0]or'0',r[1],'1']                # [a or 0, b, 1]
 if len(r)==3:return [r[0]or -1*(r[2]<0),r[1],r[2]or'1'] # [a or 0|-1, b, c or 1]

TFeld

Posted 2017-08-28T14:50:07.170

Reputation: 19 246

Change return to print for 85 bytes – Mr. Xcoder – 2017-08-29T12:14:19.543

1

Kotlin 354 330 bytes

Submission

fun f(i:List<Int?>):List<Int?>?{
val N=null
val Z=mutableListOf(0,N,1)
if(i.none{it!=N})return Z
val v:Int=i[0]?:0
val z:Int=if(i.size==3)i[2]?:1 else 1
val p=if(v<0)-1 else 1
return when(i.size){1->listOf(v,v+p,p)
2->listOf(v, i[1], z)
3->{if(i[0]==N&&i[2]!=N&&i[2]!!<0)Z[0]=-1
return i.zip(Z).map{it.first?:it.second}}
else->N}}

Beautified

fun f(input: List<Int?>): List<Int?> {
    if (input.none { it != null }) return listOf(0, null, 1)
    val item0: Int = input[0] ?: 0
    val step: Int = if (input.size == 3) input[2] ?: 1 else 1
    val direction = if (item0 < 0) -1 else 1
    return when (input.size) {
        1 -> listOf(item0, item0 + direction, direction)
        2 -> {
            listOf(item0, input[1], step)
        }
        3 -> {
            val D = mutableListOf(0, null, 1)
            if (input[0] == null && input[2] != null && input[2]!! < 0) D[0] = -1
            return input.zip(D).map { it.first ?: it.second }
        }
        else -> listOf()
    }
}

TryItOnline

Link

jrtapsell

Posted 2017-08-28T14:50:07.170

Reputation: 915

1

Python 3, 268 bytes

import re
w='([^:]*)'
def f(x):
	(a,b,c,d,e)=re.findall('\[%s(?:(:)%s(?:(:)%s)?)?\]'%(w,w,w),x)[0]
	g=int(a)if a else(-1if e and int(e)<0else 0)
	return'[%s:%s:%s]'%(g,c if c else(g+(1if g>0else-1)if not(b or d)else''),e if e else((1if g>0else-1)if not(b or d)else 1))

Try it online!

Conner Johnston

Posted 2017-08-28T14:50:07.170

Reputation: 146