Swift: Terminated by Signal 4 - swift

I'm trying to write a function that has arrayOne, arrayTwo, and arrayThree as inputs. If arrayTwo has any 0s as its last elements, the function is supposed to remove these elements from the array, as well as the same elements from arrayOne. When I run the code and try to test it, I get the error: "Terminated by signal 4".
What could the problem be?
var arrayOneNew = arrayOne
var arrayTwoNew = arrayTwo
var arrayThreeNew = arrayThree
var endElement = arrayTwoNew.last
if endElement == 0 {
var counter = arrayTwoNew.count
while arrayTwoNew[counter] == 0 {
var elementToBeRemoved = arrayTwoNew.remove(at: counter - 1)
var 2ndElementToBeRemoved = arrayOneNew.remove(at: counter - 1)
}
}

Your main problem is that you are setting counter to arrayTwoNew.count which is 1 bigger than the last valid index in arrayTwoNew, so while arrayTwoNew[counter] == 0 crashes with index out of range.
Also:
var elementToBeRemoved = arrayTwoNew.remove(at: counter - 1)
is probably meant to remove the last item from arrayTwoNew, but that is more easily accomplished with:
arrayTwoNew.removeLast()
especially since you're not using elementToBeRemoved.
I think you're trying to do this:
while arrayTwoNew.last == 0 {
arrayTwoNew.removeLast()
arrayOneNew.removeLast()
arrayThreeNew.removeLast()
}

You are creating a new array "arrayTwoNew" which is mixed up with the original one at
var arrayTwoNew = arrayTwoNew.remove(at: counter - 1)
Now I'm also struggling with your .remove - this returns an element so won't work. I'd usually use a filter here but I'm not sure what you are doing!
//code with remove taken out (replace with filter?) to get you started:
let arrayOne = [1,2,3]
let arrayTwo = [2,3,4]
let arrayThree = [5,6,7]
var arrayOneNew = arrayOne
var arrayTwoNew = arrayTwo
var arrayThreeNew = arrayThree
var endIndex = arrayTwoNew.last
if endIndex == 0 {
let counter = arrayTwoNew.count
// arrayTwoNew = arrayTwoNew.remove(at: counter - 1)
while arrayTwoNew[counter] == 0 {
// arrayOneNew = arrayOneNew.remove(at: counter - 1)
}
}

Related

Why is my app freezing when func is called

