본문으로 건너뛰기

· 약 4분
karais89

Instructions

링크

Introduction

  Welcome Adventurer. Your aim is to navigate the maze and reach the finish point without touching any walls. Doing so will kill you instantly!

Maze Runner Task

  You will be given a 2D array of the maze and an array of directions. Your task is to follow the directions given. If you reach the end point before all your moves have gone, you should return Finish. If you hit any walls or go outside the maze border, you should return Dead. If you find yourself still in the maze after using all the moves, you should return Lost.

The Maze array will look like

maze = [[1,1,1,1,1,1,1],
[1,0,0,0,0,0,3],
[1,0,1,0,1,0,1],
[0,0,1,0,0,0,1],
[1,0,1,0,1,0,1],
[1,0,0,0,0,0,1],
[1,2,1,0,1,0,1]]

..with the following key

0 = Safe place to walk
1 = Wall
2 = Start Point
3 = Finish Point
  direction = ["N","N","N","N","N","E","E","E","E","E"] == "Finish"

Rules

  1. The Maze array will always be square i.e. N x N but its size and content will alter from test to test.
2. The start and finish positions will change for the final tests.
3. The directions array will always be in upper case and will be in the format of N = North, E = East, W = West and S = South.

Good luck, and stay safe!

Kata Series

If you enjoyed this, then please try one of my other Katas. Any feedback, translations and grading of beta Katas are greatly appreciated. Thank you.

My Solution

using System;

namespace CodeWars
{
class Kata
{
private enum MazeState
{
SafePlaceToWalk,
Wall,
StartPoint,
EndPoint
};

public struct Point
{
public int x;
public int y;

public override string ToString()
{
return $"[{x}, {y}]";
}
}

public Point FindStartPoint(int[,] maze)
{
for (int i = 0; i < maze.GetLength(0); i++)
{
for (int j = 0; j < maze.GetLength(1); j++)
{
if (maze[i,j] == (int)MazeState.StartPoint)
{
Point p = new Point();
p.y = i;
p.x = j;
return p;
}
}
}

Point notFoundPoint = new Point();
notFoundPoint.x = -1;
notFoundPoint.y = -1;
return notFoundPoint;
}

public string mazeRunner(int[,] maze, string[] directions)
{
// Code here
Point startPoint = FindStartPoint(maze);
Point nextPoint = startPoint;

for (int i = 0; i < directions.Length; i++)
{
switch(directions[i])
{
case "N": // up
nextPoint.y--;
break;
case "S": // down
nextPoint.y++;
break;
case "E": // right
nextPoint.x++;
break;
case "W": // left
nextPoint.x--;
break;
}

// out side check
if (nextPoint.x < 0 || nextPoint.x >= maze.GetLength(0) ||
nextPoint.y < 0 || nextPoint.y >= maze.GetLength(1))
{
return "Dead";
}

switch ((MazeState)maze[nextPoint.y, nextPoint.x])
{
case MazeState.Wall:
return "Dead";
case MazeState.EndPoint:
return "Finish";
default:
// nothing
break;
}
}

return "Lost";
}
}
}
  • direction 배열에 있는 스트링 값으로 start point 부터 시작하여 진행.
  • 중간에 벽에 닿으면 Dead 리턴
  • 모든 행동이 끝나기전에 finish에 도착한다면 Finish 리턴
  • 모든 행동이 끝나도 죽지 않았거나, finish 지점에 도착 하지 못했다면 Lost 리턴

Best Practices

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CodeWars
{
class Kata
{
public string mazeRunner(int[,] maze, string[] directions)
{
int startX = 0;
int startY = 0;
double len = Math.Sqrt(maze.Length);
for (int x = 0; x < len; x++)
{
for (int y = 0; y < len; y++)
{
if (maze[y, x] == 2) { startX = x; startY = y; }
}
}
for (int x = 0; x < directions.Length; x++)
{
switch (directions[x])
{
case "N": startY -= 1; break;
case "E": startX += 1; break;
case "S": startY += 1; break;
case "W": startX -= 1; break;
}
if (startY < 0 || startY > len - 1 || startX < 0 || startX > len - 1 || maze[startY, startX] == 1) { return "Dead"; }
if (maze[startY,startX] == 3) { return "Finish"; }
}

return "Lost";
}
}
}
  • 논리는 거의 비슷해 보인다.
  • 예외 처리 및 매직 넘버를 사용하는 방식이라 코드가 더 짧다.
  • 이게 더 베스트한 방식인지는 의문이 든다.

