How to pick the vectors with specific number of elements? - list

Suppose that I have the following data:
k = {{4.27866*10^-13,-1.42199*10^-13,-14.3052},{1.37715*10^-12,1.54405*10^-13,57.2207},{7.5824*10^-13,-6.49694*10^-14,-14.3052},{1.27432*10^-13,5.61507*10^-13,57.2207},{3.70858*10^-14,-7.96837*10^-13,57.2207},{3.92797*10^-13,1.48757*10^-12,-28.6104},{-4.10392*10^-12,-2.73776*10^-12,114.441},{-1.51969*10^-12,1.06176*10^-12,-28.6104},{-4.59286*10^-13,-3.12823*10^-12,57.2207},{1.65875*10^-12,3.0834*10^-12,57.2207},{-3.23525*10^-13,1.71989*10^-12,-28.6104},{3.77647*10^-12,-3.01939*10^-12,114.441},{-1.87065*10^-12,1.24166*10^-12,-28.6104},{-1.943*10^-12,-2.1757*10^-13,57.2207},{8.54924*10^-13,2.33037*10^-13,57.2207},{1.63408*10^-12,-2.67705*10^-12,-28.6104},{-1.70569*10^-13,1.77206*10^-12,114.441},{5.3375*10^-13,1.17943*10^-12,-28.6104},{-1.32554*10^-12,1.54792*10^-12,57.2207},{-8.241*10^-13,-1.40979*10^-12,57.2207},{1.165*10^-12,-5.75912*10^-12,-28.6104},{3.13416*10^-12,5.60966*10^-12,114.441},{1.24376*10^-12,-9.52466*10^-15,-28.6104},{-2.89891*10^-12,2.69403*10^-12,57.2207},{-6.22802*10^-12,-2.64539*10^-12,57.2207},{2.02785*10^-12,1.37895*10^-12,-28.6104},{-4.27374*10^-12,-4.53139*10^-12,114.441},{4.02993*10^-12,3.45467*10^-12,-28.6104},{1.89303*10^-12,-2.42926*10^-12,57.2207},{2.51145*10^-12,2.5046*10^-12,57.2207},{-6.58799*10^-13,2.81488*10^-12,-28.6104},{-1.53405*10^-12,-3.34721*10^-12,114.441},{-5.55037*10^-13,9.55643*10^-13,-28.6104},{2.19236*10^-13,1.23658*10^-12,57.2207},{-9.32115*10^-14,-1.05116*10^-12,57.2207},{-4.8363*10^-13,-2.06515*10^-13,-14.3052},{1.76312*10^-12,-4.42531*10^-13,57.2207},{-6.27983*10^-13,5.71422*10^-13,-14.3052},{-8.74832*10^-29},{-7.24913*10^-29},{3.90609*10^-30},{-6.01168*10^-29},{-2.70339*10^-29},{1.13779*10^-28},{4.72628*10^-30},{-1.08871*10^-28},{-9.79436*10^-29},{-5.84032*10^-29},{-2.15675*10^-28},{-1.76768*10^-28},{-2.68466*10^-28},{-4.23548*10^-28},{-9.12504*10^-29},{-6.79045*10^-29}};
in which there are two types of lists, one with 3 elements and the other with just one element. The question is how to pick all the lists with 3 elements?

I would make use of Cases. the following options should work :
Cases[k,{_,_,_}]
or
Cases[k,{Repeated[_,{3}]}]

Related

Prolog - how to generate list of specific length?

