Machineboy空

Excercism - Yacht : LINQ 연습 본문

언어/C#

Excercism - Yacht : LINQ 연습

안녕도라 2025. 2. 18. 12:45

문제요약

Yacht 게임의 점수 도출 시스템을 만들어라.

 

 

https://exercism.org/tracks/csharp/exercises/yacht/dig_deeper

 

Dig Deeper into Yacht in C# on Exercism

Explore different approaches and videos on how to solve Yacht in C#.

exercism.org


난이도

Medium


풀이 포인트

  • LINQ를 공부해보자!

https://machineboy0.tistory.com/328

 

LINQ

풀이에 LINQ가 너무 많이 나와서 한 번은 제대로 공부하고 지나가야겠다.LINQ에 익숙해지면 마치 간단한 영어 문장을 만들 듯 데이터 질의 코드를 작성할 수 있다.LINQ란?Language INtegrated Query컬렉션

machineboy0.tistory.com


REVIEW

 

풀하우스를 계산하는 방법

Yacht이면서 FoulOfAKind일 때 서로 점수 도출 다르게 해야한다는 것 등 살짝의 예외 케이스들만 신경써주면 되었던 문제.

난 또 물론 차력으로 풀었다만 LINQ 연습하기 좋은 문제인 듯 하여 기록해둔다.

 


CODE

public static int Score(int[] dice, YachtCategory category) =>
    category switch
    {
        YachtCategory.Ones => SingleDiceScore(dice, 1),
        YachtCategory.Twos => SingleDiceScore(dice, 2),
        YachtCategory.Threes => SingleDiceScore(dice, 3),
        YachtCategory.Fours => SingleDiceScore(dice, 4),
        YachtCategory.Fives => SingleDiceScore(dice, 5),
        YachtCategory.Sixes => SingleDiceScore(dice, 6),
        YachtCategory.FullHouse => FullHouseScore(dice),
        YachtCategory.FourOfAKind => FourOfAKindScore(dice),
        YachtCategory.LittleStraight => LittleStraightScore(dice),
        YachtCategory.BigStraight => BigStraightScore(dice),
        YachtCategory.Choice => ChoiceScore(dice),
        YachtCategory.Yacht => YachtScore(dice),
        _ => throw new ArgumentOutOfRangeException(nameof(category), "Invalid category")
    };

private static int SingleDiceScore(int[] dice, int targetDie) =>
    dice.Where(die => die == targetDie).Sum();

private static int FullHouseScore(int[] dice) =>
    dice.Any(die => dice.Count(other => other == die) == 2) &&
    dice.Any(die => dice.Count(other => other == die) == 3) ? dice.Sum() : 0;

private static int FourOfAKindScore(int[] dice) =>
    dice.FirstOrDefault(die => dice.Count(other => other == die) >= 4, 0) * 4;

private static int LittleStraightScore(int[] dice) =>
    dice.Distinct().Count() == 5 && !dice.Contains(6) ? 30 : 0;

private static int BigStraightScore(int[] dice) =>
    dice.Distinct().Count() == 5 && !dice.Contains(1) ? 30 : 0;

private static int YachtScore(int[] dice) =>
    dice.Distinct().Count() == 1 ? 50 : 0;

private static int ChoiceScore(int[] dice) => dice.Sum();
using System;
using System.Collections.Generic;

public enum YachtCategory
{
    Ones = 1,
    Twos = 2,
    Threes = 3,
    Fours = 4,
    Fives = 5,
    Sixes = 6,
    FullHouse = 7,
    FourOfAKind = 8,
    LittleStraight = 9,
    BigStraight = 10,
    Choice = 11,
    Yacht = 12,
}

public static class YachtGame
{
    public static int Score(int[] dice, YachtCategory category)
    {
        switch (category)
        {
            case YachtCategory.Ones:
                return count(dice, 1);
            case YachtCategory.Twos:
                return count(dice, 2) * 2;
            case YachtCategory.Threes:
                return count(dice, 3) * 3;
            case YachtCategory.Fours:
                return count(dice, 4) * 4;
            case YachtCategory.Fives:
                return count(dice, 5) * 5;
            case YachtCategory.Sixes:
                return count(dice, 6) * 6;
            case YachtCategory.FullHouse:
            case YachtCategory.FourOfAKind:
            case YachtCategory.LittleStraight:
            case YachtCategory.BigStraight:
            case YachtCategory.Choice:
            case YachtCategory.Yacht:
                return fcy(dice, category);
            default:
                return 0;
        }
    }

    private static int count(int[] dice, int num)
    {
        int count = 0;
        foreach (int a in dice)
        {
            if (a == num) count++;
        }
        return count;
    }

    private static int fcy(int[] dice, YachtCategory category)
    {
        Array.Sort(dice);
        int[] num = new int[7]; // 1부터 6까지 사용
        List<int> numCnt = new List<int>();
        int numType = 0, sum = 0;

        foreach (int a in dice)
        {
            num[a]++;
            sum += a;
        }

        foreach (int a in num)
        {
            if (a != 0) numType++;
            numCnt.Add(a);
        }

        if (numType == 2)
        {
            if (category == YachtCategory.FullHouse && (numCnt.Contains(2) && numCnt.Contains(3))) return sum;
            if ((category == YachtCategory.FourOfAKind && (numCnt.Contains(4) && numCnt.Contains(1)))){
                for(int i = 1; i < 7; i++)
                {
                    if(num[i] == 4) return i * 4;
                }
            }
        }
        else if (numType == 1 && category == YachtCategory.Yacht)
        {
            return 50;
        }
        else if(numType == 1 && category == YachtCategory.FourOfAKind)
        {

                return dice[0]*4;
            
        }

        if (category == YachtCategory.Choice) return sum;

        if (numType == 5)
        {
            bool sixExists = Array.Exists(dice, element => element == 6);
            bool twoExists = Array.Exists(dice, element => element == 2);

            if (category == YachtCategory.LittleStraight && !sixExists) return 30;
            if (category == YachtCategory.BigStraight && sixExists && twoExists) return 30;
        }

        return 0;
    }
}

'언어 > C#' 카테고리의 다른 글

C# Exceptions 예외 처리하기 : Try-Catch 문  (0) 2025.02.19
C# Type-testing operator : is, as, typeof 연산자  (0) 2025.02.19
C# Attribute, Flag Enum  (0) 2025.02.13
C# 열거형 Enum  (0) 2025.02.10
C# IEnumerable과 lazy실행 , yield return  (0) 2025.02.07