Generating random Int array of random count without repeated vars [duplicate] - swift

This question already has answers here:
Get random elements from array in Swift
(6 answers)
Closed 5 years ago.
Code first generates a random between 0-8, assigning it to var n. Then a 2nd randomNumber Generator func is looped n amount of times to generate n amount of ints between 0 and 10, all having different probabilities of occurring and ultimately put into an array. What I want is for none of those 10 possible numbers to repeat, so once one is chosen it can no longer be chosen by the other n-1 times the func is run. I'm thinking a repeat-while-loop or an if-statement or something involving an index but I don't know exactly how, nor within what brackets. Thanks for any help! Some whisper this is the most challenging and intelligence demanding coding conundrum on earth. Challenge Accepted?
import UIKit
let n = Int(arc4random_uniform(8))
var a:Double = 0.2
var b:Double = 0.3
var c:Double = 0.2
var d:Double = 0.3
var e:Double = 0.2
var f:Double = 0.1
var g:Double = 0.2
var h:Double = 0.4
var i:Double = 0.2
var j:Double = 0.2
var k: [Int] = []
for _ in 0...n {
func randomNumber(probabilities: [Double]) -> Int {
let sum = probabilities.reduce(0, +)
let rnd = sum * Double(arc4random_uniform(UInt32.max)) / Double(UInt32.max)
var accum = 0.0
for (i, p) in probabilities.enumerated() {
accum += p
if rnd < accum {
return i
}}
return (probabilities.count - 1)
}
k.append(randomNumber(probabilities: [a, b, c, d, e, f, g, h, i, j]))
}
print(k)

pseudo Code -
1)generate a number between 1-8
n
2)take empty array
arr[]
3)loop from 0 to n
1) generate a random no
temp
2) check if it is there in arr
> if it is there in arr, generate another
3) when you get a number which is not there in arr, insert it
This is a python code
import random
n = random.randint(1,8)
arr = []
print(n)
for each in range(n):
temp = random.randint(1, 10)
while temp in arr:
temp = random.randint(1, 10)
print(temp)
arr.append(temp)
print(arr)
Check code example here

Swift version of Ankush's answer -
let n = arc4random_uniform(7) + 1
var arr: [UInt32] = []
for _ in 0 ... n {
var temp = arc4random_uniform(9) + 1
while arr.contains(temp) {
temp = arc4random_uniform(9) + 1
}
print(temp)
arr.append(temp)
}
print(arr)
Hope this helps!

Related

How to use last variable in swift

I understand how lazy variable works but I don't know how to implement properly.
Below is just an example:
func calculation() -> (firstValue: Float, secondValue: Float) {
var a: Float = 2
var b: Float = 2
for i in 1...1000 {
a = a + Float(i)
b = b + Float(i)
print(i)
}
return (a, b)
}
let m = calculation().firstValue
let n = calculation().secondValue
when I run it, the calculation function ran twice (1000 time + 1000 time), first time to get the value to m, and second time to get the value of n.
What I have to do to force the function Calculation to run just only not time and to store the value m and n without repeat the process twice.
The lazy keyword is used on the class/struct/enum member variables.
For your example, you can implement like this:
class Solution {
lazy var tuple: (firstValue: Float, secondValue: Float) = {
var a: Float = 2
var b: Float = 2
for i in 1...1000 {
a = a + Float(i)
b = b + Float(i)
print(i)
}
return (a, b)
}()
}
let s = Solution()
let m = s.tuple.firstValue
let n = s.tuple.firstValue
The tuple variable stores the value returned by the following closure which only runs once.
You can also use a variable to record the return value of the function.
let pair = calculation()
let m = pair.firstValue
let n = pair.secondValue
lazy is the keyword to delay the calculation till the result is first used, so it is not for your case.
You can write something like this:
let values = calculation()
let m: Float = values.firstValue
let n: Float = values.secondValue
Or this:
let (m, n) = calculation()

