I am initializing array size to 1 but I am updating it in the subsequent lines. It is not even storing the first element in the array as the array size is 1 initially but I expected it would. Could someone provide me with an explanation? Here is the code:
class Program
{
static void Main(string[] args)
{
int num = int.Parse(Console.ReadLine());
Console.Write("The binary number for " + num + " is ");
int size = 1;
int[] binary = new int[size];
size = 0;
while(num>=1)
{
if (num % 2 == 0)
binary[size++] = 0;
else
binary[size++] = 1;
//size += 1;
num = num / 2;
}
for (int i = size - 1; i >= 0; i--)
{
Console.Write(binary[i]);
}
Console.WriteLine();
Console.Write("The Compliment of this number is ");
for (int i = size - 1; i >= 0; i--)
{
if (binary[i] == 0)
binary[i] = 1;
else
binary[i] = 0;
}
for (int i = size - 1; i >= 0; i--)
{
Console.Write(binary[i]);
}
Console.WriteLine();
Console.ReadKey();
}
}
You cannot resize an array, it always has the length you gave it to during initialization (1 in your case).
I think the problem is specifically in your expectation that you can update an array size "in the subsequent lines."
When you make the array here:
int[] binary = new int[size];
Then the size is set in stone
When you call something like:
binary[size++] = 0;
This will not actually increase the number of slots in your array. In fact, that code is only changing the index where you are looking to read or write values. I can see that your code is going to quickly go out of bounds of the array (if you ask for anything but binary[0]
It turns out this array is a tricky data type to use; arrays have a fixed size on creation. You want something that can grow!
So you can either:
-Use an array, but declare that it's size is Math.Ciel(logbase2(yourNumber)) to make sure you will have enough space
-Use a data structure that can grow, like a string or list
-You can create a new array every time you need it bigger and assign it like:
binary = new int[++size];
binary[size-1]=whatever
Good luck, hope this helps!
Please check below code, this code try to compute birthday conflict possibility. To my surprise, if i execute those code with sequence, the result is expected around 0.44; but if try on PLinq, the result is 0.99.
Anyone can explain the result?
public static void BirthdayConflict(int num = 5, int people = 300) {
int N = 100000;
int act = 0;
Random r = new Random();
Action<int> action = (a) => {
List<int> p = new List<int>();
for (int i = 0; i < people; i++)
{
p.Add(r.Next(364) + 1);
}
p.Sort();
bool b = false;
for (int i = 0; i < 300; i++)
{
if (i + num -1 >= people) break;
if (p[i] == p[i + num -1])
b = true;
}
if (b)
Interlocked.Increment(ref act);
// act++;
};
// Result is around 0.99 - which is not OK
// Parallel.For( 0, N, action);
//Result is around 0.44 - which is OK
for (int i = 0; i < N; i++)
{
action(0);
}
Console.WriteLine(act / 100000.0);
Console.ReadLine();
}
You're using a shared (between threads) instance System.Random. It's not thread-safe then you're getting wrong results (well actually it just doesn't work and it'll return 0). From MSDN:
If your app calls Random methods from multiple threads, you must use a synchronization object to ensure that only one thread can access the random number generator at a time. If you don't ensure that the Random object is accessed in a thread-safe way, calls to methods that return random numbers return 0.
Simple (but not so efficient for parallel execution) solution is to use a lock:
lock (r)
{
for (int i = 0; i < people; i++)
{
p.Add(r.Next(364) + 1);
}
}
To improve performance (but you should measure) you may use multiple instances of System.Random, be careful to initialize each one with a different seed.
I find a useful explanation why random does not work under multi-thread, although it was original for Java, still can be benefitical.
I have some large arrays of 2D data elements. A and B aren't equally sized dimensions.
A) is between 5 and 20
B) is between 1000 and 100000
The initialization time is no problem as its only going to be lookup tables for realtime application, so performance on indexing elements from knowing value A and B is crucial. The data stored is currently a single byte-value.
I was thinking around these solutions:
byte[A][B] datalist1a;
or
byte[B][A] datalist2a;
or
byte[A,B] datalist1b;
or
byte[B,A] datalist2b;
or perhaps loosing the multidimension as I know the fixed size and just multiply the to values before looking it up.
byte[A*Bmax + B] datalist3;
or
byte[B*Amax + A] datalist4;
What I need is to know, what datatype/array structure to use for most efficient lookup in C# when I have this setup.
Edit 1
the first two solutions were supposed to be multidimensional, not multi arrays.
Edit 2
All data in the smallest dimension is read at each lookup, but the large one is only used for indexing once at a time.
So its something like - Grab all A's from sample B.
I'd bet on the jagged arrays, unless the Amax or Bmax are a power of 2.
I'd say so, because a jagged array needs two indexed accesses, thus very fast. The other forms implies a multiplication, either implicit or explicit. Unless that multiplication is a simple shift, I think could be a bit heavier than a couple of indexed accesses.
EDIT: Here is the small program used for the test:
class Program
{
private static int A = 10;
private static int B = 100;
private static byte[] _linear;
private static byte[,] _square;
private static byte[][] _jagged;
unsafe static void Main(string[] args)
{
//init arrays
_linear = new byte[A * B];
_square = new byte[A, B];
_jagged = new byte[A][];
for (int i = 0; i < A; i++)
_jagged[i] = new byte[B];
//set-up the params
var sw = new Stopwatch();
byte b;
const int N = 100000;
//one-dim array (buffer)
sw.Restart();
for (int i = 0; i < N; i++)
{
for (int r = 0; r < A; r++)
{
for (int c = 0; c < B; c++)
{
b = _linear[r * B + c];
}
}
}
sw.Stop();
Console.WriteLine("linear={0}", sw.ElapsedMilliseconds);
//two-dim array
sw.Restart();
for (int i = 0; i < N; i++)
{
for (int r = 0; r < A; r++)
{
for (int c = 0; c < B; c++)
{
b = _square[r, c];
}
}
}
sw.Stop();
Console.WriteLine("square={0}", sw.ElapsedMilliseconds);
//jagged array
sw.Restart();
for (int i = 0; i < N; i++)
{
for (int r = 0; r < A; r++)
{
for (int c = 0; c < B; c++)
{
b = _jagged[r][c];
}
}
}
sw.Stop();
Console.WriteLine("jagged={0}", sw.ElapsedMilliseconds);
//one-dim array within unsafe access (and context)
sw.Restart();
for (int i = 0; i < N; i++)
{
for (int r = 0; r < A; r++)
{
fixed (byte* offset = &_linear[r * B])
{
for (int c = 0; c < B; c++)
{
b = *(byte*)(offset + c);
}
}
}
}
sw.Stop();
Console.WriteLine("unsafe={0}", sw.ElapsedMilliseconds);
Console.Write("Press any key...");
Console.ReadKey();
Console.WriteLine();
}
}
Multidimensional ([,]) arrays are nearly always the slowest, unless under a heavy random access scenario. In theory they shouldn't be, but it's one of the CLR oddities.
Jagged arrays ([][]) are nearly always faster than multidimensional arrays; even under random access scenarios. These have a memory overhead.
Singledimensional ([]) and algebraic arrays ([y * stride + x]) are the fastest for random access in safe code.
Unsafe code is, normally, fastest in all cases (provided you don't pin it repeatedly).
The only useful answer to "which X is faster" (for all X) is: you have to do performance tests that reflect your requirements.
And remember to consider, in general*:
Maintenance of the program. If this is not a quick one off, a slightly slower but maintainable program is a better option in most cases.
Micro benchmarks can be deceptive. For instance a tight loop just reading from a collection might be optimised away in ways not possible when real work is being done.
Additionally consider that you need to look at the complete program to decide where to optimise. Speeding up a loop by 1% might be useful for that loop, but if it is only 1% of the complete runtime then it is not making much differences.
* But all rules have exceptions.
On most modern computers, arithmetic operations are far, far faster than memory lookups.
If you fetch a memory address that isn't in a cache or where the out of order execution pulls from the wrong place you are looking at 10-100 clocks, a pipelined multiply is 1 clock.
The other issue is cache locality.
byte[BAmax + A] datalist4; seems like the best bet if you are accessing with A's varying sequentially.
When datalist4[bAmax + a] is accessed, the computer will usually start pulling in datalist4[bAmax + a+ 64/sizeof(dataListType)], ... +128 ... etc, or if it detects a reverse iteration, datalist4[bAmax + a - 64/sizeof(dataListType)]
Hope that helps!
May be best way for u will be use HashMap
Dictionary?
How can the following simple implementation of sum be faster?
private long sum( int [] a, int begin, int end ) {
if( a == null ) {
return 0;
}
long r = 0;
for( int i = begin ; i < end ; i++ ) {
r+= a[i];
}
return r;
}
EDIT
Background is in order.
Reading latest entry on coding horror, I came to this site: http://codility.com which has this interesting programming test.
Anyway, I got 60 out of 100 in my submission, and basically ( I think ) is because this implementation of sum, because those parts where I failed are the performance parts. I'm getting TIME_OUT_ERROR's
So, I was wondering if an optimization in the algorithm is possible.
So, no built in functions or assembly would be allowed. This my be done in C, C++, C#, Java or pretty much in any other.
EDIT
As usual, mmyers was right. I did profile the code and I saw most of the time was spent on that function, but I didn't understand why. So what I did was to throw away my implementation and start with a new one.
This time I've got an optimal solution [ according to San Jacinto O(n) -see comments to MSN below - ]
This time I've got 81% on Codility which I think is good enough. The problem is that I didn't take the 30 mins. but around 2 hrs. but I guess that leaves me still as a good programmer, for I could work on the problem until I found an optimal solution:
Here's my result.
I never understood what is those "combinations of..." nor how to test "extreme_first"
I don't think your problem is with the function that's summing the array, it's probably that you're summing the array WAY to frequently. If you simply sum the WHOLE array once, and then step through the array until you find the first equilibrium point you should decrease the execution time sufficiently.
int equi ( int[] A ) {
int equi = -1;
long lower = 0;
long upper = 0;
foreach (int i in A)
upper += i;
for (int i = 0; i < A.Length; i++)
{
upper -= A[i];
if (upper == lower)
{
equi = i;
break;
}
else
lower += A[i];
}
return equi;
}
Here is my solution and I scored 100%
public static int solution(int[] A)
{
double sum = A.Sum(d => (double)d);
double leftSum=0;
for (int i = 0; i < A.Length; i++){
if (leftSum == (sum-leftSum-A[i])) {
return i;
}
else {
leftSum = leftSum + A[i];
}
}
return -1;
}
If this is based on the actual sample problem, your issue isn't the sum. Your issue is how you calculate the equilibrium index. A naive implementation is O(n^2). An optimal solution is much much better.
This code is simple enough that unless a is quite small, it's probably going to be limited primarily by memory bandwidth. As such, you probably can't hope for any significant gain by working on the summing part itself (e.g., unrolling the loop, counting down instead of up, executing sums in parallel -- unless they're on separate CPUs, each with its own access to memory). The biggest gain will probably come from issuing some preload instructions so most of the data will already be in the cache by the time you need it. The rest will just (at best) get the CPU to hurry up more, so it waits longer.
Edit: It appears that most of what's above has little to do with the real question. It's kind of small, so it may be difficult to read, but, I tried just using std::accumulate() for the initial addition, and it seemed to think that was all right:
Some tips:
Use a profiler to identify where you're spending a lot of time.
Write good performance tests so that you can tell the exact effect of every single change you make. Keep careful notes.
If it turns out that the bottleneck is the checks to ensure that you're dereferencing a legal address inside the array, and you can guarantee that begin and end are in fact both inside the array, then consider fixing the array, making a pointer to the array, and doing the algorithm in pointers rather than arrays. Pointers are unsafe; they do not spend any time checking to make sure you're still inside the array, so therefore they can be somewhat faster. But you take responsibility then for ensuring that you do not corrupt every byte of memory in the address space.
I don't believe the problem is in the code you provided, but somehow the bigger solution must be suboptimal. This code looks good for calculating the sum of one slice of the array, but maybe it's not what you need to solve the whole problem.
Probably the fastest you could get would be to have your int array 16-byte aligned, stream 32 bytes into two __m128i variables (VC++) and call _mm_add_epi32 (again, a VC++ intrinsic) on the chunks. Reuse one of the chunks to keep adding into it and on the final chunk extract your four ints and add them the old fashioned way.
The bigger question is why simple addition is a worthy candidate for optimization.
Edit: I see it's mostly an academic exercise. Perhaps I'll give it a go tomorrow and post some results...
In C# 3.0, my computer and my OS this is faster as long as you can guarantee that 4 consecutive numbers won't overflow the range of an int, probably because most additions are done using 32-bit math.
However using a better algorithm usually provides higher speed up than any micro-optimization.
Time for a 100 millon elements array:
4999912596452418 -> 233ms (sum)
4999912596452418 -> 126ms (sum2)
private static long sum2(int[] a, int begin, int end)
{
if (a == null) { return 0; }
long r = 0;
int i = begin;
for (; i < end - 3; i+=4)
{
//int t = ;
r += a[i] + a[i + 1] + a[i + 2] + a[i + 3];
}
for (; i < end; i++) { r += a[i]; }
return r;
}
This won't help you with an O(n^2) algorithm, but you can optimize your sum.
At a previous company, we had Intel come by and give us optimization tips. They had one non-obvious and somewhat cool trick. Replace:
long r = 0;
for( int i = begin ; i < end ; i++ ) {
r+= a[i];
}
with
long r1 = 0, r2 = 0, r3 = 0, r4 = 0;
for( int i = begin ; i < end ; i+=4 ) {
r1+= a[i];
r2+= a[i + 1];
r3+= a[i + 2];
r4+= a[i + 3];
}
long r = r1 + r2 + r3 + r4;
// Note: need to be clever if array isn't divisible by 4
Why this is faster:
In the original implementation, your variable r is a bottleneck. Every time through the loop, you have to pull data from memory array a (which takes a couple cycles), but you can't do multiple pulls in parallel, because the value of r in the next iteration of the loop depends on the value of r in this iteration of the loop. In the second version, r1, r2, r3, and r4 are independent, so the processor can hyperthread their execution. Only at the very end do they come together.
Here is a thought:
private static ArrayList equi(int[] A)
{
ArrayList answer = new ArrayList();
//if(A == null) return -1;
if ((answer.Count == null))
{
answer.Add(-1);
return answer;
}
long sum0 = 0, sum1 = 0;
for (int i = 0; i < A.Length; i++) sum0 += A[i];
for (int i = 0; i < A.Length; i++)
{
sum0 -= A[i];
if (i > 0) { sum1 += A[i - 1]; }
if (sum1 == sum0) answer.Add(i);
//return i;
}
//return -1;
return answer;
}
If you are using C or C++ and develop for modern desktop systems and are willing to learn some assembler or learn about GCC intrinsics, you could use SIMD instructions.
This library is an example of what is possible for float and double arrays, similar results should be possible for integer arithmetic since SSE has integer instructions as well.
In C++, the following:
int* a1 = a + begin;
for( int i = end - begin - 1; i >= 0 ; i-- )
{
r+= a1[i];
}
might be faster.
The advantage is that we compare against zero in the loop.
Of course, with a really good optimizer there should be no difference at all.
Another possibility would be
int* a2 = a + end - 1;
for( int i = -(end - begin - 1); i <= 0 ; i++ )
{
r+= a2[i];
}
here we traversing the items in the same order, just not comparing to end.
I did the same naive implementation and here's my O(n) solution. I did not use the IEnumerable Sum method because it was not available at Codility. My solution still doesn't check for overflow in case the input has large numbers so it's failing that particular test on Codility.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
var list = new[] {-7, 1, 5, 2, -4, 3, 0};
Console.WriteLine(equi(list));
Console.ReadLine();
}
static int equi(int[] A)
{
if (A == null || A.Length == 0)
return -1;
if (A.Length == 1)
return 0;
var upperBoundSum = GetTotal(A);
var lowerBoundSum = 0;
for (var i = 0; i < A.Length; i++)
{
lowerBoundSum += (i - 1) >= 0 ? A[i - 1] : 0;
upperBoundSum -= A[i];
if (lowerBoundSum == upperBoundSum)
return i;
}
return -1;
}
private static int GetTotal(int[] ints)
{
var sum = 0;
for(var i=0; i < ints.Length; i++)
sum += ints[i];
return sum;
}
}
}
100% O(n) solution in C
int equi ( int A[], int n ) {
long long sumLeft = 0;
long long sumRight = 0;
int i;
if (n <= 0) return -1;
for (i = 1; i < n; i++)
sumRight += A[i];
i = 0;
do {
if (sumLeft == sumRight)
return i;
sumLeft += A[i];
if ((i+1) < n)
sumRight -= A[i+1];
i++;
} while (i < n);
return -1;
}
Probably not perfect but it passes their tests anyway :)
Can't say I'm a big fan of Codility though - it is an interesting idea, but I found the requirements a little too vague. I think I'd be more impressed if they gave you requirements + a suite of unit tests that test those requirements and then asked you to write code. That's how most TDD happens anyway. I don't think doing it blind really gains anything other than allowing them to throw in some corner cases.
private static int equi ( int[] A ) {
if (A == null || A.length == 0)
return -1;
long tot = 0;
int len = A.length;
for(int i=0;i<len;i++)
tot += A[i];
if(tot == 0)
return (len-1);
long partTot = 0;
for(int i=0;i<len-1;i++)
{
partTot += A[i];
if(partTot*2+A[i+1] == tot)
return i+1;
}
return -1;
}
I considered the array as a bilance so if the equilibrium index exist then half of the weight is on the left. So I only compare the partTot (partial total) x 2 with the total weight of the array.
the Alg takes O(n) + O(n)
100% correctness and performance of this code is tested
Private Function equi(ByVal A() As Integer) As Integer
Dim index As Integer = -1
If A.Length > 0 And Not IsDBNull(A) Then
Dim sumLeft As Long = 0
Dim sumRight As Long = ArraySum(A)
For i As Integer = 0 To A.Length - 1
Dim val As Integer = A(i)
sumRight -= val
If sumLeft = sumRight Then
index = i
End If
sumLeft += val
Next
End If
Return index
End Function
Just some thought, not sure if accessing the pointer directly be faster
int* pStart = a + begin;
int* pEnd = a + end;
while (pStart != pEnd)
{
r += *pStart++;
}
{In Pascal + Assembly}
{$ASMMODE INTEL}
function equi (A : Array of longint; n : longint ) : longint;
var c:Longint;
label noOverflow1;
label noOverflow2;
label ciclo;
label fine;
label Over;
label tot;
Begin
Asm
DEC n
JS over
XOR ECX, ECX {Somma1}
XOR EDI, EDI {Somma2}
XOR EAX, EAX
MOV c, EDI
MOV ESI, n
tot:
MOV EDX, A
MOV EDX, [EDX+ESI*4]
PUSH EDX
ADD ECX, EDX
JNO nooverflow1
ADD c, ECX
nooverflow1:
DEC ESI
JNS tot;
SUB ECX, c
SUB EDI, c
ciclo:
POP EDX
SUB ECX, EDX
CMP ECX, EDI
JE fine
ADD EDI, EDX
JNO nooverflow2
DEC EDI
nooverflow2:
CMP EAX, n
JA over
INC EAX
JMP ciclo
over:
MOV EAX, -1
fine:
end;
End;
This got me 100% in Javascript:
function solution(A) {
if (!(A) || !(Array.isArray(A)) || A.length < 1) {
return -1;
}
if (A.length === 1) {
return 0;
}
var sum = A.reduce(function (a, b) { return a + b; }),
lower = 0,
i,
val;
for (i = 0; i < A.length; i++) {
val = A[i];
if (((sum - lower) - val) === (lower)) {
return i;
}
lower += val;
}
return -1;
}
Here is my answer with with explanations on how to go about it. It will get you 100%
class Solution
{
public int solution(int[] A)
{
long sumLeft = 0; //Variable to hold sum of elements to the left of the current index
long sumRight = 0; //Variable to hold sum of elements to the right of the current index
long sum = 0; //Variable to hold sum of all elements in the array
long leftHolder = 0; //Variable that holds the sum of all elements to the left of the current index, including the element accessed by the current index
//Calculate the total sum of all elements in the array and store it in the sum variable
for (int i = 0; i < A.Length; i++)
{
//sum = A.Sum();
sum += A[i];
}
for (int i = 0; i < A.Length; i++)
{
//Calculate the sum of all elements before the current element plus the current element
leftHolder += A[i];
//Get the sum of all elements to the right of the current element
sumRight = sum - leftHolder;
//Get the sum of all elements of elements to the left of the current element.We don't include the current element in this sum
sumLeft = sum - sumRight - A[i];
//if the sum of the left elements is equal to the sum of the right elements. Return the index of the current element
if (sumLeft == sumRight)
return i;
}
//Otherwise return -1
return -1;
}
}
This may be old, but here is solution in Golang with 100% pass rate:
package solution
func Solution(A []int) int {
// write your code in Go 1.4
var left int64
var right int64
var equi int
equi = -1
if len(A) == 0 {
return equi
}
left = 0
for _, el := range A {
right += int64(el)
}
for i, el := range A {
right -= int64(el)
if left == right {
equi = i
}
left += int64(el)
}
return equi
}