Some difficulties of designing with types in F# by simple graph example - f#

There is oriented graph:
We are adding node and edge to it:
and then removing some other (by the algorithm, it doesn't matter here):
I had tried to do this in F#, but I cannot choose properly architecture decisions because of my little experience.
open System.Collections.Generic
type Node = Node of int
type OGraph(nodes : Set<Node>,
edges : Dictionary<Node * int, Node>) =
member this.Nodes = nodes
member this.Edges = edges
let nodes = set [Node 1; Node 2; Node 3]
let edges = Dictionary<Node * int, Node>()
Array.iter edges.Add [|
(Node 1, 10), Node 2;
(Node 2, 20), Node 3;
|]
let myGraph = OGraph(nodes, edges)
myGraph.Nodes.Add (Node 4)
myGraph.Edges.Add ((Node 2, 50), Node 4)
myGraph.Edges.Remove (Node 2, 20)
myGraph.Nodes.Remove (Node 3)
How to add empty node? I mean, it may be 3 or 4 or even 100500. If we add node without number, then how we can use it to create edge? myGraph.Edges.Add ((Node 2, 50), ???) In imperative paradigm it would be simple because of using named references and Nulls, we can just create Node newNode = new Node() and then use this reference newNode, but seems that in F# this is a bad practice.
Should I specify separate types Node and Edge or use simple types instead? Or may be some other representation, more complicated?
It is better to use common .NET mutable collections (HashSet, Dictionary etc.), or special F# collections (Set, Map, etc.)? If collections are large, it is acceptable in terms of performance to copy entire collection every time it should be changed?

The graph itself is easy enough to model. You could define it like this:
type Graph = { Node : int option; Children : (int * Graph) list }
If you will, you can embellish it more, using either type aliases or custom types instead of primitive int values, but this is the basic idea.
You can model the three graphs pictured in the OP like the following. The formatting I've used looks quite verbose, but I deliberately formatted the values this way in order to make the structure clearer; you could write the values in a more compact form, if you'd like.
let x1 =
{
Node = Some 1;
Children =
[
(
10,
{
Node = Some 2;
Children =
[
(
20,
{
Node = Some 3;
Children = []
}
)
]
}
)
]
}
let x2 =
{
Node = Some 1;
Children =
[
(
10,
{
Node = Some 2;
Children =
[
(
20,
{
Node = Some 3;
Children = []
}
);
(
50,
{
Node = None;
Children = []
}
)
]
}
)
]
}
let x3 =
{
Node = Some 1;
Children =
[
(
10,
{
Node = Some 2;
Children =
[
(
50,
{
Node = Some 3;
Children = []
}
)
]
}
)
]
}
Notice the use of int option to capture whether or not a node has a value.
The Graph type is an F# record type, and uses the F# workhorse list for the children. This would be my default choice, and only if performance becomes a problem would I consider other data types. Lists are easy to work with.

Sine if these are easy:
Use Option - then an empty node is None
Maybe - depends on problem
This depends on your specific problem you are solving - the F# collections tend to be immutable and some operations are fast, but the .NET collections have other operations which are fast.

Related

Merge two sorted linked lists: space complexity

I am looking at the following Geeks for Geeks problem:
Given two sorted linked lists consisting of N and M nodes respectively. The task is to merge both of the list (in-place) and return head of the merged list.
Example 1
Input:
N = 4, M = 3
valueN[] = {5,10,15,40}
valueM[] = {2,3,20}
Output: 2 3 5 10 15 20 40
Explanation: After merging the two linked
lists, we have merged list as 2, 3, 5,
10, 15, 20, 40.
Below answer is the GFG answer. I don't understand how its space complexity is O(1). We are creating a new node, so it must be O(m+n).
Node* sortedMerge(Node* head1, Node* head2)
{
struct Node *dummy = new Node(0);
struct Node *tail = dummy;
while (1) {
if (head1 == NULL) {
tail->next = head2;
break;
}
else if (head2 == NULL) {
tail->next = head1;
break;
}
if (head1->data <= head2->data){
tail->next = head1;
head1 = head1->next;
}
else{
tail->next = head2;
head2 = head2->next;
}
tail = tail->next;
}
return dummy->next;
}
Could someone explain how the space complexity is O(1) here?
I can't understand how it's space complexity is O(1). Since we are creating a new node so it must be O(m+n).
Why should it be O(m+n) when it creates one node? The size of that node is a constant, so one node represents O(1) space complexity. Creating one node has nothing to do with the size of either of the input lists. Note that the node is created outside of the loop.
It is actually done this way to keep the code simple, but the merge could be done even without that dummy node.

Lua: Concise expression of table scope

I'm working on a game where a bunch of characters will be generated on the fly, based on some constraints defined either in the project or externally via mod files. I am using MoonSharp Lua (5.2) interpreter for interfacing with my C# code, and Lua tables to store the constraint presets. As an example:
require "Defaults"
AgePresets = {}
-- Single value
AgePresets.Newborn = 0
-- Simple ranges
AgePresets.Default = defaultAgeRange --referring to the Defaults require
AgePresets.Child = {1, 12}
AgePresets.Teenager = {13, 19}
AgePresets.YoungAdult = {20, 29}
AgePresets.Adult = {30, 40}
AgePresets.MiddleAge = {40, 60}
AgePresets.Senior = {61, 80}
AgePresets.Elder = {81, 99}
AgePresets.Methuselah = {100, 150}
AgePresets.Methuselah2 = {150, 200}
-- Weighted ranges // again referring to previously defined elements to keep things concise
AgePresets.Tween = {
{weight = 1, minmax = AgePresets.Teenager },
{weight = 1, minmax = AgePresets.YoungAdult }
}
This works fine, but from an end-user point of view, there's a lot of unnecessary typing involved. We are clearly working on AgePresets here but it is still mentioned as a prefix before every member name.
I could of course define AgePresets as an array, like AgePresets = { Child = {}, Teenager = {} } but the problem with that is then I cannot refer to previously defined elements in the array.
This doesn't work:
AgePresets = {
Child = {1,12},
RefToChild = Child, //attempt to index a nil value exception
Teen = {13,19}
}
What I ideally want to achieve is a clean, concise way for users to enter this data in, like in the first example but without having to put AgePresets. prefix before everything. How do I go about declaring a scope in a file such that all succeeding members defined in the file will be within that scope, while maintaining the ability to refer to other members defined previously in the scope?
AgePresets = setmetatable({}, {__index = _G})
do
local _ENV = AgePresets
Newborn = 0
Child = {1,12}
RefToChild = Child -- this ref is Ok
Teen = {13,19}
YoungAdult = {20,29}
Tween = {
{weight = 1, minmax = Teen },
{weight = 1, minmax = YoungAdult }
}
rnd = math.random(10) -- global functions are available here
end
setmetatable(AgePresets, nil)
You can mix the two styles: table constructor for fields that don't need to reference variables that aren't in scope yet, followed by assignment statements for the rest.
I would do that unless the order of the fields in the code significantly enhanced comprehension.

Lua return index of a nested table

This is my first attempt to use Lua tables and I'm getting on with it quite well. I'm struggling with one thing though, heres (a small sample of) my table as it currently stands:
objects = {
["1/1/1"] = { tl = 1, startVal = 1, stopVal = 0 },
["1/1/2"] = { tl = 11, startVal = 1, stopVal = 0 },
["1/1/3"] = { tl = 22, startVal = 1, stopVal = 0 },
["1/1/4"] = { tl = 33, startVal = 1, stopVal = 0 },
}
The typical operation of this is that I use the "1/1/1" values as a lookup to the inner tables and then use those values in various functions. This all works well. Now, I need to go the other way, say I have tl = 22 coming in, I want to return the top value ("1/1/3" in this case).
I think I need to do something with the inpairs I keep seeing on the web but I'm struggling to implement. Any help would be massively appreciated.
You can't use ipairs because your table is an associated array not a sequence, so you have to use pairs. Also, there is no search function builtin to Lua, so you have to loop over all items yourself, looking for the right field value:
function findTL(tbl)
for key, data in pairs(tbl) do
if data.tl == tlSearch then
return key
end
end
end
local key = findTL(objects, 22)
If you want something a tad more object-oriented you could do this:
objects.findTL = findTL -- ok because first arg is the table to search
local key = objects:findTL(22)
isn't it better to take the value directly?
objects.1/1/1.tl
I don't know if it will work also with slashes, but if not, you may replace it by 'x' for example. Then it will be:
objects.1x1x1.tl

I cannot understand the effectiveness of an algorithm in the Dart SDK

I cannot understand the effectiveness of an algorithm in the Dart SDK.
Here is the algorithm (List factory in dart:core, file list.dart)
factory List.from(Iterable other, { bool growable: true }) {
List<E> list = new List<E>();
for (E e in other) {
list.add(e);
}
if (growable) return list;
int length = list.length;
List<E> fixedList = new List<E>(length);
for (int i = 0; i < length; i ) {
fixedList[i] = list[i];
}
return fixedList;
}
If growable is false then both lists will be created.
List<E> list = new List<E>();
List<E> fixedList = new List<E>(length);
But the creation of list #1 in this case is redundant because it's a duplicate of Iterable other. It just wastes CPU time and memory.
In this case this algorithm will be more efficient because it wont create an unnecessary list # 1 (growable is false).
factory List.from(Iterable other, { bool growable: true }) {
if(growable) {
List<E> list = new List<E>();
for (E e in other) {
list.add(e);
}
return list;
}
List<E> fixedList = new List<E>(other.length);
var i = 0;
for (E e in other) {
fixedList[i++] = e;
}
return fixedList;
}
Or am I wrong and missed some subtleties of programming?
We usually avoid invoking the length getter on iterables since it can have linear performance and side-effects. For Example:
List list = [1, 2, 3];
Iterable iterable1 = list.map((x) {
print(x);
return x + 1;
});
Iterable iterable2 = iterable1.where((x) => x > 2);
var fixedList = new List.from(iterable2, growable: false);
If List.from invoked the length getter it would run over all elements twice (where does not cache its result). It would furthermore execute the side-effect (printing 1, 2, 3) twice. For more information on Iterables look here.
Eventually we want to change the List.from code so that we avoid the second allocation and the copying. To do this we need (internal) functionality that transforms a growable list into a fixed-length list. Tracking bug: http://dartbug.com/9459
It looks like it was just an incremental update to the existing function.
See this commit and this diff
The function started just with
List<E> list = new List<E>();
for (E e in other) {
list.add(e);
}
and had some more bits added as part of a fairly major refactoring of numerous libraries.
I would say that the best thing to do is to raise a bug report on dartbug.com, and either add a patch, or commit a CL - see instructions here: https://code.google.com/p/dart/wiki/Contributing (Note, you do need to jump through some hoops first, but once you're set up, it's all good).
It might also be worth dropping a note to one of the committers or reviewers from the original commit to let them know your plans.

pugixml number of child nodes

Does a pugixml node object have a number-of-child-nodes method? I cannot find it in the documentation and had to use an iterator as follows:
int n = 0;
for (pugi::xml_node ch_node = xMainNode.child("name"); ch_node; ch_node = ch_node.next_sibling("name")) n++;
There is no built-in function to compute that directly; one other approach is to use std::distance:
size_t n = std::distance(xMainNode.children("name").begin(), xMainNode.children("name").end());
Of course, this is linear in the number of child nodes; note that computing the number of all child nodes, std::distance(xMainNode.begin(), xMainNode.end()), is also linear - there is no constant-time access to child node count.
You could use an expression based on an xpath search (no efficiency guarantees, though):
xMainNode.select_nodes( "name" ).size()
int children_count(pugi::xml_node node)
{
int n = 0;
for (pugi::xml_node child : node.children()) n++;
return n;
}

Resources