Backstory (not important to the question): I've got a question in one of my classes and I couldn't solve it for the past week, and I am just so stuck with it and trying to find a good solution for it, maybe it's just my limited thinking or being new to the whole recursion idea in general or new to learning the programming language we are working with (C language).
The problem: So our task is to build a "function" (I don't know the correct word for it) that for a given integer num:
if the digit is in an even index the digit in that spot has to be even.
if the digit is in an odd index the digit in that spot has to be odd.
indexes start from 0.
you can only use 1 parameter (num)
you need to return 1 if the conditions are met 0 otherwise (C language)
For example:
The number 343,418 will be a valid number because every digit in an odd index is odd and every digit in an even index is even.(the example + indexes)
The number 343,518 will be an invalid number because on the second index there is a number 5, even index odd number. (the example + indexes)
Any hints to a solution or a way to solve this will be greatly appreciated as I was trying to solve this for a while.
Here is a possible approach:
Since the one's (least significant) digit must be even, a valid number considered as a whole must also be even. So stop and return 0 if num % 2 != 0.
Get the ten's digit by tens = (num / 10) % 10, leveraging that integer division rounds down. If tens is zero, we are done validating the digits, so return 1 if tens == 0. Otherwise tens must be odd, so return 0 if tens % 2 == 0.
Now discard the bottom two digits with num /= 100 and go back to step 1.
The "go back to step 1" part could be done with a while loop or as a "tail call" if you want to express it recursively.
As suggested in the discussion in the comments, the idea here is to iterate over the digits and keep track of the index as you go, where in each step you compare the digit and index's evenness:
int compareDigitsToIndexes(int num) {
int ind = 0;
while (num > 0) {
int digit = num % 10;
if (ind % 2 != digit % 2) {
return 0;
}
num /= 10;
++ind;
}
return 1;
}
Related
So I'm practicing simple python as revision for school and have come across the challenge "Write an algorithm that asks the user to input a number. The program should then count from 0 and for every other number it should output "Boo".
for count in range(count,10):
print(count)
count +=2
if count % 2 == 0:
print("boo")
That is what I tried to use, I messed around with it a bit to try make it work but for some reason I just can't think of the right way.
Here is a solution:
for num in range(0, count + 1):
if num % 2 == 0:
print(num)
else:
print("boo")
Let's look at every line:
for num in range(0, count + 1):
The number on the left of range is the starting point. The number on the right is the number it counts up to.
I changed count to num to remove some confusion in the syntax. The range function creates a list of numbers from 0 to (n - 1), so I add 1 to count so it will count to n instead of n - 1.
if num % 2 == 0:
print(num)
else:
print("boo")
num % 2 checks if a number is even. 0 will technically be considered "even" because 0 % 2 = 0. Because the algorithm starts with 0, we will have this print the num, and every other num (the odd numbers) will print "boo"
I'm currently tasked with writing a program that calculates amount of palindromes in any base from interval of <2;36>. The problem is that my solution has time complexity of O(n^2) at best and that is, if I was frank, really slow.
So far I've tried naive solutions such as converting all numbers from the interval to the base that is required, saving the conversion of the number to array and then checking each of the elements one by one.
This is what I've got so far :
int isTrue = 1;
int arr[64];
while(n > 0)
{
arr[counter] = n % base;
n = n / base;
counter++;
}
for(int i = 0; i < counter; i ++)
{
if(arr[i] != arr[counter - i - 1])
{
isTrue = 0;
break;
}
}
It is not good by any stretch, but it does work for the basic test. The problem is that I'm currently trying to solve bonus one which works with much bigger numbers.
By much bigger numbers I mean intervals that span billions of numbers, one of the inputs is for example this:
c 15 62103360044 155888062462
Result : 123502
Where c is task that the program is supposed to do (there was option of l which listed all palindromes which doesn't occur in the bonus tests), 15 is base and the two other numbers are the limits of the interval.
I'm supposed to count palindromes of five such intervals under one second and honestly, I'm pretty stuck.
I would appreciate any help, I'm sorry if I formatted my question wrongly or if it was too drawn out - This is the first time I've asked a question here.
Doing a palindrome check faster is a minor optimisation.
Initially I would even use java's number to String conversion.
What you want is to step through the interval in larger leaps.
You can use recursion for simplification in the initial version of your algorithm.
Let's look for base 10:
62_103_360_044
155_888_062_462
6 ... 6 (recursion on the middle part)
7 ... 7
8 ... 8
9 ... 9
1 ... 1
You need:
Number of digits (your counter)
First most significant digit
Parameters start and end
For this step you only need to increment one digit, which even may be done as char.
Notice also that the recursive call on ... gives the same result for 7, 8 and 9 with start 000..000 and end 999..999.
This will be tremendously faster. Happy coding.
Usage of recursion:
I am not giving a clean answer, as that would defeat the task's challenge.
public BigInteger palindromesInInterval(int base, BigInteger from, BigInteger to) {
return palindromesRec(base, from.toString(base), to.toString(base));
}
private BigInteger palindromesRec(int base, String from, String to) {
// Do the simple work:
if (from.length() > to.length()) {
return BigInteger.ZERO;
}
if (from.length() == to.length() && from.compareTo(to) > 0) {
return BigInteger.ZERO;
}
if (from.length() == 1) {
...
}
// Do a step:
int highDigit = Integer.parseInt(from.substring(0, 1), base);
int lowDigit = Integer.parseInt(from.substring(from.length() - 1), base);
BigInteger sum = BigInteger.ZERO;
int digit = Math.max(highDigit, lowDigit);
String from2 = from.substring(1, from.length() - 2); // Can start with 0
String to2 = "1000...000" -1; // Niners so to say.
while (digit < base) {
...
sum = sum.add(palidromesRec(base, from2, to2)); // RECURSION
from2 = "000...000";
}
...
return sum;
}
Recursion calling oneself, here only once, without extra parameters, which often are used. For instance it is much easier to split the work in:
from 6 2_103_360_04 4
to 9 9 .. 9 9
from 1 00 .. 0 1
to 1 55_888_062_46 2
And calculate for every X
from X 000 X (n zeroes)
to X 999 X (n time (base-1))
as base(n+1)/2.
For that you need a level of abstraction/simplification. Keep-it-simple.
I want to do this in C and I want to do it without using arrays or strings.
I have done it using arrays, but without it I do not know what to do. I am only allowed to use loops and if.
I found this to be an interesting problem and wrote the complete code for it. If you want to do it yourself, then don't look into the code. Here are some hints:
1. We know how many numbers of certain length there are: 9 1-digit numbers, 90 2-digits, 900 3-digits and so on
2. Thus, we can find out how long will be a number made of all 1, 2 and 3 -digit numbers written together: 9*1 + 90*2 + 900*3 = 2889
3. That means that if we are asked to find 253673-th digit, we can say for sure that it's a digit from a 4-digit number, because 253673 > 38889 and 253673 < 488889
4. Now we only need to find that 4-digit number and a digit inside of it.
Now, if you want just a solution, then here's my code, it's in C# though, but it should be really easy to translate if that's not a typo about C:
public static int GetDigit(long digitPosition)
{
if (digitPosition < 10)
return (int) digitPosition;
int N = 1;
long lengthOfNumber = 9;
int amountOfDigits = -1;
while(lengthOfNumber < digitPosition)
{
N++;
// there are 9 one-digit numbers, 90 two-digit numbers, 900 three-digit numbers and so on
int amountOfNumbers = 9 * (int)Math.Pow(10, N - 1);
// length of all N-digit numbers written together
amountOfDigits = amountOfNumbers * N;
// total length of composed number if we add all N-digit numbers
lengthOfNumber += amountOfDigits;
}
// now we know how much digits has the sub-number with target digit inside the composed number
// shift target digit position by removing all numbers below N length
// so if the digitPosition was 14, it will become 5th position in the number created from only 2-digit numbers, because we subtract all 9 1-digit numbers
digitPosition -= lengthOfNumber - amountOfDigits;
// get index of N-digit number that contains target digit, starting from the first N-digit number (for N=3 it's)
long numberIndex = (digitPosition - 1) / N;
// get index of digit inside that number, that is our target digit
long digitIndex = (digitPosition - 1) % N;
// find the number that contains target digit by adding index to the first N-digit number
long targetNumber = 1 * (long)Math.Pow(10, N - 1) + numberIndex;
// shift target digit to the target position
for (int i = 0; i < N - digitIndex - 1; i++)
targetNumber /= 10L;
// digit found
return (int) (targetNumber % 10L);
}
I'm a beginner still learning to us C and I don't know how to find the factors of an int that are the closest to each other.
For example, if the input was the number 6, the output would be [2,3]. If the input was 24, then the output would be [4,6].
Is there a way to do this? Any help would be appreciated.
The algorithm to do this is simple; take the square root of your number as an integer (you want to truncate, not round). Test if that value is a factor of your input; if so, your input divided by that number are your answer. Otherwise, subtract 1 from your previous value and try again.
In code (the array literal is the wrong syntax, but the theory is correct):
//this code assumes that your input is > 0, will not work otherwise
function int[] getClosestFactors(int input) {
int testNum = (int)sqrt(input);
while (input % testNum != 0) {
testNum--;
}
return {testNum, input / testNum};
}
Basically, you know that in any pair of factors, the lowest factor must be less than or equal to the square root. So if you start at the integer equal to or less than the square root of your input, and count down, the first factor you find will be the smaller of the pair of closest factors. This terminates for all integers > 0 because you will eventually reach 1, which is a factor of all other numbers.
So I have this problem.
Input # of rooms: 4
room1:6
room2:4
room3:7
room4:3
(if I type 5 in "Input # of rooms" there would also be room5)
Odd: 7 3
Even: 6 4
I have to display the odd and even numbers, so I came up with this code:
System.out.print("Input # of rooms: ");
int rms=Integer.parseInt(io.readLine());
int[] array=new int[rms];
int a=0;
int b=1;
do {
System.out.print("room "+b+":");
array[a] = Integer.parseInt(io.readLine());
a++;
b++;
} while (a<rms);
I don't know how to display which are Odd numbers and which are Even numbers?
you want to find the remainder or modulus when the param is divided by 2.
3 % 2 = 1 so odd
4 % 2 = 2 so even
if(param % 2 == 1){
Print odd number
}else{
Print even number
}
Should get you started
The use of the modulo operator (%) will be invaluable here - it performs integer division and returns the remainder of the quotient - kind of like short division.
The rules for determining the type of number are simple:
If the number is even, it is divisible by 2.
Otherwise, it is odd.
As for the printing part: I would recommend accumulating the values in two separate StringBuffers or Strings if you prefer, adding a space between when we get another of the type of value we want. Then, we can print it out pretty after we're done iterating through the array.
One last thing - you should only need one loop - preferably a for loop, since you know exactly how many elements you're going to iterate over. You can use the above rules for modulus to determine which number gets appended to which variable.