How can I covert an integer to base 3 [duplicate] - java

This question already has answers here:
Convert from one base to another in Java
(10 answers)
Closed 4 years ago.
I found a challenge online, and thought its pretty interesting but tried multiple times to understand what base 3 is and how u can get there, but unfortunately no clue how.
Write a method, convertIntegerToBase3() which does the following:
-- Accepts an integer parameter (from 0 to 26) and converts it to base 3, which is stored
as a string, which is the return value.
public String convertIntgerToBase(int num){
if(numberConv >= 0 && numberConv <= 26){
//What do I do here?
}
else{
System.out.println("Error! Number entered wasn't in the range of 0 and 26);
}
}

Update
Because below answer at just works up to base 10 I've come up with following answer which works up to base 36:
private static final char[] CHARS = "0123456789abcdefghijklmnopqrstuvwxyz".toCharArray();
private static String convertIntToBase(int i, int base){
final StringBuilder builder = new StringBuilder();
do{
builder.append(CHARS[i % base]);
i /= base;
} while(i > 0);
return builder.reverse().toString();
}
The logic stays the same, but now by accessing the CHARS array we can get up to base 36. Because we have now the whole alphabet and the numbers to create a new number in an other base.
Using this will now yield correct numbers for e.g. base 16:
convertIntToBase(255, 16);
Will return the correct hex value:
ff
Old
It's pretty simple, by division and using the remainder of the base and can be made also generic:
public String convertIntToBase(int i, int base){
final StringBuilder builder = new StringBuilder();
do {
builder.append(i % base);
i /= base;
} while(i > 0);
return builder.reverse().toString();
}
which then can be used like the following:
convertIntToBase(24, 3);
Which yields:
220
This works, as said with division and the remainder (modulo). With the sample number 24 we can go through the steps pretty easy. The iteration and calculation (i /= base) % base can be split up into the following parts:
divide i through the base (i /= base)
split of the comma places (This is done automatically because division of integers in java are always floored)
See what remainder stays by whole-dividing the i with the base (i % base)
repeat if i is bigger than zero
So with the i = 24 and base = 3 it goes through the following steps:
24 % 3 = 0
24 / 3 = 8
8 % 3 = 2, because by whole-division we get that 3 is 8 times in 2, leaving 2
8 / 3 = 2
2 % 3 = 0
2 / 3 = 0
leaving you with the known result: 220

Base 3 is simply representing a number as a polynomial where the base of the polynomial is 3. It can extend for all basis, like base 1.2, base 99... etc.
Number in Decimal = (A0)*3^0 + (A1)*3^1 + (A2)*3^2 ...
where AX can have in value that falls with in (x)mod(3) or
(x)mod(base). In your case a range of [0,1,2]. (x)mod(Anything) is
always positive or zero.
Try to think how you could guess with your base might, be but, its essentially a problem asking you to divide a number. If you know how to divide your integer number with that polynomial, you've figured out the problem.

Related

Printing random even value between two values using inheritance

I am trying to print a list of random even numbers (5 times) using a bounds. Example being from 0 to 30 (including both those numbers). This is what I have so far (this is in its own class):
public int nextEven(int h){
int n = rand.nextEven(h) % 2;
return n;
}
This is where it would print from my main method:
System.out.println("Random Even:");
for (int i = 0; i < 5; i++){
System.out.println(rand.nextEven(30));
}
When I run the program it gives me an error and I am not quite sure how to solve this. This is an example of the desired output of even numbers from 0 to 30:
4
26
12
10
20
It isn't clear why taking the remainder of 2 would yield an even number. Instead, generate a number in the range 0 to h / 2 and then multiply the result of that by 2. Like,
public int nextEven(int h){
int n = ThreadLocalRandom.current().nextInt(1 + (h / 2)); // 0 to (h / 2) inclusive
return n * 2; // n * 2 is even (or zero).
}
What exactly is rand? Is it the Random class or an instance of your own class?
Since you want to do something with inheritance I guess you want to overwrite a method, but if rand is an instance of the java Random class this won't work.
The error probably comes from recursively calling nextEven method forever.
If you could clarify what exactly you want to do?
I see at least two solutions.
The first one supposes that random + 1 = random. I mean, that if you add or subtract a random number you still get a valid random number. That's why you can use Random class to generate a value in the desired period and then add or subtract one it the number is odd.
The second approach is just to generate an array of even values for the desired period. Then take a random value from this array.
The mod operator % will give you the remainder of the first value divided by the second.
value % 2
... will return 0 if value is even, or 1 if value is odd.
Since rand is a reference to an instance of the class containing your code, you have an infinite recursion. What you really need is something like:
public int nextEven(int h){
int evenRandomValue;
do {
evenRandomValue = (int)(Math.random() * (h + 1));
} while(evenRandomValue % 2 == 1);
return evenRandomValue;
}
Here is a quite explicit way to achieve this using streams:
List<Integer> myRandomInts = Random.ints(lower, upper + 1)
.filter(i -> i % 2 == 0)
.limit(5).boxed()
.collect(Collectors.toList());
This can be read as 'generate an infinite stream of random numbers between given bounds, filter out odds, take the first 5, turn into Integer objects and then collect into a list.

Converting base of floating point number without losing precision

Terminology
In this question I am calling "floating point number" "decimal number" to prevent ambiguation with the float/double Java primitive data types. The term "decimal" has no relationship with "base 10".
Background
I am expressing a decimal number of any base in this way:
class Decimal{
int[] digits;
int exponent;
int base;
int signum;
}
which approximately expresses this double value:
public double toDouble(){
if(signum == 0) return 0d;
double out = 0d;
for(int i = digits.length - 1, j = 0; i >= 0; i--, j++){
out += digits[i] * Math.pow(base, j + exponent);
}
return out * signum;
}
I am aware that some conversions are not possible. For example, it is not possible to convert 0.1 (base 3) to base 10, because it is a recurring decimal. Similarly, converting 0.1 (base 9) to base 3 is not possible, but covnerting 0.3 (base 3) is possible. There are probably other cases that I have not considered.
The traditional way
The traditional way (by hand) of change of base, for integers, from base 10 to base 2, is to divide the number by the exponents of 2, and from base 2 to base 10 is to multiply the digits by respective exponents of 2. Changing from base x to base y usually involves converting to base 10 as an intermediate.
First question: Argument validation
Therefore, my first question is, if I were to implement the method public Decimal Decimal.changeBase(int newBase), how can I validate whether newBase can be made without resulting in recurring decimals (which is incompatible with the design of the int[] digits field, since I don't plan to make an int recurringOffset field just for this.
Second question: Implementation
Hence, how to implement this? I instinctively feel that this question is much easier to solve if the first question is solved.
Third question: What about recurring number output:
I don't plan to make an int recurringOffset field just for this.
For the sake of future readers, this question should also be asked.
For example, according to Wolfram|Alpha:
0.1 (base 4) = 0.[2...] (base 9)
How can this be calculated (by hand, if by programming sounds too complicated)?
I think that a data structure like this can represent this decimal number:
class Decimal{
int[] constDigits;
int exponent;
int base;
int signum;
#Nullable #NonEmpty int[] appendRecurring;
}
For example, 61/55 can be expressed like this:
{
constDigits: [1, 1], // 11
exponent: -1, // 11e-1
base: 10,
signum: 1, // positive
appendRecurring: [0, 9]
}
Not a homework question
I am not looking for any libraries. Please do not answer this question with reference to any libraries. (Because I'm writing this class just for fun, OK?)
To your first question: whenever the prime factors of the old base are also among the prime factors of the new base you can always convert without becoming periodic. For example every base 2 number can be represented exactly as base 10. This condition is unfortunately sufficient but not necessary, for example there are some base 10 numbers like 0.5 that can be represented exactly as base 2, although 2 does not have the prime factor 5.
When you write the number as fraction and reduce it to lowest terms it can be represented exactly without a periodic part in base x if and only if the denominator has only prime factors that also appear in x (ignoring exponents of primes).
For example, if your number is 3/25 you can represent this exactly in every base that has a prime factor 5. That is 5, 10, 15, 20, 25, ...
If the number is 4/175, the denominator has prime factors 5 and 7 and therefore can be represented exactly in base 35, 70, 105, 140, 175, ...
For implementation, you can either work in the old base (basically doing divisions) or in the new base (basically doing multiplications). I would avoid going through a third base during the conversion.
Since you added periodic representations to your question the best way for conversion seems to be to convert the original representation to a fraction (this can always be done, also for periodic representations) and then convert this to the new representation by carrying out the division.
To answer the third part of the question, once you have your fraction reduced (and you found out that the "decimal" expansion will be a recurring fraction), you can detect the recurring part by simply doing the long-hand division and remembering the remainders you've encountered.
For example to print out 2/11 in base 6, you do this:
2/11 = 0 (rem 2/11)
2*6/11 = 1 (rem 1/11)
1*6/11 = 0 (rem 6/11)
6*6/11 = 3 (rem 3/11)
3*6/11 = 1 (rem 7/11)
7*6/11 = 3 (rem 9/11)
9*6/11 = 4 (rem 10/11)
10*6/11 = 5 (rem 5/11)
5*6/11 = 2 (rem 8/11)
8*6/11 = 4 (rem 4/11)
4*6/11 = 2 (rem 2/11) <-- We've found a duplicate remainder
(Had 2/11 been convertible to a base 6 number of finite length, we would've reached 0 remainder instead.)
So your result will be 0.[1031345242...]. You can fairly easily design a data structure to hold this, bearing in mind that there could be several digits before the recurrence begins. Your proposed data structure is good for this.
Personally I'd probably just work with fractions, floating point is all about trading in some precision and accuracy for compactness. If you don't want to compromise on precision, floating point is going to cause you a lot of trouble. (Though with careful design you can get pretty far with it.)
I waited with this after the reward because this is not directly an answer to your questions rather few hints how to approach your task instead.
Number format
Arbitrary exponential form of number during base conversion is a big problem. Instead I would convert/normalize your number to form:
(sign) mantissa.repetition * base^exp
Where unsigned int exp is the exponent of least significant digit of mantissa. The mantissa,repetition could be strings for easy manipulation and printing. But that would limit your max base of coarse. For example if you reserve e for exponent then you can use { 0,1,2,..9, A,B,C,...,Z } for digits so max base would be then only 36 (if not counting special characters). If that is not enough stay with your int digit representation.
Base conversion (mantissa)
I would handle mantissa as integer number for now. So the conversion is done simply by dividing mantissa / new_base in the old_base arithmetics. This can be done on strings directly. With this there is no problem as we can always convert any integer number from any base to any other base without any inconsistencies,rounding or remainders. The conversion could look like:
// convert a=1024 [dec] -> c [bin]
AnsiString a="1024",b="2",c="",r="";
while (a!="0") { a=divide(r,a,b,10); c=r+c; }
// output c = "10000000000"
Where:
a is number in old base which you want to convert
b is new base in old base representation
c is number in new base
Used divide function looks like this:
//---------------------------------------------------------------------------
#define dig2chr(x) ((x<10)?char(x+'0'):char(x+'A'-10))
#define chr2dig(x) ((x>'9')?BYTE(x-'A'+10):BYTE(x-'0'))
//---------------------------------------------------------------------------
int compare( const AnsiString &a,const AnsiString &b); // compare a,b return { -1,0,+1 } -> { < , == , > }
AnsiString divide(AnsiString &r,const AnsiString &a, AnsiString &b,int base); // return a/b computed in base and r = a%b
//---------------------------------------------------------------------------
int compare(const AnsiString &a,const AnsiString &b)
{
if (a.Length()>b.Length()) return +1;
if (a.Length()<b.Length()) return -1;
for (int i=1;i<=a.Length();i++)
{
if (a[i]>b[i]) return +1;
if (a[i]<b[i]) return -1;
}
return 0;
}
//---------------------------------------------------------------------------
AnsiString divide(AnsiString &r,const AnsiString &a,AnsiString &b,int base)
{
int i,j,na,nb,e,sh,aa,bb,cy;
AnsiString d=""; r="";
// trivial cases
e=compare(a,b);
if (e< 0) { r=a; return "0"; }
if (e==0) { r="0"; return "1"; }
// shift b
for (sh=0;compare(a,b)>=0;sh++) b=b+"0";
if (compare(a,b)<0) { sh--; b=b.SetLength(b.Length()-1); }
// divide
for (r=a;sh>=0;sh--)
{
for (j=0;compare(r,b)>=0;j++)
{
// r-=b
na=r.Length();
nb=b.Length();
for (i=0,cy=0;i<nb;i++)
{
aa=chr2dig(r[na-i]);
bb=chr2dig(b[nb-i]);
aa-=bb+cy; cy=0;
while (aa<0) { aa+=base; cy++; }
r[na-i]=dig2chr(aa);
}
if (cy)
{
aa=chr2dig(r[na-i]);
aa-=cy;
r[na-i]=dig2chr(aa);
}
// leading zeros removal
while ((r.Length()>b.Length())&&(r[1]=='0')) r=r.SubString(2,r.Length()-1);
}
d+=dig2chr(j);
if (sh) b=b.SubString(1,b.Length()-1);
while ((r.Length()>b.Length())&&(r[1]=='0')) r=r.SubString(2,r.Length()-1);
}
return d;
}
//---------------------------------------------------------------------------
It is written in C++ and VCL. AnsiString is VCL string type with self allocating properties and its members are indexed from 1.
Base conversion (repetition)
There are 2 approaches for this I know of. The simpler but with possible round errors is setting the repetition to long enough string sequence and handle as fractional number. For example rep="123" [dec] then conversion to different base would be done by multiplying by new base in old base arithmetics. So let create long enough sequence:
0 + 0.123123123123123 * 2
0 + 0.246246246246246 * 2
0 + 0.492492492492492 * 2
0 + 0.984984984984984 * 2
1 + 0.969969969969968 * 2
1 + 0.939939939939936 * 2
1 + 0.879879879879872 * 2 ...
------------------------------
= "0.0000111..." [bin]
With this step you need to make repetition analysis and normalize the number again after exponent correction step (in next bullet).
Second approach need to have the repetitions stored as division so you need it in form a/b in old_base. You just convert a,b as integers (the same as mantissa) and then do the division to obtain fractional part + repetition part.
So now you should have converted number in form:
mantissa.fractional [new_base] * old_base^exp
or:
mantissa.fractional+a/b [new_base] * old_base^exp
Base conversion (exponent)
You need to change old_base^old_exp to new_base^new_exp. The simplest way is to multiply the number by the old_base^old_exp value in new base arithmetics. So for starters multiply the whole
mantissa.fractional+(a/b) [new_base]
by old_base old_exp times in the new arithmetics (later you can change it to power by squaring or better). And after that normalize your number. So find where the repetition string begins and its digit position relative to . is the new_exp value.
[Notes]
For this you will need routines to convert old_base and new_base between each other but as the base is not bignum but just simple small unsigned int instead it should not be any problem for you (I hope).

How to Develop a Hash function for traffic license numbers?

Develop a hash function to generate an index value between 0-4999 inclusive for a given traffic license number. Your hash function should generate as few as possible collisions. Hash function should use the properties of license numbers. Hash method should take the license number as a single String and return an index value. We assume that the license numbers to be in the following format: City code is a number between 10 and 99 inclusive. Three letters are any letter combination from English alphabet with 26 chars. Two digits number is a number between 10 and 99 inclusive.
I wrote something about this question but, collisions are a lot (1800 for 5k)
static long printValue(String s) {
long result = 0;
for (int i = 0; i < s.length(); i++) {
result += Math.pow(27, MAX_LENGTH - i - 1) * (1 + s.charAt(i) - 'A');
}
result = result % 5009;
return (int) result;
}
public int hashF(String str) {
String a = str.substring(0, 2);
String b = str.substring(5, 7);
String middle = str.substring(2, 5);
int q = (int) printValue(middle);
String last = a + q + b;
int index = Integer.parseInt(last);
index = index % 5009;
return index;
}
Link for orjinal file of licence numbers.
These are some examples from file of traffic licence number. Collisions must be 300 (maximum).
65HNM25
93DTV23
94WPX23
31RKK46
15YXX90
31MDV74
45BOG99
65JRM50
77VXR55
39TKY41
80MJU73
63QYE57
38FCO80
45ORI16
17CHN73
70SXR63
87CVM74
27EEE85
32PFJ91
50PBA66
70TVK72
15YLS20
80MPM74
21ZRN20
36VVE84
58IDW24
77VDC89
19BVK93
28SUF63
Your problem is not your code, but mathematics. Even a (perfect for you, but not very useful) hash code that produces consecutive hashes that are then mod 5000, ie
10AAA10 -> 0
10AAA11 -> 1
... etc
99ZZZ99 -> 600 (90 * 26 * 26 * 26 * 90) % 5000
will statistically produce over 1800 collisions and is no better than the simplest implementation, which is to use String's hashCode:
int hash = Math.abs(number.hashCode() % 5000);
It's a silly exercise, as it has no real world use.
Your split of the license plate into 3 parts is fine. But converting the middle to a number, hashing it, then adding the two outside strings, converting that all to an integer, and then finally executing a modulo on that is ... awkward.
I would start off with converting the prefix (10-99) to an integer, and then subtracting 10 to get the range 0-89.
Then, for each letter, I'd multiply the result by 26, and add the index of the letter (0-25).
Third, I'd multiply the whole result by 90 (the range of the final part), convert the final 2 characters to an integer, subtract 10 to convert the 10-99 range to 0-89, and add to the result from earlier.
Finally, mod the result with 5000 to get to required 0-4999 range.
Pseudo code:
result = toInt(prefix) - 10
foreach letter in middle:
result = result * 26 + ( letter - 'A' )
result = result * 90 + ( toInt(suffix) - 10)
result = result % 5000

Sorting by least significant digit

I am trying to write a program that accepts an array of five four digit numbers and sorts the array based off the least significant digit. For example if the numbers were 1234, 5432, 4567, and 8978, the array would be sorted first by the last digit so the nest sort would be 5432, 1224, 4597, 8978. Then after it would be 1224, 5432, 8978, 4597. And so on until it is fully sorted.
I have wrote the code for displaying the array and part of it for sorting. I am not sure how to write the equations I need to compare each digit. This is my code for sorting by each digit so far:
public static void sortByDigit(int[] array, int size)
{
for(int i = 0; i < size; i++)
{
for(int j = 0; j < size; j++)
{
}
for(i = 0; i < size; i++)
{
System.out.println(array[i]);
}
}
}
I am not sure what to put in the nested for loop. I think I need to use the modulus.
I just wrote this to separate the digits but I don't know how to swap the numbers or compare them.
int first = array[i]%10;
int second = (array[i]%100)/10;
int third = (array[i]%1000)/10;
int fourth = (array[i]%10000)/10;
Would this would go in the for loop?
It seems like your problem is mainly just getting the value of a digit at a certain index. Once you can do that, you should be able to formulate a solution.
Your hunch that you need modulus is absolutely correct. The modulo operator (%) returns the remainder on a given division operation. This means that saying 10 % 2 would equal 0, as there is no remainder. 10 % 3, however, would yield 1, as the remainder is one.
Given that quick background on modulus, we just need to figure out how to make a method that can grab a digit. Let's start with a general signature:
public int getValueAtIdx(int value, int idx){
}
So, if we call getValueAtIdx(145, 2), it should return 1 (assuming that the index starts at the least significant digit). If we call getValueAtIdx(562354, 3), it should return 2. You get the idea.
Alright, so let's start by using figuring out how to do this on a simple case. Let's say we call getValueAtIdx(27, 0). Using modulus, we should be able to grab that 7. Our equation is 27 % x = 7, and we just need to determine x. So 27 divided by what will give us a remainder of 7? 10, of course! That makes our equation 27 % 10 = 7.
Now that's all find and dandy, but how does 10 relate to 0? Well, let's try and grab the value at index 1 this time (2), and see if we can't figure it out. With what we did last time, we should have something like 27 % x = 27 (WARNING: There is a rabbit-hole here where you could think x should be 5, but upon further examination it can be found that only works in this case). What if we take the 10 we used earlier, but square it (index+1)? That would give us 27 % 100 = 27. Then all we have to do is divide by 10 and we're good.
So what would that look like in the function we are making?
public int getValueAtIdx(int value, int idx){
int modDivisor = (int) Math.pow(10, (idx+1));
int remainder = value % modDivisor;
int digit = remainder / (modDivisor / 10);
return digit;
}
Ok, so let's to back to the more complicated example: getValueAtIdx(562354, 3).
In the first step, modDivisor becomes 10^4, which equals 10000.
In the second step, remainder is set to 562354 % 10000, which equals 2354.
In the third and final step, digit is set to remainder / (10000 / 10). Breaking that down, we get remainder / 1000, which (using integer division) is equal to 2.
Our final step is return the digit we have acquired.
EDIT: As for the sort logic itself, you may want to look here for a good idea.
The general process is to compare the two digits, and if they are equal move on to their next digit. If they are not equal, put them in the bucket and move on.

check number present in a sequences

I am writing a program which I found on a coding competition website, I have sort of figured out how to solve the problem but, I am stuck on a math part of it, I am completely diluting the problem and showing what I need.
first I need to check if a number is part of a sequence, my sequence is 2*a+1 where a is the previous element in the sequence or 2^n-1 to get nth item in the sequence. so it is 1,3,7,15,31,63...
I don't really want to create the whole sequence and check if a number is present, but I am not sure what a quicker method to do this would be.
Second if I am given a number lets say 25, I want to figure out the next highest number in my sequence to this number. So for 25 it would be 31 and for 47 it would be 63, for 8 it would be 13.
How can i do these things without creating the whole sequence.
I have seen similar questions here with different sequences but I am still not sure how to solve this
Start by finding the explicit formula for any term in your sequence. I'm too lazy to write out a proof, so just add 1 to each term in your sequence:
1 + 1 = 2
3 + 1 = 4
7 + 1 = 8
15 + 1 = 16
31 + 1 = 32
63 + 1 = 64
...
You can clearly see that a_n = 2^n - 1.
To check if a particular number is in your sequence, assume that it is:
x = 2^n - 1
x + 1 = 2^n
From Wikipedia:
The binary representation of integers makes it possible to apply a
very fast test to determine whether a given positive integer x is a
power of two:
positive x is a power of two ⇔ (x & (x − 1)) equals to zero.
So to check, just do:
bool in_sequence(int n) {
return ((n + 1) & n) == 0;
}
As #Blender already pointed out your sequence is essentially 2^n - 1, you can use this trick if you use integer format to store it:
boolean inSequence(int value) {
for (int i = 0x7FFF; i != 0; i >>>= 1) {
if (value == i) {
return true;
}
}
return false;
}
Note that for every elements in your sequence, its binary representation will be lots of 0s and then lots of 1s.
For example, 7 in binary is 0000000000000000000000000000111 and 63 in binary is 0000000000000000000000000111111.
This solution starts from 01111111111111111111111111111111 and use an unsigned bitshift, then compare if it is equal to your value.
Nice and simple.
How to find the next higher number :
For example, we get 19 ( 10011 ) , should return 31 (11111)
int findNext(int n){
if(n == 0) return 1;
int ret = 2; // start from 10
while( (n>>1) > 0){ // end with 100000
ret<<1;
}
return ret-1;
}

Categories