Where do I put a return in a function?

My code is returning 2 errors, both are unresolved identifiers. I looked up what means and most query answers are saying that I need to declare the constant first, but I have already done that.
I'm very new to coding and everytime I encountered this problem it was because I forgot to declare the constant or variable and I would catch my mistake but I'm stumped on this one.
var counter = 2
func fibonacci(_ x:Int ) -> Int {
var a = 1
var b = 1
if counter < x {
let sum = a + b
a = b
b = sum
counter += 1
}
print(sum)
return sum
}
fibonacci(5)
I bet you'll want to define counter within the scope of your function (passing it as a parameter might not make sense) and then define sum outside the scope of the if statement like this:
func fibonacci(_ x:Int ) -> Int {
var a = 1
var b = 1
var sum = 0
var counter = 0
if counter < x {
sum = a + b
a = b
b = sum
counter += 1
}
print(sum)
return sum
}
You've declared the variable sum inside the if condition and using it outside the if condition.
Return b instead of sum at the end of the function. Your if block will be executed only once. You should use while loop
var counter = 2
func fibonacci(_ x:Int ) -> Int {
var a = 1
var b = 1
while counter < x {
let sum = a + b
a = b
b = sum
counter += 1
}
print(b)
return b
}
print(fibonacci(5))
You can simplify the swapping using a tuple
var counter = 2
func fibonacci(_ x:Int ) -> Int {
var a = 1
var b = 1
while counter < x {
(a,b) = (b,a+b)
counter += 1
}
print(b)
return b
}
print(fibonacci(5))
var counter = 2
func fibonacci(_ x:Int ) -> Int {
var a = 1
var b = 1
var sum = 0 //this is when if you want to add sum
//var counter = 0 if you may please work around the counter
if counter < x {
sum = a + b
a = b
b = sum
counter += 1
}
return sum //if you declare sum then return sum could be used
}
var x = fibonacci(5)//here the return value is stored or used for further computations
print(x) // the returned value can be printed in this way or directly print(fibonacci(5))
If you feel like learning it more please go through following link https://docs.swift.org/swift-book/LanguageGuide/Functions.html
The code above is not a solution to fibonacci series but a solution to your error. Fibonacci series can be solved in many ways using logic. As your question is only for the errors the program above solves it. If you feel like studying it using algorithms please checkout this link: https://www.codewithc.com/fibonacci-series-algorithm-flowchart/
I hope the answer helps!
The unresolved indentifiers errors is because neither counter or sum are variables defined.
Just define them, Eg:
var sum = 0;
func fibonacci(counter: Int, x:Int) -> Int {
var a = 1
var b = 1
if counter < x {
sum = a + b;
a = b
b = sum
return fibonacci(counter: counter + 1, x: x)
}
return sum
}
fibonacci(counter: 0, x: 5)
Note: the fibonacci func is not working properly but the identified errors were solved.

My Swift code getting error Can't form range with upperbound < lowerbound

