Converting a number to a user chosen base - java

I want to make a thing that takes in a number, and a base system, such that it will convert the number to that number in a different base from base 2 to base 16.
E.g. stdin would be 67 and 2, meaning the user wants the program to change the number 67 into binary form. stdout would be 1000010.
So I made the following code to get it going at first. This program takes in a number and converts it to binary format.
public class ChangeofBase {
public static void main(String[] args) {
// read in the command-line argument
int n = Integer.parseInt(args[0]);
// set v to the largest power of two that is <= n
int v = 1;
while (v <= n/2) {
v *= 2;
}
// check for presence of powers of 2 in n, from largest to smallest
while (v > 0) {
// v is not present in n
if (n < v) {
System.out.print(0);
}
// v is present in n, so remove v from n
else {
System.out.print(1);
n -= v;
}
// next smallest power of 2
v /= 2;
}
System.out.println();
}
}
How can I modify the above code to perform the following function?
Take in a number n and a base k so that n will be converted to a number in base k
Once again, k has to be between 2 and 16. Base 2 and base 16. Binary and hexadecimal. Thank you!
Edit: I would like to do this without using built-in functions. Hardcoding
Edit 2: I am new to Java. So I would like to stick to the basic stuff such as defining variables, while loops and foor loops, if-else, and printing. and parsing command line args. I believe thats all we need for this program, though correct me if i'm wrong

You can use Integer.toString(int i, int radix).

Apart from the Java built in function, You can use simple division and modulus operations in Java to achieve that.
public class IntBaseConverter {
public static void main(String[] args) {
convert(Integer.parseInt(args[0]), Integer.parseInt(args[1]));
}
public static void convert(int decimalValue, int base) {
String result = "";
while (decimalValue >= base) {
result = decimalValue % base + result;
decimalValue /= base;
}
result = decimalValue + result;
System.out.println(result);
}
}

Related

Extracting a digit from a number ranging from 0 to 99999

