Determine place values for any base - math

I'm looking for a function that will determine the value of a place given a number and a base. For example,
Given:
Whole Value: 1120
Base: 10
Place: Tens place
Should return: 2
Does anybody know the math for this?
Edit: The function is also expected to pass the whole value numerically, not as a string like "e328fa" or something. Also the return value should be numeric as well, so a FindInPlace(60 (whole value), 16 (base), 2 (place, 1-based index)) should return 3.

With 1-based place indexing the formula is:
placeval = floor(number / (base^(place-1))) mod base
In Python:
def FindInPlace(number, base, place):
return number//base**(place-1) % base

If the number is already converted to an integer (i.e. base 10)
// Supports up to base 36
char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char FindPlace(int number, int base, int digit)
{
if(digit < 0) return 0;
// Essentially divide the number by [base] to the [digit] power
for(i=0; i<digit; i++)
{
number /= base;
}
// TODO: Verify that the digit is in range of digits
return digits[number % base];
}
(0 gives you the right most digit, 1 gives you the next to right-most digit, etc)
I've returned the digit as a char, to allow for bases more than 10.
Note that if you want to allow the user to input the desired digit as "1s place, 10s place, 100s place" or "1s, 16s, 256s", you simply do
digit = log(PlaceValue, base);
or rewrite the code to be
char FindPlace(int number, int base, int digitAsBaseToAPower)
{
// TODO: Error checking
return digits[(number / digitAsBaseToAPower) % base];
}

int getPlace(float x, float place) {
return (int)(x/place) % 10;
}
This works for base-10, and can handle places to the right or left of the decimal. You'd use it like this:
place = getPlace(1120,10);
otherPlace = getPlace(0.1120,1e-3);
A more general solution for any base is tricky. I'd go with a string solution.

Something like this?
int place_value(int value, int base, int place)
{
int value_in_place= value;
for (int place_index= 1; place_index<place; ++place_index)
{
value_in_place/=base;
}
return value_in_place % base;
}
where place is the one-based index of the digit you want from the right.

The following method, placeValue, returns a char, because bases 11-36 have digits greater than 9. The method expects:
int value: the whole value
int base: the number base to convert the whole to; acceptable values are 2-36
int place: the index of the digit; the least significant digit has index 1
import java.math.BigInteger;
...
private static char placeValue(int value, int base, int place) {
BigInteger bigValue = BigInteger.valueOf(value);
String baseString = bigValue.toString(base);
int numDigits = baseString.length();
int digitIndex = numDigits - place;
char digit = baseString.charAt(digitIndex);
return digit;
}

Related

Checking an integer is palindrome using recursion without using any extra reverse function

I have been writing a is_palindrome(int num) function which takes an integer and return true or false. I got the idea of reversing the integer and then check it with the original. To do that I need an extra reverse() function. But I want to know if there is a way of checking the palindrome using only one recursive function.
While a recursive algorithm isn't necessary to determine whether or not a number is a palindrome, the simplest recursive one I could think of would be as follows:
Pseudocode:
function is_palindrome(i) {
if (i is a single-digit number) return true
x = first digit of i
y = last digit of i
if (x != y) return false
if (i is a two-digit number) return true
j = i without the first and last digit
return is_palindrome(j)
}
The algorithm compares the first and last digits, removes them and recursively calls itself with the trimmed number until either all digits have been checked or a mismatch is found.
You can do it with a recursive function and a shim. Here is the recursive function to check whether a number is a palindrome.
bool is_palindrome_impl(int number, int radix, int highest_digit_divider) {
// First check if the number has 1 digit, in which case
// it is a palindrome.
if(highest_digit_divider < radix) { return true; }
// Then check if the highest digit is different from the lowest digit,
// in which case it is NOT a palindrome.
const int highest_digit = number / highest_digit_divider;
const int lowest_digit = number % radix;
if(highest_digit != lowest_digit) { return false; }
// Then check whether the inner part is a palindrome
const int inner_part = (number % highest_digit_divider) / radix;
return is_palindrome_impl(inner_part, radix, highest_digit_divider / radix / radix);
}
Then, you need a shim to implement the function with your signature.
Numbers preceded by - cannot be palindromes, so you check that befor recursing.
Then, you should calculate the highest digit divisor to be able to extract the first digit from your number.
bool is_palindrome(int number, int radix = 10) {
// Non-positive numbers are NEVER palindromes.
if(number < 0) { return false; }
// We first suppose that the number has less than 2 digits
int highest_digit_divider = 1;
int temp_number = number;
// As long as we are proven wrong, we increase the number of digits by 1
while(temp_number >= radix) {
temp_number /= radix;
highest_digit_divider *= radix;
}
return is_palindrome_impl(number, radix, highest_digit_divider);
}
Note that the algorithm is not radix-dependent, but invalid radixes (less than 2) should also receive appropriate treatment, depending on how you want and can report the error in the language you are using.

