Computer/Coding Test
Excercism - Scale Generator : string 다루기
안녕도라
2025. 2. 6. 15:06
문제요약
- chromatic scale: 반음계
- diatonic scale: 온음계
기본음이 주어지면 음계를 출력하는 함수를 완성하라!
https://exercism.org/tracks/csharp/exercises/scale-generator
Scale Generator in C# on Exercism
Can you solve Scale Generator in C#? Improve your C# skills with support from our world-class team of mentors.
exercism.org
난이도
Medium
풀이 포인트
- 문제 해석
- bb와 Bb를 동일하게
char first = char.ToUpper(tonic[0]);
string upperTonic = first + tonic.Substring(1); // 1번 인덱스 즉, 2번째 문자
REVIEW
우선은 문제 해석에 오래 걸렸다.
음계가 장조(?) #으로 표현되도록 모두 구현했더니,
어느 음계는 b플랫으로 표현되어야 한다는 조건이 있어, 급하게 함수를 추가했다.
switch문이 이제 좀 익숙해져서 엄청난 케이스 나열로 장단조 구분을 구현했는데 뭔가 다른 방법이 있으려나?
여튼, 오랜만에 조건별 단계를 깔끔하게 처리해 나간 코드라 후련하다.
CODE
using System;
using System.Collections.Generic;
// chromatic scale: 반음계, 12 음
// diatonic scale : 온음계, 7 음 -> 온음(M), 반음(m), 확장 2도(A)
public static class ScaleGenerator
{
static string[] pitches = new string[] {"A", "A#", "B", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#"};
static string[] pitchesFlat = new string[] {"A","Bb","B","C","Db","D","Eb","E","F","Gb","G","Ab"};
public static bool checkSharp(string tonic){
bool isSharp = true;
switch(tonic)
{
case "G":
case "D":
case "A":
case "E":
case "B":
case "F#":
case "e":
case "b":
case "f#":
case "c#":
case "g#":
case "d#":
isSharp = true;
break;
case "F":
case "Bb":
case "Eb":
case "Ab":
case "Db":
case "Gb":
case "d":
case "g":
case "c":
case "f":
case "bb":
case "eb":
isSharp = false;
break;
}
return isSharp;
}
public static string[] Chromatic(string tonic)
{
List<string> chromaticScale = new List<string>();
int tonicIndex = 0;
for(int i = 0; i < 12; i++){
if(checkSharp(tonic)){
if(tonic.ToUpper() == pitches[i]) tonicIndex = i;
}else{
if(tonic.ToUpper() == pitchesFlat[i]) tonicIndex = i;
}
}
while(chromaticScale.Count <12){
if(tonicIndex >= 12) tonicIndex = 0;
if(checkSharp(tonic)){
chromaticScale.Add(pitches[tonicIndex]);
}else{
chromaticScale.Add(pitchesFlat[tonicIndex]);
}
tonicIndex++;
}
return chromaticScale.ToArray();
}
public static string[] Interval(string tonic, string pattern)
{
List<string> diatonicScale = new List<string>();
int tonicIndex = 0;
char first = char.ToUpper(tonic[0]);
string upperTonic = first + tonic.Substring(1);
for(int i = 0; i < 12; i++){
if(checkSharp(tonic)){
if(tonic.ToUpper() == pitches[i]) tonicIndex = i;
}else{
if(upperTonic == pitchesFlat[i]) tonicIndex = i;
Console.WriteLine($"플랫 음계이고 {upperTonic}을 기본음으로 시작하며 인덱스는 {tonicIndex}이다.");
}
}
diatonicScale.Add(upperTonic);
foreach(char a in pattern)
{
switch(a)
{
case 'M':
tonicIndex+=2;
if(tonicIndex >= 12) tonicIndex -=12;
if(checkSharp(tonic)){
diatonicScale.Add(pitches[tonicIndex]);
}else{
diatonicScale.Add(pitchesFlat[tonicIndex]);
}
break;
case 'm':
tonicIndex++;
if(tonicIndex >= 12) tonicIndex -=12;
if(checkSharp(tonic)){
diatonicScale.Add(pitches[tonicIndex]);
}else{
diatonicScale.Add(pitchesFlat[tonicIndex]);
}
break;
case 'A':
tonicIndex+=3;
if(tonicIndex >= 12) tonicIndex -=12;
if(checkSharp(tonic)){
diatonicScale.Add(pitches[tonicIndex]);
}else{
diatonicScale.Add(pitchesFlat[tonicIndex]);
}
break;
default:
break;
}
}
return diatonicScale.ToArray();
}
}