How to check if an interval contains power of two - java

I'm working on Java. I'd like some help with the following. So, given a specific interval (int low, int high), how can we check if it contains any number that is power of two? My method to check if a number is a power of two is:
private static boolean isPowerOfTwo(int n){
if( n == 0 || n == 1){
return false;
} else if( (n & -n) == n ){
return true;
}
else{
return false;
}
}
The method I've done to check if there is any number that is power of two in the interval is:
private static boolean ContainsPowerOfTwo(int low, int high){
boolean f = false ;
if (isPowerOfTwo(low) || isPowerOfTwo(high)){
return true;
}
for (int i = low; low <= high; i++){
if ( (low & -low ) == low && low!=0 && low!=1 ) {
f = true;
break;
}
}
if ( f == true ){
return true;
}else{
return false;
}
}
Apparently, I'm doing something wrong. If I set the interval to be: (0, 1), I do not get any message on my main program:
int high = readInt(" Please insert the number: ");
rgen = new RandomGenerator();
int random = (int) rgen.nextInt(0, high);
while (valid){
if(high<0) {
println( " The highest value must be positive. ");
high = readInt(" Please insert the highest value: ");
}else if(ContainsPowerOfTwo(0, high)==false){
println(" There are no power of two numbers in this interval.");
println("-1");
valid = false;
break;
}else{
valid=false;
}
}
while(flag2){
if(isPowerOfTwo(random) == false) {
rgen = new RandomGenerator();
random = (int) rgen.nextInt(0, high);
}else{
println(" The random generated number that is power of two is: " + random);
flag2=false;
}
}
Can you please help me find the issue(s)?

You can use Long functions to make this easier.
public static boolean powerOf2InRange(long low, long high) {
return Long.bitCount(low) == 1 ||
Long.bitCount(high) == 1 ||
Long.highestOneBit(low) != Long.highestOneBit(high);
}

If you only need to assess the existence of a power of two and not its value, it would be enough by using Bolzano's theorem:
private static boolean ContainsPowerOfTwo(int low, int high){
if(isPowerOfTwo(low) || isPowerOfTwo(high))
// Checking the extremes
return true;
else
// If the integer part of the logarithms are different, there must be a number within the interval where the logarithm is exact (Bolzano's theorem)
return (Math.floor(log(high, 2)) > Math.floor(log(low, 2)))
}
private static double log(int x, int base) {
return (Math.log(x) / Math.log(base));
}

It looks like the code:
for (int i = low; low <= high; i++){
if ( (low & -low ) == low && low!=0 && low!=1 ) {
f = true;
break;
}
}
Would result in an infinite loop. Your for loop will run if low <= high, since your loop doesn't change the value of low this will always be true and your loop will run forever. I suspect you meant i <= low.
There are a few other areas which could be improved, but if that infinite loop is the case then perhaps overcoming that can get you started. Are you using an IDE? You can debug your code and step through it to see if the flow is as you'd expect. This should highlight where the code deviates from what you expect.

A bit different approach not to check all the values in the given interval. Because the function power-of-2 is strictly increasing, I have taken the log2 of the interval limits and checked them.
public class Main {
public static void main(String[] args) {
containsPowerOfTwo(43, 64);
containsPowerOfTwo(31, 63);
containsPowerOfTwo(32, 63);
containsPowerOfTwo(33, 63);
containsPowerOfTwo(33, 64);
containsPowerOfTwo(55, 127);
containsPowerOfTwo(56, 128);
containsPowerOfTwo(34, 127);
}
private static boolean containsPowerOfTwo(int low, int high) {
double log2Low = log2(low);
// System.out.println("log2Low: " + log2Low);
double log2High = log2(high);
// System.out.println("log2High: " + log2High);
double floorlog2Low = Math.floor(log2Low);
// System.out.println("floorlog2Low: " + floorlog2Low);
double floorlog2High = Math.floor(log2High);
// System.out.println("floorlog2High: " + floorlog2High);
boolean retVal = log2High == floorlog2High || log2Low == floorlog2Low || floorlog2High - floorlog2Low >= 1;
System.out.println(String.format("%d - %d %B ",low ,high, retVal));
return retVal;
}
private static double log2(int value) {
return Math.log(value) / Math.log(2);
}
}
Output:
43 - 64 TRUE
31 - 63 TRUE
32 - 63 TRUE
33 - 63 FALSE
33 - 64 TRUE
55 - 127 TRUE
56 - 128 TRUE
34 - 127 TRUE

