What does this variable notation mean ? a[++b]=$c - bash

I have seen this notation in bash:
a=${b[c--]}
or also
a[++b]=$c
or the other way around:
a[b++]=$c
but if I execute it on the command line nothing happens.
OSX#26:~ $ a[++b]=2
OSX#27:~ $ echo ${a[++b]}
OSX#28:~ $
What is the use of this notation ?
Edit:
I am asking about this notation. As I have seen it it is a variable, because of the $ in front. But ++ does remind me of increment, so I am confused. Is this some sort of variable increment ?

c-- is an arithmetic expression, it means "return the value of c and then decrement it by 1". ${b[n]} denotes the n-th element of the array b (where the first element has index 0). Expressions inside the square brackets are interpreted as arithmetic (with some exceptions like *, #, '1' etc.) Let's try it:
b=(x y z)
c=2
a=${b[c--]}
echo $a $c # Outputs: z 1
so c-- returns 2, but sets c to 1. b[2], i.e. z, is then assigned to a.
++c is similar to c--, but it adds 1 to c before returning its value.

Related

Abort evaluation of boolean RPN expression

I have a few boolean expression in RPN-Format like this:
{0} {1} {2} AND OR // equals: {0} or {1} and {2}
Computing the boolean variables {x} is very expensive. And obviously there is no need to compute {1} and {2} if {0} is already true, since the expression will alway evaluation to true in this case.
How can I detect beforehand which boolean variables I have to evaluate first to abort the evaluation of the expression with as few variables evaluated as possible?
I want to know which variables with a definite value will evaluate the whole expression to be true or false.
You should prefer to evaluate expressions where the expected number of sub-expression evaluations is lower.
a and (b or c or d)
You should first evaluate a - since if it false - you're done
a or (b and c and d)
Again, you should first evaluate a - since if it is true - you're done
(a or b) and (c or d or e)
First, evaluate (a or b) - since if it is false - you're done
etc.
To implement:
Build a tree where the root is an or if your expression has the form "expr or expr or expr or ...". Alternatively if your expression has the form "expr and expr and expr and ..." - the root should be an and.
Build the sub-trees recursively. The levels or the trees are and / or alternatively. The number of children or each node varies (2 or more except leafs).
Evaluate recursively by selecting the sub-tree with the minimal number of children and evaluate it first.
Algorithm
One approach is to first expand the boolean expression, and then factorize.
The common factors will tell you which variables can force the expression to be false.
Then you can invert the expression and repeat to find the variables that will force the expression to be true.
Example 1
This should become clearer with an example, I'll write + for OR and . for AND:
0 + 1.2
this is already expanded. There is no common factor so there is no way a single variable can force this to be true.
Next we invert and expand using De Morgan's laws:
!(0 + 1.2)
= !0.!(1.2)
= !0.(!1 + !2)
This has a factor of !0, i.e. if 0 is false, we can conclude that the whole expression is false.
Example 2
1.2 + 1.3
= 1.(2 + 3)
so if 1 is false, the whole expression is false.
!(1.2 + 1.3)
=!(1.2).!(1.3)
=(!1 + !2).(!1 + !3)
=!1 + !2.!1 + !2.!3
This has no common factor so there is no one variable that can force the expression to be true.
Convert your expression into a minimized sum-of-product form.
This can be done by using a Karnaugh-Veitch map for small expressions. More involved methods are described here.
In your example, you get one term a (your {0}) with a single literal and a second term cb ({1}{2} in your notation) with two literals. For every input variable, count the terms affected by this variable.
A simple count would not take into account that terms may be large (many literals) or small (few literals). Therefore, you might weight the terms with the number of Karnaugh cells covered by the respective cell.
The counting result (a:1x4, b:1x2, c:1x2) tells you which variable should be evaluated first. The evaluation ends, once a single term becomes true or all terms are evaluated to false.

bash arithmetic expressions with variables

I am having troubles with the arithmetic expressions in a bash file (a unix file .sh).
I have the variable "total", which consists of a few numbers separated by spaces, and I want to calculate the sum of them (in the variable "dollar").
#!/bin/bash
..
dollar=0
for a in $total; do
$dollar+=$a
done
I know I am missing something with the arithmetic brackets, but I couldn't get it to work with variables.
Wrap arithmetic operations within ((...)):
dollar=0
for a in $total; do
((dollar += a))
done
There are a number of ways to perform arithmetic in Bash. Some of them are:
dollar=$(expr $dollar + $a)
let "dollar += $a"
dollar=$((dollar + a))
((dollar += a))
You may see more on the wiki. If you need to handle non-integer values, use a external tool such as bc.

How do you make a range in bash case sensitive?

I'm trying to use a for loop like this, where the range consists of letters, both uppercase and lowercase. The problem is, bash doesn't differentiate uppercase and lowercase when it's within a range. How do I make it case sensitive? TIA.
for s in {a..z,A..Z}
do
echo ${s}
done
If you want the letters in that order, just use:
for s in {a..z} {A..Z}
There's no requirement that bash only allows a single brace expansion per line.
The two forms currently allowed are mutually exclusive, being either a selection (of two or more) or a range:
{<val1>,<val2>[,...]}
{<from>..<to>[..<incr>]}
The brace expression {a..z,A..Z} simply expands, using the first form, to the two words (not ranges):
a..z
A..Z
Looks like you got the syntax wrong.
$ echo $BASH_VERSION
3.2.25(1)-release
$ echo {a..k} {A..K}
a b c d e f g h i j k A B C D E F G H I J K
$ echo {a..k,A..K}
a..k A..K

Lambda calculus entire expression substitution

About substitution of free occurances: can we have a substitution of an entire expression(function, application), or just of a variable:
Example:
Current expression \x.\y.(y, z)
Expression to be replaced: \y.(y z) with p so we will have \x.p.
Is it possible?
Yes, it is possible. One way is to consider the substitution of occurrences. An occurrence is a string over the set {1,2,3}, and for every lambda-term M, the sub-expression M/u at occurrence u is defined as:
M/[] = M
M/0u = N/u, if M=\x. N
M/1u = P/u, if M=PQ
M/2u = Q/u, if M=PQ
(I use the symbol [] to denote the empty string.)
Now define the substitution M[u := N] as the term obtained from replacing the occurrence u with N in M. I've seen this kind of substitution in some of P.-L. Curien work.

In Go, how to write a multi-line statement?

In python, we use backslash to indicate that the current statement continues to next line
for example,
a = b + c + s \
+ x + y
or simply,
a = b + c + s +
x + y
Is it possible to do that in Go language? Thanks
Sure it is, just put an operator at the end, for example:
a = b + c + s +
x + y
Also note that it's not possible to break the line before the operator. The following code is invalid:
a = b + c + s
+ x + y
The rule is described here and in the specification.
Interestingly, the the Go language specification itself requires semicolons at the end of each statement, but the lexer will insert implicit semicolons at the end of lines that look like statements immediately before compilation.
Therefore, to prevent the unwanted semicolon at the end of an unfinished line, all you need to do is ensure that the line doesn't end with something that could make it look like a complete statement.
In other words, avoid ending an incomplete line in a variable, constant, function, keyword, or postfix operator (e.g. ++).
What does that leave? Well, a few things come to mind -- an infix operator (e.g. = or +), a comma, or an opening paren or brace or bracket, for example.

Resources