Good day all.
I am getting back into C# after a few years, and am little stuck on an error I'm receiving. I wrote a practice program to determine whether a word is a palindrome (same backwards and forwards). I am however getting an error that confuses me.
I try to call Math.Ceiling(word.Length / 2) to get the middle of a word, but it gives me the following error:
"The call is ambiguous between the following methods or properties:'Math.Ceiling(decimal) and Math.Ceiling(double)"
Although I get that this is the compiler worrying about identifying the correct overloaded method, but am unsure how to indicate which I am using. I also don't get why should this matter?
Here is my full program:
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
string word = "Deleveled";
word = word.ToUpper();
bool isPalindrome = true;
for (var i = 0; i <= Math.Ceiling(word.Length / 2); i++)
{
char tmp = word[word.Length - i - 1];
if (Char.ToUpper(word[i]) != Char.ToUpper(tmp))
{
isPalindrome = false;
break;
}
}
Console.WriteLine(isPalindrome);
Console.ReadLine();
}
}
}
I would greatly appreciate it f anyone could help me understand what the issue is here?
My thanks in advance
Integer division always results in an integer; so: word.Length / 2 returns int (it rounds down).
When you call Math.Ceiling on this, you are passing an integer, but there is not Math.Ceiling(int). It has two choices: Math.Ceiling(double) and Math.Ceiling(decimal), but: it could use either, and neither of those is better from the compiler's perspective.
Frankly, it might be simpler to use the general purpose "page count" formula:
int pages = (items + pageSize - 1) / pageSize;
which in this case becomes simply:
int upperLimit = (word.Length + 1) / 2;
(note that the general purpose page count formula can also be written int pages = ((items - 1) / pageSize) + 1;, although in this case it would be harder to substitute your fixed page size)
It is because Math.Ceiling() only accepts a double datatype parameter and most of the time we unknowingly pass int or float, so just type casting those values to double will solve the issue
typecasting the "int" value to "double" value would look like this :::
Math.Ceiling((double) (15)); //here 15 is an int value which will be typecasted to double
Related
Is there a way to convert string to integers without using Multiplication. The implementation of int.Parse() also uses multiplication. I have other similar questions where you can manually convert string to int, but that also requires mulitiplying the number by its base 10. This was an interview question I had in one of interviews and I cant seem to find any answer regarding this.
If you assume a base-10 number system and substituting the multiplication by bit shifts (see here) this can be a solution for positive integers.
public int StringToInteger(string value)
{
int number = 0;
foreach (var character in value)
number = (number << 1) + (number << 3) + (character - '0');
return number;
}
See the example on ideone.
The only assumption is that the characters '0' to '9' lie directly next to each other in the character set. The digit-characters are converted to their integer value using character - '0'.
Edit:
For negative integers this version (see here) works.
public static int StringToInteger(string value)
{
bool negative = false;
int i = 0;
if (value[0] == '-')
{
negative = true;
++i;
}
int number = 0;
for (; i < value.Length; ++i)
{
var character = value[i];
number = (number << 1) + (number << 3) + (character - '0');
}
if (negative)
number = -number;
return number;
}
In general you should take errors into account like null checks, problems with other non numeric characters, etc.
It depends. Are we talking about the logical operation of multiplication, or how it's actually done in hardware?
For example, you can convert a hexadecimal (or octal, or any other base two multiplier) string into an integer "without multiplication". You can go character by character and keep oring (|) and bitshifting (<<). This avoids using the * operator.
Doing the same with decimal strings is trickier, but we still have simple addition. You can use loops with addition to do the same thing. Pretty simple to do. Or you can make your own "multiplication table" - hopefully you learned how to multiply numbers in school; you can do the same thing with a computer. And of course, if you're on a decimal computer (rather than binary), you can do the "bitshift", just like with the earlier hexadecimal string. Even with a binary computer, you can use a series of bitshifts - (a << 1) + (a << 3) is the same as a * 2 + a * 8 == a * 10. Careful about negative numbers. You can figure out plenty of tricks to make this interesting.
Of course, both of these are just multiplication in disguise. That's because positional numeric systems are inherently multiplicative. That's how that particular numeric representation works. You can have simplifications that hide this fact (e.g. binary numbers only need 0 and 1, so instead of multiplying, you can have a simple condition
- of course, what you're really doing is still multiplication, just with only two possible inputs and two possible outputs), but it's always there, lurking. << is the same as * 2, even if the hardware that does the operation can be simpler and/or faster.
To do away with multiplication entirely, you need to avoid using a positional system. For example, roman numerals are additive (note that actual roman numerals didn't use the compactification rules we have today - four would be IIII, not IV, and it fourteen could be written in any form like XIIII, IIIIX, IIXII, VVIIII etc.). Converting such a string to integer becomes very easy - just go character by character, and keep adding. If the character is X, add ten. If V, add five. If I, add one. I hope you can see why roman numerals remained popular for so long; positional numeric systems are wonderful when you need to do a lot of multiplication and division. If you're mainly dealing with addition and subtraction, roman numerals work great, and require a lot less schooling (and an abacus is a lot easier to make and use than a positional calculator!).
With assignments like this, there's a lot of hit and miss about what the interviewer actually expects. Maybe they just want to see your thought processes. Do you embrace technicalities (<< is not really multiplication)? Do you know number theory and computer science? Do you just plunge on with your code, or ask for clarification? Do you see it as a fun challenge, or as yet another ridiculous boring interview question that doesn't have any relevance to what your job is? It's impossible for us to tell you the answer the interviewer was looking for.
But I hope I at least gave you a glimpse of possible answers :)
Considering it being an interview question, performance might not be a high priority. Why not just:
private int StringToInt(string value)
{
for (int i = int.MinValue; i <= int.MaxValue; i++)
if (i.ToString() == value)
return i;
return 0; // All code paths must return a value.
}
If the passed string is not an integer, the method will throw an overflow exception.
Any multiplication can be replaced by repeated addition. So you can replace any multiply in an existing algorithm with a version that only uses addition:
static int Multiply(int a, int b)
{
bool isNegative = a > 0 ^ b > 0;
int aPositive = Math.Abs(a);
int bPositive = Math.Abs(b);
int result = 0;
for(int i = 0; i < aPositive; ++i)
{
result += bPositive;
}
if (isNegative) {
result = -result;
}
return result;
}
You could go further and write a specialized String to Int using this idea which minimizes the number of additions (negative number and error handling omitted for brevity):
static int StringToInt(string v)
{
const int BASE = 10;
int result = 0;
int currentBase = 1;
for (int digitIndex = v.Length - 1; digitIndex >= 0; --digitIndex)
{
int digitValue = (int)Char.GetNumericValue(v[digitIndex]);
int accum = 0;
for (int i = 0; i < BASE; ++i)
{
if (i == digitValue)
{
result += accum;
}
accum += currentBase;
}
currentBase = accum;
}
return result;
}
But I don't think that's worth the trouble since performance doesn't seem to be a concern here.
I want to learn C# so I started to use hackerearth and solve problems from their website but I got into some kind of problem. So I have the following code
using System;
namespace ConsoleApp6
{
class Program
{
static void Main(string[] args)
{
long N, i, answer = 1;
do
{
N = Convert.ToInt32(Console.ReadLine());
} while (N < 1 && N > 1000);
long[] A = new long[N];
for (i = 0; i < N; i++)
{
do
{
A[i] = Convert.ToInt32(Console.ReadLine());
} while (A[i] < 1 && A[i] > 1000);
}
for(i = 0; i < N; i++)
{
answer = (answer * A[i]) % (1000000007);
}
Console.WriteLine(answer);
}
}
}
When I compile it I get the correct answer and everything it's fine but when I submit it to hackerearth compiler it gives me the NZEC error. I thought I'm missing something since I just started C# some days ago so I wrote it again but in C++ and it gave me the maximum score on the website. I know that there might be some problems in my variable declarations since I didn't understand exactly how to read numbers and I hope you can help me solve this problem. Thank you!
Assuming you are stuck on the Find Product problem, as you've suspected, the input of the data is one line for N, and then one line for ALL N numbers that you need to multiply, separated by a space. You can parse the line of numbers quickly with LINQ (I would suggest you get stuck into LINQ as quickly as possible - this will get you away from the C++ imperative mindset).
How about:
using System;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
namespace ConsoleApp6
{
class Program
{
static void Main(string[] args)
{
var N = Convert.ToInt32(Console.ReadLine()); // Less than 2^31 integers to be read
var A = Console.ReadLine() // Read the line of space delimited numbers
.Split(' ') // Split out by the separator
.Select(n => Convert.ToInt64(n)) // Parse each number to long
.ToArray(); // Convert to a materialized array
Debug.Assert(A.Length == N, "Site lied to us about N numbers");
long answer = 1; // or var answer = 1L;
for(var i = 0; i < N; i++)
{
answer = (answer * A[i]) % (1000000007);
}
Console.WriteLine(answer);
}
}
}
Some notes:
The do..while has no effect - they will always exit after one pass - this because a value cannot be < 1 and > 1000 simultaneously
Note that Convert.ToInt32 parses a 32 bit int. You've defined a long (which is ALWAYS 64 bit in C#, unlike C++), so this should be Convert.ToInt64
The problem does however constrain A[i] under 10 ^ 3, so A[] can be int[], although the product could be larger, so long or even System.Numerics.BigInteger can be used for the product.
NZEC is a site specific error - it means the app crashed with a non zero process ecit code. The site also prints the actual error and stack trace further down the page.
Since you say you want to learn C# (and not just convert C code to C#), you can also LINQify the final for loop which calculates the answer from the array using .Aggregate. Aggregate supports both a seeded overload (i.e. a left fold, as it allows the return type to differ), and an unseeded overload (i.e. reduce where the return type must be the same as the input enumerable). In your case, you don't actually need to seed the answer with 1L since it can be seeded with A[0] and the next multiplication will be with A[1] since any number multiplied by 1 will be number.
var answer = A.Aggregate((subtotal, next) => (subtotal * next) % (1000000007));
I'm trying to figure out why if I change my values from 4 & 2 to something like 4 & 3, it doesn't compute the averages correctly.
I would like to know 2 things.
How to run a testcase for something as simple as this, and how to fix my code to where it will average out two numbers correctly every time.
using System;
public class MathUtils
{
public static double Average(int a, int b)
{
return (a + b) / 2;
}
public static void Main(string[] args)
{
Console.WriteLine(Average(4, 2));
}
}
// right now returns 3 which is correct
Change it to :
public static double Average(int a, int b)
{
return (a + b) / 2.0; // will be incorrect for edge case with int-overflow - see Edit
}
Reason:
If you add up two integers you get an integer. If you divide an integer by an integer you get another integer by default - not a float or double. The parts after the . are discarded.
Edit:
As Hans Passant pointed out, you can get an overflow error in case both ints add up to more than a int can handle - so casting (at least one of) them to double is the smarter move
return ((double)a + b) / 2; // .0 no longer needed.
You need to get some non-integers in the mix to get the .xxxx part as well.
As for the testcase - that depends on the testing framework you are using.
You should probably consider testcases of (int.MinValue, int.Minvalue) , (int.MaxValue, int.MaxValue) and some easy ones (0,0), (1,1), (1,2)
For how to detect the error: get some C# experience - or use intermediate variables and breakpoints and a debugger to see what goes wrong where.
This here:
public static double Average(int a, int b)
{
var summed = a + b;
var avg = summed / 2;
return avg;
}
in debugging would point out the error quite fast.
return ((double)a + b) / 2; //simple
So I'm a complete newb to unity and c# and I'm trying to make my first mobile incremental game. I know how to format a variable from (e.g.) 1000 >>> 1k however I have several variables that can go up to decillion+ so I imagine having to check every variable's value seperately up to decillion+ will be quite inefficient. Being a newb I'm not sure how to go about it, maybe a for loop or something?
EDIT: I'm checking if x is greater than a certain value. For example if it's greater than 1,000, display 1k. If it's greater than 1,000,000, display 1m...etc etc
This is my current code for checking if x is greater than 1000 however I don't think copy pasting this against other values would be very efficient;
if (totalCash > 1000)
{
totalCashk = totalCash / 1000;
totalCashTxt.text = "$" + totalCashk.ToString("F1") + "k";
}
So, I agree that copying code is not efficient. That's why people invented functions!
How about simply wrapping your formatting into function, eg. named prettyCurrency?
So you can simply write:
totalCashTxt.text = prettyCurrency(totalCashk);
Also, instead of writing ton of ifs you can handle this case with logarithm with base of 10 to determine number of digits. Example in pure C# below:
using System.IO;
using System;
class Program
{
// Very simple example, gonna throw exception for numbers bigger than 10^12
static readonly string[] suffixes = {"", "k", "M", "G"};
static string prettyCurrency(long cash, string prefix="$")
{
int k;
if(cash == 0)
k = 0; // log10 of 0 is not valid
else
k = (int)(Math.Log10(cash) / 3); // get number of digits and divide by 3
var dividor = Math.Pow(10,k*3); // actual number we print
var text = prefix + (cash/dividor).ToString("F1") + suffixes[k];
return text;
}
static void Main()
{
Console.WriteLine(prettyCurrency(0));
Console.WriteLine(prettyCurrency(333));
Console.WriteLine(prettyCurrency(3145));
Console.WriteLine(prettyCurrency(314512455));
Console.WriteLine(prettyCurrency(31451242545));
}
}
OUTPUT:
$0.0
$333.0
$3.1k
$314.5M
$31.5G
Also, you might think about introducing a new type, which implements this function as its ToString() overload.
EDIT:
I forgot about 0 in input, now it is fixed. And indeed, as #Draco18s said in his comment nor int nor long will handle really big numbers, so you can either use external library like BigInteger or switch to double which will lose his precision when numbers becomes bigger and bigger. (e.g. 1000000000000000.0 + 1 might be equal to 1000000000000000.0). If you choose the latter you should change my function to handle numbers in range (0.0,1.0), for which log10 is negative.
I need to resample big sets of data (few hundred spectra, each containing few thousand points) using simple linear interpolation.
I have created interpolation method in C# but it seems to be really slow for huge datasets.
How can I improve the performance of this code?
public static List<double> interpolate(IList<double> xItems, IList<double> yItems, IList<double> breaks)
{
double[] interpolated = new double[breaks.Count];
int id = 1;
int x = 0;
while(breaks[x] < xItems[0])
{
interpolated[x] = yItems[0];
x++;
}
double p, w;
// left border case - uphold the value
for (int i = x; i < breaks.Count; i++)
{
while (breaks[i] > xItems[id])
{
id++;
if (id > xItems.Count - 1)
{
id = xItems.Count - 1;
break;
}
}
System.Diagnostics.Debug.WriteLine(string.Format("i: {0}, id {1}", i, id));
if (id <= xItems.Count - 1)
{
if (id == xItems.Count - 1 && breaks[i] > xItems[id])
{
interpolated[i] = yItems[yItems.Count - 1];
}
else
{
w = xItems[id] - xItems[id - 1];
p = (breaks[i] - xItems[id - 1]) / w;
interpolated[i] = yItems[id - 1] + p * (yItems[id] - yItems[id - 1]);
}
}
else // right border case - uphold the value
{
interpolated[i] = yItems[yItems.Count - 1];
}
}
return interpolated.ToList();
}
Edit
Thanks, guys, for all your responses. What I wanted to achieve, when I wrote this questions, were some general ideas where I could find some areas to improve the performance. I haven't expected any ready solutions, only some ideas. And you gave me what I wanted, thanks!
Before writing this question I thought about rewriting this code in C++ but after reading comments to Will's asnwer it seems that the gain can be less than I expected.
Also, the code is so simple, that there are no mighty code-tricks to use here. Thanks to Petar for his attempt to optimize the code
It seems that all reduces the problem to finding good profiler and checking every line and soubroutine and trying to optimize that.
Thank you again for all responses and taking your part in this discussion!
public static List<double> Interpolate(IList<double> xItems, IList<double> yItems, IList<double> breaks)
{
var a = xItems.ToArray();
var b = yItems.ToArray();
var aLimit = a.Length - 1;
var bLimit = b.Length - 1;
var interpolated = new double[breaks.Count];
var total = 0;
var initialValue = a[0];
while (breaks[total] < initialValue)
{
total++;
}
Array.Copy(b, 0, interpolated, 0, total);
int id = 1;
for (int i = total; i < breaks.Count; i++)
{
var breakValue = breaks[i];
while (breakValue > a[id])
{
id++;
if (id > aLimit)
{
id = aLimit;
break;
}
}
double value = b[bLimit];
if (id <= aLimit)
{
var currentValue = a[id];
var previousValue = a[id - 1];
if (id != aLimit || breakValue <= currentValue)
{
var w = currentValue - previousValue;
var p = (breakValue - previousValue) / w;
value = b[id - 1] + p * (b[id] - b[id - 1]);
}
}
interpolated[i] = value;
}
return interpolated.ToList();
}
I've cached some (const) values and used Array.Copy, but I think these are micro optimization that are already made by the compiler in Release mode. However You can try this version and see if it will beat the original version of the code.
Instead of
interpolated.ToList()
which copies the whole array, you compute the interpolated values directly in the final list (or return that array instead). Especially if the array/List is big enough to qualify for the large object heap.
Unlike the ordinary heap, the LOH is not compacted by the GC, which means that short lived large objects are far more harmful than small ones.
Then again: 7000 doubles are approx. 56'000 bytes which is below the large object threshold of 85'000 bytes (1).
Looks to me you've created an O(n^2) algorithm. You are searching for the interval, that's O(n), then probably apply it n times. You'll get a quick and cheap speed-up by taking advantage of the fact that the items are already ordered in the list. Use BinarySearch(), that's O(log(n)).
If still necessary, you should be able to do something speedier with the outer loop, what ever interval you found previously should make it easier to find the next one. But that code isn't in your snippet.
I'd say profile the code and see where it spends its time, then you have somewhere to focus on.
ANTS is popular, but Equatec is free I think.
few suggestions,
as others suggested, use profiler to understand better where time is used.
the loop
while (breaks[x] < xItems[0])
could cause exception if x grows bigger than number of items in "breaks" list. You should use something like
while (x < breaks.Count && breaks[x] < xItems[0])
But you might not need that loop at all. Why treat the first item as special case, just start with id=0 and handle the first point in for(i) loop. I understand that id might start from 0 in this case, and [id-1] would be negative index, but see if you can do something there.
If you want to optimize for speed then you sacrifice memory size, and vice versa. You cannot usually have both, except if you make really clever algorithm. In this case, it would mean to calculate as much as you can outside loops, store those values in variables (extra memory) and use them later. For example, instead of always saying:
id = xItems.Count - 1;
You could say:
int lastXItemsIndex = xItems.Count-1;
...
id = lastXItemsIndex;
This is the same suggestion as Petar Petrov did with aLimit, bLimit....
next point, your loop (or the one Petar Petrov suggested):
while (breaks[i] > xItems[id])
{
id++;
if (id > xItems.Count - 1)
{
id = xItems.Count - 1;
break;
}
}
could probably be reduced to:
double currentBreak = breaks[i];
while (id <= lastXIndex && currentBreak > xItems[id]) id++;
and the last point I would add is to check if there is some property in your samples that is special for your problem. For example if xItems represent time, and you are sampling in regular intervals, then
w = xItems[id] - xItems[id - 1];
is constant, and you do not have to calculate it every time in the loop.
This is probably not often the case, but maybe your problem has some other property which you could use to improve performance.
Another idea is this: maybe you do not need double precision, "float" is probably faster because it is smaller.
Good luck
System.Diagnostics.Debug.WriteLine(string.Format("i: {0}, id {1}", i, id));
I hope it's release build without DEBUG defined?
Otherwise, it might depend on what exactly are those IList parameters. May be useful to store Count value instead of accessing property every time.
This is the kind of problem where you need to move over to native code.