Skip to content

Instantly share code, notes, and snippets.

@cdmunoz
Created March 12, 2020 15:43
Show Gist options
  • Save cdmunoz/db7f78f6079bec98e6c225a9ad7b45b2 to your computer and use it in GitHub Desktop.
Save cdmunoz/db7f78f6079bec98e6c225a9ad7b45b2 to your computer and use it in GitHub Desktop.
Solution to Hackerrank's Stock Open/Close Problem
package vanhack
import com.google.gson.Gson
import java.io.File
import java.io.InputStreamReader
import java.time.LocalDate
import java.time.Month
import java.time.format.DateTimeFormatter
import java.util.*
internal class Stock {
var date: String = ""
var open: Float = 0f
var close: Float = 0f
var high: Float = 0f
var low: Float = 0f
}
internal class StockPrice(private val stocks: Array<Stock>?) : StockInterface {
override fun openAndClosePrices(firstDate: String?, lastDate: String?, weekday: String?): List<Stock> {
val startDay = LocalDate.of(2000, Month.JANUARY, 5)
val endDay = LocalDate.of(2014, Month.JANUARY, 1)
val timeFormat = DateTimeFormatter.ofPattern("d-MMMM-yyyy", Locale.US)
val stockList = ArrayList<Stock>()
try {
var date01 = LocalDate.parse(firstDate!!, timeFormat)
var date02 = LocalDate.parse(lastDate!!, timeFormat)
var tempDate: LocalDate
val contWeekDays = arrayOf("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday")
if (date01.isBefore(startDay)) {
date01 = startDay
}
if (date02.isAfter(endDay)) {
date02 = endDay
}
if (!Arrays.asList(*contWeekDays).contains(weekday)) {
println("Invalid parameter")
} else {
stocks?.let {
for (stock in stocks) {
tempDate = LocalDate.parse(stock.date, timeFormat)
if ((tempDate.isAfter(date01) || tempDate.isEqual(date01)) && (tempDate.isBefore(date02) || tempDate.isEqual(date02))) {
val dayOfWeekRecord = tempDate.dayOfWeek.value
val dayOfWeekParam = getDayOfWeekOrdinalFromName(weekday!!, contWeekDays)
if (dayOfWeekRecord == dayOfWeekParam) {
stockList.add(stock)
}
}
}
}
}
} catch (ex: Exception) {
println(ex.message)
}
return stockList
}
private fun getDayOfWeekOrdinalFromName(name: String, daysOfWeek: Array<String>): Int {
var dayOfWeekOrdinal = 0
if (Arrays.asList(*daysOfWeek).contains(name)) {
for (i in 0 until daysOfWeek.size - 1) {
if (daysOfWeek[i].toLowerCase() == name.toLowerCase()) {
dayOfWeekOrdinal = i
break
}
}
}
return dayOfWeekOrdinal + 1
}
}
fun main(args: Array<String>) {
val `in` = Scanner(System.`in`)
val firstDate: String?
firstDate = `in`.nextLine()
if (firstDate.isNullOrBlank() || !Utils.isDateDayOfTheMonthValid(firstDate)) {
println("Invalid parameter.")
throw InvalidParameterException("Invalid parameter.")
}
val lastDate: String?
lastDate = `in`.nextLine()
if (lastDate.isNullOrBlank() || !Utils.isDateDayOfTheMonthValid(lastDate)) {
println("Invalid parameter.")
throw InvalidParameterException("Invalid parameter.")
}
val weekDay: String?
weekDay = `in`.nextLine()
if (weekDay.isNullOrBlank() || !Utils.isWeekday(weekDay)) {
println("Invalid parameter.")
throw InvalidParameterException("Invalid parameter.")
}
if (Utils.isFirstDateBeforeLastDate(firstDate, lastDate)) {
println("Invalid parameter.")
throw InvalidParameterException("Invalid parameter.")
}
try {
//get stocks info from data.json
//For local IntelliJ
/*val path = Stock::class.java.getResource("./data.json")
val reader = InputStreamReader(path.openStream())*/
//For Hackerrank
val file = File("./data.json")
val reader = InputStreamReader(file.inputStream())
val stocks = Gson().fromJson(reader, Array<Stock>::class.java)
if (null == stocks || stocks.isEmpty()) {
throw NoStockException("Stock not found.")
} else {
val stockPrice: StockInterface = StockPrice(stocks)
val stocklist = stockPrice.openAndClosePrices(firstDate, lastDate, weekDay)
for (stock in stocklist)
println(stock.date + " " + stock.open + " " + stock.close)
}
} catch (ex: Exception) {
println(ex.message)
}
}
internal class Utils {
companion object {
private val weekdays = arrayListOf("Monday", "Tuesday", "Wednesday", "Thursday", "Friday")
fun isDateDayOfTheMonthValid(date: String?): Boolean {
date?.let { theDate ->
val dayOfTheMonthValue = theDate.substring(0, theDate.indexOf("-"))
return dayOfTheMonthValue.toInt() <= 31
}
return false
}
fun isWeekday(weekday: String?): Boolean {
weekday?.let {
if (weekdays.contains(weekday)) return true
}
return false
}
fun isFirstDateBeforeLastDate(firstDate: String?, lastDate: String?): Boolean {
val timeFormat = DateTimeFormatter.ofPattern("d-MMMM-yyyy", Locale.US)
try {
val date01 = LocalDate.parse(firstDate!!, timeFormat)
val date02 = LocalDate.parse(lastDate!!, timeFormat)
return date01.isAfter(date02)
} catch (ex: Exception) {
println(ex.message)
println(ex.message)
}
return false
}
}
}
internal interface StockInterface {
fun openAndClosePrices(firstDate: String?, lastDate: String?, weekday: String?): List<Stock>
}
internal class NoStockException(message: String) : Exception(message)
internal class InvalidParameterException(message: String) : Exception(message)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment