Skip to content

Instantly share code, notes, and snippets.

@Terens777
Last active September 22, 2022 15:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Terens777/b706cc84d495919c5dcbefff468c2306 to your computer and use it in GitHub Desktop.
Save Terens777/b706cc84d495919c5dcbefff468c2306 to your computer and use it in GitHub Desktop.
Add Two Numbers
import Foundation
/*
You are given two non-empty linked lists representing two non-negative integers.
The digits are stored in reverse order, and each of their nodes contains a single digit.
Add the two numbers and return the sum as a linked list.
You may assume the two numbers do not contain any leading zero, except the number 0 itself.
Input: l1 = [2,4,3], l2 = [5,6,4]
Output: [7,0,8]
Explanation: 342 + 465 = 807.
Input: l1 = [0], l2 = [0]
Output: [0]
Input: l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
Output: [8,9,9,9,0,0,0,1]
*/
public class ListNode {
public var val: Int
public var next: ListNode?
public init() { self.val = 0; self.next = nil; }
public init(_ val: Int) { self.val = val; self.next = nil; }
public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
}
extension ListNode {
public func insertFirst(_ value: Int) {
self.next = ListNode(self.val, self.next)
self.val = value
}
public func append(_ value: Int) {
func searchLastNextNode(node: ListNode) {
if let next = node.next {
searchLastNextNode(node: next)
} else {
node.next = ListNode(value)
}
}
searchLastNextNode(node: self)
}
}
extension ListNode: Sequence {
public func makeIterator() -> ListNodeIteractor {
ListNodeIteractor(current: self)
}
}
public struct ListNodeIteractor: IteratorProtocol {
public var current: ListNode
public var lastElement: Bool = false
public mutating func next() -> ListNode? {
guard !lastElement else {
return nil
}
let current = self.current
if let next = current.next {
self.current = next
} else {
self.lastElement = true
}
return current
}
}
struct SolutionBuilder {
private static func getBigIntFromList(_ list: ListNode) -> BigInt {
return BigInt(value: list.map { $0.val }.reversed().map { String($0) }.joined())
}
static func getResult(_ l1: ListNode?, _ l2: ListNode?) -> ListNode? {
guard let l1 = l1, let l2 = l2 else {
return nil
}
let lhs = getBigIntFromList(l1)
let rhs = getBigIntFromList(l2)
guard !lhs.value.isEmpty,
!rhs.value.isEmpty else {
return nil
}
let result = lhs + rhs
var arr = result
.value
.map { String($0) }
.reversed()
.compactMap { Int($0) }
if let first = arr.first {
var listNode: ListNode = ListNode(first)
arr.dropFirst().forEach(listNode.append)
return listNode
} else {
return nil
}
}
}
//BigInt
struct BigInt {
var value: String = .init()
init(value: String) {
self.value = value
}
static func +(lhs: BigInt, rhs: BigInt) -> BigInt {
let leftReversed: String = String(lhs.value.reversed())
let rightReversed: String = String(rhs.value.reversed())
var longerNumber = rightReversed
var result: String = ""
var isLeftShorter: Bool = true
var length: Int = rightReversed.count
if rightReversed.count < leftReversed.count {
isLeftShorter = false
length = leftReversed.count
longerNumber = leftReversed
}
var buffor: Int = 0
for i in 0..<length {
let index = longerNumber.index(longerNumber.startIndex, offsetBy: i)
var left: Int = 0
var right: Int = 0
if index < leftReversed.endIndex {
left = Int(String(leftReversed[index])) ?? 0
}
if index < rightReversed.endIndex {
right = Int(String(rightReversed[index])) ?? 0
}
var sum = buffor + left + right
buffor = 0
if sum > 9 {
buffor = sum / 10
sum = sum % 10
}
result.append(String(sum))
}
if isLeftShorter && rightReversed.count != length {
let index = rightReversed.index(rightReversed.startIndex, offsetBy: length)
let right: Int = Int(String(rightReversed[index]))!
result.append(String(right + buffor))
result += rightReversed.suffix(rightReversed.count - length - 1)
} else if !isLeftShorter && leftReversed.count != length {
let index = leftReversed.index(leftReversed.startIndex, offsetBy: length)
let left: Int = Int(String(leftReversed[index]))!
result.append(String(left + buffor))
result += leftReversed.suffix(leftReversed.count - length - 1)
} else if buffor > 0 {
result.append(String(buffor))
}
return BigInt(value: String(result.reversed()))
}
}
let l1 = ListNode(2, .init(4, .init(3)))
let l2 = ListNode(5, .init(6, .init(4)))
//let l1 = ListNode(1, .init(0, .init(0, .init(0, .init(0, .init(0, .init(0, .init(0, .init(0, .init(0, .init(0, .init(0, .init(0, .init(0, .init(0, .init(0, .init(0, .init(0, .init(0, .init(0, .init(0, .init(0, .init(0, .init(0, .init(0, .init(0, .init(0, .init(0, .init(0, .init(0, .init(1)))))))))))))))))))))))))))))))
//let l2 = ListNode(5, .init(6, .init(4)))
class Solution {
func addTwoNumbers(_ l1: ListNode?, _ l2: ListNode?) -> ListNode? {
return SolutionBuilder.getResult(l1, l2)
}
}
//Example
let solution = Solution()
solution.addTwoNumbers(l1, l2)?.forEach { print($0.val) }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment