I need to write recursive function Repl
takes as input an expression in e in Expr and returns an expression in Expr
wherein each number is replaced by the number 1.
For example, if e is the expression
((((9 + 5) ∗ 2) ∗ (2 + (4 ∗ 6))))
then Repl(e) is the expression
((((1 + 1) ∗ 1) ∗ (1 + (1 ∗ 1))))
Can anybody help me how to go about this?
Iterative one is easy to write but how to write it recursively?
It is not clear why you would want a recursive solution for this problem, but the solution is relatively straightforward. Here is pseudocode:
string replace(string s, bool seenDigit) {
if (s == "") {
// The string is empty : we are done
return "";
}
if (s[0] is digit) {
if (seenDigit) {
// This is a second, third, etc. digit in a multi-digit chain
// It has been replaced with "1" already, so we cut it out
return replace(s.substring(1), true);
} else {
// This is the first digit in a chain of one or more digits
// Replace it with "1", and tell the next level that we've
// done the replacement already
return "1"+replace(s.substring(1), true);
}
} else {
// Non-digits do not get replaced
return s[0] + replace(s.substring(1), false);
}
}
s[0] means the first character; string+string denotes concatenation.
Making #dasblinkenlight's solution tail recursive:
string replace(string sToGo, string sSoFar, bool inNumber) {
if (sToGo == "") {
return sSoFar;
}
if (sToGo[0] is digit) {
if (isNumber) {
return replace(sSoFar, sToGo.substring(1), true);
} else {
return replace(sSoFar+"1", sToGo.substring(1), true);
}
} else {
return replace(sSoFar+s[0], sToGo.substring(1), false);
}
}
Notice that every return is either a direct value (the base case) or directly returns what a recursive call gives back. This means the program doesn't need to keep track of the recursive calls, because there's nothing to do with the value being returned other than returning it up the chain, which means (if the interpreter takes advantage of it) that the primary downside to using recursion (the overhead of the stack) can be eliminated.
Related
I'm looking for some way to shorten an iterator by some condition. A bit like an inverse filter but it stops iterating at the first true value. Let's call it until(f). Where:
iterator.until(f)
Would return an iterator that only runs until f is true once.
Let's use an example of finding the next prime number.
We have some structure containing known primes and a function to extend it.
// Structure for caching known prime numbers
struct PrimeGenerator {
primes:Vec<i64>
}
impl PrimeGenerator {
// Create a new prime generator
fn new()->Self{
let primes = vec![2,3];
Self {
primes,
}
}
// Extend the list of known primes by 1
fn extend_by_one(&mut self){
let mut next_option = self.primes.last().unwrap()+2;
while self.primes.iter().any(|x| next_option%x == 0) { // This is the relevant line
next_option += 2;
}
self.primes.push(next_option);
}
}
Now this snippet is a bit too exhaustive as we should only have to check until the square root of next_option, so I was looking for a some method that would shorten the iterator based on some condition, so I could write something like:
self.iter().until(|x| x*x > next_option).any(|x| next_option%x == 0)
Is there any similar pattern available?
Looks like your until is similar to inverted take_while.
self.iter().take_while(|x| x*x <= next_option).all(|x| next_option%x != 0)
I want to extract the payload of a HTTP request as a Vec<u8>. In the request, the payload is separated from the rest by the sequence \r\n\r\n, that's why I want to split my Vec at this position, and take the second element.
My current solution is to use the following function I wrote.
fn find_payload_index(buffer: &Vec<u8>) -> usize {
for (pos, e) in buffer.iter().enumerate() {
if pos < 3 {
continue
}
if buffer[pos - 3] == 13 && buffer[pos - 2] == 10 && buffer[pos - 1] == 13 && buffer[pos] == 10 {
return pos + 1;
}
}
0
}
13 is the ASCII value of \r and 10 the value of \n. I then split by the returned index. While this solution is technically working, it feels very unclean, and I was wondering how to do this in a more elegant way.
First of:
A function should almost never have a &Vec<_> parameter.
See Why is it discouraged to accept a reference to a String (&String), Vec (&Vec), or Box (&Box) as a function argument?.
Don't use the magic values 10 and 13, Rust supports byte literals: b'\r' and b'\n'.
As for your question: I believe you can make it a bit simpler using windows and matches! with a byte string literal pattern:
fn find_payload_index(buffer: &[u8]) -> Option<usize> {
buffer
.windows(4)
.enumerate()
.find(|(_, w)| matches!(*w, b"\r\n\r\n"))
.map(|(i, _)| i)
}
Permalink to the playground with test cases.
Note that slice has a starts_with method which will more easily do what you want:
fn find_payload_index(buffer: &[u8]) -> usize {
for i in 0..buffer.len() {
if buffer[i..].starts_with(b"\r\n\r\n") {
return i
}
}
panic!("malformed buffer without the sequence")
}
I see no reason to use enumerate if the actual element itself never be used, simply looping over 0..buffer.len() seems the easiest solution to me.
I have also elected to make the function panic, rather than return 0, when the sequence be malformed, which I believe is more proper, though you should probably in the end return some kind of Result value, and handle the error case cleanly, if the input be malformed, but you should never return 0 in this case.
A shorter alternative for #mccarton answer would be to use position:
fn find_payload_index(buffer: &[u8]) -> Option<usize> {
buffer
.windows(4)
.position(|arr| arr == b"\r\n\r\n")
}
I am new to recursion, and have been looking at non-tail recursion. I believe this is where the recursive call is not at the end of the function. I was looking at some recursive code examples, and I am confused about when and how the code after the recursive call is executed. To be more specific, when the current line of the program reaches the recursive call, is that last bit of code executed before actually executing the entire function again, or does the current line of execution immediately jump back to the beginning of the function, only to execute that remaining bit of code after the entire recursion bottoms out? Can anybody please clarify how this works for me?
Imagine this code here: (I'm using JS here, but it applies to all eager languages)
function add(a, b) {
return a + b;
}
function sub(a, b) {
return a - b;
}
function fib(n) {
if (n < 2) {
return n;
} else {
return add(
fib(sub(n, 2)),
fib(sub(n, 1)),
);
}
}
console.log(fib(10));
Now when n is 2 or more we we add the result of calling fib on the two predecessors to n. The order between some of the calls are JS engines choice, but sub needs to be called and return before fib can get a value and add needs to be called when both it's arguments have results. This can be rewritten as tail calls using continuation passing style:
function cadd(a, b, k) {
k(a + b);
}
function csub(a, b, k) {
k(a - b);
}
function cfib(n, k) {
if (n < 2) {
k(n);
} else {
csub(n, 2, n2 =>
cfib(n2, rn2 =>
csub(n, 1, n1 =>
cfib(n1, rn1 =>
cadd(rn2, rn1, k)))));
}
}
cfib(10, console.log);
Here you see the order which was engines choice is explicit left to right. Each call does one thing then the continuation is called with that result. Notice also that this never returns anything. "return" is only done by continuation, yet it does the exact same thing as the previous code.
In many languages they would compile to the same.
I'm trying to follow a specific implementation of a recursive (in-order traversal) isBST function.
I tried to simulate it with the simple invalid BST example:
root=5, root.left=3, root.left.right=8
5
/
3
\
8
i'm getting either 'true' or 'false' but without having to check the last node '8'.
the code is as follows:
/* wrapper that keeps track of the previous value */
class PrevWrapper {
int data = Integer.MIN_VALUE;
}
boolean isBST(Node root, PrevWrapper prev) {
/* base case: we reached null*/
if (root == null) {
return true;
}
if(!isBST(root.left, prev)) {
return false;
}
/* If previous in-order node's data is larger than
* current node's data, BST property is violated */
if (prev.data > root.data) {
return false;
}
/* set the previous in-order data to the current node's data*/
prev.data = root.data;
return isBST(root.right, prev);
}
boolean isBST(Node root) {
return isBST(root, new PrevWrapper());
}
what is the correct order of returning the recursive calls?
EDIT:
I was thinking:
(#)isBST(5,min), isBST(3,min), isBST(3.left=null,min) - returns true, skips to prev=3, isBST(8,3), isBST(8.left=null,3) - returns true, skips to prev=8, isBST(8.right=null,8) - returns true to (#), checks 8 > 5? returns false.
I think I got it, is this the correct order of calls?
thanks in advance.
function BACKTRACKING-SEARCH(csp) returns a solution, or failure
return RECURSIVE- BACKTRACKING({ }, csp)
function RECURSIVE-BACKTRACKING(assignment,csp) returns a solution, or failure
if assignment is complete then
return assignment
var ←SELECT-UNASSIGNED-VARIABLE(VARIABLES[csp],assignment,csp)
for each value in ORDER-DOMAIN-VALUES(var,assignment,csp) do
if value is consistent with assignment according to CONSTRAINTS[csp] then
add {var = value} to assignment
result ← RECURSIVE-BACKTRACKING(assignment, csp)
if result ̸= failure then
return result
remove {var = value} from assignment
return failure
This is a backtracking recursion algorythm pseudocode from AIMA. However, I don't understand if it returns ALL possible solutions or just first one found. In case it is the last option, could you please help me modify it to return a list of possible solutions instead (or at least updating some global list).
EDIT: I implemented this algorithm in Java. However, there is one problem:
if I don't return assignment, but save it in result instead, the recursion stop condition fails (i.e. it doesn't exist anymore). How can I implement another stop-condition? Maybe I should return true in the end?
Here is my code :
/**
* The actual backtracking. Unfortunately, I don't have time to implement LCV or MCV,
* therefore it will be just ordinary variable-by-variable search.
* #param line
* #param onePossibleSituation
* #param result
*/
public static boolean recursiveBacktrack(Line line, ArrayList<Integer> onePossibleSituation, ArrayList<ArrayList<Integer>> result){
if (onePossibleSituation.size() == line.getNumOfVars()){
// instead of return(assignment)
ArrayList<Integer> situationCopy = new ArrayList<Integer>();
situationCopy.addAll(onePossibleSituation);
result.add(situationCopy);
onePossibleSituation.clear();
}
Block variableToAssign = null;
// iterate through all variables and choose one unassigned
for(int i = 0; i < line.getNumOfVars(); i++){
if(!line.getCspMiniTaskVariables().get(i).isAssigned()){
variableToAssign = line.getCspMiniTaskVariables().get(i);
break;
}
}
// for each domain value for given block
for (int i = line.getCspMiniTaskDomains().get(variableToAssign.getID())[0];
i <= line.getCspMiniTaskDomains().get(variableToAssign.getID())[0]; i++){
if(!areThereConflicts(line, onePossibleSituation)){
//complete the assignment
variableToAssign.setStartPositionTemporary(i);
variableToAssign.setAssigned(true);
onePossibleSituation.add(i);
//do backtracking
boolean isPossibleToPlaceIt = recursiveBacktrack(line,onePossibleSituation,result);
if(!isPossibleToPlaceIt){
return(false);
}
}
// unassign
variableToAssign.setStartPositionTemporary(-1);
variableToAssign.setAssigned(false);
onePossibleSituation.remove(i);
}
// end of backtracking
return(false);
}
This code checks if solution found and if it is, returns the solution. Otherwise, continue backtracking. That means, it returns the first solution found.
if result ̸= failure then
return result
remove {var = value} from assignment
You can modify it like that:
if result ̸= failure then
PRINT result // do not return, just save the result
remove {var = value} from assignment
Or, better, modify this part:
if assignment is complete then
print assignment
return assignment // print it and return
About edited question:
First, return true in the first if, so recursion will know that it found a solution. The second step, there is a mistake, probably:
if(!isPossibleToPlaceIt){
return(false);
}
Should be
if(isPossibleToPlaceIt){
return(true);
}
Because if your backtracking has found something, it returns true, which means you don't have to check anything else any longer.
EDIT#2: If you want to continue backtracking to find ALL solutions, just remove the whole previous if section with return:
//if(isPossibleToPlaceIt){
// return(true);
//}
So we will continue the search in any way.