How to make an 8 bit Binary Calculator - java

So I made an 8-bit binary calculator but I kinda cheated with the following methods.
public static int[] convertToBinary(int b){
String toStr = Integer.toBinaryString(b);
String fStr = ("00000000"+toStr).substring(toStr.length());
String[] array = fStr.split("");
int[] finalArray = new int[array.length-1];
for(int i = 0; i < finalArray.length; i++){
finalArray[i] = Integer.parseInt(array[i+1]);
}
return finalArray;
}
public static int[] addBin(int a[], int b[]){
int[] added = new int[a.length];
for(int i = added.length - 1; i >= 0; i--){
if((a[i]+b[i] > 1)){
System.out.println("Error: overflow");
break;
}else{
added[i] = (a[i]+b[i]);
}
}
return added;
}
My question is how do I convert an int to binary and how do I add two binary numbers.

Is this what you're looking for?
public static int[] convertToBinary(int b) {
if (b < 0 || b > 255) {
throw new IllegalArgumentException("Argument must be between 0 and 255");
}
int[] result = new int[8];
// Working from the right side of the array to the left, we store the bits.
for (int i = 7; i >= 0; i--) {
result[i] = b & 1; // Same as b % 2
b >>>= 1; // Same as b /= 2
}
return result;
}
public static int[] addBin(int[] a, int[] b) {
if (a.length != 8 || b.length != 8) {
throw new IllegalArgumentException("Arguments must be octets");
}
for (int i = 0; i < 8; i++) {
if (a[i] < 0 || a[i] > 1 || b[i] < 0 || b[i] > 1) {
throw new IllegalArgumentException("Arguments must be binary");
}
}
// Working from the right side of the array to the left, we find the sum.
int[] result = new int[8];
for (int i = 7; i >= 1; i--) {
int sum = result[i] + a[i] + b[i]; // result[i] holds the carry from the last addition.
result[i] = sum & 1; // Same as sum % 2
result[i - 1] = sum >>> 1; // Same as sum / 2. This is the carry.
}
// The highest-order bit (bit 0) is handled as a special case to detect overflow.
int sum = result[0] + a[0] + b[0];
result[0] = sum & 1;
if (sum >>> 1 > 0) {
throw new IllegalArgumentException("Overflow");
}
return result;
}

Related

Count the minimum number of jumps required for a frog to get to the other side of a river

