I've been a zone leader with DZone since 2008, and I'm crazy about community. Every day I get to work with the best that JavaScript, HTML5, Android and iOS has to offer, creating apps that truly make at difference, as principal front-end architect at Avego. James is a DZone Zone Leader and has posted 639 posts at DZone. You can read more from them at their website. View Full User Profile

Thursday Code Puzzler: Binary Clock

03.28.2013
| 5184 views |
  • submit to reddit

Thursday is code puzzler day here at DZone. The idea is simple: solve the coding problem as efficiently as you can, in any language or framework that you find suitable.

Note: Even though there really is nothing stopping you from finding a solution to this on the internet, try to keep honest, and come up with your own answer.  It's all about the participation!

Do you have code puzzlers that you'd like to share with the DZone community?  If so, please submit here. 

How Many 1's Appear in A Binary Clock Across an Entire Day

Say you have a binary clock, where 09:30:22 would be displayed as

Hour:       00001001
Minute:    00011110
Second:   00010110

Calculate the number of 1's that would appear over the course of an entire day of military time starting from 00:00:00 all the way up to 23:59:59


Catch up on all our previous puzzlers here.

 

Comments

Adrian Buturuga replied on Thu, 2013/03/28 - 12:57am

What did you feel the need to specify "entire day of military time" ?

Military time wasn't supposed to be 0605 hours? (meaning 06:05:00 ?) - eg without seconds.

Als you represented numbers with 8 bits (0-255 values) which is overkill for 0-59 interval and too short for military time.

Vijay Nathani replied on Thu, 2013/03/28 - 12:59am

Groovy

def countOfOnesInBinary(r) { r.sum { Integer.toBinaryString(it).count('1') } }
assert 396 == countOfOnesInBinary(0..23) + countOfOnesInBinary(0..59) * 2 

Carl Rischar replied on Thu, 2013/03/28 - 11:46am

Scala

(for (h <- 0 until 24; 
    m <- 0 until 60; 
    s <- 0 until 60) yield {
      "%02d%02d%02d".format(h, m, s).toInt.toBinaryString.count( _ == '1')
}).sum

Vijay Nathani replied on Thu, 2013/03/28 - 2:38pm

 In my previous code, I was not considering the same hour being displayed for every minute and every second. So to remove that bug, the new code in Groovy:

def countOfOnesInBinary(r) { 
	r.sum { Integer.toBinaryString(it).count('1') } 
}
assert 682560 == countOfOnesInBinary(0..23) * 60 * 60 + countOfOnesInBinary(0..59)  * 24 * 60 * 2 

David Whatever replied on Thu, 2013/03/28 - 5:37pm

import java.util.BitSet;
public class Puzzler2 {
	public static void main(String[] args) {
		byte[] minutes_seconds = new byte[60];
		byte[] hours = new byte[24];
		for (byte i = 0; i < 60; i++)
			minutes_seconds[i] = i;
		System.arraycopy(minutes_seconds, 0, hours, 0, 24);
		int bits_in_all_seconds = BitSet.valueOf(minutes_seconds).cardinality();
		int bits_in_all_minutes = bits_in_all_seconds;
		int bits_in_all_hours   = BitSet.valueOf(hours).cardinality();		
		int bits_in_one_day = 60*60*bits_in_all_hours + 24*60*(bits_in_all_minutes + bits_in_all_seconds);		
		System.out.println("Bits in one day of a binary clock: " + bits_in_one_day);
	}
}

Vijay Nathani replied on Fri, 2013/03/29 - 1:54am

 A more optimized way to find number 1s in Groovy

def countOfOnesInBinary(r) { r.sum { Integer.bitCount(it) } }
assert 682560 == countOfOnesInBinary(0..23) * 60 * 60 + countOfOnesInBinary(0..59)  * 24 * 60 * 2 

shankar kumar replied on Fri, 2013/03/29 - 4:04am