Related

How to determine if a number is monotonically decreasing?

I'm working on the following problem:
The number n is given as input
Find out if it's monotonic?
A monotonic number is called - that number of numbers in which
monotonically decrease or increase monotonically. For example: 110,
111, 122, 123, 455, 554. - are monotonic. 101, 121, 231 are
non-monotonic.
Constraint: Arrays and strings cannot be used.
I wrote a function to check for a monotonically increasing number:
public static boolean isMonotonic(int num) {
int n = num; // Copy of num to be modified
int b = (n/10)%10; // Step for a number if it is monotone
n /= 10;
if (num < 100) return true; // all two-digit numbers are monotonic
while (n > 0 && n > b) {
if ((n/10)%10 != b){
return false;
}
n /= 10;
}
return true;
}
But I don't know how to make a function for a monotonically decreasing number.
Because according to your requirement the digits of a valid monotonic number can be equal (e.g. 110, 455) the decreasing order and increasing order can be easily confused while examining the digits. And we also have a case when all digits are equal, i.e. the number is neither increasing, no decreasing, but it's considered to be a valid monotonic number (e.g. 111).
I've come up with the following algorithm:
Maintain three boolean flags representing three cases when a number can be considered monotonic, described above. To initialize these flags, we need to access both the first and the last digits of the given number. Because adjacent digits can be equal, only comparison of the first and the last digits would provide sufficient information regarding expected ordering of the number. Here is how all three flags would be initialized:
isEqual = first == last;
isIncreasing = first >= last;
isDeceasing = first <= last;
Maintain a variable holding the value of the previous digit.
Iterate over the digits of the given number and compare the next and previous digits. If conditions are consistent with the flags - proceed iterating further, otherwise invalidate the number returning false.
As a small optimization we can cut out all numbers that are less the then 100 because according to the requirements are monotonic.
That's how implementation might look like:
public static boolean isMonotonic(int num) {
// NOTE: use Math.abs() to adjust the input if negative values are allowed
if (num <= 100) return true; // early kill for small number
int last = num % 10;
int first = num / (int) Math.pow(10, (int) Math.log10(num));
int prev = last;
num /= 10;
boolean isEqual = isEqual(first, last);
boolean isIncreasing = isIncreasing(first, last);
boolean isDeceasing = isDecreasing(first, last);
while (num > 0) {
int next = num % 10;
if (isEqual && !isEqual(next, prev)) return false; // next is passed before previous because we are iterating from right to left
if (isIncreasing != isIncreasing(next, prev) && isDeceasing != isDecreasing(next, prev)) {
return false;
}
prev = next;
num /= 10;
}
return true; // the number is proved to be monotonic
}
public static boolean isEqual(int left, int right) {
return left == right;
}
public static boolean isIncreasing(int left, int right) {
return left <= right;
}
public static boolean isDecreasing(int left, int right) {
return left >= right;
}
main()
public static void main(String[] args) {
System.out.println("Digits are equal:");
System.out.println(111 + " " + isMonotonic(111));
System.out.println(333 + " " + isMonotonic(333));
System.out.println(999 + " " + isMonotonic(999));
System.out.println("Increasing:");
System.out.println(189 + " " + isMonotonic(189));
System.out.println(577 + " " + isMonotonic(577));
System.out.println(779 + " " + isMonotonic(779));
System.out.println("Decreasing");
System.out.println(775 + " " + isMonotonic(775));
System.out.println(831 + " " + isMonotonic(831));
System.out.println(99333 + " " + isMonotonic(99333));
System.out.println("Non-monotonic");
System.out.println(101 + " " + isMonotonic(101));
System.out.println(45551 + " " + isMonotonic(45551));
System.out.println(95559 + " " + isMonotonic(95559));
}
Output:
Digits are equal:
111 true
333 true
999 true
Increasing:
189 true
577 true
779 true
Decreasing
775 true
831 true
99333 true
Non-monotonic
101 false
45551 false
95559 false
An easy way to solve this without dealing with n/10's is converting num into a string
public static boolean isMonotonicDecreasing(int num) {
//First, convert num into a string
String numString = String.valueOf(num);
//Iterate across numString - 1
for (int i = 0; i < numString.length() - 1; i++){
//If the current digit (character at index i, converted to integer)
//is less than the next digit, return false
if ((int)numString.charAt(i) < (int)numString.charAt(i+1)){
return false;
}
}
//Return true after reaching end of loop
return true;
}
To compare if the digits are going up or down, compare the the previous digit and the current digit. Each iteration, we must update previous digit to current digit and move current digit to the next digit and shift the digits in the integer to the right.
You need two boolean variables: tracking monotonic increasing and monotonic decreasing. Finally, return the OR of the two boolean variables.
static boolean isMonotonic(int n){
boolean inc = true; //assume monotonic increasing
boolean dec = true; //assume monotonic decreasing
int prev = n%10; //previous is right most digit
n/=10; //shift digits to the right
while(n > 0){
int cur = n%10; //current is right most digit
inc &= prev >= cur; //is monotonic increasing ?
dec &= prev <= cur; //is monotonic decreasing ?
prev = cur; //previous is set to current digit
n/=10; //shift digits to the right.
}
return inc || dec;
}
Let's introduce int order which is +1 if we have increasing sequence, -1 in case of decreasing sequence and 0 if
we don't know it so far (for instance ...111111). Then all we should do is to llop over digits:
public static bool isMonotonic(int num) {
if (num > -100 && num < 100)
return true;
int order = 0;
int prior = num % 10;
for (; num != 0; num /= 10) {
int current = num % 10;
if (order > 0 && current < prior || order < 0 && current > prior)
return false;
if (current != prior)
order = Math.sign(current - prior);
prior = current;
}
return true;
}
Another possibility is to try to find counter example: a digit which is bigger than its neighbors or smaller than its neighbors.

