Compare two arrays and retrun element with same index - ios

I have 2 inputs adress and street. I need to make 2 arrays size street. One array with odd numbers and another with even numbers. Than i need to reverse odd array. Than I need to check what array contains input adress and to return same index element from another array.
This is error what is show to me:
Fatal error: Unexpectedly found nil while unwrapping an Optional value: file test/solution.swift, line 6
func overTheRoad(address: Int, street: Int) -> Int {
var odd = Array(stride(from: 1, through: street * 2, by: 2))
let even = Array(stride(from: 2, through: street * 2, by: 2))
odd.reverse()
if address % 2 == 0{
let index = even.firstIndex(of: address)!
return odd[index]
}else{
let index = odd.firstIndex(of: address)!
return even[index]
}
}
This is how to suppose work:
You've just moved into a perfectly straight street with exactly n identical houses on either side of the road. Naturally, you would like to find out the house number of the people on the other side of the street. The street looks something like this:
Street
1| |6
3| |4
5| |2
you
Evens increase on the right; odds decrease on the left. House numbers start at 1 and increase without gaps. When n = 3, 1 is opposite 6, 3 opposite 4, and 5 opposite 2.
Example (address, n --> output)
Given your house number address and length of street n, give the house number on the opposite side of the street.
1, 3 --> 6
3, 3 --> 4
2, 3 --> 5
3, 5 --> 8

func overTheRoad(address: Int, street: Int) -> Int? {
var odd = Array(stride(from: 1, through: street * 2, by: 2))
let even = Array(stride(from: 2, through: street * 2, by: 2))
odd.reverse()
if address % 2 == 0{
guard let index = even.firstIndex(of: address) else { return nil }
return odd[index]
}else{
guard let index = odd.firstIndex(of: address) else { return nil }
return even[index]
}
}
Instead of force unwrapping, you should unwrap it safely with a guard let (or if let) statement. In case of no address value is found in the array, you can return nil.

Adding on to Hüsamettin Eyibil's answer, there one big thing that could be improved here: You're generating 2 arrays here, only to query them for a single value and discard the rest. Half the time, each of them isn't even used a single time!
There's actually a pretty simple, closed-form math solution:
func overTheRoad(address: Int, street: Int) -> Int {
let totalHouseCount = street * 2
guard address <= totalHouseCount else {
fatalError("The address number \(address) is too high for a street that's only \(street) houses long!")
}
return totalHouseCount - address + 1
}
// Some test cases:
XCTAssertEqual(overTheRoad(address: 1, street: 3), 6)
XCTAssertEqual(overTheRoad(address: 2, street: 3), 5)
XCTAssertEqual(overTheRoad(address: 3, street: 3), 4)
XCTAssertEqual(overTheRoad(address: 4, street: 3), 3)
XCTAssertEqual(overTheRoad(address: 5, street: 3), 2)
XCTAssertEqual(overTheRoad(address: 6, street: 3), 1)
XCTAssertEqual(overTheRoad(address: 3, street: 5), 8)
Here I chose to fatalError on invalid input, but it might make sense to just return nil instead.

Related

Lua loop shuffle list

i have a problem with my Script if i try to loop thought my list the output is completly random shuffled
minimal Code:
list = {
numbers = {
number1 = 1,
number2 = 2,
number3 = 3,
number4 = 4,
number5 = 5,
number6 = 6,
number7 = 7,
}
}
for k, numbers in pairs(list) do
for k, number in pairs(numbers) do
print(number)
end
end
output:
5
7
2
3
4
6
1
the only fix i figured out is to remove the variables number1 to number7
and just enter the numbers
Lua tables do not have an order.
In addition to that you're using pairs which internally uses next.
From the Lua manual:
The order in which the indices are enumerated is not specified, even
for numeric indices. (To traverse a table in numerical order, use a
numerical for.)
In your case the keys have a numeric component so you could simply create them in a numeric loop.
local numbers = {
number1 = 1,
number2 = 2,
number3 = 3,
number4 = 4,
number5 = 5,
number6 = 6,
number7 = 7,
}
for i = 1, 7 do
print(numbers["number"..i])
end
For other non-numeric keys you would have to use a second table that lists the keys in an ordered sequence:
local numbers = { bob = 1, bill = 3, john = 2}
local orderedKeys = { "bob", "john", "bill"}
for k,v in ipairs(orderedKeys) do
print(numbers[v])
end
A numeric loop will always work for any integer keys.
local numbers = {
[0] = 0,
[5] = 5,
[3] = 3,
[1] = 0,
}
for i = 0, 5 do
if numbers[i] then
print(numbers[i])
end
end
Read through this carefully:
A table with exactly one border is called a sequence. For instance,
the table {10, 20, 30, 40, 50} is a sequence, as it has only one
border (5). The table {10, 20, 30, nil, 50} has two borders (3 and 5),
and therefore it is not a sequence. (The nil at index 4 is called a
hole.) The table {nil, 20, 30, nil, nil, 60, nil} has three borders
(0, 3, and 6) and three holes (at indices 1, 4, and 5), so it is not a
sequence, too. The table {} is a sequence with border 0. Note that
non-natural keys do not interfere with whether a table is a sequence.
Things like ipairs, the length operator #, table.sort, table.concat and others only work with sequences.
Keys that do not contribute to the sequence are ignored by those functions. You can only loop over all keys of a table with next or pairs respectively. But then order is not guaranteed.

