Tricky conditional maths - math

This one is tricky to me:
I have four groups of 8 LEDs. A is 1-8, B is 9-16, C is 17-24, and D is 25-32.
I'm trying to figure out how to write a conditional where
i = 0 //this would be the LED number
loop {
i = //gets updated here
if (i is in the first group) {
// do stuff
} else {
//do other stuff
}
}
Basically, I need to check an LED before it is turned off to see if it is in the same group as the new LED that is being lit.
If it is in the same group, it will be turned off, if it is NOT in the same group it needs to stay on.
So math-wise I need to see if the number is between a certain range. I guess I could just write four versions
if (i >=8)
...
if(i <=9 && >=16)
...
etc, but that doesn't seem very tidy...

Use integer division. Subtract 1 from both values then integer divide by 8. If they're the same result then both LEDs are in the same bank.
def samebank(i, j):
return ((i - 1) // 8) == ((j - 1) // 8)

GetLedGroup(i)
string[] arrLed = {"A","B","C","D"};
return arrLed[Math.floor(i/8)-1];

Related

Unable to understand how this recursive function evaluates

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.

Compare function ( ==, all.equal) is not working properly when it comes to two digit numbers in R?

I am trying to compare two number in my code, when it comes to compare one digit number , it works fine whether I use == or all.equall function, but when it comes to comparing 2 digit number or more like 17, it can't say they are the same, I have already go through this thread and all.equall is not working as well. beside my numbers are all integers. can any one tell me what the problem is here ?
I'll put the code here so the problem can be reproducible.
library(igraph)
node1<- c(1,1,1,2,2,2,3,3,4,4,5,5,7,8,9,9,10,12,14,14,17,17,19)
node2<-c(2,3,4,5,6,17,12,14,7,8,6,13,14,9,10,11,11,13,16,15,18,19,20)
AZADEH_GRAPH.data <- data.frame(node1,node2)
dataframe_AZADEH_GRAPH<-AZADEH_GRAPH
graph_AZADEH_GRAPH=graph.data.frame(dataframe_AZADEH_GRAPH,directed=FALSE)
Nodes1_AZADEH_GRAPH<- replicate(vcount(graph_AZADEH_GRAPH), 0)
SuperEgo_AZADEH_GRAPH<- list()
Com_AZADEH_GRAPH<- list()
community_member <-matrix()
neghbor_list<-list()
count_neighbors<-list()
community_1<-list()
SuperEgo_AZADEH_GRAPH[[2]]=make_ego_graph(graph_AZADEH_GRAPH,2,
V(graph_AZADEH_GRAPH)$name[2],
mode = "all",mindist = 0)
Com_AZADEH_GRAPH[[2]] <- cluster_infomap(SuperEgo_AZADEH_GRAPH[[2]][[1]])
community_member<-data.matrix(membership(Com_AZADEH_GRAPH[[2]]))
neghbor_list[2]=ego(graph_AZADEH_GRAPH, order = 1,
nodes = V(graph_AZADEH_GRAPH)$name[2], mode = "all",mindist = 1)
count_neighbors[2]=length(neghbor_list[[2]])
for (k in 1:nrow(community_member))
{
RRR<-cbind(community_member,as.integer(rownames(community_member)[k]))
}
for (n in 1:nrow(RRR))
{
RRR[n,2]<-as.integer(rownames(RRR)[n])
}
for (i in 1: length(neghbor_list[[2]]))
{
for (j in 1:nrow(RRR))
{
if (neghbor_list[[2]][i]==RRR[[j,2]])
{
community_1[i]=RRR[[j,1]]
}
}
}
the problem is with if statements and more specifically when i=3 and j=6 neghbor_list[[2]][3],
RRR[[6,2]] both return 17 but still it gives False it is working fine when i=1 & 2
(Posted solution on behalf of the question author).
The issue is found, it was referring to the indexes, I should have use $name instead after neghbor_list[[2]][3].

How to find a pair of numbers in a list given a specific range?

The problem is as such:
given an array of N numbers, find two numbers in the array such that they will have a range(max - min) value of K.
for example:
input:
5 3
25 9 1 6 8
output:
9 6
So far, what i've tried is first sorting the array and then finding two complementary numbers using a nested loop. However, because this is a sort of brute force method, I don't think it is as efficient as other possible ways.
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(), k = sc.nextInt();
int[] arr = new int[n];
for(int i = 0; i < n; i++) {
arr[i] = sc.nextInt();
}
Arrays.sort(arr);
int count = 0;
int a, b;
for(int i = 0; i < n; i++) {
for(int j = i; j < n; j++) {
if(Math.max(arr[i], arr[j]) - Math.min(arr[i], arr[j]) == k) {
a = arr[i];
b = arr[j];
}
}
}
System.out.println(a + " " + b);
}
}
Much appreciated if the solution was in code (any language).
Here is code in Python 3 that solves your problem. This should be easy to understand, even if you do not know Python.
This routine uses your idea of sorting the array, but I use two variables left and right (which define two places in the array) where each makes just one pass through the array. So other than the sort, the time efficiency of my code is O(N). The sort makes the entire routine O(N log N). This is better than your code, which is O(N^2).
I never use the inputted value of N, since Python can easily handle the actual size of the array. I add a sentinel value to the end of the array to make the inner short loops simpler and quicker. This involves another pass through the array to calculate the sentinel value, but this adds little to the running time. It is possible to reduce the number of array accesses, at the cost of a few more lines of code--I'll leave that to you. I added input prompts to aid my testing--you can remove those to make my results closer to what you seem to want. My code prints the larger of the two numbers first, then the smaller, which matches your sample output. But you may have wanted the order of the two numbers to match the order in the original, un-sorted array--if that is the case, I'll let you handle that as well (I see multiple ways to do that).
# Get input
N, K = [int(s) for s in input('Input N and K: ').split()]
arr = [int(s) for s in input('Input the array: ').split()]
arr.sort()
sentinel = max(arr) + K + 2
arr.append(sentinel)
left = right = 0
while arr[right] < sentinel:
# Move the right index until the difference is too large
while arr[right] - arr[left] < K:
right += 1
# Move the left index until the difference is too small
while arr[right] - arr[left] > K:
left += 1
# Check if we are done
if arr[right] - arr[left] == K:
print(arr[right], arr[left])
break

Recursion confusion with local variables

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;
}

trying to learning details of recursion

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.

Resources