I am working at a programm right now where I need to sort an array of numbers ranging from 0 to 99999. In order to do so, one part of the task is to extract the digits from every number of the array, and that can be accomplished by
i = number / digit.
For example, for the number 23456, I am supposed to start by extracting the number 2, which can be done by using
digit = 10000
and calculating
i = 23456 / 10000 = 2.
A recursive call is then supposed to look at the next digit, so in this case we want to get
i = 23456 / digit = 3
and so on. I know that there are certain methods for this, but how can this be done with using only primitves? I already tried to play around with modulo and dividing the digit, but it's not giving any desired result.
Basic Formula
The n-th digit of a non-negative, integral, decimal number can be extracted by the following formula:
digit = ((num % 10^n) / 10^(n-1))
where % represents modulo division, / represents integer division, and ^ represents exponentiation in this example. Note that for this formula, the number is indexed LSD->MSD starting from 1 (not 0).
This formula will also work for non-decimal numbers (e.g. base 16) by changing 10 to the desired base. It will also work for negative numbers provided that absolute value of the final digit is taken. Finally, it can even function to extract the integer digits (but not fractional digits) of a floating point number simply by truncating and casting the floating-point number to an integral number before passing it to this formula.
Recursive Algorithm
So, to recursively extract all of the digits of a number of a certain length in order MSD->LSD, you can use the following Java method:
static public void extractDigits(int num, int length) {
if (length <= 0) { // base case
return;
}
else { // recursive case
int digit = (num % (int)Math.pow(10,length)) / (int)Math.pow(10,length-1);
/* do something with digit here */
extractDigits(num, length-1); // recurse
}
}
This method will never divide by zero.
Note: In order to "do something with digit here," you may need to pass in an additional parameter (e.g. if you want to add the digit to a list).
Optimization
Since your goal is to extract every digit from a number, rather than only one specific digit (as the basic formula assumes), this algorithm may be optimized to extract digits in order LSD->MSD so as to avoid the need for exponentiation at each step. (this approach original given here by #AdityaK ...please upvote them if you use it)
static public void extractDigits(int num) {
if (num == 0) { // base case
return;
}
else { // recursive case
int digit = num % 10;
/* do something with digit here */
extractDigits(num / 10); // recurse
}
}
Note: Any negative number should be converted to a positive number before passing it to this method.
Here's the code to recursively extract numbers from an integer. It will be in reverse order.
import java.util.*;
public class HelloWorld{
static void extractNumbers(int n, List<Integer> l) {
if(n==0)
return;
else {
l.add(n%10);
extractNumbers(n/10, l);
}
}
public static void main(String []args){
List<Integer> result = new ArrayList<Integer>();
extractNumbers(456789,result);
System.out.println(result);
}
}
Hope it helps.
I would do something like this:-
public static void main (String[] args) throws java.lang.Exception
{
// your code goes here
int num=23456;
int numSize=5;
rec(num,numSize);
}
public static void rec(int num, int numSize){
if(numSize==0)
return;
int divideBy=(int)Math.pow(10,(numSize-1));
int out=(int)(num/divideBy);
System.out.println(out);
rec((num-out*divideBy),(numSize-1));
return;
}
See the output from here: http://ideone.com/GR3l5d
This can be easily done by using the for loop by converting the array elements into string.
var arr = [234, 3456, 1234, 45679, 100];
var compare = function(val1, val2) {
return val1 - val2;
};
arr.sort(compare); //sort function
var extract = function(value, index) {
var j = "";
var element = value + "";
for (var i in element) {
var val = element[i];
console.log(parseInt(val)); // this prints the single digits from each array elements
j = j + " " + val;
}
alert(j);
};
arr.forEach(extract); //extract function..

Lambda and Generic Methods

I am learning Lambda and I came across something I cannot solve.
Originally my code was:
package Lambdas;
#FunctionalInterface
interface NumericFunc2 {
<T extends Number> T func(T n);
}
class Lbd_488_NumericFunc_SelfTest {
public static void main(String args[]) {
// This block lambda returns the smallest positive factor of a value.
NumericFunc2 smallestF = (n) -> {
double result = 1;
// Get absolute value of n.
n = n < 0 ? -n : n;
for (int i = 2; i <= n / i; i++)
if ((n % i) == 0) {
result = i;
break;
}
return result;
};
System.out.println("Smallest factor of 12 is " + smallestF.func(12));
System.out.println("Smallest factor of 11 is " + smallestF.func(11));
}
}
However, I keep getting errors next to my operators (<, -, /).
PS:Even if I change it to <T extends Double> I get the same errors.
Now, if I change the code by adding the parameter type, I get an error saying that the "Target Method is Generic":
Even if I change it to <T extends Double> I get the same errors.
package Lambdas;
#FunctionalInterface
interface NumericFunc2 {
<T extends Number> T func(T n);
}
class Lbd_488_NumericFunc_SelfTest {
public static void main(String args[]) {
// This block lambda returns the smallest positive factor of a value.
NumericFunc2 smallestF = (Double n) -> {
double result = 1;
// Get absolute value of n.
n = n < 0 ? -n : n;
for (int i = 2; i <= n / i; i++)
if ((n % i) == 0) {
result = i;
break;
}
return result;
};
System.out.println("Smallest factor of 12 is " + smallestF.func(12));
System.out.println("Smallest factor of 11 is " + smallestF.func(11));
}
}
But, if I change the class from non-generic to generic, everything works fine, like this code:
package Lambdas;
#FunctionalInterface
interface NumericFunc2<T extends Number> {
T func(T n);
}
class Lbd_488_NumericFunc_SelfTest {
public static void main(String args[]) {
// This block lambda returns the smallest positive factor of a value.
NumericFunc2<Double> smallestF = (n) -> {
double result = 1;
// Get absolute value of n.
n = n < 0 ? -n : n;
for (int i = 2; i <= n / i; i++)
if ((n % i) == 0) {
result = i;
break;
}
return result;
};
System.out.println("Smallest factor of 12 is " + smallestF.func(12));
System.out.println("Smallest factor of 11 is " + smallestF.func(11));
}
}
So, my question is. What I am doing work on my first part of the code? How can I use lambdas with generic methods, inside non-generic classes properly?
The answer is that you cannot do this sort of numeric operation on a Number object. There is no way; this has nothing to do with lambdas and everything to do with the Number abstract class just not providing those features.
There is not even any way to get the absolute value of a Number without knowing what kind of Number it is. You can't see whether it's positive or negative, you can't negate it, you can't add, subtract, or multiply it. The only thing you can do with a Number is convert it into another primitive type, but you can't convert it back and you can't do math with it.
According to the JLS, generics and lambdas won't work together. This eclipse bug report discusses it with some code examples.
In order to make it work, you have to fall back to anonymous inner classes. I.e. you have to write the full new NumberFunc() {...} mambo-jambo around your function.
I had to make some other changes in the body of the method to make it compile:
result is the boxed Double so I can cast it to T
inside of the method I'm using the doubleValue() of n because primitive operators won't work on T extends Number.
Putting it together:
class Lbd_488_NumericFunc_SelfTest {
public static void main(String args[]) {
// This block lambda returns the smallest positive factor of a value.
NumericFunc2 smallestF = new NumericFunc2() {
public <T extends Number> T func(T n) {
Double result = 1d;
// Get absolute value of n.
double nAbs = n.doubleValue() < 0 ? -n.doubleValue() : n.doubleValue();
for (int i = 2; i <= nAbs / i; i++)
if ((nAbs % i) == 0) {
result = (double) i;
break;
}
return (T) result;
}
};
System.out.println("Smallest factor of 12 is " + smallestF.func(12));
System.out.println("Smallest factor of 11 is " + smallestF.func(11));
}
}

Changing numbers places in java

Can anyone please learn me how to change this number 5486 to 4568 ? I need to change two pairs of numbers places. Any ideas please?
My code :
public Number shiftRight(int n) {
int length = (getNumOfDigits()+MINUSONE);
length = (int) Math.pow(TEN, length);
for (int i=0; i<n; i++){
int m=num%TEN;
num=(m*length) + (num/TEN);
}
return new Number(num);
}
public int shiftRightDistance(Number other){
int max = getNumOfDigits();
for (int i=0;i<max;i++)
{
if(compareTo(shiftRight(i))==ZERO)
{
return i;
}
}
return MINUSONE;
}
public Number swapPairs() {
}
}
The simplest (and least confusing) thing might be to convert the number to a char array, swap pairs of characters, and then convert back to a number. You can use String.valueOf(int), String.toCharArray(), new String(char[]) and Integer.valueOf(String) to put that together.
Alternatively, you can build on the following method that swaps the digits of a non-negative number less than 100:
private int swapDigitsLessThan100(int n) {
return 10 * (n % 10) + n / 10;
}
The way to build on that would be to extract every pair of digits from the original number, working recursively. The following deals with numbers that are an even number of digits long:
public int swapDigits(int n) {
if (n == 0) {
return 0;
return 100 * swapDigits(n / 100) + swapDigitsLessThan100(n % 100);
}
With this code, if n is an odd number of digits, the result will be to use a leading 0 as an additional digit.

Is there a better (more correct) way to calculate modulus of some power than Math.pow?

Consider the following simple block of Java code:
public static void main(String[] args) {
int a = 7;
double exp;
for (int i=0; i<71; ++i) {
exp = Math.pow(a,i) % 71;
if (exp == 59.0)
System.out.printf("k=%d: %.0f%n", i, exp);
}
}
I am trying to iterate through all of the exponents k such that a^x=59 mod 71... however there should be only a single one, and I'm getting three: k=3, k=23, k=63. This is clearly wrong, as upon verification, only k=3 is the correct answer. Is there some inherent problem in the way floating point works (and thus Math.pow), or is there some other logic problem in my code? Should I be using some other method to calculate a^x (mod n)?
The simplest correct expedient that doesn't require writing your own method is probably
BigInteger.valueOf(a)
.modPow(BigInteger.valueOf(i), BigInteger.valueOf(71))
.intValue();
If you want to avoid "big calculations", then you can perform the modulo after every multiplication:
public static void main(String[] args)
{
for (int i=0,a=1; i<71; i++, a = (a*7)%71)
{
if (a == 59)
System.out.println("k = " + i);
}
}

Memoization with recursive method in java

I am working on a homework assignment, and I have completely exhausted myself. I'm new to programming, and this is my first programming class.
this is the problem:
Consider the following recursive function in Collatz.java, which is related to a famous unsolved problem in number theory, known as the Collatz problem or the 3n + 1 problem.
public static void collatz(int n) {
StdOut.print(n + " ");
if (n == 1) return;
if (n % 2 == 0) collatz(n / 2);
else collatz(3*n + 1);}
For example, a call to collatz(7) prints the sequence
7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
as a consequence of 17 recursive calls. Write a program that takes a command-line argument N and returns the value of n < N for which the number of recursive calls for collatz(n) is maximized. Hint: use memoization. The unsolved problem is that no one knows whether the function terminates for all positive values of n (mathematical induction is no help because one of the recursive calls is for a larger value of the argument).
I have tried several things: using a for loop, trying to count the number of executions with a variable incremented each time the method executed, and hours of drudgery.
Apparently, I'm supposed to use an array somehow with the memoization. However, I don't understand how I could use an array when an array's length must be specified upon initiation.
Am I doing something completely wrong? Am I misreading the question?
Here is my code so far. It reflects an attempt at trying to create an integer array:
public class Collatz2 {
public static int collatz2(int n)
{
StdOut.print(n + " ");
if (n==1) {return 1;}
else if (n==2) {return 1;}
else if (n%2==0) {return collatz2(n/2);}
else {return collatz2(3*n+1);}
}
public static void main(String[] args)
{
int N = Integer.parseInt(args[0]);
StdOut.println(collatz2(N));
}
}
EDIT:
I wrote a separate program
public class Count {
public static void main(String[] args) {
int count = 0;
while (!StdIn.isEmpty()) {
int value = StdIn.readInt();
count++;
}
StdOut.println("count is " + count);
}
}
I then used piping: %java Collatz2 6 | java Count
and it worked just fine.
Since you are interested in the maximum sequence size and not necessarily the sequence itself, it is better to have collatz return the size of the sequence.
private static final Map<Integer,Integer> previousResults = new HashMap<>();
private static int collatz(int n) {
int result = 1;
if(previousResults.containsKey(n)) {
return previousResults.get(n);
} else {
if(n==1) result = 1;
else if(n%2==0) result += collatz(n/2);
else result += collatz(3*n + 1);
previousResults.put(n, result);
return result;
}
}
The memoization is implemented by storing sequence sizes for previous values of n in Map previousResults.
You can look for the maximum in the main function:
public static void main(String[] args) {
int N = Integer.parseInt(args[0]);
int maxn=0, maxSize=0;
for(int n=N; n>0; n--) {
int size = collatz(n);
if(size>maxSize) {
maxn = n;
maxSize = size;
}
}
System.out.println(maxn + " - " + maxSize);
}
The trick here is to write a recursive method where an argument is the value you want to "memoize". For instance, here is a version of a method which will return the number of steps needed to reach 1 (it supposes that n is greater than or equal to 1, of course):
public int countSteps(final int n)
{
return doCollatz(0, n);
}
public static int doCollatz(final int nrSteps, final int n)
{
if (n == 1)
return nrSteps;
final int next = n % 2 == 0 ? n / 2 : 3 * n + 1;
return doCollatz(nrSteps + 1, next);
}
If you were to record the different steps instead, you'd pass a List<Integer> as an argument and .add() to it as you went through, etc etc.

Categories

Resources