Collatz sequence using linq c# - c#

Good afternoon guys, I have a following problem of the school to solve, being it in relation to Collatz Problem, where I need to develop an application that will find out the starting number between 1 and 1 million that produces the largest sequence.
I made the following code without applying LINQ, and would like to know how to use linq in this situation.
var sequence_size = 0;
var best_number = 0;
var sequence = 0;
for (var i = 0; i <= 1000000; i ++)
{
var size_ = 1;
sequence = i;
while (sequence! = 1)
{
sequence = sequence% 2 == 0? sequence / 2: sequence * 3 + 1;
size ++;
}
if (size> size)
{
size_sequence = size;
best_number = i;
}
}

This is what I'd recommend:
public class MaxSequenceFinder
{
public int FindBestCollatzSequence(int start, int count)
{
return Enumerable.Range(start, count)
.Select(n => new { Number = n, SequenceLength = CalcCollatzSequence((long)n) })
.Aggregate((i, j) => i.SequenceLength > j.SequenceLength ? i : j)
.Number;
}
private int CalcCollatzSequence(long n)
{
int sequenceLength = 0;
do
{
n = CalcNextTerm(n);
sequenceLength++;
}
while (n != 1);
return sequenceLength;
}
private long CalcNextTerm(long previousTerm)
{
return previousTerm % 2 == 0 ? previousTerm / 2 : previousTerm * 3 + 1;
}
}
Which can be used like this:
var finder = new MaxSequenceFinder();
int result = finder.FindBestCollatzSequence(1, 100);
Console.WriteLine(result);
Running it for a count of 1 000 000 will take some time. But in this case (< 100) the longest sequence is:
97

Create an extension function to find the maximum of a sequence using a function on each element:
public static class Ext {
public static T MaxBy<T, TKey>(this IEnumerable<T> src, Func<T, TKey> key, Comparer<TKey> keyComparer = null) {
keyComparer = keyComparer ?? Comparer<TKey>.Default;
return src.Aggregate((a,b) => keyComparer.Compare(key(a), key(b)) > 0 ? a : b);
}
}
Create a function to return the Collatz length of a number:
public long Collatz(long seq) {
long len = 0;
while (seq != 1) {
if (seq % 2 == 0) {
seq /= 2;
++len;
}
else {
seq = (3 * seq + 1) / 2;
len += 2;
}
}
return len;
}
Then you can use these and LINQ to computer the answer for a range:
var maxn = Enumerable.Range(2, 1000000-2).Select(n => new { n, Collatz = Collatz(n) }).MaxBy(nc => nc.Collatz).n;

Related

How to get integers to an array (from integer i to integer j). c#

I want to store integers(in an array or anything) that in range of int "i" and int "j".
eg:-Think, "int i = 1" and "int j = 10".I want to store integers from 1 and 10.
So that (1,2,3,4,5,6,7,8,9,10)
Because I want to answer to HackerRank "Beautiful Days at the Movies".
link below.
https://www.hackerrank.com/challenges/beautiful-days-at-the-movies/problem?isFullScreen=false
here is my code and it a garbage.
static int beautifulDays(int i, int j, int k) {
var total = 0;
for(var a = i; a <= j; a++ )
{
if (a != 0)
{
int ri = Reverse(i);
int rj = Reverse(j);
var ra = Reverse(a);
if((ra/k) % 1 == 0)
{
total++;
}
if((rj/k) % 1 == 0)
{
total++;
}
if((ri/k) % 1 == 0)
{
total++;
}
}
return total;
}
return total;
}
public static int Reverse(int inval)
{
int result = 0;
do
{
result = (result * 10) + (inval % 10);
inval = inval / 10;
}
while(inval > 0);
return result;
}
simply, can you give me the answer of HackerRank "Beautiful Days at the Movies".
link below.
https://www.hackerrank.com/challenges/beautiful-days-at-the-movies/problem?isFullScreen=false
Using Java you can easily stream a range of numbers with IntStream, then map the reverse function for each value, then filter those that fulfils the condition and count. With streams you don't need to store, you can get straight to the answer.
IntUnaryOperator reverse = (opperand) -> {
int reversed = 0;
int num = opperand;
while (num != 0) {
int digit = num % 10;
reversed = reversed * 10 + digit;
num /= 10;
}
return Math.abs(opperand - reversed);
};
return (int) IntStream.rangeClosed(i, j).map(reverse)
.filter(v -> v % k == 0).count();

How do I speed up my Amicable number algorithm?

It take pretty long time to complete the limit(n) of 100,000.
I suspect that the problem is with the CalculateAmicable() where the number get bigger and it take more time to calculate. What can I change to make it speed up faster than this?
public static void Main (string[] args)
{
CheckAmicable (1, 100000);
}
public static int CheckAmicable(int start, int end)
{
for (int i = start; i < end; i++) {
int main = CalculateAmicable (i); //220
int temp = CalculateAmicable (main); //284
int compare = CalculateAmicable (temp); //220
if (compare == main) {
if (main != temp && temp == i) {
Console.WriteLine (main + " = " + temp + " = " + compare + " i: " + i);
i = compare + 1;
}
}
}
return 0;
}
public static int CalculateAmicable(int number)
{
int total = 0;
for (int i = 1; i < number; i++) {
if (number%i == 0){
total += i;
}
}
return total;
}
Note: English is not my first language!
Yes, CalculateAmicable is inefficient - O(N) complexity - and so you have fo N tests 1e5 * 1e5 == 1e10 - ten billions operations which is slow.
The scheme which reduces complexity to O(log(N)) is
int n = 100000;
//TODO: implement IList<int> GetPrimesUpTo(int) yourself
var primes = GetPrimesUpTo((int)(Math.Sqrt(n + 1) + 1));
// Key - number itself, Value - divisors' sum
var direct = Enumerable
.Range(1, n)
.AsParallel()
.ToDictionary(index => index,
index => GetDivisorsSum(index, primes) - index);
var result = Enumerable
.Range(1, n)
.Where(x => x < direct[x] &&
direct.ContainsKey((int) direct[x]) &&
direct[(int) direct[x]] == x)
.Select(x => $"{x,5}, {direct[x],5}");
Console.Write(string.Join(Environment.NewLine, result));
The outcome is within a second (Core i7 3.2Ghz .Net 4.6 IA-64):
220, 284
1184, 1210
2620, 2924
5020, 5564
6232, 6368
10744, 10856
12285, 14595
17296, 18416
63020, 76084
66928, 66992
67095, 71145
69615, 87633
79750, 88730
Details GetDivisorsSum:
private static long GetDivisorsSum(long value, IList<int> primes) {
HashSet<long> hs = new HashSet<long>();
IList<long> divisors = GetPrimeDivisors(value, primes);
ulong n = (ulong) 1;
n = n << divisors.Count;
long result = 1;
for (ulong i = 1; i < n; ++i) {
ulong v = i;
long p = 1;
for (int j = 0; j < divisors.Count; ++j) {
if ((v % 2) != 0)
p *= divisors[j];
v = v / 2;
}
if (hs.Contains(p))
continue;
result += p;
hs.Add(p);
}
return result;
}
And GetPrimeDivisors:
private static IList<long> GetPrimeDivisors(long value, IList<int> primes) {
List<long> results = new List<long>();
int v = 0;
long threshould = (long) (Math.Sqrt(value) + 1);
for (int i = 0; i < primes.Count; ++i) {
v = primes[i];
if (v > threshould)
break;
if ((value % v) != 0)
continue;
while ((value % v) == 0) {
value = value / v;
results.Add(v);
}
threshould = (long) (Math.Sqrt(value) + 1);
}
if (value > 1)
results.Add(value);
return results;
}

Find the missing integer in Codility

I need to "Find the minimal positive integer not occurring in a given sequence. "
A[0] = 1
A[1] = 3
A[2] = 6
A[3] = 4
A[4] = 1
A[5] = 2, the function should return 5.
Assume that:
N is an integer within the range [1..100,000];
each element of array A is an integer within the range [−2,147,483,648..2,147,483,647].
I wrote the code in codility, but for many cases it did not worked and the performance test gives 0 %. Please help me out, where I am wrong.
class Solution {
public int solution(int[] A) {
if(A.Length ==0) return -1;
int value = A[0];
int min = A.Min();
int max = A.Max();
for (int j = min+1; j < max; j++)
{
if (!A.Contains(j))
{
value = j;
if(value > 0)
{
break;
}
}
}
if(value > 0)
{
return value;
}
else return 1;
}
}
The codility gives error with all except the example, positive and negative only values.
Edit: Added detail to answer your actual question more directly.
"Please help me out, where I am wrong."
In terms of correctness: Consider A = {7,2,5,6,3}. The correct output, given the contents of A, is 1, but our algorithm would fail to detect this since A.Min() would return 2 and we would start looping from 3 onward. In this case, we would return 4 instead; since it's the next missing value.
Same goes for something like A = {14,15,13}. The minimal missing positive integer here is again 1 and, since all the values from 13-15 are present, the value variable will retain its initial value of value=A[0] which would be 14.
In terms of performance: Consider what A.Min(), A.Max() and A.Contains() are doing behind the scenes; each one of these is looping through A in its entirety and in the case of Contains, we are calling it repeatedly for every value between the Min() and the lowest positive integer we can find. This will take us far beyond the specified O(N) performance that Codility is looking for.
By contrast, here's the simplest version I can think of that should score 100% on Codility. Notice that we only loop through A once and that we take advantage of a Dictionary which lets us use ContainsKey; a much faster method that does not require looping through the whole collection to find a value.
using System;
using System.Collections.Generic;
class Solution {
public int solution(int[] A) {
// the minimum possible answer is 1
int result = 1;
// let's keep track of what we find
Dictionary<int,bool> found = new Dictionary<int,bool>();
// loop through the given array
for(int i=0;i<A.Length;i++) {
// if we have a positive integer that we haven't found before
if(A[i] > 0 && !found.ContainsKey(A[i])) {
// record the fact that we found it
found.Add(A[i], true);
}
}
// crawl through what we found starting at 1
while(found.ContainsKey(result)) {
// look for the next number
result++;
}
// return the smallest positive number that we couldn't find.
return result;
}
}
The simplest solution that scored perfect score was:
public int solution(int[] A)
{
int flag = 1;
A = A.OrderBy(x => x).ToArray();
for (int i = 0; i < A.Length; i++)
{
if (A[i] <= 0)
continue;
else if (A[i] == flag)
{
flag++;
}
}
return flag;
}
Fastest C# solution so far for [-1,000,000...1,000,000].
public int solution(int[] array)
{
HashSet<int> found = new HashSet<int>();
for (int i = 0; i < array.Length; i++)
{
if (array[i] > 0)
{
found.Add(array[i]);
}
}
int result = 1;
while (found.Contains(result))
{
result++;
}
return result;
}
A tiny version of another 100% with C#
using System.Linq;
class Solution
{
public int solution(int[] A)
{
// write your code in C# 6.0 with .NET 4.5 (Mono)
var i = 0;
return A.Where(a => a > 0).Distinct().OrderBy(a => a).Any(a => a != (i = i + 1)) ? i : i + 1;
}
}
A simple solution that scored 100% with C#
int Solution(int[] A)
{
var A2 = Enumerable.Range(1, A.Length + 1);
return A2.Except(A).First();
}
public class Solution {
public int solution( int[] A ) {
return Arrays.stream( A )
.filter( n -> n > 0 )
.sorted()
.reduce( 0, ( a, b ) -> ( ( b - a ) > 1 ) ? a : b ) + 1;
}
}
It seemed easiest to just filter out the negative numbers. Then sort the stream. And then reduce it to come to an answer. It's a bit of a functional approach, but it got a 100/100 test score.
Got an 100% score with this solution:
https://app.codility.com/demo/results/trainingUFKJSB-T8P/
public int MissingInteger(int[] A)
{
A = A.Where(a => a > 0).Distinct().OrderBy(c => c).ToArray();
if (A.Length== 0)
{
return 1;
}
for (int i = 0; i < A.Length; i++)
{
//Console.WriteLine(i + "=>" + A[i]);
if (i + 1 != A[i])
{
return i + 1;
}
}
return A.Max() + 1;
}
JavaScript solution using Hash Table with O(n) time complexity.
function solution(A) {
let hashTable = {}
for (let item of A) {
hashTable[item] = true
}
let answer = 1
while(true) {
if(!hashTable[answer]) {
return answer
}
answer++
}
}
The Simplest solution for C# would be:
int value = 1;
int min = A.Min();
int max = A.Max();
if (A.Length == 0) return value = 1;
if (min < 0 && max < 0) return value = 1;
List<int> range = Enumerable.Range(1, max).ToList();
List<int> current = A.ToList();
List<int> valid = range.Except(current).ToList();
if (valid.Count() == 0)
{
max++;
return value = max;
}
else
{
return value = valid.Min();
}
Considering that the array should start from 1 or if it needs to start from the minimum value than the Enumerable.range should start from Min
MissingInteger solution in C
int solution(int A[], int N) {
int i=0,r[N];
memset(r,0,(sizeof(r)));
for(i=0;i<N;i++)
{
if(( A[i] > 0) && (A[i] <= N)) r[A[i]-1]=A[i];
}
for(i=0;i<N;i++)
{
if( r[i] != (i+1)) return (i+1);
}
return (N+1);
}
My solution for it:
public static int solution()
{
var A = new[] { -1000000, 1000000 }; // You can try with different integers
A = A.OrderBy(i => i).ToArray(); // We sort the array first
if (A.Length == 1) // if there is only one item in the array
{
if (A[0]<0 || A[0] > 1)
return 1;
if (A[0] == 1)
return 2;
}
else // if there are more than one item in the array
{
for (var i = 0; i < A.Length - 1; i++)
{
if (A[i] >= 1000000) continue; // if it's bigger than 1M
if (A[i] < 0 || (A[i] + 1) >= (A[i + 1])) continue; //if it's smaller than 0, if the next integer is bigger or equal to next integer in the sequence continue searching.
if (1 < A[0]) return 1;
return A[i] + 1;
}
}
if (1 < A[0] || A[A.Length - 1] + 1 == 0 || A[A.Length - 1] + 1 > 1000000)
return 1;
return A[A.Length-1] +1;
}
class Solution {
public int solution(int[] A) {
int size=A.length;
int small,big,temp;
for (int i=0;i<size;i++){
for(int j=0;j<size;j++){
if(A[i]<A[j]){
temp=A[j];
A[j]=A[i];
A[i]=temp;
}
}
}
int z=1;
for(int i=0;i<size;i++){
if(z==A[i]){
z++;
}
//System.out.println(a[i]);
}
return z;
}
enter code here
}
In C# you can solve the problem by making use of built in library functions. How ever the performance is low for very large integers
public int solution(int[] A)
{
var numbers = Enumerable.Range(1, Math.Abs(A.Max())+1).ToArray();
return numbers.Except(A).ToArray()[0];
}
Let me know if you find a better solution performance wise
C# - MissingInteger
Find the smallest missing integer between 1 - 1000.000.
Assumptions of the OP take place
TaskScore/Correctness/Performance: 100%
using System;
using System.Linq;
namespace TestConsole
{
class Program
{
static void Main(string[] args)
{
var A = new int[] { -122, -5, 1, 2, 3, 4, 5, 6, 7 }; // 8
var B = new int[] { 1, 3, 6, 4, 1, 2 }; // 5
var C = new int[] { -1, -3 }; // 1
var D = new int[] { -3 }; // 1
var E = new int[] { 1 }; // 2
var F = new int[] { 1000000 }; // 1
var x = new int[][] { A, B, C, D, E, F };
x.ToList().ForEach((arr) =>
{
var s = new Solution();
Console.WriteLine(s.solution(arr));
});
Console.ReadLine();
}
}
// ANSWER/SOLUTION
class Solution
{
public int solution(int[] A)
{
// clean up array for negatives and duplicates, do sort
A = A.Where(entry => entry > 0).Distinct().OrderBy(it => it).ToArray();
int lowest = 1, aLength = A.Length, highestIndex = aLength - 1;
for (int i = 0; i < aLength; i++)
{
var currInt = A[i];
if (currInt > lowest) return lowest;
if (i == highestIndex) return ++lowest;
lowest++;
}
return 1;
}
}
}
Got 100% - C# Efficient Solution
public int solution (int [] A){
int len = A.Length;
HashSet<int> realSet = new HashSet<int>();
HashSet<int> perfectSet = new HashSet<int>();
int i = 0;
while ( i < len)
{
realSet.Add(A[i]); //convert array to set to get rid of duplicates, order int's
perfectSet.Add(i + 1); //create perfect set so can find missing int
i++;
}
perfectSet.Add(i + 1);
if (realSet.All(item => item < 0))
return 1;
int notContains =
perfectSet.Except(realSet).Where(item=>item!=0).FirstOrDefault();
return notContains;
}
class Solution {
public int solution(int[] a) {
int smallestPositive = 1;
while(a.Contains(smallestPositive)) {
smallestPositive++;
}
return smallestPositive;
}
}
Well, this is a new winner now. At least on C# and my laptop. It's 1.5-2 times faster than the previous champion and 3-10 times faster, than most of the other solutions. The feature (or a bug?) of this solution is that it uses only basic data types. Also 100/100 on Codility.
public int Solution(int[] A)
{
bool[] B = new bool[(A.Length + 1)];
for (int i = 0; i < A.Length; i++)
{
if ((A[i] > 0) && (A[i] <= A.Length))
B[A[i]] = true;
}
for (int i = 1; i < B.Length; i++)
{
if (!B[i])
return i;
}
return A.Length + 1;
}
Simple C++ solution. No additional memory need, time execution order O(N*log(N)):
int solution(vector<int> &A) {
sort (A.begin(), A.end());
int prev = 0; // the biggest integer greater than 0 found until now
for( auto it = std::begin(A); it != std::end(A); it++ ) {
if( *it > prev+1 ) break;// gap found
if( *it > 0 ) prev = *it; // ignore integers smaller than 1
}
return prev+1;
}
int[] A = {1, 3, 6, 4, 1, 2};
Set<Integer> integers = new TreeSet<>();
for (int i = 0; i < A.length; i++) {
if (A[i] > 0) {
integers.add(A[i]);
}
}
Integer[] arr = integers.toArray(new Integer[0]);
final int[] result = {Integer.MAX_VALUE};
final int[] prev = {0};
final int[] curr2 = {1};
integers.stream().forEach(integer -> {
if (prev[0] + curr2[0] == integer) {
prev[0] = integer;
} else {
result[0] = prev[0] + curr2[0];
}
});
if (Integer.MAX_VALUE == result[0]) result[0] = arr[arr.length-1] + 1;
System.out.println(result[0]);
I was surprised but this was a good lesson. LINQ IS SLOW. my answer below got me 11%
public int solution (int [] A){
if (Array.FindAll(A, x => x >= 0).Length == 0) {
return 1;
} else {
var lowestValue = A.Where(x => Array.IndexOf(A, (x+1)) == -1).Min();
return lowestValue + 1;
}
}
I think I kinda look at this a bit differently but gets a 100% evaluation. Also, I used no library:
public static int Solution(int[] A)
{
var arrPos = new int[1_000_001];
for (int i = 0; i < A.Length; i++)
{
if (A[i] >= 0)
arrPos[A[i]] = 1;
}
for (int i = 1; i < arrPos.Length; i++)
{
if (arrPos[i] == 0)
return i;
}
return 1;
}
public int solution(int[] A) {
// write your code in Java SE 8
Set<Integer> elements = new TreeSet<Integer>();
long lookFor = 1;
for (int i = 0; i < A.length; i++) {
elements.add(A[i]);
}
for (Integer integer : elements) {
if (integer == lookFor)
lookFor += 1;
}
return (int) lookFor;
}
I tried to use recursion in C# instead of sorting, because I thought it would show more coding skill to do it that way, but on the scaling tests it didn't preform well on large performance tests. Suppose it's best to just do the easy way.
class Solution {
public int lowest=1;
public int solution(int[] A) {
// write your code in C# 6.0 with .NET 4.5 (Mono)
if (A.Length < 1)
return 1;
for (int i=0; i < A.Length; i++){
if (A[i]==lowest){
lowest++;
solution(A);
}
}
return lowest;
}
}
Here is my solution in javascript
function solution(A) {
// write your code in JavaScript (Node.js 8.9.4)
let result = 1;
let haveFound = {}
let len = A.length
for (let i=0;i<len;i++) {
haveFound[`${A[i]}`] = true
}
while(haveFound[`${result}`]) {
result++
}
return result
}
class Solution {
public int solution(int[] A) {
var sortedList = A.Where(x => x > 0).Distinct().OrderBy(x => x).ToArray();
var output = 1;
for (int i = 0; i < sortedList.Length; i++)
{
if (sortedList[i] != output)
{
return output;
}
output++;
}
return output;
}
}
You should just use a HashSet as its look up time is also constant instead of a dictionary. The code is less and cleaner.
public int solution (int [] A){
int answer = 1;
var set = new HashSet<int>(A);
while (set.Contains(answer)){
answer++;
}
return answer;
}
This snippet should work correctly.
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
int result = 1;
List<int> lst = new List<int>();
lst.Add(1);
lst.Add(2);
lst.Add(3);
lst.Add(18);
lst.Add(4);
lst.Add(1000);
lst.Add(-1);
lst.Add(-1000);
lst.Sort();
foreach(int curVal in lst)
{
if(curVal <=0)
result=1;
else if(!lst.Contains(curVal+1))
{
result = curVal + 1 ;
}
Console.WriteLine(result);
}
}
}