· 약 3분
karais89

Instructions

링크

Your task is to Combine two Strings. But consider the rule...

By the way you don't have to check errors or incorrect input values, every thing is ok without bad tricks, only two input strings and as result one output string;-)...

And here's the rule: Input Strings 'a' and 'b': For every character in string 'a' swap the casing of every occurance of the same character in string 'b'. Then do the same casing swap with the inputs reversed. Return a single string consisting of the changed version of 'a' followed by the changed version of 'b'. A char of 'a' is in 'b' regardless if it's in upper or lower case - see the testcases too. I think that's all;-)...

Some easy examples:

Input: "abc" and "cde" => Output: "abCCde"
Input: "abab" and "bababa" => Output: "ABABbababa"
Input: "ab" and "aba" => Output: "aBABA"

There are some static tests at the beginning and many random tests if you submit your solution.

Hope you have fun:-)!

My Solution

namespace smile67Kata
{
using System;
using System.Text;

public class Kata
{
public string SwapUpperOrLower(string a, string b)
{
StringBuilder aBuilder = new StringBuilder();
for (int i = 0; i < a.Length; i++)
{
int equalCnt = 0;
for (int j = 0; j < b.Length; j++)
{
if (char.ToUpper(a[i]) == char.ToUpper(b[j]))
{
equalCnt++;
}
}

char inChar = a[i];
if (equalCnt % 2 != 0)
{
inChar = char.IsLower(inChar) ? char.ToUpper(inChar) : char.ToLower(inChar);
}
aBuilder.Append(inChar);
}
return aBuilder.ToString();
}

public string workOnStrings(string a, string b)
{
// a, b
string newA = SwapUpperOrLower(a, b);

// b, a
string newB = SwapUpperOrLower(b, a);

return newA+newB;
}
}
}
  • a와 b에 대해서 문자열 a의 모든 문자에 대해 문자열 b에 있는 동일한 문자가 있을때 대소 문자를 바꾼다 스위칭 하면서 바꿔준다.
  • b도 똑같은 작업을 진행한다.
  • a+b를 합친후 리턴

Best Practices

namespace smile67Kata
{
using System;
using System.Linq;
public class Kata
{
public char needswitch(string s,char c){
return !(s.ToLower().Contains(char.ToLower(c))&&s.ToLower().Count(y=>y==char.ToLower(c))%2==1)
? c : c>96 ? char.ToUpper(c) : char.ToLower(c);
}
public string workOnStrings(string a, string b){
return string.Join("",a.Select(x=>needswitch(b,x))) + string.Join("",b.Select(x=>needswitch(a,x)));
}
}
}
  • Linq 사용
  • 아스키 코드 97 부터 소문자 a

· 약 5분
karais89

Instructions

링크

Short Intro

Some of you might remember spending afternoons playing Street Fighter 2 in some Arcade back in the 90s or emulating it nowadays with the numerous emulators for retro consoles.

Can you solve this kata? Suuure-You-Can!

UPDATE: a new kata's harder version is available here.

The Kata

You'll have to simulate the video game's character selection screen behaviour, more specifically the selection grid. Such screen looks like this:

Selection Grid Layout in text:

| Ryu | E.Honda | Blanka | Guile | Balrog | Vega |
| Ken | Chun Li | Zangief | Dhalsim | Sagat | M.Bison |

Input

  • the list of game characters in a 2x6 grid;
  • the initial position of the selection cursor (top-left is (0,0));
  • a list of moves of the selection cursor (which are up, down, left, right);

Output

  • the list of characters who have been hovered by the selection cursor after all the moves (ordered and with repetition, all the ones after a move, wether successful or not, see tests);

Rules

Selection cursor is circular horizontally but not vertically!

As you might remember from the game, the selection cursor rotates horizontally but not vertically; that means that if I'm in the leftmost and I try to go left again I'll get to the rightmost (examples: from Ryu to Vega, from Ken to M.Bison) and vice versa from rightmost to leftmost.

Instead, if I try to go further up from the upmost or further down from the downmost, I'll just stay where I am located (examples: you can't go lower than lowest row: Ken, Chun Li, Zangief, Dhalsim, Sagat and M.Bison in the above image; you can't go upper than highest row: Ryu, E.Honda, Blanka, Guile, Balrog and Vega in the above image).

