< Summary

Information
Class: LeetCode.Algorithms.TwentyFourGame.TwentyFourGameBruteForce
Assembly: LeetCode
File(s): D:\a\LeetCode-CS\LeetCode-CS\source\LeetCode\Algorithms\TwentyFourGame\TwentyFourGameBruteForce.cs
Line coverage
92%
Covered lines: 81
Uncovered lines: 7
Coverable lines: 88
Total lines: 167
Line coverage: 92%
Branch coverage
88%
Covered branches: 56
Total branches: 63
Branch coverage: 88.8%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
JudgePoint24(...)100%11100%
TryBuildPermutation(...)100%1010100%
TryEvaluateAllExpressions(...)86.95%524685.71%
TryApplyOperator(...)85.71%7793.75%

File(s)

D:\a\LeetCode-CS\LeetCode-CS\source\LeetCode\Algorithms\TwentyFourGame\TwentyFourGameBruteForce.cs

#LineLine coverage
 1// --------------------------------------------------------------------------------
 2// Copyright (C) 2025 Eugene Eremeev (also known as Yevhenii Yeriemeieiv).
 3// All Rights Reserved.
 4// --------------------------------------------------------------------------------
 5// This software is the confidential and proprietary information of Eugene Eremeev
 6// (also known as Yevhenii Yeriemeieiv) ("Confidential Information"). You shall not
 7// disclose such Confidential Information and shall use it only in accordance with
 8// the terms of the license agreement you entered into with Eugene Eremeev (also
 9// known as Yevhenii Yeriemeieiv).
 10// --------------------------------------------------------------------------------
 11
 12namespace LeetCode.Algorithms.TwentyFourGame;
 13
 14/// <inheritdoc />
 15public class TwentyFourGameBruteForce : ITwentyFourGame
 16{
 17    private const double TargetValue = 24.0;
 18    private const double Tolerance = 1e-6;
 19
 20    /// <summary>
 21    ///     Time complexity - O(1)
 22    ///     Space complexity - O(1)
 23    /// </summary>
 24    /// <param name="cards"></param>
 25    /// <returns></returns>
 26    public bool JudgePoint24(int[] cards)
 327    {
 328        Array.Sort(cards);
 29
 330        Span<bool> isCardUsed = stackalloc bool[4];
 331        Span<int> cardPermutation = stackalloc int[4];
 32
 333        return TryBuildPermutation(0, cards, isCardUsed, cardPermutation);
 334    }
 35
 36    private static bool TryBuildPermutation(int depth, ReadOnlySpan<int> cards, Span<bool> isCardUsed,
 37        Span<int> cardPermutation)
 8238    {
 8239        if (depth == 4)
 2840        {
 2841            return TryEvaluateAllExpressions(cardPermutation[0], cardPermutation[1], cardPermutation[2],
 2842                cardPermutation[3]);
 43        }
 44
 5445        var previousCard = -1;
 46
 50047        for (var i = 0; i < 4; i++)
 20448        {
 20449            if (isCardUsed[i])
 11950            {
 11951                continue;
 52            }
 53
 8554            if (cards[i] == previousCard)
 655            {
 656                continue;
 57            }
 58
 7959            isCardUsed[i] = true;
 7960            cardPermutation[depth] = cards[i];
 61
 7962            if (TryBuildPermutation(depth + 1, cards, isCardUsed, cardPermutation))
 863            {
 864                return true;
 65            }
 66
 7167            isCardUsed[i] = false;
 7168            previousCard = cards[i];
 7169        }
 70
 4671        return false;
 8272    }
 73
 74    private static bool TryEvaluateAllExpressions(double a, double b, double c, double d)
 2875    {
 30076        foreach (var firstOperator in Enum.GetValues<Operation>())
 10977        {
 119178            foreach (var secondOperator in Enum.GetValues<Operation>())
 43379            {
 475780                foreach (var thirdOperator in Enum.GetValues<Operation>())
 173081                {
 173082                    if (TryApplyOperator(a, b, firstOperator, out var t) &&
 173083                        TryApplyOperator(t, c, secondOperator, out var u) &&
 173084                        TryApplyOperator(u, d, thirdOperator, out var v) &&
 173085                        Math.Abs(v - TargetValue) < Tolerance)
 186                    {
 187                        return true;
 88                    }
 89
 172990                    if (TryApplyOperator(b, c, secondOperator, out t) &&
 172991                        TryApplyOperator(a, t, firstOperator, out u) &&
 172992                        TryApplyOperator(u, d, thirdOperator, out v) &&
 172993                        Math.Abs(v - TargetValue) < Tolerance)
 094                    {
 095                        return true;
 96                    }
 97
 172998                    if (TryApplyOperator(b, c, secondOperator, out t) &&
 172999                        TryApplyOperator(t, d, thirdOperator, out u) &&
 1729100                        TryApplyOperator(a, u, firstOperator, out v) &&
 1729101                        Math.Abs(v - TargetValue) < Tolerance)
 0102                    {
 0103                        return true;
 104                    }
 105
 1729106                    if (TryApplyOperator(c, d, thirdOperator, out t) &&
 1729107                        TryApplyOperator(b, t, secondOperator, out u) &&
 1729108                        TryApplyOperator(a, u, firstOperator, out v) &&
 1729109                        Math.Abs(v - TargetValue) < Tolerance)
 1110                    {
 1111                        return true;
 112                    }
 113
 1728114                    if (TryApplyOperator(a, b, firstOperator, out t) &&
 1728115                        TryApplyOperator(c, d, thirdOperator, out u) &&
 1728116                        TryApplyOperator(t, u, secondOperator, out v) &&
 1728117                        Math.Abs(v - TargetValue) < Tolerance)
 0118                    {
 0119                        return true;
 120                    }
 1728121                }
 431122            }
 107123        }
 124
 26125        return false;
 28126    }
 127
 128    private static bool TryApplyOperator(double left, double right, Operation operation, out double result)
 25919129    {
 25919130        switch (operation)
 131        {
 132            case Operation.Addition:
 6547133                result = left + right;
 134
 6547135                return true;
 136            case Operation.Subtraction:
 6496137                result = left - right;
 138
 6496139                return true;
 140            case Operation.Multiplication:
 6462141                result = left * right;
 142
 6462143                return true;
 144            case Operation.Division:
 6414145                if (Math.Abs(right) < Tolerance)
 46146                {
 46147                    result = 0;
 148
 46149                    return false;
 150                }
 151
 6368152                result = left / right;
 153
 6368154                return true;
 155            default:
 0156                throw new ArgumentOutOfRangeException(nameof(operation), operation, null);
 157        }
 25919158    }
 159
 160    private enum Operation
 161    {
 162        Addition,
 163        Subtraction,
 164        Multiplication,
 165        Division
 166    }
 167}