I'm trying to come up with the best way of doing some kind of switch style selection on a double to find out what range it is in. Something like this:
double a = 1.1;
switch(a)
{
case: (0.0, 1.6)
return 1;
case: (1.6, 2.337)
return 2;
case: (2.337, 3.2974)
return 3;
default:
return -1;
}
Obviously in this example, one value in the range would have to be non-inclusive, but you get my drift. Any Ideas?
Edit, the ranges are not necessarily integral.
EDIT 2:
I'm actually dealing with radians and finding out which of 12 ranges a point is in. I ended up doing this:
double pi = Math.PI;
double[] zones = new double[] {
0, pi/6, pi/3, pi/2,
2*pi/3, 5*pi/6, pi, 7*pi/6,
4*pi/3, 3*pi/2, 5*pi/3, 11*pi/6
};
for (int i = 0; i < 11; i++)
{
if (radians > zones[i] && radians <= zones[i + 1])
{
return i + 1;
}
}
I started to do an binary search type if-else, but it was going to get too messy.
The following is ideally suited to adjacent ranges, since you only need to write the range limits once:
double a = 1.1;
if (a < 0.0) {
// Too low
return -1;
} else if (a < 1.6) {
// Range [0.0, 1.6)
return 1;
} else if (a < 2.337) {
// Range [1.6, 2.337)
return 2;
} else if (a < 3.2974) {
// Range [2.337, 3.2974)
return 3;
} else {
// Too high
return -1;
}
This is probably over engineering but you could create a Range Class with Min and Max values and a Callback Function.
Then just create all the Ranges with respective min, and max values and callback and add them to an IEnumerable.
Use LINQ to find out the correct range:
range = Ranges.First(r => r.MinValue <= value and r.MaxValue > value);
Then just call the range callback.
Just round up
double a = 1.1;
if(d < 0.0)
return -1;
else
return (int)Math.Ceiling(a);
Perhaps this will do what you want to do with a nice syntactic structure. Please adjust visibilities and comparisons according to your purposes:
public static class Range
{
public interface ISwitchable
{
void SetDefault(Action defaultStatement);
void Execute();
}
public interface ISwitchable<T>: ISwitchable
where T: IComparable<T>
{
T Value { get; set; }
void AddCase(ICase<T> caseStatement);
}
public class Switchable<T> : ISwitchable<T>
where T: IComparable<T>
{
private readonly IList<ICase<T>> _caseStatements = new List<ICase<T>>();
private Action _defaultStatement;
#region ISwitchable<T> Members
public T Value { get; set; }
public void AddCase(ICase<T> caseStatement)
{
_caseStatements.Add(caseStatement);
}
public void SetDefault(Action defaultStatement)
{
_defaultStatement = defaultStatement;
}
public void Execute()
{
foreach (var caseStatement in _caseStatements)
if ((caseStatement.Min.CompareTo(Value) <= 0) && (caseStatement.Max.CompareTo(Value) > 0))
{
caseStatement.Action();
return;
}
_defaultStatement();
}
#endregion
}
public interface ICase<T>
where T: IComparable<T>
{
T Min { get; set; }
T Max { get; set; }
Action Action { get; set; }
}
public sealed class Case<T>: ICase<T>
where T: IComparable<T>
{
#region ICase<T> Members
public T Min { get; set; }
public T Max { get; set; }
public Action Action { get; set; }
#endregion
}
public static ISwitchable<T> Switch<T>(T value)
where T: IComparable<T>
{
return new Switchable<T>();
}
}
public static class SwitchableExtensions
{
public static Range.ISwitchable<T> Case<T>(this Range.ISwitchable<T> switchable, T min, T max, Action action)
where T: IComparable<T>
{
switchable.AddCase(new Range.Case<T>{ Min = min, Max = max, Action = action });
return switchable;
}
public static void Default(this Range.ISwitchable switchable, Action action)
{
switchable.SetDefault(action);
switchable.Execute();
}
}
Usage:
class Program
{
static void Main(string[] args)
{
Range.Switch(10)
.Case(0, 3, () => Console.WriteLine("Between 0 and 3"))
.Case(3, 7, () => Console.WriteLine("Between 3 and 7"))
.Default(() => Console.WriteLine("Something else"));
}
}
You can't do that with a switch.
if(a >= 0 && a < 1) return 1;
else if(a < 2) return 2;
etc.
Alternatively, you could write up a class to hold minval, maxval, and outputval, then just iterate over those possibilities and return the outputval that matches.
Related
I created the pair class and array class, but I'm lost on how to implement the quicksort algorithm.
I want to do it if ints are same then I should sort by double. I was able to implement quicksort with one value per index of array, but with this I just can't find any resources.
Maybe you guys have some resources or maybe you had the same problem?
By the way I'm trying to implement it with c#.
This is my pair class:
class Pair
{
public int integer = 0;
public double doubl = 0.0;
public Pair(int integer, double doubl)
{
this.integer = integer;
this.doubl = doubl;
}
public Pair()
{
}
public int Integer() { return integer; }
public double Doubl() { return doubl; }
}
And my data array class
class MyDataArray : DataArray
{
Pair[] data;
int operations = 0;
public MyDataArray(int n, int seed)
{
data = new Pair[n];
Random rand = new Random(seed);
for (int i = 0; i < n; i++)
{
data[i] = new Pair(rand.Next(1,100), rand.NextDouble());
}
}
public override int integer(int index)
{
return data[index].integer;
}
public override double doubl(int index)
{
return data[index].doubl;
}
public override void Swap(int i, int j)
{
Pair temp = data[i]; // c3 1
data[i] = data[j]; // c3 1
data[j] = temp; // c3 1
}
Your Pair class could implement IComparable<T>, and your quick sort algorithm could be implemented using the CompareTo method.
The IComparable<T> interface:
Defines a generalized comparison method that a value type or class implements to create a type-specific comparison method for ordering or sorting its instances.
You can see the documentation on the CompareTo method to see what the return values mean.
public class Pair : IComparable<Pair>
{
public int integer = 0;
public double doubl = 0.0;
public Pair(int integer, double doubl)
{
this.integer = integer;
this.doubl = doubl;
}
public Pair()
{
}
public int CompareTo(Pair other)
{
if (other == null)
{
return 1;
}
int result = integer.CompareTo(other.integer);
if (result == 0)
{
result = doubl.CompareTo(other.doubl);
}
return result;
}
public int Integer() { return integer; }
public double Doubl() { return doubl; }
}
If you prefer to use the comparison operators, you can implement them in terms of the CompareTo method. The documentation I liked has examples on how to do that.
//sort for integer
var SortedIntegerList = data.OrderBy(x=>x.integer);
//sort for double
var SortedDoubleList = data.OrderBy(x=>x.doubl);
OrderBy for objects uses Quicksort - What Sorting Algorithm Is Used By LINQ "OrderBy"? - so you can use that.
To avoid creating IComparer<Pair> interface you can construct it using Comparer<T>.Create from just comparison delegate:
var sorted = source.OrderBy(x => x, Comparer<Pair>.Create(
(p1, p2) => p1.Integer() - p2.Integer() != 0 ?
p1.Integer() - p2.Integer() :
Math.Sign(p1.Doubl() - p2.Doubl()))).ToList();
I was attempting to solve the running median problem (on hackerrank) using a sorted set. Only it's elements don't appear properly sorted.
See it in action here: http://rextester.com/NGBN25779
public class RunningMedian{
List<int> list = new List<int>();
SortedSet<int> sorted = new SortedSet<int>();
public void Add(int num){
list.Add(num);
sorted.Add(num);
}
public double MedianNotWorking(){
return GetMedian(sorted.ToArray());
}
public double MedianWorking(){
int[] arr = list.ToArray();
Array.Sort(arr);
return GetMedian(arr);
}
public double GetMedian(int[] arr){
int idx = list.Count / 2;
if(arr.Length % 2 == 0){
return (double)((double)(arr[idx] + arr[idx-1]) / 2);
}else{
return arr[idx];
}
}
}
static void Main(String[] args) {
int n = Convert.ToInt32(Console.ReadLine());
int[] a = new int[n];
RunningMedian heap = new RunningMedian();
for(int i = 0; i < n; i++){
a[i] = Convert.ToInt32(Console.ReadLine());
heap.Add(a[i]);
//double median = heap.GetMedian();
double median = heap.MedianNotWorking();
Console.WriteLine(median.ToString("F1"));
}
}
For the most part the sorted set does work. However at larger input sizes it begins to give wrong answers. It may not be the optimal solution to the problem but I'm curious as to why it fails at all. C# doesn't have a min-heap / priority queue so why can't sorted sets be used as a substitute?
*Edited to include full code from hackerrank.
Here is an input file.
Input
http://textuploader.com/dovni
Expected
http://textuploader.com/dovnb
Output
http://textuploader.com/dovwj
Conflicts appear near the end
Expected
(Skipping 1-364)
54240.0
54576.5
54913.0
54576.5
54240.0
Results
(Skipping 1-364)
54240.0
54576.5
54913.0
54963.0
54576.5
SortedSet collections contain by definition only unique values. However your input file contains the number 21794 twice, which means that the second 21794 entry doesn't get added to your SortedSet. So your sorted set will contain fewer values than your list and your whole algorithm doesn't work anymore.
In general, this could be achieved by definition of new IComparator behavior for the SortedSet comparison. For the min priority queue it would be smth like this:
public class PriorityQueue<K,V> where K : IComparable
where V : IComparable
{
private SortedSet<Node<K,V>> _set;
private readonly int _amount;
public PriorityQueue(int amount)
{
_set = new SortedSet<Node<K,V>>(new PriorityComparer<K,V>());
_amount = amount;
}
public void Add(Node<K,V> value)
{
if (_amount > _set.Count)
_set.Add(value);
else
{
if (_set.Max.Val.CompareTo(value.Val) == 1)
{
_set.Remove(_set.Max);
_set.Add(value);
}
}
}
public Node<K,V> ExtractMax()
{
var max = _set.Max;
_set.Remove(max);
return max;
}
public Node<K,V> ExtractMin()
{
var min = _set.Min;
_set.Remove(min);
return min;
}
public bool IsEmpty => _set.Count == 0;
}
public struct Node<K,V> where K : IComparable
where V : IComparable
{
public K Key;
public V Val;
public Node(K key, V val)
{
Val = val;
Key = key;
}
}
public class PriorityComparer<K,V> : IComparer<Node<K,V>> where K: IComparable
where V: IComparable
{
public int Compare(Node<K,V> i, Node<K,V> y)
{
var compareresult = i.Val.CompareTo(y.Val);
if (compareresult == 0)
return i.Key.CompareTo(y.Key);
return compareresult;
}
}
I am trying to return max value of a T[] array by using following method. I don't understand why compiler complains here T max = _genericList[0]; that throws error cannot implicitly convert ...\GenericList(9) to ...\GenericList(123).
Why these two are different? I want to use the T[] of some GenericList class inctance to interpolate through it and find the maximum/minimum. How is that possible?
internal class GenericList<T>
{
private T[] _genericList;
private int _count;
private int _listInnitialLength;
public GenericList(int listLength)
{
_genericList = new T[listLength];
_count = 0;
_listInnitialLength = listLength;
}
public T Max<T>() where T : IComparable
{
T max = _genericList[0];
foreach (T item in _genericList)
{
if (Comparer<T>.Default.Compare(item, max) > 0)
{
max = item;
}
}
return max;
}
}
Your problem is here:
public T Max<T>() where T : IComparable
You just overrided T defined in class declaration. Should be:
internal class GenericList<T> where T : IComparable
{
private T[] _genericList;
private int _count;
private int _listInnitialLength;
public GenericList(int listLength)
{
_genericList = new T[listLength];
_count = 0;
_listInnitialLength = listLength;
}
public T Max()
{
T max = _genericList[0];
foreach (T item in _genericList)
{
if (Comparer<T>.Default.Compare(item, max) > 0)
{
max = item;
}
}
return max;
}
}
Your T in method Max<T> is not the one defined in your class GenericList<T>, even they have a same name. I think you should move the constraint to the class and make Max method non-generic.
internal class GenericList<T> where T : IComparable
{
//....
public T Max()
{
//....
}
}
The other answers will fix your problem, but why use Comparer<T>.Default when T already implements IComparable?
if (item.CompareTo(max) > 0)
{
max = item;
}
I want to implement my own Priority Queue in C# using the naive approach. I need to use PQ for edges in a graph to implement Prims algorithm. Here is what I've done so far:
public class Edge
{
private int v; // one vertex
private int w; // the other vertex
private int weight; // edge weight
public Edge(int v0, int w0, int weight0)
{
v = v0;
w = w0;
weight = weight0;
}
public Edge()
{
v = 0;
w = 0;
weight = 0;
}
public int get_weight()
{
return weight;
}
public int either()
{
return v;
}
public int the_other(int vertex)
{
if (vertex == v) return w;
else return v;
}
public int compareTo(Edge that)
{
if (this.get_weight() < that.get_weight()) return -1;
if (this.get_weight() < that.get_weight()) return 1;
else return 0;
}
public string to_str()
{
string s = v.ToString() + " " + weight.ToString() + " " + w.ToString() + '\n';
return s;
}
}
public class MyPriorityQueue_Edge
{
private List<Edge> q = new List<Edge>();
int size;
public MyPriorityQueue_Edge()
{
size = 0;
}
public void insert(Edge e)
{
q.Add(e);
size++;
}
Edge Min()
{
int min_weight = 1000;
Edge min_edge = new Edge();
foreach(Edge e in q)
if(e.get_weight()< min_weight)
min_edge = e;
return min_edge;
}
public Edge delmin()
{
Edge e = q.Min();
q.Remove(e);
size--;
return e;
}
public bool is_empty()
{
if (size == 0) return true;
else return false;
}
}
When I compile it the compiler points to this line:
Edge e = q.Min();
And says that I did not work on the exception "System.Argument.Exception". How can I fix this?
From MSDN Enumerable.Min<TSource> Method (IEnumerable<TSource>)
If type TSource implements IComparable<T>, this method uses that implementation to compare values. Otherwise, if type TSource implements IComparable, that implementation is used to compare values.
You need to implement IComparable interface in your Edge class.
public class Edge : IComparable
Then add a CompareTo() method. Something like
public int CompareTo(object obj)
{
if (obj is Edge)
{
Edge other = (Edge)obj;
return this.compareTo(other); // you already implemented this in your Edge class
}
else
{
throw new InvalidOperationException();
}
}
How would i create a type that works with integers, supports at least addition substraction division and multiplication and guarantees and integer number IF the operation leads to an integer (otherwise throw).
For example i'd like to be able to do something like:
Precise A = 10;
A.Divide(3);
A.GetNumber(); // This would throw an exception as 10/3 isn't an int.
A.Multiply(6);
int result = A.GetNumber; // I want result to be = to 20, not to a floating point type that would round to 2 or be very close like 1.9999999999999999999999998992
I realise this is a odd use case but i do have this need (performing a sequence of operations, which in floating point could be missrepresented, but are guaranteed to end up as a valid int).
Because we can't know that 10 / 3 will eventually result in a precise integer answer until after the * 6 we have to defer it until then with a promise:
public sealed class Precise
{
private interface IOperation
{
int Calculate(int value);
IOperation Combine(IOperation next);
}
private sealed class NoOp : IOperation
{
public static NoOp Instance = new NoOp();
public int Calculate(int value)
{
return value;
}
public IOperation Combine(IOperation next)
{
return next;
}
}
private sealed class Combo : IOperation
{
private readonly IOperation _first;
private readonly IOperation _second;
public Combo(IOperation first, IOperation second)
{
_first = first;
_second = second;
}
public int Calculate(int value)
{
return _second.Calculate(_first.Calculate(value));
}
public IOperation Combine(IOperation next)
{
return new Combo(_first, _second.Combine(next));
}
}
private sealed class Mult : IOperation
{
private readonly int _multiplicand;
public Mult(int multiplicand)
{
_multiplicand = multiplicand;
}
public int Calculate(int value)
{
return value * _multiplicand;
}
public int Multiplicand
{
get { return _multiplicand; }
}
public IOperation Combine(IOperation next)
{
var nextMult = next as Mult;
if(nextMult != null)
return new Mult(_multiplicand * nextMult._multiplicand);
var nextDiv = next as Div;
if(nextDiv != null)
{
int divisor = nextDiv.Divisor;
if(divisor == _multiplicand)
return NoOp.Instance;//multiplcation by 1
if(divisor > _multiplicand)
{
if(divisor % _multiplicand == 0)
return new Div(divisor / _multiplicand);
}
if(_multiplicand % divisor == 0)
return new Mult(_multiplicand / divisor);
}
return new Combo(this, next);
}
}
private sealed class Div : IOperation
{
private readonly int _divisor;
public Div(int divisor)
{
_divisor = divisor;
}
public int Divisor
{
get { return _divisor; }
}
public int Calculate(int value)
{
int ret = value / _divisor;
if(value != ret * _divisor)
throw new InvalidOperationException("Imprecise division");
return ret;
}
public IOperation Combine(IOperation next)
{
var nextDiv = next as Div;
if(nextDiv != null)
return new Div(_divisor * nextDiv._divisor);
var nextMult = next as Mult;
if(nextMult != null)
{
var multiplicand = nextMult.Multiplicand;
if(multiplicand == _divisor)
return NoOp.Instance;
if(multiplicand > _divisor)
{
if(multiplicand % _divisor == 0)
return new Mult(multiplicand / _divisor);
}
else if(_divisor % multiplicand == 0)
return new Div(multiplicand / _divisor);
}
return new Combo(this, next);
}
}
private sealed class Plus : IOperation
{
private readonly int _addend;
public Plus(int addend)
{
_addend = addend;
}
public int Calculate(int value)
{
return value + _addend;
}
public IOperation Combine(IOperation next)
{
var nextPlus = next as Plus;
if(nextPlus != null)
{
int newAdd = _addend + nextPlus._addend;
return newAdd == 0 ? (IOperation)NoOp.Instance : new Plus(newAdd);
}
return new Combo(this, next);
}
}
private readonly int _value;
private readonly IOperation _operation;
public static readonly Precise Zero = new Precise(0);
private Precise(int value, IOperation operation)
{
_value = value;
_operation = operation;
}
public Precise(int value)
: this(value, NoOp.Instance)
{
}
public int GetNumber()
{
return _operation.Calculate(_value);
}
public static explicit operator int(Precise value)
{
return value.GetNumber();
}
public static implicit operator Precise(int value)
{
return new Precise(value);
}
public override string ToString()
{
return GetNumber().ToString();
}
public Precise Multiply(int multiplicand)
{
if(multiplicand == 0)
return Zero;
return new Precise(_value, _operation.Combine(new Mult(multiplicand)));
}
public static Precise operator * (Precise precise, int value)
{
return precise.Multiply(value);
}
public Precise Divide(int divisor)
{
return new Precise(_value, _operation.Combine(new Div(divisor)));
}
public static Precise operator / (Precise precise, int value)
{
return precise.Divide(value);
}
public Precise Add(int addend)
{
return new Precise(_value, _operation.Combine(new Plus(addend)));
}
public Precise Subtract(int minuend)
{
return Add(-minuend);
}
public static Precise operator + (Precise precise, int value)
{
return precise.Add(value);
}
public static Precise operator - (Precise precise, int value)
{
return precise.Subtract(value);
}
}
Here each Precise has both an integer value and an operation that will be performed on it. Further operations produce a new Precise (doing this sort of thing as a mutable is crazy) with a new operation but when possible those operations are combined into a single simpler operation. Hence "divide by three then multiply by six" becomes "multiply by two".
We can test this thus:
public static void Main(string[] args)
{
Precise A = 10;
A /= 3;
try
{
var test = (int)A;
}
catch(InvalidOperationException)
{
Console.Error.WriteLine("Invalid operation attempted");
}
A *= 6;
int result = (int)A;
Console.WriteLine(result);
// Let's do 10 / 5 * 2 = 4 because it works but can't be pre-combined:
Console.WriteLine(new Precise(10) / 5 * 2);
// Let's do 10 / 5 * 2 - 6 + 4 == 2 to mix in addition and subtraction:
Console.WriteLine(new Precise(10) / 5 * 2 - 6 + 4);
Console.Read();
}
A good solution would also deal well with operations done where the LHS was an integer and the RHS a Precise and where both where a Precise; left as an exercise for the reader ;)
Sadly we have to get much more complicated to handle (10 / 3 + 1) * 3, with the improvement having to be made in the Combine implementations.
Edit: Musing a bit further on the issues of doing the above well enough to catch at least most of the edge cases, I think it should start with only dealing with operations between two Precise objects, because going int -> Precise is trivial and can easily be put on top, but going Precise -> int requires a call to the calculation, perhaps too early. I'd also make the operations the key thing acted upon (have the operation store one or two objects which in turn contain an operation or a value). Then if you started with a representation of the sum (10 / 3) + 5 and multiplied it by 6 it's easier to turn that into (10 * (6 / 3)) + (5 * 6) which upon final calculation can give the precise result 50 rather than fail because it hits the imprecise 10 / 3.
If you don't allow arbitrary precision rationals, it seems that you are asking the impossible without more constraints.
Take 1 and divide it by 65537 twice, then multiply by 65537 twice to retrieve 1: this can't fit in 32 bits integers.
Then round final answer using Math.Round().
I would use a decimal for the result of operation and on the GetNumber check on the .ToString if there is a "." If yes I throw an Exception, if not I convert it to an int.