Can someone help me with the method behind this shell script? - linux

Can someone help me with the method behind this linux command? I know what the outputs are, just need to know how you figure them out.
#!/bin/sh
i=0
for a in 9 8 7 6 5 4
do
j=1
for b in 1 2 3 4
do
let "j+=2"
done
let "i+=1"
done
echo "i=$i j=$j"

Fist, indenting helps make it clearer:
#!/bin/sh
i=0
for a in 9 8 7 6 5 4
do
j=1
for b in 1 2 3 4
do
let "j+=2"
done
let "i+=1"
done
echo "i=$i j=$j"
The a and b variables are never used, other than to make the outer loop execute 6 times (one loop for each number in the list 9 8 7 6 5 4) and to make the inner loop execute 4 times (one loop for each number in the list 1 2 3 4).
The outer loop adds 1 to the value of i (initialized to zero) each of the 6 times through the loop, ending up with a value of 6.
The inner loop adds 2 to the value of j each of the 4 times through the loop. Even though the inner loop itself is executed 6 times, since j is re-initialized to 1 before each execution of the inner loop, the final value of j is only 9 (1+2+2+2+2).

Related

How do I repeat this process for different values or cases?

How can I use for loop here for multiple cases:
s=int(input())
a=[]
for j in range(0,s):
b,n = map(int, input().split())
for i in range(b,n+1):
c=i*(-1)**i
a.append(c)
print(sum(a))
I want the output such like:
input
5
1 3
2 5
5 5
4 4
2 3
Output
-2
-2
-5
4
-1
but when I use the for loop, I get a result like this:
5
1 3
-2
5 5
-7
2 5
-9
7 5
-9
1 5
-12
You have made a very small error in your code. To get the results you want you would need to use
s=int(input())
for j in range(0,s):
a=[]
b,n = map(int, input().split())
for i in range(b,n+1):
c=i*(-1)**i
a.append(c)
print(sum(a))
In this case you reset the value of the array a in each outer loop instead of persisting it through the whole program.
You can check the results of the same on this TIO link here. The output is as expected for the example provided

post-order traversal binary tree right to left

I know what the output would be when we traverse a binary tree with a post order algorithm from left to right, however I am having a bit of trouble seeing what it would be when we go from right to left.
For example, would the output of a post order traversal of the following tree be "9 9 8 7 3 2 1 2 6 7"? Or would it be "9 9 7 8 3 2 1 2 6 7"? Or am I wrong in both cases?
7
3 9
2 6 8 9
1 2 7
Assuming your tree is simplebinary tree instead of binary search tree your output should be -
9 8 9 7 6 2 1 2 3 7
Actually you can simply use this function to get post order from right to left-
void post(struct Node*root){
if(root==NULL)
return;
if(root->right)
post(root->right);
if(root->left)
post(root->left);
printf("%d ",root->data);
}
whereprintfis function to print data if you dont know C.

Average from different columns in shell script

I have a datafile with 10 columns as given below
ifile.txt
2 4 4 2 1 2 2 4 2 1
3 3 1 5 3 3 4 5 3 3
4 3 3 2 2 1 2 3 4 2
5 3 1 3 1 2 4 5 6 8
I want to add 11th column which will show the average of each rows along 10 columns. i.e. AVE(2 4 4 2 1 2 2 4 2 1) and so on. Though my following script is working well, but I would like to make it more simpler and short. I appreciate, in advance, for any kind help or suggestions in this regard.
awk '{for(i=1;i<=NF;i++){s+=$i;ss+=$i}m=s/NF;$(NF+1)=ss/NF;s=ss=0}1' ifile.txt
This should work
awk '{for(i=1;i<=NF;i++)x+=$i;$(NF+1)=x/NF;x=0}1' file
For each field you add the value to x in the loop.
Next you set field 11 to the sum in xdivided by the number of fields NF.
Reset x to zero for the next line.
1 equates to true and performs the default action in awk which is to print the line.
is this helping
awk '{for(i=1;i<=NF;i++)s+=$i;print $0,s/NF;s=0}' ifile.txt
or
awk '{for(i=1;i<=NF;i++)ss+=$i;$(NF+1)=ss/NF;ss=0}1' ifile.txt