Swift - Add granularity in Array (2 by 2, 5 by 5, etc..)

I'm currently working with the "Charts" pod.
My app shows a bar chart of athletes results, with:
X Axis: number of reps / time / rounds / weight
Y Axis: number of athletes
I would like to gather the number of reps in different groups.
Something that would be like: 10 < x < 20, 20 < x < 30, etc... Rather than the real total of reps / time / whatever.
Something like that:
Depending on the difference between the Max() and Min() value, I want to change the granularity.
This is what I have right now:
let resultTime = [2458, 3500, 3600] // Fake data -> 41min, 58min, 60 min
let dict = Dictionary(grouping: resultTime, by: { $0 / 60 }).map { ($0.key, $0.value.count) }
This way, I can have a dictionary grouped by minute. I got this:
[(58, 1), (40, 1), (60, 1)]
I would like to group these data 2 by 2, to have something like that instead:
[(60, 2), (40, 1)]
Is there a possibly to play with the granularity with groupBy?
As #Alexander said, the solution is to round the by function
You can do that with this little function:
func roundWithCoef(_ x : Double, coef: Int) -> Int {
return coef * Int(round(x / Double(coef)))
}
let dict = Dictionary(grouping: resultTime, by: { roundWithCoef(Double($0 / 60), coef: 4) }).map { ($0.key, $0.value.count) }
This way you can play with the coef number

How to print an array of dictionary values into a nice string in Swift

