I have code that basically assigns a variable in one case, else a different in another. Is there a neater way that is more efficient?
I.e., not taking up so many lines. Or is this the best way?
if (ViewBag.Date != RoomBooking.StartDateTime.Date || ViewBag.DayPlannerStartTime * 12 > (Int32)RoomBooking.StartDateTime.TimeOfDay.TotalMinutes / 5)
{
StartBlock = ViewBag.DayPlannerStartTime * 12;
}
else
{
StartBlock = ((Int32)RoomBooking.StartDateTime.TimeOfDay.TotalMinutes / 5);
}
Maybe this (it's arguably neater, but definitely has the same efficiency):
StartBlock = (ViewBag.Date != RoomBooking.StartDateTime.Date || ViewBag.DayPlannerStartTime * 12 > (Int32)RoomBooking.StartDateTime.TimeOfDay.TotalMinutes / 5)
? ViewBag.DayPlannerStartTime * 12
: ((Int32)RoomBooking.StartDateTime.TimeOfDay.TotalMinutes / 5);
EDIT: You can slightly optimize the condition as well. I suspect that your DayPlannerStartTime is expressed in seconds, and if I'm right you can rewrite the comparison the following way (I just divided both operands of the > operator by 12, and TotalMinutes divided by 5*12 became TotalHours):
ViewBag.DayPlannerStartTime > (Int32)RoomBooking.StartDateTime.TimeOfDay.TotalHours
Yes, you can use the ?: operator to create a single expression that will evaluate to the first expression if the condition is true, or else to the second expression:
// condition ? first_expression : second_expression;
var value = (something that is true or false) ? value if true : value if false;
Related
Please help me understand how the following code always returns the smallest value in the array. I tried moving position of 3 but it always manages to return it irrespective of the position of it in the array.
let myA = [12,3,8,5]
let myN = 4
function F4(A,N)
{
if(N==1){
return A[0]
}
if(F4(A,N-1) < A[N-1]){
return F4(A,N-1)
}
return A[N-1]
}
console.log(F4(myA,myN))
This is quite tricky to get an intuition for. It's also quite important that you learn the process for tackling this type of problem rather than simply be told the answer.
If we take a first view of the code with a few comments and named variables it looks like this:
let myA = [12,3,8,5];
let myN = myA.length;
function F4(A, N) {
// if (once) there is only one element in the array "A", then it must be the minimum, do not recurse
if (N === 1){
return A[0]
}
const valueFromArrayLessLastEl = F4(A,N-1); // Goes 'into' array
const valueOfLastElement = A[N-1];
console.log(valueFromArrayLessLastEl, valueOfLastElement);
// note that the recursion happens before min(a, b) is evaluated so array is evaluated from the start
if (valueFromArrayLessLastEl < valueOfLastElement) {
return valueFromArrayLessLastEl;
}
return valueOfLastElement;
}
console.log(F4(myA, myN))
and produces
12 3 // recursed all the way down
3 8 // stepping back up with result from most inner/lowest recursion
3 5
3
but in order to gain insight it is vital that you approach the problem by considering the simplest cases and expand from there. What happens if we write the code for the cases of N = 1 and N = 2:
// trivially take N=1
function F1(A) {
return A[0];
}
// take N=2
function F2(A) {
const f1Val = F1(A); // N-1 = 1
const lastVal = A[1];
// return the minimum of the first element and the 2nd or last element
if (f1Val < lastVal) {
return f1Val;
}
return lastVal;
}
Please note that the array is not being modified, I speak as though it is because the value of N is decremented on each recursion.
With myA = [12, 3, 8, 5] F1 will always return 12. F2 will compare this value 12 with 3, the nth-1 element's value, and return the minimum.
If you can build on this to work out what F3 would do then you can extrapolate from there.
Play around with this, reordering the values in myA, but crucially look at the output as you increase N from 1 to 4.
As a side note: by moving the recursive call F4(A,N-1) to a local constant I've prevented it being called twice with the same values.
I'm trying to improve my recursion skill(reading a written recursion function) by looking at examples. However, I can easily get the logic of recursions without local variables. In below example, I can't understand how the total variables work. How should I think a recursive function to read and write by using local variables? I'm thinking it like stack go-hit-back. By the way, I wrote the example without variables. I tried to write just countThrees(n / 10); instead of total = total + countThrees(n / 10); but it doesn't work.
with total variable:
int countThrees(int n) {
if (n == 0) { return 0; }
int lastDigit = n % 10;
int total = 0;
total = total + countThrees(n / 10);
if (lastDigit == 3) {
total = total + 1;
}
return total;
}
simplified version
int countThrees(int x)
{
if (x / 10 == 0) return 0;
if (x % 10 == 3)
return 1 + countThrees(x / 10);
return countThrees(x / 10);
}
In both case, you have to use a stack indeed, but when there are local variables, you need more space in the stack as you need to put every local variables inside. In all cases, the line number from where you jump in a new is also store.
So, in your second algorithme, if x = 13, the stack will store "line 4" in the first step, and "line 4; line 3" in the second one, in the third step you don't add anything to the stack because there is not new recursion call. At the end of this step, you read the stack (it's a First in, Last out stack) to know where you have to go and you remove "line 3" from the stack, and so.
In your first algorithme, the only difference is that you have to add the locale variable in the stack. So, at the end of the second step, it looks like "Total = 0, line 4; Total = 0, line 4".
I hope to be clear enough.
The first condition should read:
if (x == 0) return 0;
Otherwise the single 3 would yield 0.
And in functional style the entire code reduces to:
return x == 0 ? 0
: countThrees(x / 10) + (x % 10 == 3 ? 1 : 0);
On the local variables:
int countThrees(int n) {
if (n == 0) {
return 0;
}
// Let an alter ego do the other digits:
int total = countThrees(n / 10);
// Do this digit:
int lastDigit = n % 10;
if (lastDigit == 3) {
++total;
}
return total;
}
The original code was a bit undecided, when or what to do, like adding to total after having it initialized with 0.
By declaring the variable at the first usage, things become more clear.
For instance the absolute laziness: first letting the recursive instances calculate the total of the other digits, and only then doing the last digit oneself.
Using a variable lastDigit with only one usage is not wrong; it explains what is happening: you inspect the last digit.
Preincrement operator ++x; is x += 1; is x = x + 1;.
One could have done it (recursive call and own work) the other way around, so it probably says something about the writer's psychological preferences
The stack usage: yes total before the recursive call is an extra variable on the stack. Irrelevant for numbers. Also a smart compiler could see that total is a result.
On the usage of variables: they can be stateful, and hence are useful for turning recursion into iteration. For that tail recursion is easiest: the recursion happening last.
int countThrees(int n) {
int total = 0;
while (n != 0) {
int digit = n % 10;
if (digit == 3) {
++total;
}
n /= 10; // Divide by 10
}
return total;
}
My teacher just asked this question in the exam and I have no idea where to go on.
More details, the prototype of function is given as:
stack<int> Fibonacci_sequence(int n); //fibonacci numbers count up to n
The point is this function is recursive and it should return a stack data type. In my opinion I don't think this is a possible thing to do, but my teacher asked it!!
P.s: sorry, my language is C++
function stack<int> Fibonacci_sequence(int n) {
if n == 0 {
var a stack<int>;
a.push(0);
return a
} else if n == 1 {
var a stack<int>;
a.push(0);
a.push(1);
return a
} else
var temp int;
var seq int;
seq = Fibonacci_sequence(n-1);
temp = seq.pop;
seq.push(temp);
seq.push(temp);
//above: the top element of the stack must be duplicated because it
//is popped off in the process of calculating the sum.
seq.push(seq.pop()+Fibonacci_sequence(n-2).pop());
return seq
}
}
Above is a function that does just that, written in pseudo code because you did not specify a language. Hopefully this helps, it was fun to come up with! Thanks for the interesting question.
Since you didn't specify a language, and you specified it's an exam, here it is in Ruby. Ruby provides stack operations for arrays, but I'm only using push and pop operations in the following so you should be able to easily translate it to the language of your choice.
def fib(n) # no explicit return type, since everything's an object in Ruby
fail "negative argument not allowed" if n < 0
if n > 1
stack = fib(n - 1)
# grab the last two values...
f_n_1 = stack.pop
f_n_2 = stack.pop
# ...and use them to calculate the next.
# The value of this expression is the resulting stack, return it
return stack.push(f_n_2).push(f_n_1).push(f_n_1 + f_n_2)
elsif n == 1
return fib(0).push(1)
else
return [].push(0)
end
end
p fib(10) # => [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
You may have to translate this to the language of your exam, but that's appropriate.
Here is my C++ code based on #Elliot pseudo, and it got errors, I specified these errors in the code. And I just figure out that pop() doesn't return a value, I'm gonna fix this.
stack<int> Fibonacci_sequence(int n)
{
if (n == 0) {
stack<int> a;
a.push(0);
return a;
}
else if (n == 1) {
stack<int> a;
a.push(0);
a.push(1);
return a;
}
else
{
int temp;
temp = Fibonacci_sequence(n - 1).pop(); //error C2440: '=': cannot convert from 'void' to 'int'
Fibonacci_sequence(n - 1).push(temp);
Fibonacci_sequence(n - 1).push(temp);
//above: the top element of the stack must be duplicated because it
//is popped off in the process of calculating the sum.
return Fibonacci_sequence(n - 1).push(Fibonacci_sequence(n - 1).pop() + Fibonacci_sequence(n - 2).pop());//error C2186: '+': illegal operand of type 'void'
}
}
I'm learning how to do recursion, and I want to make sure that I'm doing it correctly. I just finished a question on codingbat that reads like this:
Given a non-negative int n, return the count of the occurrences of 7
as a digit, so for example 717 yields 2. (no loops). Note that mod (%)
by 10 yields the rightmost digit (126 % 10 is 6), while divide (/) by
10 removes the rightmost digit (126 / 10 is 12).
count7(717) → 2
count7(7) → 1
count7(123) → 0
And my solution, which worked, looks like this:
public int count7(int n) {
int count = 0;
if(n < 7) {
return count;
} else {
int divided = n / 10;
if(n % 10 == 7) count++;
return count + count7(divided);
}
}
Even though my solution passed, I want to make sure that I'm working through these recursion problems correctly. Should I have a counter sitting outside the if/else statement? If not, why? If not, how would you solve it instead.
The more self-contained, the better - and your answer is self-contained. And it has the two requisites for correct recursion:
Provide a "stopper"
public int count7(int n) {
int count = 0;
if(n < 7) {
return count;
If n is less than 7, return 0, since n clearly contains no 7s.
Otherwise, assume the problem is solved for some smaller number
} else {
int divided = n / 10;
if(n % 10 == 7) count++;
return count + count7(divided);
}
}
Remove the rightmost digit and assume that the problem is solved for what's left. That's the recursion count7(divided). Meanwhile, what about that rightmost digit? If it is 7, that needs to go into our ultimate answer, so add it in.
So far, so good.
Critique
Your structure is misleading. count at the start actually does nothing. You could have written this:
public int count7(int n) {
if(n < 7) {
return 0;
In that case there is also no need for your count++. We will add 1 if this is a 7 and not if it isn't:
} else {
int divided = n / 10;
if(n % 10 == 7) return 1 + count7(divided);
return count7(divided);
}
}
Observe that that is your answer - but it is more "honest" than what you wrote. There was nothing wrong with how you were recursing, but the presentation, I'm suggesting, can be clearer and less crabbed. Your code should read like a verbal description of the approach you are taking: "If this number is less than 7, return 0. Otherwise, pull off the last digit and recurse on what's left, adding 1 only if the number we pulled off is a 7."
There are recursion problems where you might generate a "count" value of some sort and pass it into the recursion call, but this is not one of them. Thus the whole count variable thing is just a red herring.
I have an element in a data frame tmp that may contain either a number, 0, or NA. If that element is neither 0 or NA, I would like something to happen. Otherwise, nothing happens. I imagine it'd look like this:
if ( tmp[2, 19] != (0 || NA) ){
do something
}
I get this error: Error in if (tmp[2, 19] == (0 || NA)) { : missing value where TRUE/FALSE needed. I don't know if it's not possible in R to compare something to both an int and a string or if I'm just using the OR operator wrong. I've tried different variations in different cases but haven't been able to determine the problem. Please help!
As #GSee said in a comment, you need to use is.na:
if(tmp[2, 19] != 0 || is.na(tmp[2, 19])) {
# do stuff
}
You could have discovered this yourself by reading ?"if" and ?NA.