Hi I'm doing the Collatz sequence problem in project Euler (problem 14). My code works with numbers below 100000 but with numbers bigger I get stack over-flow error.
Is there a way I can re-factor the code to use tail recursion, or prevent the stack overflow. The code is below:
import java.util.*;
public class v4
{
// use a HashMap to store computed number, and chain size
static HashMap<Integer, Integer> hm = new HashMap<Integer, Integer>();
public static void main(String[] args)
{
hm.put(1, 1);
final int CEILING_MAX=Integer.parseInt(args[0]);
int len=1;
int max_count=1;
int max_seed=1;
for(int i=2; i<CEILING_MAX; i++)
{
len = seqCount(i);
if(len > max_count)
{
max_count = len;
max_seed = i;
}
}
System.out.println(max_seed+"\t"+max_count);
}
// find the size of the hailstone sequence for N
public static int seqCount(int n)
{
if(hm.get(n) != null)
{
return hm.get(n);
}
if(n ==1)
{
return 1;
}
else
{
int length = 1 + seqCount(nextSeq(n));
hm.put(n, length);
return length;
}
}
// Find the next element in the sequence
public static int nextSeq(int n)
{
if(n%2 == 0)
{
return n/2;
}
else
{
return n*3+1;
}
}
}
Your problem is not with the size of the stack (you're already memoizing the values), but with
the size of some of the numbers in the sequences, and
the upper limits of a 32-bit integer.
Hint:
public static int seqCount(int n)
{
if(hm.get(n) != null) {
return hm.get(n);
}
if (n < 1) {
// this should never happen, right? ;)
} ...
...
That should hopefully be enough :)
P.S. you'll run into a need for BigNums in a lot of project euler problems...
If you change from integer to long it will give you enough room to solve the problem.
Here was the code that I used to answer this one:
for(int i=1;i<=1000000;i+=2)
{
steps=1;
int n=i;
long current=i;
while(current!=1)
{
if(current%2==0)
{
current=current/2;
}else{
current=(current*3)+1;
}
steps++;
}
if(steps>best)
{
best=steps;
answer=n;
}
}
Brute forcing it, takes about 9 seconds to run
Side note (as it seems that you don't actually need tail call optimization for this problem): tail call optimization is not available in Java, and as far as I have heard, it is not even supported by the JVM bytecode. This means that any deep recursion is not possible, and you have to refactor it to use some other loop construct.
If you are counting the size of the Collatz sequence for numbers upto 1,000,000
you should re-consider using Integer type. I suggest using BigInteger or possible a long.
This should alleviate the problems encountered, but be warned you may still run out of heap-space depending on your JVM.
I think you need these 2 hints :
Don't use Integer because at some starting number, the sequence will fly into some numbers greater than Integer.Max_VALUE which is 2147483647. Use Long instead.
Try not to use recursion to solve this problem, even with memoization. As i mentioned earlier some numbers will fly high and produce a great deal of stacks which will lead into stack overflow. Try using "regular" iteration like do-while or for. Of course you can still use some ingredient like memoization in "regular" loop.
Oh i forget something. Perhaps the stack overflow occurs because of arithmetic overflow. Since you use Integer, maybe Java "change" those "flying numbers" into a negative number when arithmetic overflow occurs. And as seen in method seqCount(int), you don't check invariant n > 0.
You can solve this problem not only with recursion but also with a single loop. there is overflow if you write int. because it generates long while chaning and the recursion never ends because never equal to 1 and you probably get stackoverflow error
Here is my solution with loop and recursion:
public class Collatz {
public int getChainLength(long i) {
int count = 1;
while (i != 1) {
count++;
if (i % 2 == 0) {
i /= 2;
} else {
i = 3 * i + 1;
}
}
return count;
}
public static int getChainLength(long i, int count) {
if (i == 1) {
return count;
} else if (i % 2 == 0) {
return getChainLength(i / 2, count + 1);
} else {
return getChainLength(3 * i + 1, count + 1);
}
}
public int getLongestChain(int number) {
int longestChain[] = { 0, 0 };
for (int i = 1; i < number; i++) {
int chain = getChainLength(i);
if (longestChain[1] < chain) {
longestChain[0] = i;
longestChain[1] = chain;
}
}
return longestChain[0];
}
/**
* #param args
*/
public static void main(String[] args) {
System.out.println(new Collatz().getLongestChain(1000000));
}
}
Here you can have a look at my recursive implementation of problem 14:
http://chmu.bplaced.net/?p=265
import java .util.*;
public class file
{
public static void main(String [] args)
{
long largest=0;
long number=0;
for( long i=106239;i<1000000;i=i+2)
{
long k=1;
long z=i;
while(z!=1)
{
if(z%2==0)
{
k++;
z=z/2;
} else{
k++;
z=3*z+1;
}
}
if(k>largest)
{
number=i;
largest=k;
System.out.println(number+" "+largest);
}
}//for loop
}//main
}
Related
I recently gave a codility test. There was a this question which I couldn't solve. Now that I'm trying at home, I would like to get help. I don't remember the complete question language, but I do remember the output how would the program respond. Here we go.
"write a java program, for a given number N, need to find the lowest number for the given N. N could be a billion number too."
{this may not be the exact one, Sorry about that}
For Example:
N=1 then o/p is 0.
N=123 then o/p is 100
N=1234 then o/p is 1000 and so on.
My Solution: --just a workaround, this isn't actual logic.
class Solution {
public int solution(int N) {
int pointer=0;
if (N == 1) {
return 0;
} else {
String digitsCount = Integer.toString(N);
for(int i = 0; i < digitsCount.length(); i++) {
pointer++;
}
StringBuffer subString = new StringBuffer();
int count=0;
while(count < pointer-1) {
subString.append("0");
count++;
}
subString = subString.insert(0, "1");
return Integer.parseInt(subString.toString());
}
}
}
Using math library, should be good for about 16 digits.
long getLow(long in) {
if (in <= 1) return 0; // see note below
return (long)(Math.pow(10, Math.floor(Math.log10(in))));
}
The calculation is undefined for in < 1; we return 0. For in = 1 we return 0 per original code, though returning 1 would surely be more consistent: 2,3,...9 return 1, so why not 1 returns 1?
Your solution seems to work fine. The only thing it doesn't take into account is the fact that N can be a very large number. int only has a max value of about 2 billion.
Here is my solution:
public static long getLowestNumberWithSameNumberOfDigits(long input) {
if (input < 10) { // special case
return 0;
}
long trial = 10;
while (input / trial >= 10) {
trial *= 10;
}
return trial;
}
Thank You! Guys. All the suggestions were helpful. Infact, every suggestion has a learning. Here is the updated code. Please accept if you think its good enough.
private static long solution(long N) {
if (N == 1) {
return 0;
} else {
String digitsCount = Long.toString(N);
int pointer=digitsCount.length();
StringBuilder subString = new StringBuilder();
subString.append("1");
for(int i=0; i<pointer-1; i++) {
subString.append("0");
}
return Long.parseLong(subString.toString());
}
}
I'm not sure how to improve my solution for the jump game question (https://leetcode.com/problems/jump-game/description/) .It seems logically correct but I encounter a java.lang.Stackoverflow error for large inputs like [nums=[1,1,1,1,1,1,1,........]]
I know that I'm overflowing due to too many recursive calls , how can i optimize it ?
class Solution {
public boolean canJump(int[] nums) {
int []f = new int[1];
f[0] = 0;
return help(nums,0,f);
}
public static boolean help(int[]nums, int c, int[] f) {
if(c==nums.length-1) {
f[0] =1;
return true;
}
if(f[0]==1) return true;
int val = nums[c];
for(int i = 1; i <= val; i++) {
if(f[0]==1) return true;
return help(nums,(c + i), f);
}
return false;
}
}
This can be solved in T:O(N) with greedy algorithm:
class Solution {
public int jump(int[] nums) {
int res=0, l=0, r=0;
while(r<(nums.length-1)){
int farthest=0;
for (int i=l;i<r+1;i++){
farthest=Integer.max(farthest,i+nums[i]);
}
l=r+1;
r=farthest;
res++;
}
return res;
}
}
Explanation
nums = [2,3,1,1,4]
you jump 2 steps. you get the index 2.so you are jumping elements [3,1]. Nov you loop through [3,1] and check which one will take you to the further. In this case it is 3. Then update the variables. Increase res=1
From element 3 which is index-1. you jump 3 steps, jumping [1,1,4]. Now loop through [1,1,4] find the farthest. which is 4. increase res=2. Since out of while loop, return res=2.
It seems to have two nested loops, but if you look carefully, total iteration is N.
I need a task about finding Fibonacci Sequence for my independent project in Java. Here are methods for find.
private static long getFibonacci(int n) {
switch (n) {
case 0:
return 0;
case 1:
return 1;
default:
return (getFibonacci(n-1)+getFibonacci(n-2));
}
}
private static long getFibonacciSum(int n) {
long result = 0;
while(n >= 0) {
result += getFibonacci(n);
n--;
}
return result;
}
private static boolean isInFibonacci(long n) {
long a = 0, b = 1, c = 0;
while (c < n) {
c = a + b;
a = b;
b = c;
}
return c == n;
}
Here is main method:
long key = getFibonacciSum(n);
System.out.println("Sum of all Fibonacci Numbers until Fibonacci[n]: "+key);
System.out.println(getFibonacci(n)+" is Fibonacci[n]");
System.out.println("Is n2 in Fibonacci Sequence ?: "+isInFibonacci(n2));
Codes are completely done and working. But if the n or n2 will be more than normal (50th numbers in Fib. Seq.) ? Codes will be runout. Are there any suggestions ?
There is a way to calculate Fibonacci numbers instantaneously by using Binet's Formula
Algorithm:
function fib(n):
root5 = squareroot(5)
gr = (1 + root5) / 2
igr = 1 - gr
value = (power(gr, n) - power(igr, n)) / root5
// round it to the closest integer since floating
// point arithmetic cannot be trusted to give
// perfect integer answers.
return floor(value + 0.5)
Once you do this, you need to be aware of the programming language you're using and how it behaves. This will probably return a floating point decimal type, whereas integers are probably desired.
The complexity of this solution is O(1).
Yes, one improvement you can do is to getFibonacciSum(): instead of calling again and again to isInFibonacci which re-calculates everything from scratch, you can do the exact same thing that isInFibonacci is doing and get the sum in one pass, something like:
private static int getFibonacciSum(int n) {
int a = 0, b = 1, c = 0, sum = 0;
while (c < n) {
c = a + b;
a = b;
sum += b;
b = c;
}
sum += c;
return sum;
}
Well, here goes my solution using a Map and some math formulas. (source:https://www.nayuki.io/page/fast-fibonacci-algorithms)
F(2k) = F(k)[2F(k+1)−F(k)]
F(2k+1) = F(k+1)^2+F(k)^2
It is also possible implement it using lists instead of a map but it is just reinventing the wheel.
When using Iteration solution, we don't worry about running out of memory, but it takes a lot of time to get fib(1000000), for example. In this solution we may be running out of memory for very very very very big inputs (like 10000 billion, idk) but it is much much much faster.
public BigInteger fib(BigInteger n) {
if (n.equals(BigInteger.ZERO))
return BigInteger.ZERO;
if (n.equals(BigInteger.ONE) || n.equals(BigInteger.valueOf(2)))
return BigInteger.ONE;
BigInteger index = n;
//we could have 2 Lists instead of a map
Map<BigInteger,BigInteger> termsToCalculate = new TreeMap<BigInteger,BigInteger>();
//add every index needed to calculate index n
populateMapWhitTerms(termsToCalculate, index);
termsToCalculate.put(n,null); //finally add n to map
Iterator<Map.Entry<BigInteger, BigInteger>> it = termsToCalculate.entrySet().iterator();//it
it.next(); //it = key number 1, contains fib(1);
it.next(); //it = key number 2, contains fib(2);
//map is ordered
while (it.hasNext()) {
Map.Entry<BigInteger, BigInteger> pair = (Entry<BigInteger, BigInteger>)it.next();//first it = key number 3
index = (BigInteger) pair.getKey();
if(index.remainder(BigInteger.valueOf(2)).equals(BigInteger.ZERO)) {
//index is divisible by 2
//F(2k) = F(k)[2F(k+1)−F(k)]
pair.setValue(termsToCalculate.get(index.divide(BigInteger.valueOf(2))).multiply(
(((BigInteger.valueOf(2)).multiply(
termsToCalculate.get(index.divide(BigInteger.valueOf(2)).add(BigInteger.ONE)))).subtract(
termsToCalculate.get(index.divide(BigInteger.valueOf(2)))))));
}
else {
//index is odd
//F(2k+1) = F(k+1)^2+F(k)^2
pair.setValue((termsToCalculate.get(index.divide(BigInteger.valueOf(2)).add(BigInteger.ONE)).multiply(
termsToCalculate.get(index.divide(BigInteger.valueOf(2)).add(BigInteger.ONE)))).add(
(termsToCalculate.get(index.divide(BigInteger.valueOf(2))).multiply(
termsToCalculate.get(index.divide(BigInteger.valueOf(2))))))
);
}
}
// fib(n) was calculated in the while loop
return termsToCalculate.get(n);
}
private void populateMapWhitTerms(Map<BigInteger, BigInteger> termsToCalculate, BigInteger index) {
if (index.equals(BigInteger.ONE)) { //stop
termsToCalculate.put(BigInteger.ONE, BigInteger.ONE);
return;
} else if(index.equals(BigInteger.valueOf(2))){
termsToCalculate.put(BigInteger.valueOf(2), BigInteger.ONE);
return;
} else if(index.remainder(BigInteger.valueOf(2)).equals(BigInteger.ZERO)) {
// index is divisible by 2
// FORMUMA: F(2k) = F(k)[2F(k+1)−F(k)]
// add F(k) key to termsToCalculate (the key is replaced if it is already there, we are working with a map here)
termsToCalculate.put(index.divide(BigInteger.valueOf(2)), null);
populateMapWhitTerms(termsToCalculate, index.divide(BigInteger.valueOf(2)));
// add F(k+1) to termsToCalculate
termsToCalculate.put(index.divide(BigInteger.valueOf(2)).add(BigInteger.ONE), null);
populateMapWhitTerms(termsToCalculate, index.divide(BigInteger.valueOf(2)).add(BigInteger.ONE));
} else {
// index is odd
// FORMULA: F(2k+1) = F(k+1)^2+F(k)^2
// add F(k+1) to termsToCalculate
termsToCalculate.put(((index.subtract(BigInteger.ONE)).divide(BigInteger.valueOf(2)).add(BigInteger.ONE)),null);
populateMapWhitTerms(termsToCalculate,((index.subtract(BigInteger.ONE)).divide(BigInteger.valueOf(2)).add(BigInteger.ONE)));
// add F(k) to termsToCalculate
termsToCalculate.put((index.subtract(BigInteger.ONE)).divide(BigInteger.valueOf(2)), null);
populateMapWhitTerms(termsToCalculate, (index.subtract(BigInteger.ONE)).divide(BigInteger.valueOf(2)));
}
}
This method of solution is called dynamic programming
In this method we are remembering the previous results
so when recursion happens then the cpu doesn't have to do any work to recompute the same value again and again
class fibonacci
{
static int fib(int n)
{
/* Declare an array to store Fibonacci numbers. */
int f[] = new int[n+1];
int i;
/* 0th and 1st number of the series are 0 and 1*/
f[0] = 0;
f[1] = 1;
for (i = 2; i <= n; i++)
{
/* Add the previous 2 numbers in the series
and store it */
f[i] = f[i-1] + f[i-2];
}
return f[n];
}
public static void main (String args[])
{
int n = 9;
System.out.println(fib(n));
}
}
public static long getFib(final int index) {
long a=0,b=0,total=0;
for(int i=0;i<= index;i++) {
if(i==0) {
a=0;
total=a+b;
}else if(i==1) {
b=1;
total=a+b;
}
else if(i%2==0) {
total = a+b;
a=total;
}else {
total = a+b;
b=total;
}
}
return total;
}
I have checked all solutions and for me, the quickest one is to use streams and this code could be easily modified to collect all Fibonacci numbers.
public static Long fibonaciN(long n){
return Stream.iterate(new long[]{0, 1}, a -> new long[]{a[1], a[0] + a[1]})
.limit(n)
.map(a->a[0])
.max(Long::compareTo)
.orElseThrow();
}
50 or just below 50 is as far as you can go with straight recursive implementation. You can switch to iterative or dynamic programming (DP) approaches if you want to go much higher than that. I suggest learning about those from this: https://www.javacodegeeks.com/2014/02/dynamic-programming-introduction.html. And don't forget to look the a solution in the comment by David therein, real efficient. The links shows how even n = 500000 can be computed instantaneously using the DP method. The link also explains the concept of "memoization" to speed up computation by storing intermediate (but later on re-callable) results.
I was writing a recursive algorithm to calculate Fibonacci numbers in Java as part of a programming 101 course. This is the code:
public class Fib {
public static void main(String[] args) {
Fib fib = new Fib();
}
public Fib() {
int end = 9;
long[] nums = new long[2];
printFib(0, end, nums);
}
private void printFib(int i, int end, long[] nums) {
while(i < end) {
if(i == 0 || i == 1) {
nums[i] = 1;
System.out.println("1");
} else {
long fib;
fib = 0;
fib += (nums[0] + nums[1]);
nums[0] = nums[1];
nums[1] = fib;
System.out.println(fib);
}
i++;
printFib(i, end, nums);
}
}
}
As I was stepping through the program it was working as intended until i became equal to end, the variable telling the printFib method how many Fibonacci numbers it should print out. When ì was equal to end while(i < 1) returns false as expected and the program go to the last }, now you'd(me)
expect the program to return the constructor from which I initially called the function and the program should exit, this not the case. The program goes back to the while statement and somehow evaluates to false again. Then it does the same thing again except the second time it decreases i by 1(what?!) and then proceeds to the else clause when it reaches the if statement. It then does the same thing over and over alternating the amount it subtracts from i between 1 and 2. I've asked my teacher about this and he was unable to explain it.
The program works fully like I intended if I replace the while with an if so maybe there is something about while that I don't know.
Edit
So I realize now that each time the method is called i has a different value which is stored and when the method exits and i = end the program goes back to the previous calls where i had a different value.
You implemented an iterative algorithm to calculate Fibonacci series. That's what the while loop does. There is no point in making the recursive call - printFib(i, end, nums) - at the end.
If you intended a recursive implementation, the entire while loop is not needed.
This code doesn't look right to me.
I would recommend that you not print from your method. Return a value to the main and let it print.
Your recursive method should not have a while loop in it. That's iteration - exactly what you're trying to avoid here.
Your method should have a stopping condition and a call to itself. That's not what you're doing.
Think about it like this:
/**
* Recursive Fibonnaci
* User: mduffy
* Date: 2/11/2015
* Time: 8:50 AM
* #link http://stackoverflow.com/questions/28455798/strange-behavior-in-recursive-algorithm/28455863#28455863
*/
public class Math {
private static Map<Integer, Integer> memo = new ConcurrentHashMap<Integer, Integer>();
public static void main(String [] args) {
for (String arg : args) {
int n = Integer.valueOf(arg);
System.out.println(String.format("n: %d fib(n): %d", n, fibonnaci(n)));
}
}
public static int fibonnaci(int n) {
if (n < 0) throw new IllegalArgumentException("index cannot be negative");
int value = 0;
if (memo.containsKey(n)) {
value = memo.get(n);
} else {
if (n <= 1) {
value = n;
} else {
value = fibonnaci(n-1)+fibonnaci(n-2);
}
memo.put(n, value);
}
return value;
}
}
Basicly this is happening because i would guess that you are thinking of i as an reference which will influence the basic callings of the Fibunacci method calling the sub Fibunacci method. This will finally lead way to many calls of the fibunacci method.
in my eyes the loop doesn´t make sense in your recursive way of solving it.
I was given a homework assignment in Java to create classes that find Prime number and etc (you will see in code better).
My code:
class Primes {
public static boolean IsPrime(long num) {
if (num%2==0){
return false;
}
for (int i=3; i*i<=num;i+=2) {
if (num%i==0) {
return false;
}
}
return true;
} // End boolen IsPrime
public static int[] primes(int min, int max){
int counter=0;
int arcount=0;
for (int i=min;i<max;i++){
if (IsPrime(i)){
counter++;
}
}
int [] arr= new int[counter];
for (int i=min;i<max;i++){
if (IsPrime(i)){
arr[arcount]=i;
arcount++;
}
}
return arr;
} // End Primes
public static String tostring (int [] arr){
String ans="";
for (int i=0; i<arr.length;i++){
ans= ans+arr[i]+ " ";
}
return ans;
}
public static int closestPrime(long num){
long e = 0 , d = 0 , f = num;
for (int i = 2; i <= num + 1 ; i++){
if ((num + 1) % i == 0){
if ((num + 1) % i == 0 && (num + 1) == i){
d = num + 1;
break;
}
num++;
i = 1;
}
}
num = f;
for (int i = 2; i < num; i++){
if ((num - 1) % i == 0){
if ((num - 1) % i == 0 && (num - 1) == i){
e = num - 1;
break;
}
num--;
i = 1;
}
}
num = f;
if (d - num < num - e) System.out.println("Closest Prime: "+d);
else System.out.println("Closest Prime: "+e);
return (int) num;
} // End closestPrime
}//end class
The goal of my code is to be faster (and correct). I'm having difficulties achieving this. Suggestions?
**New code:
class Primes {
public static boolean IsPrime(int num) {
if (num==1){
return false;
}
for (int i=2; i<Math.sqrt(num);i++) {
if (num%i==0) {
return false;
}
}
return true;
}
// End boolen IsPrime
public static int[] primes(int min, int max){
int size=0;
int [] arrtemp= new int[max-min];
for (int i=min;i<max;i++){
if (IsPrime(i)){
arrtemp[size]=i;
size++;
}
}
int [] arr= new int[size];
for (int i=0;i<size;i++){
arr[i]=arrtemp[i];
}
return arr;
}
public static String tostring (int [] arr){
String ans="";
for (int i=0; i<arr.length;i++){
ans= ans+arr[i]+ " ";
}
return ans;
}
public static int closestPrime(int num) {
int count=1;
for (int i=num;;i++){
int plus=num+count, minus=num-count;
if (IsPrime(minus)){
return minus;
}
if (IsPrime(plus)) {
return plus;
}
count=count+1;
}
} // End closestPrime
}//end class
I did try to make it a bit better. what do you think, it can be improved more? (the speed test is still high...)
In your primes function you:
Check if the current number is divisible by two
Check to see if it's prime
Create an array to put your output in.
Check every number in the range again for primality before putting it in your array.
The problem is in the last step. By double-checking whether each number is prime, you're duplicating your most expensive operations.
You could use a dynamic data structure and add prime numbers to it as you find them. That way you only need to check once.
Alternatively, you could create a boolean array which is the size of your input range. Then as you find primes, set the corresponding array value to true.
UPDATE:
There are still a number of improvements you can make, but some will require more work than others to implement. Look at the specifics of your test and see what fits your needs.
Low-hanging fruit:
Use an ArrayList to collect primes as you find them in primes, as opposed to looping over the values twice.
In closestPrime, you're checking every single value on either side of num: half of these are even, thus not prime. You could adapt your code to check only odd numbers for primality.
Trickier to implement:
Try a more advanced algorithm for IsPrime: check out the Sieve of Eratosthenes
Above all, you should spend some time figuring out exactly where the bottlenecks are in your code. Oftentimes performance problems are caused by code we thought was perfectly fine. You might consider looking into the code-profiling options available in your development environment.
You make quite a few calls to isPrime(), each of which is very expensive. Your first step should be to minimize the number of times you do that, since the result doesn't change for any given number, there's no point calling more than once. You can do this with memoization by storing the values once they're computed:
ArrayList<Integer> memoList = new ArrayList<Integer>();
for(int i = 0; i < max; i++) {
if(isPrime(i)) {
memoList.add(i);
}
}
Now memoList holds all the primes you need, up to max, and you can loop over them rapidly without needing to recompute them every time.
Secondly, you can improve your isPrime() method. Your solution loops over every odd number from 3 to sqrt(n), but why not just loop over the primes, now that we know them?
public static boolean IsPrime(long num) {
for(int p : memoList) {
if(num % p == 0) {
return false;
}
}
return true;
}
These changes should dramatically improve how quickly your code runs, but there has been a lot of research into even more efficient ways of calculating primes. The Wikipedia page on Prime Numbers has some very good information on further tactics (prime sieves, in particular) you can experiment with.
Remember that as this is homework you should be sure to cite this page when you turn it in. You're welcome to use and expand upon this code, but not citing this question and any other resources you use is plagiarism.
I see a couple problems with your answer. First, 2 is a prime number. Your first conditional in IsPrime breaks this. Second, in your primes method, you are cycling through all number from min to max. You can safely ignore all negative numbers and all even numbers (as you do in IsPrime). It would make more sense to combine these two methods and save all the extra cycles.