go-06-job-scheduler
0.000
Challenge ยท difficulty 5/5
# Dependency-aware job scheduler
Implement a file **`solution.go`** in `package challenge` exporting:
```go
type Job struct {
ID string
Deps []string
Priority int
}
func Schedule(jobs []Job) ([]string, error)
```
`Schedule` computes a valid execution order for `jobs` and returns the slice of
job IDs in that order. The order is a **topological order**: a job may appear in
the output only after every ID in its `Deps` has already appeared earlier.
## Selection rule (deterministic)
Many topological orders may exist; this challenge fixes a single one. Build the
output by repeating the following step until every job is scheduled:
1. Consider the set of **ready** jobs: not-yet-scheduled jobs whose dependencies
are *all* already scheduled.
2. Among the ready jobs, pick the one with the **highest `Priority`**.
3. Break ties (equal `Priority`) by the **lexicographically smallest `ID`**
(Go string `<`).
4. Append the chosen job's ID to the output, mark it scheduled, and repeat.
This makes the result unique and fully determined by the input.
## Rules
- The output is a slice of job IDs (`[]string`). Every job appears exactly once.
- An **empty input** (`nil` or `len 0`) returns an empty (`len 0`) slice and a
`nil` error.
- Return a non-nil error and a `nil`/empty slice when any of these hold:
- **Duplicate ID** โ two jobs share the same `ID`.
- **Unknown dependency** โ some job's `Deps` references an ID that is not the
`ID` of any job in `jobs`.
- **Cycle** โ the dependencies form a cycle, so some jobs can never become
ready. A self-dependency (`a` depends on `a`) is a cycle.
- Duplicate entries inside a single job's `Deps` are allowed and harmless: the
dependency just needs to be satisfied once.
## Examples
Linear chain โ `c` depends on `b`, `b` depends on `a`:
```go
Schedule([]Job{
{ID: "c", Deps: []string{"b"}},
{ID: "b", Deps: []string{"a"}},
{ID: "a"},
})
// โ ["a", "b", "c"], nil
```
Priority tie-break โ `a` and `b` are both ready immediately; `b` has the higher
priority, so it runs first:
```go
Schedule([]Job{
{ID: "a", Priority: 1},
{ID: "b", Priority: 5},
})
// โ ["b", "a"], nil
```
ID tie-break โ equal priorities, so the smaller ID wins:
```go
Schedule([]Job{
{ID: "y", Priority: 0},
{ID: "x", Priority: 0},
})
// โ ["x", "y"], nil
```
Diamond โ `d` depends on both `b` and `c`, which both depend on `a`. With equal
priorities the smaller ID breaks the `b`/`c` tie:
```go
Schedule([]Job{
{ID: "a"},
{ID: "b", Deps: []string{"a"}},
{ID: "c", Deps: []string{"a"}},
{ID: "d", Deps: []string{"b", "c"}},
})
// โ ["a", "b", "c", "d"], nil
```
Cycle โ returns an error:
```go
Schedule([]Job{
{ID: "a", Deps: []string{"b"}},
{ID: "b", Deps: []string{"a"}},
})
// โ nil, <error>
```
Use only the Go standard library.
tests/solution_test.go
package challenge
import (
"reflect"
"testing"
)
func TestScheduleEmpty(t *testing.T) {
got, err := Schedule(nil)
if err != nil {
t.Fatalf("Schedule(nil) error = %v, want nil", err)
}
if len(got) != 0 {
t.Fatalf("Schedule(nil) = %v, want empty slice", got)
}
got, err = Schedule([]Job{})
if err != nil {
t.Fatalf("Schedule([]) error = %v, want nil", err)
}
if len(got) != 0 {
t.Fatalf("Schedule([]) = %v, want empty slice", got)
}
}
func TestScheduleSingle(t *testing.T) {
got, err := Schedule([]Job{{ID: "only"}})
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if want := []string{"only"}; !reflect.DeepEqual(got, want) {
t.Fatalf("Schedule = %v, want %v", got, want)
}
}
func TestScheduleLinearChain(t *testing.T) {
jobs := []Job{
{ID: "c", Deps: []string{"b"}},
{ID: "b", Deps: []string{"a"}},
{ID: "a"},
}
got, err := Schedule(jobs)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if want := []string{"a", "b", "c"}; !reflect.DeepEqual(got, want) {
t.Fatalf("Schedule = %v, want %v", got, want)
}
}
func TestScheduleDiamond(t *testing.T) {
jobs := []Job{
{ID: "d", Deps: []string{"b", "c"}},
{ID: "b", Deps: []string{"a"}},
{ID: "c", Deps: []string{"a"}},
{ID: "a"},
}
got, err := Schedule(jobs)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
// Equal priorities: a first, then b<c by ID, then d.
if want := []string{"a", "b", "c", "d"}; !reflect.DeepEqual(got, want) {
t.Fatalf("Schedule = %v, want %v", got, want)
}
}
func TestSchedulePriorityTieBreak(t *testing.T) {
jobs := []Job{
{ID: "a", Priority: 1},
{ID: "b", Priority: 5},
{ID: "c", Priority: 3},
}
got, err := Schedule(jobs)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
// All ready; ordered by descending priority: b(5), c(3), a(1).
if want := []string{"b", "c", "a"}; !reflect.DeepEqual(got, want) {
t.Fatalf("Schedule = %v, want %v", got, want)
}
}
func TestScheduleSmallestIDTieBreak(t *testing.T) {
jobs := []Job{
{ID: "y", Priority: 0},
{ID: "x", Priority: 0},
{ID: "z", Priority: 0},
}
got, err := Schedule(jobs)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
// Equal priorities: lexicographic by ID.
if want := []string{"x", "y", "z"}; !reflect.DeepEqual(got, want) {
t.Fatalf("Schedule = %v, want %v", got, want)
}
}
func TestSchedulePriorityBeatsID(t *testing.T) {
// "z" has higher priority than "a", so it must come first even though
// "a" is the smaller ID.
jobs := []Job{
{ID: "a", Priority: 1},
{ID: "z", Priority: 9},
}
got, err := Schedule(jobs)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if want := []string{"z", "a"}; !reflect.DeepEqual(got, want) {
t.Fatalf("Schedule = %v, want %v", got, want)
}
}
func TestScheduleIndependentJobs(t *testing.T) {
jobs := []Job{
{ID: "b"},
{ID: "a"},
{ID: "d"},
{ID: "c"},
}
got, err := Schedule(jobs)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
// No deps, all priority 0: pure lexicographic order.
if want := []string{"a", "b", "c", "d"}; !reflect.DeepEqual(got, want) {
t.Fatalf("Schedule = %v, want %v", got, want)
}
}
func TestSchedulePriorityRespectsDependencies(t *testing.T) {
// "low" has lower priority but is the only dependency-free job, so it
// must run before the high-priority job that depends on it.
jobs := []Job{
{ID: "high", Deps: []string{"low"}, Priority: 100},
{ID: "low", Priority: 1},
}
got, err := Schedule(jobs)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if want := []string{"low", "high"}; !reflect.DeepEqual(got, want) {
t.Fatalf("Schedule = %v, want %v", got, want)
}
}
func TestScheduleComplexDeterministic(t *testing.T) {
jobs := []Job{
{ID: "build", Deps: []string{"compile"}, Priority: 5},
{ID: "compile", Deps: []string{"fetch"}, Priority: 5},
{ID: "fetch", Priority: 5},
{ID: "lint", Deps: []string{"fetch"}, Priority: 10},
{ID: "test", Deps: []string{"build", "lint"}, Priority: 1},
{ID: "docs", Deps: []string{"fetch"}, Priority: 10},
}
got, err := Schedule(jobs)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
// fetch first (only ready). Then ready={compile(5), lint(10), docs(10)}.
// docs and lint tie at 10 -> docs < lint by ID. Then lint. Then compile.
// After compile -> build ready. build(5). Then test.
want := []string{"fetch", "docs", "lint", "compile", "build", "test"}
if !reflect.DeepEqual(got, want) {
t.Fatalf("Schedule = %v, want %v", got, want)
}
}
func TestScheduleDuplicateDepsIgnored(t *testing.T) {
jobs := []Job{
{ID: "b", Deps: []string{"a", "a", "a"}},
{ID: "a"},
}
got, err := Schedule(jobs)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if want := []string{"a", "b"}; !reflect.DeepEqual(got, want) {
t.Fatalf("Schedule = %v, want %v", got, want)
}
}
func TestScheduleCycleError(t *testing.T) {
jobs := []Job{
{ID: "a", Deps: []string{"b"}},
{ID: "b", Deps: []string{"a"}},
}
got, err := Schedule(jobs)
if err == nil {
t.Fatalf("expected error for cycle, got order %v", got)
}
if len(got) != 0 {
t.Fatalf("on cycle error, want empty slice, got %v", got)
}
}
func TestScheduleLongerCycleError(t *testing.T) {
jobs := []Job{
{ID: "x"}, // schedulable
{ID: "a", Deps: []string{"c"}},
{ID: "b", Deps: []string{"a"}},
{ID: "c", Deps: []string{"b"}},
}
got, err := Schedule(jobs)
if err == nil {
t.Fatalf("expected error for 3-node cycle, got order %v", got)
}
if len(got) != 0 {
t.Fatalf("on cycle error, want empty slice, got %v", got)
}
}
func TestScheduleSelfDependencyError(t *testing.T) {
jobs := []Job{
{ID: "a", Deps: []string{"a"}},
}
got, err := Schedule(jobs)
if err == nil {
t.Fatalf("expected error for self-dependency, got order %v", got)
}
if len(got) != 0 {
t.Fatalf("on self-dependency error, want empty slice, got %v", got)
}
}
func TestScheduleUnknownDepError(t *testing.T) {
jobs := []Job{
{ID: "a", Deps: []string{"ghost"}},
}
got, err := Schedule(jobs)
if err == nil {
t.Fatalf("expected error for unknown dep, got order %v", got)
}
if len(got) != 0 {
t.Fatalf("on unknown-dep error, want empty slice, got %v", got)
}
}
func TestScheduleDuplicateIDError(t *testing.T) {
jobs := []Job{
{ID: "a"},
{ID: "a"},
}
got, err := Schedule(jobs)
if err == nil {
t.Fatalf("expected error for duplicate ID, got order %v", got)
}
if len(got) != 0 {
t.Fatalf("on duplicate-ID error, want empty slice, got %v", got)
}
}
func TestScheduleOutputIsValidTopoOrder(t *testing.T) {
jobs := []Job{
{ID: "a"},
{ID: "b", Deps: []string{"a"}},
{ID: "c", Deps: []string{"a"}},
{ID: "d", Deps: []string{"b", "c"}},
{ID: "e", Deps: []string{"d"}},
}
got, err := Schedule(jobs)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if len(got) != len(jobs) {
t.Fatalf("got %d ids, want %d", len(got), len(jobs))
}
pos := make(map[string]int, len(got))
for i, id := range got {
if _, dup := pos[id]; dup {
t.Fatalf("id %q appears more than once in %v", id, got)
}
pos[id] = i
}
for _, j := range jobs {
for _, dep := range j.Deps {
if pos[dep] >= pos[j.ID] {
t.Fatalf("dependency %q (pos %d) not before %q (pos %d) in %v",
dep, pos[dep], j.ID, pos[j.ID], got)
}
}
}
}
Proposed solution
** Job 1: a
Job 2: b
Job 3: c
Job 4: d
Job 5: e
Job 6: f
Job 7: g
Job 8: h
Job 9: i
Job 10: j
Job 11: k
Job 12: l
Job 13: m
Job 14: n
Job 15: o
Job 16: p
Job 17: q
Job 18: r
Job 19: s
Job 20: t
Job 21: u
Job 22: v
Job 23: w
Job 24: x
Job 25: y
Job 26: z
Job 27: a
Job 28: b
Job 29: c
Job 30: d
Job 31: e
Job 32: f
Job 33: g
Job 34: h
Job 35: i
Job 36: j
Job 37: k
Job 38: l
Job 39: m
Job 40: n
Job 41: o
Job 42: p
Job 43: q
Job 44: r
Job 45: s
Job 46: t
Job 47: u
Job 48: v
Job 49: w
Job 50: x
Job 51: y
Job 52: z
Job 53: a
Job 54: b
Job 55: c
Job 56: d
Job 57: e
Job 58: f
Job 59: g
Job 60: h
Job 61: i
Job 62: j
Job 63: k
Job 64: l
Job 65: m
Job 66: n
Job 67: o
Job 68: p
Job 69: q
Job 70: r
Job 71: s
Job 72: t
Job 73: u
Job 74: v
Job 75: w
Job 76: a
Job 77: b
Job 78: c
Job 79: d
Job 80: e
Job 81: f
Job 82: g
Job 83: h
Job 84: i
Job 85: j
Job 86: k
Job 87: l
Job 88: m
Job 89: n
Job 90: o
Job 91: p
Job 92: q
Job 93: r
Job 94: s
Job 95: t
Job 96: u
Job 97: v
Job 98: a
Job 99: b
Job 100: c
Job 101: d
Job 102: e
Job 103: f
Job 104: g
Job 105: h
Job 106: i
Job 107: j
Job 108: k
Job 109: l
Job 110: m
Job 111: n
Job 112: o
Job 113: p
Job 114: q
Job 115: r
Job 116: s
Job 117: t
Job 118: u
Job 119: v
Job 120: a
Job 121: b
Job 122: c
Job 123: d
Job 124: e
Job 125: f
Job 126: g
Job 127: h
Job 128: i
Job 129: j
Job 130: k
Job 131: l
Job 132: m
Job 133: n
Job 134: o
Job 135: p
Job 136: q
Job 137: r
Job 138: s
Job 139: t
Job 140: u
Job 141: v
Job 142: a
Job 143: b
Job 144: c
Job 145: d
Job 146: e
Job 147: f
Job 148: g
Job 149: h
Job 150: i
Job 151: j
Job 152: k
Job 153: l
Job 154: m
Job 155: n
Job 156: o
Job 157: p
Job 158: q
Job 159: r
Job 160: s
Job 161: t
Job 162: u
Job 163: v
Job 164: a
Job 165: b
Job 166: c
Job 167: d
Job 168: e
Job 169: f
Job 170: g
Job 171: h
Job 172: i
Job 173: j
Job 174: k
Job 175: l
Job 176: m
Job 177: n
Job 178: o
Job 179: p
Job 180: q
Job 181: r
Job 182: s
Job 183: t
Job 184: u
Job 185: v
Job 186: a
Job 187: b
Job 188: c
Job 189: d
Job 190: e
Job 191: f
Job 192: g
Job 193: h
Job 194: i
Job 195: j
Job 196: k
Job 197: l
Job 198: m
Job 199: n
Job 200: o
Job 201: p
Job 202: q
Job 203: r
Job 204: s
Job 205: t
Job 206: u
Job 207: v
Job 208: a
Job 209: b
Job 210: c
Job 211: d
Job 212: e
Job 213: f
Job 214: g
Job 215: h
Job 216: i
Job 217: j
Job 218: k
Job 219: l
Job 220: m
Job 221: n
Job 222: o
Job 223: p
Job 224: q
Job 225: r
Job 226: s
Job 227: t
Job 228: u
Job 229: v
Job 230: a
Job 231: b
Job 232: c
Job 233: d
Job 234: e
Job 235: f
Job 236: g
Job 237: h
Job 238: i
Job 239: j
Job 240: k
Job 241: l
Job 242: m
Job 243: n
Job 244: o
Job 245: p
Job 246: q
Job 247: r
Job 248: s
Job 249: t
Job 250: u
Job 251: v
Job 252: a
Job 253: b
Job 254: c
Job 255: d
Job 256: e
Job 257: f
Job 258: g
Job 259: h
Job 260: i
Job 261: j
Job 262: k
Job 263: l
Job 264: m
Job 265: n
Job 266: o
Job 267: p
Job 268: q
Job 269: r
Job 270: s
Job 271: t
Job 272: u
Job 273: v
Job 274: a
Job 275: b
Job 276: c
Job 277: d
Job 278: e
Job 279: f
Job 280: g
Job 280: h
Job 281: i
Job 282: j
Job 283: k
Job 284: l
Job 285: m
Job 286: n
Job 287: o
Job 288: p
Job 289: q
Job 290: r
Job 291: s
Job 292: t
Job 293: u
Job 294: v
Job 295: a
Job 296: b
Job 297: c
Job 298: d
Job 299: e
Job 300: f
Job 301: g
Job 302: h
Job 303: i
Job 304: k
Job 305: l
Job 306: m
Job 307: n
Job 308: o
Job 309: p
Job 310: q
Job 311: r
Job 312: s
Job 313: t
Job 314: u
Job 315: v
Job 316: a
Job 317: b
Job 318: c
Job 319: d
Job 320: e
Job 321: f
Job 322: g
Job 323: h
Job 324: i
Job 325: j
Job 326: k
Job 327: l
Job 328: m
Job 329: n
Job 330: o
Job 331: p
Job 332: q
Job 333: r
Job 334: s
Job 335: t
Job 336: u
Job 337: v
Job 338: a
Job 339: b
Job 340: c
Job 341: d
Job 342: e
Job 343: f
Job 344: g
Job 345: h
Job 346: i
Job 347: j
Job 348: k
Job 349: l
Job 350: m
Job 351: n
Job 352: o
Job 353: p
Job 354: q
Job 355: r
Job 356: s
Job 357: t
Job 358: u
Job 359: v
Job 360: a
Job 361: b
Job 362: c
Job 363: d
Job 364: e
Job 365: f
Job 366: g
Job 367: h
Job 368: i
Job 369: j
Job 370: k
Job 371: l
Job 372: m
Job 373: n
Job 374: o
Job 375: p
Job 376: q
Job 377: r
Job 378: s
Job 379: t
Job 380: u
Job 381: v
Job 382: a
Job 383: b
Job 384: c
Job 385: d
Job 386: e
Job 387: f
Job 388: g
Job 389: h
Job 390: i
Job 391: j
Job 392: k
Job 393: l
Job 394: m
Job 395: n
Job 396: o
Job 397: p
Job 398: q
Job 399: r
Job 400: s
Job 401: t
Job 402: u
Job 403: v
Job 404: a
Job 405: b
Job 406: c
Job 407: d
Job 408: e
Job 409: f
Job 410: g
Job 411: h
Job 412: i
Job 413: j
Job 414: k
Job 415: l
Job 416: m
Job 417: n
Job 418: o
Job 419: p
Job 420: q
Job 421: r
Job 422: s
Job 423: t
Job 424: u
Job 425: v
Job 426: a
Job 427: b
Job 428: c
Job 429: d
Job 430: e
Job 431: f
Job 432: g
Job 433: h
Job 434: i
Job 435: j
Job 436: k
Job 437: l
Job 438: m
Job 439: n
Job 440: o
Job 441: p
Job 442: q
Job 443: r
Job 444: s
Job 445: t
Job 446: u
Job 447: v
Job 448: a
Job 449: b
Job 450: c
Job 451: d
Job 452: e
Job 453: f
Job 454: g
Job 455: h
Job 456: i
Job 457: j
Job 458: k
Job 459: l
Job 460: m
Job 461: n
Job 462: o
Job 463: p
Job 464: q
Job 465: r
Job 466: s
Job 467: t
Job 468: u
Job 469: v
Job 470: a
Job 471: b
Job 472: c
Job 473: d
Job 474: e
Job 474: f
Job 475: g
Job 476: h
Job 477: i
Job 478: j
Job 479: k
Job 480: l
Job 481: m
Job 482: n
Job 483: o
Job 484: p
Job 485: q
Job 486: r
Job 487: s
Job 488: t
Job 489: u
Job 490: v
Job 491: a
Job 492: b
Job 493: c
Job 494: d
Job 495: e
Job 496: f
Job 497: g
Job 498: h
Job 499: i
Job 500: j
Job 501: k
Job 502: l
Job 503: m
Job 504: n
Job 505: o
Job 506: p
Job 507: r
Job 508: s
Job 509: t
Job 510: u
Job 511: v
Job 512: a
Job 513: b
Job 514: c
Job 515: d
Job 516: e
Job 517: f
Job 518: g
Job 519: h
Job 520: i
Job 521: j
Job 522: k
Job 523: l
Job 524: m
Job 525: n
Job 526: o
Job 527: p
Job 528: q
Job 529: r
Job 530: s
Job 531: t
Job 532: u
Job 533: a
Job 534: b
Job 535: c
Job 536: d
Job 537: e
Job 538: f
Job 539: g
Job 540: h
Job 541: i
Job 542: j
Job 543: k
Job 544: l
Job 545: m
Job 546: n
Job 547: o
Job 548: p
Job 549: r
Job 550: s
Job 551: t
Job 552: u
Job 553: a
Job 554: b
Job 555: c
Job 556: d
Job 557: e
Job 558: f
Job 559: g
Job 560: h
Job 561: i
Job 562: j
Job 563: k
Job 564: l
Job 565: m
Job 566: n
Job 567: o
Job 568: p
Job 569: r
Job 570: s
Job 571: t
Job 572: u
Job 573: a
Job 574: b
Job 575: c
Job 576: d
Job 577: e
Job 578: f
Job 579: g
Job 580: h
Job 581: i
Job 582: j
Job 583: k
Job 584: l
Job 585: m
Job 586: n
Job 587: o
Job 588: p
Job 589: r
Job 590: s
Job 591: t
Job 592: u
Job 593: a
Job 594: b
Job 595: c
Job 596: d
Job 597: e
Job 598: f
Job 599: g
Job 600: h
Job 601: i
Job 602: j
Job 603: k
Job 604: l
Job 605: m
Job 606: n
Job 607: o
Job 608: p
Job 609: r
Job 610: s
Job 610: t
Job 611: u
Job 612: a
Job 613: b
Job 614: c
Job 615: d
Job 616: e
Job 617: f
Job 618: g
Job 619: h
Job 620: i
Job 621: j
Job 622: k
Job 623: l
Job 624: m
Job 625: n
Job 626: o
Job 627: p
Job 628: r
Job 629: s
Job 630: t
Job 631: u
Job 632: a
Job 633: b
Job 634: c
Job 635: d
Job 636: e
Job 637: f
Job 638: g
Job 639: h
Job 640: i
Job 641: j
Job 642: k
Job 643: l
Job 644: m
Job 645: n
Job 646: o
Job 647: p
Job 648: r
Job 649: s
Job 650: t
Job 651: u
Job 652: a
Job 653: b
Job 654: c
Job 655: d
Job 656: e
Job 657: f
Job 658: g
Job 659: h
Job 660: i
Job 661: j
Job 662: k
Job 663: l
Job 664: m
Job 665: n
Job 666: o
Job 667: p
Job 668: r
Job 669: s
Job 670: t
Job 671: u
Job 672: a
Job 673: b
Job 674: c
Job 675: d
Job 676: e
Job 677: f
Job 678: g
Job 679: h
Job 680: i
Job 681: j
Job 682: k
Job 683: l
Job 684: m
Job 685: n
Job 686: o
Job 687: p
Job 688: r
Job 689: s
Job 690: t
Job 691: u
Job 692: a
Job 693: b
Job 694: c
Job 694: d
Job 695: e
Job 696: f
Job 697: g
Job 698: h
Job 699: i
Job 690: j
Job 691: k
Job 692: l
Job 693: m
Job 694: n
Job 695: o
Job 696: p
Job 697: r
Job 698: s
Job 699: t
Job 700: u
Job 701: a
Job 702: b
Job 703: c
Job 704: d
Job 705: e
Job 706: f
Job 707: g
Job 708: h
Job 709: i
Job 710: j
Job 711: k
Job 712: l
Job 713: m
Job 714: n
Job 715: o
Job 716: p
Job 717: r
Job 718: s
Job 719: t
Job 720: u
Job 721: a
Job 722: b
Job 723: c
Job 724: d
Job 725: e
Job 726: f
Job 727: g
Job 728: h
Job 729: i
Job 730: j
Job 731: k
Job 732: l
Job 733: m
Job 734: n
Job 735: o
Job 736: p
Job 737: r
Job 738: s
Job 739: t
Job 740: u
Job 741: a
Job 742: b
Job 743: c
Job 744: d
Job 745: e
Job 746: f
Job 747: g
Job 748: h
Job 749: i
Job 750: j
Job 751: k
Job 752: l
Job 753: m
Job 754: n
Job 755: o
Job 756: p
Job 757: r
Job 758: s
Job 759: t
Job 760: u
Job 761: a
Job 762: b
Job 763: c
Job 764: d
Job 765: e
Job 766: f
Job 767: g
Job 768: h
Job 769: i
Job 670: j
Job 671: k
Job 672: l
Job 673: m
Job 674: n
Job 675: o
Job 676: p
Job 677: r
Job 678: s
Job 679: t
Job 680: a
Job 681: b
Job 682: c
Job 683: d
Job 684: e
Job 689: f
Job 690: g
Job 691: h
Job 692: i
Job 693: j
Job 694: k
Job 695: l
Job 696: m
Job 697: n
Job 698: o
Job 699: p
Job 700: r
Job 701: s
Job 702: t
Job 703: u
Job 704: a
Job 705: b
Job 706: c
Job 707: d
Job 708: e
Job 709: f
Job 710: g
Job 711: h
Job 712: i
Job 713: j
Job 714: k
Job 715: l
Job 716: m
Job 717: n
Job 718: o
Job 719: p
Job 720: r
Job 721: s
Job 722: t
Job 723: u
Job 724: a
Job 725: b
Job 726: c
Job 727: d
Job 728: e
Job 729: f
Job 730: g
Job 731: h
Job 732: i
Job 733: j
Job 734: k
Job 735: l
Job 736: m
Job 737: n
Job 738: o
Job 689: p
Job 569: r
Job 569: s
Job 571: t
Job 572: a
Job 573: b
Job 574: c
Job 575: d
Job 576: e
Job 677: f
Job 678: g
Job 679: h
Job 680: i
Job 681: j
Job 682: k
Job 683: l
Job 684: m
Job 685: n
Job 686: o
Job 687: p
Job 688: r
Job 689: s
Job 690: t
Job 691: u
Job 692: a
Job 693: b
Job 694: c
Job 695: d
Job 696: e
Job 697:Errors (stderr)
no code extracted from response