I'm having a little problem with this thing:
I have to make a PrimeCollection class in C# that implements IEnumerable interface and generates prime numbers collection on the fly.
So if I write as a test something like this:
static void Main(string[] args) {
PrimeCollection pc = new PrimeCollection();
foreach (int p in pc)
Console.WriteLine(p);
}
It should generate primes until it reaches int32 limit.
So far I have this:
class PrimeCollection {
public IEnumerable<int> Primes() {
var ints = Enumerable.Range(2, Int32.MaxValue - 1);
return ints.Where(x => !ints.TakeWhile(y => y < Math.Sqrt(x)).Any(y => x % y == 0));
}
}
However to do the generating i need to call out it like this:
static void Main(string[] args) {
PrimeCollection pc = new PrimeCollection();
foreach (int p in pc.Primes())
Console.WriteLine(p);
}
I assume I need to make the class IEnumerable, not the method, however I have no idea how to generate the numbers on the fly.
If you want to specifically create your custom primes-enumerable, you can define it as a wrapper over your existing linq query. Like this:
public class PrimesEnumerable : IEnumerable<int> {
public PrimesEnumerable() {
var ints = Enumerable.Range(2, Int32.MaxValue - 1);
_internalEnumerable = ints.Where(x => !ints.TakeWhile(y => y*y<=x).Any(y => x % y == 0));
}
public readonly IEnumerable<int> _internalEnumerable;
public IEnumerator<int> GetEnumerator() {
return _internalEnumerable.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
return _internalEnumerable.GetEnumerator();
}
}
Now you can foreach over it:
var primes = new PrimesEnumerable();
int i = 0;
foreach (var prime in primes) {
if (i == 10)
break;
Console.WriteLine(prime);
i++;
}
Console.ReadLine();
Note: do fix the bug that #CarstenKönig is talking about.
There is no reason to have an instantiable class at all. You are not holding a state.
public static class Prime
{
public static IEnumerable<int> Values()
{
var ints = Enumerable.Range(2, Int32.MaxValue - 1);
return ints.Where(x => !ints.TakeWhile(y => y < Math.Sqrt(x)).Any(y => x % y == 0));
}
}
Then you can use it like this:
static void Main(string[] args)
{
foreach (int p in Prime.Values())
Console.WriteLine(p);
}
You mean something like this?
class Program
{
static void Main(string[] args)
{
foreach(var prime in new PrimeCollection())
{
Console.WriteLine(prime);
}
Console.Read();
}
}
class PrimeCollection : IEnumerable
{
public IEnumerator GetEnumerator()
{
var ints = Enumerable.Range(2, Int32.MaxValue - 1);
return ints.Where(x => !ints.TakeWhile(y => y < Math.Sqrt(x)).Any(y => x % y == 0)).GetEnumerator();
}
}
Related
How can I get array of fixed length from Linq?
I have tried this and it doesn't work:
void Main() {
// To Array doesn't accept int argument
// Enumerable.Range(1, 3).ToArray(10);
Enumerable.Range(1, 3).Take(10);
// Result is [1,2,3], I expect [1,2,3,null,null, ..., null] or [1,2,3,0,0, ..., 0]
}
You can define your own extension method to convert an IEnumerable<T> to a fixed-length T[] like this:
static class EnumerableExtensions
{
public static T[] ToFixedLength<T>(this IEnumerable<T> source, int length)
{
var result = new T[length];
var i = 0;
foreach (var e in source)
{
if (i < length)
{
result[i++] = e;
}
}
return result;
}
}
Usage:
Enumerable.Range(1, 3).ToFixedLength(10)
You can do something like this.
class Test
{
static void Main()
{
int[] data = Enumerable.Range(1, 10).Select(x => x > 3 ? 0 : x).ToArray();
foreach (var x in data)
Console.WriteLine(x);
}
}
This will probably be easiest to explain with an example.
So, let's start with the following TryNTimes function.
public static T TryNTimes<T>(Func<T> f, int n)
{
var i = 0;
while (true)
{
try
{
return f();
}
catch
{
if (++i == n)
{
throw;
}
}
}
}
And use it like
MyType x = TryNTimes(DoSomething, 3);
MyOtherType y = TryNTimes(DoSomethingElse, 3);
But I'm using this in many cases with the same N, so I'd like to make it easy to create a function that injects the n value into here. So the use would be
var tryThreeTimes = CreateRetryWrapper(3);
MyType x = tryThreeTimes(DoSomething);
MyOtherType y = tryThreeTimes(DoSomethingElse);
The closest I could come up with was
public static Func<Func<T>, T> CreateRetryWrapper<T>(int n)
{
return f => TryNTimes(f, n);
}
But that's not really what I want, because it forces me to specify T a-priori, so it's not really reusable in the way that I want. I want to be able to delay the T, returning a generic function as a value. Something like
public static Func<Func<_>, _> CreateRetryWrapper(int n)
{
return f => TryNTimes(f, n);
}
Is this something that's possible in C#?
workaround:
class RetryWrapper
{
int n;
public RetryWrapper(int _n) => n =_n;
public T Try<T>(Func<T> f) => TryNTimes(f, n);
}
Use:
var tryThreeTimes = new RetryWrapper(3);
MyType x = tryThreeTimes.Try(DoSomething);
MyOtherType y = tryThreeTimes.Try(DoSomethingElse);
class RetryWrapper
{
readonly int n;
private RetryWrapper(int n)
{
this.n = n;
}
public static RetryWrapper Create(int n)
{
return new RetryWrapper(n);
}
public T TryNTimes<T>(Func<T> f)
{
var i = 0;
while (true)
{
try
{
return f();
}
catch
{
if (++i == n)
{
throw;
}
}
}
}
}
Usage:
RetryWrapper.Create(3).TryNTimes(() => 16);
I'm practicing some optimization problems and I'm stuck.
I have a list of tuples and I am doing the following:
private static int CalculateMinimumTotalCost(List<Tuple<int, int>> tuples)
{
int minimumCost = 0;
for(int i=0;i<tuples.Count()-1;i++)
{
minimumCost += Math.Max(Math.Abs(tuples[i].Item1 - tuples[i + 1].Item1), Math.Abs(tuples[i].Item2 - tuples[i + 1].Item2));
}
return minimumCost;
}
The idea is that given a list of tuples and this mathematical equation, I need to find the minimum cost. The catch is that the order of the tuples can be rearranged. My job is to find the LEAST costly arrangement of tuples.
So what I would like to do is loop through all possible combination of Tuples and return the combination with the minimum cost.
For example:
(1,2)(1,1)(1,3) = 3
(1,1)(1,2)(1,3) = 2
So in this case, i would return 2 because that arrangement is less costly.
I understand that when there are N tuples, the number of combinations is N!.
How do I get all the combinations possible for a list of tuples?
Thanks!
As other have suggested you should create the Point class:
public partial class Point
{
public int X { get; set; }
public int Y { get; set; }
public Point(int x, int y)
{
this.X = x;
this.Y = y;
}
}
And, let's encapsulate the functions for computing distance and total cost :
public partial class Point
{
public static int CalculateDistance(Point p0, Point p1)
{
return Math.Max(
Math.Abs(p0.X - p1.X),
Math.Abs(p0.Y - p1.Y)
);
}
}
public static class PointExtensions
{
public static int GetTotalCost(this IEnumerable<Point> source)
{
return source
.Zip(source.Skip(1), Point.CalculateDistance)
.Sum();
}
}
Finally, you will need another extension method to create "all possible combination" :
public static class PermutationExtensions
{
public static IEnumerable<IEnumerable<T>> GetPermutations<T>(this IEnumerable<T> source)
{
if (source == null || !source.Any())
throw new ArgumentNullException("source");
var array = source.ToArray();
return Permute(array, 0, array.Length - 1);
}
private static IEnumerable<IEnumerable<T>> Permute<T>(T[] array, int i, int n)
{
if (i == n)
yield return array.ToArray();
else
{
for (int j = i; j <= n; j++)
{
array.Swap(i, j);
foreach (var permutation in Permute(array, i + 1, n))
yield return permutation.ToArray();
array.Swap(i, j); //backtrack
}
}
}
private static void Swap<T>(this T[] array, int i, int j)
{
T temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
Source from Listing all permutations of a string/integer adapted to be more LINQ-friendly
Usage :
void Main()
{
var list = new List<Point>
{
new Point(1, 2),
new Point(1, 1),
new Point(1, 3),
};
// result: Point[] (3 items) : (1, 1), (1, 2), (1,3)
list.GetPermutations()
.OrderBy(x => x.GetTotalCost())
.First();
}
EDIT : As #EricLippert pointed out, source.OrderBy(selector).First() has some extra cost. This following extension method deals with this issue :
public static class EnumerableExtensions
{
public static T MinBy<T, TKey>(this IEnumerable<T> source, Func<T, TKey> keySelector, IComparer<TKey> comparer = null)
{
IEnumerator<T> etor = null;
if (source == null || !(etor = source.GetEnumerator()).MoveNext())
throw new ArgumentNullException("source");
if (keySelector == null)
throw new ArgumentNullException("keySelector");
var min = etor.Current;
var minKey = keySelector(min);
comparer = comparer ?? Comparer<TKey>.Default;
while (etor.MoveNext())
{
var key = keySelector(etor.Current);
if (comparer.Compare(key, minKey) < 0)
{
min = etor.Current;
minKey = key;
}
}
return min;
}
}
And, we can rewrite the above solution as :
list.GetPermutations().MinBy(x => x.GetTotalCost())
You can change the for loop to Foreach to make it more readable and rather than using index to fetch values.
private static int CalculateMinimumTotalCost(List<Tuple<int, int>> tuples)
{
int minimumCost = 0;
Tuple<int, int> currentTuple = tuples.First();
foreach (Tuple<int, int> tuple in tuples)
{
minimumCost += Math.Max(Math.Abs(currentTuple.Item1 - tuple.Item1), Math.Abs(currentTuple.Item2 - tuple.Item2));
currentTuple = tuple;
}
return minimumCost;
}
Is there a way to store an operator inside a variable? I want to do something like this (pseudo code):
void MyLoop(int start, int finish, operator op)
{
for(var i = start; i < finish; op)
{
//do stuff with i
}
}
I could then call this method like so:
MyLoop(15, 45, ++);
MyLoop(60, 10, --);
Does something like this exist in C#?
I suppose something like this. You do not define the operator, but a function (lambda) which does the change for you.
void MyLoop(int start, int finish, Func<int, int> op)
{
for(var i = start; i < finish; i = op(i))
{
//do stuff with i
}
}
I could then call this method like so:
MyLoop(15, 45, x => x+1);
MyLoop(60, 10, x => x-1);
Use a Function delegate;
Encapsulates a method that has one parameter and returns a value of
the type specified by the TResult parameter.
void MyLoop(int start, int finish, Func<int, int> op)
{
for(var i = start; i < finish; i = op(i))
{
//do stuff with i
}
}
Then;
MyLoop(15, 45, x => ++x);
MyLoop(60, 10, x => --x);
Here is a DEMO.
I tried a different approach, using a class that defines operators and accessing via reflection - i.e. you can store your operators as strings.
This allows for relational operators as well.
class Program
{
static void Main(string[] args)
{
Operators ops = new Operators();
object result = ops.Use("LessOrEqual", new object[] {3,2}); // output: False
Console.WriteLine(result.ToString());
result = ops.Use("Increment", new object[] {3}); // output: 4
Console.WriteLine(result.ToString());
Console.ReadKey();
}
}
public class Operators
{
public object Use(String methodName, Object[] parameters)
{
object result;
MethodInfo mInfo = this.GetType().GetMethod(methodName);
result = mInfo.Invoke(this, parameters); // params for operator, komma-divided
return result;
}
public bool LessOrEqual(int a, int b)
{
if (a <= b)
{
return true;
}
else
{
return false;
}
}
public int Increment(int a)
{
return ++a;
}
}
use something like Func<int, int> op
or change the type of op to string, then check the value and according to it build your for loop like:
void MyLoop(int start, int finish, string op)
{
if ((op.Equals("++") && (start < finish))
{
for(var i = start; i < finish; i++)
{
//processMethod(i)
}
}
else if ((op.Equals("--") && (start > finish))
{
for(var i = start; i < finish; i--)
{
//processMethod(i)
}
}
}
public class Program {
public static void Main(String[] args) {
Looper(x => x + 1);
Looper(x => ++x);
//Looper(x => x++); will not works
Looper(x => x * 2);
}
public static void Looper(Func<int, int> op) {
for (int i = 1; i < 10; i = op(i)) {
Console.WriteLine(i);
}
Console.WriteLine("----------");
}
}
HI, I am working on a simple class to combine items of any type... this is for a poker game, this is how it looks:
public static List<List<T>> combinar<T>(List<T> items, int take)
{
List<List<T>> combs = new List<List<T>>();
var stuff = permutar<T>(items, take);
var all = from s in stuff
select new Tuple<List<T>, string>(s, String.Join("", s.OrderBy(c => c).Select(c => c.ToString())));
var strs = all.Select(s => s.Item2).Distinct();
foreach (var str in strs)
{
combs.Add(all.First(a => a.Item2 == str).Item1);
}
return combs;
}
public static List<List<T>> permutar<T>(List<T> list, int take)
{
List<List<T>> combs = new List<List<T>>();
foreach (var item in list)
{
var newlist = list.Where(i => !i.Equals(item)).ToList();
var returnlist = take <= 1 ? new List<List<T>> { new List<T>() } : permutar(newlist, take - 1);
foreach (var l in returnlist)
{
l.Add(item);
}
combs.AddRange(returnlist);
}
return combs;
}
so permutation works perfect.. but I am having some trouble with combination, when T is Card it takes hell lots of time to complete... so my question is how to select distinct lists form the result of permutation???
this is the Card Class:
public class Card : IComparable
{
Suite _Suite;
public Suite Suite
{
get { return _Suite; }
set { _Suite = value; }
}
Grade _Grade;
public Grade Grade
{
get { return _Grade; }
set { _Grade = value; }
}
string _symbol;
public string Symbol
{
//stuff
}
public PictureBox Picture
{
//stuff
}
public override string ToString()
{
return _Grade.ToString() + " " + _Suite.ToString();
}
public int CompareTo(object obj)
{
Card card = (Card)obj;
return card.Grade > this.Grade ? -1 : card.Grade < this.Grade ? 1 : 0;
}
}
Assuming you don't want to make any big algorithmic changes, your biggest problem here is
combs.Add(all.First().Item1);
That doesn't make any sense. Perhaps you meant
combs.Add(all.First(c => c.Item2 == str)).Item1);
However, that would be very slow; if that's what you want, you should put the results of all into a hash table keyed by the string, and use that instead of looping through Distinct results.
If you wanted to get combinations without computing permutations first, the way to do it would be like this. Given some objects, to find the combinations of length K: if K is 0, return the empty list. Else, for each object, take that object, and then recursively append all the K-minus-1-length combinations of the rest of the objects.