How is ordered a Dictionary in Pharo? - dictionary

Let's say we have a loop that enters Associations to a Dictionary in a clear order:
| d |
d := Dictionary new: 10.
1 to: 10 do: [ :i |
d add: i -> (i + 9 printStringBase: 20)
].
d
When I evaluate this code I get a Dictionary in a "twisted" order:
9 -> I
5 -> E
1 -> A
10 ->J
6 -> F
2 -> B
7 -> G
3 -> C
8 -> H
4 -> D
Each time a Dictionary with the same entry data is created it have the same order, so I assume it is a feature not a bug ..?
I use Pharo v9.0.21.

A Dictionary is not an ordered collection. Instead it is a keyed collection, keeping key-value pairs.
There is an OrderPreservingDictionary for you to use: https://github.com/pharo-contributions/OrderPreservingDictionary

In addition to this other answer is is worth explaining the apparent disorder shown in the question.
Firstly observe that Dictionary new: 10 will create a new instance of Dictionary with capacity for a prime number p of associations greater than 10. Say 11, 13, 17, whatever.
Secondly, for every association added, the dictionary will compute the hash value of the key and deduce the location from its remainder modulo p.
Since all keys occurring in the example are instances of SmallInteger, their hashes will be themselves(*). And since these are smaller than p, they will equal the modulo and hence be stored in the slots derived from their values in some implementation-dependent way.
Finally, the printing method is free to enumerate the associations in any order.
(*) While this is true in some dialects, I've checked in Pharo and this is not true, 3 hash is not 3 etc. which explains the "twisting" in the case of Pharo.

For completeness of the answer there is such thing as ordered Dictionary.
At Smalltalk/X the #OrderedDictionary is defined as:
Dictionary subclass:#OrderedDictionary
instanceVariableNames:'order'
classVariableNames:''
poolDictionaries:''
category:'Collections-Sequenceable'
"/ I am a subclass of Dictionary whose elements (associations) are ordered in a
"/ similar fashion to OrderedCollection.
"/ That is, while being filled via #at:put: messages (or similar Dictionary protocol),
"/ the order in which associations are added, is remembered and accessible via the #atIndex:
"/ or #order messages.
"/ Therefore, this combines fast access via hashing with a defined order when enumerating.
"/
"/ [instance variables:]
"/ order <OrderedCollection> Ordered collection of keys reflecting the order of
"/ associations in the dictionary.
"/
"/ [complexity:]
"/ access by index: O(1)
"/ access by key: O(1)
"/ searching: O(n)
"/ insertion: mostly O(1)
"/ removal: mostly O(N) (because order will have O(n) behavior)
"/
"/ [author:]
"/ Ifor Wyn Williams
"/ Changed by: exept

Related

How to prove a language with (ab)^n.. is not regular with pumping lemma?

I have been working to understand the pumpming lemma better but I am quite stuck at proving these 2 languages is not regular:
L_1 = {(ab)^n c^m | n>=1, m>=2n }
L_2 = {(ab)^n a^k (ba)^n | k<3}
for the L_2 my approach was:
Let's say there is a number p.
Be the word z=(ab)^p a^k (ba)^p => |z| = 2p > p
and its decomposition may z=uvw with |uv| <= p & |v|>0.
It means that v= (ab)^j with 0<j<=p.
We choose i = 2 for uv^(i)w leads to (ab)^(p+j) a^k (ba)^p.
This Strings has more ab then ba, which means it does not belong to the language.
=> L_2 is not regular
I am actually confused with the (ab)^n, we should decomposed it, so it is necessary to consider different cases of v or is this sufficient?
For L_1, use the string (ab)^p c^2p and point out that pumping can only change the number of a's and b's, never c's, and pumping up will cause the string not to be of the proper form, or m to be less than 2n.
For L_2, use the string (ab)^p(ba)^p and argue that since pumping can only affect the prefix (ab)^p, if pumping keeps that part in the correct format, the number of b's will increase when pumping up, whereas the number of b's in the second part (which is deterministically found by looking after the only occurrence of bb) remains the same; so, the result can't be of the form (ab)^n a^k (ba)^n due to the mismatch in number of b's.