Test

For this easy version the fighters grid layout and the initial position will always be the same in all tests, only the list of moves change.

Notice : changing some of the input data might not help you.

Examples

fighters = [
["Ryu", "E.Honda", "Blanka", "Guile", "Balrog", "Vega"],
["Ken", "Chun Li", "Zangief", "Dhalsim", "Sagat", "M.Bison"]
]
initial_position = (0,0)
moves = ['up', 'left', 'right', 'left', 'left']

then I should get:

['Ryu', 'Vega', 'Ryu', 'Vega', 'Balrog']

as the characters I've been hovering with the selection cursor during my moves. Notice: Ryu is the first just because it "fails" the first up See test cases for more examples.

fighters = [
["Ryu", "E.Honda", "Blanka", "Guile", "Balrog", "Vega"],
["Ken", "Chun Li", "Zangief", "Dhalsim", "Sagat", "M.Bison"]
]
initial_position = (0,0)
moves = ['right', 'down', 'left', 'left', 'left', 'left', 'right']

Result:

['E.Honda', 'Chun Li', 'Ken', 'M.Bison', 'Sagat', 'Dhalsim', 'Sagat']

OFF-TOPIC

Some music to get in the mood for this kata :

Street Fighter 2 - selection theme

My Solution

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

public class Kata
{
public string[] StreetFighterSelection(string[][] fighters, int[] position, string[] moves)
{
int col = fighters.Length;
int row = fighters[0].Length;

int curCol = position[0];
int curRow = position[1];

List<string> charTracking = new List<string>();
for (int i = 0; i < moves.Length; i++)
{
int moveCol;
int moveRow;
switch (moves[i])
{
case "up":
moveCol = curCol - 1;
if (moveCol >= 0)
{
curCol = moveCol;
}
break;
case "down":
moveCol = curCol + 1;
if (moveCol < col)
{
curCol = moveCol;
}
break;
case "left":
moveRow = curRow - 1;
curRow = moveRow < 0 ? row - 1 : moveRow;
break;
case "right":
moveRow = curRow + 1;
curRow = moveRow > row - 1 ? 0 : moveRow;
break;
}
charTracking.Add(fighters[curCol][curRow]);
}
return charTracking.ToArray();
}
}
  • 게임 캐릭터의 리스트는 2x6 그리드 이다.
  • 선택 커서의 초기 위치는 0,0 이다.
  • 선택 커서는 위, 아래, 좌, 우로 이동할 수 있다.
  • 커서의 순환은 (양 옆 혹은 위) 수평으로만 가능 하다.

Best Practices

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

public class Kata
{
public string[] StreetFighterSelection(string[][] fighters, int[] position, string[] moves)
{
var results = new List<string>();
var row = 0;
var col = 0;

foreach (var s in moves) {
switch (s) {
case "up": row -= 1;
break;
case "down": row += 1;
break;
case "left": col -= 1;
break;
case "right": col += 1;
break;
}
if (row < 0) row = 0;
if (row == fighters.Length) row--;
if (col == fighters[0].Length) col = 0;
if (col == -1) col = fighters[0].Length - 1;

results.Add(fighters[row][col]);
}

return results.ToArray();
}
}

거의 유사하지만, 범위 체크를 맨 아래에서 해주었다. 범위체크를 움직일때마다 해주는 것보다 맨 마지막에 해주는게 깔끔한 느낌도 든다.

· 약 3분
karais89

Instructions

링크

The input is a string str of digits. Cut the string into chunks (a chunk here is a substring of the initial string) of size sz (ignore the last chunk if its size is less than sz).

If a chunk represents an integer such as the sum of the cubes of its digits is divisible by 2, reverse that chunk; otherwise rotate it to the left by one position. Put together these modified chunks and return the result as a string.

If

  • sz is <= 0 or if str is empty return ""
  • sz is greater (>) than the length of str it is impossible to take a chunk of size sz hence return "".

Examples:

revrot("123456987654", 6) --> "234561876549"
revrot("123456987653", 6) --> "234561356789"
revrot("66443875", 4) --> "44668753"
revrot("66443875", 8) --> "64438756"
revrot("664438769", 8) --> "67834466"
revrot("123456779", 8) --> "23456771"
revrot("", 8) --> ""
revrot("123456779", 0) --> ""
revrot("563000655734469485", 4) --> "0365065073456944"