How can I convert this iterative statement into a recursive statement?

So I have this programming project in which I need to create a program that determines if a number is a perfect square, and if so, write it into a .txt document. This is very easy and effective to do with a for loop, however, the instructions for the assignment say that the program should accomplish this using recursion. This is the iterative statement I came up with:
double division;
for (int i = 0; i < inputs.size(); i++) {
division = (Math.sqrt(inputs.get(i)));
if (division == (int)division) {
pw.println(inputs.get(i));
}
}
Where inputs is an ArrayList that is created by reading the inputs of the user.
This solves the problem, but like I said, it needs to be a recursive statement. I know that for recursion I need a base case that will eventually make the method stop calling itself, but I can't figure out what the base case would be. Also, I've seen several examples of converting from iteration to recursion, but all of these examples use a single int variable, and in my case I need to do it with an ArrayList.
Any help would be greatly appreciated
For recursive function, you can use bynary search algorithm:
int checkPerfectSquare(long N,
long start,
long last)
{
// Find the mid value
// from start and last
long mid = (start + last) / 2;
if (start > last)
{
return -1;
}
// Check if we got the number which
// is square root of the perfect
// square number N
if (mid * mid == N)
{
return (int)mid;
}
// If the square(mid) is greater than N
// it means only lower values then mid
// will be possibly the square root of N
else if (mid * mid > N)
{
return checkPerfectSquare(N, start,
mid - 1);
}
// If the square(mid) is less than N
// it means only higher values then mid
// will be possibly the square root of N
else
{
return checkPerfectSquare(N, mid + 1,
last);
}
}
You could use the fact that a square number is the sum of the odd integers. E.g.
1+3 = 4 = 2^2
1+3+5 = 9 = 3^2
1+3+5+7 = 16 = 4^2, etc
public static void main(String[] args) {
for (int i = 1; i < 1000; i++) {
if (isSquare(i)) System.out.println(i);
}
}
public static boolean isSquare(int n) {
if (n==0 || n==1) return true;
return isSquare(n,1,1);
}
private static boolean isSquare(int n, int sum, int odd) {
if (n==sum) return true;
if (n < sum) return false;
odd += 2;
sum += odd;
return isSquare(n, sum, odd);
}
output:
1
4
9
16
25
36
49
64
81
100
121
144
169
196
225
256
289
324
361
400
441
484
529
576
625
676
729
784
841
900
961
You could recursively check if the square of any smaller int is equal to your input.
public static boolean isSquare(int n) {
if (n==0 || n==1) return true;
return isSquare(n, 1);
}
private static boolean isSquare(int n, int i) {
if (i*i == n) return true;
if (i*i > n) return false;
return isSquare(n,i+1);
}