I work with a Codility problem provided below,
The Fibonacci sequence is defined using the following recursive formula:
F(0) = 0
F(1) = 1
F(M) = F(M - 1) + F(M - 2) if M >= 2
A small frog wants to get to the other side of a river. The frog is initially located at one bank of the river (position −1) and wants to get to the other bank (position N). The frog can jump over any distance F(K), where F(K) is the K-th Fibonacci number. Luckily, there are many leaves on the river, and the frog can jump between the leaves, but only in the direction of the bank at position N.
The leaves on the river are represented in an array A consisting of N integers. Consecutive elements of array A represent consecutive positions from 0 to N − 1 on the river. Array A contains only 0s and/or 1s:
0 represents a position without a leaf;
1 represents a position containing a leaf.
The goal is to count the minimum number of jumps in which the frog can get to the other side of the river (from position −1 to position N). The frog can jump between positions −1 and N (the banks of the river) and every position containing a leaf.
For example, consider array A such that:
A[0] = 0
A[1] = 0
A[2] = 0
A[3] = 1
A[4] = 1
A[5] = 0
A[6] = 1
A[7] = 0
A[8] = 0
A[9] = 0
A[10] = 0
The frog can make three jumps of length F(5) = 5, F(3) = 2 and F(5) = 5.
Write a function:
class Solution { public int solution(int[] A); }
that, given an array A consisting of N integers, returns the minimum number of jumps by which the frog can get to the other side of the river. If the frog cannot reach the other side of the river, the function should return −1.
For example, given:
A[0] = 0
A[1] = 0
A[2] = 0
A[3] = 1
A[4] = 1
A[5] = 0
A[6] = 1
A[7] = 0
A[8] = 0
A[9] = 0
A[10] = 0
the function should return 3, as explained above.
Assume that:
N is an integer within the range [0..100,000];
each element of array A is an integer that can have one of the following values: 0, 1.
Complexity:
expected worst-case time complexity is O(N*log(N));
expected worst-case space complexity is O(N) (not counting the storage required for input arguments).
I wrote the following solution,
class Solution {
private class Jump {
int position;
int number;
public int getPosition() {
return position;
}
public int getNumber() {
return number;
}
public Jump(int pos, int number) {
this.position = pos;
this.number = number;
}
}
public int solution(int[] A) {
int N = A.length;
List<Integer> fibs = getFibonacciNumbers(N + 1);
Stack<Jump> jumps = new Stack<>();
jumps.push(new Jump(-1, 0));
boolean[] visited = new boolean[N];
while (!jumps.isEmpty()) {
Jump jump = jumps.pop();
int position = jump.getPosition();
int number = jump.getNumber();
for (int fib : fibs) {
if (position + fib > N) {
break;
} else if (position + fib == N) {
return number + 1;
} else if (!visited[position + fib] && A[position + fib] == 1) {
visited[position + fib] = true;
jumps.add(new Jump(position + fib, number + 1));
}
}
}
return -1;
}
private List<Integer> getFibonacciNumbers(int N) {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 2; i++) {
list.add(i);
}
int i = 2;
while (list.get(list.size() - 1) <= N) {
list.add(i, (list.get(i - 1) + list.get(i - 2)));
i++;
}
for (i = 0; i < 2; i++) {
list.remove(i);
}
return list;
}
public static void main(String[] args) {
int[] A = new int[11];
A[0] = 0;
A[1] = 0;
A[2] = 0;
A[3] = 1;
A[4] = 1;
A[5] = 0;
A[6] = 1;
A[7] = 0;
A[8] = 0;
A[9] = 0;
A[10] = 0;
System.out.println(solution(A));
}
}
However, while the correctness seems good, the performance is not high enough. Is there a bug in the code and how do I improve the performance?
Got 100% with simple BFS:
public class Jump {
int pos;
int move;
public Jump(int pos, int move) {
this.pos = pos;
this.move = move;
}
}
public int solution(int[] A) {
int n = A.length;
List < Integer > fibs = fibArray(n + 1);
Queue < Jump > positions = new LinkedList < Jump > ();
boolean[] visited = new boolean[n + 1];
if (A.length <= 2)
return 1;
for (int i = 0; i < fibs.size(); i++) {
int initPos = fibs.get(i) - 1;
if (A[initPos] == 0)
continue;
positions.add(new Jump(initPos, 1));
visited[initPos] = true;
}
while (!positions.isEmpty()) {
Jump jump = positions.remove();
for (int j = fibs.size() - 1; j >= 0; j--) {
int nextPos = jump.pos + fibs.get(j);
if (nextPos == n)
return jump.move + 1;
else if (nextPos < n && A[nextPos] == 1 && !visited[nextPos]) {
positions.add(new Jump(nextPos, jump.move + 1));
visited[nextPos] = true;
}
}
}
return -1;
}
private List < Integer > fibArray(int n) {
List < Integer > fibs = new ArrayList < > ();
fibs.add(1);
fibs.add(2);
while (fibs.get(fibs.size() - 1) + fibs.get(fibs.size() - 2) <= n) {
fibs.add(fibs.get(fibs.size() - 1) + fibs.get(fibs.size() - 2));
}
return fibs;
}
You can apply knapsack algorithms to solve this problem.
In my solution I precomputed fibonacci numbers. And applied knapsack algorithm to solve it. It contains duplicate code, did not have much time to refactor it. Online ide with the same code is in repl
import java.util.*;
class Main {
public static int solution(int[] A) {
int N = A.length;
int inf=1000000;
int[] fibs={1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025};
int[] moves = new int[N+1];
for(int i=0; i<=N; i++){
moves[i]=inf;
}
for(int i=0; i<fibs.length; i++){
if(fibs[i]-1<N && A[fibs[i]-1]==1){
moves[ fibs[i]-1 ] = 1;
}
if(fibs[i]-1==N){
moves[N] = 1;
}
}
for(int i=0; i<N; i++){
if(A[i]==1)
for(int j=0; j<fibs.length; j++){
if(i-fibs[j]>=0 && moves[i-fibs[j]]!=inf && moves[i]>moves[i-fibs[j]]+1){
moves[i]=moves[i-fibs[j]]+1;
}
}
System.out.println(i + " => " + moves[i]);
}
for(int i=N; i<=N; i++){
for(int j=0; j<fibs.length; j++){
if(i-fibs[j]>=0 && moves[i-fibs[j]]!=inf && moves[i]>moves[i-fibs[j]]+1){
moves[i]=moves[i-fibs[j]]+1;
}
}
System.out.println(i + " => " + moves[i]);
}
if(moves[N]==inf) return -1;
return moves[N];
}
public static void main(String[] args) {
int[] A = new int[4];
A[0] = 0;
A[1] = 0;
A[2] = 0;
A[3] = 0;
System.out.println(solution(A));
}
}
Javascript 100%
function solution(A) {
function fibonacciUntilNumber(n) {
const fib = [0,1];
while (true) {
let newFib = fib[fib.length - 1] + fib[fib.length - 2];
if (newFib > n) {
break;
}
fib.push(newFib);
}
return fib.slice(2);
}
A.push(1);
const fibSet = fibonacciUntilNumber(A.length);
if (fibSet.includes(A.length)) return 1;
const reachable = Array.from({length: A.length}, () => -1);
fibSet.forEach(jump => {
if (A[jump - 1] === 1) {
reachable[jump - 1] = 1;
}
})
for (let index = 0; index < A.length; index++) {
if (A[index] === 0 || reachable[index] > 0) {
continue;
}
let minValue = 100005;
for (let jump of fibSet) {
let previousIndex = index - jump;
if (previousIndex < 0) {
break;
}
if (reachable[previousIndex] > 0 && minValue > reachable[previousIndex]) {
minValue = reachable[previousIndex];
}
}
if (minValue !== 100005) {
reachable[index] = minValue + 1;
}
}
return reachable[A.length - 1];
}
Python 100% answer.
For me the easiest solution was to locate all leaves within one fib jump of -1. Then consider each of these leaves to be index[0] and find all jumps from there.
Each generation or jump is recorded in a set until a generation contains len(A) or no more jumps can be found.
def gen_fib(n):
fn = [0,1]
i = 2
s = 2
while s < n:
s = fn[i-2] + fn[i-1]
fn.append(s)
i+=1
return fn
def new_paths(A, n, last_pos, fn):
"""
Given an array A of len n.
From index last_pos which numbers in fn jump to a leaf?
returns list: set of indexes with leaves.
"""
paths = []
for f in fn:
new_pos = last_pos + f
if new_pos == n or (new_pos < n and A[new_pos]):
paths.append(new_pos)
return path
def solution(A):
n = len(A)
if n < 3:
return 1
# A.append(1) # mark final jump
fn = sorted(gen_fib(100000)[2:]) # Fib numbers with 0, 1, 1, 2.. clipped to just 1, 2..
# print(fn)
paths = set([-1]) # locate all the leaves that are one fib jump from the start position.
jump = 1
while True:
# Considering each of the previous jump positions - How many leaves from there are one fib jump away
paths = set([idx for pos in paths for idx in new_paths(A, n, pos, fn)])
# no new jumps means game over!
if not paths:
break
# If there was a result in the new jumps record that
if n in paths:
return jump
jump += 1
return -1
https://app.codility.com/demo/results/training4GQV8Y-9ES/
https://github.com/niall-oc/things/blob/master/codility/fib_frog.py
Got 100%- solution in C.
typedef struct state {
int pos;
int step;
}state;
int solution(int A[], int N) {
int f1 = 0;
int f2 = 1;
int count = 2;
// precalculating count of maximum possible fibonacci numbers to allocate array in next loop. since this is C language we do not have flexible dynamic structure as in C++
while(1)
{
int f3 = f2 + f1;
if(f3 > N)
break;
f1 = f2;
f2 = f3;
++count;
}
int fib[count+1];
fib[0] = 0;
fib[1] = 1;
int i = 2;
// calculating fibonacci numbers in array
while(1)
{
fib[i] = fib[i-1] + fib[i-2];
if(fib[i] > N)
break;
++i;
}
// reversing the fibonacci numbers because we need to create minumum jump counts with bigger jumps
for(int j = 0, k = count; j < count/2; j++,k--)
{
int t = fib[j];
fib[j] = fib[k];
fib[k] = t;
}
state q[N];
int front = 0 ;
int rear = 0;
q[0].pos = -1;
q[0].step = 0;
int que_s = 1;
while(que_s > 0)
{
state s = q[front];
front++;
que_s--;
for(int i = 0; i <= count; i++)
{
int nextpo = s.pos + fib[i];
if(nextpo == N)
{
return s.step+1;
}
else if(nextpo > N || nextpo < 0 || A[nextpo] == 0){
continue;
}
else
{
q[++rear].pos = nextpo;
q[rear].step = s.step + 1;
que_s++;
A[nextpo] = 0;
}
}
}
return -1;
}
//100% on codility Dynamic Programming Solution. https://app.codility.com/demo/results/training7WSQJW-WTX/
class Solution {
public int solution(int[] A) {
int n = A.length + 1;
int dp[] = new int[n];
for(int i=0;i<n;i++) {
dp[i] = -1;
}
int f[] = new int[100005];
f[0] = 1;
f[1] = 1;
for(int i=2;i<100005;i++) {
f[i] = f[i - 1] + f[i - 2];
}
for(int i=-1;i<n;i++) {
if(i == -1 || dp[i] > 0) {
for(int j=0;i+f[j] <n;j++) {
if(i + f[j] == n -1 || A[i+f[j]] == 1) {
if(i == -1) {
dp[i + f[j]] = 1;
} else if(dp[i + f[j]] == -1) {
dp[i + f[j]] = dp[i] + 1;
} else {
dp[i + f[j]] = Math.min(dp[i + f[j]], dp[i] + 1);
}
}
}
}
}
return dp[n - 1];
}
}
Ruby 100% solution
def solution(a)
f = 2.step.inject([1,2]) {|acc,e| acc[e] = acc[e-1] + acc[e-2]; break(acc) if acc[e] > a.size + 1;acc }.reverse
mins = []
(a.size + 1).times do |i|
next mins[i] = -1 if i < a.size && a[i] == 0
mins[i] = f.inject(nil) do |min, j|
k = i - j
next min if k < -1
break 1 if k == -1
next min if mins[k] < 0
[mins[k] + 1, min || Float::INFINITY].min
end || -1
end
mins[a.size]
end
I have translated the previous C solution to Java and find the performance is improved.
import java.util.*;
class Solution {
private static class State {
int pos;
int step;
public State(int pos, int step) {
this.pos = pos;
this.step = step;
}
}
public static int solution(int A[]) {
int N = A.length;
int f1 = 0;
int f2 = 1;
int count = 2;
while (true) {
int f3 = f2 + f1;
if (f3 > N) {
break;
}
f1 = f2;
f2 = f3;
++count;
}
int[] fib = new int[count + 1];
fib[0] = 0;
fib[1] = 1;
int i = 2;
while (true) {
fib[i] = fib[i - 1] + fib[i - 2];
if (fib[i] > N) {
break;
}
++i;
}
for (int j = 0, k = count; j < count / 2; j++, k--) {
int t = fib[j];
fib[j] = fib[k];
fib[k] = t;
}
State[] q = new State[N];
for (int j = 0; j < N; j++) {
q[j] = new State(-1,0);
}
int front = 0;
int rear = 0;
// q[0].pos = -1;
// q[0].step = 0;
int que_s = 1;
while (que_s > 0) {
State s = q[front];
front++;
que_s--;
for (i = 0; i <= count; i++) {
int nextpo = s.pos + fib[i];
if (nextpo == N) {
return s.step + 1;
}
//
else if (nextpo > N || nextpo < 0 || A[nextpo] == 0) {
continue;
}
//
else {
q[++rear].pos = nextpo;
q[rear].step = s.step + 1;
que_s++;
A[nextpo] = 0;
}
}
}
return -1;
}
}
JavaScript with 100%.
Inspired from here.
function solution(A) {
const createFibs = n => {
const fibs = Array(n + 2).fill(null)
fibs[1] = 1
for (let i = 2; i < n + 1; i++) {
fibs[i] = fibs[i - 1] + fibs[i - 2]
}
return fibs
}
const createJumps = (A, fibs) => {
const jumps = Array(A.length + 1).fill(null)
let prev = null
for (i = 2; i < fibs.length; i++) {
const j = -1 + fibs[i]
if (j > A.length) break
if (j === A.length || A[j] === 1) {
jumps[j] = 1
if (prev === null) prev = j
}
}
if (prev === null) {
jumps[A.length] = -1
return jumps
}
while (prev < A.length) {
for (let i = 2; i < fibs.length; i++) {
const j = prev + fibs[i]
if (j > A.length) break
if (j === A.length || A[j] === 1) {
const x = jumps[prev] + 1
const y = jumps[j]
jumps[j] = y === null ? x : Math.min(y, x)
}
}
prev++
while (prev < A.length) {
if (jumps[prev] !== null) break
prev++
}
}
if (jumps[A.length] === null) jumps[A.length] = -1
return jumps
}
const fibs = createFibs(26)
const jumps = createJumps(A, fibs)
return jumps[A.length]
}
const A = [0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0]
console.log(A)
const s = solution(A)
console.log(s)
You should use a QUEUE AND NOT A STACK. This is a form of breadth-first search and your code needs to visit nodes that were added first to the queue to get the minimum distance.
A stack uses the last-in, first-out mechanism to remove items while a queue uses the first-in, first-out mechanism.
I copied and pasted your exact code but used a queue instead of a stack and I got 100% on codility.
100% C++ solution
More answers in my github
Inspired from here
Solution1 : Bottom-Top, using Dynamic programming algorithm (storing calculated values in an array)
vector<int> getFibonacciArrayMax(int MaxNum) {
if (MaxNum == 0)
return vector<int>(1, 0);
vector<int> fib(2, 0);
fib[1] = 1;
for (int i = 2; fib[fib.size()-1] + fib[fib.size() - 2] <= MaxNum; i++)
fib.push_back(fib[i - 1] + fib[i - 2]);
return fib;
}
int solution(vector<int>& A) {
int N = A.size();
A.push_back(1);
N++;
vector<int> f = getFibonacciArrayMax(N);
const int oo = 1'000'000;
vector<int> moves(N, oo);
for (auto i : f)
if (i - 1 >= 0 && A[i-1])
moves[i-1] = 1;
for (int pos = 0; pos < N; pos++) {
if (A[pos] == 0)
continue;
for (int i = f.size()-1; i >= 0; i--) {
if (pos + f[i] < N && A[pos + f[i]]) {
moves[pos + f[i]] = min(moves[pos]+1, moves[pos + f[i]]);
}
}
}
if (moves[N - 1] != oo) {
return moves[N - 1];
}
return -1;
}
Solution2: Top-Bottom using set container:
#include <set>
int solution2(vector<int>& A) {
int N = A.size();
vector<int> fib = getFibonacciArrayMax(N);
set<int> positions;
positions.insert(N);
for (int jumps = 1; ; jumps++)
{
set<int> new_positions;
for (int pos : positions)
{
for (int f : fib)
{
// return jumps if we reach to the start point
if (pos - (f - 1) == 0)
return jumps;
int prev_pos = pos - f;
// we do not need to calculate bigger jumps.
if (prev_pos < 0)
break;
if (prev_pos < A.size() && A[prev_pos])
new_positions.insert(prev_pos);
}
}
if (new_positions.size() == 0)
return -1;
positions = new_positions;
}
return -1;
}

