'Formula to find week numbers from the Total [closed]
Any one please help me to identify the formula or mathematical term on the below example.
Predefined sets stored in the system,
1 = Monday
2 = Tuesday
4 = Wednesday
8 = Thursday
16 = Friday
32 = Saturday
64 = Sunday.
From the Total i need to retrieve the days from the predefined set, like,
Eg: 1
127 = This means i have to take All Days in the week from the predefined sets.
Eg: 2
80 = This means i have to take Friday and Sunday only
Eg: 3
7 = This means i have to take Monday, Tuesday and Wednesday.
Thanks in advance.
Solution 1:[1]
You could take a bitwise AND &
with the day value and take this day.
const
days = { Monday: 1, Tuesday: 2, Wednesday: 4, Thursday: 8, Friday: 16, Saturday: 32, Sunday: 64 },
getDays = value => Object.keys(days).filter(day => value & days[day]);
console.log(getDays(127)); // All Days
console.log(getDays(80)); // Friday, Sunday
console.log(getDays(7)); // Monday, Tuesday, Wednesday
.as-console-wrapper { max-height: 100% !important; top: 0; }
Solution 2:[2]
Java 9 and later solution since I understand that both Java and JavaScript solutions will be helpful. First, we need
private static final Map<DayOfWeek, Integer> dayBits = new EnumMap<>(
Map.of(DayOfWeek.MONDAY, 0x1, DayOfWeek.TUESDAY, 0x2,
DayOfWeek.WEDNESDAY, 0x4, DayOfWeek.THURSDAY, 0x8,
DayOfWeek.FRIDAY, 0x10, DayOfWeek.SATURDAY, 0x20,
DayOfWeek.SUNDAY, 0x40));
then we can do
int total = 80;
Set<DayOfWeek> days = Stream.of(DayOfWeek.values())
.filter(dow -> (total & dayBits.get(dow)) > 0)
.collect(Collectors.toCollection(() -> EnumSet.noneOf(DayOfWeek.class)));
System.out.println(days);
The output we get is
[FRIDAY, SUNDAY]
The latter snippet will work in Java 8 too, only you need a more wordy way of initializing the map.
As you may have noticed, the numbers 1, 2, 4, 8, etc., represent the bits of a binary number. 1 is 00000001 in binary, 2 is 00000010 binary, 4 is 00000100, etc. So our task is to find out which bits of the total are set. 127 is 01111111, all seven bits set. 80 is 01010000, the bits for Friday and Sunday are set. To find out whether a bit is set, use the (single) &
operator. If Monday is included, total & 1
will yield 1, if it isn’t, it will yield 0. Similarly total & 2
will yield 2 if Tuesday is included an 0 if not.
I prefer to read and write bit constants in hexadecimal, like 0x20
. Because 0b0010_0000 is so long, and from 32 it’s not really clear which bit is set (unless you’re really good with binary numbers, and you shouldn’t expect that everyone reading your program is).
And of course I wouldn’t dream of representing the days of the week as anything else than the built-in DayOfWeek
enum.
Solution 3:[3]
I wanted to add it in a comment, but do not have the reputation yet.
For solving the problem you can take a look at the binary indices.
They are powers of 2, so for example:
2^0 = 1
2^1 = 2
2^2 = 4
by counting all numbers before 2^2 you get 3, which is 2^2-1, therefore you can distinguish all combinations of the days by adding the numbers.
The reverse trick is to keep subtracting the highest number that is still smaller than the asked number and keep repeating that.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | xxx |
Solution 3 | Thymen |