Parallel.For in C# - 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.

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();

Collatz sequence using linq 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;

Reorder digits in integer using C#

I want to ask how I can reorder the digits in an Int32 so they result in the biggest possible number.
Here is an example which visualizes what I am trying to do:
2927466 -> 9766422
12492771 -> 97742211
I want to perform the ordering of the digits without using the System.Linq namespace and without converting the integer into a string value.
This is what I got so far:
public static int ReorderInt32Digits(int v)
{
int n = Math.Abs(v);
int l = ((int)Math.Log10(n > 0 ? n : 1)) + 1;
int[] d = new int[l];
for (int i = 0; i < l; i++)
{
d[(l - i) - 1] = n % 10;
n /= 10;
}
if (v < 0)
d[0] *= -1;
Array.Sort(d);
Array.Reverse(d);
int h = 0;
for (int i = 0; i < d.Length; i++)
{
int index = d.Length - i - 1;
h += ((int)Math.Pow(10, index)) * d[i];
}
return h;
}
This algorithm works flawlessly but I think it is not very efficient.
I would like to know if there is a way to do the same thing more efficiently and how I could improve my algorithm.
You can use this code:
var digit = 2927466;
String.Join("", digit.ToString().ToCharArray().OrderBy(x => x));
Or
var res = String.Join("", digit.ToString().ToCharArray().OrderByDescending(x => x) );
Not that my answer may or may not be more "efficient", but when I read your code you calculated how many digits there are in your number so you can determine how large to make your array, and then you calculated how to turn your array back into a sorted integer.
It would seem to me that you would want to write your own code that did the sorting part without using built in functionality, which is what my sample does. Plus, I've added the ability to sort in ascending or descending order, which is easy to add in your code too.
UPDATED
The original algorithm sorted the digits, now it sorts the digits so that the end result is the largest or smallest depending on the second parameter passed in. However, when dealing with a negative number the second parameter is treated as opposite.
using System;
public class Program
{
public static void Main()
{
int number1 = 2927466;
int number2 = 12492771;
int number3 = -39284925;
Console.WriteLine(OrderDigits(number1, false));
Console.WriteLine(OrderDigits(number2, true));
Console.WriteLine(OrderDigits(number3, false));
}
private static int OrderDigits(int number, bool asc)
{
// Extract each digit into an array
int[] digits = new int[(int)Math.Floor(Math.Log10(Math.Abs(number)) + 1)];
for (int i = 0; i < digits.Length; i++)
{
digits[i] = number % 10;
number /= 10;
}
// Order the digits
for (int i = 0; i < digits.Length; i++)
{
for (int j = i + 1; j < digits.Length; j++)
{
if ((!asc && digits[j] > digits[i]) ||
(asc && digits[j] < digits[i]))
{
int temp = digits[i];
digits[i] = digits[j];
digits[j] = temp;
}
}
}
// Turn the array of digits back into an integer
int result = 0;
for (int i = digits.Length - 1; i >= 0; i--)
{
result += digits[i] * (int)Math.Pow(10, digits.Length - 1 - i);
}
return result;
}
}
Results:
9766422
11224779
-22345899
See working example here... https://dotnetfiddle.net/RWA4XV
public static int ReorderInt32Digits(int v)
{
var nums = Math.Abs(v).ToString().ToCharArray();
Array.Sort(nums);
bool neg = (v < 0);
if(!neg)
{
Array.Reverse(nums);
}
return int.Parse(new string(nums)) * (neg ? -1 : 1);
}
This code fragment below extracts the digits from variable v. You can modify it to store the digits in an array and sort/reverse.
int v = 2345;
while (v > 0) {
int digit = v % 10;
v = v / 10;
Console.WriteLine(digit);
}
You can use similar logic to reconstruct the number from (sorted) digits: Multiply by 10 and add next digit.
I'm posting this second answer because I think I got the most efficient algorithm of all (thanks for the help Atul) :)
void Main()
{
Console.WriteLine (ReorderInt32Digits2(2927466));
Console.WriteLine (ReorderInt32Digits2(12492771));
Console.WriteLine (ReorderInt32Digits2(-1024));
}
public static int ReorderInt32Digits2(int v)
{
bool neg = (v < 0);
int mult = neg ? -1 : 1;
int result = 0;
var counts = GetDigitCounts(v);
for (int i = 0; i < 10; i++)
{
int idx = neg ? 9 - i : i;
for (int j = 0; j < counts[idx]; j++)
{
result += idx * mult;
mult *= 10;
}
}
return result;
}
// From Atul Sikaria's answer
public static int[] GetDigitCounts(int n)
{
int v = Math.Abs(n);
var result = new int[10];
while (v > 0) {
int digit = v % 10;
v = v / 10;
result[digit]++;
}
return result;
}

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);
}
}
}