How to improve code that returns an int array with sorted index, of a given int array?

I have made a method that I believe gets an array a, take the three first values in the array and finds the values from low to high. Then those values are put in an new array and send back sorted. This means that with for example:
int[] a = {9,5,7} returns {1,2,0}. This because a[1] = 5, a[2] = 7 og a[0] = 9.
int[] a = {1,3,2} should return {0,2,1}. Array a should not be changed.
public class Testprogram {
public static void main(String[] args) {
int[] a = {9,8,7,2,7,8};
System.out.println(Arrays.toString(index(a)));
}
public static int[] index(int[] a)
{
int n = a.length;
if (n < 3)
{
throw new IllegalArgumentException("array must have at least 3 elements!");
}
int min = 0; //lowest index
int nmin = 1; //second lowest index
int tmin = 2; //third lowest index
// Controlling that the values in start are in the correct position
if (a[2] < a[1] && a[1] < a[0])
{
min = 2;
nmin = 1;
tmin = 0;
}
else if (a[2] < a[0] && a[0] < a[1])
{
min = 2;
nmin = 0;
tmin = 1;
}
else if (a[1] < a[2] && a[2] < a[0])
{
min = 1;
nmin = 2;
tmin = 0;
} else if (a[1] < a[0] && a[0] < a[2])
{
min = 1;
nmin = 0;
tmin = 2;
}
else if(a[0] < a[1] && a[1] < a[2])
{
min = 0;
nmin = 1;
tmin = 2;
} else if(a[0] < a[2] && a[2] < a[1])
{
min = 0;
nmin = 2;
tmin = 1;
}
int[] index = new int[] {min, nmin, tmin};
return index; //returns the array
}}
This method should work with only three comparisons (and max three exchanges (changes?)).
My method with the if(n < 3), has 7 comparisons.
Anyone that can help my improve my code?
Here is a possible solution
if(a[0]>a[1]){
min=1;
nmin=0;
}
if(a[nmin]>a[tmin]){
int tmp =nmin;
nmin=tmin;
tmin=tmp;
}
if(a[min]>a[nmin]){
int tmp =min;
min=nmin;
nmin=tmp;
}
it's a kind of bubble sort for this specific case (array of 3 elements).

