{
  "schemaVersion": 1,
  "slug": "random-team-generator-calculator",
  "category": "fun",
  "kind": "implementation",
  "independentValidation": false,
  "implementationHash": "0371e51c8ef064eddce4cd9a9aa58b2f8683e344487e72d1df08e929cff2dcb6",
  "provenance": "Generated from the calculation contract used by the published page. Publication is not external validation.",
  "sourceFiles": [
    "data/calculators/random-team-generator-calculator.json",
    "src/engine.js"
  ],
  "runtimeSource": "/sources/engine.txt",
  "runtimeHash": "5c888d8898afbdee36267bb9977829e1e2ac568f6677c8ee87469c139864645c",
  "scope": "The compute function records implemented equations, constants, lookup tables and custom rules. Inputs record defaults and allowed values; outputs record precision and units. Defaults are examples, not recommendations. General background references are not evidence for this specific algorithm.",
  "publishedFormula": {
    "formula": "J_i = ⌊u_i×(i+1)⌋; (arr_i, arr_{J_i}) → (arr_{J_i}, arr_i), i: m−1 → 1; G_t = {arr_t, arr_{t+n}, arr_{t+2n}, …}, t ∈ {0,…,n−1}",
    "vars": [
      [
        "m",
        "Player count"
      ],
      [
        "n",
        "Number of teams"
      ],
      [
        "i",
        "Shuffle position"
      ],
      [
        "J_i",
        "Random swap index"
      ],
      [
        "u_i",
        "Seeded random in [0,1)"
      ],
      [
        "arr",
        "Shuffled player list"
      ],
      [
        "t",
        "Team index"
      ],
      [
        "G_t",
        "Team t"
      ]
    ],
    "note": "Paste names, choose team count or maximum team size, then generate. Reshuffle keeps the list. Results stay unchanged while editing. Team sizes differ by at most one. No. The seed makes the pseudo-random shuffle repeatable, but does not provide independent auditing or cryptographic fairness. For consequential selections, agree on a transparent process everyone can verify."
  },
  "externalEvidence": null,
  "contract": {
    "compute": "const mergedResult=(()=>{if((true&&![\"teams\", \"size\"].includes(String(mode)))||(true&&![\"off\", \"on\"].includes(String(captainMode)))||(true&&![\"unique\", \"keep\"].includes(String(duplicatePolicy))))return{__error:'inputError'};\nif(([\"teams\"].includes(String(mode))&&(!Number.isFinite(teams)||teams<2||teams>100))||([\"size\"].includes(String(mode))&&(!Number.isFinite(teamSize)||teamSize<1||teamSize>500))||(true&&(!Number.isFinite(seed)||seed<0||seed>1000000)))return{__error:'inputError'};\nconst rng=s=>{let a=Math.floor(s)>>>0;return()=>{a=(a+0x6D2B79F5)>>>0;let t=a;t=Math.imul(t^(t>>>15),t|1);t^=t+Math.imul(t^(t>>>7),t|61);return((t^(t>>>14))>>>0)/4294967296;};};\nconst list=String(players).split(/[\\n\\r,\\t;]+/).map(x=>x.trim()).filter(Boolean);\nconst n=mode==='size'?Math.ceil(list.length/teamSize):teams;\nif(!list.length||list.length>500||list.some(x=>x.length>100)||!Number.isInteger(n)||n<1||n>100||n>list.length||(mode==='teams'&&n<2)||(mode==='size'&&!Number.isInteger(teamSize))||!Number.isInteger(seed)||!['teams','size'].includes(mode)||!['on','off'].includes(captainMode)||!['unique','keep'].includes(duplicatePolicy))return{__error:'inputError'};\nif(duplicatePolicy!=='keep'&&new Set(list.map(x=>x.toLowerCase())).size<list.length)return{__error:'duplicateNames'};\nconst r=rng(seed),arr=list.slice();for(let i=arr.length-1;i>0;i--){const j=Math.floor(r()*(i+1));[arr[i],arr[j]]=[arr[j],arr[i]];}\nconst buckets=Array.from({length:n},()=>[]);arr.forEach((name,i)=>buckets[i%n].push(name));return{playersPerTeam:list.length/n,largestTeam:Math.max(...buckets.map(b=>b.length)),smallestTeam:Math.min(...buckets.map(b=>b.length)),teamsList:buckets.map((b,i)=>(i+1)+' ('+b.length+'): '+b.join(', ')).join('\\n'),captains:captainMode==='on'?buckets.map(b=>b[0]).join(', '):null,groupSizes:buckets.map(b=>b.length).join(' / '),totalPlayers:list.length,__groups:buckets};\n})();return mergedResult.__error?{\"teamsList\":null,\"captains\":null,\"groupSizes\":null,\"totalPlayers\":null,\"playersPerTeam\":null,\"largestTeam\":null,\"smallestTeam\":null,...mergedResult}:mergedResult;",
    "inputs": [
      {
        "name": "players",
        "type": "text",
        "multiline": true,
        "default": "Alex\nSam\nRiley\nJordan\nCasey\nMorgan",
        "preserveEmpty": true
      },
      {
        "name": "mode",
        "type": "select",
        "default": "teams",
        "options": [
          {
            "value": "teams"
          },
          {
            "value": "size"
          }
        ]
      },
      {
        "name": "teams",
        "type": "number",
        "default": 2,
        "min": 2,
        "max": 100,
        "step": 1,
        "showWhen": {
          "mode": [
            "teams"
          ]
        },
        "requiredValue": true,
        "strictRange": true
      },
      {
        "name": "teamSize",
        "type": "number",
        "default": 3,
        "min": 1,
        "max": 500,
        "step": 1,
        "showWhen": {
          "mode": [
            "size"
          ]
        },
        "requiredValue": true,
        "strictRange": true
      },
      {
        "name": "captainMode",
        "type": "select",
        "default": "off",
        "options": [
          {
            "value": "off"
          },
          {
            "value": "on"
          }
        ],
        "advanced": true
      },
      {
        "name": "duplicatePolicy",
        "type": "select",
        "default": "unique",
        "options": [
          {
            "value": "unique"
          },
          {
            "value": "keep"
          }
        ],
        "advanced": true
      },
      {
        "name": "seed",
        "type": "number",
        "default": 5,
        "min": 0,
        "max": 1000000,
        "step": 1,
        "advanced": true,
        "requiredValue": true,
        "strictRange": true
      }
    ],
    "outputs": [
      {
        "name": "teamsList",
        "type": "text",
        "display": "list",
        "separator": "\n",
        "precision": 0
      },
      {
        "name": "captains",
        "type": "text",
        "optional": true,
        "precision": 0
      },
      {
        "name": "groupSizes",
        "type": "text",
        "precision": 0
      },
      {
        "name": "totalPlayers",
        "precision": 0
      },
      {
        "name": "playersPerTeam",
        "precision": 2,
        "unit": ""
      },
      {
        "name": "largestTeam",
        "precision": 0,
        "unit": ""
      },
      {
        "name": "smallestTeam",
        "precision": 0,
        "unit": ""
      }
    ],
    "interpret": null
  }
}