Implementation of Speck cipher

I am trying to implement the speck cipher as specified here: Speck Cipher. On page 18 of the document you can find some speck pseudo-code I want to implement.
It seems that I got a problem on understanding the pseudo-code. As you can find there, x and y are plaintext words with length n. l[m-2],...l[0], k[0] are key words (as for words, they have length n right?). When you do the key expansion, we iterate for i from 0 to T-2, where T are the round numbers (for example 34). However I get an IndexOutofBoundsException, because the array with the l's has only m-2 positions and not T-2.
Can someone clarify what the key expansions does and how?
Ah, I get where the confusion lies:
l[m-2],...l[0], k[0]
these are the input key words, in other words, they represent the key. These are not declarations of the size of the arrays, as you might expect if you're a developer.
Then the subkey's in array k should be derived, using array l for intermediate values.
According to the formulas, taking the largest i, i.e. i_max = T - 2 you get a highest index for array l of i_max + m - 1 = T - 2 + m - 1 = T + m - 3 and therefore a size of the array of one more: T + m - 2. The size of a zero-based array is always the index of the last element - plus one, after all.
Similarly, for subkey array k you get a highest index of i_max + 1, which is T - 2 + 1 or T - 1. Again, the size of the array is one more, so there are T elements in k. This makes a lot of sense if you require T round keys :)
Note that it seems possible to simply redo the subkey derivation for each round if you require a minimum of RAM. The entire l array doesn't seem necessary either. For software implementations that doesn't matter a single iota of course.

vector-of vs. vector in Clojure