Search how many characters are in a C string

My task is to count how many characters are in a C string. The input is provided by a test driver that I don't have access to but my function is supposed to access the data and determine how many characters range from a-z and A-Z but my program keeps failing and I'm not sure what I'm doing wrong.
int countLetters(char * const line)
{
char index = *line;
int count;
while(!index)
{
if (index >= 'a' && index <= 'z')
count++;
if (index >= 'A' && index <= 'Z')
count++;
}
return count;
}
Try this
int countLetters(char * const line)
{
int index = 0;
int count = 0;
while(line[index])
{
if (line[index] >= 'a' && line[index] <= 'z')
count++;
if (line[index] >= 'A' && line[index] <= 'Z')
count++;
index++;
}
return count;
}
Here's what you did wrong
First: You assign your char index = *line;
making your index the first character in the string, which is wrong, because index suppose to represent position, not a character
Second: You didnt provide any mechanism to increase the index in other to loop the string
Third: You didnt initialize your count variable
Note: line[index] is the same as *(line + index)
Your line is a pointer which point to the first character in the string
So line + index is a pointer that point to the index-nth character in the string
By prefix a pointer with a * you're saying that i want to know the content that this pointer point to

Negative Number, Positive Numbers, pointers, and characters

I'm trying to figure out this program; it is an averaging program and it requires user input of:
p 4 p 7 p 2 n 1 e sum 12 average: 4
The user enters whether he was a positive number or negative.
We are asked to use int real_number(int* value) and make value a pointer to where the input value will be stored.
So far I have:
#include <stdio.h>
int real_number(int* value);
int real_number(int* value)
{
char *n = "negative";
char *p = "positive";
char *e = "end";
int *sum = 0;
int *avg = 0;
while(sum = 0)
{
printf(" \n");
scanf("%d", &sum);
}
}
int main()
{
}
I know it is not much, but I'm lost; any ideas?
Firstly you have to read characters while your character is different "e". Secondly you have an infinite cicle. In while loop modify the condition with == .
You need to have a counter to count how many numbers you entered. While you read numbers you must add these numbers to sum and count one.
Finally, in the output you write sum/counter

how to round an odd integer towards the nearest power of two