Adding numbers in arrays element by element

The goal is to add two numbers together that are stored in arrays-element by element. The numbers do not necessarily need to be of equal length. I am having trouble accounting for the possibility of a carry over.
If the number is 1101 it would be represented : [1,0,1,1]- The least significant bit is at position 0. I am doing the addition without converting it to an integer.
I am making a separate method to calculate the sum of binary numbers but I just want to understand how to go about this using the same logic.
Ex: 349+999 or they could even be binary numbers as well such as 1010101+11
Any suggestions?
int carry=0;
int first= A.length;
int second=B.length;
int [] sum = new int [(Math.max(first, second))];
if(first > second || first==second)
{
for(int i =0; i <A.length;i++)
{
for(int j =0; j <B.length;j++)
{
sum[i]= (A[i]+B[j]);
}
}
return sum;
}
else
{
for(int i =0; i <B.length;i++)
{
for(int j =0; j <A.length;j++)
{
sum[i]= (A[i]+B[j]);
}
}
return sum;
}
For the binary addition:
byte carry=0;
int first= A.length;
int second=B.length;
byte [] sum = new byte [Math.max(first, second)+1];
if(first > second || first==second)
{
for(int i =0; i < A.length && i!= B.length ;i++)
{
sum[i]= (byte) (A[i] + B[i] + carry);
if(sum[i]>1) {
sum[i] = (byte) (sum[i] -1);
carry = 1;
}
else
carry = 0;
}
for(int i = B.length; i < A.length; i++) {
sum[i] = (byte) (A[i] + carry);
if(sum[i]>1) {
sum[i] = (byte) (sum[i] -1);
carry = 1;
}
else
carry = 0;
}
sum[A.length] = carry; //Assigning msb as carry
return sum;
}
else
{
for(int i =0; i < B.length && i!= A.length ;i++) {
sum[i]= (byte) (A[i] + B[i] + carry);
if(sum[i]>1) {
sum[i] = (byte) (sum[i] -1);
carry = 1;
}
else
carry = 0;
}
for(int i = A.length; i < B.length; i++) {
sum[i] = (byte) (B[i] + carry);
if(sum[i]>1) {
sum[i] = (byte) (sum[i] -1);
carry = 1;
}
else
carry = 0;
}
sum[B.length] = carry;//Assigning msb as carry
return sum;
}
There is no need to treat binary and decimal differently.
This handles any base, from binary to base36, and extremely
large values -- far beyond mere int's and long's!
Digits need to be added from the least significant first.
Placing the least significant digit first makes the code
simpler, which is why most CPUs are Little-Endian.
Note: Save the code as "digits.java" -- digits is the
main class. I put Adder first for readability.
Output:
NOTE: Values are Little-Endian! (right-to-left)
base1: 0(0) + 00(0) = 000(0)
base2: 01(2) + 1(1) = 110(3)
base2: 11(3) + 01(2) = 101(5)
base2: 11(3) + 011(6) = 1001(9)
base16: 0A(160) + 16(97) = 101(257)
base32: 0R(864) + 15(161) = 101(1025)
Source code: digits.java:
class Adder {
private int base;
private int[] a;
private int[] b;
private int[] sum;
public String add() {
int digitCt= a.length;
if(b.length>digitCt)
digitCt= b.length; //max(a,b)
digitCt+= 1; //Account for possible carry
sum= new int[digitCt]; //Allocate space
int digit= 0; //Start with no carry
//Add each digit...
for(int nDigit=0;nDigit<digitCt;nDigit++) {
//digit already contains the carry value...
if(nDigit<a.length)
digit+= a[nDigit];
if(nDigit<b.length)
digit+= b[nDigit];
sum[nDigit]= digit % base;//Write LSB of sum
digit= digit/base; //digit becomes carry
}
return(arrayToText(sum));
}
public Adder(int _base) {
if(_base<1) {
base= 1;
} else if(_base>36) {
base=36;
} else {
base= _base;
}
a= new int[0];
b= new int[0];
}
public void loadA(String textA) {
a= textToArray(textA);
}
public void loadB(String textB) {
b= textToArray(textB);
}
private int charToDigit(int digit) {
if(digit>='0' && digit<='9') {
digit= digit-'0';
} else if(digit>='A' && digit<='Z') {
digit= (digit-'A')+10;
} else if(digit>='a' && digit<='z') {
digit= (digit-'a')+10;
} else {
digit= 0;
}
if(digit>=base)
digit= 0;
return(digit);
}
private char digitToChar(int digit) {
if(digit<10) {
digit= '0'+digit;
} else {
digit= 'A'+(digit-10);
}
return((char)digit);
}
private int[] textToArray(String text) {
int digitCt= text.length();
int[] digits= new int[digitCt];
for(int nDigit=0;nDigit<digitCt;nDigit++) {
digits[nDigit]= charToDigit(text.charAt(nDigit));
}
return(digits);
}
private String arrayToText(int[] a) {
int digitCt= a.length;
StringBuilder text= new StringBuilder();
for(int nDigit=0;nDigit<digitCt;nDigit++) {
text.append(digitToChar(a[nDigit]));
}
return(text.toString());
}
public long textToInt(String a) {
long value= 0;
long power= 1;
for(int nDigit=0;nDigit<a.length();nDigit++) {
int digit= charToDigit(a.charAt(nDigit));
value+= digit*power;
power= power*base;
}
return(value);
}
}
public class digits {
public static void main(String args[]) {
System.out.println("NOTE: Values are Little-Endian! (right-to-left)");
System.out.println(test(1,"0","00"));
System.out.println(test(2,"01","1"));
System.out.println(test(2,"11","01"));
System.out.println(test(2,"11","011"));
System.out.println(test(16,"0A","16"));
System.out.println(test(32,"0R","15"));
}
public static String test(int base, String textA, String textB) {
Adder adder= new Adder(base);
adder.loadA(textA);
adder.loadB(textB);
String sum= adder.add();
String result= String.format(
"base%d: %s(%d) + %s(%d) = %s(%d)",
base,
textA,adder.textToInt(textA),
textB,adder.textToInt(textB),
sum,adder.textToInt(sum)
);
return(result);
}
}
First off, adding binary numbers will be different then ints. For ints you could do something like
int first = A.length;
int second = B.length;
int firstSum = 0;
for (int i = 0; i < first; i++){
firstSum += A[i] * (10 ^ i);
}
int secondSum = 0;
for (int j = 0; j < second; j++){
secondSum += B[j] * (10 ^ j);
}
int totalSum = firstSum + secondSum;
It should be represented like this in below as we have to add only the values at same position of both the arrays. Also, in your first if condition, it should be || instead of &&. This algorithm should perfectly work. Let me know if there are any complications.
int carry=0;
int first= A.length;
int second=B.length;
int [] sum = new int [Math.max(first, second)+1];
if(first > second || first==second)
{
for(int i =0; i < A.length && i!= B.length ;i++)
{
sum[i]= A[i] + B[i] + carry;
if(sum[i]>9) {
sum[i] = sum[i] -9;
carry = 1;
}
else
carry = 0;
}
for(int i = B.length; i < A.length; i++) {
sum[i] = A[i] + carry;
if(sum[i]>9) {
sum[i] = sum[i] -9;
carry = 1;
}
else
carry = 0;
}
sum[A.length] = carry; //Assigning msb as carry
return sum;
}
else
{
for(int i =0; i < B.length && i!= A.length ;i++) {
sum[i]= A[i] + B[i] + carry;
if(sum[i]>9) {
sum[i] = sum[i] -9;
carry = 1;
}
else
carry = 0;
}
for(int i = A.length; i < B.length; i++) {
sum[i] = B[i] + carry;
if(sum[i]>9) {
sum[i] = sum[i] -9;
carry = 1;
}
else
carry = 0;
}
sum[B.length] = carry //Assigning msb as carry
return sum;
}

