Hi I have a map like map<char,int> and I wish to do a reverse lookup i.e. find a key from a value.
Is there any way to do this in Dafny (e.g. map.getKey(value)) which has not been documented yet?
I am thinking that one solution could be to inverse the map so that I could inverse a map<char,int> to map<int,char and then use the normal lookup on the inversed map. I am not sure how to do this but have tried using map table[i] | i in table :: i by map comprehension but this does not work.
Please help me.
You can use a "let such-that" statement to do that. For example:
method Test(m: map<char,int>, val: int)
requires exists i :: i in m && m[i] == val;
{
var i :| i in m && m[i] == val;
// now use i...
}
You can also invert the map as follows (but you don't need to just to do a single reverse lookup)
function method InvertMap(m: map<char,int>): map<int,char>
{
map b | b in m.Values :: var a :| a in m && m[a] == b; a
}
Related
What is the shortest (and idiomatic) way to create an array from the keys and values of a map w/o compromising on time complexity too much?
For instance, from the following map:
map[string]string { "1":"a", "2":"b" }
I need to create the following array:
[]string{"1","a", "2","b"}
I can do this in Scala with following:
val myMap = Map("1" -> "a", "2" -> "b")
myMap.keySet ++ myMap.values
Thank you.
Simplest way would be to just iterate the map, since in Go the syntax would allow direct access to keys and values and dump them into the array.
m := map[string]string { "1":"a", "2":"b" }
arr := []string{}
for k, v := range m {
arr = append(arr, k, v)
}
One caveat here: In Go, map iteration order is randomized, as you can see here, under "Iteration Order":
https://blog.golang.org/go-maps-in-action
So if you want your resulting array to have a particular ordering, you should first dump the keys and order (as shown in that same blog entry).
Playground (without the sorting part):
https://play.golang.org/p/mCe6eEy25A
As I understand it, I cannot define equality for user-defined types in Go. So what would be the idiomatic way of computing the number of distinct objects of some custom type (possibly recursively defined). Here is an example of the kind of thing I am trying to do.
package main
import "fmt"
type tree struct {
left *tree
right *tree
}
func shapeOf(a tree) string {
temp := "{"
if a.left != nil {
temp += shapeOf(*(a.left))
}
temp += "}{"
if a.right != nil {
temp += shapeOf(*(a.right))
}
temp += "}"
return temp;
}
func main() {
a := tree{nil, nil}
b := tree{nil, &a}
c := tree{nil, nil}
d := tree{nil, &c}
e := tree{nil, nil}
f := tree{&e, nil}
s := make(map[string]bool)
s[shapeOf(b)] = true
s[shapeOf(d)] = true
s[shapeOf(f)] = true
fmt.Println(len(s)) // As required, prints 2 because the first two trees have the same shape
}
It works, but the use of strings is extremely ugly, and probably inefficient too. Obviously I could easily write a recursive method to tell if two trees are equal - something like
func areEqual(a, b tree) bool
but this wouldn't enable me to use trees as map keys. What is the idiomatic Go way to do something like this?
You cannot define equality for user-defined type because it is already defined by go. Basically, all there is to know about it is explained in the comparable section.
Short story: two struct values can be compared if their fields can be compared (no slice, map or function). And same thing for equality: two structs are equal if their fields are equal. In your case, the problem is that for comparing pointers, Golang compares the memory addresses, not the struct they point to.
So, is this possible to count distinct values of a certain struct ? Yes, if the struct contain no nested slice, map, function or pointer. For recursive types, that's not possible because you cannot define something like this:
type tree struct {
left tree
right tree
}
The idiomatic way of testing the equality of recursive types is to use reflect.DeepEqual(t1, t2 interface{}) as it follows indirections. However, this method is inefficient because uses heavy reflection. In your case, I do not think there is any clean and elegant solution to get what you want.
I have a variable of type value that stores a map, but I can not access the values by providing the keys:
rascal>a
value: ("s":"s")
rascal>a["s"]
|stdin:///|(2,3,<1,2>,<1,5>): subscript not supported on value at |stdin:///|(2,3,<1,2>,<1,5>)
☞ Advice
How can I parse the value to map in order to be able to retrieve my value ?
if (map[str,str] myMap := a) {
// do stuff with myMap
}
else {
throw "<a> is not a map?";
}
Another way of "narrowing types" is using pattern matching in function parameters:
rascal>value x = 1;
int: 1
rascal>int myFunc(int i) = 2 * i;
ok
rascal>myFunc(x);
int: 2
And yet another way is using visit or switch:
visit(bigValue) {
case Expression e => ...work with e...
}
The general idea is:
pattern matching means narrowing (downcasting)
pattern matching may fail and so is always in a conditional context
there are many places in Rascal where you can use pattern matching: function dispatch, switch, visit, :=, <-
There are articles and presentations about functional style programming in D (e.g. http://www.drdobbs.com/architecture-and-design/component-programming-in-d/240008321). I never used D before, but I'm interested in trying it. Is there a way to write code in D similar to this Python expression:
max(x*y for x in range(N) for y in range(x, N) if str(x*y) == str(x*y)[::-1])
Are there D constructs for generators or list (array) comprehensions?
Here's one possible solution, not particularly pretty:
iota(1,N)
.map!(x =>
iota(x,N)
.map!(y => tuple(x,y)))
.joiner
.map!(xy => xy[0]*xy[1])
.filter!(xy => equal(to!string(xy), to!string(xy).retro))
.reduce!max;
So what this actually does is create a range from 1 to N, and map each element to a range of tuples with your x,y values. This gives you a nested range ([[(1,1),(1,2)],[(2,2)]] for N = 2).
We then join this range to get a range of tuples ([(1,1),(1,2),(2,2)] for N = 2).
Next we map to x*y (D's map does for some reason not allow for unpacked tuples, so we need to use indexing).
Penultimately we filter out non-palindromes, before finally reducing the range to its largest element.
Simple answer, no, D does not have generators or list comprehensions (AFAIK). However, you can create a generator using an InputRange. For that solution, see this related question: What is a "yield return" equivalent in the D programming language?
However, your code isn't using generators, so your code could be translated as:
import std.algorithm : max, reduce, retro, equal;
import std.conv : to;
immutable N = 13;
void main() {
int[] keep;
foreach(x; 0 .. N) {
foreach(y; x .. N) {
auto val = x*y;
auto s = to!string(val);
if (equal(s, s.retro)) // reverse doesn't work on immutable Ranges
keep ~= val; // don't use ~ if N gets large, use appender instead
}
}
reduce!max(keep); // returns 121 (11*11)
}
For me, this is much more readable than your list comprehension because the list comprehension has gotten quite large.
There may be a better solution out there, but this is how I'd implement it. An added bonus is you get to see std.algorithm in all its glory.
However, for this particular piece of code, I wouldn't use the array to save on memory and instead store only the best value to save on memory. Something like this:
import std.algorithm : retro, equal;
import std.conv : to;
immutable N = 13;
void main() {
int best = 0;
foreach(x; 0 .. N) {
foreach(y; x .. N) {
auto val = x*y;
auto s = to!string(val);
if (equal(s, s.retro))
best = val;
}
}
}
I have to copy certain elements from a std::map into a vector.
It should work like in this loop:
typedef int First;
typedef void* Second;
std::map<First, Second> map;
// fill map
std::vector<Second> mVec;
for (std::map<First, Second>::const_iterator it = map.begin(); it != map.end(); ++it) {
if (it->first % 2 == 0) {
mVec.push_back (it->second);
}
}
Since I'd like to avoid using any functors, but use boost::lambda instead, I tried using std::copy, but can't get it right.
std::copy (map.begin(), map.end(), std::back_inserter(mVec)
bind(&std::map<int, void*>::value_type::first, _1) % 2 == 0);
I'm new to lambda expressions, and I can't figure it out how to use them correctly.
I didn't get any useful results on Google or StackOverflow either.
This question is similar
What you would need in STL would be a transform_if algorithm. Then you would have to write:
transform_if (mymap.begin(), mymap.end(),
back_inserter(myvec),
bind(&std::map<First, Second>::value_type::second, _1) ,
(bind(&std::map<First, Second>::value_type::first, _1) % 2) == 0 );
The code for transform_if is taken from this unrelated question and it is:
template<class InputIterator, class OutputIterator, class UnaryFunction, class Predicate>
OutputIterator transform_if(InputIterator first,
InputIterator last,
OutputIterator result,
UnaryFunction f,
Predicate pred)
{
for (; first != last; ++first)
{
if( pred(*first) )
*result++ = f(*first);
}
return result;
}
I think there is no other way to perform both steps (transform and conditional copy) at once using STL algorithms.
You can use boost range adaptors to achieve that.
using namespace boost::adaptors;
boost::copy( map | filtered( [] (const pair<First,Second> &p)->bool {return p.first % 2 == 0;})
| transformed( [] (const pair<First,Second> &p) {return p.second;}),
std::back_inserter(mVec));