My Solution

using System;
using System.Text;
using System.Linq;

public class Revrot
{
public static string InternalRevRot(string str)
{
if (String.IsNullOrEmpty(str))
{
return string.Empty;
}

int sum = 0;
for (int i = 0; i < str.Length; i++)
{
sum += int.Parse(str[i].ToString());
}

StringBuilder strBuilder = new StringBuilder();
if (sum % 2 == 0)
{
for (int i = str.Length - 1; i >= 0; i--)
{
strBuilder.Append(str[i]);
}
return strBuilder.ToString();
}

for (int i = 1; i < str.Length; i++)
{
strBuilder.Append(str[i]);
}
strBuilder.Append(str[0]);
return strBuilder.ToString();
}

public static string RevRot(string strng, int sz)
{
if (sz <= 0 || String.IsNullOrEmpty(strng) || strng.Length < sz)
{
return string.Empty;
}

StringBuilder strBuilder = new StringBuilder();
for (int i = 0; i < strng.Length; i += sz)
{
if (i + sz < strng.Length)
{
string str = strng.Substring(i, sz);
strBuilder.Append(InternalRevRot(str));
}
}
return strBuilder.ToString();
}
}

일단 영어 해석이 안되서 헤맸다. 천천히 문제를 다시 읽어 봤다.

주어진 sz 매개변수 만큼 substring으로 문자열을 가르고 각각의 문자열의 합을 기준으로 다음과 같은 기준으로 판단

  1. 문자열의 총 합이 짝수이면 숫자 뒤집기. (1->2->3 순서일때 3->2->1)
  2. 문자열의 합이 홀수이면 왼쪽으로 한칸 이동시키기. (1->2->3 순서일때 2->3->1)

Best Practices

using System;
using System.Linq;

public class Revrot
{
public static string RevRot(string strng, int sz)
{
if (String.IsNullOrEmpty(strng) || sz <= 0 || sz > strng.Length)
return String.Empty;

return
new String(
Enumerable.Range(0, strng.Length/sz)
.Select(i => strng.Substring(i*sz, sz))
.Select(
chunk =>
chunk.Sum(digit => (int) Math.Pow(int.Parse(digit.ToString()), 3))%2 == 0
? chunk.Reverse()
: chunk.Skip(1).Concat(chunk.Take(1)))
.SelectMany(x => x)
.ToArray());
}
}

chunk.Reverse() 이 부분에 해당

      StringBuilder strBuilder = new StringBuilder();
if (sum % 2 == 0)
{
for (int i = str.Length - 1; i >= 0; i--)
{
strBuilder.Append(str[i]);
}
return strBuilder.ToString();
}

chunk.Skip(1).Concat(chunk.Take(1)) 이 부분에 해당

      for (int i = 1; i < str.Length; i++)
{
strBuilder.Append(str[i]);
}
strBuilder.Append(str[0]);
return strBuilder.ToString();

· 약 3분
karais89

Instructions

링크

Task Write a function that accepts msg string and returns local tops of string from the highest to the lowest. The string's tops are from displaying the string in the below way:

When the msg string is empty, return an empty string. The input strings may be very long. Make sure your solution has good performance. Check the test cases for more samples.

Note for C++ Do not post an issue in my solution without checking if your returned string doesn't have some invisible characters. You read most probably outside of msg string.

My Solution

using System;
using System.Text;
using System.Collections.Generic;

public static class Kata
{
public static string Tops(string msg)
{
if (string.IsNullOrEmpty(msg))
{
return string.Empty;
}

int switchCount = 0;
int addNum = 0;
int goalNum = 0;
List<int> topIndexs = new List<int>();
for (int i = 0; i < msg.Length; i++)
{
if (i == goalNum)
{
// switchCount is odd top index
if (switchCount % 2 == 1)
{
topIndexs.Add(i);
}
switchCount++;
addNum++;
goalNum += addNum;
}
}

StringBuilder strBuilder = new StringBuilder();
for (int i = topIndexs.Count - 1; i >= 0; i--)
{
strBuilder.Append(msg[topIndexs[i]]);
}

return strBuilder.ToString();
}
}

공통적으로 증가하는 수가 존재할 것 같다는 생각을 했는데 (수열) 찾지를 못해서, 그냥 가장 큰 수의 인덱스를 저장한 후에 스트링을 뿌려주는 방식으로 처리 하였다.

