Assignment: Compute an according to the formulas:
a0 = 1
a1 = 3
a2 = 5
an = an-1 * a2n-2 * a3n-3
I am having trouble making the function iterative. I figured out how to do it recursively. How would I go about doing it specifically for this task and just in general?
My code for the recursive:
public static BigInteger recurs(int bigInteger){
BigInteger sum;
if (bigInteger == 0) {
sum = new BigInteger(String.valueOf("1"));
} else if (bigInteger == 1) {
sum = new BigInteger(String.valueOf("3"));
} else if (bigInteger == 2) {
sum = new BigInteger(String.valueOf("5"));
} else {
sum = recurs(bigInteger-1).multiply(recurs(bigInteger-2).pow(2).multiply(recurs(bigInteger-3).pow(3)));
}
return sum;
}
You need to remember the last three values and compute a new one each time in terms of the last one.
public static BigInteger iter(int n) {
BigInteger a = BigInteger.valueOf(1);
BigInteger b = BigInteger.valueOf(3);
BigInteger c = BigInteger.valueOf(5);
switch (n) {
case 0: return a;
case 1: return b;
case 2: return c;
default:
for (int i = 2; i < n; i++) {
BigInteger next = c.multiply(b.pow(2)).multiply(a.pow(3));
a = b;
b = c;
c = next;
}
return c;
}
}
Note this is O(n) instead of O(n^3)
To give you a hint:
Initialize an array of size n which will hold the answers. For example, ith index will store the answer for a_i. Initialize a_0, a_1 and a_2 to the values given to you (1,3 and 5 in your case). Now start iterating from index 3 onwards and use your formula to calculate a_i.
You have to store your last three results in three variables and apply the formula on these. Below you can find a simplified example using int. You can enhance this code by using BigInteger so it will work for larger numbers as well.
static int compute_iterative(int n) {
if (n == 0) return 1;
if (n == 1) return 3;
if (n == 2) return 5;
int a_n3 = 1;
int a_n2 = 3;
int a_n1 = 5;
int a_n = a_n1;
int i = 3;
while (i <= n) {
a_n = a_n1 * (int) Math.pow(a_n2, 2) * (int) Math.pow(a_n3, 3);
a_n3 = a_n2;
a_n2 = a_n1;
a_n1 = a_n;
i++;
}
return a_n;
}
Version using BigInterger:
static BigInteger compute_iterative(int n) {
if (n < 0) {
throw new IllegalArgumentException("Unsupported input value: " + n);
}
final BigInteger[] values = { BigInteger.valueOf(1), BigInteger.valueOf(3), BigInteger.valueOf(5) };
if (n < values.length) {
return values[n];
}
int i = 3;
while (i <= n) {
final BigInteger result = values[2].multiply(values[1].pow(2)).multiply(values[0].pow(3));
values[0] = values[1];
values[1] = values[2];
values[2] = result;
i++;
}
return values[2];
}
Related
Trying to solve this problem with recursion and memoization but for input 7168 I'm getting wrong answer.
public int numSquares(int n) {
Map<Integer, Integer> memo = new HashMap();
List<Integer> list = fillSquares(n, memo);
if (list == null)
return 1;
return helper(list.size()-1, list, n, memo);
}
private int helper(int index, List<Integer> list, int left, Map<Integer, Integer> memo) {
if (left == 0)
return 0;
if (left < 0 || index < 0)
return Integer.MAX_VALUE-1;
if (memo.containsKey(left)) {
return memo.get(left);
}
int d1 = 1+helper(index, list, left-list.get(index), memo);
int d2 = 1+helper(index-1, list, left-list.get(index), memo);
int d3 = helper(index-1, list, left, memo);
int d = Math.min(Math.min(d1,d2), d3);
memo.put(left, d);
return d;
}
private List<Integer> fillSquares(int n, Map<Integer, Integer> memo) {
int curr = 1;
List<Integer> list = new ArrayList();
int d = (int)Math.pow(curr, 2);
while (d < n) {
list.add(d);
memo.put(d, 1);
curr++;
d = (int)Math.pow(curr, 2);
}
if (d == n)
return null;
return list;
}
I'm calling like this:
numSquares(7168)
All test cases pass (even complex cases), but this one fails. I suspect something is wrong with my memoization but cannot pinpoint what exactly. Any help will be appreciated.
You have the memoization keyed by the value to be attained, but this does not take into account the value of index, which actually puts restrictions on which powers you can use to attain that value. That means that if (in the extreme case) index is 0, you can only reduce what is left with one square (1²), which rarely is the optimal way to form that number. So in a first instance memo.set() will register a non-optimal number of squares, which later will get updated by other recursive calls which are pending in the recursion tree.
If you add some conditional debugging code, you'll see that map.set is called for the same value of left multiple times, and with differing values. This is not good, because that means the if (memo.has(left)) block will execute for cases where that value is not guaranteed to be optimal (yet).
You could solve this by incorporating the index in your memoization key. This increases the space used for memoization, but it will work. I assume you can work this out.
But according to Lagrange's four square theorem every natural number can be written as the sum of at most four squares, so the returned value should never be 5 or more. You can shortcut the recursion when you get passed that number of terms. This reduces the benefit of using memoization.
Finally, there is a mistake in fillSquares: it should add n itself also when it is a perfect square, otherwise you'll not find solutions that should return 1.
Not sure about your bug, here is a short dynamic programming Solution:
Java
public class Solution {
public static final int numSquares(
final int n
) {
int[] dp = new int[n + 1];
Arrays.fill(dp, Integer.MAX_VALUE);
dp[0] = 0;
for (int i = 1; i <= n; i++) {
int j = 1;
int min = Integer.MAX_VALUE;
while (i - j * j >= 0) {
min = Math.min(min, dp[i - j * j] + 1);
++j;
}
dp[i] = min;
}
return dp[n];
}
}
C++
// Most of headers are already included;
// Can be removed;
#include <iostream>
#include <cstdint>
#include <vector>
#include <algorithm>
// The following block might slightly improve the execution time;
// Can be removed;
static const auto __optimize__ = []() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
return 0;
}();
#define MAX INT_MAX
using ValueType = std::uint_fast32_t;
struct Solution {
static const int numSquares(
const int n
) {
if (n < 1) {
return 0;
}
static std::vector<ValueType> count_perfect_squares{0};
while (std::size(count_perfect_squares) <= n) {
const ValueType len = std::size(count_perfect_squares);
ValueType count_squares = MAX;
for (ValueType index = 1; index * index <= len; ++index) {
count_squares = std::min(count_squares, 1 + count_perfect_squares[len - index * index]);
}
count_perfect_squares.emplace_back(count_squares);
}
return count_perfect_squares[n];
}
};
int main() {
std::cout << std::to_string(Solution().numSquares(12) == 3) << "\n";
return 0;
}
Python
Here we can simply use lru_cache:
class Solution:
dp = [0]
#functools.lru_cache
def numSquares(self, n):
dp = self.dp
while len(dp) <= n:
dp += min(dp[-i * i] for i in range(1, int(len(dp) ** 0.5 + 1))) + 1,
return dp[n]
Here are LeetCode's official solutions with comments:
Java: DP
class Solution {
public int numSquares(int n) {
int dp[] = new int[n + 1];
Arrays.fill(dp, Integer.MAX_VALUE);
// bottom case
dp[0] = 0;
// pre-calculate the square numbers.
int max_square_index = (int) Math.sqrt(n) + 1;
int square_nums[] = new int[max_square_index];
for (int i = 1; i < max_square_index; ++i) {
square_nums[i] = i * i;
}
for (int i = 1; i <= n; ++i) {
for (int s = 1; s < max_square_index; ++s) {
if (i < square_nums[s])
break;
dp[i] = Math.min(dp[i], dp[i - square_nums[s]] + 1);
}
}
return dp[n];
}
}
Java: Greedy
class Solution {
Set<Integer> square_nums = new HashSet<Integer>();
protected boolean is_divided_by(int n, int count) {
if (count == 1) {
return square_nums.contains(n);
}
for (Integer square : square_nums) {
if (is_divided_by(n - square, count - 1)) {
return true;
}
}
return false;
}
public int numSquares(int n) {
this.square_nums.clear();
for (int i = 1; i * i <= n; ++i) {
this.square_nums.add(i * i);
}
int count = 1;
for (; count <= n; ++count) {
if (is_divided_by(n, count))
return count;
}
return count;
}
}
Java: Breadth First Search
class Solution {
public int numSquares(int n) {
ArrayList<Integer> square_nums = new ArrayList<Integer>();
for (int i = 1; i * i <= n; ++i) {
square_nums.add(i * i);
}
Set<Integer> queue = new HashSet<Integer>();
queue.add(n);
int level = 0;
while (queue.size() > 0) {
level += 1;
Set<Integer> next_queue = new HashSet<Integer>();
for (Integer remainder : queue) {
for (Integer square : square_nums) {
if (remainder.equals(square)) {
return level;
} else if (remainder < square) {
break;
} else {
next_queue.add(remainder - square);
}
}
}
queue = next_queue;
}
return level;
}
}
Java: Most efficient solution using math
Runtime: O(N ^ 0.5)
Memory: O(1)
class Solution {
protected boolean isSquare(int n) {
int sq = (int) Math.sqrt(n);
return n == sq * sq;
}
public int numSquares(int n) {
// four-square and three-square theorems.
while (n % 4 == 0)
n /= 4;
if (n % 8 == 7)
return 4;
if (this.isSquare(n))
return 1;
// enumeration to check if the number can be decomposed into sum of two squares.
for (int i = 1; i * i <= n; ++i) {
if (this.isSquare(n - i * i))
return 2;
}
// bottom case of three-square theorem.
return 3;
}
}
I've written this code that computes the sum of the positive divisors, and all the values have to be to the power of a.
For instance:
sigma(0,14) = 1^0 + 2^0 + 7^0 + 14^0 = 4;
sigma(2,12) = 1^2 + 2^2 + 3^2 + 4^2 + 6^2 + 12^2 = 210.
sigma(a, b).
I have tried different versions but I don't know how to add the power function.
try {
int a = Integer.parseInt(input1.getText());
int b = Integer.parseInt(input2.getText());
int result1 = 0;
for (int i = 2; i <= Math.sqrt(b); i++)
{
if (b % i == 0)
{
if (i == (b / i))
result1 += i;
else
result1 += (i + b / i);
}
}
result.setText(String.valueOf(result1 + b + 1));
}
}
In Java the ^ character means XOR.
The power function is provided by the Math.pow() method.
So 3^2 would be Math.pow(3, 2).
If you wanted to implement it yourself for integers, you could do it simply like this:
double power(int a, int b) {
int pow = (b < 0) ? -b : b;
double result = 1;
for (int i = 0; i < pow; i++) {
result *= a;
}
return (b < 0) ? 1 / result : result;
}
But I wouldn't do it myself. It gets a bit more complicated for floating points, and Java has a native underlying implementation which is much faster.
IntStream delivers beautiful concise calculation.
static int sigma(int exp, int num) {
IntStream.rangeClosed(1, num) // 1, ..., num
.filter(k -> num % k == 0) // Only divisors
.map(k -> pow(k, exp))
.sum();
}
static int pow(int k, int exp) {
if (exp == 0) {
return 1;
}
int squareRoot = pow(k, exp/2);
int n = squareRoot * squareRoot;
return (exp % 2) == 0 ? n : n*k;
}
The power calculation can be optimized by not using exp# multiplications of k but square roots.
For those interested in program transformation:
pow(k, exp) needs only to rely on exp with recursion to exp/2 (integer division). So you could turn the code inside out, have a vector of divisors,
and operate on that.
If you want to implement it without using Math.pow() you can simply follow the mathematical definition of the exponentiation for a positive exponent:
public static long exp(int a, int b){ //computes a^b
long result = 1;
for (int i = 0; i < b; i++) {
result *= a;
}
return result;
}
I would recommend that you use Java lambdas to accomplish what you're looking for.
Taking an input and returning a List of positive divisors seems useful on its own.
Raising every entry to a power could be done easily with a lambda.
Keep the two functions separate. Take a more functional approach.
Here is a simple code for you:
public static void main(String args[]) {
Scanner scanner = new Scanner(System.in);
List<Integer> listOfBs = new ArrayList<>();
System.out.println("Input your a");
int a = scanner.nextInt();
System.out.println("Input your b");
int b = scanner.nextInt();
int sqrt = (int) Math.sqrt(b);
for (int i = 1; i <= sqrt; i++) {
if (b % i == 0) {
listOfBs.add(i);
int d = b / i;
if (d != i) {
listOfBs.add(d);
}
}
}
int sigma = 0;
for(int e : listOfBs)
{
sigma += Math.pow(e,a);
}
System.out.println("Your sigma function is: "+sigma);
}
}
Let's say that I want to calculate the square root of 8. There are two ways to display the result as you can see here:
I think that the best way I have to obtain the second solution is this:
I want to try do display in my Java application 2√2 instead of 2,828427... and so I thought to develop a class following these steps. Let's consider the square root of 8.
Get the prime factors of 8 (2*2*2)
Count the exponent and try to export them (2^2 * 2 --> 2√2)
I have developed, as you can see below, a code that outputs the factors. If you input 8, the method estraiRadice() will output 2 * 2 * 2, which is correct.
private int b = 2;
public String estraiRadice(double x) {
String resRad = "";
int[] exponents = new int[100];
//Scomposizione in fattori primi
while (x > 1) {
if ((x % b) == 0) {
x /= b;
resRad += String.valueOf(b) + " * ";
} else {
b++;
}
}
return resRad;
}
The second step is giving me problems because I don't know exactly how to do create the power of a number and export it from the square root. I mean: how can that √2*2*2 become a √4*2 and then 2√2?
I thought that I could store in an array the exponent for each base and then try to export it somehow. Do you have any advice?
Try this:
public static int[] squareRoot(int number) {
int number1 = number;
List<Integer> roots = new ArrayList<>();
int coefficient = 1;
for (int i = 2; i < number1; i++) {
if (number1 % (i * i) == 0) {
roots.add(i);
number1 /= i * i;
for (int j = 2; j < number1; j++) {
if (number1 % (j * j) == 0) {
roots.add(j);
number1 /= j * j;
}
}
}
}
for (int root : roots) coefficient *= root;
return new int[]{coefficient, number1};
}
You can call it like this:
System.out.println(squareRoot(96)[0] + "√" + squareRoot(96)[1]);
You can use a HashMap to store prime number power pairs
HashMap<Integer,Integer> getRoots(int x)
{
HashMap<Integer,Integer> retval = new HashMap<Integer,Integer>();
int i=2;
while(i<=x)
{
int power = 0;
while( x%i == 0)
{
power++;
x /= i;
}
if(power>0)
{
retval.put(i,power);
}
if(x==1)
{
break;
}
i++;
}
return retval;
}
This is my program
// ************************************************************
// PowersOf2.java
//
// Print out as many powers of 2 as the user requests
//
// ************************************************************
import java.util.Scanner;
public class PowersOf2 {
public static void main(String[] args)
{
int numPowersOf2; //How many powers of 2 to compute
int nextPowerOf2 = 1; //Current power of 2
int exponent= 1;
double x;
//Exponent for current power of 2 -- this
//also serves as a counter for the loop Scanner
Scanner scan = new Scanner(System.in);
System.out.println("How many powers of 2 would you like printed?");
numPowersOf2 = scan.nextInt();
System.out.println ("There will be " + numPowersOf2 + " powers of 2 printed");
//initialize exponent -- the first thing printed is 2 to the what?
while( exponent <= numPowersOf2)
{
double x1 = Math.pow(2, exponent);
System.out.println("2^" + exponent + " = " + x1);
exponent++;
}
//print out current power of 2
//find next power of 2 -- how do you get this from the last one?
//increment exponent
}
}
The thing is that I am not allowed to use the math.pow method, I need to find another way to get the correct answer in the while loop.
Powers of 2 can simply be computed by Bit Shift Operators
int exponent = ...
int powerOf2 = 1 << exponent;
Even for the more general form, you should not compute an exponent by "multiplying n times". Instead, you could do Exponentiation by squaring
Here is a post that allows both negative/positive power calculations.
https://stackoverflow.com/a/23003962/3538289
Function to handle +/- exponents with O(log(n)) complexity.
double power(double x, int n){
if(n==0)
return 1;
if(n<0){
x = 1.0/x;
n = -n;
}
double ret = power(x,n/2);
ret = ret * ret;
if(n%2!=0)
ret = ret * x;
return ret;
}
You could implement your own power function.
The complexity of the power function depends on your requirements and constraints.
For example, you may constraint exponents to be only positive integer.
Here's an example of power function:
public static double power(double base, int exponent) {
double ans = 1;
if (exponent != 0) {
int absExponent = exponent > 0 ? exponent : (-1) * exponent;
for (int i = 1; i <= absExponent; i++) {
ans *= base;
}
if (exponent < 0) {
// For negative exponent, must invert
ans = 1.0 / ans;
}
} else {
// exponent is 0
ans = 1;
}
return ans;
}
If there are no performance constraints you can do:
double x1=1;
for(int i=1;i<=numPowersOf2;i++){
x1 =* 2
}
You can try to do this based on this explanation:
public double myPow(double x, int n) {
if(n < 0) {
if(n == Integer.MIN_VALUE) {
n = (n+1)*(-1);
return 1.0/(myPow(x*x, n));
}
n = n*(-1);
return (double)1.0/myPow(x, n);
}
double y = 1;
while(n > 0) {
if(n%2 == 0) {
x = x*x;
}
else {
y = y*x;
x = x*x;
}
n = n/2;
}
return y;
}
It's unclear whether your comment about using a loop is a desire or a requirement. If it's just a desire there is a math identity you can use that doesn't rely on Math.Pow.
xy = ey∙ln(x)
In Java this would look like
public static double myPow(double x, double y){
return Math.exp(y*Math.log(x));
}
If you really need a loop, you can use something like the following
public static double myPow(double b, int e) {
if (e < 0) {
b = 1 / b;
e = -e;
}
double pow = 1.0;
double intermediate = b;
boolean fin = false;
while (e != 0) {
if (e % 2 == 0) {
intermediate *= intermediate;
fin = true;
} else {
pow *= intermediate;
intermediate = b;
fin = false;
}
e >>= 1;
}
return pow * (fin ? intermediate : 1.0);
}
// Set the variables
int numPowersOf2; //How many powers of 2 to compute
int nextPowerOf2 = 1; //Current power of 2
int exponent = 0;
/* User input here */
// Loop and print results
do
{
System.out.println ("2^" + exponent + " = " + nextPowerOf2);
nextPowerOf2 = nextPowerOf2*2;
exponent ++;
}
while (exponent < numPowersOf2);
here is how I managed without using "myPow(x,n)", but by making use of "while". (I've only been learning Java for 2 weeks so excuse, if the code is a bit lumpy :)
String base ="";
String exp ="";
BufferedReader value = new BufferedReader (new InputStreamReader(System.in));
try {System.out.print("enter the base number: ");
base = value.readLine();
System.out.print("enter the exponent: ");
exp = value.readLine(); }
catch(IOException e){System.out.print("error");}
int x = Integer.valueOf(base);
int n = Integer.valueOf(exp);
int y=x;
int m=1;
while(m<n+1) {
System.out.println(x+"^"+m+"= "+y);
y=y*x;
m++;
}
To implement pow function without using built-in Math.pow(), we can use the below recursive way to implement it. To optimize the runtime, we can store the result of power(a, b/2) and reuse it depending on the number of times is even or odd.
static float power(float a, int b)
{
float temp;
if( b == 0)
return 1;
temp = power(a, b/2);
// if even times
if (b%2 == 0)
return temp*temp;
else // if odd times
{
if(b > 0)
return a * temp * temp;
else // if negetive i.e. 3 ^ (-2)
return (temp * temp) / a;
}
}
I know this answer is very late, but there's a very simple solution you can use if you are allowed to have variables that store the base and the exponent.
public class trythis {
public static void main(String[] args) {
int b = 2;
int p = 5;
int r = 1;
for (int i = 1; i <= p; i++) {
r *= b;
}
System.out.println(r);
}
}
This will work with positive and negative bases, but not with negative powers.
To get the exponential value without using Math.pow() you can use a loop:
As long as the count is less than b (your power), your loop will have an
additional "* a" to it. Mathematically, it is the same as having a Math.pow()
while (count <=b){
a= a* a;
}
Try this simple code:
public static int exponent(int base, int power) {
int answer = 1;
for(int i = 0; i < power; i++) {
answer *= base;
}
return answer;
}
I have a function it returns prime factors of a number but when I initialize int array I set size.So the result consists unnecessary zeros.How can I return result array without zeros or how can I initialize array applicable size? I am not using Lists
public static int[] encodeNumber(int n){
int i;
int j = 0;
int[] prime_factors = new int[j];
if(n <= 1) return null;
for(i = 2; i <= n; i++){
if(n % i == 0){
n /= i;
prime_factors[j] = i;
i--;
j++;
}
}
return prime_factors;
}
Thanx!!!
Here is a quick way to get about the prime factors problem that I recently worked out. I don't claim it is original, but I did create it on my own. Actually had to do this in C, where I wanted to malloc only once.
public static int[] getPrimeFactors(final int i) {
return getPrimeFactors1(i, 0, 2);
}
private static int[] getPrimeFactors1(int number, final int numberOfFactorsFound, final int startAt) {
if (number <= 1) { return new int[numberOfFactorsFound]; }
if (isPrime(number)) {
final int[] toReturn = new int[numberOfFactorsFound + 1];
toReturn[numberOfFactorsFound] = number;
return toReturn;
}
final int[] toReturn;
int currentFactor = startAt;
final int currentIndex = numberOfFactorsFound;
int numberOfRepeatations = 0;
// we can loop unbounded by the currentFactor, because
// All non prime numbers can be represented as product of primes!
while (!(isPrime(currentFactor) && number % currentFactor == 0)) {
currentFactor += currentFactor == 2 ? 1 : 2;
}
while (number % currentFactor == 0) {
number /= currentFactor;
numberOfRepeatations++;
}
toReturn = getPrimeFactors1(number, currentIndex + numberOfRepeatations, currentFactor + (currentFactor == 2 ? 1 : 2));
while (numberOfRepeatations > 0) {
toReturn[currentIndex + --numberOfRepeatations] = currentFactor;
}
return toReturn;
}
Allocate as many factors as you think the number may have (32 sounds like a good candidate), and then use Arrays.copyOf() to cut off the array at the actual limit:
return Arrays.copyOf(prime_factors, j);