blob: 24661fe41f9ba3f72bb40734532e09b8c41695f1 (
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
|
#!/usr/bin/env -S nim r -d:release --verbosity:0 --hints:off
import std/[strutils, parseutils, math]
type
Sign = enum
None
Plus
Minus
proc evaluate(s: string): int =
var index = 0
let length = s.skipWhile(Digits, index)
result = parseInt(s[0..<length])
index += length
while index < s.len:
doAssert s[index] in {'-', '+'}
let addition = s[index] == '+'
inc index
let length = s.skipWhile(Digits, index)
let num = parseInt(s[index..<index+length])
index += length
if addition:
result += num
else:
result -= num
proc toTrinary(n, digits: int): string =
var n = n
while n > 0:
result.insert $(n mod 3)
n = n div 3
result = result.align(digits, '0')
iterator allSignPermutations(n: int): seq[Sign] =
var buf = newSeqOfCap[Sign](n)
for i in 1..<3^n:
for digit in i.toTrinary(n):
buf.add (
case digit
of '0': None
of '1': Plus
of '2': Minus
else:
raiseAssert("Invalid digit.")
)
yield buf
buf.setLen(0)
when isMainModule:
const Expression = "123456789"
for signs in allSignPermutations(Expression.len - 1):
var newExpression = Expression
var shift = 1
for i, sign in signs:
case sign
of None:
discard
of Plus:
newExpression.insert("+", i + shift)
inc shift
of Minus:
newExpression.insert("-", i + shift)
inc shift
if evaluate(newExpression) == 100:
echo newExpression, " == 100"
break
|