Adding binary numbers in Java

I have a function which takes two binary numbers as an array of integers, adds the numbers, then returns the sum as a new array of integers.
public static int[] addBin(int a[], int b[]){
int[] sum = {0, 0, 0, 0, 0, 0, 0, 0};
int carryover = 0;
int randombanana = 0;
int x = 7;
for(x = 7; x > 0; x--){
randombanana = a[x] + a[x] + carryover;
if(randombanana == 1){
sum[x] = 1;
carryover = 0;
}
else if(randombanana == 2){
sum[x] = 0;
carryover = 1;
}
else if(randombanana == 3){
sum[x] = 1;
carryover = 1;
}
else if(randombanana == 0){
sum[x] = 0;
carryover = 0;
}
else{
System.out.println("Either I [censored] up, or you [censored] up. I'm a genius so I'm going to assume you [censored] up");
}
}
if(carryover == 1){
sum[x] = 1;
}
return sum;
}
The code works fine on single digit numbers, including numbers that require carrying a digit, but on double or triple digit numbers it works when a number is added to itself, but not when different multiple digit numbers are added.
Should be
randombanana = a[x] + b[x] + carryover;
Your for loop isn't handling the 0th bit
for(x = 7; x >= 0; x--){
Assuming the two numbers are of the same length the numbers could be added as follows:
public static int[] addNumbers(int[] firstNum, int[] secondNum) {
int[] result = new int[firstNum.length + 1];
int digitSum, carry = 0, i;
for (i = firstNum.length - 1; i >= 0; i--) {
digitSum = firstNum[i] + secondNum[i] + carry;
result[i + 1] = digitSum % 2;
carry = digitSum / 2;
}
result[0] = carry;
return result;
}
Here is a short and crisp solution.
public static int [] addBinaryNumbers(int a[],int b[])
{
int n =Integer.max(a.length, b.length);
int c[]=new int[n+1];
int carry =0;
for(int i=0;i<n;i++)
{
c[n-i]=(a[i]+b[i]+carry)%2;
carry= (a[i]+b[i]+carry) /2;
}
c[n]=carry;
return c;
}

Need help count inversions with merge sort

The following code counts inversions in an array nums (pairs i,j such that j>i && nums[i] > nums[j]) by merge sort.
Is it possible to use the same approach to count the number of special inversions like j>i && nums[i] > 2*nums[j]?
How should I modify this code?
public static void main (String args[])
{
int[] nums = {9, 16, 1, 2, 3, 4, 5, 6};
System.out.println("Strong Inversions: " + countInv(nums));
}
public static int countInv(int nums[])
{
int mid = nums.length/2;
int countL, countR, countMerge;
if(nums.length <= 1)
{
return 0;
}
int left[] = new int[mid];
int right[] = new int[nums.length - mid];
for(int i = 0; i < mid; i++)
{
left[i] = nums[i];
}
for(int i = 0; i < nums.length - mid; i++)
{
right[i] = nums[mid+i];
}
countL = countInv (left);
countR = countInv (right);
int mergedResult[] = new int[nums.length];
countMerge = mergeCount (left, right, mergedResult);
for(int i = 0; i < nums.length; i++)
{
nums[i] = mergedResult[i];
}
return (countL + countR + countMerge);
}
public static int mergeCount (int left[], int right[], int merged[])
{
int a = 0, b = 0, counter = 0, index=0;
while ( ( a < left.length) && (b < right.length) )
{
if(left[a] <= right[b])
{
merged [index] = left[a++];
}
else
{
merged [index] = right[b++];
counter += left.length - a;
}
index++;
}
if(a == left.length)
{
for (int i = b; i < right.length; i++)
{
merged [index++] = right[i];
}
}
else
{
for (int i = a; i < left.length; i++)
{
merged [index++] = left[i];
}
}
return counter;
}
I tried this
while ((a < left.length) && (b < right.length)) {
if (left[a] <= right[b]) {
merged[index] = left[a++];
} else {
if (left[a] > 2 * right[b]) {
counter += left.length - a;
}
merged[index] = right[b++];
}
index++;
}
but there's a bug in the while loop, when left[a]<2*right[b] but left[a+n] maybe>2*right[b], for instance left array is {9,16} and right array is {5,6}, 9<2*5 but 16>2*5. My code just skip cases like this and the result number is less than it should be
The while loop in mergeCount serves two functions: merge left and right into merged, and count the number of left–right inversions. For special inversions, the easiest thing would be to split the loop into two, counting the inversions first and then merging. The new trigger for counting inversions would be left[a] > 2*right[b].
The reason for having two loops is that counting special inversions needs to merge left with 2*right, and sorting needs to merge left with right. It might be possible to use three different indexes in a single loop, but the logic would be more complicated.
while ( ( a < left.length) && (b < right.length) ) {
if(left[a] <= right[b]) {
merged [index] = left[a++];
} else {
counter += updateCounter(right[b],a,left);
merged [index] = right[b++];
}
index++;
//Rest of the while loop
}
//Rest of the mergeCount function
}
public static int updateCounter(int toSwitch, int index, int[] array) {
while(index < array.length) {
if(array[index] >= 2*toSwitch)
break;
index++;
}
return array.length-index;
}
Not very efficient, but it should do the work. You initialise index with a, because elements lower than a will never will never meet the condition.

Categories

Resources