Credit Card Number validity with Luhn's Algorithm (Java)

I'm working on a school assignment that checks whether a credit card number that is entered is valid or not, using Luhn's Algorithm.
In 1954, Hans Luhn of IBM proposed an algorithm for validating credit card numbers. The algorithm is useful to determine whether a card number is entered correctly or whether a credit card is scanned correctly by a scanner. Credit card numbers are generated following this validity check, commonly known as the Luhn check or the Mod 10 check, which can be described as follows (for illustration, consider the card number 4388 5760 1840 2626):
Double every second digit from right to left. If doubling of a digit results in a two-digit number, add up the two digits to get a single-digit number.
Now add all single-digit numbers from Step 1: 4 + 4 + 8 + 2 + 3 + 1 + 7 + 8 = 37
Add all digits in the odd places from right to left in the card number: 6 + 6 + 0 + 8 + 0 + 7 + 8 + 3 = 38
Sum the results from Step 2 and Step 3: 37 + 38 = 75
If the result from Step 4 is divisible by 10 the card number is valid; otherwise, it is invalid. For example, the number 4388 5760 1840 2626 is invalid, but the number 4388 5760 1841 0707 is valid.
I need to write this program using the methods in the code I have written:
public class CreditCardValidation {
public static void main(String[] args, long input) {
Scanner numberinput = new Scanner(System.in);
System.out.println("Enter a credit card number as a long integer: ");
long cardnumber = numberinput.nextLong();
if (isValid(input) == true) {
System.out.println(numberinput + " is valid.");
} else {
System.out.println(numberinput + " is invalid.");
}
}
public static boolean isValid(long number){
int total = sumOfDoubleEvenPlace + sumOfOddPlace;
return (total % 10 == 0) && (prefixMatched(number, 1) == true) &&
(getSize(number)>=13) && (getSize(number)<=16);
}
public static int sumOfDoubleEvenPlace(long number) {
int doubledevensum = 0;
long place = 0;
while (number > 0) {
place = number % 100;
doubledevensum += getDigit((int) (place / 10) * 2);
number = number / 100;
}
return doubledevensum;
}
public static int sumOfOddPlace(long number) {
int oddsum = 0;
while (number <= 9) {
oddsum += (int)(number % 10);
number = number % 100;
}
return oddsum;
}
public static int getDigit(int number) {
if (number <= 9) {
return number;
} else {
int firstDigit = number % 10;
int secondDigit = (int)(number / 10);
return firstDigit + secondDigit;
}
}
public static boolean prefixMatched(long number, int d) {
if ((getPrefix(number, d) == 4)
|| (getPrefix(number, d) == 5)
|| (getPrefix(number, d) == 3)) {
if (getPrefix(number, d) == 3) {
System.out.println("\nVisa Card ");
} else if (getPrefix(number, d) == 5) {
System.out.println("\nMaster Card ");
} else if (getPrefix(number, d) == 3) {
System.out.println("\nAmerican Express Card ");
}
return true;
} else {
return false;
}
}
public static int getSize(long d) {
int count = 0;
while (d > 0) {
d = d / 10;
count++;
}
return count;
}
public static long getPrefix(long number, int k) {
if (getSize(number) < k) {
return number;
} else {
int size = (int)getSize(number);
for (int i = 0; i < (size - k); i++) {
number = number / 10;
}
return number;
}
}
}
I just started learning how to program two months ago so I am fairly new to this. The program doesn't compile and I don't know why and what I have to do to fix this. I know there are similar topics already posted regarding this and I have been using this post to help guide me a bit. Can someone help point a student in the right direction and let me know what I'm doing wrong?
Your program isn't compiling because this line:
int total = sumOfDoubleEvenPlace + sumOfOddPlace;
since sumOfDoubleEvenPlace and sumOfOddPlace are functions, you must use them as such:
int total = sumOfDoubleEvenPlace(number) + sumOfOddPlace(number);
In the function isValid you are trying to add two variables which do not exist. However you have defined them as functions and to use them as functions you must call them as functions using
int total = sumOfDoubleEvenPlace(number) + sumOfOddPlace(number);

