Lisp - Logical operators - functional-programming

I am new to Lisp so this might be so simple but I am curious to know about this in any case.
I am familiar with logical operators like AND and OR but lisp does not seem to behave as expected.
For example, For (and 1 8)
Expected:
1 => 0 0 0 1
8 => 1 0 0 0
(and 1 8) => 0 0 0 0
Received:
So, the answer should have been 0
...but instead it is 8
Questions:
How is this calculation done in LISP?
Is Logical operators
fundamentally different in LISP?

In Common Lisp, AND and OR operate on boolean values, not binary digits. NIL is the only false value, anything else is considered true.
To operate on the binary representation of numbers, use LOGAND, LOGIOR, etc. These are all documented at http://clhs.lisp.se/Body/f_logand.htm.
(logand 1 8) ==> 0

In programming languages there are often two types of and and or operator. The Conditional Operators are called && and || in Algol languages and in Common Lisp they are called and and or. On the other hand the arithmetic operators &, and | have CL equivalents logand and logior.
In Common Lisp every value are booleans and with the exception of nil every other value is considered a true value. Perl is very similar except it has a couple of false values, however 1 and 8 are true values in both languages:
1 && 8 # ==> 8
1 & 8 # ==> 0
1 || 8 # ==> 1
1 | 8 # ==> 9
Same in CL
(and 1 8) ; ==> 8
(logand 1 8) ; ==> 0
(or 1 8) ; ==> 1
(logior 1 8) ; ==> 9

Related

Julia BitArray with 128 Bits

I need a Julia BitArray-like object that can encode more than 64 bits, say 128 bits. Does a simple replacement of UInt64 with UInt128 in bitarray.jl work?
Based on the information in your comment, the existing BitArray would itself serve your needs. Note that BitArray uses UInt64s internally, but that's not a limitation on the size of the array - it actually stores the bits as a Vector of UInt64s, so there's no special size limitation. You can create a 5x5x5 BitArray with no problem.
julia> b = BitArray(undef, 5, 5, 5);
julia> b .= 0;
julia> b[3, 5, 5] = 1
1
julia> b[3, :, :]
5×5 BitMatrix:
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 1
Maybe this part of the documentation threw you off:
BitArrays pack up to 64 values into every 8 bytes, resulting in an 8x space efficiency over Array{Bool, N} and allowing some
operations to work on 64 values at once.
but that's talking about internal implementation details. BitArrays are not limited to 8 bytes, so they're not limited to having just 64 values in them either.
Creating a new type of bit array using UInt128s would likely not be optimized, and is unnecessary anyway.

Stream cipher LFSR Known-Plaintext

I am currently learning cryptography,
I got different tasks. The current one features stream ciphers based on LFSR which can be solved with the Gaussian algorithm.
The cipher is: 0001 0010 01101101
I know that the first 8 bits of plaintext are all 1.
The length of n is 4.
So if I XOR them I get:
11101101
But now I am stuck and don't know how to translate it into a correct matrix.
1 1 1 0 | ?
1 1 0 1 | ?
1 0 1 1 | ?
0 1 1 0 | ?
Is this the correct way or do there only need to be 3 variables in front of the line? And where do I get the solution of the question marks from?
I hope someone can help me understanding cryptography. Thanks.

Finding matching rows

Given two matrices A and B with the same number of columns I would like to know if there are any rows which are the same in A and B. In Dyalog APL I can use the function split like this:
(↓A) ∊ ↓B
Is there a way to calculate the same result without the split function?
What you've found is a design flaw in Membership ∊ in that it implies that the right argument is a set of scalars rather than looking at it as a collection of major cells. This precluded extension according to Leading axis theory. However, Index of ⍳ was extended thus, and so we can use the fact that it returns the index beyond the end of of the lookup array when a major cell isn't found:
⎕← A ← 4 2⍴2 7 1 8 2 8 1 8
2 7
1 8
2 8
1 8
⎕← B ← 5 2⍴1 6 1 8 0 3 3 9 8 9
1 6
1 8
0 3
3 9
8 9
(↓A) ∊ ↓B
0 1 0 1
Membership ← {(≢⍵) ≥ ⍵⍳⍺}
A Membership B
0 1 0 1
Try it online!
This can also be written tacitly as Membership ← ⊢∘≢ ≥ ⍳⍨.
Either way, note that avoiding the detour of nested arrays leads to significant speed gains:
A←?1000 4⍴10
B←?1000 4⍴10
]runtime -compare "(↓A) ∊ ↓B" "A Membership B"
(↓A) ∊ ↓B → 1.6E¯4 | 0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
A Membership B → 8.9E¯6 | -95% ⎕⎕
Something like A⍳B would show not only membership but location of equal rows.

Why does Julia DIct.keys show a power of 2 values

