I have a groovy collections which is an array, containing value starting from 0 through 'n'. I need to find a particular array index when a series of conditions occured. And,I do not need to scan through every value of the array but can jump across pre-defined intervals. For example, look for the condition for every 10 values in the array. Can someone tell me a way to do this?
For example, I want to do somehting like this below
def alltimes = [0 . . . . . 10000]
def end_time = 10000
def time = 0
while(time <= end_time)
{
// check the condition for alltimes[time]
if(condition_satisfied){
println "condition satisfied at time ${time}"
break
}
time = time + 50
}
When i explored all available methods of array, i did not find any one which can allow to jump variables instead of just one as in methods each, eachwithindex.
Seems like I need to use metaclass and create a new method?
You can use find for this:
def allTimes = 0..10000
Closure<Boolean> checkCondition = { all, single ->
single > 300
}
(0..10000).step( 50 ).find { time -> checkCondition( allTimes, time ) }
Which is ripe for currying:
def allTimes = 0..10000
Closure<Boolean> checkCondition = { all, single ->
single > 300
}
(0..10000).step( 50 ).find checkCondition.curry( allTimes )
Related
for my code I want all numbers from a dictionary under 70 to be deleted, I'm unsure of how to specify this and I need it to also delete the associated name with that number as well, either that or only diplay numbers that are 70 or above.
Below is the code that I have in it's entirety:
name = []
number =[]
name_grade = {}
counter = 0
counter_bool= True
num_loop = True
while counter_bool:
stu = int(input("please enter the number of students: "))
if stu < 2:
print("value is too low, try again")
continue
else:
break
while counter != stu:
name_inp = str(input("Enter your name: "))
while num_loop:
number_inp = int(input("Enter your number: "))
if number_inp < 0 or number_inp > 100:
print("The value is too high or too low, please enter a number between 0 and 100.")
continue
else:
break
name_grade[name_inp] = number_inp
name.append(name_inp)
number.append(number_inp)
counter += 1
print(name_grade)
sorted_numbers = sorted(name_grade.items(), key= lambda x:x[1])
print(sorted_numbers)
if number > 70:
resorted_numbers = number < 70
print(resorted numbers)
how would I go about this?
Also if it's also not too much trouble could someone explain in detail about dictionary keys and how the lambda function I've used works? I got help but I would prefer to know the small details on how it's applied and formatted but don't worry if it's a pain to explain.
You can just iterate over the dictionary and filter for values less than 70:
resorted_numbers = {k:v for k,v in name_grade.items() if v<70}
dict.items method returns a list of key-value tuple pairs of a dictionary, so the lambda function is telling the sorted function to sort by the second element in each tuple.
Please help me understand how the following code always returns the smallest value in the array. I tried moving position of 3 but it always manages to return it irrespective of the position of it in the array.
let myA = [12,3,8,5]
let myN = 4
function F4(A,N)
{
if(N==1){
return A[0]
}
if(F4(A,N-1) < A[N-1]){
return F4(A,N-1)
}
return A[N-1]
}
console.log(F4(myA,myN))
This is quite tricky to get an intuition for. It's also quite important that you learn the process for tackling this type of problem rather than simply be told the answer.
If we take a first view of the code with a few comments and named variables it looks like this:
let myA = [12,3,8,5];
let myN = myA.length;
function F4(A, N) {
// if (once) there is only one element in the array "A", then it must be the minimum, do not recurse
if (N === 1){
return A[0]
}
const valueFromArrayLessLastEl = F4(A,N-1); // Goes 'into' array
const valueOfLastElement = A[N-1];
console.log(valueFromArrayLessLastEl, valueOfLastElement);
// note that the recursion happens before min(a, b) is evaluated so array is evaluated from the start
if (valueFromArrayLessLastEl < valueOfLastElement) {
return valueFromArrayLessLastEl;
}
return valueOfLastElement;
}
console.log(F4(myA, myN))
and produces
12 3 // recursed all the way down
3 8 // stepping back up with result from most inner/lowest recursion
3 5
3
but in order to gain insight it is vital that you approach the problem by considering the simplest cases and expand from there. What happens if we write the code for the cases of N = 1 and N = 2:
// trivially take N=1
function F1(A) {
return A[0];
}
// take N=2
function F2(A) {
const f1Val = F1(A); // N-1 = 1
const lastVal = A[1];
// return the minimum of the first element and the 2nd or last element
if (f1Val < lastVal) {
return f1Val;
}
return lastVal;
}
Please note that the array is not being modified, I speak as though it is because the value of N is decremented on each recursion.
With myA = [12, 3, 8, 5] F1 will always return 12. F2 will compare this value 12 with 3, the nth-1 element's value, and return the minimum.
If you can build on this to work out what F3 would do then you can extrapolate from there.
Play around with this, reordering the values in myA, but crucially look at the output as you increase N from 1 to 4.
As a side note: by moving the recursive call F4(A,N-1) to a local constant I've prevented it being called twice with the same values.
First off, let me warn you that my Maths knowledge is fairly limited (hence my coming here to ask about this).
It's a silly example, but what I essentially want is to have a variable number of rows, and be able to set a maximum value, then for each progressive row decrease that value until half way at which point start increasing the value again back up to the maximum by the final row.
To illustrate this... Given that: maxValue = 20, and rows = 5, I need to be able to get to the following values for the row values (yes, even the 0):
row 1: 20
row 2: 10
row 3: 0
row 4: 10
row 5: 20
There are limitations though because I'm trying to do this in Compass which uses SASS. See here for the available operations, but to give you the gist of it, only basic operations are available.
I'm able to loop through the rows, so just need the calculation that will work for each individual row in the series. This is the kind of loop I'm able to use:
$maxValue:20;
$rows:5;
#for $i from 1 through $rows {
// calculation here.
}
I haven't really worked with SASS before, but try something like this using a basic if and the floor function, not sure if will work
// set various variables
$maxValue:20;
$rows:5;
// get row number before middle row, this instance it will be 2
$middleRow = floor( $maxValue / $rows )
// get increment amount, this instance should be 10
$decreaseValue = ( max / floor( rows / 2) )
#for $i from 0 through $rows - 1 {
#if $i <= $middleRow {
( $maxValue- ( $decreaseValue * $i ) )
}
#else{
// times by -1 to make positive value
( $maxValue - ( $decreaseValue * -$i ) ) * -1
}
}
I have tested the above in js ( with relative syntax ) and it yielded the required results ( jsBin example ). Hope this helps
So I have a table that holds references to other tables like:
local a = newObject()
a.collection = {}
for i = 1, 100 do
local b = newObject()
a[#a + 1] = b
end
Now if I want to see if a particular object is within "a" I have to use pairs like so:
local z = a.collection[ 99 ]
for i,j in pairs( a.collection ) do
if j == z then
return true
end
end
The z object is in the 99th spot and I would have to wait for pairs to iterate all the way throughout the other 98 objects. This set up is making my program crawl. Is there a way to make some sort of key that isn't a string or a table to table comparison that is a one liner? Like:
if a.collection[{z}] then return true end
Thanks in advance!
Why are you storing the object in the value slot and not the key slot of the table?
local a = newObject()
a.collection = {}
for i = 1, 100 do
local b = newObject()
a.collection[b] = i
end
to see if a particular object is within "a"
return a.collection[b]
If you need integer indexed access to the collection, store it both ways:
local a = newObject()
a.collection = {}
for i = 1, 100 do
local b = newObject()
a.collection[i] = b
a.collection[b] = i
end
Finding:
local z = a.collection[99]
if a.collection[z] then return true end
Don't know if it's faster or not, but maybe this helps:
Filling:
local a = {}
a.collection = {}
for i = 1, 100 do
local b = {}
a.collection[b] = true -- Table / Object as index
end
Finding:
local z = a.collection[99]
if a.collection[z] then return true end
If that's not what you wanted to do you can break your whole array into smaller buckets and use a hash to keep track which object belongs to which bucket.
you might want to consider switching from using pairs() to using a regular for loop and indexing the table, pairs() seems to be slower on larger collections of tables.
for i=1, #a.collection do
if a.collection[i] == z then
return true
end
end
i compared the speed of iterating through a collection of 1 million tables using both pairs() and table indexing, and the indexing was a little bit faster every time. try it yourself using os.clock() to profile your code.
i can't really think of a faster way of your solution other than using some kind of hashing function to set unique indexes into the a.collection table. however, doing this would make getting a specific table out a non-trivial task (you wouldn't just be able to do a.collection[99], you'd have to iterate through until you found one you wanted. but then you could easily test if the table was in a.collection by doing something like a.collection[hashFunc(z)] ~= nil...)
Let's say I have a closure:
def increment = {value, step ->
value + step
}
Now I want to loop over every item of my integers collection, increment it with 5, and save new elements to a new collection:
def numbers = [1..10]
def biggerNumbers = numbers.collect {
it + 5
}
And now I want to achieve the same result but by means of using increment closure. How can I do this?
Should be something like this (wrong code below):
def biggerNumbers = numbers.collect increment(it, 5) //what's the correct name of 'it'??
The solution to your problem would be nesting your call of increment in a closure:
def biggerNumbers = numbers.collect {increment(it, 5)}
If you wanted to pass a premade closure to the collect you should have made it compatible with collect - accepting a single parameter that is:
def incrementByFive = {it + 5}
def biggerNumbers = numbers.collect incrementByFive
mojojojo has the right answer, but just thought I'd add that this looks like a good candidate for currying (specifically using rcurry)
If you have:
def increment = {value, step ->
value + step
}
You can then curry the right-hand parameter of this function with:
def incrementByFive = increment.rcurry 5
And then, you can do:
def numbers = 1..10
def biggerNumbers = numbers.collect incrementByFive
Just thought it might be of interest ;-)
The main issue is that [1..10] creates a List<IntRange> which you are trying to increment. You should collect on the IntRange directly (note the lack of brackets):
(1..10).collect { it + 5 }
Or with curry:
def sum = { a, b -> a + b }
(1..10).collect(sum.curry(5))