What a mess! 18-20, no Part 2 solve. Oh well!
This commit is contained in:
58
2023/19/README.md
Executable file
58
2023/19/README.md
Executable file
@@ -0,0 +1,58 @@
|
||||
## \-\-\- Day 19: Aplenty ---
|
||||
|
||||
The Elves of Gear Island are thankful for your help and send you on your way. They even have a hang glider that someone [stole](9) from Desert Island; since you're already going that direction, it would help them a lot if you would use it to get down there and return it to them.
|
||||
|
||||
As you reach the bottom of the _relentless avalanche of machine parts_, you discover that they're already forming a formidable heap. Don't worry, though - a group of Elves is already here organizing the parts, and they have a _system_.
|
||||
|
||||
To start, each part is rated in each of four categories:
|
||||
|
||||
- `x`: E _x_ tremely cool looking
|
||||
- `m`: _M_ usical (it makes a noise when you hit it)
|
||||
- `a`: _A_ erodynamic
|
||||
- `s`: _S_ hiny
|
||||
|
||||
Then, each part is sent through a series of _workflows_ that will ultimately _accept_ or _reject_ the part. Each workflow has a name and contains a list of _rules_; each rule specifies a condition and where to send the part if the condition is true. The first rule that matches the part being considered is applied immediately, and the part moves on to the destination described by the rule. (The last rule in each workflow has no condition and always applies if reached.)
|
||||
|
||||
Consider the workflow `ex{x>10:one,m<20:two,a>30:R,A}`. This workflow is named `ex` and contains four rules. If workflow `ex` were considering a specific part, it would perform the following steps in order:
|
||||
|
||||
- Rule " `x>10:one`": If the part's `x` is more than `10`, send the part to the workflow named `one`.
|
||||
- Rule " `m<20:two`": Otherwise, if the part's `m` is less than `20`, send the part to the workflow named `two`.
|
||||
- Rule " `a>30:R`": Otherwise, if the part's `a` is more than `30`, the part is immediately _rejected_ ( `R`).
|
||||
- Rule " `A`": Otherwise, because no other rules matched the part, the part is immediately _accepted_ ( `A`).
|
||||
|
||||
If a part is sent to another workflow, it immediately switches to the start of that workflow instead and never returns. If a part is _accepted_ (sent to `A`) or _rejected_ (sent to `R`), the part immediately stops any further processing.
|
||||
|
||||
The system works, but it's not keeping up with the torrent of weird metal shapes. The Elves ask if you can help sort a few parts and give you the list of workflows and some part ratings (your puzzle input). For example:
|
||||
|
||||
```
|
||||
px{a<2006:qkq,m>2090:A,rfg}
|
||||
pv{a>1716:R,A}
|
||||
lnx{m>1548:A,A}
|
||||
rfg{s<537:gd,x>2440:R,A}
|
||||
qs{s>3448:A,lnx}
|
||||
qkq{x<1416:A,crn}
|
||||
crn{x>2662:A,R}
|
||||
in{s<1351:px,qqz}
|
||||
qqz{s>2770:qs,m<1801:hdj,R}
|
||||
gd{a>3333:R,R}
|
||||
hdj{m>838:A,pv}
|
||||
|
||||
{x=787,m=2655,a=1222,s=2876}
|
||||
{x=1679,m=44,a=2067,s=496}
|
||||
{x=2036,m=264,a=79,s=2244}
|
||||
{x=2461,m=1339,a=466,s=291}
|
||||
{x=2127,m=1623,a=2188,s=1013}
|
||||
|
||||
```
|
||||
|
||||
The workflows are listed first, followed by a blank line, then the ratings of the parts the Elves would like you to sort. All parts begin in the workflow named `in`. In this example, the five listed parts go through the following workflows:
|
||||
|
||||
- `{x=787,m=2655,a=1222,s=2876}`: `in` -\> `qqz` -\> `qs` -\> `lnx` -\> `A`
|
||||
- `{x=1679,m=44,a=2067,s=496}`: `in` -\> `px` -\> `rfg` -\> `gd` -\> `R`
|
||||
- `{x=2036,m=264,a=79,s=2244}`: `in` -\> `qqz` -\> `hdj` -\> `pv` -\> `A`
|
||||
- `{x=2461,m=1339,a=466,s=291}`: `in` -\> `px` -\> `qkq` -\> `crn` -\> `R`
|
||||
- `{x=2127,m=1623,a=2188,s=1013}`: `in` -\> `px` -\> `rfg` -\> `A`
|
||||
|
||||
Ultimately, three parts are _accepted_. Adding up the `x`, `m`, `a`, and `s` rating for each of the accepted parts gives `7540` for the part with `x=787`, `4623` for the part with `x=2036`, and `6951` for the part with `x=2127`. Adding all of the ratings for _all_ of the accepted parts gives the sum total of `19114`.
|
||||
|
||||
Sort through all of the parts you've been given; _what do you get if you add together all of the rating numbers for all of the parts that ultimately get accepted?_
|
||||
389
2023/19/code.go
Normal file
389
2023/19/code.go
Normal file
@@ -0,0 +1,389 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/jpillora/puzzler/harness/aoc"
|
||||
)
|
||||
|
||||
func main() {
|
||||
aoc.Harness(run)
|
||||
}
|
||||
|
||||
// on code change, run will be executed 4 times:
|
||||
// 1. with: false (part1), and example input
|
||||
// 2. with: true (part2), and example input
|
||||
// 3. with: false (part1), and user input
|
||||
// 4. with: true (part2), and user input
|
||||
// the return value of each run is printed to stdout
|
||||
type Part struct {
|
||||
X int
|
||||
M int
|
||||
A int
|
||||
S int
|
||||
}
|
||||
|
||||
type PartAcceptor struct {
|
||||
Wfl []Workflow
|
||||
Xmax int
|
||||
Xmin int
|
||||
Mmax int
|
||||
Mmin int
|
||||
Amax int
|
||||
Amin int
|
||||
Smax int
|
||||
Smin int
|
||||
}
|
||||
|
||||
type Workflow struct {
|
||||
Comparing string
|
||||
CompareType string
|
||||
Value int
|
||||
Result string
|
||||
Method func(p Part) string
|
||||
}
|
||||
|
||||
func run(part2 bool, input string) any {
|
||||
// when you're ready to do part 2, remove this "not implemented" block
|
||||
workflows := make(map[string][]Workflow)
|
||||
parts := make([]Part, 0)
|
||||
|
||||
inParts := false
|
||||
for _, l := range strings.Split(input, "\n") {
|
||||
if l == "" {
|
||||
inParts = true
|
||||
continue
|
||||
}
|
||||
|
||||
if !inParts {
|
||||
cutoff := strings.Index(l, "{")
|
||||
name := l[0:cutoff]
|
||||
wkflow := l[cutoff+1 : len(l)-1]
|
||||
|
||||
functions := make([]Workflow, 0)
|
||||
for _, wkF := range strings.Split(wkflow, ",") {
|
||||
|
||||
if strings.Contains(wkF, ":") {
|
||||
// Mapping function
|
||||
spl := strings.Split(wkF, ":")
|
||||
|
||||
comparing := spl[0][0:2]
|
||||
compared, _ := strconv.Atoi(spl[0][2:])
|
||||
res := spl[1]
|
||||
|
||||
if comparing == "x>" {
|
||||
functions = append(functions, Workflow{"x", ">", compared, res, func(p Part) string {
|
||||
if p.X > compared {
|
||||
return res
|
||||
}
|
||||
return ""
|
||||
}})
|
||||
} else if comparing == "x<" {
|
||||
functions = append(functions, Workflow{"x", "<", compared, res, func(p Part) string {
|
||||
if p.X < compared {
|
||||
return res
|
||||
}
|
||||
return ""
|
||||
}})
|
||||
} else if comparing == "m>" {
|
||||
functions = append(functions, Workflow{"m", ">", compared, res, func(p Part) string {
|
||||
if p.M > compared {
|
||||
return res
|
||||
}
|
||||
return ""
|
||||
}})
|
||||
} else if comparing == "m<" {
|
||||
functions = append(functions, Workflow{"m", "<", compared, res, func(p Part) string {
|
||||
if p.M < compared {
|
||||
return res
|
||||
}
|
||||
return ""
|
||||
}})
|
||||
} else if comparing == "a>" {
|
||||
functions = append(functions, Workflow{"a", ">", compared, res, func(p Part) string {
|
||||
if p.A > compared {
|
||||
return res
|
||||
}
|
||||
return ""
|
||||
}})
|
||||
} else if comparing == "a<" {
|
||||
functions = append(functions, Workflow{"a", "<", compared, res, func(p Part) string {
|
||||
if p.A < compared {
|
||||
return res
|
||||
}
|
||||
return ""
|
||||
}})
|
||||
} else if comparing == "s>" {
|
||||
functions = append(functions, Workflow{"s", ">", compared, res, func(p Part) string {
|
||||
if p.S > compared {
|
||||
return res
|
||||
}
|
||||
return ""
|
||||
}})
|
||||
} else if comparing == "s<" {
|
||||
functions = append(functions, Workflow{"s", "<", compared, res, func(p Part) string {
|
||||
if p.S < compared {
|
||||
return res
|
||||
}
|
||||
return ""
|
||||
}})
|
||||
} else {
|
||||
panic("!??")
|
||||
}
|
||||
|
||||
} else {
|
||||
// Just a return function
|
||||
functions = append(functions, Workflow{"", "", 0, wkF, func(p Part) string { return wkF }})
|
||||
}
|
||||
}
|
||||
|
||||
workflows[name] = functions
|
||||
} else {
|
||||
l = strings.Replace(strings.Replace(l, "{", "", -1), "}", "", -1)
|
||||
|
||||
spl := strings.Split(l, ",")
|
||||
|
||||
x, _ := strconv.Atoi(spl[0][2:])
|
||||
m, _ := strconv.Atoi(spl[1][2:])
|
||||
a, _ := strconv.Atoi(spl[2][2:])
|
||||
s, _ := strconv.Atoi(spl[3][2:])
|
||||
|
||||
parts = append(parts, Part{x, m, a, s})
|
||||
}
|
||||
}
|
||||
|
||||
if part2 {
|
||||
pa := PartAcceptor{workflows["in"], 4000, 1, 4000, 1, 4000, 1, 4000, 1}
|
||||
|
||||
pas := []PartAcceptor{pa}
|
||||
|
||||
combos := int64(0)
|
||||
for len(pas) > 0 {
|
||||
//fmt.Printf("%v\n", pas)
|
||||
p := pas[0]
|
||||
pas = pas[1:]
|
||||
|
||||
for _, wf := range p.Wfl {
|
||||
if wf.CompareType != "" {
|
||||
//fmt.Printf("Splitting comparator\n")
|
||||
// Comparator! Will split
|
||||
if wf.CompareType == ">" {
|
||||
if wf.Comparing == "x" && p.Xmax > wf.Value {
|
||||
if p.Xmin > wf.Value {
|
||||
if wf.Result == "A" {
|
||||
fmt.Printf("Accepted: %v\n", p)
|
||||
combos += int64(p.Xmax-p.Xmin+1) * int64(p.Mmax-p.Mmin+1) * int64(p.Amax-p.Amin+1) * int64(p.Smax-p.Smin+1)
|
||||
} else if wf.Result != "R" {
|
||||
newP := PartAcceptor{workflows[wf.Result], p.Xmax, p.Xmin, p.Mmax, p.Mmin, p.Amax, p.Amin, p.Smax, p.Smin}
|
||||
pas = append(pas, newP)
|
||||
}
|
||||
} else { // Split
|
||||
if wf.Result == "A" {
|
||||
fmt.Printf("Accepted (split): %v\n", p)
|
||||
combos += int64(p.Xmax-(wf.Value+1)+1) * int64(p.Mmax-p.Mmin+1) * int64(p.Amax-p.Amin+1) * int64(p.Smax-p.Smin+1)
|
||||
} else if wf.Result != "R" {
|
||||
newP := PartAcceptor{workflows[wf.Result], p.Xmax, p.Xmin, p.Mmax, p.Mmin, p.Amax, p.Amin, p.Smax, p.Smin}
|
||||
pas = append(pas, newP)
|
||||
}
|
||||
|
||||
p.Xmax = wf.Value
|
||||
}
|
||||
} else if wf.Comparing == "m" && p.Mmax > wf.Value {
|
||||
if p.Mmin > wf.Value {
|
||||
if wf.Result == "A" {
|
||||
fmt.Printf("Accepted: %v\n", p)
|
||||
combos += int64(p.Xmax-p.Xmin+1) * int64(p.Mmax-p.Mmin+1) * int64(p.Amax-p.Amin+1) * int64(p.Smax-p.Smin+1)
|
||||
} else if wf.Result != "R" {
|
||||
newP := PartAcceptor{workflows[wf.Result], p.Xmax, p.Xmin, p.Mmax, p.Mmin, p.Amax, p.Amin, p.Smax, p.Smin}
|
||||
pas = append(pas, newP)
|
||||
}
|
||||
} else { // Split
|
||||
if wf.Result == "A" {
|
||||
fmt.Printf("Accepted: %v\n", p)
|
||||
combos += int64(p.Xmax-p.Xmin+1) * int64(p.Mmax-(wf.Value+1)+1) * int64(p.Amax-p.Amin+1) * int64(p.Smax-p.Smin+1)
|
||||
} else if wf.Result != "R" {
|
||||
newP := PartAcceptor{workflows[wf.Result], p.Xmax, p.Xmin, p.Mmax, p.Mmin, p.Amax, p.Amin, p.Smax, p.Smin}
|
||||
pas = append(pas, newP)
|
||||
}
|
||||
|
||||
p.Mmax = wf.Value
|
||||
}
|
||||
} else if wf.Comparing == "a" && p.Amax > wf.Value {
|
||||
if p.Amin > wf.Value {
|
||||
if wf.Result == "A" {
|
||||
fmt.Printf("Accepted: %v\n", p)
|
||||
combos += int64(p.Xmax-p.Xmin+1) * int64(p.Mmax-p.Mmin+1) * int64(p.Amax-p.Amin+1) * int64(p.Smax-p.Smin+1)
|
||||
} else if wf.Result != "R" {
|
||||
newP := PartAcceptor{workflows[wf.Result], p.Xmax, p.Xmin, p.Mmax, p.Mmin, p.Amax, p.Amin, p.Smax, p.Smin}
|
||||
pas = append(pas, newP)
|
||||
}
|
||||
} else { // Split
|
||||
if wf.Result == "A" {
|
||||
fmt.Printf("Accepted: %v\n", p)
|
||||
combos += int64(p.Xmax-p.Xmin+1) * int64(p.Mmax-p.Mmin+1) * int64(p.Amax-(wf.Value+1)+1) * int64(p.Smax-p.Smin+1)
|
||||
} else if wf.Result != "R" {
|
||||
newP := PartAcceptor{workflows[wf.Result], p.Xmax, p.Xmin, p.Mmax, p.Mmin, p.Amax, p.Amin, p.Smax, p.Smin}
|
||||
pas = append(pas, newP)
|
||||
}
|
||||
|
||||
p.Amax = wf.Value
|
||||
}
|
||||
} else if wf.Comparing == "s" && p.Smax > wf.Value {
|
||||
if p.Smin > wf.Value {
|
||||
if wf.Result == "A" {
|
||||
fmt.Printf("Accepted: %v\n", p)
|
||||
combos += int64(p.Xmax-p.Xmin+1) * int64(p.Mmax-p.Mmin+1) * int64(p.Amax-p.Amin+1) * int64(p.Smax-p.Smin+1)
|
||||
} else if wf.Result != "R" {
|
||||
newP := PartAcceptor{workflows[wf.Result], p.Xmax, p.Xmin, p.Mmax, p.Mmin, p.Amax, p.Amin, p.Smax, p.Smin}
|
||||
pas = append(pas, newP)
|
||||
}
|
||||
} else { // Split
|
||||
if wf.Result == "A" {
|
||||
fmt.Printf("Accepted: %v\n", p)
|
||||
combos += int64(p.Xmax-p.Xmin+1) * int64(p.Mmax-p.Mmin+1) * int64(p.Amax-p.Amin+1) * int64(p.Smax-p.Smin+1)
|
||||
} else if wf.Result != "R" {
|
||||
newP := PartAcceptor{workflows[wf.Result], p.Xmax, p.Xmin, p.Mmax, p.Mmin, p.Amax, p.Amin, p.Smax, wf.Value + 1}
|
||||
pas = append(pas, newP)
|
||||
}
|
||||
|
||||
p.Smax = wf.Value
|
||||
}
|
||||
}
|
||||
} else if wf.CompareType == "<" {
|
||||
if wf.Comparing == "x" && p.Xmin < wf.Value {
|
||||
if p.Xmax < wf.Value {
|
||||
if wf.Result == "A" {
|
||||
fmt.Printf("Accepted: %v\n", p)
|
||||
combos += int64(p.Xmax-p.Xmin+1) * int64(p.Mmax-p.Mmin+1) * int64(p.Amax-p.Amin+1) * int64(p.Smax-p.Smin+1)
|
||||
} else if wf.Result != "R" {
|
||||
newP := PartAcceptor{workflows[wf.Result], p.Xmax, p.Xmin, p.Mmax, p.Mmin, p.Amax, p.Amin, p.Smax, p.Smin}
|
||||
pas = append(pas, newP)
|
||||
}
|
||||
} else { // Split
|
||||
if wf.Result == "A" {
|
||||
fmt.Printf("Accepted (split): %v\n", p)
|
||||
combos += int64((wf.Value-1)-p.Xmin+1) * int64(p.Mmax-p.Mmin+1) * int64(p.Amax-p.Amin+1) * int64(p.Smax-p.Smin+1)
|
||||
} else if wf.Result != "R" {
|
||||
newP := PartAcceptor{workflows[wf.Result], p.Xmax, p.Xmin, p.Mmax, p.Mmin, p.Amax, p.Amin, p.Smax, p.Smin}
|
||||
pas = append(pas, newP)
|
||||
}
|
||||
|
||||
p.Xmin = wf.Value
|
||||
}
|
||||
} else if wf.Comparing == "m" && p.Mmin < wf.Value {
|
||||
if p.Mmax < wf.Value {
|
||||
if wf.Result == "A" {
|
||||
fmt.Printf("Accepted: %v\n", p)
|
||||
combos += int64(p.Xmax-p.Xmin+1) * int64(p.Mmax-p.Mmin+1) * int64(p.Amax-p.Amin+1) * int64(p.Smax-p.Smin+1)
|
||||
} else if wf.Result != "R" {
|
||||
newP := PartAcceptor{workflows[wf.Result], p.Xmax, p.Xmin, p.Mmax, p.Mmin, p.Amax, p.Amin, p.Smax, p.Smin}
|
||||
pas = append(pas, newP)
|
||||
}
|
||||
} else { // Split
|
||||
if wf.Result == "A" {
|
||||
fmt.Printf("Accepted: %v\n", p)
|
||||
combos += int64(p.Xmax-p.Xmin+1) * int64((wf.Value-1)-p.Mmin+1) * int64(p.Amax-p.Amin+1) * int64(p.Smax-p.Smin+1)
|
||||
} else if wf.Result != "R" {
|
||||
newP := PartAcceptor{workflows[wf.Result], p.Xmax, p.Xmin, p.Mmax, p.Mmin, p.Amax, p.Amin, p.Smax, p.Smin}
|
||||
pas = append(pas, newP)
|
||||
}
|
||||
|
||||
p.Mmin = wf.Value
|
||||
}
|
||||
} else if wf.Comparing == "a" && p.Amin < wf.Value {
|
||||
if p.Amax < wf.Value {
|
||||
if wf.Result == "A" {
|
||||
fmt.Printf("Accepted: %v\n", p)
|
||||
combos += int64(p.Xmax-p.Xmin+1) * int64(p.Mmax-p.Mmin+1) * int64(p.Amax-p.Amin+1) * int64(p.Smax-p.Smin+1)
|
||||
} else if wf.Result != "R" {
|
||||
newP := PartAcceptor{workflows[wf.Result], p.Xmax, p.Xmin, p.Mmax, p.Mmin, p.Amax, p.Amin, p.Smax, p.Smin}
|
||||
pas = append(pas, newP)
|
||||
}
|
||||
} else { // Split
|
||||
if wf.Result == "A" {
|
||||
fmt.Printf("Accepted: %v\n", p)
|
||||
combos += int64(p.Xmax-p.Xmin+1) * int64(p.Mmax-p.Mmin+1) * int64((wf.Value-1)-p.Amin+1) * int64(p.Smax-p.Smin+1)
|
||||
} else if wf.Result != "R" {
|
||||
newP := PartAcceptor{workflows[wf.Result], p.Xmax, p.Xmin, p.Mmax, p.Mmin, p.Amax, p.Amin, p.Smax, p.Smin}
|
||||
pas = append(pas, newP)
|
||||
}
|
||||
|
||||
p.Amin = wf.Value
|
||||
}
|
||||
} else if wf.Comparing == "s" && p.Smin < wf.Value {
|
||||
if p.Smax < wf.Value {
|
||||
if wf.Result == "A" {
|
||||
fmt.Printf("Accepted: %v\n", p)
|
||||
combos += int64(p.Xmax-p.Xmin+1) * int64(p.Mmax-p.Mmin+1) * int64(p.Amax-p.Amin+1) * int64(p.Smax-p.Smin+1)
|
||||
} else if wf.Result != "R" {
|
||||
newP := PartAcceptor{workflows[wf.Result], p.Xmax, p.Xmin, p.Mmax, p.Mmin, p.Amax, p.Amin, p.Smax, p.Smin}
|
||||
pas = append(pas, newP)
|
||||
}
|
||||
} else { // Split
|
||||
if wf.Result == "A" {
|
||||
fmt.Printf("Accepted: %v\n", p)
|
||||
combos += int64(p.Xmax-p.Xmin+1) * int64(p.Mmax-p.Mmin+1) * int64(p.Amax-p.Amin+1) * int64((wf.Value-1)-p.Smin+1)
|
||||
} else if wf.Result != "R" {
|
||||
newP := PartAcceptor{workflows[wf.Result], p.Xmax, p.Xmin, p.Mmax, p.Mmin, p.Amax, p.Amin, p.Smax, p.Smin}
|
||||
pas = append(pas, newP)
|
||||
}
|
||||
|
||||
p.Smin = wf.Value
|
||||
}
|
||||
}
|
||||
} else {
|
||||
panic("!?!?")
|
||||
}
|
||||
|
||||
} else if wf.Result == "A" {
|
||||
// Auto accept
|
||||
fmt.Printf("Accepted: %v\n", p)
|
||||
combos += int64(p.Xmax-p.Xmin+1) * int64(p.Mmax-p.Mmin+1) * int64(p.Amax-p.Amin+1) * int64(p.Smax-p.Smin+1)
|
||||
} else if wf.Result == "R" {
|
||||
// Do nothing, rejected
|
||||
fmt.Printf("Rejected: %v\n", p)
|
||||
} else {
|
||||
//fmt.Printf("Moved to %v (%v)\n", wf.Result, p)
|
||||
p.Wfl = workflows[wf.Result]
|
||||
pas = append(pas, p)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Expect: 167409079868000
|
||||
// Getting: 397530093888000
|
||||
|
||||
return combos
|
||||
|
||||
}
|
||||
|
||||
ratingSum := 0
|
||||
for _, p := range parts {
|
||||
wk := workflows["in"]
|
||||
|
||||
for wk != nil {
|
||||
workflowOne:
|
||||
for _, fnc := range wk {
|
||||
res := fnc.Method(p)
|
||||
|
||||
if res != "" {
|
||||
if res == "A" {
|
||||
ratingSum += (p.X + p.M + p.A + p.S)
|
||||
wk = nil
|
||||
} else if res == "R" {
|
||||
wk = nil
|
||||
} else {
|
||||
// it's a mapping
|
||||
wk = workflows[res]
|
||||
}
|
||||
break workflowOne
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// solve part 1 here
|
||||
return ratingSum
|
||||
}
|
||||
18
2023/19/input-example.txt
Executable file
18
2023/19/input-example.txt
Executable file
@@ -0,0 +1,18 @@
|
||||
px{a<2006:qkq,m>2090:A,rfg}
|
||||
pv{a>1716:R,A}
|
||||
lnx{m>1548:A,A}
|
||||
rfg{s<537:gd,x>2440:R,A}
|
||||
qs{s>3448:A,lnx}
|
||||
qkq{x<1416:A,crn}
|
||||
crn{x>2662:A,R}
|
||||
in{s<1351:px,qqz}
|
||||
qqz{s>2770:qs,m<1801:hdj,R}
|
||||
gd{a>3333:R,R}
|
||||
hdj{m>838:A,pv}
|
||||
|
||||
{x=787,m=2655,a=1222,s=2876}
|
||||
{x=1679,m=44,a=2067,s=496}
|
||||
{x=2036,m=264,a=79,s=2244}
|
||||
{x=2461,m=1339,a=466,s=291}
|
||||
{x=2127,m=1623,a=2188,s=1013}
|
||||
-
|
||||
Reference in New Issue
Block a user