Project Euler #5(Smallest positive number divisible by all numbers from 1 to 20): Ways to Optimize? ~Java

Problem 5: 2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.
What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?
I have solved the problem 5 of Project Euler
Here is the Java code:
static long FindLcm(long a,long b)
{
long lcm,hcf = 0;
long i=1;
long ger=a>b?a:b;
while(i<ger)
{
if((a%i==0) && (b%i==0))
hcf=i;
i++;
}
lcm=(a*b)/hcf;
return lcm;
}
static void FindMultiple()
{
long lcm=1;
for(long i=2;i<=20;i++)
{
lcm=FindLcm(lcm,i);
}
System.out.println("Lcm="+lcm);
}
How can optimize this?
Your FindMultiple() method is not bad,
static void FindMultiple()
{
long lcm=1;
for(long i=2;i<=20;i++)
{
lcm=FindLcm(lcm,i);
}
System.out.println("Lcm="+lcm);
}
it implements a fairly good algorithm. Your problem is that your FindLcm() contains a nasty performance bug.
static long FindLcm(long a,long b)
{
long lcm,hcf = 0;
long i=1;
// This sets ger to max(a,b) - why?
long ger=a>b?a:b;
// This would return a wrong result if a == b
// that never happens here, though
while(i<ger)
{
if((a%i==0) && (b%i==0))
hcf=i;
i++;
}
lcm=(a*b)/hcf;
return lcm;
}
You are looping until you reach the larger of the two arguments. Since the cumulative LCMs grow rather fast, that takes a lot of time. But the GCD (or HCF, if you prefer) of two (positive) numbers cannot be larger than the smaller of the two. So looping only until the smaller of the two arguments is reached makes the number of iterations at most 20 here, do that 19 times (for i = 2, ..., 20), it's a trivial amount of computation.
Changing to
long ger = a < b ? a : b;
while(i <= ger) {
gives me (adding timing code, not measuring the printing):
17705 nanoseconds
Lcm=232792560
So less than 20 microseconds for the computation. We can easily push that below 6 microseconds if we use the euclidean algorithm to find the greatest common divisor,
static long gcd(long a, long b) {
while(b > 0) {
a %= b;
if (a == 0) return b;
b %= a;
}
return a;
}
and below 5 if we directly use the GCD as
lcm *= i/gcd(lcm,i);
in FindMultiple().
You're solution is more or less brute force which is why it's taking so long. We know that 2520 is the lcm of (1,2,...,9,10) which means two useful things: 1.) We can start checking factors at 11 and 2.) The answer is a multiple of 2520.
You're searching for the Greatest Common Divisor (gcd) of the answer and the next number in your sequence (similar to a bubble sort). You could just check to see if your current answer is divisible by the next factor and if not then add your current answer to itself until the answer is divisible by the next factor. For Example:
static long findLCM(long a, long b) {
long lcm = (a>b) ? a : b;
while (lcm % b != 0) {
lcm += a;
}
return lcm;
}
Since we started with lcm = a, we know that as long as we add a's to lcm then lcm will always be divisible by a. Now, we just need to make some multiple of a divisible by b. This process should cut out many steps of first finding the gcd as well as iterating from 2 through 10.
i did it like this, which was the easiest way i could think of. it's also a little faster than yours.
for(int i = 190; ; i += 190) {
if(i % 3 == 0
&& i % 4 == 0
&& i % 6 == 0
&& i % 7 == 0
&& i % 8 == 0
&& i % 9 == 0
&& i % 11 == 0
&& i % 12 == 0
&& i % 13 == 0
&& i % 14 == 0
&& i % 15 == 0
&& i % 16 == 0
&& i % 17 == 0
&& i % 18 == 0
&& i % 20 == 0) {
System.out.println(i);
break;
}
}
Here are 4 different methods to obtain the result (4 different ways to obtain GCD) + the total time. All of them are based on the following observation:
a*b
lcm(a,b) = ----------
gcd(a,b)
where:
LCM = Least Common Multiple
GCD = Greatest Common Divisor
import java.lang.reflect.Method;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;
public class A {
final static int N = 20;
static Map<Integer, String> messages = new HashMap<>();
static {
messages.put(0, "Euler - difference");
messages.put(1, "modulo - recursive");
messages.put(2, "modulo - iterative");
messages.put(3, "BigInteger implementation");
}
private static long GCD0(long x, long y) {
while (x != y) {
if (x > y) {
x -= y;
} else {
y -= x;
}
}
return x;
}
private static long GCD1(long x, long y) {
if (x % y == 0) {
return y;
}
return GCD1(y, x % y);
}
private static long GCD2(long x, long y) {
long aux;
while (x % y != 0) {
aux = y;
y = x % y;
x = aux;
}
return y;
}
private static long GCD3(long x, long y) {
BigInteger xx = BigInteger.valueOf(x);
BigInteger yy = BigInteger.valueOf(y);
return xx.gcd(yy).longValue();
}
private static void doIt(int pos) throws Exception {
System.out.print("\n" + messages.get(pos));
printSpaces(25, messages.get(pos).length());
Class cls = Class.forName("A");
Object obj = cls.newInstance();
Method method = cls.getDeclaredMethod("GCD" + pos, long.class,
long.class);
long start = System.nanoTime();
long p = 1;
for (int i = 2; i <= N; i++) {
p = (p * i) / (long) method.invoke(obj, p, i);
}
long stop = System.nanoTime();
System.out.println("\tTime: " + (stop - start) / 1000 + " microseconds");
System.out.println(p);
}
private static void printSpaces(int total, int actualLength) {
for (int i = 0; i < total - actualLength; i++) {
System.out.print(" ");
}
}
public static void main(String[] args) throws Exception {
doIt(0);
doIt(1);
doIt(2);
doIt(3);
}
}
Output:
Euler - difference Time: 137205 microseconds
232792560
modulo - recursive Time: 1240 microseconds
232792560
modulo - iterative Time: 1228 microseconds
232792560
BigInteger implementation Time: 2984 microseconds
232792560
P.S.: I used reflection to call those methods easier, but you can call the method directly to obtain a better performance + a better readability.
int i = 20;
while (true)
{
if (
(i % 1 == 0) &&
(i % 2 == 0) &&
(i % 3 == 0) &&
(i % 5 == 0) &&
(i % 7 == 0) &&
(i % 9 == 0) &&
(i % 11 == 0) &&
(i % 13 == 0) &&
(i % 16 == 0) &&
(i % 17 == 0) &&
(i % 19 == 0) )
{
break;
}
i += 20;
}
S.O.P(i);
C++ Program with minimum iteration... very much resemble to Daniel Fischer
#include<iostream>
using namespace std;
int main()
{
int num = 20;
long lcm = 1L;
for (int i = 2; i <= num; i++)
{
int hcf = 1;
for (int j = 2; j <= i; j++)
{
if (i % j == 0 && lcm % j == 0)
{
hcf = j;
}
}
lcm = (lcm * i) / hcf;
}
cout << lcm << "\n";
}
This method uses brute force, but skips as soon as a number fails instead of continuing to compare the remainders. Heck, it never checks for 20 unless 19 has passed already, which actually makes it pretty efficient.
#include<stdio.h>
int a = 1, b = 1, rem;
int main() {
while (b < 20){
rem = a % b;
if (rem != 0){
a++;
b = 1;
}
b++;
}
printf("%d is the smallest positive number divisible by all of the numbers from 1 to 20.", a);
}
A Non Brute Force Method
This one is instantaneous! Doesn't even take a second. Run the code to understand the logic. It's written in C
#include <stdio.h>
int main() {
int primes[8]={2,3,5,7,11,13,17,19};
int primes_count[8]={0,0,0,0,0,0,0,0};
int i,j,num,prime_point;
int largest_num=1;
printf("\nNUM");
for(j=0;j<8;j++)
printf("\t%d",primes[j]);
for(i=2;i<=20;i++) {
num=i;
int primes_count_temp[8]={0,0,0,0,0,0,0,0};
for(j=0;j<8;j++) {
while(num%primes[j]==0) {
num=num/primes[j];
primes_count_temp[j]++;
}
}
for(j=0;j<8;j++)
if(primes_count_temp[j]>primes_count[j])
primes_count[j]=primes_count_temp[j];
printf("\n %d",i);
for(j=0;j<8;j++)
printf("\t %d",primes_count_temp[j]);
}
printf("\nNET");
for(j=0;j<8;j++)
printf("\t%d",primes_count[j]);
printf("\n");
for(i=0;i<8;i++)
while(primes_count[i]) {
largest_num*=primes[i];
primes_count[i]--;
}
printf("The answer is %d \n",largest_num);
return 0;
}
Now if a number is divisible by X it will be divisible by its prime factors also. So if a number is divisible by 20 it will be divisible by its prime factors. And there are 8 prime factors under 20. I take each number under 20 and find its prime factors, also see the power of the prime factor and keep a count of the highest power.
Once you're done. Multiply all the prime factors raised to their highest power.
my Solution for this in python. this is so simple and use pure Math rules
get the Least Common Multiple
def getLCM (x, y):
return x*y/getGCD(x,y)
get the Greatest Common Divisor
def getGCD(a,b):
while(True):
if(a%b != 0):
temp = b
b = a%b
a = temp
else:
return b
break
Find the Least Common Multiple of, LCM of prev two numbers and next number in list.
LCM(LCM of prev two numbers,next number in list)
num_list = list(range(1,21))
finalLCM = 1
for i in num_list:
finalLCM = getLCM(finalLCM,i)
print(finalLCM)
Full Python Code
def getLCM (x, y):
return x*y/getGCD(x,y)
def getGCD(a,b):
while(True):
if(a%b != 0):
temp = b
b = a%b
a = temp
else:
return b
break
num_list = list(range(1,21))
finalLCM = 1
for i in num_list:
finalLCM = getLCM(finalLCM,i)
print(finalLCM)
we have create an array which was common divisible eg: if any number is divisible by 20 then no need to divisible by 2,4,5,10
<?php
$chk=20;
$div=array(11,12,13,14,15,16,17,18,19,20);
for($number=1;1;$number++){
$chk=$number;
foreach($div as $value){
if($number%$value!=0){
$chk=0;
$number+=$value;
break;
}
}
if($chk!=0){break;}
}
echo $chk;
?>