Whenever I call this function, my app freezes and nothing in the debug console prints. I am trying to get strings and a double from firebase and then stick them into an identifiable struct array. Any Ideas???
If you have another idea for storing that object, I would love to read it.
var count = Int()
var name = Array<String>()
var imageUrl = Array<String>()
var id = Array<String>()
var rating = Array<Double>()
var url = Array<String>()
var keys = 0
db.collection("parties").document(Utilities.code).addSnapshotListener { document, error in
//check for error
if error == nil {
//check if document exists
print("No error")
if document != nil && document!.exists {
print("Document Exists")
if let array = document!.get("yesName") as? Array<String> {
count = array.count
name = array
print("yesName = \(array)")
keys += 1
}
if let array = document!.get("yesImg") as? Array<String> {
imageUrl = array
print("yesImg = \(array)")
keys += 1
}
if let array = document!.get("yesId") as? Array<String> {
id = array
print("yesId = \(array)")
keys += 1
}
if let array = document!.get("yesRating") as? Array<Double> {
rating = array
print("yesRating = \(array)")
keys += 1
}
if let array = document!.get("yesUrl") as? Array<String> {
url = array
print("yesUrl = \(array)")
keys += 1
}
}
}else {
print("error = \(error!)")
}
}
while keys < 6 {
if name.count > 0 && imageUrl.count > 0 && id.count > 0 && rating.count > 0 && url.count > 0 {
for _ in 0...count {
yes.list.append(RestaurantListViewModel(name: name.first!, imageUrl: URL(string: imageUrl.first!)!, id: id.first!, rating: rating.first!, url: url.first!))
print("combined = \(yes.list.append(RestaurantListViewModel(name: name.first!, imageUrl: URL(string: imageUrl.first!)!, id: id.first!, rating: rating.first!, url: url.first!)))")
name.removeFirst()
imageUrl.removeFirst()
id.removeFirst()
rating.removeFirst()
url.removeFirst()
}
keys = 6
}
}
The snapshot listener will execute asynchronously that means in some time after the current method is finished. So the code after it is called is executed only once and just after listener creation : there is nothing yet in the arrays and keys == 0. May be this code should be inside the listener call after document is read and array updated.
Have you tried to debug while keys < 6 { circle?
Next line condition
if name.count > 0 && imageUrl.count > 0 && id.count > 0 && rating.count > 0 && url.count > 0
can easily equals to false and you get infinity circle running.
Also I see few logic issues in your code: in the first part of code you set up required fields (keys equals in a range from 0 to 6). But in the second part inside circle while keys < 6 you require all 6 fields and want to exit only after all values will have count > 0. You need to get value.count only when it needed.

no response on stdout HackerRank Swift

Hello i practice on hackerRank using swift and now i have a problem. My code works great in swift playground, and return the expected result, but in HackerRank i have runtime error ~ no response on stdout ~ I've tried to reset code and refresh page. What could be the problem?
func diagonalDifference(arr: [[Int]]) -> Int {
// Write your code here
let rowNumber = arr[0][0]
var leftD = 0
var rightD = 0
for i in 1...rowNumber {
leftD += arr[i][i - 1]
}
var increasedNum = 0
for i in (1...rowNumber).reversed() {
rightD += arr[i][increasedNum]
increasedNum += 1
}
var absoluteDifference = leftD - rightD
if absoluteDifference < 0 {
absoluteDifference = absoluteDifference * -1
}
return absoluteDifference
}
Here is the challenge page:
https://www.hackerrank.com/challenges/diagonal-difference/problem
Your problem is a misunderstanding of what is passed to your diagonalDifference() function. The code which calls that function uses the first line of input to correctly size the array, but that value is not passed to your function in arr[0][0]. Instead, you should use arr.count to determine the dimensions of the array, then you should be indexing the array as 0..<arr.count.
To fix your code
change:
let rowNumber = arr[0][0]
to:
let rowNumber = arr.count
change:
leftD += arr[i][i - 1]
to:
leftD += arr[i][i]
And change both instances of
1...rowNumber
to:
0..<rowNumber
func diagonalDifference(arr: [[Int]]) -> Int {
var difference = 0
for i in 0..<arr.count {
difference += (arr[i][i] - arr[i][arr.count-1-i])
}
return Int(abs(difference))
}

"Attemped to add a SKNode which already has a parent:" in Repeat Loop. Any simple work around?

I am pretty Newbie to programming. And I am trying to pile up the random blocks dynamically till it hits the upper frame. But it seems that Swift doesn't let me to do so. Did I miss anything please? Any input are appreciated.
let blocks =[block1,block2,block3,block4,block5,block6,block7,block8,block9,block10,block11,block12]
var block:SKSpriteNode!
let blockX:Double = 0.0
var blockY:Double = -(self.size.height/2)
repeat{
block = blocks.randomBlock()
block.zPosition = 2
block.position = CGPoint(x:blockX, y:blockY)
block.size.height = 50
block.size.width = 50
self.addChild(block)
blockY += 50
} while( block.position.y < self.size.height)
extension Array {
func randomBlock()-> Element {
let randint = Int(arc4random_uniform(UInt32(self.count)))
return self[randint]
}
}
you need to have someway of tracking which blocks have been selected and ensure that they don't get selected again. The method below uses an array to store the indexes of selected blocks and then uses recursion to find a cycle through until an unused match is found.
private var usedBlocks = [Int]()
func randomBlock() -> Int {
guard usedBlocks.count != blocks.count else { return -1 }
let random = Int(arc4random_uniform(UInt32(blocks.count)))
if usedBlocks.contains(random) {
return randomBlock()
}
usedBlocks.append(random)
return random
}
in your loop change your initializer to
let index = randomBlock()
if index > -1 {
block = blocks[index]
block.zPosition = 2
block.position = CGPoint(x:blockX, y:blockY)
}
remember that if you restart the game or start a new level, etc. you must clear all of the objects from usedBlocks
usedBlocks.removeAll()

Why Realm "to many" relationship having always the same reference?

Why is the realm-list containing the very same elements instead of different ones ?
As you can see in the picture below, there are two relam-objects (UndoMemoryNameEntry and NameEntry). The first one contains a list of 8 elements. The list's element-type is of type NameEntry !
My last NameEntry object is written with currentScorePlayer=1 and currentScoreMe=15 as you can see in the picture below:
The list in UndoMemoryNameEntry is correctly inserted the last NameEntry object. You find the insertion-code further down...
But now the problem: Why are all the existing list-elements as well changed to the newest inserted element ???? As you can see in the picture below, all the elements are unfortunately identical to the last one added - why ??????
If I change the NameEntry to the following :
And inserting at index=0 to the list, then the List changes to :
Why are all the elments changed ? And not just the inserted one ??? Thanks for any help on this !
My two realm-objects are :
class NameEntry: Object {
dynamic var playerName = ""
dynamic var isMyAdversary: Bool = false
dynamic var currentScorePlayer: Int = 0
dynamic var currentScoreMe: Int = 0
}
and the List :
class UndoMemoryNameEntry: Object {
dynamic var undoPlayerName = ""
let NameEntryList = List<NameEntry>()
}
The following code creates the Realm-List :
// query rlm for existing object (with name adversary
let undoPredicate = NSPredicate(format: "undoPlayerName == %#", adversaryName)
let undoPlayerName = rlm.objects(UndoMemoryNameEntry).sorted("undoPlayerName", ascending: true).filter(undoPredicate)
// if undoPlayerName object does not exist - then create it!
if (undoPlayerName.count < 1) {
rlm.beginWrite()
let undoEntry = UndoMemoryNameEntry()
undoEntry.undoPlayerName = adversaryName
rlm.add(undoEntry)
rlm.commitWrite()
}
The following code adds a "NameEntry"-Element in the List :
let undoPredicate = NSPredicate(format: "undoPlayerName == %#", plaNameLab)
let undoPlayerName = rlm.objects(UndoMemoryNameEntry).sorted("undoPlayerName", ascending: true).filter(undoPredicate)
if (undoPlayerName.count == 1) {
rlm.beginWrite()
println(entry)
var undoEntry = undoPlayerName[0] as UndoMemoryNameEntry
undoEntry.NameEntryList.insert(entry, atIndex: 0)
rlm.commitWrite()
}
The above code-excerts work perfectly - except that the realm-List always changes all its elements to the one just inserted.
I finally found a solution:
First of all rearrange the two realm objects as follows:
class NameEntry: Object {
dynamic var playerName = ""
dynamic var currentScorePlayer: Int = 0
dynamic var currentScoreMe: Int = 0
// the undo-list is better placed in the first object...
let undoEntryList = List<UndoMemoryNameEntry>()
override static func primaryKey() -> String? {
return "playerName"
}
}
class UndoMemoryNameEntry: Object {
dynamic var undoPlayerName = ""
dynamic var currentScorePlayer: Int = 0
dynamic var currentScoreMe: Int = 0
// no primary key here since the undoEntry will have several items with the same undoPlayerName
}
Then when adding a "NameEntry"-Element in the List :
let predicate = NSPredicate(format: "playerName == %#", plaNameLab)
let playerName = rlm.objects(NameEntry).sorted("playerName", ascending: true).filter(predicate)
if (playerName.count == 1) {
rlm.beginWrite()
var entry = playerName[0] as NameEntry
// you need to create a new list object first !!!!!!!!!!!!
// ...in my initial example, this creation was missing !!!!!!
var siblingEntry = UndoMemoryNameEntry()
siblingEntry.undoPlayerName = plaNameLab
siblingEntry.currentScorePlayer = entry.currentScorePlayer
siblingEntry.currentScoreMe = entry.currentScoreMe
// insert new list-element
entry.undoEntryList.insert(siblingEntry, atIndex: 0)
// alternatively choose append if you want to add the element at the end of the list
entry.undoEntryList.append(siblingEntry)
// or choose the "ringbuffer-solution" given in the add-on below if you want to restrict the number of list-elements to ringbuffer-size !
// ...
rlm.commitWrite()
}
Add-on: If you want to create a ringbuffer having only a limited number of list-elements:
// create ringbuffer of 20 elements (20th element will be newest)
let ringBufferSize = 20
let undoPredicate = NSPredicate(format: "undoPlayerName == %#", plaNameLab)
if (entry.undoEntryList.filter(undoPredicate).sorted("undoPlayerName").count < ringBufferSize) {
entry.undoEntryList.append(siblingEntry)
}
else {
// entry.undoEntryList.replace(ringBufferSize-1, object: siblingEntry)
entry.undoEntryList.removeAtIndex(ringBufferSize-1)
entry.undoEntryList.append(siblingEntry)
for index in 0..<ringBufferSize-1 {
let tempEntry1 = rlm.objects(UndoMemoryNameEntry).filter(undoPredicate).sorted("undoPlayerName")[index] as UndoMemoryNameEntry
let tempEntry2 = rlm.objects(UndoMemoryNameEntry).filter(undoPredicate).sorted("undoPlayerName")[index+1] as UndoMemoryNameEntry
tempEntry1.currentScorePlayer = tempEntry2.currentScorePlayer
tempEntry1.currentScoreMe = tempEntry2.currentScoreMe
}
let tempEntry = rlm.objects(UndoMemoryNameEntry).filter(undoPredicate).sorted("undoPlayerName")[ringBufferSize-1] as UndoMemoryNameEntry
rlm.delete(tempEntry)
}

display the value of bool in swift

I would like to print the result of the bool value
When I do it I have "true" instead the amount.
I know it probably sounds really stupid but I'm just getting started with swift
var monthsWeek:Int?
var hoursWageHours:Double = 14.47
let months4WeeksHours:Double = 156.00
let months5WeeksHours:Double = 195.00
var normalpay:Double = 0
let months5weeks:Bool = true
let months4weeks:Bool = true
if months5weeks {
normalpay = hoursWageHours * months5WeeksHours
if months4weeks {
normalpay = hoursWageHours * months4WeeksHours
}
}
or woud that make more sence even if didnt print the result still
var monthsWeek:Int?
var hoursWageHours:Double = 14.47
let months4WeeksHours:Double = 156.00
let months5WeeksHours:Double = 195.00
var normalpay:Double = 0
if monthsWeek == 195 {
normalpay = hoursWageHours * months5WeeksHours
if monthsWeek == 4 {
normalpay = hoursWageHours * months4WeeksHours
}
}
monthsWeek = 4
I came here looking for an actual print of a bool. It turns out you can do this:
var a_bool = false
print("a_bool is ")
println(a_bool)
And you can do this with ints:
var a_int = 42
println("This is an int " + String(a_int))
You can't do this with bools though. However you can do:
println("This is a bool " + String(stringInterpolationSegment: a_bool))
This is the closet I can come up with for something like this:
println("a_bool is ", a_bool) // does not work
println("a_bool is " + a_bool) // also does not work
Later on, I learned you can use \(variable) embedding like this:
println("This is an int \(a_int)")
A boolean variable can take only 2 values (true or false).
So it is logical that when you print it you have true or false.