Add one to or subtract one from an odd integer such that the even result is closer to the nearest power of two.
if ( ??? ) x += 1; else x -= 1;// x > 2 and odd
For example, 25 through 47 round towards 32, adding one to 25 through 31 and subtracting one from 33 through 47. 23 rounds down towards 16 to 22 and 49 rounds up towards 64 to 50.
Is there a way to do this without finding the specific power of two that is being rounded towards. I know how to use a logarithm or count bits to get the specific power of two.
My specific use case for this is in splitting odd sized inputs to karatsuba multiplication.
If the second most significant bit is set then add, otherwise subtract.
if ( (x&(x>>1)) > (x>>2) ) x += 1; else x -= 1;
It isn't a big deal to keep all of the powers of 2 for a 32 bit integer (only 32 entries) do a quick binary search for the location it's supposed to be in. Then you can easily figure out which number it's closer to by subtracting from the higher and lower numbers and getting the abs. Then you can easily decide which one to add to.
You may be able to avoid the search by taking the log base 2 of your number and using that to index into the array
UPDATE: reminder this code is not thoroughly tested.
#include <array>
#include <cmath>
#include <iostream>
const std::array<unsigned int,32> powers =
{
1,1<<1,1<<2,1<<3,1<<4,1<<5,1<<6,1<<7,1<<8,1<<9,1<<10,1<<11,1<<12,1<<13,1<<14,
1<<15,1<<16,1<<17,1<18,1<<19,1<<20,1<<21,1<<22,1<<23,1<<24,1<<25,1<<26,1<<27,
1<<28,1<<29,1<<30,1<<31 -1
};
std::array<unsigned int,32> powers_of_two() {
std::array<unsigned int,32> powers_of_two{};
for (unsigned int i = 0; i < 31; ++i) {
powers_of_two[i] = 1 << i;
}
powers_of_two[31]=~0;
return powers_of_two;
}
unsigned int round_to_closest(unsigned int number) {
if (number % 2 == 0) return number;
unsigned int i = std::ceil(std::log2(number));
//higher index
return (powers[i]-number) < (number - powers[i-1]) ?
++number:--number;
}
int main() {
std::cout << round_to_closest(27) << std::endl;
std::cout << round_to_closest(23) << std::endl;
return 0;
}
Since I can't represent 2 ^ 31 I used the closest unsigned int to it ( all 1's) this means that 1 case out of all of them will produce the incorrect result, I figured that's not a big deal.
I was thinking that you could use a std::vector<bool> as a very large lookup table on wether to add 1 or subtract 1, seems like overkill to me for an operation that seems to run quite fast.
As #aaronman pointed out, if you are working with integers only the fastest way to do this is to have all powers of 2 in table as there are not that many. By construction, in an unsigned 32 bit integer there are 32 powers of 2 (including the number 1), in a 64 bit integer there are 64 and so on.
But if you want to do it on the fly for a generic case you can easily calculate the surrounding powers of 2 of any number. In c/c++:
#include <math.h>
(...)
double bottom, top, number, exponent;
number = 1234; // Set the value for number
exponent = int(log(number) / log(2.0)); // int(10.2691) = 10
bottom = pow(2, exponent); // 2^10 = 1024
top = bottom * 2; // 2048
// Calculate the difference between number, top and bottom and add or subtract
// 1 accordingly
number = (top - number) < (number - bottom) ? number + 1 : number - 1;
For nearest (not greatest or equal) - see this:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
unsigned int val = atoi(argv[1]);
unsigned int x = val;
unsigned int result;
do {
result = x;
} while(x &= x - 1);
if((result >> 1) & val)
result <<= 1;
printf("result=%u\n", result);
return 0;
}
if you need greatest or equal - change:
if((result >> 1) & val)
to
if(result != val)

Codility K-Sparse Test **Spoilers**

