a to the power of b - recursive algorithm - algorithm

I am having a hard time understanding the following recursive algorithm in terms of the multiplication operation used in the code.
int power(int a, int b) {
if (b < 0) {
return 0;
} else if (b == 0) {
return 1;
} else {
return a * power(a, b - 1);
}
}
For inputs (3,7) the result would be 2187. There are total of 6 recursive calls being made:
Initial values - 3,7
First recursive call(3,6)
Second recursive call(3,5)
Third recursive call(3,4)
Fourth recursive call(3,3)
Fifth recursive call(3,2)
Sixth recursive call(3,1)
Given the following formula:
a * power(a, b - 1)
is each recursive call multiplying the values of a & b? Which wouldn't make sense, since that would return 81 at the end. I am trying to understand the factors and product in the multiplication operation of each recursive call.

You have to keep in mind that a is multiplied by the result of the recursive function call at every step. You might look at it like this:
power(3,7)
= 3 * power(3,6)
= 3 * 3 * power(3,5)
= 3 * 3 * 3 * power(3,4)
= 3 * 3 * 3 * 3 * power(3,3)
= 3 * 3 * 3 * 3 * 3 * power(3,2)
= 3 * 3 * 3 * 3 * 3 * 3 * power(3,1)
= 3 * 3 * 3 * 3 * 3 * 3 * 3 * power(3,0)
= 3 * 3 * 3 * 3 * 3 * 3 * 3 * 1 // by definition when b = 0
At each step we replace the call to power(a,b) with a * power(a,b-1), as the function defines, until we get to power(3,0). Does that help clear up what's going on?

Your function int power(int a, int b) returns an int.
So every time return a * power(a, b - 1); is called, a is multiplied by the value returned by power(a, b - 1) until you get b == 0 which returns 1.
At the end you get:
return (3 * (3 * (3 * (3 * (3 * (3 * (3 * 1)))))));
The value of b is the one that stops the recursivity and make you get a result. If b wasn't decreased, you'd be in an infinite loop.
So to answer to your question, neither a or b are multiplied, since all is in the return value. Only b is decreased to make the number of loops expected.
I hope this helped you understand.

return a * power(a, b - 1);
This line has a lot of information to convey. Actually a the the base and b is the power, which is to be raised to a. Now, each time we multiply a with the returned value, we are actually raising it to some power.
When return statement is executed for the first time, it stores product of a and a call to the power function. During the subsequent calls to power function, the value of b, reduces by 1 every time.
Hence in the end, when recursion, unfolds, you get something like this:
return a*a*a*a*a*a*a*1
Finally in the end, the result is computed and is sent back to the main method. (The calling method)

actually what is happening here, each call is made with a new value of variables, for instance the last call(3* power(3, 0)) would return 3, as (3* 1) = 3, and last call returns the '1' first, and them back tracks,, for last call b = 0, so 1 is returned which is multiplied with 3, which becomes 3
for rest of calls, this 3 would be simply being multiplied each time,,
for fifth call,
it would return value 3 * 3
for forthh it would return,
3 * 9 ,,
and so on

is each recursive call multiplying the values of a & b? Which wouldn't
make sense
This is the wrong assumption. Each recursive call multiplying the values of a & (result of exectuing the same fucntion with a & b-1).