I have an array of routine objects thats are defined as:
struct Routine {
let routineName: String
let routineExercisesAndSets: [String: Int]
}
let routines: [Routine] = {
let firstRoutine = Routine(routineName: "Legs", routineExercisesAndSets: ["Squats":4,"Lunges":4,"Calf Raises":4])
let secondRoutine = Routine(routineName: "Chest", routineExercisesAndSets: ["Bench Press":4,"Press Ups":4,"Flyes":4,"Inclined Bench Press":4])
let thirdRoutine = Routine(routineName: "Arms", routineExercisesAndSets: ["Bicep Curls":4,"Hammer Curls":4,"Preacher Curls":4,"Tricep Extension":4,"Tricep Dips":4])
return [firstRoutine, secondRoutine, thirdRoutine]
}()
I am trying to return them routineExercisesAndSets array into a UITableViewCell as detail text and when using the array.description function I get this result in the tableView
My question is, how could I iterate through the routine objects and print out a 'pretty' formatted string that looks something like:
"Calf Raises x 4, Squats x 4, Lunges x 4..."
I can print out the individual key, value pairs on new lines using this code:
for i in routines{
for (key, value) in (i.routineExercisesAndSets)! {
print("\(key) x \(String(value))")
}
}
which produces:
Calf Raises x 4
Squats x 4
Lunges x 4
Bench Press x 4
Press Ups x 4
Flyes x 4
Inclined Bench Press x 4
Tricep Extension x 4
Tricep Dips x 4
Preacher Curls x 4
Hammer Curls x 4
Bicep Curls x 4
but I want to group them by their parent object so the exercises for a routine display on the same line so it looks like the example "Calf Raises x 4, Squats x 4, Lunges x 4...".
You could make of a chained map and joined operation to construct a single String describing the exercise dictionary for a given exercise. E.g.
for routine in routines {
print("Routine:", routine.routineName)
print("--------------")
print(routine.routineExercisesAndSets
.map { $0 + " x \($1)" }
.joined(separator: ", "))
print()
}
/* Routine: Legs
--------------
Calf Raises x 4, Squats x 4, Lunges x 4
Routine: Chest
--------------
Bench Press x 4, Press Ups x 4, Flyes x 4, Inclined Bench Press x 4
Routine: Arms
--------------
Tricep Extension x 4, Tricep Dips x 4, Preacher Curls x 4, Hammer Curls x 4, Bicep Curls x 4
*/
Furthermore, instead of explicitly performing these "presentation" conversions upon each use, you could implement them as the return of the computed description property of Routine, as a part of letting Routine conform to CustomStringConvertible:
extension Routine: CustomStringConvertible {
var description: String {
return routineName + ":\n" + routineExercisesAndSets
.map { $0 + " x \($1)" }
.joined(separator: ", ")
}
}
for routine in routines {
print(routine) /* uses Routine:s implementation of 'CustomStringConvertible',
the computed property 'description`, specifically */
print()
}
/* Legs:
Calf Raises x 4, Squats x 4, Lunges x 4
Chest:
Bench Press x 4, Press Ups x 4, Flyes x 4, Inclined Bench Press x 4
Arms:
Tricep Extension x 4, Tricep Dips x 4, Preacher Curls x 4, Hammer Curls x 4, Bicep Curls x 4
*/
Given your comment below, it seems as if the properties routineName and routineExercisesAndSets of Routine are optionals. If this is the case, you naturally need to handle unwrapping them prior to accessing their (possibly existing) values. E.g., returning an empty description if any of the two properties is nil, and otherwise, the combined routine name and details description (as done in the non-optional examples above):
struct Routine {
let routineName: String?
let routineExercisesAndSets: [String: Int]?
}
extension Routine: CustomStringConvertible {
var description: String {
guard let name = routineName, let details = routineExercisesAndSets else { return "" }
return name + ":\n" + details.map { $0 + " x \($1)" }.joined(separator: ", ")
}
}
First of all let's conform Routine to CustomStringConvertible
extension Routine: CustomStringConvertible {
var description: String {
return routineExercisesAndSets.map { $0 + " x " + $1.description }.joined(separator: ", ")
}
}
Now you can easily write
routines.forEach { print($0) }
Result
Calf Raises x 4, Squats x 4, Lunges x 4
Bench Press x 4, Press Ups x 4, Flyes x 4, Inclined Bench Press x 4
Tricep Extension x 4, Tricep Dips x 4, Preacher Curls x 4, Hammer Curls x 4, Bicep Curls x 4
Or given a UITableViewCell...
let cell: UITableViewCell = ...
let routine: Routine = ...
cell.detailTextLabel?.text = routine.description

Swift: Print Coordinates from Firebase: 0,1 - 2,3 instead of 0,1 - 1,2

I am trying to print locations for each row in IndexPath.row because the IndexPath.row determine which specific content they want to receive in the TableView.
The NSDictionary from Firebase looks like: x,y,x,y,x,y and so on in coordinates.
0,1 = first coordinates
2,3 = second coordinates
Output: [55.617804300000003, 12.98939, 55.601572900000001, 12.979585399999999, 34.506667999999998, -81.948334000000003, -7.0909109999999993, 107.668887]
So first 0 and 1 is x, y for first coordinates with following:
print(CLLocationCoordinate2D(latitude: openLocations[indexPath.row], longitude: openLocations[indexPath.row + 1]))
How our results is at the moment:
x= longitude, y = altitude
x, y
0, 1
1, 2
2, 3
3, 4
5, 6
How it should be:
x= longitude, y = altitude
x, y
0, 1
2, 3
4, 5
6, 7
8, 9
NSDictonary looks like:
x,y,x,y,x,y ..
This should be an easy task but my mind at the moment is somewhere else, if any could help me straight this out, it would be highly appreciated.
Thanks In Advance,
Sincerely yours,
Filip
You have to take every second row:
latitude: openLocations[2 * indexPath.row], longitude: openLocations[2 * indexPath.row + 1]
In reality what you have is an Array, you can loop throught then like (asumming that you receive the locations in pair):
var openLocations = [55.617804300000003, 12.98939, 55.601572900000001, 12.979585399999999, 34.506667999999998, -81.948334000000003, -7.0909109999999993, 107.668887]
for(var i = 0; i < openLocations.count; i += 2){
let location = CLLocationCoordiante2D(latitude: openLocations[i], longitude: openLocations[i+1])
print(location)
}
In the case to work with IndexPath and UITableView, first you have some options:
Option 1:
First map the data that you recieve from firebase to a datastructure that bind the locations. Ex. It can be an Array of CLLocationCoordinate2D or you're own structure that you want.
Option 2:
You need to do some modifications on the datasource method, suppose:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return openLocations.count / 2
}

