###################Task 1#########################

obs <- c('f7','f8','m1','m2','m3','f3','m4','f1','m7','m7','f4','m5','f5','m6','f6','m8','m9','f9','m10','f10','f2')

##function task1 takes a vector where each element starts with a single character and is follwed by an integer
##task1 splits these into a dataframe with two variables
task1 <- function(x) {
	##Create categorical variable
	cat <- substr(x,1,1)
	##Create numerical value variable
	value <- as.numeric(substr(x,2,nchar(x)))
	##Check for errors (for this particular application)
	if(any(!(cat %in% c('m','f')))) stop('Coding error: first character must be m or f')
	##Create dataframe
	new.df <- data.frame(cat,value)
	return(new.df)
}

###################Task 2 -- incomplete #########################
load('ragged.rda')

##part 1: number of people with x observations
id.count <- table(table(ragged$id))
##part 4: (not tested)
by.id <- split(ragged$trt,ragged$id)
check.dup <- lapply(by.id,function(x) duplicated(x))
constant <- lapply(check.dup,function(x) if(length(x)) any(x[-1]) else TRUE)


###################Task 3#########################

##function reduce takes a vector and a binary operator (in quotes) and 
##applies the operator to the elements of the vector
reduce <- function(x,operator) {
	op.exprs <- paste(x,collapse=operator)
	eval(parse(text=op.exprs))
}

##function accumulate takes a vector and a cumulative operator (in quotes) and 
##applies the operator to the elements of the vector, outputting a vector with
##the same length as x
accumulate <- function(x,operator) {
	out <- rep(NA,length(x))
	for (i in 1:length(x)) {
		out[i] <- reduce(x[1:i],operator)
	}
	out
}