Probability of multiple dice rolls with recursion - java

How would I go about using recursion to calculate the probability of rolling a certain number, r, with a given number of dice? I tried to treat this as a choose problem but am still quite confused as to how the algorithm should work.
For example, it should work out to be something like this:
P(4,14)=(1/6)P(3,13)+(1/6)P(3,12)+(1/6)P(3,11)+(1/6)P(3,10)+(1/6)P(3,9)+(1/6)P(3,8)
P(3,8)=(1/6)P(2,7)+(1/6)P(2,6)+(1/6)P(2,5)+(1/6)P(2,4)+(1/6)P(2,3)+(1/6)P(2,2)
P(2,4)=(1/6)P(1,3)+(1/6)P(1,2)+(1/6)P(1,1)+(1/6)P(1,0)+(1/6)P(1,-1)+(1/6)P(1,-2)
=(1/6)(1/6)+(1/6)(1/6)+(1/6)(1/6)+(1/6)(0)+(1/6)(0)+(1/6)(0)
I'm just having trouble converting it into code.
static double P(int dice, int r) {
int ret = 1;
for (int i = 2; i < 7; i++) {
ret = (1/6)(ret*(dice-i))/(i+1);
}
return ret;
}
static double RollDice(int dice,int r) {
if (dice==1 && (r<1 || r>6)){
return 0;
}
if (dice==1 && (r>=1 && r<=6)){
return (1.0/6);
}
else {
return ((1.0/6)*P(dice-1,r-1));
}

I do not understand why you have to separate methods P() and RollDice(), since in your formulae you (correctly) describe everything with P.
If you were to put your formulae into code, it should look something like this:
EDIT: changed the base case to 0 dice, since then it becomes even simpler.
static double P(int dice, int r) {
if (dice == 0) {
// Zero dice: probabiliy 1 to get 0
if (r == 0) {
return 1.0;
} else {
return 0.0;
}
else {
// Multiple dice: recursion
double sum = 0.0;
for (/* TODO */) {
sum += //TODO
}
}
}
For the recursion part, try working it out by looking at the formula:
P(4, 14) = (1/6)P(3, 13) + (1/6)P(3, 12) + ... + (1/6)P(3, 8)
i.e. in the general case
P(dice, r)=(1/6)P(dice-1, r-1) + (1/6)P(dice-1, r-2) + ... + (1/6)P(dice-1, r-6)
meaning that you have to loop from r-6 to r-1.
And since you are taking a sum over multiple recursive calls, you have to use an accumulator initialized to 0. (The variable I called sum)
EDIT: Click here for a complete example, compare to WolframAlpha to verify the result.

Related

Digit amount in an integer [duplicate]

This question already has answers here:
Way to get number of digits in an int?
(29 answers)
Closed 24 days ago.
How can I find the amount of digits in an integer? Mathematically, and by using functions if there are any.
I don't really know how to do that, since I'm a somewhat beginner.
Another option would be to do it iteratively by dividing number by 10, until result is 0.
int number = ...;
int count = 1;
while ((number /= 10) != 0) {
count++;
}
In this program we use a for loop without any body.
On each iteration, the value of num is divided by 10 and count is incremented by 1.
The for loop exits when num != 0 is false, i.e. num = 0.
Since, for loop doesn't have a body, you can change it to a single statement in Java as such:
for(; num != 0; num/=10, ++count);
public class Main {
public static void main(String[] args) {
int count = 0, num = 123456;
for (; num != 0; num /= 10, ++count) {
}
System.out.println("Number of digits: " + count);
}
}
There are many ways to calculate the number of digits in a number. The main difference between them is how important performance is to you. The first way is to translate a number into a string and then take its length:
public static int countDigitsFoo(int x) {
if (x == Integer.MIN_VALUE) {
throw new RuntimeException("Cannot invert Integer.MIN_VALUE");
}
if (x < 0) {
return countDigitsFoo(-x); // + 1; if you want count '-'
}
return Integer.toString(x).length();
}
This method is bad for everyone, except that it is easy to write. Here there is an extra allocation of memory, namely the translation of a number into a string. That with private calls to this function will hit performance very hard.
The second way. You can use integer division and sort of go by the number from right to left:
public static int countDigitsBoo(int x) {
if (x == Integer.MIN_VALUE) {
throw new RuntimeException("Cannot invert Integer.MIN_VALUE");
}
if (x < 0) {
return countDigitsBoo(-x); // + 1; if you want count '-'
}
int count = 0;
while (x > 0) {
count++;
x /= 10;
}
return count;
}
but even this method can be improved. I will not write it in full, but I will give part of the code.
P.S. never use this method, it is rather another way to solve this problem, but no more
public static int countDigitsHoo(int x) {
if (x == Integer.MIN_VALUE) {
throw new RuntimeException("Cannot invert Integer.MIN_VALUE");
}
if (x < 0) {
return countDigitsHoo(-x); // + 1; if you want count '-'
}
if (x < 10) {
return 1;
}
if (x < 100) {
return 2;
}
if (x < 1000) {
return 3;
}
// ...
return 10;
}
You also need to decide what is the number of digits in the number. Should I count the minus sign along with this? Also, in addition, you need to add a condition on Integer.MIN_VALUE because
Integer.MIN_VALUE == -Integer.MIN_VALUE
This is due to the fact that taking a unary minus occurs by -x = ~x + 1 at the hardware level, which leads to "looping" on -Integer.MIN_VALUE
In Java, I would convert the integer to a string using the .toString() function and then use the string to determine the number of digits.
Integer digit = 10000;
Integer digitLength = abs(digit).toString().length();

Program to sum the odd digits recursively

Using recursion, If n is 123, the code should return 4 (i.e. 1+3). But instead it is returning the last digit, in this case 3.
public static int sumOfOddDigits(NaturalNumber n) {
int ans = 0;
if (!n.isZero()) {
int r = n.divideBy10();
sumOfOddDigits(n);
if (r % 2 != 0) {
ans = ans + r;
}
n.multiplyBy10(r);
}
return ans;
}
It isn't clear what NaturalNumber is or why you would prefer it to int, but your algorithm is easy enough to follow with int (and off). First, you want the remainder (or modulus) of division by 10. That is the far right digit. Determine if it is odd. If it is add it to the answer, and then when you recurse divide by 10 and make sure to add the result to the answer. Like,
public static int sumOfOddDigits(int n) {
int ans = 0;
if (n != 0) {
int r = n % 10;
if (r % 2 != 0) {
ans += r;
}
ans += sumOfOddDigits(n / 10);
}
return ans;
}
One problem is that you’re calling multiplyBy on n and not doing anything with the result. NaturalNumber seems likely to be immutable, so the method call has no effect.
But using recursion lets you write declarative code, this kind of imperative logic isn’t needed. instead of mutating local variables you can use the argument list to hold the values to be used in the next iteration:
public static int sumOfOddDigits(final int n) {
return sumOfOddDigits(n, 0);
}
// overload to pass in running total as an argument
public static int sumOfOddDigits(final int n, final int total) {
// base case: no digits left
if (n == 0)
return total;
// n is even: check other digits of n
if (n % 2 == 0)
return sumOfOddDigits(n / 10, total);
// n is odd: add last digit to total,
// then check other digits of n
return sumOfOddDigits(n / 10, n % 10 + total);
}

Why does my recursion fall through?

My recursive function is falling through in my program. I am making a method that constructs a relatively simple object array and populates them with certain values. i.e. object 1 has these values 3,2,5,6,7, object 2 has these values; 4,5,6,4,5. and so on
the recursion comes in when I have different parts of the method that do different things to the function. as shown below:
objectConstructor(Object foo, int switcherVar){
if(switcherVar == 1){
//terminating condition leave method
return 1;
} else {
if(switcherVar == 2){
//do something
objectConstructor(object foo, 1)
}
}
return 0;
}
When I check my return value i get a 0. The stuff that I'm actually doing in the method is unrelated to my recursive function and the function IS re cursing just at the end it falls through when its supposed to jump to the terminating condition. From my understanding the problem is the way I'm formatting my recursive function.
Below is the actual code It's an airplane seat constructor that give values to an airplanes seats, like if it is occupied and whatnot. the above is easier to read but if my syntax is off that might be the problem as well.
private int airplaneSeatConstructor(Airplane airplane, String className, int numberOfSeats){
/*Airplane Seat Creator, loops through the seats and attaches credentials to them based on the type of plane
* being formed.*/
//currently only one plane type. 777.
//777 seat number 257
//does have a first class section.
System.out.println("iteration");
if(className.equals("TERM")){
return 1;
}else {
if (className.equals("FIRST")) {
for (int x = 0; x < numberOfSeats; x++) {
airplane.getSeats()[x].setOccupied(false);
airplane.getSeats()[x].setFirstClass(true);
airplane.getSeats()[x].setBusinessClass(false);
if ((x % 4) == 0 || (x % 4) == 3) {
airplane.getSeats()[x].setWindowseat(true);
airplane.getSeats()[x].setAisleSeat(false);
} else {
airplane.getSeats()[x].setAisleSeat(true);
airplane.getSeats()[x].setWindowseat(false);
}
}
System.out.println("in first");
airplaneSeatConstructor(airplane, "BUSINESS", 40);
}
if (className.equals("BUSINESS")) {
for (int x = 0; x < numberOfSeats; x++) {
airplane.getSeats()[airplane.getNumberOfSeatsPerClass()[0] + x].setBusinessClass(true);
airplane.getSeats()[airplane.getNumberOfSeatsPerClass()[0] + x].setFirstClass(false);
airplane.getSeats()[airplane.getNumberOfSeatsPerClass()[0] + x].setOccupied(false);
}
System.out.println("in business");
airplaneSeatConstructor(airplane, "ECONOMY", 209);
}
if (className.equals("ECONOMY")) {
for (int x = 0; x < numberOfSeats; x++) {
airplane.getSeats()[airplane.getNumberOfSeatsPerClass()[0] + airplane.getNumberOfSeatsPerClass()[1] + x].setBusinessClass(false);
airplane.getSeats()[airplane.getNumberOfSeatsPerClass()[0] + airplane.getNumberOfSeatsPerClass()[1] + x].setFirstClass(false);
airplane.getSeats()[airplane.getNumberOfSeatsPerClass()[0] + airplane.getNumberOfSeatsPerClass()[1] + x].setOccupied(false);
}
System.out.println("in economy");
airplaneSeatConstructor(airplane, "SPECIAL", 26);
}
if (className.equals("SPECIAL")) {
System.out.println("in special");
airplaneSeatConstructor(airplane, "TERM", 273);
}
}
return 0;
}
my print lines all hit but I'm still getting 0 from my return value.
In your code, whatever recursion you do, in fact, whatever calculation you do is not going to count, since you're finally returning 0 for all cases but the base one (in which you return 1).
objectConstructor(Object foo, int switcherVar){
if(switcherVar == 1){
//terminating condition leave method
return 1;
} else {
if(switcherVar == 2){
//do something
objectConstructor(object foo, 1)
}
}
return 0;
}
Recursion in your program works this way: you do the first call with switcher == 2, which makes the recursive call whit switcher == 1. But then you discard that result and just return 0.
The correct or logic way of things for doing this is more similar to this:
objectConstructor(Object foo, int switcherVar){
if(switcherVar == 1){
//terminating condition leave method
return 1;
} else {
if(switcherVar == 2){
//do something
return objectConstructor(object foo, 1)
}
}
}
Hope this helps.
However, looking closely to your code, I think that you are substituting sequence by recursion. I would refactor (i.e., divide the code of) your function by classes of seats, and make the needed calls. Recursion is not needed at all in your code. See below:
private void airplaneSeatConstructorFirstClass(Airplane airplane, int numberOfSeats)
{
for (int x = 0; x < numberOfSeats; x++) {
airplane.getSeats()[x].setOccupied(false);
airplane.getSeats()[x].setFirstClass(true);
airplane.getSeats()[x].setBusinessClass(false);
if ((x % 4) == 0 || (x % 4) == 3) {
airplane.getSeats()[x].setWindowseat(true);
airplane.getSeats()[x].setAisleSeat(false);
} else {
airplane.getSeats()[x].setAisleSeat(true);
airplane.getSeats()[x].setWindowseat(false);
}
}
}
private void airplaneSeatConstructorBussinessClass(Airplane airplane, int numberOfSeats)
{
for (int x = 0; x < numberOfSeats; x++) {
airplane.getSeats()[airplane.getNumberOfSeatsPerClass()[0] + x].setBusinessClass(true);
airplane.getSeats()[airplane.getNumberOfSeatsPerClass()[0] + x].setFirstClass(false);
airplane.getSeats()[airplane.getNumberOfSeatsPerClass()[0] + x].setOccupied(false);
}
}
...and so on.
Now you just have to call:
airplaneSeatConstructorFirstClass( airplane, 80 );
airplaneSeatConstructorBussinessClass( airplane, 40 );
As you can see is far easier (unless I'm missing something big).
Let's say that this
objectConstructor(object foo, 1);
returns 1.
After that you do return 0. Of course the whole thing will return 0.
Maybe you should
return objectConstructor(object foo, 1);

All digits in int are divisible by certain int

I am trying to figure out how to count all numbers between two ints(a and b), where all of the digits are divisible with another int(k) and 0 counts as divisible.Here is what I've made so far, but it is looping forever.
for (int i = a; i<=b; i++){
while (i < 10) {
digit = i % 10;
if(digit % k == 0 || digit == 0){
count ++;
}
i = i / 10;
}
}
Also I was thinking about comparing if all of the digits were divisible by counting them and comparing with number of digits int length = (int)Math.Log10(Math.Abs(number)) + 1;
Any help would be appreciated. Thank you!
Once you get in to your while block you're never going to get out of it. The while condition is when i less than 10. You're dividing i by 10 at the end of the whole block. i will never have a chance of getting above 10.
Try this one
public class Calculator {
public static void main(String[] args) {
int a = 2;
int b = 150;
int k = 3;
int count = 0;
for (int i = a; i <= b; i++) {
boolean isDivisible = true;
int num = i;
while (num != 0) {
int digit = num % 10;
if (digit % k != 0) {
isDivisible = false;
break;
}
num /= 10;
}
if (isDivisible) {
count++;
System.out.println(i+" is one such number.");
}
}
System.out.println("Total " + count + " numbers are divisible by " + k);
}
}
Ok, so there are quite a few things going on here, so we'll take this a piece at a time.
for (int i = a; i <= b; i++){
// This line is part of the biggest problem. This will cause the
// loop to skip entirely when you start with a >= 10. I'm assuming
// this is not the case, as you are seeing an infinite loop - which
// will happen when a < 10, for reasons I'll show below.
while (i < 10) {
digit = i % 10;
if(digit % k == 0 || digit == 0){
count ++;
// A missing line here will cause you to get incorrect
// results. You don't terminate the loop, so what you are
// actually counting is every digit that is divisible by k
// in every number between a and b.
}
// This is the other part of the biggest problem. This line
// causes the infinite loop because you are modifying the
// variable you are using as the loop counter. Mutable state is
// tricky like that.
i = i / 10;
}
}
It's possible to re-write this with minimal changes, but there are some improvements you can make that will provide a more readable result. This code is untested, but does compile, and should get you most of the way there.
// Extracting this out into a function is often a good idea.
private int countOfNumbersWithAllDigitsDivisibleByN(final int modBy, final int start, final int end) {
int count = 0;
// I prefer += to ++, as each statement should do only one thing,
// it's easier to reason about
for (int i = start; i <= end; i += 1) {
// Pulling this into a separate function prevents leaking
// state, which was the bulk of the issue in the original.
// Ternary if adds 1 or 0, depending on the result of the
// method call. When the methods are named sensibly, I find
// this can be more readable than a regular if construct.
count += ifAllDigitsDivisibleByN(modBy, i) ? 1 : 0;
}
return count;
}
private boolean ifAllDigitsDivisibleByN(final int modBy, final int i) {
// For smaller numbers, this won't make much of a difference, but
// in principle, there's no real reason to check every instance of
// a particular digit.
for(Integer digit : uniqueDigitsInN(i)) {
if ( !isDigitDivisibleBy(modBy, digit) ) {
return false;
}
}
return true;
}
// The switch to Integer is to avoid Java's auto-boxing, which
// can get expensive inside of a tight loop.
private boolean isDigitDivisibleBy(final Integer modBy, final Integer digit) {
// Always include parens to group sub-expressions, forgetting the
// precedence rules between && and || is a good way to introduce
// bugs.
return digit == 0 || (digit % modBy == 0);
}
private Set<Integer> uniqueDigitsInN(final int number) {
// Sets are an easy and efficient way to cull duplicates.
Set<Integer> digitsInN = new HashSet<>();
for (int n = number; n != 0; n /= 10) {
digitsInN.add(n % 10);
}
return digitsInN;
}

TestDome: my solution works but I am only getting %50 right and not %100?

This is the scenario question:
A frog only moves forward, but it can move in steps 1 inch long or in jumps 2 inches long. A frog can cover the same distance using different combinations of steps and jumps.
Write a function that calculates the number of different combinations a frog can use to cover a given distance.
For example, a distance of 3 inches can be covered in three ways: step-step-step, step-jump, and jump-step.
public class Frog{
public static int numberOfWays(int input) {
int counter = 2;
int x = 0;
for (int i = 1 ; i< input -1; i++ ){
x = i + counter;
counter = x;
}
if (input <3){
x = input;
}
return x;
}
public static void main(String[] args) {
System.out.println(numberOfWays(10));
}
}
This solution only gives me %50 right not sure why its not %100 right, I tested it with other values and returns the right results.
I think recursion is a nice way to solve problems like that
public int numberOfCombinations(int distance) {
if (distance == 1) {
return 1; //step
} else if (distance == 2) {
return 2; // (step + step) or jump
} else {
return numberOfCombinations(distance - 1) + numberOfCombinations(distance - 2);
// we jumped or stepped into the current field
}
}
Let f[n] be the number of combinations of steps and jumps such that you travel n inches. You can immediately see that f[n] = f[n-1] + f[n-2], that is first you can travel n-1 inches in some way and then use 1 step or you can travel n-2 inches in some way and then use 1 jump. Since f[1] = 1 and f[2] = 2 you can see that f[n] = fib(n+1), the n+1-th Fibonacci number. You can calculate it in linear time if it suits the purpose or, more efficiently, you can calculate it in log n time - reference
The problem is a modified version of the Fibonacci series. I get 100% for the following (sorry it's C# but is very similar):
using System;
public class Frog
{
public static int NumberOfWays(int n)
{
int firstnumber = 0, secondnumber = 1, result = 0;
if (n == 1) return 1;
if (n == 2) return 2;
for (int i = 2; i <= n + 1; i++)
{
result = firstnumber + secondnumber;
firstnumber = secondnumber;
secondnumber = result;
}
return result;
}
public static void Main(String[] args)
{
Console.WriteLine(NumberOfWays(3));
Console.WriteLine(NumberOfWays(4));
Console.WriteLine(NumberOfWays(5));
Console.WriteLine(NumberOfWays(6));
Console.WriteLine(NumberOfWays(7));
Console.WriteLine(NumberOfWays(8));
}
}
Think overlapping subproblem / dynamic programming. You need to memorize the repetitive calls to the sub-problem which will save you all the time.
I believe this should cover your all scenarios.
public static string numberOfCombinations(int distance)
{
if (distance == 1) {
return "Step";//1
} else if (distance == 2) {
return "Jump";//2
} else{
return numberOfCombinations(1) + numberOfCombinations(distance - 1);
}
}

Categories

Resources