summaryrefslogtreecommitdiffstats
path: root/Day 2/Day_02.swift
blob: dc991d6ba6b891bed492c1ce7fe3260f6a82da38 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#!/usr/bin/swift
import Foundation

guard CommandLine.arguments.count >= 2 else {
  fatalError("Usage: ./Day_01 <input.txt>")
}


let ranges: [ClosedRange<Int>] = try! String.init(contentsOfFile: CommandLine.arguments[1],
  encoding: .utf8)
.split(separator: ",")
.map { rangeString in
  guard let separatorIdx = rangeString.firstIndex(of: "-"),
  let lower = Int(rangeString[..<separatorIdx]),
  let upper = Int(rangeString[rangeString.index(after: separatorIdx)...]) else {
    fatalError("L16 : [ERROR] Failed to create ClosedRange!")
  }
  return lower...upper
}

var invalidIdSum: Int = 0

for range in ranges {
  for number in range {
    let numString = String(number)
    let length = numString.count
    guard length.isMultiple(of: 2) else { continue }
    let mid = numString.index(numString.startIndex, offsetBy: length / 2)
    let left  = numString[numString.startIndex..<mid]
    let right = numString[mid..<numString.endIndex]
    if left == right {
      invalidIdSum += number
    }
  }
}
print("=======Part 1=======\n\(invalidIdSum)")

invalidIdSum = 0
func isRepeating(_ x: Int) -> Bool {
  if x < 10 { return false }
  var digits = 0
  var temp = x
  while temp > 0 {
    digits += 1
    temp /= 10
  }
  if digits < 2 { return false }
  for period in 1...(digits / 2) {
    guard digits % period == 0 else { continue }
    var divisor = 1
    for _ in 0..<period { divisor *= 10 }
    let pattern = x % divisor
    guard pattern != 0 else { continue }
    var reconstructed = 0
    var multiplier = 1
    for _ in 0..<(digits / period) {
      reconstructed += pattern * multiplier
      multiplier *= divisor
    }
    if reconstructed == x { return true }
  }
  return false
}

ranges.forEach { range in 
  for id in range {
    if isRepeating(id) {
      invalidIdSum += id
    }
  }
}
print("=======Part 2=======\n\(invalidIdSum)")

invalidIdSum = 0
ranges.forEach { group in
  for id in group {
    let numString = String(id)
    let numstrLength = numString.count
    if numstrLength < 2 { continue }
    for patternLength in 1...(numstrLength / 2) {
      let remainder = numString.replacingOccurrences(of: numString[..<numString.index(numString.startIndex, offsetBy: patternLength)], with: "")
      if remainder.isEmpty {
        invalidIdSum += id
        break
      }
    }
  }
}

print("=======Part 2.2=======\n\(invalidIdSum)")