Parallel.For in C#

I am trying convert the following Collatz Conjecture algorithm from:
public class CollatzConjexture
{
public static int Calculate(int StartIndex, int MaxSequence)
{
int ChainLength = 0;
int key = 0;
bool ContinuteCalulating = true;
int LongestChain = 0;
Int64 Remainder = 0;
for (int i = StartIndex; i <= MaxSequence; i++)
{
ChainLength = 1;
Remainder = i;
ContinuteCalulating = true;
while (ContinuteCalulating)
{
Remainder = CalculateCollatzConjecture(Remainder);
if (Remainder == 1)
ContinuteCalulating = false;
ChainLength += 1;
}
if (ChainLength > LongestChain)
{
LongestChain = ChainLength;
key = i;
}
}
return key;
}
private static Int64 CalculateCollatzConjecture(Int64 Number)
{
if (Number % 2 == 0)
return Number / 2;
else
return (3 * Number) + 1;
}
}
To instead use the .NET 4.0 Parallel.For :
int ChainLength = 0;
int key = 0;
bool ContinuteCalulating = true;
int LongestChain = 0;
Int64 Remainder = 0;
int[] nums = Enumerable.Range(1, 1500000).ToArray();
long total = 0;
// Use type parameter to make subtotal a long, not an int
Parallel.For<int>(1, nums.Length, () => 1, (j, loop, subtotal) =>
{
Remainder = j;
while (ContinuteCalulating)
{
Remainder = CalculateCollatzConjecture(Remainder);
if (Remainder == 1)
ContinuteCalulating = false;
ChainLength += 1;
}
if (ChainLength > LongestChain)
{
LongestChain = ChainLength;
key = j;
}
return key;
},
(x) => Interlocked.Add(ref key, x)
);
I have a feeling I'm not too far from it, famous last words.
Thanks in advance.
Your problem is that you don't want to use Parallel.For in this instance because you already have an array (nums) to iterate over, which calls for Parallel.ForEach. However, your array is created with Enumerable.Range and you don't actually use it for anything, so the best way to do it is with AsParallel and LINQ (PLINQ):
public static class CollatzConjexture2
{
public static int Calculate(int StartIndex, int MaxSequence)
{
var nums = Enumerable.Range(StartIndex, MaxSequence);
return nums.AsParallel()
// compute length of chain for each number
.Select(n => new { key = n, len = CollatzChainLength(n) })
// find longest chain
.Aggregate((max, cur) => cur.len > max.len ||
// make sure we have lowest key for longest chain
max.len == cur.len && cur.key < max.key ? cur : max)
// get number that produced longest chain
.key;
}
private static int CollatzChainLength(Int64 Number)
{
int chainLength;
for (chainLength = 1; Number != 1; chainLength++)
Number = (Number & 1) == 0 ? Number >> 1 : Number * 3 + 1;
return chainLength;
}
}
This method is about twice as fast on my computer as the serial implementation. Also note that I optimized the main loop so that it does the computation inline rather than calling a function and it uses bitwise math instead of multiplying and dividing. This made it about twice as fast again. Compiling it for x64 instead of x86 also made it more than twice as fast.

