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.
export function validateString(input: string, index: number): boolean { const validator = new BracketsValidator(); for (let i = index; i < input.length; i++) { const char = input[i]; if (!validator.isValidChar(char)) { return false; } } return true; } class BracketsValidator { private readonly bracketPairs: Record<string, string> = { '{': '}', '[': ']', '(': ')', }; private readonly openBrackets: Set<string> = new Set(Object.keys(this.bracketPairs)); private readonly closingBrackets: Set<string> = new Set(Object.values(this.bracketPairs)); private stack: string[] = []; public isValidChar(char: string): boolean { if (this.isNotBracket(char)) { return true; } if (this.isOpeningBracket(char)) { this.push(char); return true; } if (this.hasMatchFor(char)) { this.pop(); return true; } return false; } private push(bracket: string): void { this.stack.push(bracket); } private pop(): string|undefined { return this.stack.pop(); } private lastFromStack(): string|undefined { return this.stack.slice(-1)[0]; } private hasMatchFor(bracket: string): boolean { const previousBracket: string|undefined = this.lastFromStack(); if (undefined === previousBracket) { return false; } const match = this.matchFor(bracket); if (previousBracket !== match) { return false; } return true; } private isOpeningBracket(char: string): boolean { if (this.openBrackets.has(char)) { return true; } return false; } private isClosingBracket(char: string): boolean { if (this.closingBrackets.has(char)) { return true; } return false; } private isNotBracket(char: string): boolean { if (this.isOpeningBracket(char)) { return false; } if (this.isClosingBracket(char)) { return false; } return true; } private matchFor(bracket: string): string { const index: number = Object.values(this.bracketPairs).indexOf(bracket); return Object.keys(this.bracketPairs)[index]; } }
const bracketPairs: Record<string, string> = {'{': '}','[': ']','(': ')',}const openBrackets: Set<string> = new Set(Object.keys(bracketPairs));const closingBrackets: Set<string> = new Set(Object.values(bracketPairs));- export function validateString(input: string, index: number): boolean {
const stack: string[] = [];for (let i = index, len = input.length; i < len; i++) {- const validator = new BracketsValidator();
- for (let i = index; i < input.length; i++) {
- const char = input[i];
if (openBrackets.has(char)) {stack.push(bracketPairs[char])} else if (closingBrackets.has(char)) {const match = stack.pop();if (match !== char) {return false;}}- if (!validator.isValidChar(char)) {
- return false;
- }
- }
- return true;
}- }
- class BracketsValidator {
- private readonly bracketPairs: Record<string, string> = {
- '{': '}',
- '[': ']',
- '(': ')',
- };
- private readonly openBrackets: Set<string> = new Set(Object.keys(this.bracketPairs));
- private readonly closingBrackets: Set<string> = new Set(Object.values(this.bracketPairs));
- private stack: string[] = [];
- public isValidChar(char: string): boolean {
- if (this.isNotBracket(char)) {
- return true;
- }
- if (this.isOpeningBracket(char)) {
- this.push(char);
- return true;
- }
- if (this.hasMatchFor(char)) {
- this.pop();
- return true;
- }
- return false;
- }
- private push(bracket: string): void {
- this.stack.push(bracket);
- }
- private pop(): string|undefined {
- return this.stack.pop();
- }
- private lastFromStack(): string|undefined {
- return this.stack.slice(-1)[0];
- }
- private hasMatchFor(bracket: string): boolean {
- const previousBracket: string|undefined = this.lastFromStack();
- if (undefined === previousBracket) {
- return false;
- }
- const match = this.matchFor(bracket);
- if (previousBracket !== match) {
- return false;
- }
- return true;
- }
- private isOpeningBracket(char: string): boolean {
- if (this.openBrackets.has(char)) {
- return true;
- }
- return false;
- }
- private isClosingBracket(char: string): boolean {
- if (this.closingBrackets.has(char)) {
- return true;
- }
- return false;
- }
- private isNotBracket(char: string): boolean {
- if (this.isOpeningBracket(char)) {
- return false;
- }
- if (this.isClosingBracket(char)) {
- return false;
- }
- return true;
- }
- private matchFor(bracket: string): string {
- const index: number = Object.values(this.bracketPairs).indexOf(bracket);
- return Object.keys(this.bracketPairs)[index];
- }
- }
// See https://www.chaijs.com for how to use Chai. import { assert } from "chai"; import { validateString } from "./solution"; describe('validateString', function() { it('test', function() { assert.strictEqual(validateString('{([])}', 0), true, 'A'); assert.strictEqual(validateString('(A[B{C}D]E)', 0), true, 'B'); assert.strictEqual(validateString('a(b[d{a+b]/2]/4)/1', 0), false, 'C'); assert.strictEqual(validateString('[}{})()', 5), true, 'D'); }); });
- // See https://www.chaijs.com for how to use Chai.
- import { assert } from "chai";
- import { validateString } from "./solution";
- describe('validateString', function() {
- it('test', function() {
assert.strictEqual(validateString('{([])}', 0), true);assert.strictEqual(validateString('(A[B{C}D]E)', 0), true);assert.strictEqual(validateString('a(b[d{a+b]/2]/4)/1', 0), false);assert.strictEqual(validateString('[}{})()', 5), true);- assert.strictEqual(validateString('{([])}', 0), true, 'A');
- assert.strictEqual(validateString('(A[B{C}D]E)', 0), true, 'B');
- assert.strictEqual(validateString('a(b[d{a+b]/2]/4)/1', 0), false, 'C');
- assert.strictEqual(validateString('[}{})()', 5), true, 'D');
- });
- });
A few less spaces...
Assumes entry lists are sorted !!
#include <list> auto merge_list(const std::list<int>& a, const std::list<int>& b) { std::list<int> o{a}; for(auto i : b) o.insert(std::lower_bound(o.begin(), o.end(), i), i); return o; }
#include <algorithm>- #include <list>
#include <execution>#include <iterator>- auto merge_list(const std::list<int>& a, const std::list<int>& b) {
std::list<int> o;std::merge(std::execution::seq,a.begin(),a.end(),b.begin(),b.end(),std::back_inserter(o)// std::less is default sort);- std::list<int> o{a};
- for(auto i : b) o.insert(std::lower_bound(o.begin(), o.end(), i), i);
- return o;
- }
- Added 3 more test cases
- Follwing problem description:
Counting from 1 to n, then back to 1 - Wait, why am I doing this?
module NumberPrint where numberprint :: Int -> Integer numberprint n = read . concat $ show <$> [1 .. pred n] <> [n, pred n .. 1]
- module NumberPrint where
- numberprint :: Int -> Integer
numberprint = read . (>>= id) . ((++) <*> (reverse . init)) . (\x -> show <$> [1..x])- numberprint n = read . concat $ show <$> [1 .. pred n] <> [n, pred n .. 1]
module NumberPrintSpec where import Test.Hspec import NumberPrint spec :: Spec spec = do describe "Tests" $ do it "Fixed Tests" $ do numberprint 1 `shouldBe` 1 numberprint 2 `shouldBe` 121 numberprint 10 `shouldBe` 12345678910987654321 numberprint 12 `shouldBe` 1234567891011121110987654321 numberprint 15 `shouldBe` 1234567891011121314151413121110987654321 main = hspec spec
- module NumberPrintSpec where
- import Test.Hspec
- import NumberPrint
- spec :: Spec
- spec = do
- describe "Tests" $ do
- it "Fixed Tests" $ do
- numberprint 1 `shouldBe` 1
- numberprint 2 `shouldBe` 121
- numberprint 10 `shouldBe` 12345678910987654321
- numberprint 12 `shouldBe` 1234567891011121110987654321
- numberprint 15 `shouldBe` 1234567891011121314151413121110987654321
- main = hspec spec
Combinators are useful.
I'd like a safe tail
function though.
EDIT: drop
could be used instead.
<*>
is S
combinator.
- For
A <*> B
, parameter is piped to both A and B - and then, they are applied
- i.e.
A <*> B = \x -> (A x) (B x)