On your last recursive call (a = 3, b = 0), you are in this case :
} else if (b == 0) {
return 1;
This means, the previous caller (a = 3, b = 1) that was on the line return a * power(a, b - 1); can be replaced with values return 3 * power(3, 1 - 1); -> return 3 * 1; // 1 being the last recursive call return value.
Taking the previous one (a = 3, b = 2) and doing the same operation
return a * power(a, b - 1);
-->
return 3 * power(3, 2 - 1);
-->
return 3 * 3 * 1; //the result of the a = 3, b = 1 call
And so on...
a = 3, b = 3
return 3 * 3 * 3 * 1;
a = 3, b = 4
return 3 * 3 * 3 * 3 * 1;
a = 3, b = 5
return 3 * 3 * 3 * 3 * 3 * 1;
a = 3, b = 6
return 3 * 3 * 3 * 3 * 3 * 3 * 1;
a = 3, b = 7
return 3 * 3 * 3 * 3 * 3 * 3 * 3 * 1;

Related

using while loop the page keep loading over and over (codewars problem)

heyy guys i m trying to solve Factorial decomposition (codewars task )
well some numbers work with me untill i reach number 23 the page keep looping over and over someone help me please
function decomp(n) {
let c =[]
let sum =1
for(let i=n;i>=1;i--){
sum*=i
}
let k= 2
while(k<=sum){
if(sum%k!==0){
k++}
while(sum%k==0){
c.push(k)
sum = sum/k
}
}
return c.join('*')
}
the function works good until i reach the number 23 the keep loading over and over , the tasks is about the function is decomp(n) and should return the decomposition of n! into its prime factors in increasing order of the primes, as a string.
factorial can be a very big number (4000! has 12674 digits, n can go from 300 to 4000).
In Fortran - as in any other language - the returned string is not permitted to contain any redundant trailing whitespace: you can use dynamically allocated character strings.
example
n = 12; decomp(12) -> "2^10 * 3^5 * 5^2 * 7 * 11"
since 12! is divisible by 2 ten times, by 3 five times, by 5 two times and by 7 and 11 only once.
n = 22; decomp(22) -> "2^19 * 3^9 * 5^4 * 7^3 * 11^2 * 13 * 17 * 19"
n = 25; decomp(25) -> 2^22 * 3^10 * 5^6 * 7^3 * 11^2 * 13 * 17 * 19 * 23
23! cannot be exactly expressed in double-precision floating-point format, which JavaScript uses for its numbers.
However, you don't need to compute n!. You just need to factorize each number and concat their factorization.
Actually, you don't even need to factorize each number. Note that given n and p, there are (n/p) numbers no greater than n that are multiples of p, (n/(p*p)) that are multiples of p*p, etc.
function *primes(n) {
// Sieve of Eratosthenes
const isPrime = Array(n + 1).fill(true);
isPrime[0] = isPrime[1] = false;
for (let i = 2; i <= n; i++) {
if (isPrime[i]) {
yield i;
for (let j = i * i; j <= n; j += i)
isPrime[j] = false;
}
}
}
function decomp(n) {
let s = n + '! =';
for (const p of primes(n)) {
let m = n, c = 0;
// There are (n/p) numbers no greater than n that are multiples of p
// There are (n/(p*p)) numbers no greater than n that are multiples of p*p
// ...
while (m = ((m / p) | 0)) {
c += m;
}
s += (p == 2 ? ' ' : ' * ') + p + (c == 1 ? '' : '^' + c);
}
return s;
}
console.log(decomp(12))
console.log(decomp(22))
console.log(decomp(23))
console.log(decomp(24))
console.log(decomp(25))

How can I improve my Countdown Numbers Solver algorithm to find more solutions?

As my school Project, I need to build a solver for Countdown Numbers & Letters rounds. I wanted to develop a structure which I can use to build both solvers, and I first developed a Numbers solver. However, before using this solution for Letters, I need to improve my current algorithm. I think I'm wrong somewhere, because I don't get the same results with other tools I am using to compare my program. Here is program for my solver;
/// numbers_game_solver.dart
import 'dart:collection';
import 'package:trotter/trotter.dart';
/* Import statements was package-based, I turned them into relative paths for question. */
import 'number_generator.dart';
import 'operation.dart';
import 'solution.dart';
import 'solutions.dart';
/* Will try to combine numbers with operations, as shown below;
* List<List<Operation>> operations = <Operations>[a, ,b, ,c, ,d, ,e, ,f
* + - + * / ]
* Then if last operations result is equal to target, will result it.
* If not will show closest result.
*/
const List<String> kOperators = const <String>[kOpAdd, kOpDiv, kOpMul, kOpSub];
class NumbersGameSolver {
NumbersGameSolver()
: this.solutions = Solutions(_expectedResult);
/* TODO: Do tests with smaller numbers and targets. */
final List<int> _numbers = const <int>[1, 2, 3, 4]; // NumberGenerator.numbers;
static final int _expectedResult = 15; //NumberGenerator.expectedResult;
final Solutions solutions;
void solve() {
/* All permutations of operators with replacement, which will be inserted between numbers. */
final Set<List<String>> amalgamsOperators = Amalgams<String>(_numbers.length - 1, kOperators)().toSet();
/* There may duplicates occur in numbers list, because of this, numbers will be mapped
using permutations of indices. */
final List<int> indices = List<int>.generate(_numbers.length, (int index) => index);
final Iterable<List<int>> permutationsIndices = Permutations<int>(indices.length, indices)();
final Set<List<int>>
permutationsNumbers = permutationsIndices.map(
(List<int> listPerm) => listPerm.map(
(int index) => _numbers[index]
).toList()
).toSet();
for (final List<int> numbers in permutationsNumbers) {
for (final List<String> operators in amalgamsOperators) {
Queue<int> stackNums = Queue<int>.from(numbers);
Queue<String> stackOprts = Queue<String>.from(operators);
Solution tempSolution = Solution(_expectedResult);
do {
int left = stackNums.removeFirst(), right = stackNums.removeFirst();
Operation tempOperation = Operation(stackOprts.removeFirst(), left, right);
/* Record solutions current state. */
SolutionState solutionState = tempSolution.addOperation(tempOperation);
if (solutionState == SolutionState.currentlyValid) {
/* If valid, add result to the current numbers stack. */
stackNums.addFirst(tempOperation.result);
} else if (solutionState == SolutionState.lastOperationRedundant) {
/* If operation is redundant, dispose it and continue. */
continue;
} else if (solutionState == SolutionState.lastResultInvalid) {
/* If results is invalid at any stage, dispose whole solution. */
break;
}
if (solutions.addSolution(tempSolution) == true) break;
} while (stackNums.length > 1);
}
}
/* Will show only accurate solutions.
* If there is no accurate solutions, will show solutions which results
* are closest to the expected result.
*/
solutions.showSolutions();
}
}
There are 5 classes, to shorten the question I added them in this Gist.
My algorithm is as follows;
Rules for this Project are; program must randomly generate 5 single digit number and 1 two digit number where twoDigitNumber % 10 == 0 and a three digit number as target.
I get permutations of 4 operators and numbers that will be used in operations (Using trotter package.)
For each permutation of numbers, I apply each permutation of operators; using Operation class and add them into a Solution instance for each permutation.
I pass some redundant operations in each iteration, and if there is an invalid result at any stage, I dispose that solution and continue. (I'm taking this DataGenetics blog about this topic as a reference.)
To test my algorithm I used numbers 1, 2, 3, 4 and set target as 15. The results from dcode.fr Solver are as is;
15 (2 op.)
4 + 1 = 5
5 x 3 = 15
15 (3 op.)
4 + 3 = 7
7 x 2 = 14
14 + 1 = 15
15 (3 op.)
4 x 3 = 12
12 + 2 = 14
14 + 1 = 15
15 (3 op.)
4 x 3 = 12
2 + 1 = 3
12 + 3 = 15
15 (3 op.)
3 + 2 = 5
4 - 1 = 3
5 x 3 = 15
15 (3 op.)
4 x 3 = 12
12 + 1 = 13
13 + 2 = 15
15 (3 op.)
4 - 1 = 3
3 + 2 = 5
5 x 3 = 15
15 (3 op.)
4 + 2 = 6
6 - 1 = 5
5 x 3 = 15
15 (3 op.)
2 + 1 = 3
4 x 3 = 12
12 + 3 = 15
15 (3 op.)
2 - 1 = 1
4 + 1 = 5
5 x 3 = 15
(A total of 10 solutions.)
and the solutions my program found are as is;
> SOLUTION 1 ~
4 - 1 = 3
3 + 2 = 5
5 x 3 = 15
> SOLUTION 2 ~
4 + 1 = 5
5 x 3 = 15
(A total of 2 solutions.)
Can you tell me what am I thinking wrongly; Why can't I find all solutions? What are alternative approaches I can take to solve this problem? Is there anything I'm missing?
TY for taking time.

Does d3.js have reverse ease functions?

With d3.js we can achieve eased time out of normalized time t, typically in the range [0,1]
For example:
d3.easeCubic(0.25) = 0.0625
How can we reverse that, how can we find x given known y ?
d3.easeCubic(X) = 0.0625,
X ???
The answer here is cubic root, but still.
The problem is in reusability, ease function can change to d3.easeExpIn, or `d3.easeCircleOut, or any other, do you need to invent reverse functions on your own, or are they hidden anywhere ?
Firstly, your math is wrong. d3.easeCubic(0.25) will give you 0.0625:
var easy = d3.easeCubic(0.25);
console.log(easy);
<script src="https://d3js.org/d3.v4.min.js"></script>
Now, back to your question:
How can we reverse that, how can we find x given known y?
There is no native solution, but we can create our own function to find X given a known Y. The problem, of course, is that we have to invert the math for each specific easing... But, since you asked about d3.easeCubic, which is the same of d3.easeCubicInOut, let's try to create an inverted function for that particular easing.
First step, let's have a look at the source code:
export function cubicInOut(t) {
return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2;
}
You can easily see that this is the correct function, giving us the same value as the first snippet:
function cubicInOut(t) {
return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2;
}
console.log(cubicInOut(0.25))
Now, let's try to invert it.
The math here is somehow complicated, but for values less than 1, here is the function:
function inverseEaseCubic(t){
return Math.cbrt(t * 2) / 2;
}
And here is the demo. We pass 0.0625 to the function, and it returns 0.25:
function inverseEaseCubic(t){
return Math.cbrt(t * 2) / 2;
}
console.log(inverseEaseCubic(0.0625))
If you want to deal with numbers bigger than 1, this is the complete function:
function InverseEaseCubic(t){
return t <= 1 ? Math.cbrt(t * 2) / 2 : (Math.cbrt(2 * t - 2) + 2) / 2;
}
PS: In his comment, #altocumulus just reminded us that, sometimes, it's even impossible to find the value. Here is a very simple example. Suppose this function:
function exponentiation(a){
return a*a;
}
Now imagine that, when called with an unknown argument, the function returned 4. What's the argument? Can we find out? Impossible to determine, because second degree equations, like this one, have 2 roots:
console.log(exponentiation(2))//returns 4
console.log(exponentiation(-2))//also returns 4
I used the #Gerardo Furtado answer but the inverse function didn't work well so I wrote another
function cubicInOut(t) {
return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2;
}
function inverseEaseCubic(x) {
return x < .5 ? Math.cbrt(x / 4) : (2 - Math.cbrt(2 - 2 * x)) / 2;
}
console.log(inverseEaseCubic(cubicInOut(1)) === 1);
console.log(inverseEaseCubic(cubicInOut(0.6)) === 0.6);
console.log(inverseEaseCubic(cubicInOut(0.4)) === 0.4);
console.log(inverseEaseCubic(cubicInOut(0.1)) === 0.1);
console.log(inverseEaseCubic(cubicInOut(0)) === 0);

Permutations excluding repeated characters

I'm working on a Free Code Camp problem - http://www.freecodecamp.com/challenges/bonfire-no-repeats-please
The problem description is as follows -
Return the number of total permutations of the provided string that
don't have repeated consecutive letters. For example, 'aab' should
return 2 because it has 6 total permutations, but only 2 of them don't
have the same letter (in this case 'a') repeating.
I know I can solve this by writing a program that creates every permutation and then filters out the ones with repeated characters.
But I have this gnawing feeling that I can solve this mathematically.
First question then - Can I?
Second question - If yes, what formula could I use?
To elaborate further -
The example given in the problem is "aab" which the site says has six possible permutations, with only two meeting the non-repeated character criteria:
aab aba baa aab aba baa
The problem sees each character as unique so maybe "aab" could better be described as "a1a2b"
The tests for this problem are as follows (returning the number of permutations that meet the criteria)-
"aab" should return 2
"aaa" should return 0
"abcdefa" should return 3600
"abfdefa" should return 2640
"zzzzzzzz" should return 0
I have read through a lot of post about Combinatorics and Permutations and just seem to be digging a deeper hole for myself. But I really want to try to resolve this problem efficiently rather than brute force through an array of all possible permutations.
I posted this question on math.stackexchange - https://math.stackexchange.com/q/1410184/264492
The maths to resolve the case where only one character is repeated is pretty trivial - Factorial of total number of characters minus number of spaces available multiplied by repeated characters.
"aab" = 3! - 2! * 2! = 2
"abcdefa" = 7! - 6! * 2! = 3600
But trying to figure out the formula for the instances where more than one character is repeated has eluded me. e.g. "abfdefa"
This is a mathematical approach, that doesn't need to check all the possible strings.
Let's start with this string:
abfdefa
To find the solution we have to calculate the total number of permutations (without restrictions), and then subtract the invalid ones.
TOTAL OF PERMUTATIONS
We have to fill a number of positions, that is equal to the length of the original string. Let's consider each position a small box.
So, if we have
abfdefa
which has 7 characters, there are seven boxes to fill. We can fill the first with any of the 7 characters, the second with any of the remaining 6, and so on. So the total number of permutations, without restrictions, is:
7 * 6 * 5 * 4 * 3 * 2 * 1 = 7! (= 5,040)
INVALID PERMUTATIONS
Any permutation with two equal characters side by side is not valid. Let's see how many of those we have.
To calculate them, we'll consider that any character that has the same character side by side, will be in the same box. As they have to be together, why don't consider them something like a "compound" character?
Our example string has two repeated characters: the 'a' appears twice, and the 'f' also appears twice.
Number of permutations with 'aa'
Now we have only six boxes, as one of them will be filled with 'aa':
6 * 5 * 4 * 3 * 2 * 1 = 6!
We also have to consider that the two 'a' can be themselves permuted in 2! (as we have two 'a') ways.
So, the total number of permutations with two 'a' together is:
6! * 2! (= 1,440)
Number of permutations with 'ff'
Of course, as we also have two 'f', the number of permutations with 'ff' will be the same as the ones with 'aa':
6! * 2! (= 1,440)
OVERLAPS
If we had only one character repeated, the problem is finished, and the final result would be TOTAL - INVALID permutations.
But, if we have more than one repeated character, we have counted some of the invalid strings twice or more times.
We have to notice that some of the permutations with two 'a' together, will also have two 'f' together, and vice versa, so we need to add those back.
How do we count them?
As we have two repeated characters, we will consider two "compound" boxes: one for occurrences of 'aa' and other for 'ff' (both at the same time).
So now we have to fill 5 boxes: one with 'aa', other with 'ff', and 3 with the remaining 'b', 'd' and 'e'.
Also, each of those 'aa' and 'bb' can be permuted in 2! ways. So the total number of overlaps is:
5! * 2! * 2! (= 480)
FINAL SOLUTION
The final solution to this problem will be:
TOTAL - INVALID + OVERLAPS
And that's:
7! - (2 * 6! * 2!) + (5! * 2! * 2!) = 5,040 - 2 * 1,440 + 480 = 2,640
It seemed like a straightforward enough problem, but I spent hours on the wrong track before finally figuring out the correct logic. To find all permutations of a string with one or multiple repeated characters, while keeping identical characters seperated:
Start with a string like:
abcdabc
Seperate the first occurances from the repeats:
firsts: abcd
repeats: abc
Find all permutations of the firsts:
abcd abdc adbc adcb ...
Then, one by one, insert the repeats into each permutation, following these rules:
Start with the repeated character whose original comes first in the firsts
e.g. when inserting abc into dbac, use b first
Put the repeat two places or more after the first occurance
e.g. when inserting b into dbac, results are dbabc and dbacb
Then recurse for each result with the remaining repeated characters
I've seen this question with one repeated character, where the number of permutations of abcdefa where the two a's are kept seperate is given as 3600. However, this way of counting considers abcdefa and abcdefa to be two distinct permutations, "because the a's are swapped". In my opinion, this is just one permutation and its double, and the correct answer is 1800; the algorithm below will return both results.
function seperatedPermutations(str) {
var total = 0, firsts = "", repeats = "";
for (var i = 0; i < str.length; i++) {
char = str.charAt(i);
if (str.indexOf(char) == i) firsts += char; else repeats += char;
}
var firsts = stringPermutator(firsts);
for (var i = 0; i < firsts.length; i++) {
insertRepeats(firsts[i], repeats);
}
alert("Permutations of \"" + str + "\"\ntotal: " + (Math.pow(2, repeats.length) * total) + ", unique: " + total);
// RECURSIVE CHARACTER INSERTER
function insertRepeats(firsts, repeats) {
var pos = -1;
for (var i = 0; i < firsts.length, pos < 0; i++) {
pos = repeats.indexOf(firsts.charAt(i));
}
var char = repeats.charAt(pos);
for (var i = firsts.indexOf(char) + 2; i <= firsts.length; i++) {
var combi = firsts.slice(0, i) + char + firsts.slice(i);
if (repeats.length > 1) {
insertRepeats(combi, repeats.slice(0, pos) + repeats.slice(pos + 1));
} else {
document.write(combi + "<BR>");
++total;
}
}
}
// STRING PERMUTATOR (after Filip Nguyen)
function stringPermutator(str) {
var fact = [1], permutations = [];
for (var i = 1; i <= str.length; i++) fact[i] = i * fact[i - 1];
for (var i = 0; i < fact[str.length]; i++) {
var perm = "", temp = str, code = i;
for (var pos = str.length; pos > 0; pos--) {
var sel = code / fact[pos - 1];
perm += temp.charAt(sel);
code = code % fact[pos - 1];
temp = temp.substring(0, sel) + temp.substring(sel + 1);
}
permutations.push(perm);
}
return permutations;
}
}
seperatedPermutations("abfdefa");
A calculation based on this logic of the number of results for a string like abfdefa, with 5 "first" characters and 2 repeated characters (A and F) , would be:
The 5 "first" characters create 5! = 120 permutations
Each character can be in 5 positions, with 24 permutations each:
A**** (24)
*A*** (24)
**A** (24)
***A* (24)
****A (24)
For each of these positions, the repeat character has to come at least 2 places after its "first", so that makes 4, 3, 2 and 1 places respectively (for the last position, a repeat is impossible). With the repeated character inserted, this makes 240 permutations:
A***** (24 * 4)
*A**** (24 * 3)
**A*** (24 * 2)
***A** (24 * 1)
In each of these cases, the second character that will be repeated could be in 6 places, and the repeat character would have 5, 4, 3, 2, and 1 place to go. However, the second (F) character cannot be in the same place as the first (A) character, so one of the combinations is always impossible:
A****** (24 * 4 * (0+4+3+2+1)) = 24 * 4 * 10 = 960
*A***** (24 * 3 * (5+0+3+2+1)) = 24 * 3 * 11 = 792
**A**** (24 * 2 * (5+4+0+2+1)) = 24 * 2 * 12 = 576
***A*** (24 * 1 * (5+4+3+0+1)) = 24 * 1 * 13 = 312
And 960 + 792 + 576 + 312 = 2640, the expected result.
Or, for any string like abfdefa with 2 repeats:
where F is the number of "firsts".
To calculate the total without identical permutations (which I think makes more sense) you'd divide this number by 2^R, where R is the number or repeats.
Here's one way to think about it, which still seems a bit complicated to me: subtract the count of possibilities with disallowed neighbors.
For example abfdefa:
There are 6 ways to place "aa" or "ff" between the 5! ways to arrange the other five
letters, so altogether 5! * 6 * 2, multiplied by their number of permutations (2).
Based on the inclusion-exclusion principle, we subtract those possibilities that include
both "aa" and "ff" from the count above: 3! * (2 + 4 - 1) choose 2 ways to place both
"aa" and "ff" around the other three letters, and we must multiply by the permutation
counts within (2 * 2) and between (2).
So altogether,
7! - (5! * 6 * 2 * 2 - 3! * (2 + 4 - 1) choose 2 * 2 * 2 * 2) = 2640
I used the formula for multiset combinations for the count of ways to place the letter pairs between the rest.
A generalizable way that might achieve some improvement over the brute force solution is to enumerate the ways to interleave the letters with repeats and then multiply by the ways to partition the rest around them, taking into account the spaces that must be filled. The example, abfdefa, might look something like this:
afaf / fafa => (5 + 3 - 1) choose 3 // all ways to partition the rest
affa / faaf => 1 + 4 + (4 + 2 - 1) choose 2 // all three in the middle; two in the middle, one anywhere else; one in the middle, two anywhere else
aaff / ffaa => 3 + 1 + 1 // one in each required space, the other anywhere else; two in one required space, one in the other (x2)
Finally, multiply by the permutation counts, so altogether:
2 * 2! * 2! * 3! * ((5 + 3 - 1) choose 3 + 1 + 4 + (4 + 2 - 1) choose 2 + 3 + 1 + 1) = 2640
Well I won't have any mathematical solution for you here.
I guess you know backtracking as I percieved from your answer.So you can use Backtracking to generate all permutations and skipping a particular permutation whenever a repeat is encountered. This method is called Backtracking and Pruning.
Let n be the the length of the solution string, say(a1,a2,....an).
So during backtracking when only partial solution was formed, say (a1,a2,....ak) compare the values at ak and a(k-1).
Obviously you need to maintaion a reference to a previous letter(here a(k-1))
If both are same then break out from the partial solution, without reaching to the end and start creating another permutation from a1.
Thanks Lurai for great suggestion. It took a while and is a bit lengthy but here's my solution (it passes all test cases at FreeCodeCamp after converting to JavaScript of course) - apologies for crappy variables names (learning how to be a bad programmer too ;)) :D
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class PermAlone {
public static int permAlone(String str) {
int length = str.length();
int total = 0;
int invalid = 0;
int overlap = 0;
ArrayList<Integer> vals = new ArrayList<>();
Map<Character, Integer> chars = new HashMap<>();
// obtain individual characters and their frequencies from the string
for (int i = 0; i < length; i++) {
char key = str.charAt(i);
if (!chars.containsKey(key)) {
chars.put(key, 1);
}
else {
chars.put(key, chars.get(key) + 1);
}
}
// if one character repeated set total to 0
if (chars.size() == 1 && length > 1) {
total = 0;
}
// otherwise calculate total, invalid permutations and overlap
else {
// calculate total
total = factorial(length);
// calculate invalid permutations
for (char key : chars.keySet()) {
int len = 0;
int lenPerm = 0;
int charPerm = 0;
int val = chars.get(key);
int check = 1;
// if val > 0 there will be more invalid permutations to calculate
if (val > 1) {
check = val;
vals.add(val);
}
while (check > 1) {
len = length - check + 1;
lenPerm = factorial(len);
charPerm = factorial(check);
invalid = lenPerm * charPerm;
total -= invalid;
check--;
}
}
// calculate overlaps
if (vals.size() > 1) {
overlap = factorial(chars.size());
for (int val : vals) {
overlap *= factorial(val);
}
}
total += overlap;
}
return total;
}
// helper function to calculate factorials - not recursive as I was running out of memory on the platform :?
private static int factorial(int num) {
int result = 1;
if (num == 0 || num == 1) {
result = num;
}
else {
for (int i = 2; i <= num; i++) {
result *= i;
}
}
return result;
}
public static void main(String[] args) {
System.out.printf("For %s: %d\n\n", "aab", permAlone("aab")); // expected 2
System.out.printf("For %s: %d\n\n", "aaa", permAlone("aaa")); // expected 0
System.out.printf("For %s: %d\n\n", "aabb", permAlone("aabb")); // expected 8
System.out.printf("For %s: %d\n\n", "abcdefa", permAlone("abcdefa")); // expected 3600
System.out.printf("For %s: %d\n\n", "abfdefa", permAlone("abfdefa")); // expected 2640
System.out.printf("For %s: %d\n\n", "zzzzzzzz", permAlone("zzzzzzzz")); // expected 0
System.out.printf("For %s: %d\n\n", "a", permAlone("a")); // expected 1
System.out.printf("For %s: %d\n\n", "aaab", permAlone("aaab")); // expected 0
System.out.printf("For %s: %d\n\n", "aaabb", permAlone("aaabb")); // expected 12
System.out.printf("For %s: %d\n\n", "abbc", permAlone("abbc")); //expected 12
}
}

Can integer division be rounded up, instead of down?

Is there a way to round the result of integer division up to the nearest integer, rather than down?
For example, I would like to change the default behavior:
irb(main):001:0> 5 / 2
=> 2
To the following behavior:
irb(main):001:0> 5 / 2
=> 3
The function you are looking for is ceil.
Ceil returns the nearest integer, rounded upwards, for a floating point number.
4/3 = 1
4.0/3.0 = 1.3333...3
(4.0/3.0).ceil = 2
Also, note that this rounds in the positive direction, so
(-4.0/3.0).ceil = -1, NOT -2
Also, there is the corresponding floor function which rounds downwards.
This is rather an algorithm question than a ruby specific question.
Try (a + b - 1) / b. For example
(5 + 2 - 1) / 2 #=> 3
(10 + 3 - 1) / 3 #=> 4
(6 + 3 - 1) / 3 #=> 2
You can define an instance method, say divide_by, in the Integer class (monkey patch):
class Integer
def divide_by(divisor)
(self + divisor - 1) / divisor
end
end
According to my benchmark result, it's about 1/2 times faster than the to_f then ceil solution.
CORRECTION
The method shown above gives wrong result when both the dividend and the divisor are negative.
Here's the method that gives the correct result in all cases: (a * 2 + b) / (b * 2)
a = 5
b = 2
(a * 2 + b) / (b * 2) #=> 3
a = 6
b = 2
(a * 2 + b) / (b * 2) #=> 3
a = 5
b = 1
(a * 2 + b) / (b * 2) #=> 5
a = -5
b = 2
(a * 2 + b) / (b * 2) #=> -2 (-2.5 rounded up to -2)
a = 5
b = -2
(a * 2 + b) / (b * 2) #=> -2 (-2.5 rounded up to -2)
a = -5
b = -2
(a * 2 + b) / (b * 2) #=> 3
a = 10
b = 0
(a * 2 + b) / (b * 2) #=> raises ZeroDivisionError
The monkey patch should be
class Integer
def divide_by(divisor)
(self * 2 + divisor) / (divisor * 2)
end
end
Mathematical Proof:
The dividend a and the divisor b meets the equation a = kb + m where a, b, k, m are all integers, b is not zero, and m is between b and 0 (can be 0).
For example, when a is 5 and b is 2, then a = 2b + 1, thus in this case, k = 2 and m = 1.
Another example for negative divisor, a is 5, b is -2, then a = -3b + (-1), thus k = -3 and m = -1.
(2a + b) / 2b
= (2(kb + m) + b) / 2b
= (2kb + b + 2m) / 2b
When m = 0
(2kb + b + 2m) / 2b
= (2k + 1)b / 2b
= k + (1 / 2)
= k + 0 # in Ruby
= k # in Ruby
and since k = a / b, we got the correct answer.
When m is not 0,
(2kb + b + 2m) / 2b
= ((2k + 2)b - b + 2m) / 2b
= (k + 1) + (2m - b) / 2b
If b > 0, then 2m - b < b so (2m - b) / 2b < 1 / 2. So the second term is always 0 in integer division.
If b < 0, then 2m - b > b and still (2m - b) / 2b < 1 / 2 so the second term is still 0.
In either case, (2a + b) / 2b is rounded to k + 1 when m is not 0.
If what you actually want is to Integer div and round up if there's any left over, just do it straightforward as the logic would dictate on paper using a second line of modular operation (%) to check the remainders of the division:
a = 5
b = 2
result = a / b #=> 2
result += 1 if (a % b).positive?
#=> 3
a = 6
b = 3
result = a / b #=> 2
result += 1 if (a % b).positive?
#=> 2

Resources