type EnneagramType = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9; const directKeys: Record = { 1: 1, 10: 1, 19: 1, 28: 1, 2: 2, 11: 2, 20: 2, 29: 2, 3: 3, 12: 3, 21: 3, 30: 3, 4: 4, 13: 4, 22: 4, 31: 4, 5: 5, 14: 5, 23: 5, 32: 5, 6: 6, 15: 6, 24: 6, 33: 6, 7: 7, 16: 7, 25: 7, 34: 7, 8: 8, 17: 8, 26: 8, 35: 8, 9: 9, 18: 9, 27: 9, 36: 9, }; const bipolarKeys: Record = { 37: { left: [8], right: [6] }, 38: { left: [1], right: [4, 7] }, 39: { left: [9], right: [3] }, 40: { left: [7], right: [5] }, 41: { left: [1], right: [7] }, 42: { left: [2], right: [5] }, 43: { left: [7, 8], right: [9] }, 44: { left: [5], right: [2, 4] }, 45: { left: [8], right: [2, 9] }, 46: { right: [1] }, 47: { right: [2] }, 48: { left: [3] }, 49: { right: [4] }, 50: { right: [5] }, 51: { right: [6] }, 52: { left: [7] }, 53: { left: [8] }, 54: { left: [9] }, }; export const enneagramTypeInfo: Record = { 1: { name: '1号 改革者', shortName: '改革者', description: '追求正确、负责、自律和改进。' }, 2: { name: '2号 助人者', shortName: '助人者', description: '重视关系、照顾他人和被需要。' }, 3: { name: '3号 成就者', shortName: '成就者', description: '重视目标、效率、表现和认可。' }, 4: { name: '4号 自我型', shortName: '自我型', description: '重视真实、独特、情绪深度和个人意义。' }, 5: { name: '5号 探索者', shortName: '探索者', description: '重视知识、理解、独立和能力感。' }, 6: { name: '6号 忠诚者', shortName: '忠诚者', description: '重视安全、支持、可靠性和风险预判。' }, 7: { name: '7号 享乐者', shortName: '享乐者', description: '重视自由、可能性、新体验和快乐。' }, 8: { name: '8号 挑战者', shortName: '挑战者', description: '重视力量、直接、掌控和保护边界。' }, 9: { name: '9号 调停者', shortName: '调停者', description: '重视和谐、稳定、舒适和避免冲突。' }, }; function addScore( scores: Record, type: EnneagramType, value: number, ) { scores[type].total += value; scores[type].count += 1; } export function calculateOEPSResults(answers: string[]) { const scores = Object.fromEntries( ([1, 2, 3, 4, 5, 6, 7, 8, 9] as EnneagramType[]).map((type) => [ type, { total: 0, count: 0 }, ]), ) as Record; answers.forEach((answer, index) => { const questionId = index + 1; const value = Number(answer || 0); if (!value) return; const directType = directKeys[questionId]; if (directType) { addScore(scores, directType, value); return; } const key = bipolarKeys[questionId]; if (!key) return; key.left?.forEach((type) => addScore(scores, type, 6 - value)); key.right?.forEach((type) => addScore(scores, type, value)); }); const ranked = (Object.entries(scores) as [string, { total: number; count: number }][]) .map(([type, score]) => ({ type: Number(type) as EnneagramType, total: score.total, count: score.count, average: score.count ? score.total / score.count : 0, ...enneagramTypeInfo[Number(type) as EnneagramType], })) .sort((a, b) => b.average - a.average); return { ranked, top: ranked[0], }; }