본문으로 건너뛰기

"kata" 태그로 연결된 63개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 2분
karais89

Instructions

Your task is to make function, which returns the sum of a sequence of integers.

The sequence is defined by 3 non-negative values: begin, end, step.

If begin value is greater than the end, function should returns 0

Examples

SequenceSum (2,2,2); // => 2
SequenceSum (2,6,2); // => 12 -> 2 + 4 + 6
SequenceSum (1,5,1); // => 15 -> 1 + 2 + 3 + 4 + 5
SequenceSum (1,5,3); // => 5 -> 1 + 4
This is the first kata in the series:

1) Sum of a sequence (this kata) 2) Sum of a Sequence [Hard-Core Version]

My Solution

public static class Kata 
{
public static int SequenceSum(int start, int end, int step)
{
int sum = 0;
for (int i = start; i <= end; i += step)
{
sum += i;
}
return sum;
}
}

기본적인 for문의 사용 방법만 알면 풀 수 있는 문제.

Best Practices 1

public static class Kata
{
public static int SequenceSum(int start, int end, int step)
{
int sum = 0;

for ( int i = start; i <= end; i += step)
{
sum += i;
}

return sum;
}
}

답은 일치 한다.

Best Practices 2

public static class Kata
{
public static int SequenceSum(int start, int end, int step)
{
return start == end ? end : start > end ? 0 : SequenceSum(start + step, end, step) + start;
}
}

표 자체는 많이 받지 못한 해답인데. 재귀 함수를 사용하여 푸는 방식을 사용 하였다.

· 약 3분
karais89

Instructions

In mathematics, the factorial of a non-negative integer n, denoted by n!, is the product of all positive integers less than or equal to n. For example: 5! = 5 4 3 2 1 = 120. By convention the value of 0! is 1.

Write a function to calculate factorial for a given input. If input is below 0 or above 12 throw an exception of type

