Kumite (ko͞omiˌtā) is the practice of taking techniques learned from Kata and applying them through the act of freestyle sparring.
You can create a new kumite by providing some initial code and optionally some test cases. From there other warriors can spar with you, by enhancing, refactoring and translating your code. There is no limit to how many warriors you can spar with.
A great use for kumite is to begin an idea for a kata as one. You can collaborate with other code warriors until you have it right, then you can convert it to a kata.
const numMinusSeven = function(num) { let youGoodBro = []; while (num > 0) { num -= 7; youGoodBro.push(num); } return youGoodBro.length; }
function numMinusSeven(num) {let youGoodBro = []while (num > 0) {num -= 7youGoodBro.push(num)}return youGoodBro.length- const numMinusSeven = function(num) {
- let youGoodBro = [];
- while (num > 0) {
- num -= 7;
- youGoodBro.push(num);
- }
- return youGoodBro.length;
- }
import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertFalse; // TODO: Replace examples and use TDD by writing your own tests class CalculatorTest { private Calculator calculator = new Calculator(); @Test public void shouldBeEven() { assertTrue(calculator.isEven(2)); } @Test public void shouldBeOdd() { assertFalse(calculator.isEven(3)); } }
- import org.junit.jupiter.api.Test;
- import static org.junit.jupiter.api.Assertions.assertTrue;
- import static org.junit.jupiter.api.Assertions.assertFalse;
- // TODO: Replace examples and use TDD by writing your own tests
- class CalculatorTest {
- private Calculator calculator = new Calculator();
- @Test
- public void shouldBeEven() {
Calculator calculator = new Calculator();- assertTrue(calculator.isEven(2));
- }
- @Test
- public void shouldBeOdd() {
Calculator calculator = new Calculator();- assertFalse(calculator.isEven(3));
- }
- }
Description:
The grid is a rectangular matrix consisting of non-negative integers representing the cost of moving to a specific cell. Each cell in the grid corresponds to a position in the path, and the value of the cell represents the cost associated with taking a step to that position.
Goal:
Move from position grid[0][0]
to position grid[-1][-1]
with as little cost as possible.
Allowed Moves:
You can only move horizontally (left or right) or vertically (up or down) to adjacent cells. Diagonal moves are not allowed
Additional Logic:
If there is uncertainty for which direction to go, AKA a tie, prioritize moving right. If you cannot move right, move down.
Examples:
Input:
[[0, 5, 4, 3],
[1, 0, 0, 0],
[2, 6, 7, 0]]
Logic:
(0,0) -> (1,0) -> (1,1) -> (1,2) -> (1,3) -> (2,3)
Output:
(0 + 1 + 0 + 0 + 0 + 0) = 1
Input (Edge case):
[[0, 9, 0, 0, 0],
[0, 9, 0, 9, 0],
[0, 0, 0, 9, 0]]
Logic:
(0,0) -> (1,0) -> (2,0) -> (2,1) -> (2,2) -> (1,2) -> (0,2) -> (0,3) ...
... -> (0,4) -> (1,4) -> (2,4)
Output:
0 (no values higher than zero collected on this path)
Fork #1:
Based off of the description you made, you left a couple of edge cases. Mainly that you never clarified that up or left are invalid. It could be assumed by the way your code ran, but it wasn't clear. I covered three of those edge cases here, but I left edge case 4 as a failed test just because my brain already hurts too much to add depth to the algorithm. Either way, this was a fun challenge! If no one makes improvements on this in a few days, I'll refactor again and write random tests for this.
def kimite(grid): rows, cols = len(grid), len(grid[0]) position = (0, 0) seen = set() total_cost = 0 # Helper function to find the min cost based on current coordinates def get_step_cost(*directions, ): compare = sorted([i for i in directions if i != None], key=lambda x: x[0]) multiple = [x for x in [i for i in directions if i != None] if x[0] == compare[0][0]] if len(multiple) > 1: for i in multiple: if i[1] == 'right': return i for i in multiple: if i[1] == 'down': return i else: return compare[0] # Helper function to find polar directions def get_direction(): up, down, left, right = None, None, None, None # Check Y if position[0] > 0 and (position[0] - 1, position[1]) not in seen: up = (grid[position[0] - 1][position[1]], 'up') if position[0] + 1 < rows and (position[0] + 1, position[1]) not in seen: down = (grid[position[0] + 1][position[1]], 'down') # Check X if position[1] > 0 and (position[0], position[1] - 1) not in seen: left = (grid[position[0]][position[1] - 1], 'left') if position[1] + 1 < cols and (position[0], position[1] + 1) not in seen: right = (grid[position[0]][position[1] + 1], 'right') return (up, down, left, right) # Traverse the grid to find the minimum cost path while position != (rows - 1, cols - 1): direction = get_direction() cost, move = get_step_cost(*direction) if move == 'up': position = (position[0] - 1, position[1]) total_cost += cost seen.add(position) continue if move == 'down': position = (position[0] + 1, position[1]) total_cost += cost seen.add(position) continue if move == 'left': position = (position[0], position[1] - 1) total_cost += cost seen.add(position) continue if move == 'right': position = (position[0], position[1] + 1) total_cost += cost seen.add(position) return total_cost
- def kimite(grid):
rows = len(grid)cols = len(grid[0])# Helper function to calculate the cost of a step based on current coordinates and directiondef get_step_cost(x, y, direction):if direction == "right" and x + 1 < cols:return grid[y][x + 1]elif direction == "down" and y + 1 < rows:return grid[y + 1][x]- rows, cols = len(grid), len(grid[0])
- position = (0, 0)
- seen = set()
- total_cost = 0
- # Helper function to find the min cost based on current coordinates
- def get_step_cost(*directions, ):
- compare = sorted([i for i in directions if i != None], key=lambda x: x[0])
- multiple = [x for x in [i for i in directions if i != None] if x[0] == compare[0][0]]
- if len(multiple) > 1:
- for i in multiple:
- if i[1] == 'right':
- return i
- for i in multiple:
- if i[1] == 'down':
- return i
- else:
return float('inf') # Return a very high cost if the step is not allowed- return compare[0]
# Initialize a 2D list to keep track of the minimum cost to reach each cellmin_costs = [[float('inf')] * cols for _ in range(rows)]min_costs[0][0] = grid[0][0]- # Helper function to find polar directions
- def get_direction():
- up, down, left, right = None, None, None, None
- # Check Y
- if position[0] > 0 and (position[0] - 1, position[1]) not in seen:
- up = (grid[position[0] - 1][position[1]], 'up')
- if position[0] + 1 < rows and (position[0] + 1, position[1]) not in seen:
- down = (grid[position[0] + 1][position[1]], 'down')
- # Check X
- if position[1] > 0 and (position[0], position[1] - 1) not in seen:
- left = (grid[position[0]][position[1] - 1], 'left')
- if position[1] + 1 < cols and (position[0], position[1] + 1) not in seen:
- right = (grid[position[0]][position[1] + 1], 'right')
- return (up, down, left, right)
- # Traverse the grid to find the minimum cost path
for y in range(rows):for x in range(cols):# Check rightward moveright_cost = min_costs[y][x] + get_step_cost(x, y, "right")if x + 1 < cols and right_cost < min_costs[y][x + 1]:min_costs[y][x + 1] = right_cost# Check downward movedown_cost = min_costs[y][x] + get_step_cost(x, y, "down")if y + 1 < rows and down_cost < min_costs[y + 1][x]:min_costs[y + 1][x] = down_cost# The minimum cost to reach the destination is stored at the bottom-right celldestination_cost = min_costs[rows - 1][cols - 1]return destination_cost if destination_cost != float('inf') else -1# Test casesgrid1 = [[0, 5, 4, 3],[1, 0, 0, 0],[2, 6, 7, 0]]print(kimite(grid1)) # Output: 12grid2 = [[0, 2, 3, 4],[5, 0, 0, 0],[6, 7, 8, 0]]print(kimite(grid2)) # Output: 9grid3 = [[0, 1, 2, 3],[6, 0, 4, 0],[5, 9, 8, 0]]print(kimite(grid3)) # Output: 6- while position != (rows - 1, cols - 1):
- direction = get_direction()
- cost, move = get_step_cost(*direction)
- if move == 'up':
- position = (position[0] - 1, position[1])
- total_cost += cost
- seen.add(position)
- continue
- if move == 'down':
- position = (position[0] + 1, position[1])
- total_cost += cost
- seen.add(position)
- continue
- if move == 'left':
- position = (position[0], position[1] - 1)
- total_cost += cost
- seen.add(position)
- continue
- if move == 'right':
- position = (position[0], position[1] + 1)
- total_cost += cost
- seen.add(position)
- return total_cost
import codewars_test as test # TODO Write tests import solution # Replace 'solution' with the actual name of your Python file # test.assert_equals(actual, expected, [optional] message) @test.describe("The Perplexing Path Puzzle") def test_group(): @test.it("Test Case 1") def test_case1(): grid = [[0, 5, 4, 3], [1, 0, 0, 0], [2, 6, 7, 0]] test.assert_equals(solution.kimite(grid), 1, "Failed Test Case 1") @test.it("Test Case 2") def test_case2(): grid = [[0, 2, 3, 4], [5, 0, 0, 0], [6, 7, 8, 0]] test.assert_equals(solution.kimite(grid), 2, "Failed Test Case 2") @test.it("Test Case 3") def test_case3(): grid = [[0, 1, 2, 3], [6, 0, 4, 0], [5, 9, 8, 0]] test.assert_equals(solution.kimite(grid), 5, "Failed Test Case 3") @test.it("Edge Case") def test_edge1(): grid = [ [0, 9, 0, 0, 0, 9, 0, 0, 0, 9], [0, 9, 0, 9, 0, 9, 0, 9, 0, 9], [0, 9, 0, 9, 0, 9, 0, 9, 0, 9], [0, 9, 0, 9, 0, 9, 0, 9, 0, 9], [0, 9, 0, 9, 0, 9, 0, 9, 0, 9], [0, 0, 0, 9, 0, 0, 0, 9, 0, 0], ] test.assert_equals(solution.kimite(grid), 0, "Failed Edge Case 1") @test.it('Edge Case 2') def test_edge2(): grid = [ [0, 9, 0, 0, 0, 9, 0, 0, 0, 9], [9, 9, 0, 9, 0, 9, 0, 9, 0, 9], [0, 9, 0, 9, 0, 9, 0, 9, 0, 9], [0, 9, 0, 9, 0, 9, 0, 9, 0, 9], [0, 9, 0, 9, 0, 9, 0, 9, 0, 9], [0, 0, 0, 9, 0, 0, 0, 9, 9, 0], ] test.assert_equals(solution.kimite(grid), 18, "Failed Edge Case 2") @test.it('Edge Case 3') def test_edge2(): grid = [ [0, 9, 0, 0, 0, 0, 0, 0, 0, 0], [0, 9, 0, 9, 0, 0, 9, 9, 9, 0], [0, 9, 0, 9, 9, 9, 9, 9, 0, 0], [0, 9, 0, 0, 0, 0, 0, 0, 9, 0], [0, 9, 9, 9, 9, 9, 9, 0, 9, 0], [0, 0, 0, 0, 0, 0, 0, 0, 9, 0], ] test.assert_equals(solution.kimite(grid), 0, "Failed Edge Case 3") @test.it('Edge Case 4') def test_edge2(): grid = [ [9, 9, 9, 9, 9, 9, 9, 9, 9, 9], [9, 9, 9, 9, 9, 9, 9, 9, 9, 9], [0, 0, 0, 0, 0, 0, 0, 0, 9, 9], [0, 0, 0, 0, 0, 0, 0, 0, 9, 9], [0, 0, 0, 0, 0, 0, 0, 0, 9, 9], [0, 0, 0, 0, 0, 0, 0, 0, 9, 9], ] test.assert_equals(solution.kimite(grid), 36, "Failed Edge Case 4")
- import codewars_test as test
- # TODO Write tests
- import solution # Replace 'solution' with the actual name of your Python file
- # test.assert_equals(actual, expected, [optional] message)
- @test.describe("The Perplexing Path Puzzle")
- def test_group():
- @test.it("Test Case 1")
- def test_case1():
- grid = [[0, 5, 4, 3],
- [1, 0, 0, 0],
- [2, 6, 7, 0]]
- test.assert_equals(solution.kimite(grid), 1, "Failed Test Case 1")
- @test.it("Test Case 2")
- def test_case2():
- grid = [[0, 2, 3, 4],
- [5, 0, 0, 0],
- [6, 7, 8, 0]]
- test.assert_equals(solution.kimite(grid), 2, "Failed Test Case 2")
- @test.it("Test Case 3")
- def test_case3():
- grid = [[0, 1, 2, 3],
- [6, 0, 4, 0],
- [5, 9, 8, 0]]
- test.assert_equals(solution.kimite(grid), 5, "Failed Test Case 3")
- @test.it("Edge Case")
- def test_edge1():
- grid = [
- [0, 9, 0, 0, 0, 9, 0, 0, 0, 9],
- [0, 9, 0, 9, 0, 9, 0, 9, 0, 9],
- [0, 9, 0, 9, 0, 9, 0, 9, 0, 9],
- [0, 9, 0, 9, 0, 9, 0, 9, 0, 9],
- [0, 9, 0, 9, 0, 9, 0, 9, 0, 9],
- [0, 0, 0, 9, 0, 0, 0, 9, 0, 0],
- ]
- test.assert_equals(solution.kimite(grid), 0, "Failed Edge Case 1")
- @test.it('Edge Case 2')
- def test_edge2():
- grid = [
- [0, 9, 0, 0, 0, 9, 0, 0, 0, 9],
- [9, 9, 0, 9, 0, 9, 0, 9, 0, 9],
- [0, 9, 0, 9, 0, 9, 0, 9, 0, 9],
- [0, 9, 0, 9, 0, 9, 0, 9, 0, 9],
- [0, 9, 0, 9, 0, 9, 0, 9, 0, 9],
- [0, 0, 0, 9, 0, 0, 0, 9, 9, 0],
- ]
- test.assert_equals(solution.kimite(grid), 18, "Failed Edge Case 2")
- @test.it('Edge Case 3')
- def test_edge2():
- grid = [
- [0, 9, 0, 0, 0, 0, 0, 0, 0, 0],
- [0, 9, 0, 9, 0, 0, 9, 9, 9, 0],
- [0, 9, 0, 9, 9, 9, 9, 9, 0, 0],
- [0, 9, 0, 0, 0, 0, 0, 0, 9, 0],
- [0, 9, 9, 9, 9, 9, 9, 0, 9, 0],
- [0, 0, 0, 0, 0, 0, 0, 0, 9, 0],
- ]
- test.assert_equals(solution.kimite(grid), 0, "Failed Edge Case 3")
- @test.it('Edge Case 4')
- def test_edge2():
- grid = [
- [9, 9, 9, 9, 9, 9, 9, 9, 9, 9],
- [9, 9, 9, 9, 9, 9, 9, 9, 9, 9],
- [0, 0, 0, 0, 0, 0, 0, 0, 9, 9],
- [0, 0, 0, 0, 0, 0, 0, 0, 9, 9],
- [0, 0, 0, 0, 0, 0, 0, 0, 9, 9],
- [0, 0, 0, 0, 0, 0, 0, 0, 9, 9],
- ]
- test.assert_equals(solution.kimite(grid), 36, "Failed Edge Case 4")
- changed the comments, giving the interface for cmp and swap
- added a reminder about what is supposed to be the pivot
- it works. with my approch without any troubles on the way, so looks good on user's side
- error messages seem ok. I'd still prefer the errors to be caught and transformed into a
test.fail(...)
- when scanning the tests, it seems very weird to have
swap_allowed
anddisallowed_swap
=> maybe rename one? unless they are actually opposite of each others, meaning only one should survive?
I didn't try to break it because I'm very bad at this (and mostly "not interested in that"). Seems mostly fine, from what I grab of it.
import random # Rules: # - no need to return anything # - the pivot is always the first value in the list # - `cmp(i,j)`: return -1,0 or 1 depending on element at index i being (resp) lower, equal or bigger than the element at index j. May be used `length` times # - `swap(i,j)`: exchange elements at index i and j. May be used at most one time, only after a call to `cmp` def one_quicksort_pass(n, cmp, swap): l,i,r = 0,0,n while i<r: match cmp(i,l): case 0: i+=1 case -1: swap(i,l) ; l,i = l+1,i+1 case 1: swap(i,r-1) ; r-=1
- import random
# enforced rules:# - `cmp` may be used `length` times# - `swap` may be used at most one times after `cmp`## ... thoughts?- # Rules:
- # - no need to return anything
- # - the pivot is always the first value in the list
- # - `cmp(i,j)`: return -1,0 or 1 depending on element at index i being (resp) lower, equal or bigger than the element at index j. May be used `length` times
- # - `swap(i,j)`: exchange elements at index i and j. May be used at most one time, only after a call to `cmp`
# this is :carrot:'s solution used as demo# don't comment on the kumite since then this shows up on the front page with solutiondef one_quicksort_pass(length, cmp, swap):e, i, w = length - 1, 1, 1while i <= e:c = cmp(i-w, i)if c > 0:swap(i-w, i)i += 1elif c < 0:if random.randrange(5): # 20% chance to behave wrong, remove condition for correct solutionswap(i, e)e -= 1else:w += 1i += 1- def one_quicksort_pass(n, cmp, swap):
- l,i,r = 0,0,n
- while i<r:
- match cmp(i,l):
- case 0: i+=1
- case -1: swap(i,l) ; l,i = l+1,i+1
- case 1: swap(i,r-1) ; r-=1