Okay, so I'm getting a "cannot convert int to bool" error.
I'm trying to convert this VB .net code:
Function GetChecksum(ByVal Source As String) As Long
Dim iVal, Weight, CheckHold, CheckSum As Long
Weight = 1
CheckSum = 0
For iVal = 1 To Len(Source)
CheckHold = Asc(Mid$(Source, iVal, 1)) * Weight
CheckSum = CheckSum + CheckHold
Weight = Weight + 2
Next iVal
GetChecksum = CheckSum Mod &H7FFFFFFF
End Function
I've gotten up to here:
public long getCheckSum(string source)
{
long iVal, weight, checkgold, checksum = new long();
weight = 1;
checksum = 0;
for (iVal = 1; Strings.Len(source);)
{
}
}
The problem is the "For (iVal = 1; Strings.Len(source);)" code. I am using "Microsoft.VisualBasic". I just don't know what to do right now. If you could help me that'd be great.
Looks like you need to set your loop correctly. In C#, a for loop (generally) follows the following format:
for(initializer; conditional check; evaluation)
initializer is where you set variables like iVal = 1
conditional check is where you determine the bounds of the for loop
evaluation is usually where you increment a variable
In your code, you have an integer, Strings.Len(source), as the conditional check, which is expecting a boolean response so it's failing.
Your for loop opener should look something like this:
for (iVal = 1; iVal < source.Length; iVal++)
That's assuming your logic is 0 < iVal < length of source string.
As an aside, the way you check the length of a string in C# is with the .Length property, rather than using the Strings.Len() function.
for (iVal = 1; iVal < source.Length; iVal++)
{
}
The middle section is a condition.
You will need:
for (iVal = 1; iVal <= source.Length; ival += 1)
But be aware this loops through 1..source.Length,
not the more common (in C#) 0..source.Length-1
As the others have already solved your problem, I only want to add for future reference that you might want to check out Convert VB to C#.
I've used it myself on a number of occasions with pretty good results.
Standard syntax of for loop:
for(counter initialize; counter compare; counter increment) {}
The comparison expects a bool, you're providing an int with Strings.Len(source), which returns some number, not a Boolean value like true or false.
Try
for(iVal = 1; iVal < String.Len(source); iVal++)
You may want to use <= since your starting at 1 or set iVal to 0
Your For syntax should looks something like this :
For(ival = 1; source.Length; ival++)
{
// your code here
}
ival++ will replace the "Next" in VB.
Rather than translate the for loop literally into C#, I'd use a foreach, as you're doing a straightforward iteration over the elements of a sequence (each char in the string):
public long getCheckSum(string source)
{
long checkHold = 0, checkSum = 0, weight = 1;
foreach (char ch in source)
{
checkHold = (long)ch * weight;
checkSum += checkHold;
weight += 2;
}
return checkSum % 0x7FFFFFFF;
}
you want
for (iVal = 1; iVal <= source.Length; iVal++)
{
//your code here
}
Alternatively, if you want to leave iVal alone (because you need it "pure" for something later)
for(i = iVal; i <= source.Length; i++)
{
//your code here.
}
Related
TLDR: Codility "Challenge" - my results: Where is the error?
Short Description (Full Description): Given an Array, split the array into two (Upper and lower parts) and give the minimum difference between two possible parts in absolute value.
My thought process is:
create an "Upper" and "Lower" bucket for sums.
In one pass of the array, we get a sum for the "Upper" bucket.
Then, one array value at a time, move the numbers into lower (Upper-n, Lower+n).
At each step, get the difference (Abs(Upper-lower))
Monitor lowest "Minimum"
Submitted Code:
public int solution(int[] A)
{
// Quick results:
if (A == null) return -1;
if (A.Length == 0) return -1; // Can't split
if (A.Length == 1) return -1; // Can't split
if (A.Length == 2) return Math.Abs(A[0] - A[1]); // Only one way to split
// Hold above/below/result...
long lower = 0;
long upper = 0;
var min = long.MaxValue;
// Pass#1: Sum All to get "Upper"
for (long i = 0; i < A.Length; i++) upper += A[i];
// Pass#2:
// foreach in array
// ... Shift number from upper to lower
// ... Calculate new difference/minimum
for (var i = 0; i < A.Length; i++)
{
lower += A[i];
upper -= A[i];
var diff = Math.Abs(upper - lower);
min = Math.Min(min, diff);
if (diff == 0) return 0;
}
return (int) min;
}
Out of 13 test cases, the only one that Codility fails me on is: "Small Numbers". it says "Wrong answer, expected 20 got 0". It doesn't show the test data it uses, so I'm left guessing as to "Why".
Where is my error? I think I've stared at it too much, but I can't seem to figure out what case would "break" my function.
Edit: Fixed translation. Submitted code to Codility uses a Foreach, and the code I have here is a For. Corrected the variables in the loop.
The problem is that you didn't take into account one of the rules: 0 < P < N.
Your second loop is assuming 0 < P <= N.
Assume this input:
10, 10, -20
Your code would return 0 but 40 would be correct.
Fix:
Change your second loop header to
for (var i = 0; i < A.Length - 1; i++)
Proof
So I have pow - a list containing numbers. I have to examine other numbers like this: Get all the digits and sum the numbers from pow having the same index as the certain digit.
So if I check number 4552 I need to get pow[4]+pow[5]+pow[5]+pow[2]. Because I'm a noob I try to convert the number to string, get the characters with loop and then convert back to int to get the index. So the code is as follows for getting the sums between 4550 and 4559:
for (int i = 4550; i < 4560; i++)
{
int sum = 0;
for (int j = 0; j < i.ToString().Length; j++)
{
sum += pows[Convert.ToInt32(i.ToString()[j])]; //here is the error - index was out of range
//do something with sum (like store it in another list)
}
}
So what is wrong with that?
EDIT: To avoid confusion... pow has 10 elements, from indexes 0-9.
SOLUTION: The issue with my code was that I got the character code not the digit itself, thanks Steve Lillis. Though the solution provided by Dmitry Bychenko is far more superior to my attempt. Thank you all.
What you're looking for is similar to a digital root:
Modulus (% in C#) is easier and faster than conversion to string:
public static int DigitalRootIndex(IList<int> list, int value) {
if (value < 0)
value = -value;
int result = 0;
// for value == 4552
// result == list[4] + list[5] + list[5] + list[2]
while (value > 0) {
int index = value % 10;
result += list[index];
value /= 10;
}
return result;
}
...
int test = DigitalRootIndex(pow, 4552);
This bit of code gets a single character such as '4' which is character code 59:
c = i.ToString()[j]
Then this bit of code turns that char into an integer. It doesn't parse it like you're expecting, so the result for '4' is 59, not 4:
Convert.ToInt32(c)
Do this instead:
int.Parse(c.ToString())
Something like this (quick and dirty try)?
int currentDigit;
int sum;
for (int i = 4550; i < 4560; i++)
{
sum = 0;
currentDigit = i;
while (currentDigit > 0)
{
if (pow.Count > (currentDigit % 10))
{
sum += pow[((currentDigit % 10))];
}
}
}
Note that lists have zero based index so when you do pow[1], you are actually accessing second element in the list. Is that what you want?
Basically, every time in a for/loop how do you know when you hit a certain increment?
A way to do is to use a second variable as a counter, like this:
int i2 = 0;
for(int i=0;i<70;i++){
if(i2==7){ i2=0; #Model.Value }
i2++;
}
This writes #Model.Value once for every 7 times it loops.
Is there a way to avoid using a second variable (i2)--A shorthand way to do something like this?
Use modular arithmetic:
for (int i = 0; i < 70; i++)
{
if (i % 7 == 0)
// Do stuff
}
I think you want to use the modulus operator, which returns the remainder after doing a division operation. Since you want it to happen every seventh iteration, you would use % 7. Since your index is starting at zero, you also want to add 1 to i when doing the division, or else it will start on your eighth iteration (when i is seven).
for (int i = 0; i < 70; i++)
{
if((i + 1) % 7 == 0) #Model.Value;
}
Follow this format
for (;;)
statement;
In your example you would accomplish your task by writing:
for (int iii = 0; iii < 70; iii++){
if (iii % 7 == 0)
(#Model.Value)
}
For example i have a long[] x
And im doing:
for (int i=0; i<x.length;x--)
{
}
I know that in x for example i have 30 indexs cells.
How can i loop over the cells(indexs) in the x array and find on each cell the length of it and also to get/show the numbers in each cell.
If in x[0] there is 232
And in x[1] there is 21
And so on...
I want to display 232,21,....etc
And then i want to check that if x[i].length is above 0 do...
But there is no x[i].length
So how do i do it ?
I did:
public long GetHistogramMaximum(long[] histogram)
{
long result = 0;
long count = 0;
for (int i = 0; i < histogram.Length; i++)
{
if (histogram[i] > 0)
{
MessageBox.Show(histogram[i].ToString());
break;
}
}
return result;
}
And its working but each time its showing me the number twice why the messagebox is working twice each time ?
If in the first array the number is 33454 then i see the messagebox once and then once again. Whats wrong here ? I want it to show me the number only once each time.
Its like repeating each number and show it once and then once again and only then moving to the next one.
EDIT **
Maybe the problem its showing the number twice each time have something to do with the scroll event im using ?
void trackBar1_Scroll(object sender, EventArgs e)
{
myTrackPanelss1.trackBar1.Minimum = 0;
myTrackPanelss1.trackBar1.Maximum = counter - 1;//list_of_histograms.Count-1;
long[] tt = list_of_histograms[myTrackPanelss1.trackBar1.Value];
histogramControl1.DrawHistogram(tt);
long res = GetTopLumAmount(tt, 1000);
long max = GetHistogramMaximum(tt);
if (res > -1)
label24.Text = (res / 1000.0).ToString();
setpicture(myTrackPanelss1.trackBar1.Value);
this.pictureBox1.Refresh();
}
For some reason its getting to the scroll and do everything here again. Twice in a row.
What can be the problem ?
A long[] basically holds a number of long values. Doing x[i].length is invalid, because a long does not have a property length. What is it that you are trying to achieve?
long[] x = {1,2,3} ;
x.length; //this is valid because you are querying the length / count of the array
x[0].length; //this is invalid because 1 does not have a property length
EDIT
Your loop counter will be the index. So,
for (int i =0; i < x.Length; i++)
{
//check for maximum, when you find it
Console.WriteLine("The maximum value is " + x[i]);
Console.WriteLine("The maximum value is present at index " + i);
}
As Michael says, you can find the length of the array via x.Length. In C#, x.Length (where x is an array) will return a 32-bit integer that represents the total number of elements across all dimensions. You only have a 1D array here, so that should be sufficient for what you're trying to achieve.
If you're also after the value stored in the array, the value is called as:
x[i];
So, in an example:
for ( int i = 0; i < x.Length; i++)
{
Console.WriteLine(x[i]);
}
... would display the value in the array in your console.
Is that what you were asking?
Here is how to do something based on the values in the array.:
for (int i=0; i < x.Length; i++)
{
// print the number to the screen.
Console.WriteLine(x[i]);
if (x[i] > 0) {
// do something else.
}
}
I'm not sure what you meant by x--, but that's probably wrong from your description.
You could cast it to a string and get the length property.
x[i].ToString().Length
Although if you want to check if the length is above zero, then surely just the presence of a value proves this?
Your function has a terrible problem:
public long GetHistogramMaximum(long[] histogram)
{
long result = 0;
long count = 0;
for (int i = 0; i < histogram.Length; i++)
{
if (histogram[i] > 0)
{
MessageBox.Show(histogram[i].ToString());
break;
}
}
return result;
}
This way, you check the values in your array.
When i=0, it checks x[i]. So, 33454 (the value you gave in x[0]) is greater than 0, it shows the number and "break;", so it stops the "for" and do what's next: it returns the result variable that is never modified.
So variables result and count are useless in your code.
Rewrite with something that way for getting the maximum in your array:
public long GetHistogramMaximum(long[] histogram)
{
long result = 0;
for (int i = 0; i < histogram.Length; i++)
{
if (histogram[i] > result)
{
MessageBox.Show(string.Format("{0} is greater than {1}", histogram[i], result);
result = histogram[i];
}
}
return result;
}
I wrote this code and its always showing the same results why?
The code is a searching method.
using System;
using System.Collections.Generic;
using System.Text;
namespace CArraySe
{
class Program
{
class CArray
{
private int[] arr;
private int upper;
private int numElements;
private int compCount;
public CArray(int size)
{
arr = new int[size];
upper = size - 1;
numElements = 0;
compCount = 0;
}
public void Insert(int item)
{
arr[numElements] = item;
numElements++;
}
public void DisplayElements()
{
for (int i = 0; i <= upper; i++)
{
Console.Write(arr[i]);
if (i == upper)
{
Console.WriteLine();
continue;
}
Console.Write(", ");
}
}
public void Clear()
{
for (int i = 0; i <= upper; i++)
arr[i] = 0;
numElements = 0;
}
public bool SeqSearch(CArray n, int sValue)
{
for (int index = 0; index < n.upper; index++)
{
if (arr[index] == sValue)
return true;
}
compCount++;
return false;
}
public int binSearch(CArray n, int value)
{
int upperBound, lowerBound, mid;
upperBound = n.upper; lowerBound = 0;
while (lowerBound <= upperBound)
{
mid = (upperBound + lowerBound) / 2;
if (arr[mid] == value)
return mid;
else if (value < arr[mid]) upperBound = mid - 1;
else lowerBound = mid + 1;
}
compCount++;
return -1;
}
static void Main(string[] args)
{
CArray nums = new CArray(10);
Random rnd = new Random(100);
for (int i = 0; i < 10; i++)
nums.Insert((int)(rnd.NextDouble() * 100));
Console.WriteLine();
Console.Write("The Binary Search Result is: ");
Console.WriteLine(nums.binSearch(nums, 500));
Console.WriteLine(nums.compCount);
nums.Clear();
for (int i = 0; i < 10; i++)
nums.Insert((int)(rnd.NextDouble() * 100));
Console.Write("The Sequential Search result is: ");
Console.WriteLine(nums.SeqSearch(nums, 500));
Console.WriteLine(nums.compCount);
}
}
}
}
Its always showing the same result even if I changed the number I'm looking for.
The output is:
The Binary Search Result is: -1
1
The Sequential Search result is: False
2
Press any key to continue . . .
I think your value being searched for (500) is not being found. Try outputting the nums array and verifying that what you are looking for is in the array.
Plus, one search returns an int and the other returns a bool. Is there a specific reason for that?
Edit: Also, Binary Search only works with sorted lists.
Your method binSearch returns "-1" when the number isn't found. Since you're populating your array with random values, the odds are very good that the number you search for won't be found. So you're always getting "-1".
To test your binSearch method, you should populate the array with known values, then search for some value that is guaranteed to be in the array.
The first answer is correct. Also, even though you are using a random number, each run of the program will produce the same sequence of random numbers. You should seed it with a different number each time you run the program if you want to test the code well.
As the others have already mentioned, in the general case, there's no guarantee that the number you're searching for is in the list of randomly generated numbers. In the specific case that you posted, the number will never appear in the list because you're generating random numbers in the 0-100 range, then trying to find 500.
Running what you provided does not add a value above 100. If you change your add to this:
for (int i = 0; i < 9; i++)
nums.Insert((int)(rnd.NextDouble() * 100));
nums.Insert(500);
The binSearch returns 9, but the SeqSearch return false because your looping search is index < n.upper and you need to do index <= n.upper to check all values. Additionally, as noted above, the binSearch only works in this case because 500 is larger than all the numbers in the array and has been placed at the last index. The binary search will only work by luck if the list its searching is not sorted. Therefore changing to:
nums.Insert(500);
for (int i = 0; i < 9; i++)
nums.Insert((int)(rnd.NextDouble() * 100));
Will return -1; and true for the SeqSearch.
Although this probably doesn't answer your question directly, here are some observations which makes your code hard to understand and debug:
You need either one of numElements or upper, not both. In Clear(), you are setting only numElements to 0 whereas you are using upper in your loops everywhere?
Binary search works only with sorted arrays
If SeqSearch and BinSearch are receiving an instance of the array, shouldn't they be static methods instead of instance methods?