ArgumentOutOfRangeException (C#) or IllegalArgumentException (Java) or RangeException (PHP) or throw a RangeError (JavaScript).

More details about factorial can be found here: http://en.wikipedia.org/wiki/Factorial

My Solution

using System;

public static class Kata
{
public static int Factorial(int n)
{
if (n < 0 || n > 12)
throw new ArgumentOutOfRangeException("invalid value");

int sum = 1;
for (int i = 1; i <= n; i++)
{
sum *= i;
}
return sum;
}
}

팩토리얼 문제. 예외를 발생시키는 코드는 사실 잘 사용하지 않아서.. 예외 발생 부분은 찾아봤다.

Best Practices 1

using System;

public static class Kata
{
public static int Factorial(int n)
{
if(n < 0 || n > 12)
throw new ArgumentOutOfRangeException();
return n > 0 ? n * Factorial(n - 1) : 1;
}
}

재귀 함수 사용. 재귀 함수 부분도 생각해 보았는데.. 속된말로 스택 뽕빨 난다..란 말이 있어서 그냥 시도 조차 안했다. 사실 문제에서는 12개 까지의 값을 제한 하기 때문에 어떻게 본다면 이게 가장 좋은 코드 일 수도 있을 것 같다.

Best Practices 2

using System;
using System.Linq;

public static class Kata
{
public static int Factorial(int n)
{
if(n < 0 || n > 12) throw new ArgumentOutOfRangeException();

return Enumerable.Range(1, n).Aggregate(1, (x,y) => x * y);
}
}

Aggregate란 메서드는 처음 봄.

확인해보니 누산기에 값을 누적해준다고 생각하면 될 듯.

1부터 시작해서 n까지의 값을 누적해서 계속 곱해준다고 생각하면 될듯.

https://docs.microsoft.com/ko-kr/dotnet/api/system.linq.enumerable.aggregate?view=netframework-4.7.2

· 약 3분
karais89

Instructions

You probably know the "like" system from Facebook and other pages. People can "like" blog posts, pictures or other items. We want to create the text that should be displayed next to such an item.

Implement a function likes :: [String] -> String, which must take in input array, containing the names of people who like an item. It must return the display text as shown in the examples:

Kata.Likes(new string[0]) => "no one likes this"
Kata.Likes(new string[] {"Peter"}) => "Peter likes this"
Kata.Likes(new string[] {"Jacob", "Alex"}) => "Jacob and Alex like this"
Kata.Likes(new string[] {"Max", "John", "Mark"}) => "Max, John and Mark like this"
Kata.Likes(new string[] {"Alex", "Jacob", "Mark", "Max"}) => "Alex, Jacob and 2 others like this"

For 4 or more names, the number in and 2 others simply increases.

My Solution

using System;

public static class Kata
{
public static string Likes(string[] name)
{
if (name == null || name.Length == 0)
{
return "no one likes this";
}
else if (name.Length == 1)
{
return $"{name[0]} likes this";
}
else if (name.Length == 2)
{
return $"{name[0]} and {name[1]} like this";
}
else if (name.Length == 3)
{
return $"{name[0]}, {name[1]} and {name[2]} like this";
}
return $"{name[0]}, {name[1]} and {name.Length-2} others like this";
}
}

풀면서 이런 해결 방법 밖에 없나? 라는 생각을 했는데.. 다른 방법은 없나 보다.

결국엔 if else 다.. 원래는 string.Format을 사용하려다가..

그냥 $ 표현을 사용 하였다.

$ 기호는 C# 6.0에서 추가된 문자열 보간 (Interpolated Strings) 이다.

Best Practices

public static class Kata
{
public static string Likes(string[] names)
{
switch (names.Length)
{
case 0: return "no one likes this"; // :(
case 1: return $"{names[0]} likes this";
case 2: return $"{names[0]} and {names[1]} like this";
case 3: return $"{names[0]}, {names[1]} and {names[2]} like this";
default: return $"{names[0]}, {names[1]} and {names.Length - 2} others like this";
}
}
}

if와 switch의 차이 정도.. 나의 코드에서는 names가 null이 아니라는 보장이 없어서, null 검사를 해줬었는데 여기서는 그런 null 체크 코드는 없다.

· 약 2분
karais89

Instructions

Given a string of digits, you should replace any digit below 5 with '0' and any digit 5 and above with '1'. Return the resulting string.

My Solution

public class Kata
{
public static string FakeBin(string x)
{
string copyX = "";
for (int i = 0; i < x.Length; i++)
{
if (x[i] < '5')
copyX += '0';
else
copyX += '1';
}
return copyX;
}
}

처음에 문제 자체를 이해를 못해서, 테스트 코드를 보고 이해 한 후 해결 하였다.

해결하고 보니 string을 for문에서 계속 더해주는 문제가 있네..

StringBuilder을 쓸걸 그랬다..

그리고 비교 자체를 문자열 자체로 비교한게 문제가 있지 않을까 싶었는데.. 그냥 다들 그렇게 하네..

Best Practices 1

using System.Linq;

public class Kata
{
public static string FakeBin(string x)
{
return string.Concat(x.Select(a => a < '5' ? "0" : "1"));
}
}

Linq를 사용하여 해결 하였다.

Best Practices 2

using System.Text;
public class Kata
{
public static string FakeBin(string x)
{
StringBuilder builder = new StringBuilder();

foreach (char t in x)
{
builder.Append( t >= '5' ? '1' : '0' );
}

return builder.ToString();
}
}

builder를 사용하였다. 그리고 for 대신 foreach 사용.

· 약 3분
karais89

Instructions

There is an array with some numbers. All numbers are equal except for one. Try to find it!

findUniq([ 1, 1, 1, 2, 1, 1 ]) === 2
findUniq([ 0, 0, 0.55, 0, 0 ]) === 0.55

It’s guaranteed that array contains more than 3 numbers.

The tests contain some very huge arrays, so think about performance.

This is the first kata in series:

  1. Find the unique number (this kata)
  2. Find the unique string
  3. Find The Unique

My Solution

using System.Collections.Generic;
using System.Linq;

public class Kata
{
public static int GetUnique(IEnumerable<int> numbers)
{
int count = -1;
int firstNum = 0;
int diffCount = 0;
int findNum = 0;
foreach (int num in numbers)
{
if (++count == 0)
{
firstNum = num;
continue;
}

if (num == firstNum)
continue;


diffCount++;
findNum = num;
}

if (diffCount == 1)
return findNum;
else
return firstNum;
}
}
  • 배열의 개수는 3개 이상이 보증된다.
  • 원소 중 1개를 제외하고는 모든 수가 똑같다. 다른 수를 리턴해야 된다.
  • IEnumerable로 받아서 foreach문으로 루프를 돌렸다.
  • 첫번째 원소의 숫자를 기준으로 비교를 함.

풀이 방법

  1. 첫번째 원소와 다른 숫자가 1개 이상 존재시(diffCount가 1이상)에는 첫번째 원소가 유일한 수
  2. 첫번째 원소와 다른 숫자가 1개 이면 findNum으로 대입된 숫자가 유일한 수 이다.

좋은 방법 같지는 않다.

Best Practices 1

using System.Collections.Generic;
using System.Linq;

public class Kata
{
public static int GetUnique(IEnumerable<int> numbers)
{
return numbers.GroupBy(x=>x).Single(x=> x.Count() == 1).Key;
}
}

Linq를 사용하면 한 줄이면 풀수 있는 문제..

Best Practices 2

using System.Collections.Generic;
using System.Linq;

public class Kata
{
public static int GetUnique(IEnumerable<int> numbers)
{
int[] numArray = numbers.ToArray();

int prevNum = numbers.First();
for (int i = 0; i < numArray.Length - 1; i++)
{
if (numArray[i] != prevNum){
if(numArray[i+1] == numArray[i])
return prevNum;
else
return numArray[i];
}
}

return 0;
}
}

ToArray 함수의 경우 메모리 많은 양의 메모리를 사용한다고 한다. 문제에서는 아주 큰 배열도 가능하게 처리해달라고 하여 해당 답안은 적절치 않다고 한다.

· 약 3분
karais89

Instructions

The museum of incredible dull things

The museum of incredible dull things wants to get rid of some exhibitions. Miriam, the interior architect, comes up with a plan to remove the most boring exhibitions. She gives them a rating, and then removes the one with the lowest rating.

However, just as she finished rating all exhibitions, she's off to an important fair, so she asks you to write a program that tells her the ratings of the items after one removed the lowest one. Fair enough.

Task

Given an array of integers, remove the smallest value. Do not mutate the original array/list. If there are multiple elements with the same value, remove the one with a lower index. If you get an empty array/list, return an empty array/list.

Don't change the order of the elements that are left.

Remover.RemoveSmallest(new List<int>{1,2,3,4,5}) = new List<int>{2,3,4,5}
Remover.RemoveSmallest(new List<int>{5,3,2,1,4}) = new List<int>{5,3,2,4}
Remover.RemoveSmallest(new List<int>{2,2,1,2,1}) = new List<int>{2,2,2,1}

My Solution

using System;
using System.Collections.Generic;
using System.Linq;

public class Remover
{
public static List<int> RemoveSmallest(List<int> numbers)
{
// Good Luck!
if (numbers == null || numbers.Count == 0)
{
return new List<int>() { };
}

int minVal = int.MaxValue;
int minIndex = 0;
for (int i = 0; i < numbers.Count; i++)
{
if (minVal > numbers[i])
{
minVal = numbers[i];
minIndex = i;
}
}

List<int> removeSmallests = new List<int>(numbers);
removeSmallests.RemoveAt(minIndex);
return removeSmallests;
}
}

문제 자체는 전달 받은 리스트의 값 변경 없이 최소 값을 뺀 리스트를 반환하는 문제이다.

전달 받은 리스트에서 최소값을 구하고, 그 리스트를 복사한후 최소값을 구한 인덱스를 빼준후 반환해 주는 식으로 구했다.

Best Practices

using System;
using System.Collections.Generic;
using System.Linq;

public class Remover
{
public static List<int> RemoveSmallest(List<int> numbers)
{
numbers.Remove(numbers.DefaultIfEmpty().Min());
return numbers;
}
}

Linq를 사용하여 해결 하였다. 하지만 목록을 복제하지는 않아서, 문제에서 요구하는 완벽한 해결 방법은 아닌거 같다.

DefaultIfEmpty

  • IEnumerable<T>의 요소를 반환하거나, 시퀀스가 비어 있으면 기본값이 할당된 singleton 컬렉션을 반환합니다

DefaultIfEmpty 메서드는 객체 자체가 null 일때의 예외 처리도 함께 되어 있다.

public static IEnumerable<TSource> DefaultIfEmpty<TSource>(this IEnumerable<TSource> source, TSource defaultValue)
{
if (source == null)
throw Error.ArgumentNull(nameof (source));
return Enumerable.DefaultIfEmptyIterator<TSource>(source, defaultValue);
}

· 약 2분
karais89

Instructions

All of the animals are having a feast! Each animal is bringing one dish. There is just one rule: the dish must start and end with the same letters as the animal's name. For example, the great blue heron is bringing garlic naan and the chickadee is bringing chocolate cake.

Write a function feast that takes the animal's name and dish as arguments and returns true or false to indicate whether the beast is allowed to bring the dish to the feast.

Assume that beast and dish are always lowercase strings, and that each has at least two letters. beast and dish may contain hyphens and spaces, but these will not appear at the beginning or end of the string. They will not contain numerals.

My Solution

public class Kata
{
public static bool Feast(string beast, string dish)
{
return beast[0] == dish[0] && beast[beast.Length-1] == dish[dish.Length-1];
}
}```


맨 처음 문자열과 맨 마지막 문자열만 같으면 된다.

## Best Practices 1

```csharp
public class Kata
{
public static bool Feast(string beast, string dish)
{
return beast[0] == dish[0] && beast[beast.Length - 1] == dish[dish.Length - 1];
}
}

푸는 방식이 완전히 동일하여 다른 방식이 있나 보니 Linq를 사용하는 방식이 있다.

Linq를 사용하는 방식이 더 직관적인 것 같은데.. 이런걸 보면 무슨 기준으로 표를 주는건지 잘 모르겠다..

Best Practices 2

using System.Linq;

public class Kata
{
public static bool Feast(string beast, string dish) => beast.First() == dish.First() && beast.Last() == dish.Last();
}

· 약 1분
karais89

Instructions

Given a set of numbers, return the additive inverse of each. Each positive becomes negatives, and the negatives become positives.

invert([1,2,3,4,5]) == [-1,-2,-3,-4,-5]
invert([1,-2,3,-4,5]) == [-1,2,-3,4,-5]
invert([]) == []

My Solution

using System.Linq;
namespace Solution
{
public static class ArraysInversion
{
public static int[] InvertValues(int[] input)
{
//Code it!
int[] inversArray = new int[input.Length];
for (int i = 0; i < input.Length; i++)
{
inversArray[i] = -input[i];
}
return inversArray;
}
}
}

새로운 배열을 만들고, 역이 되는 정수를 저장하고 반환.

Best Practices

using System.Linq;
namespace Solution
{
public static class ArraysInversion
{
public static int[] InvertValues(int[] input)
{
return input.Select(n => -n).ToArray();
}
}
}

Linq의 Select 함수를 사용하여 역을 만들고 그 역을 배열로 반환해준다.

· 약 2분
karais89

Instructions

Create a function isDivisible(n, x, y) that checks if a number n is divisible by two numbers x AND y. All inputs are positive, non-zero digits.

Example:
isDivisible(3,1,3)--> true because 3 is divisible by 1 and 3
isDivisible(12,2,6)--> true because 12 is divisible by 2 and 6
isDivisible(100,5,3)--> false because 100 is not divisible by 3
isDivisible(12,7,5)--> false because 12 is neither divisible by 7 nor 5

My Solution

public class DivisibleNb {
public static bool isDivisible(long n, long x, long y) {
// your code
return n % x == 0 && n % y == 0;
}
}

조건 자체가 모든 수는 0이 아니고, 자연수이기때문에 따로 조건 체크는 하지 않고, 두개의 수를 나누었을때 나머지가 0이 아닌 경우를 구하여 리턴 해 주었다.

Best Practices

public class DivisibleNb {
public static bool isDivisible(long n, long x, long y) {
return (x != 0 && y != 0 && n % x == 0 && n % y == 0);
}
}

문제 해결 방법은 똑같은것 같고, 여기서는 x, y에 대한 0 검사를 해주어 Division by zero에 대한 처리를 해주었다.

이 해결에 대한 의견으로 아래와 같은 의견이 달림.

All inputs are positive, non-zero digits!
x != 0 && y != 0 superfluous

· 약 1분
karais89

Instructions

Nathan loves cycling.

Because Nathan knows it is important to stay hydrated, he drinks 0.5 litres of water per hour of cycling.

You get given the time in hours and you need to return the number of litres Nathan will drink, rounded to the smallest value.

For example:

time = 3 ----> litres = 1

time = 6.7---> litres = 3

time = 11.8--> litres = 5

My Solution

using System;

public class Kata
{
public static int Litres(double time)
{
int intTime = (int)time;

//The fun begins here.
return (intTime / 2);
}
}

어렵지 않게 해결.

Best Practices

using System;

public class Kata
{
public static int Litres(double time)
{
return (int)(time/2);
}
}

내 해결 방법과 유사하다.

Best Practices 2

using System;

public class Kata
{
public static int Litres(double time) => (int)(time*0.5);

}

2번째로 좋은 Best Practices인데..

C# 6.0 에서 새로 추가된 Expression-bodied member 기능을 사용하여 한줄로 표현 할 수 있다.