I try to run my code in leetcode site. In XCode this code compiled successful. But in leetcode is error:
Fatal error: Can't form range with upperbound < lowerbound
Description of task:
Given an array nums of n integers, are there elements a, b, c in nums
such that a + b + c = 0? Find all unique triplets in the array which
gives the sum of zero.
My solution of this task is:
class Solution {
func threeSum(_ nums: [Int]) -> [[Int]] {
var arr: [[Int]] = []
var fIndex = 0
var sIndex = 1
var tIndex = 2
for i in fIndex..<nums.count-2 {
for n in sIndex..<nums.count-1 {
for z in tIndex..<nums.count {
let sum = nums[i] + nums[n] + nums[z]
if sum == 0 {
arr.append([nums[i], nums[n], nums[z]])
}
}
sIndex += 1
tIndex += 1
}
fIndex += 1
}
return arr
}
}
// delete this in leetcode site
let threeNums = [-1, 0, 1, 2, -1, -4]
let sol = Solution()
print(sol.threeSum(threeNums))
Where is the problem in my code?
Assuming all the other parts of your code works, you just need to check if the input array has less than 3 elements before the loops:
class Solution {
func threeSum(_ nums: [Int]) -> [[Int]] {
var arr: [[Int]] = []
var fIndex = 0
var sIndex = 1
var tIndex = 2
if nums.count < 3 { return [] } // if there is less than 3 elements, there can't be any triplets
for i in fIndex..<nums.count-2 {
...
Without the check, your code will fail when, say, nums has only one element, and enums.count - 2 would be -1.

Swift - how to reduce matrix

I have an 3 dimension array (array[x][y][z], x y z can flexible)
var array = [ [[1,1,1],[0,0,0],[1,1,1]],
[[1,0,1],[1,0,1],[1,0,1]],
[[1,1,1],[0,0,0],[1,1,1]]
]
How can I reduce 3D to 2D to : array[z][y]
[3,1,3],[2,0,2],[3,1,3]
I read the instruction here but couldn't figure out how to apply to mine.
Updated :
Here is the logic
Let's start by forming a utility function as an extension on a matrix-style array ("cw" means column-wise):
extension Array where Element == [[Int]] {
func cwsum(_ ix1:Int, _ ix2:Int) -> Int {
return reduce(0) {$0 + $1[ix1][ix2]}
}
}
Then if the array is:
let array = [[[1,1,1],[0,0,0],[1,1,1]],
[[1,0,1],[1,0,1],[1,0,1]],
[[1,1,1],[0,0,0],[1,1,1]]]
... then the answer is:
[[array.cwsum(0,0), array.cwsum(1,0), array.cwsum(2,0)],
[array.cwsum(0,1), array.cwsum(1,1), array.cwsum(2,1)],
[array.cwsum(0,2), array.cwsum(1,2), array.cwsum(2,2)]]
// [[3, 1, 3], [2, 0, 2], [3, 1, 3]]
But wait — I think I see a pattern here! We can rewrite that without hard-coding the indices, as:
var result = [[Int]]()
for j in 0..<3 {
var r1 = [Int]()
for i in 0..<3 {
r1.append(array.cwsum(i,j))
}
result.append(r1)
} // result is now [[3, 1, 3], [2, 0, 2], [3, 1, 3]]
Okay, but where we can loop and append, we can map instead, thus turning i into the map variable:
var result = [[Int]]()
for j in 0..<3 {
result.append((0..<3).map{i in array.cwsum(i,j)})
}
But then we can do that for j as well — and thus it becomes a single line:
result = (0..<3).map{j in (0..<3).map{i in array.cwsum(i,j)}}
Since it sounds like you’re looking for a functional programming one-liner, here’s your answer:
array.indices.map{ j in array.indices.map{ i in array.map{ $0[i][j] }.reduce(0, +) } }
It’s basically the same as this code, which, while much longer, I consider much easier to read and gives me fewer headaches to reason about.
func flatten2(_ array:[[[Int]]]) -> [[Int]]
{
var result:[[Int]] = []
for j in 0..<array.count
{
var row:[Int] = []
for i in 0..<array.count
{
row.append(array.map{ $0[i][j] }.reduce(0, +))
}
result.append(row)
}
return result
}
Keep in mind the one-liner will take over two orders of magnitude longer to compile, since the Swift compiler is not very optimized for functional and closure programming, and so it has to construct enormous overload trees to parse that expression. As I suspect this is a question from a practice exam for a CS final, please, please, make your poor TA’s life easier and use the multi-liner.
Given this
let matrix = [
[[1,1,1],[0,0,0],[1,1,1]],
[[1,0,1],[1,0,1],[1,0,1]],
[[1,1,1],[0,0,0],[1,1,1]]
]
lets calculate these
let all = matrix.joined().enumerated()
let a = all.filter { $0.offset % 3 == 0 }.map { $0.element[0] }.reduce(0, +)
let b = all.filter { $0.offset % 3 == 1 }.map { $0.element[0] }.reduce(0, +)
let c = all.filter { $0.offset % 3 == 2 }.map { $0.element[0] }.reduce(0, +)
let d = all.filter { $0.offset % 3 == 0 }.map { $0.element[1] }.reduce(0, +)
let e = all.filter { $0.offset % 3 == 1 }.map { $0.element[1] }.reduce(0, +)
let f = all.filter { $0.offset % 3 == 2 }.map { $0.element[1] }.reduce(0, +)
let g = all.filter { $0.offset % 3 == 0 }.map { $0.element[2] }.reduce(0, +)
let h = all.filter { $0.offset % 3 == 1 }.map { $0.element[2] }.reduce(0, +)
let i = all.filter { $0.offset % 3 == 2 }.map { $0.element[2] }.reduce(0, +)
and finally lets put the values together
let res = [[a, b, c], [d, e, f], [g, h, i]]
After hours of attempts. This is my output, it's very simple and unrelated to reduce. The inputs of 3d array are flexible x,y,z
let x = array.count
let y = array[0].count
let z = array[0][0].count
var final = Array(repeating: Array(repeating: 0, count: y), count: z)
for i in 0..<z {
for ii in 0..<y {
var sum = 0
for iii in 0..<x {
sum = sum + array[iii][ii][i]
}
final[i][ii] = sum
}
}

Make Int round off to nearest value

I've got two Int values (they have to be Ints) and I want them to round off to the nearest value when in an equation;
var Example = Int()
var secondExample = Int()
Example = (secondExample / 7000)
This equation makes the variable Example always round down to the lowest value. Say for example that the numbers are the following;
var Example = Int()
var secondExample : Int = 20000
Example = (20000 / 7000)
20000 / 7000 equals 2.857... But the variable Example displays 2.
How can I make Example round off to closest number without changing it to a Double
For nonnegative integers, the following function gives
the desired result in pure integer arithmetic :
func divideAndRound(numerator: Int, _ denominator: Int) -> Int {
return (2 * numerator + denominator)/(2 * denominator)
}
Examples:
print(20000.0/7000.0) // 2.85714285714286
print(divideAndRound(20000, 7000)) // 3 (rounded up)
print(10000.0/7000.0) // 1.42857142857143
print(divideAndRound(10000, 7000)) // 1 (rounded down)
The idea is that
a 1 2 * a + b
- + - = ---------
b 2 2 * b
And here is a possible implementation for arbitrarily signed
integers which also does not overflow:
func divideAndRound(num: Int, _ den: Int) -> Int {
return num / den + (num % den) / (den / 2 + den % 2)
}
(Based on #user3441734's updated solution, so we have a reference
cycle between our answers now :)
There is also a ldiv function which computes both quotient
and remainder of a division, so the last function could also be
implemented as
func divideAndRound(num: Int, _ den: Int) -> Int {
let div = ldiv(num, den)
let div2 = ldiv(den, 2)
return div.quot + div.rem / (div2.quot + div2.rem)
}
(I did not test which version is faster.)
see Martin's answer! his idea is great, so i extend his solution for negative numbers
func divideAndRound(n: Int, _ d: Int) -> Int {
let sn = n < 0 ? -1 : 1
let sd = d < 0 ? -1 : 1
let s = sn * sd
let n = n * sn
let d = d * sd
return (2 * n + d)/(2 * d) * s
}
divideAndRound(1, 2) // 1
divideAndRound(1, 3) // 0
divideAndRound(-1, 2) // -1
divideAndRound(-1, 3) // 0
divideAndRound(1, -2) // -1
divideAndRound(1, -3) // 0
the only trouble is that (2 * n + d) can overflow and code will crash.
UPDATE! with help of mathematics for children
func divr(a: Int, _ b: Int)->Int {
return (a % b) * 2 / b + a / b
}
it should work for any Int :-) except 0 denominator.