C# fibonacci function returning errors

I am practising a C# console application, and I am trying to get the function to verify if the number appears in a fibonacci series or not but I'm getting errors.
What I did was:
class Program
{
static void Main(string[] args)
{
System.Console.WriteLine(isFibonacci(20));
}
static int isFibonacci(int n)
{
int[] fib = new int[100];
fib[0] = 1;
fib[1] = 1;
for (int i = 2; i <= 100; i++)
{
fib[i] = fib[i - 1] + fib[i - 2];
if (n == fib[i])
{
return 1;
}
}
return 0;
}
}
Can anybody tell me what am I doing wrong here?
Here's a fun solution using an infinite iterator block:
IEnumerable<int> Fibonacci()
{
int n1 = 0;
int n2 = 1;
yield return 1;
while (true)
{
int n = n1 + n2;
n1 = n2;
n2 = n;
yield return n;
}
}
bool isFibonacci(int n)
{
foreach (int f in Fibonacci())
{
if (f > n) return false;
if (f == n) return true;
}
}
I actually really like this kind of Fibonacci implementation vs the tradition recursive solution, because it keeps the work used to complete a term available to complete the next. The traditional recursive solution duplicates some work, because it needs two recursive calls each term.
The problem lies in <= the following statement:
for (int i = 2; i <= 100; i++)
more to the point the =. There is no fib[100] (C# zero counts) so when you check on i=100 you get an exception.
the proper statement should be
for (int i = 2; i < 100; i++)
or even better
for (int i = 2; i < fib.Length; i++)
And here is a solution that beats all of yours!
Because, why iteration when you have smart mathematicians doing closed-form solutions for you? :)
static bool IsFibonacci(int number)
{
//Uses a closed form solution for the fibonacci number calculation.
//http://en.wikipedia.org/wiki/Fibonacci_number#Closed-form_expression
double fi = (1 + Math.Sqrt(5)) / 2.0; //Golden ratio
int n = (int) Math.Floor(Math.Log(number * Math.Sqrt(5) + 0.5, fi)); //Find's the index (n) of the given number in the fibonacci sequence
int actualFibonacciNumber = (int)Math.Floor(Math.Pow(fi, n) / Math.Sqrt(5) + 0.5); //Finds the actual number corresponding to given index (n)
return actualFibonacciNumber == number;
}
Well, for starters your array is only 10 long and you're filling it with ~100 items (out-of-range-exception) - but there are better ways to do this...
for example, using this post:
long val = ...
bool isFib = Fibonacci().TakeWhile(x => x <= val).Last() == val;
int[] fib = new int[10];
for (int i = 2; i <= *100*; i++)
You're going out of the bounds of your array because your loop conditional is too large. A more traditional approach would be to bound the loop by the size of the array:
for (int i = 2; i < fib.Length; i++)
And make your array bigger, but as Marc said, there are better ways to do this, and I would advise you spend some time reading the wikipedia article on Fibonacci numbers.
One thing you can do is check for an early exit. Since you're trying to determine if a given number is in the Fibonacci sequence, you can do bounds checking to exit early.
Example:
static bool isFibonacci(int n)
{
int[] fib = new int[100];
fib[0] = 1;
fib[1] = 1;
for (int i = 2; i <= fib.Length; i++)
{
fib[i] = fib[i - 1] + fib[i - 2];
if (n == fib[i])
{
return true;
}
else if (n < fib[i])
{
return false; //your number has been surpassed in the fib seq
}
}
return false;
}
public static int FibNo(int n) {
int result = 0; int No = 0; int N1 = 1;
if (n< 0)
{ throw new ArguementException("number must be a positive value"); }
if (n <= 1)
{ result = n; return result; }
for(int x=1; x < n; x++)
{ result = No + N1; No = N1; N1=result; }
return result;
}

Categories