Pascal - Order Of Operations - math

I have a simple yet irritating problem.
When I execute the code below and write 10 for 'a' I get 1010 as a result,
but I really don't know how, if i try solve this problem by myself.
In know the order of operations, but I'm kinda stuck, like I'd overlook something.
Please, give me a kick-start. I would be very grateful.
program task1 (input,output);
var
a, b, c : integer;
begin
b := 0;
c := 1;
readln(a);
while a > 0 do
begin
b := b + c * (a mod 2);
a := a div 2;
c := c * 10;
end;
writeln(b)
end.

Here is what the program calculates. The table has the assignment of b on a separate line, followed by the assignments of a and c on the same line:
a b c
10 0 1 Initialization
0 10 mod 2 = 0
5 10
10 5 mod 2 = 1; 0 + 10 * 1 = 10
2 100
10 2 mod 2 = 0
1 1000
1010 1 mod 2 = 1; 10 + 1000 * 1 = 1010
0 10000

Related

R: Problem using a for loop to modify existing variables in a data.table; the loop does not affect the row filtering

The task that I want to complete is the following:
I have a dataset with hundreds of variables. I need to recode all of them following the same logic. The logic is the following: if the GIVEN VARIABLE == 0 & a SPECIFIC VARIABLE == 1, the GIVEN VARIABLE must = -1. The SPECIFIC VARIABLE is the same for all of them.
What I have done is the following:
set.seed(123)
data=data.table(a = 0:10, b= 0:10, c = 0:10, d = 1:0)
Here "d" is the SPECIFIC VARIABLE and a:c are the GIVEN VARIABLEs
list_variables <- names(data)
list_variables_v2 <- list_variables[-c(4)]
I extracted the names of the variables from the dataset (minus d) and put them on a list, so they can be fed into the loop
data_v1 = copy(d)
for(i in (list_variables_v2)) {
data_v1[(i) == 0 & d == 1, (i) := -1]
}
Problematically, when I run the loop nothing happens. Those variables that comply with the condition (e.g. a == 0 & d == 1) are not recoded as -1. Various problems could be happening, but I think I have reduced them to one. Potential problems:
a) The code, even outside the loop, does not work. But this is not true. The following code produces the expected result:
data_v1[a == 0 & d == 1, a := -1]
b) The loop is not working, hence, the variable names are not really sorted and recognized. Nonetheless, if I exclude the (i) == 0 condition, the code does work, implying that the loop works for the right side:
for(i in (list_variables_v2)) {
data_v1[d == 1, (i) := -1]
}
I think that the root of the problem is that R, in the row filtering side, is not recognizing (i) == 0 as e.g. a == 0. This is quite weird given that R, when dealing with the right side (columns), does recognize that (i) := -1 as e.g. a := -1. Any idea of what might be causing this and, hopefully, how to solve it?
Again, many many thanks, and please let me know if something is unclear or repeated.
A simple correction would be to wrap with get
for(i in (list_variables_v2)) {
data_v1[get(i) == 0 & d == 1, (i) := -1]
}
-output
> data_v1
a b c d
<int> <int> <int> <int>
1: -1 -1 -1 1
2: 1 1 1 0
3: 2 2 2 1
4: 3 3 3 0
5: 4 4 4 1
6: 5 5 5 0
7: 6 6 6 1
8: 7 7 7 0
9: 8 8 8 1
10: 9 9 9 0
11: 10 10 10 1
> data
a b c d
<int> <int> <int> <int>
1: 0 0 0 1
2: 1 1 1 0
3: 2 2 2 1
4: 3 3 3 0
5: 4 4 4 1
6: 5 5 5 0
7: 6 6 6 1
8: 7 7 7 0
9: 8 8 8 1
10: 9 9 9 0
11: 10 10 10 1

R - Using the output of compare_df() to update original data frame

