R, 142 bytes
Assuming I understood the challenge correctly, here I am assuming that r
is the pre-defined range clause in string format, and that the input array ("Hello world", in the examples) is read from stdin.
r=eval(parse(t=paste("c(",gsub("AND",",",gsub("TO",":",r)),")")))
o=strsplit(readline(),e<-"")[[1]][r[r>0]]
o[is.na(o)]=e
c(rep(e,sum(r<1)),o)
Some test cases:
r="1 TO 3"
[1] "H" "e" "l"
r="5"
[1] "o"
r="-10 TO 10"
[1] "" "" "" "" "" "" "" "" "" "" "" "H" "e" "l" "l" "o" " " "w" "o" "r" "l"
r="0 AND 2 AND 4"
[1] "" "e" "l"
r="8 TO 3"
[1] "o" "w" " " "o" "l" "l"
r="-300 AND 300"
[1] "" ""
Ungolfed/explained
Line 1
r=eval(parse(t=paste("c(",gsub("AND",",",gsub("TO",":",r)),")")))
R has a nice infix operator :
which generates sequences. 1:5
gives [1, 2, 3, 4, 5]
, and 0:-2
gives [0, -1, -2]
. So, we replace the TO
in the loose range clause with :
.
gsub("TO",":",r)
Interpreting AND
is just concatenation. We can use the function c
for that, which handily is able to take an arbitrary number of arguments, comma-separated. So we replace AND
with ,
gsub("AND",",", ... )
and then wrap the whole thing in c(
, )
.
paste("c(", ... ,")")
This yields a character string that could look like c( 1 : 5 , 7 )
. We call parse
to convert to type "expression" and then eval
to evaluate the expression. The resulting sequence of numbers is then re-assigned to the variable r
.
r=eval(parse(t= ... ))
Line 2
o=strsplit(readline(),e<-"")[[1]][r[r>0]]
Now for the ugly part - dealing with strings in R, which gets messy quickly. First we define e
to be an empty string (we will need this later).
e<-""
We read from stdin and convert the character string to an array of individual characters by splitting at the empty string. (E.g. we go from "Hi" to ["H", "i"].) This returns a list of length 1, so we have to ask for the first element [[1]]
to get an array that we can work with. Ugh, I warned you this was messy.
strsplit(readline(), ... )[[1]]
R indexes beginning at 1, and has a nice feature with negative numbers. Suppose x
is ['a', 'b', 'c']
. Calling x[1]
unsurprisingly returns 'a'
. Calling x[-1]
returns all of x
except index 1
, i.e. ['b', 'c']
. This is a cool feature, but means that we have to be careful with our negative indices for this problem. So for now, we just return the elements of the input array with index >0
, and assign the result to o
.
o= ... [r[r>0]]
Line 3
However, there's a problem! For indices that are greater than the length of the array, R just returns NA
values. We need it to return empty strings. So we redefine the elements of o
for which is.na(o)
is TRUE
to be the empty string.
o[is.na(o)]=e
Line 4
c(rep(e,sum(r<1)),o)
Finally, how do we deal with the negative (and zero) indices? They all need to return the empty string, so we repeat the empty string N times, where N is the number of indices that are <1
.
rep(e,sum(r<1))
Finally, we concatenate the previously-defined o
to this (potentially empty) list.
c( ... ,o)
"0 TO 2"
=>{'H', 'e', 'l'}
? \$\endgroup\$3 TO 3
ever be an input and what is the expected output? \$\endgroup\$AND
ing multiples ranges. Also, You didn't answer if we can use zero-based indexing, which is standard in most languages. \$\endgroup\$