using Julia 0.6.2
when i create a dictionary of 10 items, the array for the keys is 16, apparently rounding up to the next power of 2.
julia> dk.keys
16-element Array{Int64,1}:
0
4
9
25
100
81
0
0
16
36
64
0
49
0
0
1
when i create a dictionary with 17 keys
julia> dkk = Dict(k^2 => "*"^k for k = 1:17)
Dict{Int64,String} with 17 entries:
...
julia> dkk.keys
64-element Array{Int64,1}:
0
0
100
0
121
81
0
0
16
0
⋮
4536409040
4536409456
36
225
256
0
0
4536409904
1
why 64 instead of the next power of 2, which would be 32?
either way, i really just want the keys and not the hash table.
note: when the dictionary is access directly, the number of entries is what i'd expect.
julia> dk
Dict{Int64,String} with 10 entries:
julia> dkk
Dict{Int64,String} with 17 entries:
It's powers of 2 for some internal reason (which I would guess is due to using a tree or something like that, I don't know). Avoid directly grabbing internals. Instead, use the iterator keys(dk). If you want the keys as an array, use collect(keys(dk)).

Is preprocessing file with awk needed or it can be done directly in R?

I used to process csv file with awk, here is my 1st script:
tail -n +2 shifted_final.csv | awk -F, 'BEGIN {old=$2} {if($2!=old){print $0; old=$2;}}' | less
this script looks for repeating values in 2nd column (if value on line n is same as on line n+1, n+2 ...) and prints only first occurrence. For example if you feed following input:
ord,orig,pred,as,o-p
1,0,0,1.0,0
2,0,0,1.0,0
3,0,0,1.0,0
4,0,0,0.0,0
5,0,0,0.0,0
6,0,0,0.0,0
7,0,0,0.0,0
8,0,0,0.0,0
9,0,0,0.0,0
10,0,0,0.0,0
11,0,0,0.0,0
12,0,0,0.0,0
13,0,0,0.0,0
14,0,0,0.0,0
15,0,0,0.0,0
16,0,0,0.0,0
17,0,0,0.0,0
18,0,0,0.0,0
19,0,0,0.0,0
20,0,0,0.0,0
21,0,0,0.0,0
22,0,0,0.0,0
23,4,0,0.0,4
24,402,0,1.0,402
25,0,0,1.0,0
Then the output will be:
1,0,0,1.0,0
23,4,0,0.0,4
24,402,0,1.0,402
25,0,0,1.0,0
EDIT:
I've made this a bit challenging adding 2nd script:
The second script does the same but prints last duplicate occurrence:
tail -n +2 shifted_final.csv | awk -F, 'BEGIN {old=$2; line=$0} {if($2==old){line=$0}else{print line; old=$2; line=$0}} END {print $0}' | less
It's output will be:
22,0,0,0.0,0
23,4,0,0.0,4
24,402,0,1.0,402
25,0,0,1.0,0
I suppose R is powerful language which should handle such tasks, but I've found only questions regarding calling awk scripts from R etc. How to do this in R?
Regarding the update to your question, a more general solution, thanks to #nicola:
Idx.first <- c(TRUE, tbl$orig[-1] != tbl$orig[-nrow(tbl)])
##
R> tbl[Idx.first,]
# ord orig pred as o.p
# 1 1 0 0 1 0
# 23 23 4 0 0 4
# 24 24 402 0 1 402
# 25 25 0 0 1 0
If you want to use the last occurrence of a value in a run, rather than the first, just append TRUE to #nicola's indexing expression instead of prepending it:
Idx.last <- c(tbl$orig[-1] != tbl$orig[-nrow(tbl)], TRUE)
##
R> tbl[Idx.last,]
# ord orig pred as o.p
# 22 22 0 0 0 0
# 23 23 4 0 0 4
# 24 24 402 0 1 402
# 25 25 0 0 1 0
In either case, tbl$orig[-1] != tbl$orig[-nrow(tbl)] is comparing the 2nd through nth values in column 2 with the 1st through n-1th values in column 2. The result is a logical vector, where TRUE elements indicate a change in consecutive values. Since the comparison is of length n-1, pushing an extra TRUE value to the front (case 1) will select the first occurrence in a run, whereas adding an extra TRUE to the back (case 2) will select the last occurrence in a run.
Data:
tbl <- read.table(text = "ord,orig,pred,as,o-p
1,0,0,1.0,0
2,0,0,1.0,0
3,0,0,1.0,0
4,0,0,0.0,0
5,0,0,0.0,0
6,0,0,0.0,0
7,0,0,0.0,0
8,0,0,0.0,0
9,0,0,0.0,0
10,0,0,0.0,0
11,0,0,0.0,0
12,0,0,0.0,0
13,0,0,0.0,0
14,0,0,0.0,0
15,0,0,0.0,0
16,0,0,0.0,0
17,0,0,0.0,0
18,0,0,0.0,0
19,0,0,0.0,0
20,0,0,0.0,0
21,0,0,0.0,0
22,0,0,0.0,0
23,4,0,0.0,4
24,402,0,1.0,402
25,0,0,1.0,0",
header = TRUE,
sep = ",")
For the (updated) question, you could use for example (thanks to #nrussell for his comment and suggestion):
idx <- c(1, cumsum(rle(tbl[,2])[[1]])[-1])
tbl[idx,]
# ord orig pred as o.p x
#1 1 0 0 1 0 1
#23 23 4 0 0 4 2
#24 24 402 0 1 402 3
#25 25 0 0 1 0 4
It will return the first row of each 'block' of identical values in column orig.
rle(tbl[,2])[[1]] computes the run lengths of each new (different than previous) value that appears in column orig
cumsum(...) computes the cumulative sum of those run lengths
finally, c(1, cumsum(...)[-1]) replaces the first number in that vector with a 1, so that the very first line of the data will always be present

Resources