Scala repeat Array - arrays

I am a newbie to scala. I try to write a function that is "repeating" an Array (Scala 2.9.0):
def repeat[V](original: Array[V],times:Int):Array[V]= {
if (times==0)
Array[V]()
else
Array.concat(original,repeat(original,times-1)
}
But I am not able to compile this (get an error about the manifest)...

You need to ask compiler to provide class manifest for V:
def repeat[V : Manifest](original: Array[V], times: Int): Array[V] = ...
The answer to question: why is that needed, you can find here:
Why is ClassManifest needed with Array but not List?
I'm not sure where you want to use it, but I can generally recommend you to use List or other suitable collection instead of Array.

BTW, an alternative way to repeat a Array, would be to "fill" a Seq with references of the Array and then flatten that:
def repeat[V: Manifest](original: Array[V], times: Int) : Array[V] =
Seq.fill(times)(original).flatten.toArray;

Related

Optimizing custom fill of a 2d array in Julia

I'm a little new to Julia and am trying to use the fill! method to improve code performance on Julia. Currently, I read a 2d array from a file say read_array and perform row-operations on it to get a processed_array as follows:
function preprocess(matrix)
# Initialise
processed_array= Array{Float64,2}(undef, size(matrix));
#first row of processed_array is the difference of first two row of matrix
processed_array[1,:] = (matrix[2,:] .- matrix[1,:]) ;
#last row of processed_array is difference of last two rows of matrix
processed_array[end,:] = (matrix[end,:] .- matrix[end-1,:]);
#all other rows of processed_array is the mean-difference of other two rows
processed_array[2:end-1,:] = (matrix[3:end,:] .- matrix[1:end-2,:]) .*0.5 ;
return processed_array
end
However, when I try using the fill! method I get a MethodError.
processed_array = copy(matrix)
fill!(processed_array [1,:],d[2,:]-d[1,:])
MethodError: Cannot convert an object of type Matrix{Float64} to an object of type Float64
I'll be glad if someone can tell me what I'm missing and also suggest a method to optimize the code. Thanks in advance!
fill!(A, x) is used to fill the array A with a unique value x, so it's not what you want anyway.
What you could do for a little performance gain is to broadcast the assignments. That is, use .= instead of =. If you want, you can also use the #. macro to automatically add dots everywhere for you (for maybe cleaner/easier-to-read code):
function preprocess(matrix)
out = Array{Float64,2}(undef, size(matrix))
#views #. out[1,:] = matrix[2,:] - matrix[1,:]
#views #. out[end,:] = matrix[end,:] - matrix[end-1,:]
#views #. out[2:end-1,:] = 0.5 * (matrix[3:end,:] - matrix[1:end-2,:])
return out
end
For optimal performance, I think you probably want to write the loops explicitly and use multithreading with a package like LoopVectorization.jl for example.
PS: Note that in your code comments you wrote "cols" instead of "rows", and you wrote "mean" but take a difference. (Not sure it was intentional.)

Develop a class a one-dimensional array and two instances of this class

My task:
 Create 2 class objects. Delete all elements in the first object that are contained in the second.
My implementation:
class Vector
def initialize
#vector = Array.new
end
end
vector1 = Vector.new(1,2,3,4,5,6,7)
vector2 = Vector.new(3,6,7)
But this does not work as needed. What should I fix?
I think it is some sort of question from institute, and requirements are different than what you coded, I am just trying to correct your coding and rectify so you get some result, than you can further proceed to full-fill your requirements.
Your first mistake is you are asking for one parameter but providing
commas is giving multiple parameters, so I have changed it to get
array.
As changed array so now you can't add another array in first, as it
is just one array so I am removing << and adding = in initialize
method
Your initialize method is not taking any parameter, but you are
providing, but you have to define a method set_vector so you have
to use that method instead of class, as per your requirement that is
what you want.
You should define - method but than you have to play with class
variables too, as you are playing with two object and with in your
class you have to define - function, but I am here just using your
get_vector method to compare arrays and return your response.
changing put to print so you can have variables instead of all items.
Hope this will give you some helpful insight to coding.
class Vector
def initialize
#vector = Array.new
end
def set_vector=(vector)
#vector = vector
end
def get_vector
#vector
end
end
def confront(first_vector, second_vector)
first_vector.get_vector - second_vector.get_vector
end
first_vector = Vector.new
first_vector.set_vector=[1,2,3,4,5,6,7]
second_vector = Vector.new
second_vector.set_vector=[3,6,7]
final_vector = confront(first_vector, second_vector)
begin
puts "First:"
print first_vector.get_vector
puts "\nSecond:"
print second_vector.get_vector
puts "\nFinal Vector:"
print final_vector
end

Adding elements to a Map in F# using a for loop

Code:
let studentMap =
for i = 0 to count do
Map.empty.Add(students.[i].getId(), students.[i].getScores())
I am trying to add to a map sequentially. I have student objects in an array and am trying to add them in order. I am confused at how to do this. I thought maybe you make an empty map then add to it in order via a for loop, but it always causes trouble and won't work. Is there a way to add items to a map using a for loop? The <key/value> pairs are this: <string, int array>. That is the way I want it formatted but it keeps giving me trouble. I'll restate the goal again to clarify: I want to be able to add items to a map using a for loop with my student objects array being used to get the appropriate data I need in there. I will be able to give it a string and get back that student's grades for example. I know it's a weird problem I'm working on, but I needed to try something simple at first.
You can try a more functional idiomatic approach:
Let's say you have an array of type Student (in the example below is an empty array):
let students = Array.empty<Student>
You can transform your array in to a Map:
let mapStudents = students
|> Array.map (fun s -> (s.getId(), s.getScore()))
|> Map.ofArray
You could use a mutable map variable:
let studentMap =
let mutable m <- Map.empty
for i = 0 to count do
m <- m.Add(students.[i].getId(), students.[i].getScores())
m
or a mutable dictionary:
let studentMap =
let m = new System.Collections.Generic.Dictionary<int, Scores>()
for i = 0 to count do
m.Add(students.[i].getId(), students.[i].getScores())
m
a more functional solution would be to use a fold:
let studentMap = seq { 0 .. count } |> Seq.fold (fun (m: Map<int, Scores>) i -> m.Add(students.[i].getId(), students.[i].getScores())) Map.empty
I think the Map.ofArray approach is probably the best, but it is worthwhile to point out that the for loops can done a bit better:
let map = new System.Collections.Generic.Dictionary<int, Scores>()
for student in students do
map.Add(student.getId(), student.getScore())
This neatly avoids making array bounds mistakes.
In functional languages, the built-in data structures are immutable, that is, when you add an element, a new value of the data structure is returned.
If you want to convert one structure to another, you can often use one of the build-in functions like Map.ofArray. If you have a more complex scenario, like a function generating your values, then you can use a 'loop', and each iteration of the loop returns a new value of the data structure. The way to express such a 'loop' in a functional way, is to use a recursive function:
let studentMap =
let rec loop currentMap i =
if i >= count then currentMap
else
let newMap = Map.add (students.[i].getId()) (students.[i].getScores()) currentMap
loop newMap (i+1)
loop Map.empty 0
Now you have full flexibility in how you generate the values (they don't have to be part of an array) and you're avoiding mutable variables that are un-idiomatic in functional programming. Ideally, like in this case, the function should be tail-recursive to allow tail-call optimisation (and avoid stack overflow for large inputs).

How to stop a loop in Groovy

From the collection fileMatches, I want to assign the maps with the 10 greatest values to a new collection called topTen. So I try to make a collection:
def fileMatches = [:].withDefault{[]}
new File('C:\\BRUCE\\ForensicAll.txt').eachLine { line ->
def (source, matches) = line.split (/\t/)[0, 2]
fileMatches[source] << (matches as int)
I want to iterate through my collection and grab the 10 maps with greatest values. One issue I might be having is that the output of this doesn't look quite like I imagined. One entry for example:
C:\cygwin\home\pro-services\git\projectdb\project\stats\top.h:[984, 984]
The advice so far has been excellent, but I'm not sure if my collection is arranged to take advantage of the suggested solutions (I have filename:[984, 984] when maybe I want [filename, 984] as the map entries in my collection). I don't understand this stuff quite yet (like how fileMatches[source] << (matches as int) works, as it produces the line I posted immediately above (with source:[matches, matches] being the output).
Please advise, and thanks for the help!
Check this another approach, using some Collection's skills. It does what you want with some simplicity...
def fileMatches = [um: 123, dois: 234, tres: 293, quatro: 920, cinco: 290];
def topThree;
topThree = fileMatches.sort({tup1, tup2 -> tup2.value <=> tup1.value}).take(3);
Result:
Result: [quatro:920, tres:293, cinco:290]
You might find it easier to use some of the built-in collection methods that Groovy provides, e.g.:
fileMatches.sort { a, b -> b.someFilename <=> a.someFilename }[0..9]
or
fileMatches.sort { it.someFileName }[-1..-10]
The range on the end there will cause an error if you have < 10 entries, so it may need some adjusting if that's your case.

ruby oneliner vs groovy

i was going through railstutorial and saw the following one liner
('a'..'z').to_a.shuffle[0..7].join
it creates random 7 character domain name like following:
hwpcbmze.heroku.com
seyjhflo.heroku.com
jhyicevg.heroku.com
I tried converting the one liner to groovy but i could only come up with:
def range = ('a'..'z')
def tempList = new ArrayList (range)
Collections.shuffle(tempList)
println tempList[0..7].join()+".heroku.com"
Can the above be improved and made to a one liner? I tried to make the above code shorter by
println Collections.shuffle(new ArrayList ( ('a'..'z') ))[0..7].join()+".heroku.com"
However, apparently Collections.shuffle(new ArrayList ( ('a'..'z') )) is a null
Not having shuffle built-in adds the most to the length, but here's a one liner that'll do it:
('a'..'z').toList().sort{new Random().nextInt()}[1..7].join()+".heroku.com"
Yours doesn't work because Collections.shuffle does an inplace shuffle but doesn't return anything. To use that as a one liner, you'd need to do this:
('a'..'z').toList().with{Collections.shuffle(it); it[1..7].join()+".heroku.com"}
It isn't a one-liner, but another Groovy way to do this is to add a shuffle method to String...
String.metaClass.shuffle = { range ->
def r = new Random()
delegate.toList().sort { r.nextInt() }.join()[range]}
And then you have something very Ruby-like...
('a'..'z').join().shuffle(0..7)+'.heroku.com'
This is my attempt. It is a one-liner but allows repetition of characters. It does not perform a shuffle, though it generates suitable output for a random domain name.
I'm posting it as an example of a recursive anonymous closure:
{ i -> i > 0 ? "${(97 + new Random().nextInt(26) as char)}" + call(i-1) : "" }.call(7) + ".heroku.com"
This is definitely not as pretty as the Ruby counterpart but, as Ted mentioned, it's mostly because of the fact that shuffle method is a static method in Collections.
[*'a'..'z'].with{ Collections.shuffle it; it }.take(7).join() + '.heroku.com'
I am using the spread operator trick to convert the range into a list :)

Resources