This might be a beginner Java question but I would like to be able to calculate the number bytes it will require to store a whole number. And to convert that number into a byte array. Its do with some TLV encoding that I am performing. I realise that Java stores everything in twos completement but I am ignoring that, I am just interested in keeping the binary representation.
For example, if you had the number 256 it would take 2 bytes (as 1 byte can store 2^8-1, i think) then I would like to convert that number into a byte array.
Where:
byte[0] = 1111 1111
byte[1] = 0000 0001
Thanks for any help.
You can use Math.ceil(Math.log(number) / Math.log(2)) to get number of bits to store your number in binary format. Devide by 8 and you will get bytes to store your number.
The binary logarithm (log2) of a number gives you the number of bits needed to display the number. From there it should be easy to get to bytes.
Since Java only contains log10, you have to first convert it to log2. Consider the definition of change of base
We can then write Math.ceil(Math.log(256) / Math.log(2)) for the suggested answers... For instance, you would need 9 bits to save 256 or 2 bytes:
System.out.println(Integer.toBinaryString(256));
int numberBits = (int) Math.ceil(Math.log(256) / Math.log(2)) + 1;
int numberBytes = (int) (Math.ceil(Math.log(256) / Math.log(2)) / 8) + 1;
System.out.println(numberBits);
System.out.println(numberBytes);
100000000
9
2
I was just intrigued in how to get the byte[] of your requirement (to have them in revert order)... I started the implementation of the following test class with a char[]. Then, it came to my mind you could also a BitSet if you need operations over the bit set.
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.List;
public class TestRevertBitSet {
public static class RevertableBitSet {
private BitSet bitSet;
private boolean flipped;
private RevertableBitSet(BitSet bitSet) {
this.bitSet = bitSet;
}
public static RevertableBitSet makeNew(char[] bitArray) {
BitSet byteValue = new BitSet(bitArray.length);
for (int i = 0; i < bitArray.length; i++) {
if (bitArray[i] == '1') {
byteValue.flip(i);
}
}
RevertableBitSet r = new RevertableBitSet(byteValue);
if (r.hasZeroCardinality()) {
r.flipAllBitsTrue();
} else {
r.revertBitsOrder();
}
return r;
}
public boolean hasAllBitsFlip() {
return this.flipped;
}
/**
* #return if all the bits are set.
*/
public boolean hasZeroCardinality() {
return this.bitSet.cardinality() == 0;
}
/**
* Flips all bits from the given bitSet to true.
*/
public void flipAllBitsTrue() {
this.bitSet.set(0, this.bitSet.size());
this.flipped = true;
}
/**
* Reverts the bits sequence. For instance, from 01100 to 00110.
*/
public void revertBitsOrder() {
for (int i = 0; i < 4; i++) {
boolean nthBit = this.bitSet.get(i);
this.bitSet.set(i, this.bitSet.get(7 - i));
this.bitSet.set(7 - i, nthBit);
}
}
/**
* #return a char array with values based on the bit indexes of the
* given bit set.
*/
public char[] toCharArray() {
char[] bitChars = new char[8];
for (int i = 0; i < bitChars.length; i++) {
bitChars[i] = bitSet.get(i) ? '1' : '0';
}
return bitChars;
}
/**
* #param bitIndex
* #return the boolean value of the given bit index.
*/
public boolean getBitBooleanAtIndex(int bitIndex) {
if (bitIndex > 7) {
return false;
}
return this.bitSet.get(bitIndex);
}
/**
* #param byteSetsList
* is the list of BitSet.
* #return the integer representation of the entire bit set.
*/
public static int convertSetToInteger(
List<RevertableBitSet> byteSetsList) {
int sum = 0;
int index = 0;
for (RevertableBitSet bitSet : byteSetsList) {
if (bitSet.hasAllBitsFlip()) {
for (int i = 0; i < 8; i++) {
index++;
}
continue;
}
for (int i = 7; i >= 0; i--) {
int bit = bitSet.getBitBooleanAtIndex(i) ? 1 : 0;
int intValue = (int) Math.pow((double) 2, (double) index++)
* bit;
sum = sum + intValue;
}
}
return sum;
}
#Override
public String toString() {
StringBuilder b = new StringBuilder();
b.append("[ ");
for (int i = 0; i < 7; i++) {
b.append(i);
b.append(" , ");
}
b.delete(0, b.length() - 2);
b.append(" ]");
return b.toString();
}
}
public static void main(String[] args) throws IOException {
int decimalNumber = 256;
System.out.println("Decimal Number: " + decimalNumber);
System.out.println(Integer.toBinaryString(decimalNumber));
int numberBits = (int) Math.ceil(Math.log(decimalNumber) / Math.log(2)) + 1;
int numberBytes = (int) (Math.ceil(Math.log(decimalNumber)
/ Math.log(2)) / 8) + 1;
System.out.println("Number of bits: " + numberBits);
System.out.println("Number of bytes: " + numberBytes);
List<RevertableBitSet> bytesSet = new ArrayList<RevertableBitSet>();
int bitsCounter = -1;
char[] binaryChars = Integer.toBinaryString(decimalNumber)
.toCharArray();
char[] currentChars = new char[8];
Arrays.fill(currentChars, '0');
for (int i = binaryChars.length - 1; i >= 0; i--) {
if (bitsCounter + 1 <= 7) {
currentChars[++bitsCounter] = binaryChars[i];
} else {
RevertableBitSet bitSet = RevertableBitSet
.makeNew(currentChars);
bytesSet.add(bitSet);
bitsCounter = -1;
Arrays.fill(currentChars, '0');
currentChars[++bitsCounter] = binaryChars[i];
}
}
bytesSet.add(RevertableBitSet.makeNew(currentChars));
System.out.println("------------");
for (RevertableBitSet bitSet : bytesSet) {
System.out.println(Arrays.toString(bitSet.toCharArray()));
}
System.out.println("------------");
System.out.println("Number: "
+ RevertableBitSet.convertSetToInteger(bytesSet));
}
}
The output of the execution of the main method is:
Decimal Number: 256
100000000
Number of bits: 9
Number of bytes: 2
------------
[1, 1, 1, 1, 1, 1, 1, 1]
[0, 0, 0, 0, 0, 0, 0, 1]
------------
Number: 256
Larger numbers as well work...
Decimal Number: 33456176
1111111101000000000110000
Number of bits: 26
Number of bytes: 4
------------
[0, 0, 1, 1, 0, 0, 0, 0]
[1, 0, 0, 0, 0, 0, 0, 0]
[1, 1, 1, 1, 1, 1, 1, 0]
[0, 0, 0, 0, 0, 0, 0, 1]
------------
Number: 33456176
Related
Given a value N, if we want to make change for N cents, and we have infinite supply of each of S = { S1, S2, .. , Sm} valued coins, what is the optimal way to make change for N cents.
Example:
S = {2, 5, 10}
N = 6, then optimal solution is : 2, 2, 2
I have below working code:
public static void main(String argv[]) {
long n = 10L;
int[] combo = new int[100];
int[] amounts = { 2, 5, 10 };
ways(n, amounts, combo, 0, 0, 0);
}
public static void ways(long n, int[] amounts, int[] combo, int startIndex, int sum, int index) {
if (sum == n) {
printArray(combo, index);
}
if (sum > n) {
return;
}
for (int i = 0; i < amounts.length; i++) {
sum = sum + amounts[i];
combo[index] = amounts[i];
ways(n, amounts, combo, startIndex, sum, index + 1);
sum = sum - amounts[i];
}
}
public static void printArray(int[] combo, int index) {
for (int i = 0; i < index; i++) {
System.out.print(combo[i] + " ");
}
System.out.println();
}
Output:
2 2 2 2 2
5 5
10
Here I just need to optimal combination with less number of coins so only 10 in this example code.
But this code uses recursive approach, my value for N is Long type so as the value of N increases I am getting stackoverflow error.
The recursive approach I am following here is not correct, What is the correct way to solve this problem?
Update:
Based on MBo answer I tried below program, but I am not able to get the correct results:
static void testcase() {
// make int array A of size N+1
int N = 6;
int[] A = new int[N + 1];
// make int array P of size N+1
int[] P = new int[N + 1];
// fill A[] with large value (len(S) + 1)
int[] S = { 2, 5, 10 };
int lengthOfS = S.length;
for (int i = 0; i < A.length; i++) {
A[i] = lengthOfS + 1;
}
A[0] = 0;
for (int s : S) {// coin value
for (int i = s; i <= N; i++) {
if (A[i - s] < A[i] + 1) { // using this coin we can get better
// result for sum i
A[i] = A[i - s] + 1;
P[i] = s; // write down coin for this sum
}
}
}
System.out.println(Arrays.toString(P)); // [0, 0, 2, 2, 2, 5, 2]
System.out.println(A[N]);// 3
int idx = N;
for (int i = 0; i < A[N]; i++) {
int result = idx - P[idx];
System.out.println(result); // 4 2 0
idx = result;
}
}
This code prints:
[0, 0, 2, 2, 2, 5, 2]
3
4
2
0
How to fix this code?
For fixed set S = {2, 5, 10} solution is rather simple:
No solutions for N=1,3
if N is odd, you must use 5 - so N=N-5
Now use greedy approach: get as much 10-s as possible, then as much 2-s as possible
def best(N):
print(N, end = ": ")
if (N % 2):
print("5", end = " ")
N = N - 5
if N >= 10:
print("10*", N//10, end = " ")
N = N % 10
if N > 1:
print("2*", N//2, end = " ")
21: 5 10* 1 2* 3
22: 10* 2 2* 1
23: 5 10* 1 2* 4
24: 10* 2 2* 2
In general you can find optimal solution using dynamic programming.
The first way is "memoization" - you have to implement recursive approach with the choice of the best solution, then add storing intermediate results in hashmap or another structure. Simple implementation:
S = [2, 3, 5, 7, 11]
dic = {}
def rec(summ):
if summ == 0:
return 0
rd = dic.get(summ)
if rd != None:
return rd
minn = 9999999999999
for s in S:
if s <= summ:
minn = min(minn, 1 + rec(summ - s))
dic[summ] = minn
return minn
N = 1000
print(rec(N))
>>92
Another way is using table - you fill it with the best possible results using the first item, then update solution using the second item and so on.
Pseudocode
make int array A of size N+1
make int array P of size N+1
fill A[] with large value (MaxInt` or at least `N/min(S))
A[0] = 0
for s in S: //coin value
for (i = s; i <= N; i++)
if A[i - s] < A[i] + 1 //using this coin we can get better result for sum i
A[i] = A[i - s] + 1
P[i] = s //write down coin for this sum
Now we have A[N] with the best count, and can retrieve needed coins using P[N], P[N - P[N]]... sequence.
Working Python code
S = [2, 3, 5, 7, 11]
N = 17
A = [0] + [10000] * N
P = [0] * (N + 1)
for s in S: #coin value
for i in range(s, N + 1):
if A[i - s] < A[i] + 1: #using this coin we can get better result for sum i
A[i] = A[i - s] + 1
P[i] = s #write down coin for this sum
print(A) #for reference
i = N
while i > 0:
print(P[i], end = " ")
i = i - P[i]
>> [0, 10000, 1, 1, 2, 1, 2, 1, 2, 2, 2, 1, 2, 2, 2, 3, 2, 3]
>> 11 3 3
Note - if we can use every coin only once, we have to make inner loop in backward direction to avoid multiple adding the same coin
As the number of coins is small, and since the amount can be large, it is likely that backtracking can provide a good solution
Here is an implementation in C++
(Note: this code was already posted, but I can't find the post. Question deleted ?)
The coins are first sorted if descending order, to fasten the search.
In order to minimize the number of coins, we first try solutions with maximum possible number of coins of largest value.
In a given search, if the current number of coins is larger than the current minimum number of coins, we stopped the search ("premature abandon").
In the code, "UP" means that we will consider adding coins with a lower value
"DOWN" means that we will try to decrease the number of coins of higher value.
At a given step, we maintain an array corresponding to the number of coins for each coin value
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
// The order of array coins is modified
std::vector<int> get_change(std::vector<int>& coins, int amount) {
std::vector<int> n_coins(coins.size(), 0);
std::vector<int> n_coins_opt(coins.size(), 0);
int n = coins.size();
std::sort(coins.begin(), coins.end(), std::greater<int>());
int sum = 0; // current sum
int i = 0; // index of the coin being examined
int n_min_coins = amount / coins[n - 1] + 1;
int n_total_coins = 0;
bool up_down = true;
while (true) { // UP
if (up_down) {
n_coins[i] = (amount - sum) / coins[i]; // max possible number of coins[i]
sum += n_coins[i] * coins[i];
n_total_coins += n_coins[i];
if (sum == amount) {
if (n_total_coins < n_min_coins) {
n_min_coins = n_total_coins;
n_coins_opt = n_coins;
}
up_down = false;
sum -= n_coins[i] * coins[i];
n_total_coins -= n_coins[i];
n_coins[i] = 0;
i--;
}
else {
if (i == (n - 1) || (n_total_coins >= n_min_coins)) { // premature abandon
sum -= n_coins[i] * coins[i];
n_total_coins -= n_coins[i];
n_coins[i] = 0;
up_down = false;
i--;
}
else {
i++;
}
}
}
else { // DOWN
if (i < 0) break;
if (n_coins[i] == 0) {
if (i == 0) break;
i--;
}
else {
sum -= coins[i];
n_coins[i] --;
n_total_coins--;
i++;
up_down = true;
}
}
}
return n_coins_opt;
}
int main() {
std::vector<int> coins = {2, 5, 10};
int amount = 1731;
auto n_coins = get_change(coins, amount);
int sum = std::accumulate (n_coins.begin(), n_coins.end(), 0);
if (sum == 0) {
std::cout << "no solution\n";
} else {
std::cout << amount << " = ";
for (int i = 0; i < n_coins.size(); i++) {
std::cout << n_coins[i] << "*" << coins[i] << " ";
}
std::cout << "\n";
}
return 1;
}
I have an array that represents a Max Heap. For example
84 81 41 79 17 38 33 15 61 6
so the root is max. Each mid tier node at index i can have at most two children. They would be at 2*i+1 and 2*i+2.
How can i print this heap out in a level by level fashion? like
84(0)
81(1) 41(2)
79(3) 17(4) 38(5) 33(6)
15(7) 61(8) 6(9)
the index of each element in the array is shown in paranthesis for clarification. i dont have to print the index. I was thinking it would be similar to printing a BST in level order but here, the heap is stored in an array not a list which makes it a bit tricky!
Try this code:
public class NewClass56 {
public static void main(String args[]){
int a[] = new int[] {84 ,81 ,41 ,79 ,17 ,38 ,33 ,15 ,61 ,6};
for(int i=0;i<10;i++){
for(int j=0;j<Math.pow(2,i)&&j+Math.pow(2,i)<10;j++){
System.out.print(a[j+(int)Math.pow(2,i)-1]+" ");
}
System.out.println();
}
}
}
If you have n number of numbers then replace 10 by n.
and you want the spaces then try this code:
public class NewClass56 {
public static void main(String args[]){
int a[] = new int[] {84 ,81 ,41 ,79 ,17 ,38 ,33 ,15 ,61 ,6};
StringBuilder sb = new StringBuilder();
int max=0;
for(int i=0;i<10;i++){
for(int j=0;j<Math.pow(2,i)&&j+Math.pow(2,i)<10;j++){
if(j>max){
max=j;
}
}
}
for(int i=0;i<10;i++){
for(int j=0;j<Math.pow(2,i)&&j+Math.pow(2,i)<10;j++){
for(int k=0;(k<max/((int)Math.pow(2, i)));k++){
sb.append(" ");
}
sb.append(a[j+(int)Math.pow(2,i)-1]+" ");
}
sb.append("\n");
}
System.out.println(sb.toString());
}
}
There is another way to print heap. Imagine you have the structure with the following indexes (index 0 is guardian and equals to Integer.MIN_VALUE, not shown here):
1
/ \
2 3
/ \ / \
4 5 6 7
/ \ /\ /\ /\
8 9 10 11 12 13 14 15
and it's represented by array of numbers. What do you see here? Right, 1, 3, 7, 15. If you increase it by 1 it will be 2, 4, 8, 16.
And what are these numbers? It's just 2^level. Where level is level from 1 to 4.
How we can calculate this level? It's logarithm of index with base 2.
Here is the code that implements this approach (see dump function):
package org.solutions;
import java.util.ArrayList;
import java.util.Arrays;
class Heap {
public ArrayList<Integer> arr;
public Heap() {
this.arr = new ArrayList<>();
arr.add(Integer.MIN_VALUE); // add guardian
}
public void add(int x) {
int i = arr.size();
arr.add(x);
while(arr.get(i) < arr.get(i / 2)) {
swap(i, i/2);
i = i / 2;
}
}
private void swap(int i, int j) {
int tmp = arr.get(i);
arr.set(i, arr.get(j));
arr.set(j, tmp);
}
public void dump() {
int height = log2(arr.size()) + 1;
for (int i = 1, len = arr.size(); i < len; i++) {
int x = arr.get(i);
int level = log2(i) + 1;
int spaces = (height - level + 1) * 2;
System.out.print(stringOfSize(spaces, ' '));
System.out.print(x);
if((int)Math.pow(2, level) - 1 == i) System.out.println();
}
}
private String stringOfSize(int size, char ch) {
char[] a = new char[size];
Arrays.fill(a, ch);
return new String(a);
}
// log with base 2
private int log2(int x) {
return (int)(Math.log(x) / Math.log(2)); // = log(x) with base 10 / log(2) with base 10
}
}
public class Main {
public static void main(String[] args) {
Heap heap = new Heap();
heap.add(30);
heap.add(2);
heap.add(15);
heap.add(10);
heap.add(31);
heap.dump();
}
}
The existing solutions didn't work for me so here's slightly different way of doing it that I think is also more human readable. Additionally, this doesn't use any external libraries. Note that this assumes that the first spot of the array is null, because often array-based heaps skip the array[0]. This will automatically determine the number of levels based on the input size which should be the number of nodes in the heap. It will add -- in every spot that is empty (e.g. if you have a 13-node heap the last two nodes will show up as empty).
private void printHeap(int[] heap, size) {
int maxDepth = (int) (Math.log(size) / Math.log(2)); // log base 2 of n
StringBuilder hs = new StringBuilder(); // heap string builder
for(int d = maxDepth; d >= 0; d--) { // number of layers, we build this backwards
int layerLength = (int) Math.pow(2, d); // numbers per layer
StringBuilder line = new StringBuilder(); // line string builder
for(int i = layerLength; i < (int) Math.pow(2, d + 1); i++) {
// before spaces only on not-last layer
if(d != maxDepth) {
line.append(" ".repeat((int) Math.pow(2, maxDepth - d)));
}
// extra spaces for long lines
int loops = maxDepth - d;
if(loops >= 2) {
loops -= 2;
while(loops >= 0) {
line.append(" ".repeat((int) Math.pow(2, loops)));
loops--;
}
}
// add in the number
if(i <= size) {
line.append(String.format("%-2s", heap[i])); // add leading zeros
} else {
line.append("--");
}
line.append(" ".repeat((int) Math.pow(2, maxDepth - d))); // after spaces
// extra spaces for long lines
loops = maxDepth - d;
if(loops >= 2) {
loops -= 2;
while(loops >= 0) {
line.append(" ".repeat((int) Math.pow(2, loops)));
loops--;
}
}
}
hs.insert(0, line.toString() + "\n"); // prepend line
}
System.out.println(hs.toString());
}
Example input:
int[] heap = new int[]{0, 84, 81, 41, 79, 17, 38, 33, 15, 61, 6};
int size = heap.length-1 = 10
Example output:
84
81 41
79 17 38 33
15 61 6 -- -- -- -- --
You should be able to fairly easily change this to work as a toString method instead if necessary. The spacing will have to be modified if you want to use 3-digit numbers, if someone requests it I can edit with modified code for that.
Divide & Conquer. Create the line lists of the subtrees, concatenate the lines and prepend the String for the root node of the subtree. Also make sure the lines have the same length and all are centered:
static String pad(String s, int lengthRigth, int length) {
StringBuilder sb = new StringBuilder();
for (int i = length - lengthRigth - s.length(); i > 0; i--) {
sb.append(' ');
}
sb.append(s);
for (int i = 0; i < lengthRigth; i++) {
sb.append(' ');
}
return sb.toString();
}
static StringBuilder withSpacesAppended(String s, int spaceCount) {
StringBuilder sb = new StringBuilder(s.length()+spaceCount).append(s);
for (int i = 0; i < spaceCount; i++) {
sb.append(' ');
}
return sb;
}
static void joinLists(List<String> list1, List<String> list2) {
int i;
final int size = list2.size();
for (i = 0; i < size; i++) {
list1.set(i, withSpacesAppended(list1.get(i), 2).append(list2.get(i)).toString());
}
}
static List<String> createTreeStrings(int index, int[] array) {
int child1 = 2 * index + 1;
int child2 = 2 * index + 2;
if (child1 >= array.length) {
return new ArrayList<>(Collections.singletonList(toText(index, array)));
} else {
List<String> childList1 = createTreeStrings(child1, array);
if (child2 < array.length) {
joinLists(childList1, createTreeStrings(child2, array));
}
String text = toText(index, array);
int currentLength = childList1.get(0).length();
if (currentLength >= text.length()) {
text = pad(text, (currentLength - text.length()) / 2, currentLength);
} else {
for (int i = 0, size = childList1.size(); i < size; i++) {
childList1.set(i, pad(childList1.get(i), (currentLength - text.length()) / 2, currentLength));
}
}
childList1.add(0, text);
return childList1;
}
}
static String toText(int index, int[] array) {
return Integer.toString(array[index]) + '(' + index + ')';
}
Example use:
createTreeStrings(0, new int[]{84, 81, 41, 79, 17, 38, 33, 15, 61, 6}).forEach(System.out::println);
createTreeStrings(0, new int[]{Integer.MAX_VALUE, 6}).forEach(System.out::println);
The accepted answer created many new lines and ignores last element while displaying. Hence sharing optimised code,
public void display() {
// n is number of elements in the heap
// It can be further optimised by calculating height of the heap
// and looping i only till height of the tree
for (int i = 0; i <= n / 2; i++) {
for (int j = 0; j < Math.pow(2, i) && j + Math.pow(2, i) <= n; j++) { // Each row has 2^n nodes
System.out.print(heap[j + (int) Math.pow(2, i) - 1] + " ");
}
System.out.println();
}
}
If you want to store it in a list of lists (level order) , just split it once for every power of 2, like 1,2,4,8,16 ..
private ArrayList<ArrayList<Integer>> heapParse(int[] arr) {
ArrayList<ArrayList<Integer>> heap = new ArrayList<ArrayList<Integer>>();
int j=-1;
for (int i=0; i< arr.length;i++){
if(isPowerOfTwo(i+1)){
heap.add(new ArrayList<>());
j++;
}
heap.get(j).add(arr[i]);
}
return heap;
}
private boolean isPowerOfTwo(int i){
return (i&(i-1))==0;
}
The following algorithm will print value as defined grid length.
For example, the max element equals 100, mean each digits sit in placeholder that has length == 3. If max length is even, for ex: 4. Then the placeholder value will be 5. Always odds for center alignment.
Result: [placeholder == 3] && [maxWidthLine == 31]
100 // [rear == 14] && [between == 29 -> Not Use]
15- 17- // [rear == 6] && [between == 13]
-9- -6- 13- 10- // [rear == 2] && [between == 5]
-4- -8- -3- -1- -5- --- --- --- // [rear == 0] && [between == 1]
Result: [placeholder == 5] && [maxWidthLine == 5 * 2^3 + 2 ^ 3 - 1 == 47]
1000- // [Level == 0]
-17-- -13-- // [Level == 1]
--9-- -15-- --5-- -10-- // [Level == 2]
--4-- --8-- --3-- --6-- --1-- ----- ----- ----- // [Level == 3]
TypeScript source code:
/** #example
** > format(10, 3) -> "10-"
** > format(10, 4) -> "-10-"
** > format(100, 3) -> "100"
** > format(100, 4) -> "100-"
**/
const format = <T extends string | number>(value: T, placeholder: number): string => {
if (!value && value !== 0) {
return "-".repeat(placeholder);
}
const number = Number.call(null, value).toString();
const size = number.length;
if (size > placeholder) {
throw new EvalError(">>> Place-Holder is smaller than Number Length <<<");
}
const pads = (placeholder - size) >> 1;
return "-".repeat(pads) + number + "-".repeat(placeholder - size - pads);
};
public print(): void {
const size = this.heap.length;
const maxDigit = Math.max(...this.heap as Array<number>);
/** Place holder must be odds [1, 3, 5, 7, 9, 11, ...] ~!*/
const placeholder = (Number.call(null, maxDigit).toString().length & ~1) + 1;
/** Max Depth of Binary Search Tree from [0] to [N] ~!*/
const maxDepth = Math.floor(Math.log(size) / Math.log(2)); // Min Depth = 0; [Root Level]
/** Total Spaces of Line == <The Amount of placeholders> && <The Amount of Space-1 between Placeholders> ~!*/
const totalLineSpaces = placeholder * (2 ** maxDepth) + (2 ** maxDepth - 1);
/** Calculate the spaces need to pad to the Rear-Side and Between each Placeholders ~!*/
const calculateSpace = (level: number): [number, number] => {
/** #equation: ${TotalSpaces} - ${placeholder} * (2 ^ level) == 2x + (2 ^ level - 1)(2x + 1) ~!*/
/** #constraint: ${BetweenSpaces} == (2x + 1) <- Space between each placeholders ~!*/
const rear = (totalLineSpaces - (placeholder + 1) * (2 ** level) + 1) / Math.pow(2, level + 1);
return [rear, 2 * rear + 1];
};
console.log("------------------------------------------");
console.log(">>> Array representation of Heap Array <<<");
console.log("------------------------------------------\n");
let str = ''; /** Heap string builder ~!*/
for (let level = 0; level <= maxDepth; level++) {
const [rear, middle] = calculateSpace(level);
if (level === 0) {
str += " ".repeat(rear) + this.format(this.heap[0], placeholder) + " ".repeat(rear) + "\n";
continue;
}
const elements: Array<string> = [];
/** #description: Looping through each Tree-Layer. Ranged from [2^level - 1] to [2^(level+1) - 2] ~!*/
for (let i = Math.pow(2, level) - 1; i <= Math.pow(2, level + 1) - 2; i++) {
elements.push(this.format(this.heap[i], placeholder));
}
str += " ".repeat(rear) + elements.join(" ".repeat(middle)) + " ".repeat(rear) + "\n";
}
str += "\n" + "------------------------------------------";
return console.log(str);
};
I have the following program to write:
An interesting (yet unsolved) question in mathematics is called "hailstone numbers". This series is produced by taking an initial integer and if the number is even, dividing it by 2. If the number is odd, multiply it by 3 and add 1. This process is the repeated.
For example: An initial number of 10 produces: 10, 5, 16, 8, 4, 2, 1, 4, 2, 1... An initial value of 23 produces: 23, 70, 35, 106, 53, 160, 80, 40, 20, 10, 5, 16, 8, 4, 2, 1, 4, 2, 1...
Note that both numbers eventually reach the 4, 2, 1, 4, 2, 1... cycle.
Create an application that offers the user three different ways to run this program.
Option 1: Print the hailstone numbers for a single entry and its length
Example: Input> 10 10, 5, 16, 8, 4, 2, 1 Length 7
Option 2: Print all of the hailstone numbers from 4 to a given entry
Example: Input> 6 4, 2, 1 Length 3 5, 16, 8, 4, 2, 1 Length 6 6, 3, 10, 5, 16, 8, 4, 2, 1 Length 9
Option 3: Print out the number with the maximum number of iterations need to reach the cycle and which starting number produces this maximum from 4 to the number entered.
Example: Input> 6 Longest: 6 Length: 9
In writing this program you must implement the following method...
/**
*
* #param num Number that a hailstone chain will be generated
* #param showNumbers true if list of numbers is shown to screen
* #return Count of the numbers in the num hailstone chain.
*/
private static int hailStone(int num, boolean showNumbers) {
// your code
}
This is the code I've written so far:
public static void main(String[] args) {
int a = getInt("Give a number: ");
System.out.print("How would you like to run the program? Option 1 prints hailstone numbers for a single entry and its length." +
"Option 2 prints all the hailstone numbers from 4 to a given entry. Option 3 prints the number with the maximum number" +
"of iterations needed to reach the 4, 2, 1 cycle.");
int option = console.nextInt();
boolean showNumbers = (option == 1 || option == 2);
hailStone(a, showNumbers);
}
public static int getInt(String prompt) {
int input;
System.out.print(prompt);
input = console.nextInt();
return input;
}
private static void hailStone (int a, boolean showNumbers) {
if (showNumbers == true) {
if (a % 2 == 0) {
for (int i = 0; i < 50; i++) {
for (int j = 0; j <= i; j++)
a /= 2;
System.out.print(a + " ");
a *= 3;
a += 1;
System.out.print(a + " ");
}
} else {
for (int i = 0; i != a; i++) {
}
}
} else {
}
}
I feel like I've hit a brick wall because I have no idea how to implement all these options in the method my teacher is requiring us to use. Plus, I can't seem to get even the basic hailstone chain to print. Help?
The HailStone algorithm should not be hard to implement. It will actually be much easier if you make it a recursive function, since that is more natural Writing it as an iterative function is probably what is causing your issues.
This should be enough to get you started, this is a working HailStone implementation using a recursive function. You can implement the rest of the project requirements quite easily once you've got the algorithm working... but I'd like to challenge you to convert this into a working iterative function once you get the features correct and to write unit tests to test the program. (TDD dictates that you should write your tests BEFORE you write the actual implementation. This is a great practice that is often skipped due to time constraints and the perception that a strong test suite is overkill.)
HailStone.java
public class HailStone {
/* static variable to count calls to hailStone */
public static int iterCount = 0;
/* This variable is a senti */
public static boolean isRepeating = 0;
/* Simple main function */
public static void main(String[] args) {
// TODO:
// Either parse args or use a scanner to get input.
// Args = verbose, entryPoint
hailStone(10, true);
}
/* Recursive hailStone implementation */
private static void hailStone(int a, boolean showNumbers) {
// start off by printing the numbers if showNumbers is true
if (showNumbers) {
System.out.printf("Iteration #%d: %d\n", ++iterCount, a);
}
// base case: a = 1 => most important part of recursion
if (a == 1) {
if (isRepeating) {
return;
}
isRepeating = true;
}
// check if a is odd
// You can use modulo divison, but we'll use bitwise &
/* Explained: [ bitwise AND... bits that are set in a AND in 1 ]
**********************************************
Case 1: a is even =>
a = 10
10 in binary is 00001010
1 in binary is 00000001
------------------------------
10 & 1 in binary is 00000000
Case 2: a is odd =>
a = 10
11 in binary is 00001011
1 in binary is 00000001
------------------------------
11 & 1 in binary is 00000001
**********************************************
set(X) = set of all even numbers
set(Y) = set of all odd numbers
{
x is any arbitrary number in set X,
y is any arbitrary number in set Y
}
x & 1 will ALWAYS equal 0 -\
>- know this. bitwise hacks rock.
y & 1 will ALWAYS equal 1 -/
*/
if ((a & 1) == 1) {
a *= 3;
a += 1;
} else {
a /= 2;
}
// Tail recursion.
hailStone(a, showNumbers);
return;
}
}
without all the comments and extra stuff:
public class HailStone {
public static int iter_count = 0;
public static void main(String[] args) {
hailStone(10, true);
}
/* Recursive hailStone implementation */
private static void hailStone(int a, boolean showNumbers) {
if (showNumbers) {
System.out.printf("Iteration #%d: %d\n", ++iter_count, a);
}
// base case: a = 1
if (a == 1) {
return;
}
if ((a & 1) == 1) { // a is odd:
a *= 3;
a += 1;
} else {
a /= 2;
}
hailStone(a, showNumbers);
return;
}
}
private static Scanner console = new Scanner(System.in);
public static void main(String[] args) {
System.out.println("How would you like to run the program?");
System.out.println(" [1] - print hailstone numbers for a single entry and its length.");
System.out.println(" [2] - print all hailstone numbers from 4 to a given entry.");
System.out.println(" [3] - print the number with the maximum number of iterations needed to reach the 4, 2, 1 cycle.");
int option = queryInt("Option: ", 1, 3);
switch (option) {
case 1: {
int seed = queryInt("INPUT> ", 1, Integer.MAX_VALUE);
hailStone(seed, true);
break;
}
case 2: {
int maxSeed = queryInt("INPUT> ", 4, Integer.MAX_VALUE);
for (int i = 4; i <= maxSeed; i++) {
hailStone(i, true);
}
break;
}
case 3: {
int maxSeed = queryInt("INPUT> ", 4, Integer.MAX_VALUE);
int longestChain = 0;
int longestChainLength = 0;
for (int i = 4; i <= maxSeed; i++) {
int length = hailStone(i, false);
if(length > longestChainLength) {
longestChain = i;
longestChainLength = length;
}
}
System.out.println("Longest: " + longestChain + " Length: " + longestChainLength);
break;
}
}
}
private static int queryInt(String prompt, int min, int max) {
while (true) {
System.out.print(prompt);
String input = console.nextLine();
try {
int result = Integer.parseInt(input);
if (result >= min && result <= max) {
return result;
} else {
System.err.print("Expected a number ");
if (min == Integer.MIN_VALUE) {
System.err.println(" less than or equal to " + max);
} else if (max == Integer.MAX_VALUE) {
System.err.println(" greater than or equal to " + min);
} else {
System.err.println(" between " + min + " and " + max);
}
}
} catch (NumberFormatException ex) {
System.err.println("Not a number: " + input);
}
}
}
private static int hailStone(int num, boolean showNumbers) {
int result = 1;
for (Iterator<Integer> chain = iterateHailStone(num); num != 1; num = chain.next(), result++) {
if (showNumbers) {
System.out.print(num + ", ");
}
}
if (showNumbers) {
System.out.print(num);
System.out.println(" (length=" + result + ")");
}
return result;
}
private static Iterator<Integer> iterateHailStone(int seed) {
return new Iterator<Integer>() {
int value = seed;
#Override
public boolean hasNext() {
return true;
}
#Override
public Integer next() {
if (value % 2 == 0) {
value /= 2;
} else {
value *= 3;
value++;
}
return value;
}
};
}
So I am not very good at it yet at all (understatement). I am trying to solve problems in the Euler project, and I am already stuck on 2.
Each new term in the Fibonacci sequence is generated by adding the previous 2 terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.
Here is my code which I have repeatedly tried to fix:
(I think there is something wrong with the for loop logic.)
public class tesy {
public static void main(String args[]) {
int fib = 0;
int tot = 0;
int total = 0;
for (fib = 0; tot < 4000000; fib++) {
tot = fib + (fib + 1);
if (tot % 2 == 0) {
total = tot + total;
}
}
System.out.println(total);
}
}
Your logic is erroneous in couple of ways,
tot = fib + (fib + 1); /** This will always be `(2*fib + 1)` and `fib` is getting
incremented by 1 each time. You have no reference to the previous two terms of the
sequence. **/
Try the below logic instead.
class Fibonacci
{
public static void main (String[] args)
{
int fiboFirst = 1;
int fiboSecond =2;
int fib = 0;
int sum = 0;
while(fiboSecond < 4000000)
{
// This will calculate the current term of the sequence
fib = fiboFirst + fiboSecond;
// Below two lines will update fib[i] and fib[i - 1] terms
// for the next loop iteration.
fiboFirst = fiboSecond; // fib[i]
fiboSecond = fib; // fib[i -1]
if (fib % 2 == 0)
{
sum = sum + fib;
}
}
System.out.println(sum+2);
}
}
Explanation
Here fiboFirst is equivalent to F[n] and fiboSecond is equivalent
to F[n - 1] in the Fibonacci sequence definition. In each iteration,
those two values should be replaced, in order to be used in the next
iteration. That is why I have these two lines,
fiboFirst = fiboSecond; // fib[i]
fiboSecond = fib; // fib[i -1]
HERE is the execution of the above program
You don't seem to be following the actual equation used to generate a fibonacci sequence, therefore there is no (obvious) way of fixing your code.
int fibA = 1, fibB = 2, total = 0;
while(fibB <= 4000000) {
// Add to the total, set fibA to fibB and get the next value in the sequence.
if(fibB % 2 == 0) total += fibB;
int temp = fibA;
fibA = fibB;
fibB = fibB + temp;
}
The above code should find the sum of all values less than or equal to 4000000
Here is a solution that uses BigInteger. Please verify the results.
public class Fibonacci{
public static void main(String[] args) {
BigInteger r = fibonacciEvenSum();
System.out.println(r);
}
public static BigInteger fibonacciEvenSum(){
int f = 1;
int s = 2;
int mn4 = 4000000;
BigInteger sum = BigInteger.valueOf(0);
while(s <= mn4){
if(s % 2 == 0){
sum = sum.add(BigInteger.valueOf(s));
}
f = f + s;
s = s + f;
}
return sum;
}
}
Before writing a program like this, you should first think of what's underlying this program. You should first understand how to generate a Fibonacci series before graduating on to doing something with the series. I'll give you my solution so that you can understand.
class euler2 {
public static void main(String[] args) {
int a = 0, b = 1; /* the first elements of Fibonacci series are generally
thought to be 0 and 1. Therefore the series is 0, 1, 1, 2, 3... .
I've initialized first and second elements such */
double sum = 0; // The initial sum is zero of course.
while (b < 4000000) /* since b is the second term, it will be our control variable.
This wouldn't let us consider values above 4M. */
{
int ob = b; // to swap the values of a and b.
b = a + b; // generating next in the series.
a = ob; // a is now the older value of b since b is now a + b.
if (b % 2 == 0) // if b is even
sum += b; // we add it to the sum
}
System.out.println(sum); // and now we just print the sum
}
}
Hope this helped!
I'm using zxing to generate an EAN13 barcode. Everything works fine when I use this code:
new EAN13Writer().encode(eanValue, BarcodeFormat.EAN_13, requestedWidth, requestedHeight);
Result:
Now, the customer wants to have a lead, separater and a trailer like this one:
(Image source)
As far as I understand the code of zxing (see here) I'm using above can't make those lines longer than others. But I've found out that there are two encode-methods in the EAN13Writer and it seems like, the second encode-function does exactly what I want to do. But the problem is that this function doesn't return a bitmatrix but a boolean array. (Edit: Nope the function does not achieve what I want to do)
Can anybody tell me how I can achieve the second barcode style?
As I couldn't find a solution in the zxing code I wrote my own EAN13Writer. I had to copy paste some methods and constants as they were package-private in the zxing package.
Basically it just stores the position of the lines which shall be longer in a member variable. When the BitMatrix is rendered every line which should not be longer will be shortened by 5%. If anybody has the same problem this code might help a little bit.
/**
* This is a custom implementation as the customer wants a modified barcode with longer and shorter lines for start, middle and end.
* Most code is based on Code from the OneDimensionalCodeWriter, EAN13Writer and UPCEANReader but
* had to be copied as the methods were package private
*
*/
public class CustomEAN13Writer extends OneDimensionalCodeWriter {
// For an EAN-13 barcode, the first digit is represented by the parities used
// to encode the next six digits, according to the table below. For example,
// if the barcode is 5 123456 789012 then the value of the first digit is
// signified by using odd for '1', even for '2', even for '3', odd for '4',
// odd for '5', and even for '6'. See http://en.wikipedia.org/wiki/EAN-13
//
// Parity of next 6 digits
// Digit 0 1 2 3 4 5
// 0 Odd Odd Odd Odd Odd Odd
// 1 Odd Odd Even Odd Even Even
// 2 Odd Odd Even Even Odd Even
// 3 Odd Odd Even Even Even Odd
// 4 Odd Even Odd Odd Even Even
// 5 Odd Even Even Odd Odd Even
// 6 Odd Even Even Even Odd Odd
// 7 Odd Even Odd Even Odd Even
// 8 Odd Even Odd Even Even Odd
// 9 Odd Even Even Odd Even Odd
//
// Note that the encoding for '0' uses the same parity as a UPC barcode. Hence
// a UPC barcode can be converted to an EAN-13 barcode by prepending a 0.
//
// The encoding is represented by the following array, which is a bit pattern
// using Odd = 0 and Even = 1. For example, 5 is represented by:
//
// Odd Even Even Odd Odd Even
// in binary:
// 0 1 1 0 0 1 == 0x19
//
static final int[] FIRST_DIGIT_ENCODINGS = {
0x00, 0x0B, 0x0D, 0xE, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A
};
/**
* Start/end guard pattern.
*/
static final int[] START_END_PATTERN = {1, 1, 1,};
/**
* As above but also including the "even", or "G" patterns used to encode UPC/EAN digits.
*/
static final int[][] L_AND_G_PATTERNS;
/**
* "Odd", or "L" patterns used to encode UPC/EAN digits.
*/
static final int[][] L_PATTERNS = {
{3, 2, 1, 1}, // 0
{2, 2, 2, 1}, // 1
{2, 1, 2, 2}, // 2
{1, 4, 1, 1}, // 3
{1, 1, 3, 2}, // 4
{1, 2, 3, 1}, // 5
{1, 1, 1, 4}, // 6
{1, 3, 1, 2}, // 7
{1, 2, 1, 3}, // 8
{3, 1, 1, 2} // 9
};
/**
* Pattern marking the middle of a UPC/EAN pattern, separating the two halves.
*/
static final int[] MIDDLE_PATTERN = {1, 1, 1, 1, 1};
static {
L_AND_G_PATTERNS = new int[20][];
System.arraycopy(L_PATTERNS, 0, L_AND_G_PATTERNS, 0, 10);
for (int i = 10; i < 20; i++) {
int[] widths = L_PATTERNS[i - 10];
int[] reversedWidths = new int[widths.length];
for (int j = 0; j < widths.length; j++) {
reversedWidths[j] = widths[widths.length - j - 1];
}
L_AND_G_PATTERNS[i] = reversedWidths;
}
}
private static final int CODE_WIDTH = 3 + // start guard
(7 * 6) + // left bars
5 + // middle guard
(7 * 6) + // right bars
3; // end guard
private static final int DEFAULT_MARGIN = 10;
//This list should contain all positions of lines which should be longer than the other lines
private List<Integer> mLongLinePositions;
public CustomEAN13Writer() {
mLongLinePositions = new ArrayList<>();
}
/**
* #param target encode black/white pattern into this array
* #param pos position to start encoding at in {#code target}
* #param pattern lengths of black/white runs to encode
* #param startColor starting color - false for white, true for black
* #return the number of elements added to target.
*/
public int appendPatternAndConsiderLongLinePosition(boolean[] target, int pos, int[] pattern,
boolean startColor) {
boolean color = startColor;
int numAdded = 0;
for (int len : pattern) {
for (int j = 0; j < len; j++) {
//If the pattern is the start-, middle- or end-pattern save the position for rendering later
if (pattern.equals(START_END_PATTERN) || pattern.equals(MIDDLE_PATTERN) || pattern
.equals(START_END_PATTERN)) {
mLongLinePositions.add(pos);
}
target[pos++] = color;
}
numAdded += len;
color = !color; // flip color after each segment
}
return numAdded;
}
#Override
public boolean[] encode(final String contents) {
if (contents.length() != 13) {
throw new IllegalArgumentException(
"Requested contents should be 13 digits long, but got " + contents.length());
}
try {
if (!checkStandardUPCEANChecksum(contents)) {
throw new IllegalArgumentException("Contents do not pass checksum");
}
} catch (FormatException ignored) {
throw new IllegalArgumentException("Illegal contents");
}
int firstDigit = Integer.parseInt(contents.substring(0, 1));
int parities = FIRST_DIGIT_ENCODINGS[firstDigit];
boolean[] result = new boolean[CODE_WIDTH];
int pos = 0;
pos += appendPatternAndConsiderLongLinePosition(result, pos, START_END_PATTERN, true);
// See {#link #EAN13Reader} for a description of how the first digit & left bars are encoded
for (int i = 1; i <= 6; i++) {
int digit = Integer.parseInt(contents.substring(i, i + 1));
if ((parities >> (6 - i) & 1) == 1) {
digit += 10;
}
pos += appendPatternAndConsiderLongLinePosition(result, pos, L_AND_G_PATTERNS[digit],
false);
}
pos += appendPatternAndConsiderLongLinePosition(result, pos, MIDDLE_PATTERN, false);
for (int i = 7; i <= 12; i++) {
int digit = Integer.parseInt(contents.substring(i, i + 1));
pos += appendPatternAndConsiderLongLinePosition(result, pos, L_PATTERNS[digit], true);
}
appendPatternAndConsiderLongLinePosition(result, pos, START_END_PATTERN, true);
return result;
}
public BitMatrix encodeAndRender(String contents, int width, int height) {
boolean[] code = encode(contents);
int inputWidth = code.length;
// Add quiet zone on both sides.
int fullWidth = inputWidth + DEFAULT_MARGIN;
int outputWidth = Math.max(width, fullWidth);
int outputHeight = Math.max(1, height);
int multiple = outputWidth / fullWidth;
int leftPadding = (outputWidth - (inputWidth * multiple)) / 2;
BitMatrix output = new BitMatrix(outputWidth, outputHeight);
for (int inputX = 0, outputX = leftPadding; inputX < inputWidth;
inputX++, outputX += multiple) {
if (code[inputX]) {
int barcodeHeight = outputHeight;
//if the position isn't in the list for long lines we have to shorten the line by 5%
if (!mLongLinePositions.contains(inputX)) {
barcodeHeight = (int) ((float) outputHeight * 0.95f);
}
output.setRegion(outputX, 0, multiple, barcodeHeight);
}
}
return output;
}
/**
* Computes the UPC/EAN checksum on a string of digits, and reports whether the checksum is
* correct or not.
*
* #param s string of digits to check
* #return true iff string of digits passes the UPC/EAN checksum algorithm
* #throws FormatException if the string does not contain only digits
*/
static boolean checkStandardUPCEANChecksum(CharSequence s) throws FormatException {
int length = s.length();
if (length == 0) {
return false;
}
int sum = 0;
for (int i = length - 2; i >= 0; i -= 2) {
int digit = (int) s.charAt(i) - (int) '0';
if (digit < 0 || digit > 9) {
throw FormatException.getFormatInstance();
}
sum += digit;
}
sum *= 3;
for (int i = length - 1; i >= 0; i -= 2) {
int digit = (int) s.charAt(i) - (int) '0';
if (digit < 0 || digit > 9) {
throw FormatException.getFormatInstance();
}
sum += digit;
}
return sum % 10 == 0;
}
}
The second encode method returns an array of boolean that is a row of pixels. A true value is black, a false value is white. That array is extrapolated into your first image by: OneDimensionalCodeWriter::renderResult().
That method makes no provision for the human readable image. The separators are there in your first image, but they are not extended nor, obviously, is the human readable rendering of the number that is encoded.
My best advice is to fork the github repo and modify the renderResult method to do what you want. Obviously you need to provide something to your client, so I'd just do something quick in it's own branch. Ultimately the best thing is to do it correctly and offer the changes back to the zxing team.
I would assume that there should be a hint (EncodeHintType) added to allow a choice to make the barcode human readable. To save yourself time, I would post a message to their dev mailing list and see what they feel would be the best way to add this feature.