수열을 찾지 못한 이유는 중간에 계산 실수가 있었다.

Best Practices 1

using System.Text;

public static class Kata
{
public static string Tops(string msg)
{
StringBuilder result = new StringBuilder();

for(int i = 1, x = 0; i < msg.Length; i += 5 + 4 * x, x++)
result.Insert(0, msg[i]);

return result.ToString();
}
}

큰 수의 인덱스 배열 : 1 -> 6 -> 15 -> 28

차이 5, 9, 13

차이 : 5+(4*x) -> 5 -> 9 -> 13

으로 수열이 존재한다.

Best Practices 2

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


public static class Kata
{
public static string Tops(string msg)
{
int jump = 1;
Stack<char> result = new Stack<char>() { };
for (int i = 1; i < msg.Length; i += jump)
{
if (jump % 2 != 0)
result.Push(msg[i]);
jump += 1;
}
return String.Join("", result);
}

}

나와 생각한 방식은 거의 똑같은데, 훨씬 깔끔하게 처리 하였다.

일단 스트링을 뒤로 뿌려주는 부분을 스택을 통해 처리 하였다. 그리고 추가적으로 내 해결책에서 사용 하던 쓸데없는 변수도 사용하지 않았다.

· 약 2분
karais89

Instructions

Your task is to construct a building which will be a pile of n cubes. The cube at the bottom will have a volume of n^3, the cube above will have volume of (n-1)^3 and so on until the top which will have a volume of 1^3.

You are given the total volume m of the building. Being given m can you find the number n of cubes you will have to build?

The parameter of the function findNb (find_nb, find-nb, findNb) will be an integer m and you have to return the integer n such as n^3 + (n-1)^3 + ... + 1^3 = m if such a n exists or -1 if there is no such n.

Examples:

findNb(1071225) --> 45
findNb(91716553919377) --> -1
mov rdi, 1071225
call find_nb ; rax <-- 45

mov rdi, 91716553919377
call find_nb ; rax <-- -1

My Solution

def find_nb(m):
# your code
sum = 0
count = 0
while True:
count += 1
sum += count**3

if sum == m:
return count

if sum > m:
return -1

c#으로 똑같은 방법으로 풀었는데 테스트 케이스 몇 군데서 계속 에러가 나옴.

codewars 자체가 유저들이 문제를 직접 내고, 테스트 케이스를 작성을 하는 방식이라, 이런식으로 아예 통과를 못하는 경우가 있음.

그냥 넘어가려다가 그냥 파이썬으로 똑같은 방식으로 풀자! 해서 풀었음.

하다 보니 알게 된건 파이썬에서는 증감연산자가 없다는 사실.. (++, --)등

Best Practices

def find_nb(m):
n = 1
volume = 0
while volume < m:
volume += n**3
if volume == m:
return n
n += 1
return -1

거의 비슷한 방식이다.

· 약 2분
karais89

Instructions

Write a function, persistence, that takes in a positive parameter num and returns its multiplicative persistence, which is the number of times you must multiply the digits in num until you reach a single digit.

For example:

 persistence(39) == 3 // because 3*9 = 27, 2*7 = 14, 1*4=4
// and 4 has only one digit

persistence(999) == 4 // because 9*9*9 = 729, 7*2*9 = 126,
// 1*2*6 = 12, and finally 1*2 = 2

persistence(4) == 0 // because 4 is already a one-digit number

My Solution

using System;
using System.Collections.Generic;

public class Persist
{
public static long SumList(List<int> list)
{
long sum = 1;
foreach (int num in list)
{
sum *= num;
}
return sum;
}

public static bool CheckPersistenceList(List<int> list)
{
if (list.Count <= 1)
{
return false;
}

return true;
}

public static int RecusviePersistence(long n, int count)
{
List<int> toInts = new List<int>();
string strNum = n.ToString();
for (int i = 0; i < strNum.Length; i++)
{
toInts.Add(int.Parse(strNum[i].ToString()));
}

long sum = SumList(toInts);
Console.WriteLine("n: " + n + ", sum: " + sum);
if (CheckPersistenceList(toInts))
{
count++;
return RecusviePersistence(sum, count);
}
else
{
return count;
}
}

public static int Persistence(long n)
{
return RecusviePersistence(n, 0);
}
}

뭔가 쓸데 없이 길어지는 느낌..

Best Practices

using System;
using System.Linq;