When would I use vector-of to create a vector, instead of the vector function. Is the guideline to use vector most of the time and only for performance reason switch to vector-of?
I could not find good info on when to use vector-of.
vector-of is used for creating a vector of a single primitive type, :int, :long, :float, :double, :byte, :short, :char, or :boolean. It doesn't allow other types as it stores the values unboxed internally. So, if your vector need to include other types than those primitive types, you cannot use vector-of. But if you are sure that the vector will have data of a single primitive type, you can use vector-of for better performance.
user=> (vector-of :int 1 2 3 4 5)
[1 2 3 4 5]
user=> (vector-of :double 1.0 2.0)
[1.0 2.0]
user=> (vector-of :string "hello" "world")
Execution error (IllegalArgumentException) at user/eval5 (REPL:1).
Unrecognized type :string
As you can see, you should specify primitive type as an argument.
vector can be used to create a vector of any type.
user=> (vector 1 2.0 "hello")
[1 2.0 "hello"]
You can put any type when you use vector.
Also, there's another function vec, which is used for creating a new vector containing the contents of coll.
user=> (vec '(1 2 3 4 5))
[1 2 3 4 5]
Usually, you can get the basic information of a function/macro from the repl, like the following.
user=> (doc vector-of)
-------------------------
clojure.core/vector-of
([t] [t & elements])
Creates a new vector of a single primitive type t, where t is one
of :int :long :float :double :byte :short :char or :boolean. The
resulting vector complies with the interface of vectors in general,
but stores the values unboxed internally.
Optionally takes one or more elements to populate the vector.
Reference:
https://clojuredocs.org/clojure.core/vector-of
https://clojuredocs.org/clojure.core/vector
https://clojuredocs.org/clojure.core/vec
Nobody really ever uses vector-of. If you don't super care about performance, vector is fine, and if you do super care about performance you usually want a primitive array or some other java type. Honestly I would expect occasional weird snags when passing a vector-of to anything that expects an ordinary vector or sequence - maybe it works fine, but it's just such a rare thing to see that it wouldn't surprise me if it caused issues.

Generate Unique Combinations of Integers

I am looking for help with pseudo code (unless you are a user of Game Maker 8.0 by Mark Overmars and know the GML equivalent of what I need) for how to generate a list / array of unique combinations of a set of X number of integers which size is variable. It can be 1-5 or 1-1000.
For example:
IntegerList{1,2,3,4}
1,2
1,3
1,4
2,3
2,4
3,4
I feel like the math behind this is simple I just cant seem to wrap my head around it after checking multiple sources on how to do it in languages such as C++ and Java. Thanks everyone.
As there are not many details in the question, I assume:
Your input is a natural number n and the resulting array contains all natural numbers from 1 to n.
The expected output given by the combinations above, resembles a symmetric relation, i. e. in your case [1, 2] is considered the same as [2, 1].
Combinations [x, x] are excluded.
There are only combinations with 2 elements.
There is no List<> datatype or dynamic array, so the array length has to be known before creating the array.
The number of elements in your result is therefore the binomial coefficient m = n over 2 = n! / (2! * (n - 2)!) (which is 4! / (2! * (4 - 2)!) = 24 / 4 = 6 in your example) with ! being the factorial.
First, initializing the array with the first n natural numbers should be quite easy using the array element index. However, the index is a property of the array elements, so you don't need to initialize them in the first place.
You need 2 nested loops processing the array. The outer loop ranges i from 1 to n - 1, the inner loop ranges j from 2 to n. If your indexes start from 0 instead of 1, you have to take this into consideration for the loop limits. Now, you only need to fill your target array with the combinations [i, j]. To find the correct index in your target array, you should use a third counter variable, initialized with the first index and incremented at the end of the inner loop.
I agree, the math behind is not that hard and I think this explanation should suffice to develop the corresponding code yourself.

Get all childs of a particular node till a particular depth

I have this relationship in my neo4j:
Parent -> Childs
F -> D,E
D -> A,B,C
A -> X
Use case: I am trying to get all child of a particular node using this query till a particular depth let's say depth = 2
Query to get All child of node F
MATCH (p:Person)-[:REPORTS_TO *]->(c:Person) WHERE p.name="F"
WITH COLLECT (c) + p AS all
UNWIND all as p MATCH (p)-[:REPORTS_TO]-(c)
RETURN p,c;
This returns me this: (which is all child's node of F without limit)
But when I try to get all childs till depth 2 :
Query to get All child of node F with depth = 2
MATCH (p:Person)-[:REPORTS_TO *2]->(c:Person) WHERE p.name="F"
WITH COLLECT (c) + p AS all
UNWIND all as p MATCH (p)-[:REPORTS_TO]->(c)
RETURN p,c;
Which returns
When I put depth = 2, it didn't return all child's of D' (only returned A and notB`, 'C')
Expected response was:
All child's of 'F', child's of all child's of `F' (i.e level 1) and child's of all childs of nodes of level 1 (i.e level 2)
Am I missing something in my query or any another way to get a response as I expected above?
Adding dataset
CREATE (f:Person {name: "F"})
CREATE (e:Person {name: "E"})
CREATE (d:Person {name: "D"})
CREATE (c:Person {name: "C"})
CREATE (b:Person {name: "B"})
CREATE (a:Person {name: "A"})
CREATE (x:Person {name: "X"})
CREATE (a)-[:REPORTS_TO]->(x)
CREATE (d)-[:REPORTS_TO]->(a)
CREATE (d)-[:REPORTS_TO]->(b)
CREATE (d)-[:REPORTS_TO]->(c)
CREATE (f)-[:REPORTS_TO]->(d)
CREATE (f)-[:REPORTS_TO]->(e)
The problem is you're not querying for what you think you're querying for.
[:REPORTS_TO *2]
doesn't query up to depth 2, it queries nodes at exactly depth 2. The result is nodes B, C, A, and F (since you added it in).
Of those nodes, only nodes A and F have an outgoing :REPORTS_TO relationship, so your match eliminates B and C from the result set. The nodes returned are A and F and the nodes reachable by an outgoing :REPORTS_TO relationship (E, D, and X).
If you want to alter your query so it's up to depth 2 instead of exactly depth 2, use a range on the variable-length relationship (omitting the lower-bound makes it default to 1):
[:REPORTS_TO *..2]
And if you want this to include F in the match itself (instead of manually adding it when you collect the nodes), use a lower bound of 0:
[:REPORTS_TO *0..2]

Resources