For this exercise I'm making I want a decimal < 4096 to be written in binary form in an int array.
So for example, 4 would be {0,0,0,0,0,0,0,0,0,1,0,0}. I need this for (nearly) all integers up to 4096, so I've written this piece of code:
for(int k=0; k<4096; k++){
int[] myNumber = { (k / 2048) % 2, (k / 1024) % 2, (k / 512) % 2, (k / 256) % 2, (k / 128) % 2, (k / 64) % 2, (k / 32) % 2, (k / 16) % 2, (k / 8) % 2, (k / 4) % 2, (k / 2) % 2, (k / 1) % 2 }
/* Some processing */
}
This looks kind of ugly, so that's why I'm curious to find out if there is a more elegant way of achieving this?
For the interested reader:
I chose for the array approach of storing the binary numbers, because I need to perform some shifting and addition modulo 2. I'm using an LFSR, and this is my implementation for that:
public class LFSR {
private int[] polynomial;
public LFSR(int[] polynomial) {
this.polynomial = polynomial;
}
public int[] shiftLeft(int[] input) {
int[] result = new int[input.length];
int out = input[0];
result[input.length - 1] = out;
for (int i = input.length - 1; i > 0; i--) {
result[i - 1] = (input[i] + polynomial[i - 1] * out) % 2;
}
return result;
}
}
Any suggestions?
Some pseudo code:
While (int i = 0; i < 12; i++) {
bitarray[i] = numericalValue & 0x1;
numericalValue = numericalValue >> 1;
}
So, shifting right by one bit is division by 2, and ANDing with 1 always leaves you only with the lowest bit which is what you want.
One quick suggestion would be to switch to a byte array instead of an int array, simply to save space, as they will only be 'bits'.
With regards to improving the elegance of your solution, it is perhaps easier to use subcomputations:
int[] intToBinaryArray(int dec){
int[] res = int[12]
for(int i =0; i < 12; i++)
bitarray[i] = numericalValue & 0x1; //grab first bit only
dec /= 2;
}
return res;
}
String s = Integer.toBinaryString(int value);
Now convert the String to int[]
int[] intArray = new int[s.length()];
for (int i = 0; i < s.length(); i++) {
intArray[i] = Character.digit(s.charAt(i), 10);
}
This is somewhat shorter ;)
int[] bits = new int[13];
String bin = Integer.toBinaryString(8192 + value);
for(int i = 1; i < bin.length(); i++) {
bits[i-1] = bin.charAt(i)-'0';
}
"Elegance" is in the eye of the beholder, but I'd start by creating a method to avoid repetition and improve clarity:
int[] myNumber = { getBit(k, 12), getBit(k, 11), ... };
I personally feel this is the "most elegant" way to get a particular bit:
int getBit(int v, int i)
{
return v >> i & 1;
}
Then you have to decide whether you want to keep repeating yourself with the calls to getBit or whether you'd rather just use a single while or for loop to populate the whole array. You'd think it'd be quicker the way you've got it written, but there's good chance the JIT compiler automatically unrolls your loop for you if you use a loop like Jochen suggests.
Since this particular operation is entirely self contained, you might even want to create a special method for it:
int[] getBits(int v, int num)
{
int[] arr = new int[num];
for(int i=0; i<num; i++) {
arr[i] = getBit(v, num - i - 1);
}
return arr;
}
That makes it easier to unit test, and you can reuse it in a variety of situations.
public int[] toBin (int num)
{
int[] ret = new int[8];
for (int i = 7, p = 0; i>=0; i--, p++)
{
ret[i] = (num/2**p) % 2;
}
return ret;
}
You could use the bit shift operator together withbthe bitwise AND operator as follows. Note bitCount - i - 1 is needed to get the high bit first.
final int bitCount =12; // Increase to support greater than 4095
int[] number = new int[bitCount];
for( int i = 0; i < bitCount; i++ )
{
number[i] = ( k >>> ( bitCount - i - 1 ) ) & 1;
}
Related
I have to write a function that multiplies two numbers represented by two int arrays (so I can't use ArrayLists or something).
Each digit of a number is represented by an int between 0 and 9 in the array, no element should be greater than that.
The first element of the array represents the last digit of the number and so on, therefore the number 1234 would be {4,3,2,1} as an array in this function.
I thought multiplying those arrays that way would be similar to long multiplication, so I tried to implement it in a similar way: You multiply every digit of the first array with every digit of the second one and store the rest if the result is equal or greater to 10 and then add it to the next digit. However, I seem to have done something wrong in the code (maybe the calculation of the rest??) because the result of my function is not correct: I tested it with 190 times 86 (represented by the arrays {0,9,1} and {6,8}) and get 15342 ({2,4,3,5,1}) instead of the actual result 16340 (which would be {0,4,3,6,1}).
Can somebody here help me out with this please? This is my code:
import java.util.Arrays;
public class MultiplyArrays {
static int[ ] times(int[ ] a, int[ ] b) {
int[] arr = new int[a.length + b.length - 1];//arr should be the result of a*b. The result shouldn't be shorter than that
int tmp = 0;//stores the rest of two-digit numbers
for(int i = b.length - 1; i >= 0; i--){
for(int j = 0; j < a.length; j++){//should multiply all digits of a with the current index of b
arr[i + j] = (arr[i + j] + (b[i] * a[j] + tmp)) % 10;//sets the value of the (i+j)th index in arr to the multiplication of two numbers from a and b adding the rest tmp.
if((arr[i + j] + b[i] * a[j] + tmp) < 10){//if this number is less than 10, there is no rest
tmp = 0;
}
else{//otherwise, the rest should be the second digit
tmp = (((arr[i + j] + (b[i] * a[j] + tmp))) - ((arr[i + j] + (b[i] * a[j] + tmp)) % 10)) / 10;//something in the formula for the rest is wrong, I guess
}
}
}
if(tmp != 0){//if the last number of the array containing the result is calculated and there still is a rest, a new array with one more digit is created
int[] arr2 = new int[arr.length + 1];
for(int i = arr.length - 1; i >= 0; i--){//the new array copies all numbers from the old array
arr2[i] = arr[i];
arr2[arr2.length - 1] = tmp;//the last space is the rest now
}
return arr2;
}
else{//if there is no rest after calculating the last number of arr, a new array isn't needed
return arr;
}
}
public static void main(String[] args) {//test the function with 190 * 86
int[] a = {0,9,1};
int[] b = {6,8};
System.out.println(Arrays.toString(times(a,b)));
}
}
Maybe this comes from the fact that your indices in the for-loops of the times()-method are incrementing AND decrementing.
The i is going down and the j is going up.
Also, in the second for loop, you should only increment to 'a.length - 1', not to 'a.length'.
Arbitrary precision multiplication is more complex than it seems, and contains corner cases (like one and zero). Fortunately, Java has an arbitrary precision type; BigInteger. In order to use it here, you would need to create two additional methods; one for converting an int[] to a BigInteger, and the second the convert a BigInteger to an int[].
The first can be done with a single loop adding each digit at index i (multiplied by 10i) to a running total. Like,
private static BigInteger fromArray(int[] arr) {
BigInteger bi = BigInteger.ZERO;
for (int i = 0, pow = 1; i < arr.length; pow *= 10, i++) {
bi = bi.add(BigInteger.valueOf(arr[i] * pow));
}
return bi;
}
And the second can be done a number of ways, but the easiest is simply to convert the BigInteger to a String to get the length() - once you've done that, you know the length of the output array - and can populate the digits in it. Like,
private static int[] toArray(BigInteger bi) {
String s = bi.toString();
int len = s.length();
int[] r = new int[len];
for (int i = 0; i < len; i++) {
r[i] = s.charAt(len - i - 1) - '0';
}
return r;
}
Finally, call those two methods and let BigInteger perform the multiplication. Like,
static int[] times(int[] a, int[] b) {
BigInteger ba = fromArray(a), bb = fromArray(b);
return toArray(ba.multiply(bb));
}
Running your original main with those changes outputs (as expected)
[0, 4, 3, 6, 1]
Well, your thought would work with addition, but on multiplication you multiply each digit of one with the whole number of the other and step one digit to the left (*10) each time you change the multiplication digit of the first number.
So you might brought something into confusion.
I just solved it in a more structured way, running the debugger will hopefully explain the process. In the solutions you can remove the trailing / leading zero by checking the digit if 0 and replace the array with one of length - 1.
The solutions are:
With conditions mentioned (numbers in reverse order):
public static void main(String[] args) {
int[] a = {3,2,1};
int[] b = {9,8};
System.out.println("Result is: " + Arrays.toString(calculate(a, b)));
}
private static int[] calculate(int[] a, int[] b) {
// final result will be never longer than sum of number lengths + 1
int[] finalResult = new int[a.length + b.length + 1];
int position = 0;
for(int i = 0; i < a.length; i++) {
int[] tempResult = multiplyWithOther(a[i], b);
addToFinalResult(finalResult, tempResult, position);
position++;
}
return finalResult;
}
private static int[] multiplyWithOther(int number, int[] otherArray) {
// The number cannot be more digits than otherArray.length + 1, so create a temp array with size +1
int[] temp = new int[otherArray.length + 1];
// Iterate through the seconds array and multiply with current number from first
int remainder = 0;
for(int i = 0; i < otherArray.length; i++) {
int result = number * otherArray[i];
result += remainder;
remainder = result / 10;
temp[i] = result % 10;
}
// Add remainder (even if 0) to start
temp[temp.length - 1] = remainder;
return temp;
}
private static void addToFinalResult(int[] finalResult, int[] tempResult, int position) {
int remainder = 0;
for(int i = 0; i < tempResult.length; i++) {
int currentValue = tempResult[i];
int storedValue = finalResult[i + position];
int sum = storedValue + currentValue + remainder;
remainder = sum / 10;
finalResult[i + position] = sum % 10;
}
finalResult[position + tempResult.length] = remainder;
}
And with numbers in normal order in array:
public static void main(String[] args) {
int[] a = {1,2,3,6};
int[] b = {8, 9, 1};
System.out.println("Result is: " + Arrays.toString(calculate(a, b)));
}
private static int[] calculate(int[] a, int[] b) {
// final result will be never longer than sum of number lengths + 1
int[] finalResult = new int[a.length + b.length + 1];
int positionFromEnd = 0;
for(int i = 1; i <= a.length; i++) {
int[] tempResult = multiplyWithOther(a[a.length-i], b);
addToFinalResult(finalResult, tempResult, positionFromEnd);
positionFromEnd++;
}
return finalResult;
}
private static int[] multiplyWithOther(int number, int[] otherArray) {
// The number cannot be more digits than otherArray.length + 1, so create a temp array with size +1
int[] temp = new int[otherArray.length + 1];
// Iterate through the seconds array and multiply with current number from first
int remainder = 0;
for(int i = 1; i <= otherArray.length; i++) {
int result = number * otherArray[otherArray.length - i];
result += remainder;
remainder = result / 10;
temp[otherArray.length - i +1] = result % 10;
}
// Add remainder (even if 0) to start
temp[0] = remainder;
return temp;
}
private static void addToFinalResult(int[] finalResult, int[] tempResult, int positionFromEnd) {
int remainder = 0;
for(int i = 1; i <= tempResult.length; i++) {
int currentValue = tempResult[tempResult.length - i];
int storedValue = finalResult[finalResult.length - positionFromEnd - i];
int sum = storedValue + currentValue + remainder;
remainder = sum / 10;
finalResult[finalResult.length - positionFromEnd - i] = sum % 10;
}
finalResult[finalResult.length - positionFromEnd - tempResult.length - 1] = remainder;
}
I am trying to write a function that will accept an array length, and return a "ripple out" array.
For example:
rippleOut(3) would return [0,1,0]
rippleOut(6) would return [0,1,2,2,1,0]
This is what I've got so far. It works, but I'm sure that there is a more efficient way to do it:
public int[] rippleOut(int size){
int[] output = new int[size];
int middle = 0;
boolean even = false;
if(size%2==0){
middle = (size/2-1);
even = true;
} else {
middle = (int)Math.floor(size/2);
}
for(int i = middle; i>0; i--){
output[i] = middle - (middle-i);
if (even){
output[middle+(middle - i+1)] = middle - (middle-i);
} else {
output[middle+(middle - i)] = middle - (middle-i);
}
}
return output;
}
This is a Java 8 version:
int size = 11;
int odd = (size % 2 == 0) ? 0 : 1;
int mid = (size / 2) - 1;
int[] output = IntStream.range(0, size - 1)
.map(i -> (i > mid) ? mid + (mid - i) + odd : i).toArray();
IntStream.of(output).forEach(System.out::print);
There is at least a simpler way to write it, I haven't compared the performance:
public static int[] rippleOut(int x) {
int[] r = new int[x];
// everything except the middle of an odd array
for (int i = 0; i < (x >> 1); i++) {
r[i] = i;
r[x - i - 1] = i;
}
// fix middle
if ((x & 1) == 1)
r[x >> 1] = x >> 1;
return r;
}
Feel free to replace the bitmath with "normal" math if you're more comfortable with that, it's not integral to the solution. I just like it this way, that's all.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I received a codility test the other day for a job, as such I've been practicing using some of the problems from their training page
Link
Unfortunately, I've only been able to get 83/100 on the Tape-Equilibrium question:
A non-empty zero-indexed array A consisting of N integers is given. Array A represents numbers on a tape.
Any integer P, such that 0 < P < N, splits this tape into two non−empty parts: A\[0], A\[1], …, A\[P − 1] and A\[P], A\[P + 1], …, A\[N − 1].
The difference between the two parts is the value of: |(A\[0] + A\[1] + … + A\[P − 1]) − (A\[P] + A\[P + 1] + … + A\[N − 1])|
In other words, it is the absolute difference between the sum of the first part and the sum of the second part.
Write a function that, given a non-empty zero-indexed array A of N integers, returns the minimal difference that can be achieved.
Example: A[0] = 3 A[1] = 1 A[2] = 2 A[3] = 4 A[4] = 3
We can split this tape in four places:
P = 1, difference = |3 − 10| = 7
P = 2, difference = |4 − 9| = 5
P = 3, difference = |6 − 7| = 1
P = 4, difference = |10 − 3| = 7
In this case I would return 1 as it is the smallest difference.
N is an int, range [2..100,000];
each element of A is an int, range [−1,000..1,000]. It needs to be O(n) time complexity,
My code is as follows:
import java.math.*;
class Solution {
public int solution(int[] A) {
long sumright = 0;
long sumleft = 0;
long ans;
for (int i =1;i<A.length;i++)
sumright += A[i];
sumleft = A[0];
ans =Math.abs(Math.abs(sumright)+Math.abs(sumleft));
for (int P=1; P<A.length; P++)
{
if (Math.abs(Math.abs(sumleft) - Math.abs(sumright))<ans)
ans = Math.abs(Math.abs(sumleft) - Math.abs(sumright));
sumleft += A[P];
sumright -=A[P];
}
return (int) ans;
}
I went a bit mad with the Math.abs. The two test areas it fails on are "double" (which I think is two values, -1000 and 1000, and "small".
http://codility.com/demo/results/demo9DAQ4T-2HS/
Any help would be appreciated, I want to make sure I'm not making any basic mistakes.
Your solution is already O(N). You need to remove the abs from sumleft and sumright.
if (Math.abs( sumleft - sumright ) < ans)
{
ans = Math.abs( sumleft - sumright );
}
Also before the second for loop,
ans =Math.abs( sumleft - sumright );
It should work.
100%, in Javascript
var i, ll = A.length, tot = 0, upto = 0, min = Number.MAX_INT;
for (i=0; i<ll; i++) tot += A[i];
for (i=0; i<ll-1; i++)
{
upto += A[i];
var a1 = upto, a2 = tot - a1, dif = Math.abs(a1 - a2);
if (dif < min)
min = dif;
}
return min;
I found perfect solution for TapeEquilibrium by Cheng on Codesays. I translated it to Java for anybody who is curious about it. Cheng's solution hit 100% on Codility
public int solution(int[] A) {
// write your code in Java SE 7
int N = A.length;
int sum1 = A[0];
int sum2 = 0;
int P = 1;
for (int i = P; i < N; i++) {
sum2 += A[i];
}
int diff = Math.abs(sum1 - sum2);
for (; P < N-1; P++) {
sum1 += A[P];
sum2 -= A[P];
int newDiff = Math.abs(sum1 - sum2);
if (newDiff < diff) {
diff = newDiff;
}
}
return diff;
}
Consider this 100/100 solution in Ruby:
# Algorithm:
#
# * Compute the sum of all elements.
# * Iterate over elements, maintain left and right weights appropriately.
# * Maintain a minimum of `(left - right).abs`.
def solution(ar)
sum = ar.inject(:+)
left = ar[0]
right = sum - left
min_diff = (right - left).abs
1.upto(ar.size - 2) do |i|
left += ar[i]
right -= ar[i]
diff = (right - left).abs
min_diff = [min_diff, diff].min
end
# Result.
min_diff
end
#--------------------------------------- Tests
def test
sets = []
sets << ["1", 1, [1]]
sets << ["31", 2, [3, 1]]
sets << ["312", 0, [3, 1, 2]]
sets << ["[1]*4", 0, [1]*4]
sets << ["[1]*5", 1, [1]*5]
sets << ["sample", 1, [3, 1, 2, 4, 3]]
sets.each do |name, expected, ar|
out = solution(ar)
raise "FAILURE at test #{name.inspect}: #{out.inspect} != #{expected.inspect}" if out != expected
end
puts "SUCCESS: All tests passed"
end
Here is my 100/100 Python solution:
def TapeEquilibrium(A):
left = A[0]
right = sum(A[1::])
diff = abs(left - right)
for p in range(1, len(A)):
ldiff = abs(left - right)
if ldiff < diff:
diff = ldiff
left += A[p]
right -= A[p]
return diff
Some C# for ya.
using System;
// you can also use other imports, for example:
// using System.Collections.Generic;
class Solution
{
public int solution(int[] A)
{
// write your code in C# with .NET 2.0
int sumRight = 0;
for(int i=0; i<A.Length; i++)
{
sumRight += A[i];
}
int sumLeft = 0;
int min = int.MaxValue;
for(int P=1; P<A.Length; P++)
{
int currentP = A[P-1];
sumLeft += currentP;
sumRight -= currentP;
int diff = Math.Abs(sumLeft - sumRight);
if(diff < min)
{
min = diff;
}
}
return min;
}
}
Here is my solution (Java) that i just wrote up for it, very simple to understand and is O(n) and does 100% score on codility:
public int solution(int[] A) {
if (A.length == 2)
return Math.abs(A[0]-A[1]);
int [] s1 = new int[A.length-1];
s1[0] = A[0];
for (int i=1;i<A.length-1;i++) {
s1[i] = s1[i-1] + A[i];
}
int [] s2 = new int[A.length-1];
s2[A.length-2] = A[A.length-1];
for (int i=A.length-3;i>=0;i--) {
s2[i] = s2[i+1] + A[i+1];
}
int finalSum = Integer.MAX_VALUE;
for (int j=0;j<s1.length;j++) {
int sum = Math.abs(s1[j]-s2[j]);
if (sum < finalSum)
finalSum = sum;
}
return finalSum;
}
I was doing the same task, but couldn't get better than 50 something points. My algorithm was too slow. So, I searched for a hint and found your solution. I've used the idea of summing the elements in the array only once and got 100/100. My solution is in JavaScript, but it can be easily transformed into Java. You can go to my solution by using the link below.
http://codility.com/demo/results/demo8CQZY5-RQ2/
Please take a look at my code and let me know if you have some questions. I'd be very happy to help you.
function solution(A) {
// write your code in JavaScript 1.6
var p = 1;
var sumPartOne = A[p - 1];
var sumPartTwo = sumUpArray(A.slice(p, A.length));
var diff = Math.abs(sumPartOne - sumPartTwo);
for(p; p < A.length - 1; p++) {
sumPartOne += A[p];
sumPartTwo -= A[p];
var tempDiff = Math.abs(sumPartOne - sumPartTwo);
if(tempDiff < diff) {
diff = tempDiff;
}
}
return diff;
}
function sumUpArray(A) {
var sum = 0;
for(var i = 0; i < A.length; i++) {
sum += A[i];
}
return sum;
}
I was also running into issues getting 83% just like CTB, but for my C++ solution.
For my code, my tape sum was evaluating AFTER updating rightsum and leftsum, but therein lies the problem. In this case, the second loop should evaluate up until P=A.size()-1. Otherwise, you will end up evaluating a tape pair where everything is added to leftsum, and nothing is added to rightsum (which is not allowed according to the problem description).
One possibly nice aspect about my solution below (now fixed to get 100%) is that it does one less evaluation of the sum, compared to a couple solutions above.
#include <stdlib.h>
int solution(vector<int> &A) {
int sumright = 0;
int sumleft;
int result;
for (int i=1; i<A.size(); i++) {
sumright += A[i];
}
sumleft = A[0];
result = abs(sumleft-sumright);
for (int i=1; i<A.size()-1; i++) {
sumleft += A[i];
sumright -= A[i];
if (abs(sumleft-sumright)<result) {
result = abs(sumleft-sumright);
}
}
return result;
}
My C# code 100/100:
using System;
class Solution
{
public int solution (int[] A)
{
int min = int.MaxValue;
int sumLeft = 0;
int sumRight = ArraySum (A);
for (int i = 1; i < A.Length; i++)
{
int val = A[i - 1];
sumLeft += val;
sumRight -= val;
int diff = Math.Abs (sumLeft - sumRight);
if (min > diff)
{
min = diff;
}
}
return min;
}
private int ArraySum (int[] array)
{
int sum = 0;
for (int i = 0; i < array.Length; i++)
{
sum += array[i];
}
return sum;
}
}
100% Score : Tape Equilibrium : Codility : JavaScript
function solution(A) {
// write your code in JavaScript (ECMA-262, 5th edition)
var p=0;
var index=0;
var leftSum=0;
var rightSum=0;
var totalSum=0;
var N = A.length;
var last_minimum=100000;
if(A.length == 2)
return (Math.abs(A[0]-A[1]));
if(A.length == 1)
return (Math.abs(A[0]));
for(index=0; index < N; index++)
totalSum = totalSum + A[index];
for(p=1; p <= N-1; p++){
leftSum += A[p - 1];
rightSum = totalSum - leftSum;
current_min = Math.abs(leftSum - rightSum);
last_minimum = current_min < last_minimum ? current_min : last_minimum;
if (last_minimum === 0)
break;
}
return last_minimum;
}
Similar algorithm of CTB posted above:
This code get 100% score in JAVA;
class Solution {
public int solution(int[] A) {
int [] diff;
int sum1;
int sum2=0;
int ans, localMin;
diff = new int[A.length-1];
//AT P=1 sum1=A[0]
sum1=A[0];
for (int i =1;i<A.length;i++){
sum2 += A[i];
}
ans = Math.abs(sum1- sum2);
for (int p= 1;p<A.length;p++){
localMin= Math.abs(sum1- sum2);
if( localMin < ans ){
ans = localMin;
}
//advance the sum1, sum2
sum1+= A[p];
sum2-= A[p];
diff[p-1]=localMin;
}
return (getMinVal(diff));
}
public int getMinVal(int[] arr){
int minValue = arr[0];
for(int i=1;i<arr.length;i++){
if(arr[i] < minValue){
minValue = arr[i];
}
}
return minValue;
}
}
this is my 100 score code in Python maybe will help you. You should take a look at if statment its prevent from "double error" if You have N=2 A=[-1,1] when you make sum You get 0 but it should return |-1-1|=|-2|=2
def solution(A):
a=A
tablica=[]
tablica1=[]
suma=0
if len(a) == 2:
return abs(a[0]-a[1])
for x in a:
suma = suma + x
tablica.append(suma)
for i in range(len(tablica)-1):
wynik=(suma-2*tablica[i])
tablica1.append(abs(wynik))
tablica1.sort()
return tablica1[0]
100% Score in C Program : Codility - TapeEquilibrium
int solution(int A[], int N) {
int i, leftSum, rightSum, last_minimum, current_min;
//initialise variables to store the right and left partition sum
//of the divided tape
//begin dividing from position 1 (2nd element) in a 0-based array
//therefore the left partition sum will start with
//just the value of the 1st element
leftSum = A[0];
//begin dividing from position 1 (2nd element) in a 0-based array
//therefore the right partition initial sum will start with
//the sum of all array element excluding the 1st element
rightSum = 0;
i = 1;
while (i < N) {
rightSum += A[i];
i++;
}
//get the initial sum difference between the partitions
last_minimum = abs(leftSum - rightSum);
if (last_minimum == 0) return last_minimum; //return immediately if 0 diff found
//begins shifting the divider starting from position 2 (3rd element)
//and evaluate the diff, return immediately if 0 diff found
//otherwise shift till the end of array length
i = 2; //shift the divider
while (i < N){
leftSum += A[i-1]; //increase left sum
rightSum -= A[i-1]; //decrease right sum
current_min = abs(leftSum - rightSum); //evaluate current diff
if (current_min == 0) return current_min; //return immediately if 0 diff
if (last_minimum > current_min) last_minimum = current_min; //evaluate
//lowest min
i++; //shift the divider
}
return last_minimum;
}
This is 100 score in ruby
def solution(a)
right = 0
left = a[0]
ar = Array.new
for i in 1...a.count
right += a[i]
end
for i in 1...a.count
check = (left - right).abs
ar[i-1] = check
left += a[i]
right -= a[i]
end
find = ar.min
if a.count == 2
find = (a[0]-a[1]).abs
end
find
end
this is what I did!!!
// write your code in C# with .NET 2.0
using System;
class Solution
{
public int solution(int[] A)
{
int sumRight = 0, sumleft, result;
for(int i=1; i<A.Length; i++)
{
sumRight += A[i];
}
int sumLeft = A[0];
int min = int.MaxValue;
for(int P=1; P<A.Length; P++)
{
int currentP = A[P-1];
sumLeft += currentP;
sumRight -= currentP;
int diff = Math.Abs(sumLeft - sumRight);
if(diff < min)
{
min = diff;
}
}
return min;
}
}
Here is an easy solution in C++ (100/100):
#include <numeric>
#include <stdlib.h>
int solution(vector<int> &A)
{
int left = 0;
int right = 0;
int bestDifference = 0;
int difference = 0;
left = std::accumulate( A.begin(), A.begin() + 1, 0);
right = std::accumulate( A.begin() + 1, A.end(), 0);
bestDifference = abs(left - right);
for( size_t i = 2; i < A.size(); i++ )
{
left += A[i - 1];
right -= A[i - 1];
difference = abs(left - right);
if( difference < bestDifference )
{
bestDifference = difference;
}
}
return bestDifference;
}
100% Score in C Program : Codility
int solution(int A[], int N) {
long p;
long index;
long leftSum;
long rightSum;
long totalSum=0;
long last_minimum=100000;
long current_min;
if(N==2) return abs(A[0]-A[1]);
if(N==1) return abs(A[0]);
for(index=0; index < N; index++)
totalSum = totalSum + A[index];
leftSum = 0; rightSum = 0;
for (p = 1; p <= N-1; p++) {
leftSum += A[p - 1];
rightSum = totalSum - leftSum;
current_min = abs((long)(leftSum - rightSum));
last_minimum = current_min < last_minimum ? current_min : last_minimum;
if (last_minimum == 0)
break;
}
return last_minimum;
}
int abs(int n) {
return (n >= 0) ? n : (-(n));
}
def TapeEquilibrium (A):
n = len(A)
pos = 0
diff= [0]
if len(A) == 2: return abs(a[0]-a[1])
for i in range(1,n-1,1):
diff.sort()
d = (sum(A[i+1:n-1]) - sum(A[0:i]))
diff.append(abs(d) + 1)
if abs(d) < diff[1]:
pos = i + 1
return pos
public static int solution(int[] A)
{
int SumLeft=0;
int SumRight = 0;
int bestValue=0;
for (int i = 0; i < A.Length; i++)
{
SumRight += A[i];
}
bestValue=SumRight;
for(int i=0;i<A.Length;i++)
{
SumLeft += A[i];
SumRight-=A[i];
if (Math.Abs(SumLeft - SumRight) < bestValue)
{
bestValue = Math.Abs(SumLeft - SumRight);
}
}
return bestValue;
}
The start and end points of the indexes are not correct - hence the 'doubles' test fails, since this test only has a start and end point. Other tests may pass if the set of numbers used does not happen to contain a dependency on the endpoints.
Let N = A.length
The sumright is sums from the right. The maximum value of this should exclude A[N] but include A[0].
sumleft - sums from the left. The maximum value of this should include A[0] but exclude A[N].
So the max sumright is incorrectly calculated in the first loop.
Similarly in the second loop the max value of sumleft is not calculated since A[0] is excluded.
Nadesri points out this problem, but I thought it would be useful if I explicitly pointed out the errors in your code, since that was what you originally asked.
Here is my solution written in c99.
https://codility.com/demo/results/demoQ5UWYG-5KG/
I am stuck on this merge sort method. I an not trying to do it recursively but I can't get this one to work for me. I think there is a minor change that needs to be done to get it to work. Any suggestions?
protected static void merge(long[] a, long[] workSpace, int lowPtr, int highPtr, int upperBound) {
int j = 0; // workspace index
int lowerBound = lowPtr;
int mid = highPtr-1;
int n = upperBound-lowerBound+1; // # of items
while(lowPtr <= mid && highPtr <= upperBound)
if(a[lowPtr] < a[highPtr] )
workSpace[j++] = a[lowPtr++];
else
workSpace[j++] = a[highPtr++];
while(lowPtr <= mid)
workSpace[j++] = a[lowPtr++];
while(highPtr <= upperBound)
workSpace[j++] = a[highPtr++];
for(j=0; j<n; j++)
a[lowerBound+j] = workSpace[j];
I suspect that it has to do with how you use this routine externally. I could not see an error after 5 minute staring at it, so I tested it and it seems to work fine.
You don't need to know c++ (which is what I happen to have a handy compiler for on this machine)
int main() {
long a[10] = {1,2,3,4,15,5,11,12,13,14}; // two sorted halves to merge
long * temp = new long[10];
for (int i = 0; i < 10; i++)
{
cout << a[i] << ","; // printout before merge
}
cout << endl;
merge(a, temp, 0, 5, 9); // 0-4 and 5-9
for (int i = 0; i < 10; i++)
{
cout << a[i] << ","; // printout after merge
}
}
output:
1,2,3,4,15,5,11,12,13,14,
1,2,3,4,5,11,12,13,14,15,
Some more outputs just to convince you:
1,2,6,14,15,5,11,12,32,100,
1,2,5,6,11,12,14,15,32,100,
1,2,100,143,1500,5,112,121,320,1000,
1,2,5,100,112,121,143,320,1000,1500,
12,20,100,143,179,5,12,121,320,430,
5,12,12,20,100,121,143,179,320,430,
If you have the binary number 10110 how can I get it to return 5? e.g a number that tells how many bits are used? There are some likewise examples listed below:
101 should return 3
000000011 should return 2
11100 should return 5
101010101 should return 9
How can this be obtained the easiest way in Java? I have come up with the following method but can i be done faster:
public static int getBitLength(int value)
{
if (value == 0)
{
return 0;
}
int l = 1;
if (value >>> 16 > 0) { value >>= 16; l += 16; }
if (value >>> 8 > 0) { value >>= 8; l += 8; }
if (value >>> 4 > 0) { value >>= 4; l += 4; }
if (value >>> 2 > 0) { value >>= 2; l += 2; }
if (value >>> 1 > 0) { value >>= 1; l += 1; }
return l;
}
Easiest?
32 - Integer.numberOfLeadingZeros(value)
If you are looking for algorithms, the implementors of the Java API agree with your divide-and-conquer bitshifting approach:
public static int numberOfLeadingZeros(int i) {
if (i == 0)
return 32;
int n = 1;
if (i >>> 16 == 0) { n += 16; i <<= 16; }
if (i >>> 24 == 0) { n += 8; i <<= 8; }
if (i >>> 28 == 0) { n += 4; i <<= 4; }
if (i >>> 30 == 0) { n += 2; i <<= 2; }
n -= i >>> 31;
return n;
}
Edit: As a reminder to those who trust in the accuracy of floating point calculations, run the following test harness:
public static void main(String[] args) {
for (int i = 0; i < 64; i++) {
long x = 1L << i;
check(x);
check(x-1);
}
}
static void check(long x) {
int correct = 64 - Long.numberOfLeadingZeros(x);
int floated = (int) (1 + Math.floor(Math.log(x) / Math.log(2)));
if (floated != correct) {
System.out.println(Long.toString(x, 16) + " " + correct + " " + floated);
}
}
The first detected deviation is:
ffffffffffff 48 49
Unfortunately there is no Integer.bitLength() method that would give you the answer directly.
An analogous method exists for BigInteger, so you could use that one:
BigInteger.valueOf(value).bitLength()
Constructing the BigInteger object will make it somewhat less efficient, but that will only matter if you do it many millions of times.
You want to compute the base 2 logarithm of the number - specifically: 1 + floor(log2(value))
Java has a Math.log method which uses base e, so you can do:
1 + Math.floor(Math.log(value) / Math.log(2))
Be careful what you ask for. One very fast technique is to do a table lookup:
int bittable [] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, ... };
int numbits (int v)
{
return bittable [v];
}
where bittable contains an entry for every int. Of course that has complications for negative values. A more practical way would be to count the bits in bitfields of the number
int bittable [16] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
int numbits (int v)
{
int s = 0;
while (v != 0)
{
s += bittable [v & 15];
v >>= 4;
}
return s;
}
You really just want to find the position of the highest bit that is a 1. See this page, under the heading "Finding integer log base 2 of an integer (aka the position of the highest bit set)".
From here, a way to do it with just bitwise-and and addition:
int GetHighestBitPosition(int value) {
if (value == 0) return 0;
int position = 1;
if ((value & 0xFFFF0000) == 0) position += 16;
if ((value & 0xFF00FF00) == 0) position += 8;
if ((value & 0xF0F0F0F0) == 0) position += 4;
if ((value & 0xCCCCCCCC) == 0) position += 2;
if ((value & 0xAAAAAAAA) == 0) position += 1;
return position;
}
Integer.toBinaryString(value).length()
I think the rounded-up log_2 of that number will give you what you need.
Something like:
return (int)(Math.log(value) / Math.log(2)) + 1;
int CountBits(uint value)
{
for (byte i = 32; i > 0; i--)
{
var b = (uint)1 << (i - 1);
if ((value & b) == b)
return i;
}
return 0;
}
If you are looking for the fastest (and without a table, which is certainly faster), this is probably the one:
public static int bitLength(int i) {
int len = 0;
while (i != 0) {
len += (i & 1);
i >>>= 1;
}
return len;
}
Another solution is to use the length() of a BitSet which according to the API
Returns the "logical size" ... the index of
the highest set bit ... plus one.
To use the BitSet you need to create an array. So it is not as simple as starting with a pure int. But you get it out of the JDK box - tested and supported. It would look like this:
public static int bitsCount(int i) {
return BitSet.valueOf(new long[] { i }).length();
}
Applied to the examples in the question:
bitsCount(0b101); // 3
bitsCount(0b000000011); // 2
bitsCount(0b11100); // 5
bitsCount(0b101010101); // 9
When asking for bits the BitSetseems to me to be the appropriate data structure.