Lauren has a chart of projected prices for a house over the next
nyears, where the price of the house in thei-thyear isP_i. She wants to purchase and resell the house at a minimal loss according to the following rules:
- The house cannot be sold at a price greater than or equal to the price it was purchased at (i.e., it must be resold at a loss).
- The house cannot be resold within the same year it was purchased.
Find and print the minimum amount of money Lauren must lose if she buys the house and resells it within the next
nyears.https://www.hackerrank.com/contests/womens-codesprint-2/challenges/minimum-loss
The minimum cost algorithm is implemented in C++ set, Java TreeSet, no timeout. But, C# code using SortedSet has a timeout issue. C# SortedSet uses extension methods, using LINQ to simulate TreeSet floor method. I need help with avoiding LINQ performance issues as well as algorithm design, code style, etc.
Java code using TreeSet:
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int numYears = sc.nextInt();
long[] data = new long[numYears];
for (int i = 0; i < numYears; i++) {
data[i] = sc.nextLong();
}
TreeSet<Long> values = new TreeSet<>();
long best = Long.MAX_VALUE;
for (int i = numYears-1; i >= 0; i--) {
Long smaller = values.floor(data[i]);
if (smaller != null) {
long diff = (data[i] - smaller);
if (diff >= 0) {
best = Math.min(best, diff);
}
}
values.add(data[i]);
}
System.out.println(best);
}
}
C# implementation - failed test cases 11 - 15 due to timeout:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace minimumLoss
{
class Program
{
static void Main(string[] args)
{
Process();
//Testcase2();
}
private static void Process()
{
int n = int.Parse(Console.ReadLine());
Int64[] prices = new Int64[n];
string[] arr = Console.ReadLine().Split(' ');
prices = Array.ConvertAll(arr, Int64.Parse);
Console.WriteLine(MinimumLossCal(n, prices));
}
private static void Testcase2()
{
Int64[] prices = new Int64[5] { 20, 7, 8, 2, 5 };
Console.WriteLine(MinimumLossCal(5, prices));
}
private static void Testcase3()
{
Int64[] prices = new Int64[4] { 2, 3, 4, 1 };
Console.WriteLine(MinimumLossCal(4, prices));
}
/*
* minimum loss
*
*
* read Java TreeSet floor method:
* https://www.tutorialspoint.com/java/util/treeset_floor.htm
*
* http://stackoverflow.com/questions/4872946/linq-query-to-select-top-five
*
* http://stackoverflow.com/questions/11549580/find-key-with-max-value-from-sorteddictionary
*
* http://stackoverflow.com/questions/1635497/orderby-descending-in-lambda-expression
*
* timeout issue - try to find LINQ has a solution or not
* http://stackoverflow.com/questions/14675108/sortedset-sortedlist-with-better-linq-performance
*
*
*/
private static Int64 MinimumLossCal(int n, Int64[] prices)
{
SortedSet<Int64> data = new SortedSet<Int64>();
Int64 minLoss = Int64.MaxValue;
for (int i = n - 1; i >= 0; i--)
{
var smaller = data.Where(p => p < prices[i]).OrderByDescending(p => p).Take(1);
if (smaller.Any())
{
Int64 newDiff = prices[i] - smaller.Last();
minLoss = (newDiff < minLoss) ? newDiff : minLoss;
}
data.Add(prices[i]);
}
return minLoss;
}
}
}
I did study the C# solution to work around the timeout issue - write a binary search tree piggybacked with floor function (similar to Java TreeSet.floor functionality), or bucket-sort like solution; see the blog.
private static void Testcase3()with unit tests \$\endgroup\$