I have 3 questions relating to the compare_df() function within the compareDF CRAN package.
I have two data frames with identical structures but different contents (this_week and last_week):
this_week
Week A B C
1 1 0 0 0
2 2 0 1 0
3 3 0 1 0
4 4 2 1 0
5 5 2 0 0
last_week
Week A B C
1 1 0 0 0
2 2 0 0 0
3 3 0 0 1
4 4 3 0 0
5 5 0 0 0
I am using compare_df(this_week, last_week, group_col = "Week") to compare these two data frames. Specifically, I am interested in the second of the compare_df() function outputs which gives cell-level comparisons.
The output shows which cells have increased from one week to the next:
weeks_compared <- compare_df(this_week, last_week, group_col = "Week")
weeks_compared
$comparison_df
Week chng_type A B C
1 2 + 0 1 0
2 2 - 0 0 0
3 3 + 0 1 0
4 3 - 0 0 1
5 4 + 2 1 0
6 4 - 3 0 0
7 5 + 2 0 0
8 5 - 0 0 0
$comparison_table_diff
Week chng_type A B C
1 = + = + =
2 = - = - =
3 = + = + +
4 = - = - -
5 = + + + =
6 = - - - =
7 = + + = =
8 = - - = =
Interestingly, row 5 and 6 do not provide the comparison results that I would expect. I would expect:
row 5, column 3 ("A") of the second dataframe ($comparison_table_diff) to be "-"
row 6, column 3 ("A") to be "+".
However, it is actually the opposite way around:
$comparison_df
Week chng_type A B C
5 4 + 2 1 0
6 4 - 3 0 0
$comparison_table_diff
Week chng_type A B C
5 = + + + =
6 = - - - =
1) Does anyone know why this happens?
In addition, I do not know how to use this output further. My aims are:
2) To update the old data which has increased in last_week
3) To add an asterisk to the last_week data which has increased (in columns "B" and "C" only)
I have not found anything related to actually using the compare_df() outputs on Stack Overflow other than to simply paste these tables, which isn't sufficient for my task.
I wondered if anyone has done anything similar and/or could share some ideas of how I might go about reaching these two aims. Alternatively, would be interested to know if there is a better package to use/workaround for this task. And of course, let me know if there is any further information that's required.
Thanks in advance for any help you can provide!

Iteration methods for a recursive sequence