How to remove an element from a list in J by index?

The rather verbose fork I came up with is
({. , (>:#[ }. ]))
E.g.,
3 ({. , (>:#[ }. ])) 0 1 2 3 4 5
0 1 2 4 5
Works great, but is there a more idiomatic way? What is the usual way to do this in J?
Yes, the J-way is to use a 3-level boxing:
(<<<5) { i.10
0 1 2 3 4 6 7 8 9
(<<<1 3) { i.10
0 2 4 5 6 7 8 9
It's a small note in the dictionary for {:
Note that the result in the very last dyadic example, that is, (<<<_1){m , is all except the last item.
and a bit more in Learning J: Chapter 6 - Indexing: 6.2.5 Excluding Things.
Another approach is to use the monadic and dyadic forms of # (Tally and Copy). This idiom of using Copy to remove an item is something that I use frequently.
The hook (i. i.##) uses Tally (monadic #) and monadic and dyadic i. (Integers and Index of) to generate the filter string:
2 (i. i.##) 'abcde'
1 1 0 1 1
which Copy (dyadic #) uses to omit the appropriate item.
2 ((i. i.##) # ]) 0 1 2 3 4 5
0 1 3 4 5
2 ((i. i.##) # ]) 'abcde'
abde

slicing table into two parts and box it afterwards

I have a table like the following
0 1 2 3
4 5 6 7
8 9 10 11
and I want to make the following structure.
┌──────┬──┐
│0 1 2│ 3│
│4 5 6│ 7│
│8 9 10│11│
└──────┴──┘
Could anyone please help me?
And in J there is always another way!
]a=. i. 3 4
0 1 2 3
4 5 6 7
8 9 10 11
('' ;1 0 0 1) <;.1 a
┌──────┬──┐
│0 1 2│ 3│
│4 5 6│ 7│
│8 9 10│11│
└──────┴──┘
This uses the dyadic cut conjunction (;.) with the general form of x u ;. n y
y is the argument that we would like to partition, x specifies where the partitions are to be put, n is positive if we would like the frets (the partition positions) included in the result and a value of 1 means that we work from left to right, and u is the verb that we would like to apply to the partition.
One tricky point:
x is ('';1 0 0 1) because we want the entire first dimension of the array (rows) after which the 1's indicate the partition start. In this case we take all the rows and make the first partition the first 3 columns, and the final 1 makes the last partition its own column.
There is much going on in this solution, and that allows it to be used in many different ways, depending on the needs of the programmer.
The title of your question ("slicing table into two parts and box it afterwards") suggests that the example you sketch may not reflect what you want to learn.
My impression is that you think of your resulting noun as a two-axis table boxed into two sections. The main problem with that interpretation is that boxes divide their contents very thoroughly. It takes special effort to make the numbers in your second box look like they've been trimmed from the structure in the first box. Such effort is rarely worthwhile.
If it is natural to need to take the 3 7 11 and remove it as a unit from the structure in which it occurs, there is an advantage to making it a row of the table, rather than a column. A 2-axis table is always a list of 1-axis lists. If your problem is a matter of segregating items, this orientation of the atoms makes it simpler to do.
Putting this into practice, here we deal with rows instead of columns:
aa=: |:i.3 4
aa
0 4 8
1 5 9
2 6 10
3 7 11
(}: ; {:) aa
+------+------+
|0 4 8|3 7 11|
|1 5 9| |
|2 6 10| |
+------+------+
The program, in parentheses, can be read literally as "curtail link tail". This is the sort of program I'd expect from the title of your question.
Part of effective J programming is orienting the data (nouns) so that they are more readily manipulated by the programs (verbs).
Here is one way:
]a=: i. 3 4
0 1 2 3
4 5 6 7
8 9 10 11
3 ({."1 ; }."1) a
┌──────┬──┐
│0 1 2│ 3│
│4 5 6│ 7│
│8 9 10│11│
└──────┴──┘
In other words "take the first 3 items in each row of a and Link (;) with the result of dropping the first 3 items in each row of a"
Other methods and/or structures may be more appropriate depending on the exact use case.

Resources