How does Integer.parseInt(string) actually work?

Was asked this question recently and did not know the answer. From a high level can someone explain how Java takes a character / String and convert it into an int.
Usually this is done like this:
init result with 0
for each character in string do this
result = result * 10
get the digit from the character ('0' is 48 ASCII (or 0x30), so just subtract that from the character ASCII code to get the digit)
add the digit to the result
return result
Edit: This works for any base if you replace 10 with the correct base and adjust the obtaining of the digit from the corresponding character (should work as is for bases lower than 10, but would need a little adjusting for higher bases - like hexadecimal - since letters are separated from numbers by 7 characters).
Edit 2: Char to digit value conversion: characters '0' to '9' have ASCII values 48 to 57 (0x30 to 0x39 in hexa), so in order to convert a character to its digit value a simple subtraction is needed. Usually it's done like this (where ord is the function that gives the ASCII code of the character):
digit = ord(char) - ord('0')
For higher number bases the letters are used as 'digits' (A-F in hexa), but letters start from 65 (0x41 hexa) which means there's a gap that we have to account for:
digit = ord(char) - ord('0')
if digit > 9 then digit -= 7
Example: 'B' is 66, so ord('B') - ord('0') = 18. Since 18 is larger than 9 we subtract 7 and the end result will be 11 - the value of the 'digit' B.
One more thing to note here - this works only for uppercase letters, so the number must be first converted to uppercase.
The source code of the Java API is freely available. Here's the parseInt() method. It's rather long because it has to handle a lot of exceptional and corner cases.
public static int parseInt(String s, int radix) throws NumberFormatException {
if (s == null) {
throw new NumberFormatException("null");
}
if (radix < Character.MIN_RADIX) {
throw new NumberFormatException("radix " + radix +
" less than Character.MIN_RADIX");
}
if (radix > Character.MAX_RADIX) {
throw new NumberFormatException("radix " + radix +
" greater than Character.MAX_RADIX");
}
int result = 0;
boolean negative = false;
int i = 0, max = s.length();
int limit;
int multmin;
int digit;
if (max > 0) {
if (s.charAt(0) == '-') {
negative = true;
limit = Integer.MIN_VALUE;
i++;
} else {
limit = -Integer.MAX_VALUE;
}
multmin = limit / radix;
if (i < max) {
digit = Character.digit(s.charAt(i++), radix);
if (digit < 0) {
throw NumberFormatException.forInputString(s);
} else {
result = -digit;
}
}
while (i < max) {
// Accumulating negatively avoids surprises near MAX_VALUE
digit = Character.digit(s.charAt(i++), radix);
if (digit < 0) {
throw NumberFormatException.forInputString(s);
}
if (result < multmin) {
throw NumberFormatException.forInputString(s);
}
result *= radix;
if (result < limit + digit) {
throw NumberFormatException.forInputString(s);
}
result -= digit;
}
} else {
throw NumberFormatException.forInputString(s);
}
if (negative) {
if (i > 1) {
return result;
} else { /* Only got "-" */
throw NumberFormatException.forInputString(s);
}
} else {
return -result;
}
}
I'm not sure what you're looking for, as "high level". I'll give it a try:
take the String, parse all characters one by one
start with a total of 0
if it is between 0 and 9, total = (total x 10) + current
when done, the total is the result
public class StringToInt {
public int ConvertStringToInt(String s) throws NumberFormatException
{
int num =0;
for(int i =0; i<s.length();i++)
{
if(((int)s.charAt(i)>=48)&&((int)s.charAt(i)<=59))
{
num = num*10+ ((int)s.charAt(i)-48);
}
else
{
throw new NumberFormatException();
}
}
return num;
}
public static void main(String[]args)
{
StringToInt obj = new StringToInt();
int i = obj.ConvertStringToInt("1234123");
System.out.println(i);
}
}
Find the length of the String (s) (say maxSize )
Initialize result = 0
begin loop ( int j=maxSize, i =0 ; j > 0; j--, i++)
int digit = Character.digit(s.charAt(i))
result= result + digit * (10 power j-1)
end loop
return result
this is my simple implementation of parse int
public static int parseInteger(String stringNumber) {
int sum=0;
int position=1;
for (int i = stringNumber.length()-1; i >= 0 ; i--) {
int number=stringNumber.charAt(i) - '0';
sum+=number*position;
position=position*10;
}
return sum;
}
Here is what I came up with (Note: No checks are done for alphabets)
int convertStringtoInt(String number){
int total =0;
double multiplier = Math.pow(10, number.length()-1);
for(int i=0;i<number.length();i++){
total = total + (int)multiplier*((int)number.charAt(i) -48);
multiplier/=10;
}
return total;
}
Here is my new approach which is not in a math way.
let n = 12.277;
// converting to string
n = n.toString();
let int = "";
for (let i = 0; i < n.length; i++) {
if (n[i] != ".") {
int += n[i];
} else {
break;
}
}
console.log(Number(int));

Categories

Resources