Have you tried the latest Codility test?
I felt like there was an error in the definition of what a K-Sparse number is that left me confused and I wasn't sure what the right way to proceed was. So it starts out by defining a K-Sparse Number:
In the binary number "100100010000" there are at least two 0s between
any two consecutive 1s. In the binary number "100010000100010" there
are at least three 0s between any two consecutive 1s. A positive
integer N is called K-sparse if there are at least K 0s between any
two consecutive 1s in its binary representation. (My emphasis)
So the first number you see, 100100010000 is 2-sparse and the second one, 100010000100010, is 3-sparse. Pretty simple, but then it gets down into the algorithm:
Write a function:
class Solution { public int sparse_binary_count(String S,String T,int K); }
that, given:
string S containing a binary representation of some positive integer A,
string T containing a binary representation of some positive integer B,
a positive integer K.
returns the number of K-sparse integers within the range [A..B] (both
ends included)
and then states this test case:
For example, given S = "101" (A = 5), T = "1111" (B=15) and K=2, the
function should return 2, because there are just two 2-sparse integers
in the range [5..15], namely "1000" (i.e. 8) and "1001" (i.e. 9).
Basically it is saying that 8, or 1000 in base 2, is a 2-sparse number, even though it does not have two consecutive ones in its binary representation. What gives? Am I missing something here?
Tried solving that one. The assumption that the problem makes about binary representations of "power of two" numbers being K sparse by default is somewhat confusing and contrary.
What I understood was 8-->1000 is 2 power 3 so 8 is 3 sparse. 16-->10000 2 power 4 , and hence 4 sparse.
Even we assume it as true , and if you are interested in below is my solution code(C) for this problem. Doesn't handle some cases correctly, where there are powers of two numbers involved in between the two input numbers, trying to see if i can fix that:
int sparse_binary_count (const string &S,const string &T,int K)
{
char buf[50];
char *str1,*tptr,*Sstr,*Tstr;
int i,len1,len2,cnt=0;
long int num1,num2;
char *pend,*ch;
Sstr = (char *)S.c_str();
Tstr = (char *)T.c_str();
str1 = (char *)malloc(300001);
tptr = str1;
num1 = strtol(Sstr,&pend,2);
num2 = strtol(Tstr,&pend,2);
for(i=0;i<K;i++)
{
buf[i] = '0';
}
buf[i] = '\0';
for(i=num1;i<=num2;i++)
{
str1 = tptr;
if( (i & (i-1))==0)
{
if(i >= (pow((float)2,(float)K)))
{
cnt++;
continue;
}
}
str1 = myitoa(i,str1,2);
ch = strstr(str1,buf);
if(ch == NULL)
continue;
else
{
if((i % 2) != 0)
cnt++;
}
}
return cnt;
}
char* myitoa(int val, char *buf, int base){
int i = 299999;
int cnt=0;
for(; val && i ; --i, val /= base)
{
buf[i] = "0123456789abcdef"[val % base];
cnt++;
}
buf[i+cnt+1] = '\0';
return &buf[i+1];
}
There was an information within the test details, showing this specific case. According to this information, any power of 2 is considered K-sparse for any K.
You can solve this simply by binary operations on integers. You are even able to tell, that you will find no K-sparse integers bigger than some specific integer and lower than (or equal to) integer represented by T.
As far as I can see, you must pay also a lot of attention to the performance, as there are sometimes hundreds of milions of integers to be checked.
My own solution, written in Python, working very efficiently even on large ranges of integers and being successfully tested for many inputs, has failed. The results were not very descriptive, saying it does not work as required within question (although it meets all the requirements in my opinion).
/////////////////////////////////////
solutions with bitwise operators:
no of bits per int = 32 on 32 bit system,check for pattern (for K=2,
like 1001, 1000) in each shift and increment the count, repeat this
for all numbers in range.
///////////////////////////////////////////////////////
int KsparseNumbers(int a, int b, int s) {
int nbits = sizeof(int)*8;
int slen = 0;
int lslen = pow(2, s);
int scount = 0;
int i = 0;
for (; i < s; ++i) {
slen += pow(2, i);
}
printf("\n slen = %d\n", slen);
for(; a <= b; ++a) {
int num = a;
for(i = 0 ; i < nbits-2; ++i) {
if ( (num & slen) == 0 && (num & lslen) ) {
scount++;
printf("\n Scount = %d\n", scount);
break;
}
num >>=1;
}
}
return scount;
}
int main() {
printf("\n No of 2-sparse numbers between 5 and 15 = %d\n", KsparseNumbers(5, 15, 2));
}

Resources