How can I get refer to the statically known size and type of a literal array? - ats

For example,
#include "share/atspre_staload.hats"
implement main0() =
let
var A = #[int](1, 2, 3, 4, 5)
val n = 5
val what = "int"
in
println!("the array A contains ", n, " elements of type ", what)
end
how could I define n and what with reference to A?

The short answer is that you could not because neither 'n' nor 'int' is
in the dynamic representation of A.

Related

Difference between arr and &arr if arr is an array of ints

I am just starting out with C++ and I have a question. If arr is an array or 10 ints, then arr is a pointer to the first element in the array. But what is meant by &arr? SO what is the difference bwteen a pointer to an array and a reference to an array?
then arr is a pointer to the first element in the array
No!
Arrays and pointers are two different types in C++ that have enough similarities between them to create confusion if they are not understood properly. The fact that pointers are one of the most difficult concepts for beginners to grasp doesn't help either.
So I fell a quick crash course is needed.
Crash course
Arrays, easy
int a[3] = {2, 3, 4};
This creates an array named a that contains 3 elements.
Arrays have defined the array subscript operator:
a[i]
evaluates to the i'th element of the array.
Pointers, easy
int val = 24;
int* p = &val;
p is a pointer pointing to the address of the object val.
Pointers have the indirection (dereference) operator defined:
*p
evaluates to the value of the object pointed by p.
Pointers, acting like arrays
Pointers give you the address of an object in memory. It can be a "standalone object" like in the example above, or it can be an object that is part of an array. Neither the pointer type nor the pointer value can tell you which one it is. Just the programmer. That's why
Pointers also have the array subscript operator defined:
p[i]
evaluates to the ith element to the "right" of the object pointed by p. This assumes that the object pointer by p is part of an array (except in p[0] where it doesn't need to be part of an array).
Note that p[0] is equivalent to (the exact same as) *p.
Arrays, acting like pointers
In most contexts array names decay to a pointer to the first element in the array. That is why many beginners think that arrays and pointers are the same thing. In fact they are not. They are different types.
Back to your question
what is meant by &arr
As said above, arr is not a pointer. So &arr means pointer to array. This is different from pointer to the first element of the array (&arr[0]).
SO what is the difference between a pointer to an array and a reference to an array?
Well, first of all please read What are the differences between a pointer variable and a reference variable in C++?. Second of all... well that's pretty much it.
the bulk of this answer is copied from this other answer of mine
There are 3 different concepts that you need to think about:
Pointer : the pointer is a variable that is used for storing the address of another variable.
Array: An array is a collection of variables of a similar data type
Reference : A reference variable is an alias, that is, another name for an already existing variable.
Here is a summary of how you can connect these three variables together:
arr == &arr[0]
and
*arr == arr[0]
For example
int arr[5] = {0,1,2,3,4};
arr is a pointer to pointer to the first element of array. While &arr a pointer to whole array of 5 int.
The value of arr and &arr are the same, but arr + 1 and &arr + 1 is different.
#include <iostream>
using namespace std;
int main()
{
int array[5];
cout << "array = " << array << " : &array = " << &array << endl;
cout << "array + 1 = " << array + 1 << " : &array + 1 = " << &array + 1;
return 0;
}
Result
array = 0x7fffebce1b80 : &array = 0x7fffebce1b80
array + 1 = 0x7fffebce1b84 : &array + 1 = 0x7fffebce1b94

Interesting search question: Find a value that's NOT in a list (Daily coding problem, May 26, 2020)

I was wondering if anyone would be willing to give me some feedback on my solution to today's question from the Daily Coding problem email list. It's an interesting question about finding the first value that's NOT present in a list, as opposed to finding a value that IS there.
This problem was asked by Stripe.
Given an array of integers, find the first missing positive integer in linear time and
constant space.
In other words, find the lowest positive integer that does not exist in the array.
The array can contain duplicates and negative numbers as well.
For example, the input [3, 4, -1, 1] should give 2. The input [1, 2, 0] should give 3.
You can modify the input array in-place.
My main question is that I'm not sure if I've met the O(n) time and O(1) space requirements. Here is my solution using Groovy:
def find_first( Xs ) {
ys = []
szXs = Xs.size()
// First, transfer Xs list to a set ys.
szXs.times { // this loop is O(n)
if ( (hd = Xs.head()) > 0 ) { ys << hd; } // We only need to keep val if it's positive.
Xs = Xs.drop(1); // Remove val from Xs in order to meet O(1) space requirement.
}
ys = ys.toSet() // converting list to set is O(n)
sz = ys.size() // ys.size() might be same as Xs.size(), but it could be smaller, so give it a new var.
for (int i = 1; i < sz; ++i) { // this loop is O(n)
if ( !ys.contains(i) ) return i // Testing a hash set for set membership is O(1)
}
return sz + 1 // if this point is reached, ys had all values [1..sz] already
} // end find_first
def test(Xs) {
println "\nstarting with Xs = " + Xs
ans1 = find_first( Xs )
println "first missing = " + ans1
}
xs1 = [ 3,4,-1,1 ]
xs2 = [ 1, 2, 0 ]
xs3 = [ 7, 8 ]
xs4 = [ 1,1,2,1 ]
xs5 = [ -4, -1 ]
test(xs1)
test(xs2)
test(xs3)
test(xs4)
test(xs5)
And here is the output:
starting with Xs = [3, 4, -1, 1]
first missing = 2
starting with Xs = [1, 2, 0]
first missing = 3
starting with Xs = [7, 8]
first missing = 1
starting with Xs = [1, 1, 2, 1]
first missing = 3
starting with Xs = [-4, -1]
first missing = 1
So it's correct on that limited set of values, just want to be sure that it's O(n) time and O(1) space. Any advice is appreciated!
Hank
I am not familiar with groovy, but it seems like your code is O(n) space, since you create an additional hash set (ys).
Note that the question has a hint:
You can modify the input array in-place.
This can be done in O(n) time with O(1) space, by first sorting the array inplace with radix sort, and then iterating over the values to find first missing one.

Algorithm to find the most common substrings in a string

Is there any algorithm that can be used to find the most common phrases (or substrings) in a string? For example, the following string would have "hello world" as its most common two-word phrase:
"hello world this is hello world. hello world repeats three times in this string!"
In the string above, the most common string (after the empty string character, which repeats an infinite number of times) would be the space character .
Is there any way to generate a list of common substrings in this string, from most common to least common?
This is as task similar to Nussinov algorithm and actually even simpler as we do not allow any gaps, insertions or mismatches in the alignment.
For the string A having the length N, define a F[-1 .. N, -1 .. N] table and fill in using the following rules:
for i = 0 to N
for j = 0 to N
if i != j
{
if A[i] == A[j]
F[i,j] = F [i-1,j-1] + 1;
else
F[i,j] = 0;
}
For instance, for B A O B A B:
This runs in O(n^2) time. The largest values in the table now point to the end positions of the longest self-matching subquences (i - the end of one occurence, j - another). In the beginning, the array is assumed to be zero-initialized. I have added condition to exclude the diagonal that is the longest but probably not interesting self-match.
Thinking more, this table is symmetric over diagonal so it is enough to compute only half of it. Also, the array is zero initialized so assigning zero is redundant. That remains
for i = 0 to N
for j = i + 1 to N
if A[i] == A[j]
F[i,j] = F [i-1,j-1] + 1;
Shorter but potentially more difficult to understand. The computed table contains all matches, short and long. You can add further filtering as you need.
On the next step, you need to recover strings, following from the non zero cells up and left by diagonal. During this step is also trivial to use some hashmap to count the number of self-similarity matches for the same string. With normal string and normal minimal length only small number of table cells will be processed through this map.
I think that using hashmap directly actually requires O(n^3) as the key strings at the end of access must be compared somehow for equality. This comparison is probably O(n).
Python. This is somewhat quick and dirty, with the data structures doing most of the lifting.
from collections import Counter
accumulator = Counter()
text = 'hello world this is hello world.'
for length in range(1,len(text)+1):
for start in range(len(text) - length):
accumulator[text[start:start+length]] += 1
The Counter structure is a hash-backed dictionary designed for counting how many times you've seen something. Adding to a nonexistent key will create it, while retrieving a nonexistent key will give you zero instead of an error. So all you have to do is iterate over all the substrings.
just pseudo code, and maybe this isn't the most beautiful solution, but I would solve like this:
function separateWords(String incomingString) returns StringArray{
//Code
}
function findMax(Map map) returns String{
//Code
}
function mainAlgorithm(String incomingString) returns String{
StringArray sArr = separateWords(incomingString);
Map<String, Integer> map; //init with no content
for(word: sArr){
Integer count = map.get(word);
if(count == null){
map.put(word,1);
} else {
//remove if neccessary
map.put(word,count++);
}
}
return findMax(map);
}
Where map can contain a key, value pairs like in Java HashMap.
Since for every substring of a String of length >= 2 the text contains at least one substring of length 2 at least as many times, we only need to investigate substrings of length 2.
val s = "hello world this is hello world. hello world repeats three times in this string!"
val li = s.sliding (2, 1).toList
// li: List[String] = List(he, el, ll, lo, "o ", " w", wo, or, rl, ld, "d ", " t", th, hi, is, "s ", " i", is, "s ", " h", he, el, ll, lo, "o ", " w", wo, or, rl, ld, d., ". ", " h", he, el, ll, lo, "o ", " w", wo, or, rl, ld, "d ", " r", re, ep, pe, ea, at, ts, "s ", " t", th, hr, re, ee, "e ", " t", ti, im, me, es, "s ", " i", in, "n ", " t", th, hi, is, "s ", " s", st, tr, ri, in, ng, g!)
val uniques = li.toSet
uniques.toList.map (u => li.count (_ == u))
// res18: List[Int] = List(1, 2, 1, 1, 3, 1, 5, 1, 1, 3, 1, 1, 3, 2, 1, 3, 1, 3, 2, 3, 1, 1, 1, 1, 1, 3, 1, 3, 3, 1, 3, 1, 1, 1, 3, 3, 2, 4, 1, 2, 2, 1)
uniques.toList(6)
res19: String = "s "
Perl, O(n²) solution
my $str = "hello world this is hello world. hello world repeats three times in this string!";
my #words = split(/[^a-z]+/i, $str);
my ($display,$ix,$i,%ocur) = 10;
# calculate
for ($ix=0 ; $ix<=$#words ; $ix++) {
for ($i=$ix ; $i<=$#words ; $i++) {
$ocur{ join(':', #words[$ix .. $i]) }++;
}
}
# display
foreach (sort { my $c = $ocur{$b} <=> $ocur{$a} ; return $c ? $c : split(/:/,$b)-split(/:/,$a); } keys %ocur) {
print "$_: $ocur{$_}\n";
last if !--$display;
}
displays the 10 best scores of the most common sub strings (in case of tie, show the longest chain of words first). Change $display to 1 to have only the result.There are n(n+1)/2 iterations.

Balanced partition

I know this was talked over a lot here, but I am struggling with this problem.
We have a set of numbers, e.g [3, 1, 1, 2, 2, 1], and we need to break it into two subsets, so the each sum is equal or difference is minimal.
I've seen wikipedia entry, this page (problem 7) and a blog entry.
But every algorithm listed is giving only YES/NO result and I really don't understand how to use them to print out two subsets (e.g S1 = {5, 4} and S2 = {5, 3, 3}). What am I missing here?
The pseudo-polynomial algorithm is designed to provide an answer to the decision problem, not the optimization problem. However, note that the last row in the table of booleans in the example indicates that the current set is capable of summing up to N/2.
In the last row, take the first column where the boolean value is true. You can then check what the actual value of the set in the given column is. If the sets summed value is N/2 you have found the first set of the partition. Otherwise you have to check which set is capable of being the difference to N/2. You can use the same approach as above, this time for the difference d.
This will be O(2^N). No Dynamic Programming used here. You can print result1, result2 and difference after execution of the function. I hope this helps.
vector<int> p1,p2;
vector<int> result1,result2;
vector<int> array={12,323,432,4,55,223,45,67,332,78,334,23,5,98,34,67,4,3,86,99,78,1};
void partition(unsigned int i,long &diffsofar, long sum1,long sum2)
{
if(i==array.size())
{
long diff= abs(sum1 - sum2);
if(diffsofar > diff)
{
result1 = p1;
result2 = p2;
diffsofar = diff;
}
return;
}
p1.push_back(array[i]);
partition(i+1,diffsofar,sum1+array[i],sum2);
p1.pop_back();
p2.push_back(array[i]);
partition(i+1,diffsofar,sum1,sum2+array[i]);
p2.pop_back();
return;
}
I faced this same problem recently, and I posted a question about it (here: Variant of Knapsack). The difference in my case is that the resulting subsets must be the same size (if the original set has an even number of elements). In order to assure that, I added a few lines to #Sandesh Kobal answer;
void partition(unsigned int i,long &diffsofar, long sum1,long sum2)
{
int maxsize = (array.size()+1)/2;
if(p1.size()>maxsize)
return;
if(p2.size()>maxsize)
return;
if(i==array.size())
{
...
Also, after both calls to partition, I added if(diffsofar==0) return;. If we already found an optimal solution, it makes no sense to keep searching...
All the articles I've seen take a dynamic programming approach. Do we really need one?
Suppose the array given is arr
Use the following algorithm :
Sort the array in descending order
Create two empty arrays, a = [] and b = []
sum_a = sum_b = 0
for x in arr:
if sum_a > sum_b:
b.append(x)
sum_b += x
else:
a.append(x)
sum_a += x
The absolute difference between sum_a and sum_b would be the minimum possible difference between the two subsets.
Consider arr = [3,1,1,2,2,1]
Sorting the array : arr = [3,2,2,1,1,1]
a = [], b = []
a = [3], b = []
a = [3], b = [2]
a = [3], b = [2,2]
a = [3,1], b = [2,2]
a = [3,1,1], b = [2,2]
a = [3,1,1], b = [2,2,1]
sa = 5, sb = 5
Minimum difference : 5 - 5 = 0

Mapping an array to consecutive non-nil values of a method?

So, I have x variable names I want to assign to x consecutive non-nil values from a method… how can I do that?
For example, I want to map %w[alpha beta gamma] to the three consecutive non-nil values of the function get(x) beginning with 0.
So, say the values of get(x) are get(0)=1, get(1)=54, get(2)=nil, get(3)=6. I'd want alpha = 1, beta = 54, and gamma = 6.
How can I do this?
Setting Hash key/value pairs may not really answer the question but it's almost always the right solution for a real program ...
def get x # test sub
[1, 54, nil, 6][x]
end
# find the next n non-nil values of an integer function
def find n, sofar, nextval
return sofar if sofar.length >= n
return find n, (sofar << get(nextval)).compact, nextval + 1
end
h = {}
h[:alpha], h[:beta], h[:gamma] = find 3, [], 0
p h

Resources