I'm doing this exercise for which I have to write a predicate randomnames/1 for generating a random list of three names (no duplicates allowed). I have a database with 10 names in it already and they all correspond to a number, for example: name(1, Mary).
I wrote a predicate for generating one random name:
randomname(Name) :-
random(0, 11, N), % generate random integer between 1 and 10.
name(N, Name).
My question would be: How do I get this in a list? And a list of exactly three elements at that?
I don't want to use too many built-ins. length/2 would be alright though. I think I might need it :)
Thanks a lot!
Edit: I figured I would first try to generate a list of three random numbers (the names can come later). I wrote this horribly wrong little thing:
numberlist([N|T]) :-
random(0, 11, N),
length([N|T], 3),
numberlist(T).
I know how to do this with a /2 predicate; when the user can just enter in the query that they want a list with three elements (numberlist(3,X).for example). But I'm can't seem to figure out how to write down in code that I always want a list of three numbers.
I was also thinking of using findall for generating my list, but again I don't know how to limit the length of the list to three random elements.
When describing lists in Prolog, it is often useful to first describe how a single element looks like.
For example, in your case, it seems you already have a predicate like random_name/1, and it describes a single element of the list you want to describe.
So, to describe a list consisting of three such elements, what about:
random_names([A,B,C]) :-
random_name(A),
random_name(B),
random_name(C).
This describes a list with three elements, and random_name/1 holds for each of these elements.

How can one populate a vector with all possible string combinations of n vector length in the C++ programming language

I have a vector of 100 strings and another empty vector and I'm trying to fill the empty vector with every possible combination of n strings from the group of 100. (n = 1, 2, 3,...)
If n =1 then you get every unique vector composed of 1 string (or all 100 strings as vectors)
If n =2 then you get every unique vector composed of 2 strings(or 100^2 variations)
C++ is not my native language.
I have some attempts so far, and what I'd do in Zou_script (proprietary in-house) would be to assign each string a number and then permute through all possible combinations of those numbers, and then reference individual strings through Vector[] to create the vectors.
This seems slow and has a lack of elegance, holding the string bank in memory could be bad if the string bank was much bigger.
I have used std::next_permutation but I'm having trouble extending it elegantly to sorting vectors composed of strings.
How can one populate a vector with all possible string combinations of n vector length in the C++ programming language? <- Question.
Might anyone be of any assistance? If you're unsure, or intimidated by the question it's OK to go to the next one.
Update
I have managed to replicate the technique in C++ but next_permutation is significantly slower because it does not understand it does not need to calculate the entire permutation vector, only up to n amount.
Any way to manipulate next_permutation to only calculate x elements of a vector permutation?
I have asked this question but I will do the best that I can to give an answer. This is in fact a well researched and often asked question in C/C++.
"How to consider permutations of a group of N elements, r at a time?"
There are many ways to tackle the problem. One such way is to generate a vector of integers with which to map to a vector of your elements.
Using std::next_permutation you can generate a list of numbers (permutations of the integer vector) and truncate to the amount of items you are considering. This list can then be sorted using vector tools, duplicates removed. This will give you a list of all unique permutations of N integers, r at a time, for mapping to your element vector.
Then it can be as easy as calling the r numbers from your permutation integer list and using them in your element list index to generate the permutations of your elements.
for (int k = 0; k < linecount_of_integer_permutation_list; k++)
{
// insert code for calling up integer permutation list line
// and assigning that permutation to vector
for (int i = 0; i < r; i++)
{
file << element[intvec[r]]; // can put whatever delimiters you want/need
}
file << std::endl;
intvec.clear();
// remember to clear vectors, or other flags depending on what you need
}
This is cumbersome and very slow.
https://howardhinnant.github.io/combinations.html
Has some very good ideas on how to handle this issue faster. The above will work for small sets, however the jump from small to absolutely unmanageable is very quick in permutations.
Thank you for all your help. It is actually an interesting question but apparently it isnt needed for many people's applications in programming.

Implementation of non increasing list with STL C++

In a problem inputs are several lists of numbers,
Ex-
(1,5,4,3), (2,7,3,1,5), (1,9,1,7,3,7,2), (3,5,4,2,3).
where each list may appear twice.
In the final output distinct lists should be printed, in which elements in each list should be sorted in non increasing order, as well as lists should be sorted like that.
Is it possible to implement this whole thing with map in c++ ?
Output for the above example should be
9,7,7,3,2,1,1
7,5,3,2,1
5,4,3,3,2
5,4,3,1
Simply,set of unique lists where within each lists numbers again sorted in non increasing order.
std::set will definitely help you. You will get a unique sorted list as the resultant set if you insert your list into a std::set<int>
Edit:
std::set<std::multiset<int, std::greater<int>> myList;
Inner set going to sort in non increasing order and keeping duplicates elements, and outer set going to keep only unique list of inner list.