public class BitPuzzle {
	public static void main(String[] args) throws Exception {
		long totalNumOfBits = 0;
		for (int h = 0; h < 24; h++) {
			for (int m = 0; m < 60; m++) {
				for (int s = 0; s < 60; s++) {
					totalNumOfBits += Integer.bitCount(h) + Integer.bitCount(m)
							+ Integer.bitCount(s);
				}
			}
		}
		System.out.println("Total Num Of Bits " + totalNumOfBits);
	}
}

Vijay Nathani replied on Fri, 2013/03/29 - 4:44am

Please ignore this addtion. (Duplicate)

Anders Falk replied on Fri, 2013/03/29 - 5:22am

Plain old Javascript

function b(i) {
	var s = 0;
	while (--i) {
		for (var j = i; j; j >>= 1)
			s += j & 1;
	}
	return s;
}
var t = b(24) * 60 * 60 + 24 * b(60) * 60 + 24 * 60 * b(60);
console.log('Bit count:', t);

Anders Falk replied on Fri, 2013/03/29 - 8:37am

Still plain old Javascript but harder to read for human eye. Luckily we have computers

// DZone Code Puzzler
function c(i) {
	return i && i.toString(2).split("1").length-1 + c(i-1);
}
var t = c(23) * 60 * 60 + 24 * c(59) * 60 + 24 * 60 * c(59);
console.log('Bit count:', t);

Anders Falk replied on Fri, 2013/03/29 - 8:53am

which boils down to

// DZone Code Puzzler
function c(i) {
	return i && i.toString(2).split("1").length-1 + c(i-1);
}
console.log('Bit count:', c(23)*3600 + c(59)*2880);

Tridib Samanta replied on Sat, 2013/03/30 - 2:56am

int countOnes(int no) {
    int count = 0;
    for(int i=1; i<=no; i++) {
        count+=Integer.bitCount(i);
    }
    return count;
}

int onesInADay = countOnes(23) + 2*countOnes(59);

 

Skeeve Magick replied on Wed, 2013/04/03 - 5:45am

Perl:

<code>

print unpack ("%".(60*8)."B*", pack("i*",0..59))*2*60*24+unpack ("%".(24*8)."B*", pack("i*",0..23))*3600

</code>

Gabor Kocsis replied on Wed, 2013/04/03 - 7:04am

In C# using LINQ:

int SumOfOnes()
{
	return Enumerable.Range(0, 24)
			.Select(h => Enumerable.Range(0, 60)
				.Select(m => Enumerable.Range(0, 60)
					.Select(s => (Convert.ToString(h, 2) + Convert.ToString(m, 2) + Convert.ToString(s, 2))
						.ToCharArray()
						.Count(c => c == '1'))))
				.SelectMany(t => t)
			.SelectMany(t => t)
			.Sum();
}

Jay Pedersen replied on Wed, 2013/04/03 - 7:31am

Ruby

def count_one_bits(n)
  (0..(0.size*8-1)).map { |i| (n & (1 << i)) >> i }.inject(0) { |sum,x| sum + x }
end

one_bits = 0
0.upto(23) do |hour|
  0.upto(59) do |minute|
    0.upto(59) do |second|
      one_bits += [hour,minute,second].inject(0) { |sum,x| sum + count_one_bits(x) }
    end
  end
end
puts "There are #{one_bits} one bits set on a binary clock over the course of a day."


Jay Pedersen replied on Wed, 2013/04/03 - 4:19pm

ruby -- a little shorter than before, pack h,m,s into a single integer, one value per bytedef one_bits(n)
  (0..(0.size*8-1)).map { |i| (n & (1 << i)) >> i }.inject(0) { |sum,x| sum + x }
end

ones = 0; (0..23).each { |h| (0..59).each { |m| (0..59).each { |s| ones += one_bits((h<<16)+(m<<8)+s) } } }

Skeeve Magick replied on Wed, 2013/04/03 - 5:57pm

A short perl one-liner calculating the correct result without putting any knowledge about seconds in a minute, hour or day into it by just relying on standard perl functions:

while(1){$_+=(unpack"%32B*",pack"i3",gmtime++$i)||last}print

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.