insert table values with string keys into Lua table

I'm relatively new to the Lua language and there's something I'm obviously missing about table structures.
I'm trying to create a table of tables, with each table in the table having a key and the value being the respective table.
Ok, that statement can be confusing. Here's an example:
{{ key = "RC", value = {1, 2, 3, 4}},
{ key = "M", value = {4, 8, 7}},
{ key = "D", value = {3, 8, 9}}
...}
for this I used the following algorithm:
local listOfLists = {};
...
if condition1 then
listOfLists[key1] = list1;
end
...
if condition2 then
listOfLists[key2] = list2;
end
...
And so on...
I hope to use the keys to later determine which lists have been added to the table.
But the thing is, no lists seem to be added to the table even if all the conditions are met.
I can use table.insert(listOfLists, list1) in place of listOfLists[key1] = list1 but then I won't be able to tell which lists were added to the collection.
Ant suggestions?
Lua tables are a flexible data structure. Elements are key-value pairs. A key is any Lua value except nil. A value can have any value except nil. Assigning nil to the value obliterates the pair.
The (possibly empty) subset of a table that has key values of the number type that are integers from 1 to n is called a sequence. n is determined as the last such key that is paired with a nil value. Several table functions and operators work only with sequences.
Table constructors allow several syntaxes for keys:
Implied via a sequence: {1, 2, 3}
Explicit keys: {[1] = 1, [3] = 3, ["two"] = "value"}
Identifier keys: {one = 1, two = 2}
A table constructor can use any combination of them.
You have defined a sequence of elements, each of which is a table with two elements, the
second of which is a sequence.
It appears you want keys to be strings and values to be sequences:
{
RC = {1, 2, 3, 4},
M = {4, 8, 7},
D = {3, 8, 9}
}
It's hard to understand, what do you wanna achieve. So, if you want more specific answer, provide more info.
You can create associative table of tables.
local map = {}
map["key"] = { 1, 2, 3, 4 }
print(map.key[3])
Or you can create an array of tables
local vector = {}
vector[1] = { 1, 2, 3, 4 }
print(vector[1][2])
Or you can combine approaches.
To create
{{ key = "RC", value = {1, 2, 3, 4}},
{ key = "M", value = {4, 8, 7}},
{ key = "D", value = {3, 8, 9}}
...}
You can use table constructor or smth from code.
local tbl = { { key = "RC", value = {1, 2, 3, 4}} } -- init first elem from constructor
table.insert(tbl, { key = "M", value = {4, 8, 7}}) -- table insert & constructor
tbl[2] = {} -- Array-based access.
tbl[2].key = "D" --key access
tbl[2]["value"] = { 3, 8, 9 } -- other way
Note, that each table consists of two parts: vector for sequental keys from 1 to N, and map otherwise. Some functions, like table length operator or ipairs iterator are guaranteed to work only with vector-part of table. But they are significantly faster.
EDIT: (last paragraph explanation)
If you have a table with some keys and want to iterate through, you can use ipairs or pairs.
ipairs is ordered, and goes from 1 to first not-nil element. It doesn't iterate over not-integer keys. pairs goes trough any key, but doesn't guarantee order.
local map = { 1, 2, 3, key = 6, [5] = 5 }
for i, v in ipairs(map) do
print(v) -- will output 1, 2, 3. first nil element is map[4]. map[5] will mot be visited.
end
for i, v in pairs(map) do -- NOTE pairs usage
print(v) -- will output 1, 2, 3, 5, 6 in ANY order
end
map[4] = 4 -- Fill gap
for i, v in ipairs(map) do
print(v) -- will output 1, 2, 3, 4, 5. Now first nil element is map[6]
end
Length operator works similar to ipairs, it doesn't count elements not visited by ipairs method.
table.maxn works with numerical indices, and will return zero for your table.
Reference say that table.maxn
Returns the largest positive numerical index of the given table, or zero if the table has no positive numerical indices. (To do its job this function does a linear traversal of the whole table.)
Little example about length and table.maxn
local a = { 1, 2, 3, [5] = 5}
print(table.maxn(a)) -- 5
print(#a) -- 3
a = { key = 4 }
print(table.maxn(a)) -- 0
print(#a) -- 0
print(a["key"]) -- 4, nothing is lost
local num = 0
for _, __ in pairs(a) do num = num + 1 end
print(num) -- 1 We find it.

Resources