public class Persist
{
public static int Persistence(long n)
{
int count = 0;
while (n > 9)
{
count++;
n = n.ToString().Select(digit => int.Parse(digit.ToString())).Aggregate((x, y) => x * y);
}
return count;
}
}

Linq 사용

· 약 4분
karais89

Instructions

Given an array of integers of any length, return an array that has 1 added to the value represented by the array.

  • the array can't be empty
  • only non-negative, single digit integers are allowed

Return nil (or your language's equivalent) for invalid inputs.

Examples

For example the array [2, 3, 9] equals 239, adding one would return the array [2, 4, 0].

[4, 3, 2, 5] would return [4, 3, 2, 6]

My Solution

using System;

namespace Kata
{
public static class Kata
{
public static int[] UpArray(int[] num)
{
// invaild check
if (num == null || num.Length == 0)
{
return null;
}

// invalid check
for (int i = 0; i < num.Length; i++)
{
if (num[i] < 0 || num[i] >= 10)
{
return null;
}
}

// array init
int[] arrayOnePlus = new int[num.Length];
for (int i = 0; i < arrayOnePlus.Length; i++)
{
arrayOnePlus[i] = num[i];
}

// one plus array
for (int i = num.Length - 1; i >= 0; i--)
{
int n = num[i] + 1;
if (n != 10)
{
arrayOnePlus[i] = n;
break;
}
else
{
arrayOnePlus[i] = 0;

// array size up..
if (i == 0)
{
int[] newArr = new int[arrayOnePlus.Length + 1];
newArr[0] = 1;
for (int j = 0; j < arrayOnePlus.Length; j++)
{
newArr[j+1] = arrayOnePlus[j];
}

return newArr;
}
}
}

return arrayOnePlus;
}
}
}

원래는 int 배열을 숫자로 바꾼후에 +1을 해주고 int 배열로 다시 만드는 방식으로 구현하려다, 그냥 배열 자체에 값을 구하는 식으로 구현 하였다.

  1. invaild 체크
  2. 인자로 전달 받은 배열을 새 배열에 복사
  3. 각 배열의 인덱스에 +1을 해준다. 그리고 만약 그 합이 10이 넘지 않으면 바로 새 배열의 값을 리턴.
  4. 만약 그 합이 10이 넘는다면 루프를 돌면서 10이 넘지 않을때 까지 반복한다.
  5. 마지막 배열까지 검사를 한 경우에도 10이 넘는 경우면 배열의 길이를 1 증가시켜줘야 되는 경우이므로 1을 증가 시켜준 후에 해당 배열을 다시 만들어 준다음에 리턴 해준다.

Best Practices

using System.Linq;

namespace Kata
{
public static class Kata
{
public static int[] UpArray(int[] num)
{
if (num.Length == 0 || num.Any(a => a < 0 || a > 9))
return null;

for (var i = num.Length - 1; i >= 0; i--)
{
if (num[i] == 9)
{
num[i] = 0;
}
else
{
num[i]++;
return num;
}
}
return new []{ 1 }.Concat(num).ToArray();
}
}
}

구하는 공식은 거의 비슷하지만, 이 코드가 더 짧다. int형 배열의 경우 레퍼런스를 넘겨주기 때문에, 배열 값 자체가 변하는 문제가 있으므로, 배열 값 변경을 원치 않는다면 새로운 배열에 값을 복사해서 진행 하면 될것 같고..

여기서 참고할 부분은 배열의 길이를 1 증가시켜주기 위해 새로 생성해 주는 부분.

int[] newArr = new int[arrayOnePlus.Length + 1];
newArr[0] = 1;
for (int j = 0; j < arrayOnePlus.Length; j++)
{
newArr[j+1] = arrayOnePlus[j];
}
new []{ 1 }.Concat(num).ToArray();

Linq를 사용하면 Concat 메서드를 사용하여 이렇게 간단히 줄일 수 있다는 점은 참고할 만 한 사실이다.

· 약 2분
karais89

Instructions

Some numbers have funny properties. For example:

89 --> 8¹ + 9² = 89 * 1

695 --> 6² + 9³ + 5⁴= 1390 = 695 * 2

46288 --> 4³ + 6⁴+ 2⁵ + 8⁶ + 8⁷ = 2360688 = 46288 * 51

Given a positive integer n written as abcd... (a, b, c, d... being digits) and a positive integer p we want to find a positive integer k, if it exists, such as the sum of the digits of n taken to the successive powers of p is equal to k * n. In other words:

Is there an integer k such as : (a ^ p + b ^ (p+1) + c ^(p+2) + d ^ (p+3) + ...) = n * k

If it is the case we will return k, if not return -1.

Note: n, p will always be given as strictly positive integers.

digPow(89, 1) should return 1 since 8¹ + 9² = 89 = 89 * 1
digPow(92, 1) should return -1 since there is no k such as 9¹ + 2² equals 92 * k
digPow(695, 2) should return 2 since 6² + 9³ + 5⁴= 1390 = 695 * 2
digPow(46288, 3) should return 51 since 4³ + 6⁴+ 2⁵ + 8⁶ + 8⁷ = 2360688 = 46288 * 51

My Solution

using System;

public class DigPow {
public static long digPow(int n, int p) {
string strN = n.ToString();
long sum = 0;
for (int i = 0; i < strN.Length; i++)
{
int digit = int.Parse(strN[i].ToString());
long powVal = (long)Math.Pow(digit, p + i);
sum += powVal;
}

if (sum % n == 0)
{
return sum / n;
}

return -1;
}
}
  1. int형을 String으로 변환
  2. 각 자릿수 대로 제곱 해준후 더해준다.
  3. 더해준 값이 n으로 나누어지면 몫 반환. 아니면 -1 반환

Best Practices

using System.Linq;
using System;

public class DigPow {
public static long digPow(int n, int p) {
var sum = Convert.ToInt64(n.ToString().Select(s => Math.Pow(int.Parse(s.ToString()), p++)).Sum());
return sum % n == 0 ? sum / n : -1;
}
}

Linq는 2줄이면 해결

· 약 3분
karais89

Instructions

Write Number in Expanded Form You will be given a number and you will need to return it as a string in Expanded Form. For example:

Kata.ExpandedForm(12); # Should return "10 + 2"
Kata.ExpandedForm(42); # Should return "40 + 2"
Kata.ExpandedForm(70304); # Should return "70000 + 300 + 4"

NOTE: All numbers will be whole numbers greater than 0.

If you liked this kata, check out part 2!!

My Solution

using System;
using System.Text;

public static class Kata
{
public static string ExpandedForm(long num)
{
// long to string
string strNum = "" + num;
StringBuilder builder = new StringBuilder();
for (int i = 0; i < strNum.Length; i++)
{
if (strNum[i] > '0')
{
if (builder.Length != 0)
{
builder.Append(" + ");
}

// char to string to int
int n = int.Parse(strNum[i].ToString());
double digit = strNum.Length - i - 1;
digit = Math.Pow(10, digit);

string strResult = "" + (n * digit);
builder.Append(strResult);
}
}
return builder.ToString();
}
}

항상 이런 자릿수 문제가 나오면 long형을 string으로 바꾸어 준다음에 풀면 쉽게 풀 수 있다.

builder를 사용하여 풀었고, 저번에 문제를 풀다 보니 맨 처음에만 검사를 해서 기호를 넣어주면 쉽게 해결이 되는 부분이 있어서 그게 생각나서 그렇게 풀어 봤다.

[Codewars #13] Help the bookseller (6kyu) Best Practices 2에서 사용한 방식

Best Practices 1

using System;
using System.Linq;

public static class Kata
{
public static string ExpandedForm(long num)
{
var str = num.ToString();
return String.Join(" + ", str
.Select((x, i) => char.GetNumericValue(x) * Math.Pow(10, str.Length - i - 1))
.Where(x => x > 0));
}
}

Linq를 사용하여 간단히 해결!

string에 있는 0 보다 큰 모든 값을 전부 자릿수대로 곱해주고 그 값을 조인 시켜 구한다.

Best Practices 2

using System;
using System.Collections.Generic;

public static class Kata
{
public static string ExpandedForm(long num)
{
Stack<long> parts = new Stack<long>();

for (long m = 1, n = num; n > 0; n /= 10, m *= 10)
{
long digit = n % 10;
if (digit > 0)
{
parts.Push(m * digit);
}
}

return string.Join(" + ", parts);
}
}

이거는 표 자체는 많이 받지 못한 풀이 방식인데.

stack을 사용하여 일단 자리수를 전부 구한다음에, string join으로 " + "를 연결하는게 신박한 방식인 것 같아서 실어 봤다.