-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy path15.swift
88 lines (78 loc) · 1.92 KB
/
15.swift
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
var s = 0
var boxes: [Box] = Array(repeating: [], count: 256)
while let line = readLine() {
for word in line.split(separator: ",") {
s += hash(word)
boxes = modify(boxes, step: decode(word))
}
}
print(s, power(boxes))
func hash<S: StringProtocol>(_ s: S) -> Int {
var v = 0;
for c in s.utf8 {
v += Int(c)
v *= 17
v %= 256
}
return v;
}
enum Op {
case remove(String)
case replace(Lens)
}
struct Lens {
let label: String
let length: Int
init<S: StringProtocol>(label: S, length: S) {
self.label = String(label)
self.length = Int(length, radix: 10)!
}
}
typealias Box = [Lens]
struct Step {
let op: Op
let box: Int
}
func decode<S: StringProtocol>(_ s: S) -> Step {
let splits = s.split { $0 == "=" || $0 == "-" }
let box = hash(splits[0])
if splits.count == 1 {
return Step(op: .remove(String(splits[0])), box: box)
}
let lens = Lens(label: splits[0], length: splits[1])
return Step(op: .replace(lens), box: box)
}
func modify(_ boxes: [Box], step: Step) -> [Box] {
var boxes = boxes;
boxes[step.box] = modify(box: boxes[step.box], step: step)
return boxes
}
func modify(box: Box, step: Step) -> Box {
var box = box
switch step.op {
case .remove(let label):
box.removeAll { $0.label == label }
case .replace(let lens):
var found = false
for (i, l) in box.enumerated() {
if l.label == lens.label {
box[i] = lens
found = true
break
}
}
if !found {
box.append(lens)
}
}
return box
}
func power(_ boxes: [Box]) -> Int {
var s = 0
for (i, box) in boxes.enumerated() {
for (j, lens) in box.enumerated() {
s += (i + 1) * (j + 1) * lens.length
}
}
return s
}