โ† run

go-06-job-scheduler

0.000
0/1 testsยท architecture
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