I am working on a program right now and part of it requires me to find the total amount of digits between two integers, I have figured it out for integers that have the same amount of digits, e.g. 1234 and 4980 (both have four digits) but I can't seem to figure it out for the integers that don't have the same amount of digits, i.e. 3 and 5698 (3 only has one digit and 5698 has four). How might I go about this?
Boy, the algorithm is not obvious – your last comment is rather crucial.
Evidently this question boils down to:
For each 'number' between the 2, including both of the edges, count how many digits that number has.
Sum those up.
For your example it's simply (4980 - 1234 + 1) * 4 = 14988.
Sounds like you simply need to for-loop: for (int i = 1234; i <= 4980; i++), and then for each i just figure out how many digits there are and add those.
An straightforward way is to use logarithms. The number of digits in an integer n is (int)Math.log10(n)+1. Assuming you are doing inclusive computations on first thru last it would be as follows:
int sum = 0;
int first = 3;
int last = 3333;
for (int i = first; i <= last; i++) {
sum += Math.log10(i)+1;
}
System.out.println(sum);
prints
12223
But a more efficient and perhaps less obvious way it to forgo logs and simply compute in pieces. This will reduce number of iterations of the loop. This works by computing the number of digits and the power in increments. I put in print statements so you can see the progression.
int digits = 1;
int power = 10;
int limit = last;
sum = 0;
while(power < limit) {
if (power > first) {
sum += (power - first) * digits;
System.out.println(power + " " + first + " " + digits + " : partial running sum = " + sum);
first = power;
}
digits++;
power*= 10;
}
sum += (limit - power/10 + 1)*digits;
System.out.println(limit + " " + power/10 + " " + digits + " : partial running sum = " + sum);
System.out.println(sum);
prints
10 3 1 : partial running sum = 7
100 10 2 : partial running sum = 187
1000 100 3 : partial running sum = 2887
3333 1000 4 : final sum = 12223
12223
I was asked below question in an interview:
Every number can be described via the addition and subtraction of powers of 2. For example, 29 = 2^0 + 2^2 + 2^3 + 2^4.
Given an int n, return minimum number of additions
and subtractions of 2^i to get n.
Example 1:
Input: 15
Output: 2
Explanation: 2^4 - 2^0 = 16 - 1 = 15
Example 2:
Input: 8
Output: 1
Example 3:
Input: 0
Output: 0
Below is what I got but is there any way to improve this or is there any better way to solve above problem?
public static int minPowerTwo(int n) {
if (n == 0) {
return 0;
}
if (Integer.bitCount(n) == 1) {
return 1;
}
String binary = Integer.toBinaryString(n);
StringBuilder sb = new StringBuilder();
sb.append(binary.charAt(0));
for (int i = 0; i < binary.length() - 1; i++) {
sb.append('0');
}
int min = Integer.parseInt(sb.toString(), 2);
sb.append('0');
int max = Integer.parseInt(sb.toString(), 2);
return 1 + Math.min(minPowerTwo(n - min), minPowerTwo(max - n));
}
Well... we can deduce that each power of two should be used only once, because otherwise you can get the same result a shorter way, since 2x + 2x = 2x+1, -2x - 2x = -2x+1, and 2x - 2x = 0.
Considering the powers used in order, each one has to change the corresponding bit from an incorrect value to the correct value, because there will be no further opportunities to fix that bit, since each power is used only once.
When you need to add or subtract, the difference is what happens to the higher bits:
000000 000000 111100 111100
+ 100 - 100 + 100 - 100
------ ------ ------ ------
000100 111100 000000 111000
One way, all the higher bits are flipped. The other way they are not.
Since each decision can independently determine the state of all the higher bits, the consequences of choosing between + or - are only relevant in determining the next power of 2.
When you have to choose + or -, one choice will correct 1 bit, but the other choice will correct 2 bits or more, meaning that the next bit that requires correction will be higher.
So, this problem has a very straightforward solution with no dynamic programming or searching or anything like that:
Find the smallest power of 2 that needs correction.
Either add it or subtract it. Pick the option that corrects 2 bits.
Repeat until all the bits are correct
in java, that would look like this. Instead of finding the operations required to make the value, I'll find the operations required to change the value to zero, which is the same thing with opposite signs:
int minPowersToFix(int val) {
int result = 0;
while(val!=0) {
++result;
int firstbit = val&-val; //smallest bit that needs fixed
int pluscase = val+firstbit;
if ((pluscase & (firstbit<<1)) == 0) {
val+=firstbit;
} else {
val-=firstbit;
}
}
return result;
}
And, here is a test case to check whether a solution is correct, written in Java.
(It was written for my solution, which is proven not correct in some case, so I removed that answer, but the test case is still relevant.)
Matt Timmermans's answer passes all the test cases, including negative numbers.
And, Integer.bitCount(val ^ (3 * val)) passes most of them, except when input is Integer.MAX_VALUE.
Code
MinCountOf2PowerTest.java
import org.testng.Assert;
import org.testng.annotations.Test;
public class MinCountOf2PowerTest {
#Test
public void testPositive() {
// no flip,
Assert.assertEquals(MinCountOf2Power.minCount(Integer.parseInt("01010001", 2)), 3);
// flip,
Assert.assertEquals(MinCountOf2Power.minCount(Integer.parseInt("011", 2)), 2);
Assert.assertEquals(MinCountOf2Power.minCount(Integer.parseInt("0111", 2)), 2);
Assert.assertEquals(MinCountOf2Power.minCount(Integer.parseInt("01111", 2)), 2);
Assert.assertEquals(MinCountOf2Power.minCount(Integer.MAX_VALUE), 2);
Assert.assertEquals(MinCountOf2Power.minCount(Integer.parseInt("01101", 2)), 3);
Assert.assertEquals(MinCountOf2Power.minCount(Integer.parseInt("011011", 2)), 3);
// flip, there are multiple flippable location,
Assert.assertEquals(MinCountOf2Power.minCount(Integer.parseInt("0100000111", 2)), 3);
Assert.assertEquals(MinCountOf2Power.minCount(Integer.parseInt("010010000000111", 2)), 4);
Assert.assertEquals(MinCountOf2Power.minCount(Integer.parseInt("0100100000001111111", 2)), 4);
Assert.assertEquals(MinCountOf2Power.minCount(Integer.parseInt("010011000000001111111", 2)), 5);
}
#Test
public void testZero() {
Assert.assertEquals(MinCountOf2Power.minCount(0), 0);
}
#Test
public void testNegative() {
Assert.assertEquals(MinCountOf2Power.minCount(-1), 1);
Assert.assertEquals(MinCountOf2Power.minCount(-9), 2);
Assert.assertEquals(MinCountOf2Power.minCount(-100), 3);
}
// a positive number has the same result as its negative number,
#Test
public void testPositiveVsNegative() {
for (int i = 1; i <= 1000; i++) {
Assert.assertEquals(MinCountOf2Power.minCount(i), MinCountOf2Power.minCount(-i));
}
Assert.assertEquals(MinCountOf2Power.minCount(Integer.MAX_VALUE), MinCountOf2Power.minCount(-Integer.MAX_VALUE));
}
// corner case - ending 0,
#Test
public void testCornerEnding0() {
Assert.assertEquals(MinCountOf2Power.minCount(Integer.parseInt("01110", 2)), 2);
Assert.assertEquals(MinCountOf2Power.minCount(Integer.parseInt("011110", 2)), 2);
Assert.assertEquals(MinCountOf2Power.minCount(Integer.parseInt("011100", 2)), 2);
Assert.assertEquals(MinCountOf2Power.minCount(Integer.parseInt("0111000", 2)), 2);
Assert.assertEquals(MinCountOf2Power.minCount(Integer.parseInt("01110000", 2)), 2);
}
// input from OP's question, refer: https://stackoverflow.com/questions/57797157
#Test
public void testOpInput() {
Assert.assertEquals(MinCountOf2Power.minCount(15), 2);
Assert.assertEquals(MinCountOf2Power.minCount(8), 1);
Assert.assertEquals(MinCountOf2Power.minCount(0), 0);
}
}
Tips:
It's written in Java, and use TestNG.
But you can use JUnit instead simply by replacing the import statement, I guess.
Or translate to other languages by coping the input / output value pairs with specific syntax.
I also found that a positive integer always has the same result as its negative number.
And there is a test case included to proved that.
I wrote this algorithm to solve the problem.
Given N a positive integer:
Find the highest power of 2 A and the lowest power of 2 B, such that A ≤ N ≤ B and A≠B. In other words find in what interval of
consecutive powers of 2 N belongs;
Find if N is closer to A or B, for example by comparing N with the mid value between A and B (It is their average, and since B=2×A the average is 3×A/2 or 1.5×A)
If N is closer to the lower bound (A) than N = A + δ: Append "subtract B" to the explanation message;
If N is closer to the higher bound (B) than N = B - δ: Append "add A" to the explanation message;
Replace N with δ and repeat
The number of iterations minus 1 is the solution you are looking for.
To solve step 1 I wrote this support method that returns the closest power of 2 that is smaller than input, that is A (and we can get B because it is just the double of A)
public int getClosestLowerboundPowerof2 (int n)
{
int i = 1;
while (i<=n/2){
i*=2;
}
return i;
}
The rest is done here:
int operations;
String explanation = "";
if (input>0){
operations = -1;
int n = input, a;
while (n >= 1) {
operations++;
a = getClosestLowerboundPowerof2(n);
if (n > a*1.5) {
explanation += " - "+ a * 2;
n = a * 2 - n;
} else {
explanation += " + " + a;
n -= a;
}
}
System.out.println(input + " = " + explanation.substring(3,explanation.length()) + ", that " + ((operations==1)?"is":"are") + " "+ operations + " operation" + ((operations==1)?"":"s"));
}
else{
System.out.println("Input must be positive");
}
As an example with input = 403 it would print:
403 = 512 - 128 + 16 + 2 + 1, that are 4 operations
Hope I helped!
NOTE: I first misinterpreted the question so I put effort in writing a detailed answer to the wrong problem...
I'm keeping here the original answer because it may be interesting for somebody.
The problem is actually a mathematical argument: how to convert a
number from base 10 to base 2, and they just asked you to implement
an algorithm for that.
Here some theory about this concept and here a method for
reference.
Programmatically I'm interpreting the problem as "Given an integer
print a string of its representation in base 2". For instance given
100 print 2^6 + 2^5 + 2^2. As the linked wiki on radixes explains,
that there is no need for subtractions, so there will only be
additions.
The shortest way to do is to start from n, halve it at each iteration
(i), and write 2^i only if this number (m) is odd. This is tested
with modulo operator (% in java). So the method will be just
this:
public String from10to2(int n){
String str = "";
for (int m = n, i=0; m>=1; m/=2, i++){
str = ((m%2==1)?"+ 2^"+i+" ":"")+str; //"adds '+ 2^i' on top of the string when m is odd, keep str the same otherwise
}
return str.substring(2,str.length()); //debug to remove " + " at the start of the string
}
The content of the for may look inintuitive because I put effort to
make the code as short as possible.
With little effort my method can be generalized to convert a number in
base 10 to any base:
public String baseConverter(int targetBase, int decimalNumber){
String str = "";
for (int m = decimalNumber, i=0; m>=1; m/=targetBase, i++){
str = ((m%targetBase==1)?"+ "+targetBase+"^"+i+" ":"")+str; //"adds '+ x^i' on top of the string when m is odd, keep str the same
otherwise
}
return str.substring(2,str.length()); //debug to remove " + " at the start of the string
}
PS: I didn't use StringBuilder because it's not conceived to append a string on the start. The use of the String concatenation as I
did is argument of debate (someone approve it, other don't).
I guess
For example, 29 = 2^0 + 2^2 + 2^3 + 2^4
is not a correct example in the context of this question. As far as I understand, I should be able to do like
29 = 2^5 - 2^2 + 2^0
Alright, basically this is a math problem. So if math isn't your best suit like me then i would advise you to consider logarithm in the first place whenever you see exponentials in a question. Sometimes it is very useful like in this case since it reduces this problem to a sort of coin change problem with dynamical denominators and also subtraction is allowed.
First I need to find the biggest n that's close to the target.
Lets find the exact n value in 2^n = 29 which is basically log
(2^n) = log 29, which is n log 2 = log 29 so n = log 29 / log
2. Which happens to be 4.857980995127573 and now i know that i
will start with by rounding it to 5.
2^5 is an overshoot. Now i need to reach 32-29 = 3 and also since 32 > 29 the result, 2^2 will be subtracted.
Now we have 2^5 - 2^2 which is 28 and less than 29. Now we need to add the next result and our target is 1.
Ok here is a simple recursive code in JS. I haven't fully tested but seemingly applies the logic just fine.
function pot(t, pr = 0){ // target and previous result
var d = Math.abs(t - pr), // difference
n = Math.round(Math.log(d)/Math.log(2)), // the n figure
cr = t > pr ? pr + 2**n // current result
: pr - 2**n;
return t > cr ? `2^${n} + ` + pot(t, cr) // compose the string result
: t < cr ? `2^${n} - ` + pot(t, cr)
: `2^${n}`;
}
console.log(pot(29));
console.log(pot(1453));
console.log(pot(8565368));
This seems pretty trivial to solve for the cases presented in the examples, like:
0111...1
You can replace any of this pattern with just two powers; i.e.: 7 = 8 - 1 or 15 = 16 - 1 and so on.
You can also deduce that if there are less then 3 consecutive ones, you don't gain much, for example:
0110 (4 + 2)
0110 (8 - 2)
But at the same time, you don't lose anything by doing that operation; in contrast for some cases this is even beneficial:
0110110 - // 54, this has 4 powers
we can take the "last" 0110 and replace it with 1000 - 0010 (8-2) or:
0111000 - 000010 (56 - 2)
but now we can replace 0111 with just two powers : 1000 - 0001.
As such a simple "replace" algorithm can be made:
static int count(int x) {
String s = new StringBuffer(Integer.toBinaryString(x)).reverse().toString() + "0";
Pattern p = Pattern.compile("1+10");
Matcher m = p.matcher(s);
int count = 0;
while (m.find()) {
++count;
s = m.replaceFirst("1");
m = p.matcher(s);
}
return Integer.bitCount(Integer.parseInt(s, 2)) + count;
}
∑i=1n1i
In other words, the method should generate the following sequence:
1+12+13+14+15+⋯
I've been stumped on this problem for quite a bit. Having a tough time understand what "n" stands for in the equation and applying it to my for loop.
Would a for loop be optimal for solving this? Or should I just use a formula and somehow solve it then?
public static void main(String[] args) {
//Chapter 4 Exercise 1
System.out.println("--Chapter 4, Exercise 1");
System.out.println("How many integers do you want?:");
Scanner console = new Scanner(System.in);
int numb = console.nextInt();
fractionSum(numb)
public static double fractionSum(int numb) {
for(int i = 1; i <numb; i++) {
if (i !=1)
System.out.print("1 + 1" + i);
else
System.out.print("1");
}
return(numb);
}
1+12+13+14+15+⋯
Should be the output.
My output is coming out as:
11 + 121 + 131 + 141 + 15
Answering the first part of your question:
∑i=1n1i is known as the Harmonic Sum - the output you give in your question is wrong, harmonic sum can be described as the sum of reciprocals of the positive integers - for example:
H1 = 1
H2 = 1 + 1/2 = 1.5
H3 = 1 + 1/2 + 1/3 = 1.8333
H4 = 1 + 1/2 + 1/3 + 1/4 = 2.0833
H(n) = 1 + 1/2 + 1/3 + 1/4 ... + 1/n = answer ---> see what n is now?
You should use a for-loop for this, and its not very complex. Hopefully, this answer will clear up the task for you (I assume homework from Chapter 4 Exercise 1) and you can try again.
Here:
class Harmonic {
public static void main(String… s) {
int n, i;
float sum = 0;
n = Integer.parseInt(s[0]);
for (i = 1; i <= n; i++) {
sum = sum + (float) 1 / i;
}
System.out.println(“nSum = ”+sum);
}
}
Returns a string consisting of a Hailstone sequence beginning with the positive integer n and ending with 1. The
string should consist of a sequence of numerals, with each numeral followed by a single space. When a numeral m
(other than 1) appears in the sequence, it should be followed by nextHailstone(m).
Examples: nextHailstone(1) is "1 " and nextHailstone(5) is "5 16 8 4 2 1 ".
public static String hailstones (int n)
{
int calculation = 1;
System.out.print(n + " ");
while (n > 1)
{
if (n % 2 == 0)
{
n /= 2;
}
else
{
n = (n*3) + 1;
}
calculation++;
System.out.print(n + " ");
}
return " ";
}
The code works fine when I call the method in the main method but the test case for it is failing.
#Test
public void testHailstones ()
{
assertEquals("1 ", hailstones(1));
assertEquals("16 8 4 2 1 ", hailstones(16));
assertEquals("7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1 ", hailstones(7));
}
Those are the test cases. any insight into this would be great. thanks!
You return " " every time the function is called. You need to build up an internal string and return that as result.
Write statements that can be used in a Java Program two integers and display the number of even integers that lie between them. For example, the number of even integers that lie between 12 and 5 are 4
So far below is what i have.... the program outputs all the numbers between the two integers, and not the actual number of even integers.
Can someone please help / tell me what i am doing wrong ?
import java.util.Scanner;
public class evenNumberPrinter {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter the smaller integer");
int numOne = keyboard.nextInt();
System.out.println("Enter the larger integer");
int numTwo = keyboard.nextInt();
for (int i = numOne; i <= numTwo; i++) {
System.out.println(i + " ");
}
}
}
to calculate count of even numbers you don't have to use for loop, here is the formula:
static long evenCount(long a, long b) {
return ((Math.abs(a - b) + 1) >>> 1) + ((~((a & 1) | (b & 1))) & 1);
}
some clarification:
zero (0) is even number
count of even numbers obviously depends on distance between two values, lets pull some data:
0-0 - 1 number, distance 0 (0)
0-1 - 1 number, distance 1
0-2 - 2 numbers, distance 2 (0, 2)
0-3 - 2 numbers, distance 3
0-4 - 3 numbers, distance 4 (0, 2, 4)
0-5 - 3 numbers, distance 5
0-6 - 4 numbers, distance 6 (0, 2, 4, 6)
1-1 - no even, distance 0
1-2 - 1 number, distance 1 (2)
so, count of even numbers is determined by (distance+1)/2 plus one if both numbers are even
so, if we take distance Math.abs(a-b) + 1 divide it by two (>>>1) and then add 1 if and only if both numbers are even (a&1)==0
Another solution is to use pure math:
round the smaller number to the next even number (e.g. 5 to 6)
round the bigger number to the previous even number (e.g. 13 to 12)
subtract from the bigger rounded the smaller, e.g. 12-6 = 6
since even numbers are every second, divide it by 2 plus add one to count the first number of the range as well, that is 3+1=4
That is:
public static void main(final String[] args) {
final int number1=1;
final int number2=6;
int min=Math.min(number1, number2);
int max=Math.max(number1, number2);
min=min+min%2; // round up
max=max-max%2; // round down
final int evens=(max-min)/2+1; // even range plus the first number
System.out.println(evens); // Look ma, no loops
}
Edited to include explanation
Your for loop is doing nothing more than printing each number between numOne and numTwo. What you want to do is check to see if i is even or odd which can be accomplished using the modulus operator if i modulus 2 equals zero, then that number is even, and you should increment a counter variable each time this is true.
Change your for loop to something like this:
int evenCounter = 0;
for (int i = numOne; i < numTwo; i++){
if (i % 2 == 0){
System.out.print(i + " ");
evenCounter++;
}
}
System.out.println("There are " + evenCounter + " even numbers between " +
numOne + " and " + numTwo);
A little more optimal solution (if you want to print the numbers). Testing for parity (odd vs even) can be done only once, before entering the loop. Afterwards, just stay on even numbers by incrementing by 2.
int n = numOne;
int evenCount = 0;
if ((n%2)==1) { n++; }
while (n <= numTwo) {
System.out.println(n);
n += 2;
evenCount ++;
}
System.out.println( "There are " + evenCount + " even numbers between " + numOne + " and " + numTwo );
However, if your goal is only to determine how many there are (not print them), this is not optimal. A mathematical solution will be much faster.
int n = 0; //this is your counter
for (int i = numOne; i < numTwo; i++) { //use < numTwo instead of <= numTwo
//so it doesn't count numTwo as an int between your range
if (i%2 == 0) {n++;} //checks to see if number is even
// if it is, it adds one to the counter and moves on
}
System.out.println("there are " +n+ "even numbers between " +numOne+ " and " +numTwo); //prints out how many even ints were counted.