How would the recursive sequence a(n)=-a(n-1)+n-1 be solved?
I tried forward and backward iterations but haven't been able to get a explicit solution for a(n).
Your first step should be to write out a result table
f(n)=x
n | x
-----
0 | 7
1 | -7 (-7 + 1 - 1)
2 | 8 ( 7 + 2 - 1)
3 | -6 (-8 + 3 - 1)
4 | 9 ( 6 + 4 - 1)
5 | -5 (-9 + 5 - 1)
6 | 10 ( 5 + 6 - 1)
7 | -4 (-10 + 7 - 1)
8 | 11 ( 4 + 8 - 1)
9 | -3 (-11 + 9 - 1)
You should see a pattern emerging. Each pair of solutions [(0, 1), (2, 3), (4, 5), ...] have a difference of 14, starting with (7, -7) and incrementing one every two points of n. We can generalize this:
f(0) = 7
f(n) = 7 + k - 14 * b
where k is the increment value (each 1 k per 2 n)
b is 1 when n is odd, else 0.
Now we just have to define k and b in terms of n. k shouldn't be too hard, let's see:
n | k
0 | 0
1 | 0
2 | 1
3 | 1
Does that remind you of anything? That's a floored div2.
7 + (n // 2) - 14 * b
Now for b
n | b
0 | 0
1 | 1
2 | 0
3 | 1
That looks like mod 2 to me! Modulo is the remainder of a division problem, and is a great way to check if a number is even or odd. We're looking for the plain modulo, too, since we want b==1 when n is odd and vice versa.
f(0) = 7
f(n) = 7 + (n // 2) - 14 * (n%2)
where (//) is the floor division function
(%) is the modulo function
Now we can put that all together in a function. In Go this is:
func f(n int) int {
return 7 + n/2 - 14 * (n % 2)
}
In Python it's
def f(n):
return 7 + n//2 - 14 * (n%2)
In Haskell we've got
f :: Int -> Int
f n = 7 + n `div` 2 - 14 * (n `mod` 2)
or, since Haskell implements recursion exceedingly well, simply...
f :: Int -> Int
f 0 = 7
f n = f (n-1) + n - 1

How to count combinations of elements in a data set?

I have an order data set in the following format:
Ordernumber; Category; # Sold Items
123; A; 3
123; B; 4
234; B; 2
234; C; 1
234; D; 5
...
So, every order has as many lines as there were different categories in the order.
Now, I want to count for every category pair how often they were ordered together in one order.
In the end I would like to have a "correlation" matrix like this
A B C D
A 1
B 1 1 1
C 1 1
D 1 1
Has anyone a good (simple) idea?
Thank you so much!
Perhaps using matrix multiplication gets you there:
dat <- read.table(header=T, text="Ordernumber; Category; Sold Items
123; A; 3
123; B; 4
234; B; 2
234; C; 1
234; D; 5", sep=";")
tt <- table(dat[1:2])
crossprod(tt) # t(tt) %*% tt
# Category
#Category A B C D
# A 1 1 0 0
# B 1 2 1 1
# C 0 1 1 1
# D 0 1 1 1
This has the diagonal but can easily be removed with diag

Apply in R: recursive function that operates on its own previous result

How do I apply a function that can "see" the preceding result when operating by rows?
This comes up a lot, but my current problem requires a running total by student that resets if the total doesn't get to 5.
Example Data:
> df
row Student Absent Consecutive.Absences
1 A 0 0
2 A 1 1
3 A 1 2
4 A 0 0 <- resets to zero if under 5
5 A 0 0
6 A 1 1
7 A 1 2
8 A 1 3
9 B 1 1 <- starts over for new factor (Student)
10 B 1 2
11 B 0 0
12 B 1 1
13 B 1 2
14 B 1 3
15 B 1 4
16 B 0 0
17 B 1 1
18 B 1 2
19 B 1 3
20 B 1 4
21 B 1 5
22 B 0 5 <- gets locked at 5
23 B 0 5
24 B 1 6
25 B 1 7
I've tried doing this with a huge matrix of shifted vectors.
I've tried doing this with the apply family of functions and half of them do nothing, the other half hit 16GB of RAM and crash my computer.
I've tried straight looping and it takes 4+ hours (it's a big data set)
What bothers me is how easy this is in Excel. Usually R runs circles around Excel both in speed and writability, which leads me to believe I'm missing something elementary here.
Forgetting even the more challenging ("lock at 5") feature of this, I can't even get a cumsum that resets. There is no combination of factors I can think of to group for ave like this:
Consecutive.Absences = ave(Absent, ..., cumsum)
Obviously, grouping on Student will just give the Total Cumulative Absences -- it "remembers" the kid's absence over the gaps because of the split and recombine in ave.
So as I said, the core of what I don't know how to do in R is this:
How do I apply a function that can "see" the preceding result when operating by rows?
In Excel it would be easy:
C3 = IF($A3=$A2,$B3+$C2,$B3)*$B3
This excel function is displayed without the 5-absence lock for easy readability.
Once I figure out how to apply a function that looks at previous results of the same function in R, I'll be able to figure out the rest.
Thank you in advance for your help--this will be very useful in a lot of my applications!
Genuinely,
Sam
UPDATE:
Thank you everyone for the ideas on how to identify if a student has 5 consecutive absences!
However, that's easy enough to do in the database at the STUDENTS table. What I need to know is the number of consecutive absences by student in the attendance record itself for things like, "Do we count this particular attendance record when calculating other summary statistics?"
If you're looking to apply a function to every element in a vector while making use the previous element's value, you might want to check out "Reduce", with the accumulate parameter set to True
Here's an example:
##define your function that takes two parameters
##these are the 'previous' and the 'current' elements
runSum <- function(sum, x){
res = 0
if (x == 1){
res = sum + 1
}
else if (x == 0 & sum < 5){
res = 0
}
else{
res = sum
}
res
}
#lets look at the absent values from subject B
x = c(1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1)
Reduce(x=x, f=runSum, accumulate=T)
# [1] 1 2 0 1 2 3 4 0 1 2 3 4 5 5 5 6 7
It's fairly easy to identify the students with one or more runs of 5:
tapply(dfrm$Absent, dfrm$Student, function(x) rle(x)$value[rle(x)$length >=5] )
$A
integer(0)
$B
[1] 1
Look for any values of "1" in the result:
tapply(dfrm$Absent, dfrm$Student, function(x) 1 %in% rle(x)$value[rle(x)$length >=5] )
A B
FALSE TRUE
I also struggled through to a Reduce solution (but am second in priority to #kithpradhan):
ave(dfrm$Absent, dfrm$Student,
FUN= function(XX)
Reduce(function(x,y) if( x[1] >= 5){ y+x[1]
} else{ x[1]*y+y } , #Resets to 0 if y=0
XX, accumulate=TRUE)
)
#[1] 0 1 2 0 0 1 2 3 1 2 0 1 2 3 4 0 1 2 3 4 5 5 5 6 7
For the record, you can also create your own Reduce-derivative which receives f and x, and applies f(x) on its output until x == f(x) or maxiter is reached:
ireduce = function(f, x, maxiter = 50){
i = 1
while(!identical(f(x), x) & i <= maxiter) {x = f(x); i = i+1}; x
}

Resources