I am trying to implement a generic linkedList API like in Java in swift.This has been done probably in hundreds of ways but my question is not on how to do it rather, on what is wrong with a part of my logic when removing an item whose index is zero. I know, there are alternate ways to achieve what I want and I did that but I need to understand the flaw in a particular logic. please have a look.
I have following functions for now.
var size : Int { get } //give the size of the list
func add(_ value: Item) //add items to the list
func removeAt(index: Int) // removes the item from the specified index
func print() //prints the list
My logic flaw is in the remove(index:) method only when I try to remove an item from the beginning of the list(index=0). My logic is to set the head's next node to be the head if there are more than 1 item in the list(list.size>0).
The following is the full implementation-
import Foundation
class Node<Item>{
var value: Item
var next: Node?
init(value: Item) {
self.value = value
self.next = nil
}
}
class LinkedList<Item> {
var head: Node<Item>?
public init(){
self.head = nil
}
public init(_ value: Item){
self.head = Node(value: value)
}
private func isEmpty()->Bool{
if head == nil{
return true
}
return false
}
var size : Int {
guard var current = head else{
return 0
}
var count = 1
while current.next != nil {
guard let next = current.next else {
return count
}
count = count + 1
current = next
}
return count
}
func add(_ value: Item){
let node = Node(value: value)
if isEmpty(){
head = node
return
}
guard let head = head else {
return
}
var currentNode = head
while currentNode.next != nil {
guard let nextNode = currentNode.next else {
break
}
currentNode = nextNode
}
currentNode.next = node
}
func removeAt(index: Int) {
if isEmpty() || index >= self.size{
return
}
guard var last = head, var secondLast = head else{
return
}
// when index is zero and either the list has only one item or it has multiple items
if index == 0{ //here is the bug
if let next = last.next{
last = next
}else{
head = nil
}
return
}
var count = 0
while count < index{
guard let next = last.next else{
return
}
secondLast = last
last = next
count = count + 1
}
secondLast.next = last.next
}
func print(){
guard var current = head else {
return
}
if current.next == nil{ //if list contains only head
Swift.print(current.value)
return
}
while current.next != nil{
Swift.print(current.value)
guard let next = current.next else {
return
}
current = next
}
Swift.print(current.value)
}
}
Testing the code like -
let list = LinkedList<Int>()
for i in 0...5{
list.add(i)
}
list.print()
let index = 0
list.removeAt(index: index)
print("After removing..")
list.print()
Output:
1
2
3
4
5
After removing..
1
2
3
4
5
Can anyone please points out my fault.
The head of the list becomes the next item, if there is one. If the next item is nil, then the head of the list is also nil, like so:
if index == 0 { //here is the bug
head = head?.next
return
}
This code:
if let next = last.next{
last = next
}else{
head = nil
}
In the first branch, you return without changing "head", so the head of the list remains unchanged.
suppose head is at address 100
and the second item in the list is at address 200
let list = LinkedList<Int>()
list's head -> 100
in remove at index 0 we set last to head, and secondLast also to head
last -> 100[ |next -> 200]
secondLast -> 100[ |next -> 200]
then we say
if let next = last.next { last = next } return
Now last points to 200:
last -> 200[ |next -> 300]
But list's head hasn't changed
list's head -> 100[ |next -> 200]
secondLast -> 100[ |next -> 200]
Last goes out of scope, when we return, no changes to the list structure (in the heap) have happened.
In the working branch (where index > 0):
while count < index{
guard let next = last.next else{
return
}
secondLast = last
last = next
count = count + 1
}
secondLast.next = last.next
we go over the loop manipulating secondLast and last, and at some point we then reach the line
secondLast.next = ...
So then we actually assign to the object, we mutate the object in the heap, it's next pointer, we go from something like:
secondLast -> 100[ |next -> 200]
secondLast -> 100[ |next -> 300]
So now the list itself has changed, in the heap, the object at address e.g. 100 has a next pointer that is pointing to some object, e.g. at address 300.
Firstly, I really appreciate the time and effort #Shadowrun put into. However, the explanation still lack the reason as of why the code works when I am iterating the list and removing in between the list.
The reason is List itself only holds one pointer, head which is referring to an address in memory. Sure the last node points to the same address but when I try to update update the head (index = 0) with the help of last, last is points to a different address which means it deviates from head as soon as it leaves the scope. While list has no clue that there was a change and list still holds the same pointer to address as of before.
Now when I am iterating from head(index>0), the last is same as head and with each iteration the last moves forward to the next node. I change the next pointer of any node at anytime, the next pointer gets updated for that node successfully. Here the starting node is same as head as last and head is pointing to the same address. So, for iteration over the list, it doesn't matter whether I start with head or last, the chain linking is same. Here head and last is same at the beginning. But for index = 0, as list's head, itself needs to be changed, making last pointing to a different node won't work because list knows head and the head is not updated.
So, the real reason is the list has no clue of how the node's are inter-related with one exception and that is the head.
It's not about assigning object or anything else. It's about list pointing to only one node and that is head.
Related
I am trying to find the number of array item matches between multiple test arrays and one control array. After finding the number of matches, I want to append the test arrays to another array, sorted by number of matches between the control array and test array. For example, a test array with 3 matches would be at index 0, 2 matches at index 1, and so on.
let controlArray = ["milk", "honey"]
let test1 = ["honey", "water"]
let test2 = ["milk", "honey", "eggs"]
var sortedArrayBasedOnMatches = [[String]]()
/*I want to append test1 and test2 to sortedArrayBasedOnMatches based on how many items
test1 and test2 have in common with controlArray*/
/*in my example above, I would want sortedArrayBasedOnMatches to equal
[test2, test1] since test 2 has two matches and test 1 only has one*/
This can be done in a very functional and Swiftish way by writing a pipeline to process the input arrays:
let sortedArrayBasedOnMatches = [test1, test2] // initial unsorted array
.map { arr in (arr, arr.filter { controlArray.contains($0) }.count) } // making pairs of (array, numberOfMatches)
.sorted { $0.1 > $1.1 } // sorting by the number of matches
.map { $0.0 } // getting rid of the match count, if not needed
Update As #Carpsen90 pointed out, Switf 5 comes with support for count(where:) which reduces the amount of code needed in the first map() call. A solution that makes use of this could be written along the lines of
// Swift 5 already has this, let's add it for current versions too
#if !swift(>=5)
extension Sequence {
// taken from the SE proposal
// https://github.com/apple/swift-evolution/blob/master/proposals/0220-count-where.md#detailed-design
func count(where predicate: (Element) throws -> Bool) rethrows -> Int {
var count = 0
for element in self {
if try predicate(element) {
count += 1
}
}
return count
}
}
#endif
let sortedArrayBasedOnMatches = [test1, test2] // initial unsorted array
.map { (arr: $0, matchCount: $0.count(where: controlArray.contains)) } // making pairs of (array, numberOfMatches)
.sorted { $0.matchCount > $1.matchCount } // sorting by the number of matches
.map { $0.arr } // getting rid of the match count, if not needed
Another change in style from the original solution is to use labels for the tuple components, this makes the code a little bit clearer, but also a little bit more verbose.
One option is to convert each array to a Set and find the count of elements in the intersection with controlArray.
let controlArray = ["milk", "honey"]
let test1 = ["honey", "water"]
let test2 = ["milk", "honey", "eggs"]
var sortedArrayBasedOnMatches = [ test1, test2 ].sorted { (arr1, arr2) -> Bool in
return Set(arr1).intersection(controlArray).count > Set(arr2).intersection(controlArray).count
}
print(sortedArrayBasedOnMatches)
This will cover the case where elements are not unique in your control array(such as milk, milk, honey...) and with any number of test arrays.
func sortedArrayBasedOnMatches(testArrays:[[String]], control: [String]) -> [[String]]{
var final = [[String]].init()
var controlDict:[String: Int] = [:]
var orderDict:[Int: [[String]]] = [:] // the value is a array of arrays because there could be arrays with the same amount of matches.
for el in control{
if controlDict[el] == nil{
controlDict[el] = 1
}
else{
controlDict[el] = controlDict[el]! + 1
}
}
for tArr in testArrays{
var totalMatches = 0
var tDict = controlDict
for el in tArr{
if tDict[el] != nil && tDict[el] != 0 {
totalMatches += 1
tDict[el] = tDict[el]! - 1
}
}
if orderDict[totalMatches] == nil{
orderDict[totalMatches] = [[String]].init()
}
orderDict[totalMatches]?.append(tArr)
}
for key in Array(orderDict.keys).sorted(by: >) {
for arr in orderDict[key]! {
final.append(arr)
}
}
return final
}
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()
Question:
You have two numbers represented by a linked list, where each node contains a single digit. The digits are stored in reverse order, such that the 1 's digit is at the head of the list. Write a function that adds the two numbers and returns the sum as a linked list.
An Example:
Input: (7-> 1 -> 6) + (5 -> 9 -> 2).
That is: 617 + 295.
Output: 2 -> 1 -> 9.
That is: 912.
In order to begin with this question, I first created a class that would define what a linked list:
Step 1: Defining the linked list
class Node: CustomStringConvertible{
var value: Int
var next: Node?
var description: String{
if next != nil {
return "\(value) -> \(next!)"
}
else{
return "\(value) -> \(next)"
}
}
init(value: Int) {
self.value = value
}
}
Step: 2 - Generated the linked list, from user input of integer values
func generateList (num: Int) -> Node {
var stringNum = Array(String(num).characters)
let head = Node.init(value:Int(String(stringNum.first!))!)
var current = head
for i in 1..<stringNum.count{
let num = Int(String(stringNum[i]))
current.next = Node.init(value: num!)
current = current.next!
}
return head
}
let list = generateList(num: 716)
// The following prints out: 7 -> 1 -> 6 -> nil
Then I proceeded over to reverse the linked list using following function.
Step 3: Reverse the linked list
func reverseLinkedList (head: Node?) -> Node?{
var current = head
var prev: Node?
var next: Node?
while current != nil {
next = current?.next
current?.next = prev
prev = current
current = next
}
return prev
}
let reversedList = reverseLinkedList(head: list)
// The following prints out is: 6 -> 1 -> 7 -> nil
Step 4: The idea behind this step is to extract the values on each of the nodes, cast them as a string and then concatenate them to a string variable and then lastly cast the string value into an Int and then use that Int value and eventually add them.
func getValuesFrom (head: Node?) -> Int {
var string = ""
var current = head
while current != nil {
var stringVal = String(describing: current?.value)
string += stringVal
current = current?.next
}
return Int(string)!
}
Here is where I am having a problem:
When I plug in the following into this function like so:
getValuesFrom(head: reversedList)
I get the following error:
fatal error: unexpectedly found nil while unwrapping an Optional value
And I can't seem to figure out why I having a problem and would really appreciate any sort of insight.
There is no need to convert back and forth between String and the linked list, except to print it for results. This is done simply like this:
class Node {
var value: Int
var next: Node?
// init and generator can be the same method
init(value: Int) {
// store ones place and divide by 10
self.value = value % 10
var nextValue = value / 10
// set up for loop
var currentNode = self
while nextValue > 0 {
// create a new Node
// store ones place and divide by 10
let next = Node(value: nextValue % 10)
nextValue /= 10
// make the new Node the next Node
currentNode.next = next
// set up for next iteration
currentNode = next
}
}
}
// make the list printable
extension Node: CustomStringConvertible {
var description: String{
if let next = next {
return "\(value) -> \(next)"
}
else {
return "\(value) -> nil"
}
}
}
Now you can do:
print(Node(value: 671)) // prints "7 -> 1 -> 6 -> nil"
There is also no need to reverse the lists, given your question.
To sum the lists you can do just as you've said, convert to an Int, add them, then generate a new list:
extension Node {
func toValue() -> Int {
var place = 10
var current = self
// add each value and multiply by the place value
// first is 1, second 10, third 100, etc.
var result = current.value
while let next = current.next {
result += next.value * place
place *= 10
current = next
}
return result
}
}
Then all you need is to overload the addition operator...
func +(lhs: Node, rhs: Node) -> Node {
return Node(value: lhs.toValue() + rhs.toValue())
}
and test...
let first = Node(value: 617)
let second = Node(value: 295)
print(first)
print(second)
print(first + second)
Result:
7 -> 1 -> 6 -> nil
5 -> 9 -> 2 -> nil
2 -> 1 -> 9 -> nil
I was trying this code in Xcode Playground and noticed that the description getter method got called too many times.
The code is here: https://gist.github.com/T-Pham/4b72d17851162a32b2fc534f0618135d
First with both print lines, the code is run 3176 times.
Then with the first print commented out, the code is run 3164 times.
That means the first print would have to run the code 12 times.
However,
it is 148 times instead.
It is the playground that is messing with your head.
Playground is counting calls of its own for variables that have the CustomStringConvertibe protocol (probably to feed the information on the right side panel).
You can see this going on if you simply invoke mirror(tree) without printing at all.
If you count the actual number of invocations using your own counter, it will give a very different result:
var descCount = 0
extension Node: CustomStringConvertible {
var description: String
{
descCount += 1
return "id: \(id)\nleft: \(left)\nright: \(right)"
}
}
descCount = 0
print(tree)
descCount // 12
descCount = 0
print(mirror(tree))
descCount // 12
By the way, I had a little trouble understanding the mirror() function and I figured that a recursive one would probably be simpler to understand. How about adding a mirror() function to Node :
func mirror() -> Node
{
let result = Node()
result.id = id
result.left = right?.mirror()
result.right = left?.mirror()
return result
}
print(tree.mirror())
[EDIT] Here's a non-recursive mirror function (same logic as yours) with a somewhat clearer structure:
func mirror2(tree:Node) -> Node
{
// will return top of mirrored tree
let newTree = Node()
// node pair used for traversal and duplication
var original:Node! = tree
var mirrored:Node! = newTree
// traversal of tree structure left side first
// (uses mirrored tree to keep track of traversed nodes)
while original != nil
{
// carry node identifier (and contents eventually)
mirrored.id = original.id
// downwards, mirror left side first (if not already done)
if (original.left == nil) != (mirrored.right == nil)
{
original = original.left
mirrored.right = Node()
mirrored = mirrored.right
continue
}
// downwards, mirror right side second (if not already done)
if (original.right == nil) != (mirrored.left == nil)
{
original = original.right
mirrored.left = Node()
mirrored = mirrored.left
continue
}
// upwards from leaves and completed branches
original = original.parent
mirrored = mirrored.parent
}
return newTree
}
and some visual candy for tree descriptions:
extension Node: CustomStringConvertible
{
var indent:String
{ return " " + (parent?.indent ?? "") }
var description: String
{
return "\(id)\n"
+ ( left != nil ? "\(indent)L:\(left!)" : "" )
+ ( right != nil ? "\(indent)R:\(right!)" : "" )
}
}
resulting in an easier comparison of results:
print(tree)
// 0
// L:1
// L:3
// L:7
// R:8
// R:4
// L:9
// R:10
// R:2
// R:6
// L:13
// R:14
//
print(mirror2(tree))
// 0
// L:2
// L:6
// L:14
// R:13
// R:1
// L:4
// L:10
// R:9
// R:3
// L:8
// R:7
I have a quick question that is confusing me a little bit. I made a simple average function that takes an array of optional Ints. I check to make sure the array does not contain a nil value but when I use reduce I have to force unwrap one of the two elements in the closure. Why is it that I only force unwrap the second one (in my case $1!)
func average2(array: [Int?]) -> Double? {
let N = Double(array.count)
guard N > 0 && !array.contains({$0 == nil}) else {
return nil
}
let sum = Double(array.reduce(0) {$0+$1!})
let average = sum / N
return average
}
I know it is simple but I would like to understand it properly.
The first parameter of reduce is the sum, which is 0 in the beginning. The second one is the current element of your array which is an optional Int and therefore has to be unwrapped.
Your invocation of reduce does this:
var sum = 0 // Your starting value (an Int)
for elem in array {
sum = sum + elem! // This is the $0 + $1!
}
EDIT: I couldn't get a more functional approach than this to work:
func average(array: [Int?]) -> Double? {
guard !array.isEmpty else { return nil }
let nonNilArray = array.flatMap{ $0 }
guard nonNilArray.count == array.count else { return nil }
return Double(nonNilArray.reduce(0, combine: +)) / Double(nonNilArray.count)
}
You can also discard the second guard if you want something like average([1, 2, nil]) to return 1.5 instead of nil