95 lines
1.6 KiB
Plaintext
95 lines
1.6 KiB
Plaintext
Kind :: enum {
|
|
first
|
|
second
|
|
third
|
|
}
|
|
|
|
Pair :: struct {
|
|
left i32
|
|
right i32
|
|
}
|
|
|
|
Value :: union(enum) {
|
|
number i32
|
|
pair Pair
|
|
empty void
|
|
}
|
|
|
|
enum_score func(kind Kind) i32 {
|
|
result :: match kind {
|
|
.first: 1
|
|
expand |value|: {
|
|
yield match value {
|
|
.second: 2
|
|
.third: 3
|
|
}
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
equal_value func(a, b Value) bool {
|
|
if (tag!(a) != tag!(b)) return false
|
|
result :: match a {
|
|
expand |value, tag|: {
|
|
yield match tag {
|
|
.number: value == field!(b, tagname!(tag))
|
|
.pair: {
|
|
other :: field!(b, tagname!(tag))
|
|
yield value.left == other.left and value.right == other.right
|
|
}
|
|
.empty: {
|
|
yield true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
increment func(value @mut Value) void {
|
|
match value^ {
|
|
expand |@payload, tag|: match tag {
|
|
.number: payload^ += 1
|
|
.pair: payload.left += 1
|
|
.empty: _ = payload
|
|
}
|
|
}
|
|
}
|
|
|
|
main func() i32 {
|
|
if enum_score(.first) != 1 or enum_score(.second) != 2 or enum_score(.third) != 3 {
|
|
return 1
|
|
}
|
|
|
|
known :: $tag!(Value{number = 1})
|
|
known_direct :: tag!(Value{pair = Pair{left = 0, right = 0}})
|
|
if (known != .number) or (known_direct != .pair) {
|
|
return 2
|
|
}
|
|
|
|
a Value = .number{41}
|
|
b Value = .number{41}
|
|
if !equal_value(a, b) or equal_value(a, .pair{left = 41, right = 0}) {
|
|
return 3
|
|
}
|
|
increment(&a)
|
|
if a.number != 42 {
|
|
return 4
|
|
}
|
|
|
|
pair_a Value = .pair{left = 2, right = 3}
|
|
pair_b Value = .pair{left = 2, right = 3}
|
|
if !equal_value(pair_a, pair_b) or !equal_value(.empty, .empty) {
|
|
return 5
|
|
}
|
|
increment(&pair_a)
|
|
if pair_a.pair.left != 3 {
|
|
return 6
|
|
}
|
|
|
|
empty Value = .empty
|
|
increment(&empty)
|
|
return 0
|
|
}
|