Fastest way to compare 2 c++ std::lists, changing in each iteration

Let's say i have 2 std::lists, each contains various numbers of elements. Every element (on each list) has UNIQUE int id value. On every iteration i need to remove elements from first list that don't appear on the second one and add elements from the second list that don't belong to the first one. E.g (numbers=unique ids):
iteration: first[3,2,1], second[4,3,5,7,6], result: [3,4,5,6,7]
iteration: first[3,4,5,6,7], second[4,10,9], result: [4,10,9]
etc...
I cannot simply swap second one to first one (let us recognise it's impossible, too long to read). My question is:
What is the best search algorithm I can perform to update first list? I mean, should i use nested loops on both sorted lists and compare ids? Remove continuously elements from first lacking in the second but also delete repeating ones in first. Then merge it? Or maybe make one of them unordered_map(hash table)?
Edited:
I wanted to simplify problem but in fact, it's unclear now. I cannot change containers, there are 2 unsorted lists contain 2 different structures each. The only link between 2 types of structures is an id parameter. In every iteration i have to check if first list looks just like the second one. Ids are unique, no repeats allowed. So if ids match lists will be identical. I can't swap them because first list has e.g 30 values and the second one 10 (it's incompleted). There are another special functions to prepare structure for first list that consist of many different structures (including structure from list 2). These functions are launched only if there are ids from the second list that don't appear in the first list. I mustn't manipulate first list but i'm able to modify the second one.
I tried in this ways. In every iteration:
1. Create a std::unordered_set with hashed ids from second list. Then compare it to first list and remove outdated ids from first list. Remove also repeating ids from unordered_set. We'll end up with the set of new structures from list 2. We can run another functions and then add suitable ones to first list.
2. Sort list2 by ids. Then do binary search.
3. Linear search. 2 loops. Id that appears in first list and doesn't in the second one is removed from first list. Id that appears in both lists is removed from the second list. And finally we got ids that appear in second list and don't in the second one. We can process them and merge with list 1.
The most important thing: There will be a lot of comparisons but lists are the same most of the time!
The most efficient way to do this is probably going to be to simply assign the second list to the first:
first = second;
which will copy all the elements in second and put them in first.
If for some reason you need to keep the elements in place, you can sort each list and use the set_difference algorithm to find all the elements in one list that are not in the other list.

Find common elements in two Integer List

I have two given integer List:
alist : TList<Integer>; // eg. 1,2,3,4,5,6,7,8,9
blist : TList<Integer>; // e.g 1,2,3,4,5
Resultlist : TList<Integer>;
IgnoreList : TList<Integer>; // e,g, 1,2,3
What is a effective way to find the common elements on both lists, excluding elements from the ignore list. As I have to run this procedure over many items I need a effective and fast way of implementation for this problem.
Resultlist should be 4,5
I agree with Dmitry. Converting lists to hash sets and looking up in them would be fast irrespective of whether the lists are sorted.
Have a look at Delphi's TDictionary. TDictionary intersection is one quick way of finding common elements. Otherwise,
1) Create a TDictionary for blacklisted elements.
2) Create a TDictionary and insert elements from alist that are not present in blacklist-dictionary. This operation is fast because TDictionary are optimized for lookup.
3) finally, iterate over elements of blist and only output elements preent in alist-dictionary.
What you want for this is the list comparison algorithm. You take two sorted lists (make sure to sort them first if they aren't already) and two index variables, set both indices to 0, and start comparing values, advancing one index or the other if they aren't equal, or both indices of they are. By customizing the behavior of the algorithm when unequal or equal values are found, there are a lot of things you can do with this. What you want for here is, when equal values are found, insert the value into the output list.