ThoughtWorks 코드 도전-FizzBuzzWhizz
20914 단어 코드
LZ의 2B 청년 코드를 보니 참혹하기 때문에 이런 문제에 대한 일반적인 사고를 탐구하기 위해 글을 쓴다.
원제:
Fizz Buzz Whizzz 당신은 체육 선생님입니다. 어떤 수업이 끝나기 5분 전에 게임을 하기로 결정했습니다.이때 100명의 학생이 수업을 하고 있었다.게임의 규칙은:
1. 당신은 먼저 세 개의 다른 특수수를 말하고, 요구는 반드시 한 자리수여야 한다. 예를 들어 3, 5, 7.
2. 모든 학생을 한 팀으로 만들어 순서대로 번호를 매긴다.
3. 학생이 숫자를 보고할 때 만약에 보고한 숫자가 첫 번째 특수수(3)의 배수라면 이 숫자를 말하지 말고 Fizz를 말해야 한다.만약 보고된 숫자가 두 번째 특수수(5)의 배수라면 버즈라고 한다.만약 보고된 숫자가 세 번째 특수수(7)의 배수라면 Whizz라고 해야 한다.
4. 학생이 숫자를 보고할 때 만약에 보고한 숫자가 두 개의 특수수의 배수인 경우에도 특수하게 처리해야 한다. 예를 들어 첫 번째 특수수와 두 번째 특수수의 배수라면 이 숫자를 말하지 말고 피자버즈라고 해야 한다.만약 동시에 세 개의 특수수의 배수라면, 피자 버즈 위즈라고 해야 한다.5. 학생이 숫자를 보고할 때 만약에 보고한 숫자에 첫 번째 특수수가 포함된다면 그 숫자를 말하지 말고 해당하는 단어를 말해야 한다. 예를 들어 이 예에서 첫 번째 특수수가 3이라면 13을 보고해야 하는 학생은 Fizz라고 말해야 한다.만약 숫자에 첫 번째 특수수가 포함된다면 규칙 3과 규칙 4를 무시한다. 예를 들어 35를 보고하려는 학생은 Fizz만 보고하고 BuzzWhizz는 보고하지 않는다.
간단해 보이는 제목이 그렇게 간단하지는 않다. 직접 쓰면 다음과 같다.
if, if , else if , if , for, [0] [1] [2]….
우리는 이 문제를 이해하자.
1. 당신은 먼저 세 개의 다른 특수수를 말하고, 요구는 반드시 한 자리수여야 한다. 예를 들어 3, 5, 7.
다른 세 개의 수는 반드시 한 자리수여야 한다. 이것들은 모두 검증 조건이다. 너는 알아차렸니?
2. 모든 학생을 한 팀으로 만들어 순서대로 번호를 매긴다.
생성 순서의 숫자.
3. 학생이 숫자를 보고할 때 만약에 보고한 숫자가 첫 번째 특수수(3)의 배수라면 이 숫자를 말하지 말고 Fizz를 말해야 한다.만약 보고된 숫자가 두 번째 특수수(5)의 배수라면 버즈라고 한다.만약 보고된 숫자가 세 번째 특수수(7)의 배수라면 Whizz라고 해야 한다.
규칙: 특정한 수의 배수라면 대응하는 값을 출력하고, 그렇지 않으면 숫자를 출력합니다.
4. 학생이 숫자를 보고할 때 만약에 보고한 숫자가 두 개의 특수수의 배수인 경우에도 특수하게 처리해야 한다. 예를 들어 첫 번째 특수수와 두 번째 특수수의 배수라면 이 숫자를 말하지 말고 피자버즈라고 해야 한다.만약 동시에 세 개의 특수수의 배수라면, 피자 버즈 위즈라고 해야 한다.
규칙: 여러 개의 특수수의 배수라면 모든 대응값을 출력합니다.
5. 학생이 숫자를 보고할 때 만약에 보고한 숫자에 첫 번째 특수수가 포함된다면 그 숫자를 말하지 말고 해당하는 단어를 말해야 한다. 예를 들어 이 예에서 첫 번째 특수수가 3이라면 13을 보고해야 하는 학생은 Fizz라고 말해야 한다.만약 숫자에 첫 번째 특수수가 포함된다면 규칙 3과 규칙 4를 무시한다. 예를 들어 35를 보고하려는 학생은 Fizz만 보고하고 BuzzWhizz는 보고하지 않는다.
규칙: 첫 번째 특수 숫자를 포함하면 첫 번째 특수 숫자에 대응하는 값만 출력합니다.
OK, 우리가 어떻게 해야 할지 생각해 보자...
우리는 다음 제목을 추상적으로 이해한다. "당신에게 한 무더기의 숫자를 입력한 다음에 일정한 규칙에 따라parse를 진행하고parse의 결과를 출력합니다."
그래서 이 제목에서 고찰하고자 하는 것은 당신이 어떻게 이런 규칙을 정의하고 어떻게 이런 규칙을 응용하며 어떻게 Parse를 해야 하는가?
규칙 Rule을 살펴보겠습니다.
Rule, 우선 순위가 있고 입력에 대한 패스를 할 수 있으며, 패스에 대응하는 사전이 필요합니다.
그래서 Rule은 이렇게 한다.
abstract class Rule
{
public abstract int Priority { get; }
public Dictionary<int, string> SpecialDictionary { get; set; }
public Rule(Dictionary<int, string> specialDictionary)
{
this.SpecialDictionary = specialDictionary;
}
public bool ParseNum(int num, ref string result)
{
if ((SpecialDictionary != null) && (SpecialDictionary.Count > 0))
{
return ParseNumCore(num, ref result);
}
else
{
return false;
}
}
protected abstract bool ParseNumCore(int num, ref string result);
}
이어서 Rule3: 만약에 특정한 수의 배수라면 대응하는 값을 출력해야 한다. 그렇지 않으면 출력 숫자를 출력하고 출력 숫자는 내가 가장 바깥쪽에 놓고 처리한다. 물론 필요하면 Rule2를 쓸 수도 있다.
class Rule3 : Rule
{
public Rule3(Dictionary<int, string> specialDictionary)
: base(specialDictionary)
{
}
public override int Priority
{
get { return 3; }
}
protected override bool ParseNumCore(int num, ref string result)
{
foreach (var special in SpecialDictionary)
{
if (num % special.Key == 0)
{
result = special.Value;
return true;
}
}
return false;
}
}
Rule4: 특수수의 배수가 여러 개인 경우 해당 값을 모두 내보냅니다.
class Rule4 : Rule
{
public Rule4(Dictionary<int, string> specialDictionary)
: base(specialDictionary)
{
}
public override int Priority
{
get { return 4; }
}
protected override bool ParseNumCore(int num, ref string result)
{
List<string> matches = new List<string>();
foreach (var special in SpecialDictionary)
{
if (num % special.Key == 0)
{
matches.Add(special.Value);
}
}
if (matches.Count > 1)
{
result = string.Join("", matches);
return true;
}
else
{
return false;
}
}
}
Rule5: 첫 번째 특수 숫자가 포함된 경우 첫 번째 특수 숫자에 해당하는 값만 출력됩니다.
class Rule5 : Rule
{
public Rule5(Dictionary<int, string> specialDictionary)
: base(specialDictionary)
{
}
public override int Priority
{
get { return 5; }
}
protected override bool ParseNumCore(int num, ref string result)
{
if (SpecialDictionary.Count > 0)
{
var firstSpecial = SpecialDictionary.First();
if (num.ToString().Contains(firstSpecial.Key.ToString()))
{
result = firstSpecial.Value;
return true;
}
}
return false;
}
}
다음: 가장 중요한 것은 바로 Parse 논리입니다. 이 Rule을 어떻게 호출해야 할지 생각해 보세요(visitor?):
foreach (var student in studentNums)
{
string parseResult = student.ToString();
foreach (Rule rule in rules)
{
if (rule.ParseNum(student, ref parseResult))
{
break;
}
}
Console.WriteLine(parseResult);
}
다음은 전체 코드입니다.
private static void FizzBuzz()
{
bool isValidInput = false;
do
{
Console.WriteLine("please input three numbers which is units digit, use ',' division ");
string[] inputNums = Console.ReadLine().Split(',');
if (ValidSpecialInput(inputNums))
{
isValidInput = true;
// create special dictionary to parse the students nums.
Dictionary<int, string> special = new Dictionary<int, string>();
special.Add(Int32.Parse(inputNums[0]), "Fizz");
special.Add(Int32.Parse(inputNums[1]), "Buzz");
special.Add(Int32.Parse(inputNums[2]), "Whizz");
// get students nums.
int studentsCount = 100;
var studentNums = Enumerable.Range(1, studentsCount);
// create rules to parse.
var rules = new List<Rule>()
{
new Rule5(special),
new Rule4(special),
new Rule3(special),
}.OrderByDescending(r => r.Priority);
// parse logic.
foreach (var student in studentNums)
{
string parseResult = student.ToString();
foreach (Rule rule in rules)
{
if (rule.ParseNum(student, ref parseResult))
{
break;
}
}
Console.WriteLine(parseResult);
}
Console.ReadLine();
}
else
{
Console.WriteLine("the input is not valid.");
}
}
while (isValidInput == false);
}
private static bool ValidSpecialInput(string[] specialInputs)
{
bool result = false;
if (specialInputs.Length == 3)
{
return specialInputs.All(input =>
{
int num = 0;
return Int32.TryParse(input, out num) && (num > 0) && (num < 10);
});
}
return result;
}
몇 가지 후속 사고:
1: 만약 입력한 것이 세 개가 아니라 네 개, 다섯 개의 스페셜이라면 어떻게 고쳐야 합니까?
2:학생 수가 100명이 아니면 1000명?
3: Rule3을 제한적으로 고려하고 그 다음에 Rule4, Rule5를 고려하면 어떻게 고쳐야 합니까?
4: 만약 또 다른 제한 조건이 있다면: 예를 들어 숫자가 소수라면 대응하는 값을 반순으로 출력하면 어떻게 처리합니까?
5: 숫자가 아닌 문자열을 입력하면 어떻게 처리해야 합니까?
전체 소스 다운로드:http://files.cnblogs.com/LoveJenny/FizzBuzz.7z
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
vue 단일 페이지에 여러 개의 echarts 도표가 있을 때의 공용 코드 쓰기html에서: 데이터 처리는 말할 필요가 없다.응, 직접 그림을 그려: 공통 섹션: 이 페이지를 떠날 때 파괴: 추가 정보: Vue + Echarts 차트 표시 및 동적 렌더링 준비 작업 echarts 의존 설치 n...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.