-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsolution.nim
76 lines (66 loc) · 1.46 KB
/
solution.nim
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
import std/[
algorithm,
bitops,
deques,
json,
math,
re,
sequtils,
sets,
strformat,
strutils,
tables,
sugar,
]
proc dance(s, cmd: string): string =
case cmd[0]:
of 's':
let x = cmd[1 .. ^1].parseInt
result = s[^x .. ^1] & s[0 ..< ^x]
of 'x':
let p = cmd[1 .. ^1].split("/")
let a = p[0].parseInt
let b = p[1].parseInt
result = s
swap(result[a], result[b])
of 'p':
let (a, b) = (cmd[1], cmd[3])
let i = s.find(a)
let j = s.find(b)
result = s
swap(result[i], result[j])
else:
raise newException(ValueError, "unknown dance: " & cmd)
when defined(test):
block:
var s = "abcde".dance("s1")
doAssert s == "eabcd"
s = s.dance("x3/4")
doAssert s == "eabdc"
s = s.dance("pe/b")
doAssert s == "baedc"
proc parse(input: string): seq[string] =
input.split(",")
proc part1(input: string): string =
var s = ('a' .. 'p').toSeq.join
for cmd in input.parse:
s = s.dance(cmd)
s
proc part2(input: string): string =
let cmds = input.parse
var s = ('a' .. 'p').toSeq.join
var seen = initTable[string, int]()
var seenList = newSeq[string]()
while s notin seen:
seen[s] = seen.len
seenList.add s
for cmd in cmds:
s = s.dance(cmd)
let start = seen[s]
let cycle = seen.len - start
let N = 1e9.int
seenList[start + (N - start) mod cycle]
when isMainModule and not defined(test):
let input = readAll(stdin).strip
echo part1(input)
echo part2(input)