Help with LINQ Expression

How to write a LINQ Expression (method call syntax preferred) that gives a list of fibonacci numbers lying within a certain range, say 1 to 1000 ?
OK; for a more "FP" answer:
using System;
using System.Collections.Generic;
using System.Linq;
static class Program
{
static void Main()
{
Func<long, long, long, IEnumerable<long>> fib = null;
fib = (n, m, cap) => n + m > cap ? Enumerable.Empty<long>()
: Enumerable.Repeat(n + m, 1).Concat(fib(m, n + m, cap));
var list = fib(0, 1, 1000).ToList();
}
}
Note that in theory this can be written as a single lambda, but that is very hard.
Using the iterator-block answer from here:
foreach (long i in Fibonacci()
.SkipWhile(i => i < 1)
.TakeWhile(i => i <= 1000)) {
Console.WriteLine(i);
}
or for a list:
var list = Fibonacci().SkipWhile(i => i < 1).TakeWhile(i => i <= 1000)
.ToList();
Output:
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
Here is enumerator base solution. Its a lazy evaluation. So next number is generated when MoveNext() is done.
foreach (int k in Fibonacci.Create(10))
Console.WriteLine(k);
class Fibonacci : IEnumerable<int>
{
private FibonacciEnumertor fibEnum;
public Fibonacci(int max) {
fibEnum = new FibonacciEnumertor(max);
}
public IEnumerator<int> GetEnumerator() {
return fibEnum;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
return GetEnumerator();
}
public static IEnumerable<int> Create(int max) {
return new Fibonacci(max);
}
private class FibonacciEnumertor : IEnumerator<int>
{
private int a, b, c, max;
public FibonacciEnumertor(int max) {
this.max = max;
Reset();
}
// 1 1 2 3 5 8
public int Current {
get {
return c;
}
}
public void Dispose() {
}
object System.Collections.IEnumerator.Current {
get { return this.Current; }
}
public bool MoveNext() {
c = a + b;
if (c == 0)
c = 1;
a = b;
b = c;
;
return max-- > 0;
}
public void Reset() {
a = 0;
b = 0;
}
}
}
not very performant:
val fibonacci = Enumerable
.Range(0, 1000)
.Aggregate(new List<int>{1,0}, (b,j)=>{
b.Insert(0,b[0]+b[1]);
return b; });
late, but a fast version with the "yield" keyword :-)
IEnumerable<int> Fibonacci(int limit)
{
int number = 1, old = 0;
while (number < limit)
{
yield return number;
int tmp = number; number += old; old = tmp;
}
}
var list = Fibonacci(1000).ToList();
Easiest way to print fibonacci using linq
List<int> lst = new List<int> { 0, 1 };
for (int i = 0; i <= 10; i++)
{
int num = lst.Skip(i).Sum();
lst.Add(num);
foreach (int number in lst)
Console.Write(number + " ");
Console.WriteLine();
}

Categories