I explore the usage of activityOf(state_0, change, picture) in CodeWorld framework.
The state is described as a tuple. I test the possibility to let one of the elements in the tuple to be a list, since I think that would be very useful and make coding more compact.
In the example below I show that it seems to work if I just print out the first element u1 in the u_list. I can control the value by keys for up and down and time t goes on. The second element u2 in the u_list is simply there and not changed.
program = activityOf(state_0, change, picture)
state_0(rs) = (t0, u_list_0)
u_list_0 = [u10,u20]
t0 = 0
u10 = 0
u20 = 7
t_of((t_value,_)) = t_value
u1_of((_, ulist)) = ulist#1
u2_of((_, ulist)) = ulist#2
change((t, u_list), KeyPress("Up")) = (t_of((t,u_list)), [u1_of((t, u_list))+1])
change((t, u_list), KeyPress("Down")) = (t_of((t,u_list)), [u1_of((t, u_list))-1])
change((t, u_list), TimePassing(dt)) = (t_of((t,u_list))+dt, u_list)
change((t, u_list), other) = (t, u_list)
picture((t, u_list)) = pictures [translated(lettering(printed(t_of((t, u_list)))),0,1),
lettering(printed(u1_of((t, u_list))))]
However, if I change the example on the last row to just print out u2, i.e. change u1_of (..) to u2_of(..) then I get get no compilation error and the program runs. But if I press any of the keys up and down then I get a runtime error for the line 11 of the code where u2_of() is defined.
Error message:
List index is too large.
When evaluating: error, called in the standard library idxErrorTooLarge, called
in the standard library #, used at Line 11, Column 21 in your code
What is going on here?
Is it at all possible to use a list as one element in the state tuple?
Link to run https://code.world/#PBKh1Aucqqxg48ePyxxAuUg
In your up and down key handlers, you are changing the list to have only one element:
change((t, u_list), KeyPress("Up")) = (t_of((t,u_list)), [u1_of((t, u_list))+1])
change((t, u_list), KeyPress("Down")) = (t_of((t,u_list)), [u1_of((t, u_list))-1])
^^^^^^^^^^^^^^^^^^^^^^
If you ask for the second element of the list (as picture does) after pressing one of those keys, there won't be one to access. You might want something like:
[u1_of((t, u_list))-1, u2_of(t, u_list)]
As a stylistic comment: it's fairly unusual to use accessor functions like this in Haskell if pattern matching gets you where you want to go. For example, this would be a bit more idiomatic:
change ((t, [r, c]), KeyPress "Up" ) = (t, [r+1, c])
change ((t, [r, c]), KeyPress "Down") = (t, [r-1, c])
This would be much more idiomatic:
data GameState = GameState
{ t :: Int
, r :: Int
, c :: Int
}
change (s, KeyPress "Up" ) = s { r = r s + 1 }
change (s, KeyPress "Down") = s { r = r s - 1 }
One benefit of this final style is that it's not possible to accidentally create a "list" with the wrong number of elements.
Related
Hi I'm starting to play around with NIM
I get a "can't evaluate at compile time" error on this code:
import strutils
type
Matrix[x, y: static[int], T] = object
data: array[x * y, T]
var n,m: int = 0
proc readFile() =
let f = open("matrix.txt")
defer: f.close()
var graph_size = parseInt(f.readline)
var whole_graph: Matrix[graph_size, graph_size, int]
for line in f.lines:
for field in line.splitWhitespace:
var cell = parseInt(field)
whole_graph[n][m] = cell
m = m + 1
n = n + 1
readFile()
Any help appreciated.
Unless you absolutely positively need array in this scenario while not knowing its size at compile-time, you may want to rather swap to the seq type, whose size does not need to be known at compile-time.
Together with std/enumerate you can even save yourself the hassle of tracking the index with n and m:
import std/[strutils, enumerate]
type Matrix[T] = seq[seq[T]]
proc newZeroIntMatrix(x: int, y: int): Matrix[int] =
result = newSeqOfCap[seq[int]](x)
for i in 0..x-1:
result.add(newSeqOfCap[int](y))
for j in 0..y-1:
result[i].add(0)
proc readFile(): Matrix[int] =
let f = open("matrix.txt")
defer: f.close()
let graph_size = parseInt(f.readline)
var whole_graph = newZeroIntMatrix(graph_size, graph_size)
for rowIndex, line in enumerate(f.lines):
for columnIndex, field in enumerate(line.split):
let cell = parseInt(field)
whole_graph[rowIndex][columnIndex] = cell
result = whole_graph
let myMatrix = readFile()
echo myMatrix.repr
Further things I'd like to point out though are:
array[x * y, T] will not give you a 2D array, but a single array of length x*y. If you want a 2D array, you would most likely want to store this as array[x, array[y, T]]. That is assuming that you know x and y at compile-time, so your variable declaration would look roughly like this: var myMatrix: array[4, array[5, int]]
Your Matrix type has the array in its data field, so trying to access the array with that Matrix type needs to be done accordingly (myMatrix.data[n][m]). That is, unless you define proper []and []= procs for the Matrix type that do exactly that under the hood.
I'm working on a Julia project which requires matrices to satisfy a trace-one constraint. To avoid checking if matrices are trace-one at inputs and outputs of numerous functions, I'd like to create a new data structure which implicitly contains this constraint.
In my working example, I've defined a struct TraceOne which throws an error if the trace is not equal to one.
struct TraceOne
M :: Matrix{Complex{Float64}}
TraceOne(M) = (tr(M) == 1) ? new(M) : throw(DomainError(M, "Matrix M is not trace-one."))
end
A = TraceOne([0.1 0.5;0.3 0.9])
However, I would like to avoid accessing the trace-one matrix with a key, A.M returns [0.1 0.5;0.3 0.9].
Alternatively, I've tried to create a struct which is a SubType of an AbstractMatrix, but I can't get the values of the AbstractMatrix to initialize properly.
struct TraceOne2 <: AbstractMatrix{Complex{Float64}}
M :: Matrix{Complex{Float64}}
Base.size(T::TraceOne2) = size(T.M)
Base.getindex(T::TraceOne2, I::Vararg{Int,2}) = getindex(T.M, size(T.M)...)
Base.setindex!(T::TraceOne2, v, I::Vararg{Int,2}) = (T.M[I] = v)
TraceOne2(M) = (tr(M) == 1) ? new(M) : throw(DomainError(M, "Matrix M is not trace-one."))
end
B = TraceOne2([0.1 0.5;0.3 0.9])
When I run this code, I find that B is [0.9 0.9;0.9 0.9]. All elements of B are initialized to the value of the (2,2), the index of the input array.
How should I modify struct TraceOne2 ... end such that the resulting matrix B is initialized as [0.1 0.5;0.3 0.9]?
Change this functions from:
Base.getindex(T::TraceOne2, I::Vararg{Int,2}) = getindex(T.M, size(T.M)...)
Base.setindex!(T::TraceOne2, v, I::Vararg{Int,2}) = (T.M[I] = v)
to:
Base.getindex(T::TraceOne2, I::Vararg{Int,2}) = getindex(T.M, I...)
Base.setindex!(T::TraceOne2, v, I::Vararg{Int,2}) = (T.M[I...] = v)
here is the code:
val a = "abcabca"
a.groupBy((c: Char) => a.count( (d:Char) => d == c))
here is the result I want:
scala.collection.immutable.Map[Int,String] = Map(2 -> b, 2 -> c, 3 -> a)
but the result I get is
scala.collection.immutable.Map[Int,String] = Map(2 -> bcbc, 3 -> aaa)
why?
thank you.
Write an expression like
"abcabca".groupBy(identity).collect{
case (k,v) => (k,v.length)
}
which will give output as
res0: scala.collection.immutable.Map[Char,Int] = Map(b -> 2, a -> 3, c -> 2)
Let's dissect your initial attempt :
a.groupBy((c: Char) => a.count( (d:Char) => d == c))
So, you're grouping by something which is what ? the result of a.count(...), so the key of your Map will be an Int. For the char a, we will get 3, for the chars b and c, we'll get 2.
Now, the original String will be traversed and for the results accumulated, char by char.
So after traversing the first "ab", the current state is "2-> b, 3->c". (Note that for each char in the string, the .count() is called, which is a n² wasteful algorithm, but anyway).
The string is progressively traversed, and at the end the accumulated results is shown. As it turns out, the 3 "a" have been sent under the "3" key, and the b and c have been sent to the key "2", in the order the string was traversed, which is the left to right order.
Now, a usual groupBy on a list returns something like Map[T, List[T]], so you may have expected a List[Char] somewhere. It doesn't happen (because the Repr for String is String), and your list of chars is effectively recombobulated into a String, and is given to you as such.
Hence your final result !
Your question header reads as "Scala count chars in a string logical error". But you are using Map and you wanted counts as keys. Equal keys are not allowed in Map objects. Hence equal keys get eliminated in the resulting Map, keeping just one, because no duplicate keys are allowed. What you want may be a Seq of tuples like (count, char) like List[Int,Char]. Try this.
val x = "abcabca"
x.groupBy(identity).mapValues(_.size).toList.map{case (x,y)=>(y,x)}
In Scal REPL:
scala> x.groupBy(identity).mapValues(_.size).toList.map{case (x,y)=>(y,x)}
res13: List[(Int, Char)] = List((2,b), (3,a), (2,c))
The above gives a list of counts and respective chars as a list of tuples.So this is what you may really wanted.
If you try converting this to a Map:
scala> x.groupBy(identity).mapValues(_.size).toList.map{case (x,y)=>(y,x)}.toMap
res14: scala.collection.immutable.Map[Int,Char] = Map(2 -> c, 3 -> a)
So this is not what you want obviously.
Even more concisely use:
x.distinct.map(v=>(x.filter(_==v).size,v))
scala> x.distinct.map(v=>(x.filter(_==v).size,v))
res19: scala.collection.immutable.IndexedSeq[(Int, Char)] = Vector((3,a), (2,b), (2,c))
The problem with your approach is you are mapping count to characters. Which is:
In case of
val str = abcabca
While traversing the string str a has count 3, b has count 2 and c has count 2 while creating the map (with the use of groupBy) it will put all the characters in the value which has the same key that is.
Map(3->aaa, 2->bc)
That’s the reason you are getting such output for your program.
As you can see in the definition of the groupBy function:
def
groupBy[K](f: (A) ⇒ K): immutable.Map[K, Repr]
Partitions this traversable collection into a map of traversable collections according to some discriminator function.
Note: this method is not re-implemented by views. This means when applied to a view it will always force the view and return a new traversable collection.
K
the type of keys returned by the discriminator function.
f
the discriminator function.
returns
A map from keys to traversable collections such that the following invariant holds:
(xs groupBy f)(k) = xs filter (x => f(x) == k)
That is, every key k is bound to a traversable collection of those elements x for which f(x) equals k.
GroupBy returns a Map which holds the following invariant.
(xs groupBy f)(k) = xs filter (x => f(x) == k)
Which means it return collection of elements for which the key is same.
in designing an algebraic equation modelling system, I had this dilemma: we cannot associate properties to a number, if I turn the number to a table with a field "value" for example, I can overload arithmetic operators, but not the logic operator since that only works when both operands have same metatable, while my users will compare "x" with numbers frequently.
For example, here is a minimal equation solver system:
x = 0
y = 0
eq1 = {function() return 2*x + 3*y end, rhs = 1 }
eq2 = {function() return 3*x + 2*y end, rhs = 2 }
p = {{x,y},{eq1, eq2}}
solve(p)
The "solve()" will process table "p" to get all coefficients of the equation system and rhs. However, it is essential, a user can associate properties to "x" and "y", for example, lower bound, upper bound. I tries using table,
x = {val=0, lb=0, ub=3}
y = {val=1,lb=3,ub=5}
....
and write metamethods for "x" and "y" such that arithmetic operating will act on x.val and y.val. However, in a scripting environment, we also need to compare "x" with numbers, i.e., "if x>0 then ...". And I stuck here. An ugly solution is to ask users to use x.val, y.val everywhere in modelling the equation and scripting. Does anyone here has similar need to associate properties to a number, and the number can still be used in arithmetic/logic operations?
Something like this could work:
x = {val = 10}
mt = {}
mt.__lt = function (op1, op2)
if (type(op1) == 'table') then a = op1.val else a = op1 end
if (type(op2) == 'table') then b = op2.val else b = op2 end
return a < b
end
setmetatable(x, mt)
print(x < 5) -- prints false
print(x < 15) -- prints true
print(x < x) -- prints false
print(5 < x) -- prints true
Of course, you would write similar methods for the other operators (__add, __mul, __eq and so on).
If you'd rather not use type()/reflection, you can use an even dirtier trick that takes advantage of the fact that unary minus is well, unary:
mt = {}
mt.__unm = function (num) return -(num.val) end
mt.__lt = function (a, b) return -(-a) < -(-b) end
This is rather simple if you have access to the debug library, do you?
debug.setmetatable(0, meta)
meta will be the metatable of ALL numbers. This will solve your logical overloading problem.
However if you would prefer assigning properties to numbers, there is a way you could do this, I wrote a quick example on how one would do so:
local number_props = {
{val="hi"},
{val="hi2"}
}
debug.setmetatable(0,{__index=function(self,k)return number_props[self][k]end})
print((1).val, (2).val)
How would you print() out or find out the index of an object?
For example, if I spawned 20 random rock objects on screen into an array RockTable = {};
Like this RockTable[#RockTable + 1] = rock;
And all 20 rocks are displayed on screen how would I find out what key or index each rock has by clicking on them?
I'm using Corona SDK.
Any help would be greatly appreciated.
Invert the table:
function table_invert(t)
local u = { }
for k, v in pairs(t) do u[v] = k end
return u
end
You can then use the inverted table to find the index.
I find this function so useful that it goes into my permanent "Lua utilities" libraries.
There's another way you can do it, using metamethods.
[Edited to allow you to remove values too]
t = {} -- Create your table, can be called anything
t.r_index = {} -- Holds the number value, i.e. t[1] = 'Foo'
t.r_table = {} -- Holds the string value, i.e. t['Foo'] = 1
mt = {} -- Create the metatable
mt.__newindex = function (self, key, value) -- For creating the new indexes
if value == nil then -- If you're trying to delete an entry then
if tonumber(key) then -- Check if you are giving a numerical index
local i_value = self.r_index[key] -- get the corrosponding string index
self.r_index[key] = nil -- Delete
self.r_table[i_value] = nil
else -- Otherwise do the same as above, but for a given string index
local t_value = self.r_table[key]
self.r_index[t_value] = nil
self.r_table[key] = nil
end
else
table.insert(self.r_index, tonumber(key), value) -- For t[1] = 'Foo'
self.r_table[value] = key -- For t['Foo'] = 1
end
end
mt.__index = function (self, key) -- Gives you the values back when you index them
if tonumber(key) then
return (self.r_index[key]) -- For For t[1] = 'Foo'
else
return (self.r_table[key]) -- For t['Foo'] = 1
end
end
setmetatable(t, mt) -- Creates the metatable
t[1] = "Rock1" -- Set the values
t[2] = "Rock2"
print(t[1], t[2]) -- And *should* proove that it works
print(t['Rock1'], t['Rock2'])
t[1] = nil
print(t[1], t[2]) -- And *should* proove that it works
print(t['Rock1'], t['Rock2'])
It's more versatile as you can copy the t value and take it with you; it also means that you only have to play around with the one variable most of the time - hopefully should reduce the likelihood of you trying to access the wrong thing.
The simplest way is to add an "index" property to each rock:
RockTable = {}
for i=1,20 do
local rock
-- do your thing that generates a new 'rock' object
rock.index = #RockTable + 1
RockTable[rock.index] = rock
end
If you use a touch listener method, you can retrieve the rock this way:
function touchListener( event )
local rock = event.target
local rockIndex = rock.index
-- ...
end
It is true that you can maintain a second table with indices, but I find my method cleaner - when it is time to remove things, you only have to worry about one table, the main one.
I have a question though: why do you need to retrieve that index? In most cases, well designed event listener functions are enough, you don't need to "find" your objects. Of course I lack information on what you are trying to do, but it is possible that you are over-complicating things.
you could do something like this to save you some trouble of constantly looping over a table to find the index...
RockTable = {}
RockIndicies = {}
for i = 1, 20 do
idx = #RockTable + 1
RockTable[idx] = rock
RockIndicies[rock] = idx
end
then when you need to know the index, you can just use the rock you have to index RockIndices to quickly get it. If you 'delete' a rock, you'd want to make sure to remove it in both places.
Unfortunately you'd need to brute the table, to my knowledge. Although, to know that one was clicked, wouldn't you need to be looping them in some way anyway; and therefore already know the index?
Edit
Oh, unless Corona has some sort of callback event for clicking. I've never used it, I've got experience in Lua though.
You could maybe do a backwards reference, like so:
Rocks = {a rock, a rockB, a rockC}
RocksB = {[a rock] = 1, [a rockB] = 2, [a rockC] = 3}
Then just say rockNum = RocksB[rock]
I'm pretty certain that should work but I can't guarantee it, worth a try though.
Edit2
The brute method would look somewhat like:
function getRock(rock)
for _,v in pairs(rocks) do
if (v == rock)
return _
end
end
return "Rock does not exist."
end