sorry Friends i did a mistake. I have did this mistake again. am really very sorry.
this is the Issue.
I have a time range like
int Starttime = 2 which mean(02:00)
int enttime = 8 which mean(08:00)
i want time in sum of bits,
example
00:00 1
01:00 2
02:00 4 -----
03:00 8 R
04:00 16 a
05:00 32 n
06:00 64 g
07:00 128 e
08:00 256 -----
and soo on till 23:00
so i need totalRange = 256+128+64+32+16+8+4 ;
it should be like this
sorry again.
Thanks
The table indicates that you want to map the hour value of a time to an integer value using this function:
int value = (int) Math.pow(2, hourValue);
or, in other words, 00:00h will map to 20, 12:00h to 212 and so on.
Now if you have need the sum of start and endtime, you can simple use the function from above and add the values:
int totalrange = (int) Math.pow(2, starttime) + (int) Math.pow(2, endtime);
Now if you have starttime=2 and endtime=23, this will give a result (written in binary):
01000000 00000000 00000100
shamelessly adapting polygenelubricants much faster solution:
int totalrange = (1 << starttime) + (1 << endtime);
This works, because 2i is equal to (1 << i).
System.out.println(Integer.toBinaryString(2+24)); // 11010
This uses the Integer.toBinaryString method. There's also toHexString, toOctalString, and a toString with variable radix.
If you need the string to be zero-padded to a specific width, you can write something simple like this:
static String binaryPadded(int n, int width) {
String s = Integer.toBinaryString(n);
return "00000000000000000000000000000000"
.substring(0, width - s.length()) + s;
}
//...
System.out.println(binaryPadded(2+24, 8)); // 00011010
There are different ways to zero pad a string to a fixed width, but this will work for any int value.
For hexadecimal or octal, you can use formatting string instead:
System.out.println(String.format("%04X", 255)); // 00FF
The specification isn't very clear, but it looks like you want this mapping:
0 -> 1
1 -> 2
2 -> 4
3 -> 8
4 -> 16
:
i -> 2i
In that case, your mapping is from i to (1 << i) (the << is the bitwise left-shift operator).
System.out.println(
(1 << 2) + (1 << 4)
); // 20
Note that depending on what is it that you're trying to do, you may also consider using a java.util.BitSet instead.
BitSet demonstration
This may be completely off-the-mark, but assuming that you're doing some sort of interval arithmetics, then BitSet may be the data structure for you (see also on ideone.com):
import java.util.BitSet;
//...
static String interval(BitSet bs) {
int i = bs.nextSetBit(0);
int j = bs.nextClearBit(i);
return String.format("%02d:00-%02d:00", i, j);
}
public static void main(String[] args) {
BitSet workTime = new BitSet();
workTime.set(9, 17);
System.out.println(interval(workTime));
// 09:00-17:00
BitSet stackOverflowTime = new BitSet();
stackOverflowTime.set(10, 20);
System.out.println(interval(stackOverflowTime));
// 10:00-20:00
BitSet busyTime = new BitSet();
busyTime.or(workTime);
busyTime.or(stackOverflowTime);
System.out.println(interval(busyTime));
// 09:00-20:00
}
Note that methods like nextSetBit and nextClearBit makes it easy to find empty/occupied time slots. You can also do intersect, or, and, etc.
This simple example only finds the first interval, but you can make this more sophisticated and do various arithmetics on non-contiguous time intervals.
Integer.toBinaryString(i)
Returns a string representation of the integer argument as anunsigned integer in base 2.
To compute the length of the time-interval, you have to do
int totalrange = endtime - starttime;
Perhaps this is what you're looking for:
int startTime = 2;
int endTime = 24;
int range = endTime - startTime;
System.out.println(range + " can be expressed as the following sum:");
for (int size = 1; range > 0; size <<= 1, range >>= 1)
if ((range & 1) != 0)
System.out.format("+ %02d:00%n", size);
Output:
22 can be expressed as the following sum:
+ 02:00
+ 04:00
+ 16:00
Related
Java's Random function takes a seed and produces the a sequence of 'psuedo-random' numbers.
(It is implemented based on some algorithm discussed in Donald Knuth, The Art of Computer Programming, Volume 3, Section 3.2.1.), but the article is too technical for me to understand)
Is there an inverse function of it?
That is, given a sequence of numbers, would it be possible to mathematically determine what the seed would be?
(, which means, brute-forcing doesn't count as a valid method)
[Edit]
There seems to be quite a number of comments here... I thought I'd clarify what I am looking for.
So for instance, the function y = f(x) = 3x has an inverse function, which is y = g(x) = x/3.
But the function z = f(x, y) = x * y does not have an inverse function, because (I could give a full mathematical proof here, but I don't want to sidetrack my main question), intuitively speaking, there are more than one pair of (x, y) such that (x * y) == z.
Now back to my question, if you say the function is not inversible, please explain why.
(And I am hoping to get answers from those who have really read to article and understand it. Answers like "It's just not possible" aren't really helping)
If we're talking about the Oracle (née Sun) implementation of java.util.Random, then yes, it is possible once you know enough bits.
Random uses a 48-bit seed and a linear congruential generator. These are not cryptographically safe generators, because of the tiny state size (bruteforceable!) and the fact that the output just isn't that random (many generators will exhibit small cycle length in certain bits, meaning that those bits can be easily predicted even if the other bits seem random).
Random's seed update is as follows:
nextseed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1)
This is a very simple function, and it can be inverted if you know all the bits of the seed by calculating
seed = ((nextseed - 0xBL) * 0xdfe05bcb1365L) & ((1L << 48) - 1)
since 0x5DEECE66DL * 0xdfe05bcb1365L = 1 mod 248. With this, a single seed value at any point in time suffices to recover all past and future seeds.
Random has no functions that reveal the whole seed, though, so we'll have to be a bit clever.
Now, obviously, with a 48-bit seed, you have to observe at least 48 bits of output or you clearly don't have an injective (and thus invertible) function to work with. We're in luck: nextLong returns ((long)(next(32)) << 32) + next(32);, so it produces 64 bits of output (more than we need). Indeed, we could probably make do with nextDouble (which produces 53 bits), or just repeated calls of any other function. Note that these functions cannot output more than 248 unique values because of the seed's limited size (hence, for example, there are 264-248 longs that nextLong will never produce).
Let's specifically look at nextLong. It returns a number (a << 32) + b where a and b are both 32-bit quantities. Let s be the seed before nextLong is called. Then, let t = s * 0x5DEECE66DL + 0xBL, so that a is the high 32 bits of t, and let u = t * 0x5DEECE66DL + 0xBL so that b is the high 32 bits of u. Let c and d be the low 16 bits of t and u respectively.
Note that since c and d are 16-bit quantities, we can just bruteforce them (since we only need one) and be done with it. That's pretty cheap, since 216 is only 65536 -- tiny for a computer. But let's be a bit more clever and see if there's a faster way.
We have (b << 16) + d = ((a << 16) + c) * 0x5DEECE66DL + 11. Thus, doing some algebra, we obtain (b << 16) - 11 - (a << 16)*0x5DEECE66DL = c*0x5DEECE66DL - d, mod 248. Since c and d are both 16-bit quantities, c*0x5DEECE66DL has at most 51 bits. This usefully means that
(b << 16) - 11 - (a << 16)*0x5DEECE66DL + (k<<48)
is equal to c*0x5DEECE66DL - d for some k at most 6. (There are more sophisticated ways to compute c and d, but because the bound on k is so tiny, it's easier to just bruteforce).
We can just test all the possible values for k until we get a value whos negated remainder mod 0x5DEECE66DL is 16 bits (mod 248 again), so that we recover the lower 16 bits of both t and u. At that point, we have a full seed, so we can either find future seeds using the first equation, or past seeds using the second equation.
Code demonstrating the approach:
import java.util.Random;
public class randhack {
public static long calcSeed(long nextLong) {
final long x = 0x5DEECE66DL;
final long xinv = 0xdfe05bcb1365L;
final long y = 0xBL;
final long mask = ((1L << 48)-1);
long a = nextLong >>> 32;
long b = nextLong & ((1L<<32)-1);
if((b & 0x80000000) != 0)
a++; // b had a sign bit, so we need to restore a
long q = ((b << 16) - y - (a << 16)*x) & mask;
for(long k=0; k<=5; k++) {
long rem = (x - (q + (k<<48))) % x;
long d = (rem + x)%x; // force positive
if(d < 65536) {
long c = ((q + d) * xinv) & mask;
if(c < 65536) {
return ((((a << 16) + c) - y) * xinv) & mask;
}
}
}
throw new RuntimeException("Failed!!");
}
public static void main(String[] args) {
Random r = new Random();
long next = r.nextLong();
System.out.println("Next long value: " + next);
long seed = calcSeed(next);
System.out.println("Seed " + seed);
// setSeed mangles the input, so demangle it here to get the right output
Random r2 = new Random((seed ^ 0x5DEECE66DL) & ((1L << 48)-1));
System.out.println("Next long value from seed: " + r2.nextLong());
}
}
I normally wouldn't just link articles... But I found a site where someone looks into this in some depth and thought it was worth posting. http://jazzy.id.au/default/2010/09/20/cracking_random_number_generators_part_1.html
It seems that you can calculate a seed this way:
seed = (seed * multiplier + addend) mod (2 ^ precision)
where multiplier is 25214903917, addend is 11, and precision is 48 (bits). You can't calculate what the seed was with only 1 number, but you can with 2.
EDIT: As nhahtdh said there's a part 2 where he delves into more of the math behind the seeds.
I would like to present an implementation to reverse a sequence of integers generated by nextInt().
The program will brute force on the lower 16-bit discarded by nextInt(), use the algorithm provided in the blog by James Roper to find previous seed, then check that upper 32 bit of the 48-bit seed are the same as the previous number. We need at least 2 integers to derive the previous seed. Otherwise, there will be 216 possibilities for the previous seed, and all of them are equally valid until we have at least one more number.
It can be extended for nextLong() easily, and 1 long number is enough to find the seed, since we have 2 pieces of upper 32-bit of the seed in one long, due to the way it is generated.
Note that there are cases where the result is not the same as what you set as secret seed in the SEED variable. If the number you set as secret seed occupies more than 48-bit (which is the number of bits used for generating random numbers internally), then the upper 16 bits of 64 bit of long will be removed in the setSeed() method. In such cases, the result returned will not be the same as what you have set initially, it is likely that the lower 48-bit will be the same.
I would like to give most the credit to James Roper, the author of this blog article which makes the sample code below possible:
import java.util.Random;
import java.util.Arrays;
class TestRandomReverse {
// The secret seed that we want to find
private static long SEED = 782634283105L;
// Number of random numbers to be generated
private static int NUM_GEN = 5;
private static int[] genNum(long seed) {
Random rand = new Random(seed);
int arr[] = new int[NUM_GEN];
for (int i = 0; i < arr.length; i++) {
arr[i] = rand.nextInt();
}
return arr;
}
public static void main(String args[]) {
int arr[] = genNum(SEED);
System.out.println(Arrays.toString(arr));
Long result = reverse(arr);
if (result != null) {
System.out.println(Arrays.toString(genNum(result)));
} else {
System.out.println("Seed not found");
}
}
private static long combine(int rand, int suffix) {
return (unsignedIntToLong(rand) << 16) | (suffix & ((1L << 16) - 1));
}
private static long unsignedIntToLong(int num) {
return num & ((1L << 32) - 1);
}
// This function finds the seed of a sequence of integer,
// generated by nextInt()
// Can be easily modified to find the seed of a sequence
// of long, generated by nextLong()
private static Long reverse(int arr[]) {
// Need at least 2 numbers.
assert (arr.length > 1);
int end = arr.length - 1;
// Brute force lower 16 bits, then compare
// upper 32 bit of the previous seed generated
// to the previous number.
for (int i = 0; i < (1 << 16); i++) {
long candidateSeed = combine(arr[end], i);
long previousSeed = getPreviousSeed(candidateSeed);
if ((previousSeed >>> 16) == unsignedIntToLong(arr[end - 1])) {
System.out.println("Testing seed: " +
previousSeed + " --> " + candidateSeed);
for (int j = end - 1; j >= 0; j--) {
candidateSeed = previousSeed;
previousSeed = getPreviousSeed(candidateSeed);
if (j > 0 &&
(previousSeed >>> 16) == unsignedIntToLong(arr[j - 1])) {
System.out.println("Verifying: " +
previousSeed + " --> " + candidateSeed);
} else if (j == 0) {
// The XOR is done when the seed is set, need to reverse it
System.out.println("Seed found: " + (previousSeed ^ MULTIPLIER));
return previousSeed ^ MULTIPLIER;
} else {
System.out.println("Failed");
break;
}
}
}
}
return null;
}
private static long ADDEND = 0xBL;
private static long MULTIPLIER = 0x5DEECE66DL;
// Credit to James Roper
// http://jazzy.id.au/default/2010/09/21/cracking_random_number_generators_part_2.html
private static long getPreviousSeed(long currentSeed) {
long seed = currentSeed;
// reverse the addend from the seed
seed -= ADDEND; // reverse the addend
long result = 0;
// iterate through the seeds bits
for (int i = 0; i < 48; i++)
{
long mask = 1L << i;
// find the next bit
long bit = seed & mask;
// add it to the result
result |= bit;
if (bit == mask)
{
// if the bit was 1, subtract its effects from the seed
seed -= MULTIPLIER << i;
}
}
return result & ((1L << 48) - 1);
}
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Best algorithm to count the number of set bits in a 32-bit integer?
How do I count the number of 1's a number will have in binary?
So let's say I have the number 45, which is equal to 101101 in binary and has 4 1's in it. What's the most efficient way to write an algorithm to do this?
Instead of writing an algorithm to do this its best to use the built in function. Integer.bitCount()
What makes this especially efficient is that the JVM can treat this as an intrinsic. i.e. recognise and replace the whole thing with a single machine code instruction on a platform which supports it e.g. Intel/AMD
To demonstrate how effective this optimisation is
public static void main(String... args) {
perfTestIntrinsic();
perfTestACopy();
}
private static void perfTestIntrinsic() {
long start = System.nanoTime();
long countBits = 0;
for (int i = 0; i < Integer.MAX_VALUE; i++)
countBits += Integer.bitCount(i);
long time = System.nanoTime() - start;
System.out.printf("Intrinsic: Each bit count took %.1f ns, countBits=%d%n", (double) time / Integer.MAX_VALUE, countBits);
}
private static void perfTestACopy() {
long start2 = System.nanoTime();
long countBits2 = 0;
for (int i = 0; i < Integer.MAX_VALUE; i++)
countBits2 += myBitCount(i);
long time2 = System.nanoTime() - start2;
System.out.printf("Copy of same code: Each bit count took %.1f ns, countBits=%d%n", (double) time2 / Integer.MAX_VALUE, countBits2);
}
// Copied from Integer.bitCount()
public static int myBitCount(int i) {
// HD, Figure 5-2
i = i - ((i >>> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
i = (i + (i >>> 4)) & 0x0f0f0f0f;
i = i + (i >>> 8);
i = i + (i >>> 16);
return i & 0x3f;
}
prints
Intrinsic: Each bit count took 0.4 ns, countBits=33285996513
Copy of same code: Each bit count took 2.4 ns, countBits=33285996513
Each bit count using the intrinsic version and loop takes just 0.4 nano-second on average. Using a copy of the same code takes 6x longer (gets the same result)
The most efficient way to count the number of 1's in a 32-bit variable v I know of is:
v = v - ((v >> 1) & 0x55555555);
v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
c = ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; // c is the result
Updated: I want to make clear that it's not my code, actually it's older than me. According to Donald Knuth (The Art of Computer Programming Vol IV, p 11), the code first appeared in the first textbook on programming, The Preparation of Programs for an Electronic Digital Computer by Wilkes, Wheeler and Gill (2nd Ed 1957, reprinted 1984). Pages 191–193 of the 2nd edition of the book presented Nifty Parallel Count by D B Gillies and J C P Miller.
See Bit Twidling Hacks and study all the 'counting bits set' algorithms. In particular, Brian Kernighan's way is simple and quite fast if you expect a small answer. If you expect an evenly distributed answer, lookup table might be better.
This is called Hamming weight. It is also called the population count, popcount or sideways sum.
The following is either from "Bit Twiddling Hacks" page or Knuth's books (I don't remember). It is adapted to unsigned 64 bit integers and works on C#. I don't know if the lack of unsigned values in Java creates a problem.
By the way, I write the code only for reference; the best answer is using Integer.bitCount() as #Lawrey said; since there is a specific machine code operation for this operation in some (but not all) CPUs.
const UInt64 m1 = 0x5555555555555555;
const UInt64 m2 = 0x3333333333333333;
const UInt64 m4 = 0x0f0f0f0f0f0f0f0f;
const UInt64 h01 = 0x0101010101010101;
public int Count(UInt64 x)
{
x -= (x >> 1) & m1;
x = (x & m2) + ((x >> 2) & m2);
x = (x + (x >> 4)) & m4;
return (int) ((x * h01) >> 56);
}
public int f(int n)
{
int result = 0;
for(;n > 0; n = n >> 1)
result += ((n & 1) == 1 ? 1 : 0);
return result;
}
The following Ruby code works for positive numbers.
count = 0
while num > 1
count = (num % 2 == 1) ? count + 1 : count
num = num >> 1
end
count += 1
return count
The fastest I have used and also seen in a practical implementation (in the open source Sphinx Search Engine) is the MIT HAKMEM algorithm. It runs superfast over a very large stream of 1's and 0's.
I'm creating a program to solve Project Euler Problem 303
My method to find f(n) is barely short of brute force:
static BigInteger findFn(int n){
Long Fn = new Long(n);
String test = Fn.toString();
Long multiplier = new Long("1");
long counter = 0;
boolean done = false;
BigInteger fn = new BigInteger("0");
while(!done){
counter = 0;
BigInteger tempOne = new BigInteger(multiplier.toString());
BigInteger tempTwo = new BigInteger(Fn.toString());
BigInteger product = tempOne.multiply(tempTwo);
test = product.toString();
for(int i = 0; i < test.toString().length(); i++){
if(Character.getNumericValue(test.toString().charAt(i)) <= 2){
counter++;
}else{
//Is it better to set done = true here as opposed to breaking?
break; //breaks if it encounters any number in the multiple >2.
}
}
if(counter == test.length()){
fn = product;
done = true;
break;
}
multiplier++;
}
return fn;
}
It works well on most numbers, but there are a few (usually those that end in 9) that it just gets stuck on.
I think that the BigIntegers slow it down, so firstly, is there anywhere I've used a BigInteger where it isn't necessary?
Secondly, there has to be either an alternate method or some sort of other trick to cut down on the number of loops that I haven't thought of.
Any thoughts to give me a push in the right direction?
Thanks!!
I'm thinking you could cut out 67% of your trials just by looking at the digit in the one's place in the tested number because if that doesn't go to 0, 1, or 2 then it doesn't matter what the rest go to.
Consider that if the number ends in a 1, then the number it is multiplied by must end with a 0, 1, or 2 in order for the last digit of the result to be <= 2. So you test 1 then 2, and if those don't work then you test 10, 11, 12, then 20, 21, 22. So if the test number ends in a 1, you've now cut down your trials by 70%.
For XXX2, the multiplier would have to end in 0, 1, 5, or 6. That removes 60%. You can continue for 3-9.
What about trying the other way?
I have solved this problem by generating numbers that are composed of 0, 1 and 2 from smallest to bigger and looking at whom this number is the multiple of. Moreover, I have used the pattern for 9, 99, etc. (btw, you don't need BigInteger other than them. Since you will precompute them, get rid of BigInteger) but I found their values like your bruteforce method by incrementing in the multiples of interested number as pointed out before. Result popped out in around 6 seconds. If you want to see my solution, here it is.
test is a string, so there's no need to call toString() on it. Not a big improvement, but it makes the code a little cleaner.
Just off the top of my head here's an algorithm that would avoid BigInteger altogether.
For each multiplier
Set carry = 0
Set multiple = ""
Iterate through the digits of the multiplier from right to left
Set temp = digit * n + carry
if (right-most digit of temp > 2)
break and go to next multiplier
else
Set carry = temp / 10 // drop last digit and carry result
This basically does a long multiplication with the opportunity to break out of it as soon as a digit > 2 is found. Note that, to solve the problem, we don't actually need to get F(n), just F(n)/n which is the first multiplier for which the above digit iteration completes. Then just sum the least multiplier for each n.
Without actually trying it out, i'm pretty sure that this will run with just int values.
Update
So I've been playing with some code, and got it to work for 1 <= n <= 100. Looks like the multiplier for n = 999 > 2^31, so we need to use at least 64-bit values. Not sure what the multiplier is yet. My code has been running in LinqPad for over 21 minutes and has passed 3.2*10^9 with no result yet. Of course, there could be a problem with my code.
Try keeping around the results as you go forward. You can use these to make lowerbound guesses for their multiples.
Suppose the acceptable LCM for some X is Y, with Y = RX. Then you know that Y is also a lowerbound for all {X, 2X, 3X, 4X, ... (R-1)X}.
Not sure if the following idea would help:
Let P(N, M) = digits of M base 10 are (<= 2) and M is a multiple of N.
Let G(N) = Some M such that P(N, M).
Let F(N) = M such that P(N, M) and M is minimal.
Important observation: F(N) <= G(N).
Would want G(N) to be "reasonable" in that it isn't gratuitously large and is easy to calculate. You might be able to caculate it effectively using F(N') on smaller components N' of N (digits of N perhaps).
Knowing G(N) might be extremely useful...
Perhaps you can work backwards with it.
Perhaps you can perform some sort of binary search with it.
If this technique is at all useful, I imagine the hard math would be to find G(N). The rest would probably be some clever computer science technique.
To reduce the number of iterations you may increment the trial product by 1 instead of incrementing the trial multiplier by 1. Then you check whether or not the trial product is divisible by f()'s argument. This will enable you to get to bigger values quicker because you can skip digit values 4 through 9 in the product when adding 1.
The below C code completes in under 5 minutes on a 2.4 GHz PC:
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stddef.h>
#include <time.h>
typedef unsigned uint;
typedef unsigned char uint8;
typedef unsigned long long uint64;
uint64 f(uint n, uint64* multiplier)
{
uint8 carry, digits[20]; // 20 digits max for 64-bit values
uint digcnt = 1, i;
uint64 result;
assert(n > 0);
#if 0
// short cut:
//
// f(9) = 12222 = 9 * 1358
// f(99) = 1122222222 = 99 * 11335578
// f(999) = 111222222222222 = 999 * 111333555778
// f(9999) = 11112222222222222222 = 9999 * 1111333355557778
if (n == 9999)
{
*multiplier = 11112222222222222222ULL / 9999;
return 11112222222222222222ULL;
}
#endif
memset(digits, 0, sizeof(digits));
for (;;)
{
carry = 1;
for (i = 0; carry; i++)
{
assert(i < sizeof(digits));
carry += digits[i];
digits[i] = carry % 3;
carry /= 3;
}
if (i >= digcnt) digcnt = i;
result = 0;
for (i = 0; i < digcnt; i++)
result = result * 10 + digits[digcnt - 1 - i];
if (result % n == 0)
{
*multiplier = result / n;
break;
}
}
return result;
}
int main(void)
{
uint i;
uint64 sum = 0, product, multiplier;
time_t t;
char* p;
for (i = 1; i <= 10000; i++)
{
product = f(i, &multiplier);
printf("%s ", ((time(&t), p = ctime(&t)), p[strlen(p) - 1] = '\0', p));
printf("f(%u) = %llu = %u * %llu\n", i, product, i, multiplier);
sum += multiplier;
}
printf("%s ", ((time(&t), p = ctime(&t)), p[strlen(p) - 1] = '\0', p));
printf("sum(f(n)/n) = %llu\n", sum);
return 0;
}
Output:
Mon Jan 9 12:18:22 2012 f(1) = 1 = 1 * 1
Mon Jan 9 12:18:22 2012 f(2) = 2 = 2 * 1
Mon Jan 9 12:18:22 2012 f(3) = 12 = 3 * 4
Mon Jan 9 12:18:22 2012 f(4) = 12 = 4 * 3
Mon Jan 9 12:18:22 2012 f(5) = 10 = 5 * 2
Mon Jan 9 12:18:22 2012 f(6) = 12 = 6 * 2
Mon Jan 9 12:18:22 2012 f(7) = 21 = 7 * 3
Mon Jan 9 12:18:22 2012 f(8) = 112 = 8 * 14
Mon Jan 9 12:18:22 2012 f(9) = 12222 = 9 * 1358
...
Mon Jan 9 12:18:39 2012 f(9998) = 111122211112 = 9998 * 11114444
Mon Jan 9 12:22:50 2012 f(9999) = 11112222222222222222 = 9999 * 1111333355557778
Mon Jan 9 12:22:50 2012 f(10000) = 10000 = 10000 * 1
Mon Jan 9 12:22:50 2012 sum(f(n)/n) = 1111981904675169
If you change #if 0 to #if 1 and enable the short cut mentioned in a comment by Peter Lawrey, it will complete in just about 1 minute.
Here's my contribution for this interesting problem. Pardon me for using Java and BigInteger but based on my loose testing it wasn't such a blocker after all (calculating sum [1, 100] takes less than a second and sum [1, 10000] roughly 4,5mins on my 2.4 dual core). And out of those 4+ mins around 4mins are spent on f(9999). Quite a surprise.
import java.math.BigInteger;
public class Main {
public static void main(String args[]) {
BigInteger result = BigInteger.ZERO;
for (int i = 1; i <= 10000; ++i) {
BigInteger r = f(BigInteger.valueOf(i));
System.out.println("i=" + i + " r=" + r);
result = result.add(r.divide(BigInteger.valueOf(i)));
}
System.out.println("result=" + result);
}
// Find smallest x * value which consists only of numbers {0, 1, 2}.
private static BigInteger f(BigInteger value) {
BigInteger retVal = value;
while (!check(retVal)) {
BigInteger remainder = remainder(retVal);
BigInteger mult = remainder.subtract(retVal.remainder(remainder))
.divide(value);
retVal = retVal.add(value.multiply(mult.max(BigInteger.ONE)));
}
return retVal;
}
// Find highest remainder for given value so that value % retVal =
// XYYYYY.. Where X > 2 and 0 <= Y <= 9.
private static BigInteger remainder(BigInteger value) {
BigInteger curVal = BigInteger.TEN;
BigInteger retVal = BigInteger.TEN;
while (value.compareTo(BigInteger.TEN) >= 0) {
curVal = curVal.multiply(BigInteger.TEN);
value = value.divide(BigInteger.TEN);
if (value.remainder(BigInteger.TEN).intValue() > 2) {
retVal = curVal;
}
}
return retVal;
}
// Check if given value contains only 0, 1 and 2.
private static boolean check(BigInteger value) {
do {
if (value.remainder(BigInteger.TEN).intValue() > 2) {
return false;
}
value = value.divide(BigInteger.TEN);
} while (value.compareTo(BigInteger.ZERO) == 1);
return true;
}
}
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Best algorithm to count the number of set bits in a 32-bit integer?
I want to find out how many 1s are there in binary representation of a number.I have 2 logic .
int count =0;
int no = 4;
while(no!=0){
int d = no%2;
if(d==1)
count++;
no = no/2;
str = str+ d;
}
Now second logic is to keep on masking number iteratively with 1,2,4,8,32 and check if result is 1,2,4, 8..... Am not geting what should be ending condition for this loop.
Use Java API(java 5 or above).
Integer.bitCount(int);
Long.bitCount(long);
NOTE: The above java methods are based on hacker's delight
faster than any of the earlier answers:
(proportional to number of 1 bits rather than total bits)
public class Foo {
public static void main(String[] argv) throws Exception {
int no = 12345;
int count;
for (count = 0; no > 0; ++count) {
no &= no - 1;
}
System.out.println(count);
}
}
Looks like c/c++/c#, if so you have shifting.. just loop to N-1 bits from 0 and use sum+=(value>>i)&1
Ie: you always check the last/right most bit but move the binary representation of the number to the right for every iteration until you have no more bits to check.
Also, think about signed/unsigned and any integer format. But you dont state how that should be handled in the question.
We can make use of overflow for your loop:
int count = 0;
int number = 37;
int mask = 1;
while(mask!=0)
{
int d = number & mask;
if(d != 0)
count++;
/* Double mask until we overflow, which will result in mask = 0... */
mask = mask << 1;
str = str+ d;
}
One idea that's commonly employed for counting ones is to build a lookup table containing the answers for each individual byte, then to split apart your number into four bytes and sum the totals up. This requires four lookups and is quite fast. You can build this table by writing a program that manually computes the answer (perhaps using your above program), and then can write a function like this:
private static final int[] BYTE_TOTALS = /* ... generate this ... */;
public static int countOneBits(int value) {
return BYTE_TOTALS[value & 0xFF] +
BYTE_TOTALS[value >>> 8 & 0xFF] +
BYTE_TOTALS[value >>> 16 & 0xFF] +
BYTE_TOTALS[value >>> 24 & 0xFF];
}
Hope this helps!
There are various ways to do this very fast.
MIT HAKMEM Count
int no =1234;
int tmp =0;
tmp = no - ((no >> 1) & 033333333333) - ((no >> 2) & 011111111111);
System.out.println( ((tmp + (tmp >> 3)) & 030707070707) % 63);
Your end condition should be keeping track of the magnitude of the bit you are at; if it is larger than the original number you are done (will get only 0s from now on).
Oh, and since you didn't specify a language, here's a Ruby solution :)
class Integer
def count_binary_ones
to_s(2).scan('1').length
end
end
42.count_binary_ones #=> 3
How about using the BigInteger class.
public void function(int checkedNumber) {
BigInteger val = new BigInteger(String.valueOf(checkedNumber));
val = val.abs();
int count = val.bitCount();
String binaryString = val.toString(2);
System.out.println("count = " + count);
System.out.println("bin = " + binaryString);
}
The result of function(42); is following.
count = 3
bin = 101010
I'm trying to store a number as a binary string in an array but I need to specify how many bits to store it as.
For example, if I need to store 0 with two bits I need a string "00". Or 1010 with 6 bits so "001010".
Can anyone help?
EDIT: Thanks guys, as I'm rubbish at maths/programming in general I've gone with the simplest solution which was David's. Something like:
binaryString.append(Integer.toBinaryString(binaryNumber));
for(int n=binaryString.length(); n<numberOfBits; n++) {
binaryString.insert(0, "0");
}
It seems to work fine, so unless it's very inefficient I'll go with it.
Use Integer.toBinaryString() then check the string length and prepend it with as many zeros as you need to make your desired length.
Forget about home-made solutions. Use standard BigInteger instead. You can specify number of bits and then use toString(int radix) method to recover what you need (I assume you need radix=2).
EDIT: I would leave bit control to BigInteger. The object will internally resize its bit buffer to fit the new number dimension. Moreover arithmetic operations can be carried out by means of this object (you do not have to implement binary adders/multipliers etc.). Here is a basic example:
package test;
import java.math.BigInteger;
public class TestBigInteger
{
public static void main(String[] args)
{
String value = "1010";
BigInteger bi = new BigInteger(value,2);
// Arithmetic operations
System.out.println("Output: " + bi.toString(2));
bi = bi.add(bi); // 10 + 10
System.out.println("Output: " + bi.toString(2));
bi = bi.multiply(bi); // 20 * 20
System.out.println("Output: " + bi.toString(2));
/*
* Padded to the next event number of bits
*/
System.out.println("Padded Output: " + pad(bi.toString(2), bi.bitLength() + bi.bitLength() % 2));
}
static String pad(String s, int numDigits)
{
StringBuffer sb = new StringBuffer(s);
int numZeros = numDigits - s.length();
while(numZeros-- > 0) {
sb.insert(0, "0");
}
return sb.toString();
}
}
This is a common homework problem. There's a cool loop that you can write that will compute the smallest power of 2 >= your target number n.
Since it's a power of 2, the base 2 logarithm is the number of bits. But the Java math library only offers natural logarithm.
math.log( n ) / math.log(2.0)
is the number of bits.
Even simpler:
String binAddr = Integer.toBinaryString(Integer.parseInt(hexAddr, 16));
String.format("%032", new BigInteger(binAddr));
The idea here is to parse the string back in as a decimal number temporarily (one that just so happens to consist of all 1's and 0's) and then use String.format().
Note that you basically have to use BigInteger, because binary strings quickly overflow Integer and Long resulting in NumberFormatExceptions if you try to use Integer.fromString() or Long.fromString().
Try this:
String binaryString = String.format("%"+Integer.toString(size)+"s",Integer.toBinaryString(19)).replace(" ","0");
where size can be any number the user wants
Here's a simple solution for int values; it should be obvious how to extend it to e.g. byte, etc.
public static String bitString(int i, int len) {
len = Math.min(32, Math.max(len, 1));
char[] cs = new char[len];
for (int j = len - 1, b = 1; 0 <= j; --j, b <<= 1) {
cs[j] = ((i & b) == 0) ? '0' : '1';
}
return new String(cs);
}
Here is the output from a set of sample test cases:
0 1 0 0
0 -1 0 0
0 40 00000000000000000000000000000000 00000000000000000000000000000000
13 1 1 1
13 2 01 01
13 3 101 101
13 4 1101 1101
13 5 01101 01101
-13 1 1 1
-13 2 11 11
-13 3 011 011
-13 4 0011 0011
-13 5 10011 10011
-13 -1 1 1
-13 40 11111111111111111111111111110011 11111111111111111111111111110011
Of course, you're on your own to make the length parameter adequate to represent the entire value.
import java.util.BitSet;
public class StringifyByte {
public static void main(String[] args) {
byte myByte = (byte) 0x00;
int length = 2;
System.out.println("myByte: 0x" + String.valueOf(myByte));
System.out.println("bitString: " + stringifyByte(myByte, length));
myByte = (byte) 0x0a;
length = 6;
System.out.println("myByte: 0x" + String.valueOf(myByte));
System.out.println("bitString: " + stringifyByte(myByte, length));
}
public static String stringifyByte(byte b, int len) {
StringBuffer bitStr = new StringBuffer(len);
BitSet bits = new BitSet(len);
for (int i = 0; i < len; i++)
{
bits.set (i, (b & 1) == 1);
if (bits.get(i)) bitStr.append("1"); else bitStr.append("0");
b >>= 1;
}
return reverseIt(bitStr.toString());
}
public static String reverseIt(String source) {
int i, len = source.length();
StringBuffer dest = new StringBuffer(len);
for (i = (len - 1); i >= 0; i--)
dest.append(source.charAt(i));
return dest.toString();
}
}
Output:
myByte: 0x0
bitString: 00
myByte: 0x10
bitString: 001010
So here instead of 8 you can write your desired length and it will append zeros accordingly. If the length of your mentioned integer exceeds that of the number mentioned then it will not append any zeros
String.format("%08d",1111);
Output:00001111
String.format("%02d",1111);
output:1111