const ROCK = 0; const PAPER = 1; const SCISSORS = 2; const LOOSE = 0; const DRAW = 1; const WIN = 2; const sum = (array) => array.reduce((prev, curr) => prev + curr); const modulo = (n, d) => ((n % d) + d) % d; const scoreForShape = (round) => { return round.me + 1; } const scoreForResult = (round) => { const pointDiff = modulo(round.opponent - round.me, 3); return { 0: 3, // tie 1: 0, // loose 2: 6 // win }[pointDiff] }; const decodeShapeSymbol = (symbol) => { return { A: ROCK, B: PAPER, C: SCISSORS, X: ROCK, Y: PAPER, Z: SCISSORS }[symbol]; } const decodeGuideSymbol = (symbol) => { return { X: LOOSE, Y: DRAW, Z: WIN }[symbol] } const getShapeForGuide = (opponent, guideHint) => { return modulo(guideHint - 1 + opponent, 3); }; // parse first part into {opponent, me} shapes const parseHandsPerRound = (inputString) => { const rounds = inputString.split('\n'); return rounds.map(p => { const shapes = p.split(' '); return { opponent: decodeShapeSymbol(shapes[0]), me: decodeShapeSymbol(shapes[1]) } }) }; // parse second part into {opponent, me} shapes const parseHandGuidePerRound = (inputString) => { const rounds = inputString.split('\n'); return rounds.map(p => { const shapes = p.split(' '); const opponent = decodeShapeSymbol(shapes[0]); const guideHint = decodeGuideSymbol(shapes[1]); return { opponent, me: getShapeForGuide(opponent, guideHint) } }) }; const mainDayTwoA = (inputString) => { const rounds = parseHandsPerRound(inputString); const scores = rounds.map(round => { return scoreForShape(round) + scoreForResult(round) }) return sum(scores); } const mainDayTwoB = (inputString) => { const rounds = parseHandGuidePerRound(inputString); const scores = rounds.map(round => { return scoreForShape(round) + scoreForResult(round) }) return sum(scores); }