Begin a new Kumite
Search
About
  • Filter by Language:
  • 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.

Utilities

The idea here is to provide the ability to process a batch of callbacks. It provides the following capabilities:

  • dynamic batch list, can be exanded at any time
  • each callback is isolated, if an error is thrown it will not prevent the next callback from being called
  • each callback has a timeout, so that if it does not call the next function itself, it will eventually be called automatically.
  • batches can be ran at intervals, either forever, or up to configured amount of times
  • events are provided to hook into batchStart, batchEnd, error and stopped
  • nextTick can automatically be called for each item within the batch
// interval processor's job is to run a batch of callback items, one at a time. It runs these batches
// at a given interval, and will continue to run batches either forever or until a maxBatches value is reached.
var Processor = function(interval)
{
    this.nextTick = true;
    this.interval = interval;
    this.timeout = 50;
    this.items = [];
    this.maxBatch = null;
    this.events = {error: [], batchStart: [], batchEnd: [], stopped: [], timeout: []};
    console.log('Interval Processor created with ' + interval + 'ms interval');
}

Processor.prototype.on = function on(event, callback)
{
    this.events[event].push(callback);
}

// returns a new function that ensures that the passed in fn only gets called once no matter
// how many times the returned function is called.
function once(fn)
{
    var called = false;
    return function()
    {
        if (!called)
        {
            if (fn) fn();
            called = true;
        }
    }
}

function fire(processor, event, arg)
{
    processor.events[event].forEach(function(fn)
    {
        fn(processor, arg);
    });
}

function nextTick(run)
{
    return function(i)
    {
        process.nextTick(function()
        {
            run(i);
        });
    }
};

// add a new callback to the processor chain. 
Processor.prototype.add = function add(item)
{
    var self = this;
    this.items.push(function(next)
    {
        var _next = once(function(){
          clearTimeout(timeout);
          next();
        });

        // set a timeout so that if for some reason the item fails and doesn't call its callback,
        // we make sure that the chain doesn't break.
        var timeout = setTimeout(function()
        {
            fire(self, 'timeout')
            _next();
        }, self.timeout);
        try
        {
            item(_next);
        }
        catch(ex)
        {
            fire(self, 'error', ex);
            _next();
        }
    });
}

// stop any additional iterations from happening
Processor.prototype.stop = function stop()
{
    this.started = false;
    clearTimeout(this._timeout);
    fire(this, 'stopped');
}

// start the loop
Processor.prototype.start = function start()
{
    // if not started yet and there are items to process
    if (!this.started && this.items.length > 0)
    {
        var self = this;
        self.started = true;
        self.batch = 0;

        function run(i)
        {
            i = i || 0;
            // call the runStart event
            if (i == 0)
            {
                self.batch++;
                fire(self, 'batchStart');
            }

            // if not the end of the loop
            if (i < self.items.length)
            {
                // run the current item, pass in the next run as the next function
                self.items[i](function(){ run(++i);})
            }
            // if no more items to process then check if still running and if so then schedule the next batch
            else if (self.started)
            {
                fire(self, 'batchEnd');

                if (self.maxBatches && self.maxBatches == self.batch)
                {
                    self.stop();
                }
                else
                {
                    self._timeout = setTimeout(run, self.interval);
                }
            }
        }

        // if nextTick is true then wrap each run within a nextTick call
        if (this.nextTick)
        {
            run = nextTick(run);
        }

        // run the first batch now
        run();
        return true;
    }

    return false;
}



module.exports = Processor;
Numbers
Interview Questions

Converts a number to English. This is a horrendous mess...

(ns number-to-words
  (:require [clojure.string :refer [join]]))

(def digit-to-word
  {1 "One"
   2 "Two"
   3 "Three"
   4 "Four"
   5 "Five"
   6 "Six"
   7 "Seven"
   8 "Eight"
   9 "Nine"})

(def tens-to-word
  {
   20 "Twenty"
   30 "Thirty"
   40 "Fourty"
   50 "Fifty"
   60 "Sixty"
   70 "Seventy"
   80 "Eighty"
   90 "Ninety"})

(def teen-to-word
  {10 "Ten"
   11 "Eleven"
   12 "Twelve"
   13 "Thirteen"
   14 "Fourteen"
   15 "Fifteen"
   16 "Sixteen"
   17 "Seventeen"
   18 "Eighteen"
   19 "Nineteen"})

(defn- small-number-to-words
  [x]
  (cond
   (<= x 9) (digit-to-word x)
   (< x 20) (teen-to-word x)
   (< x 100)
   (let [ones-part (mod x 10)
         tens-part (- x ones-part)]
     (str (tens-to-word tens-part) "-"
          (digit-to-word ones-part)))
   (<= x 999)
   (let [small-part (mod x 100)
         hundreds-digit (-> x (- small-part) (/ 100))]
     (str (digit-to-word hundreds-digit) " Hundred " (small-number-to-words small-part)))))

(defn- digit-shift
  [x shift]
  (-> x (- (mod x shift)) (/ shift) int))

(defn convert
  [x]
  (loop [words [] x x]
    (cond
     
     (-> x (>= 1e6))
     (recur (conj words "One Million")
            (- x 1e6))
     
     (-> x (>= 1e3))
     (recur (conj words
                  (str
                   (-> x (digit-shift 1000) small-number-to-words)
                   " Thousand"))
            (mod x 1000))
     
     (-> x (> 0))
     (recur (conj words (small-number-to-words x)) 0)
     
     :else (join ", " words))))

Bash is pretty silly...

Code
Diff
  • #!/bin/bash
    printf "Hello %s!\n" "Bash"
  • 1
    #!/bin/bash          
    
    2
    echo Hello Bash!
    
    1+
    #!/bin/bash
    
    2+
    printf "Hello %s!\n" "Bash"
    

Recent Moves:

Even more golfing

Code
Diff
  • (ns bubble
      (:refer-clojure :exclude [sort]))
    
    (defn bubble [[truck & [jeep & bigdogs :as convoy] :as tanks]]
      (cond
       (some nil? [truck convoy]) [tanks true]
       (<= truck jeep) (update-in (bubble convoy) [0] conj truck)
       :else [(cons jeep (first (bubble (cons truck bigdogs)))) false]))
    
    (defn sort [l]
      (let [[value done?] (bubble l)]
        (if done?
          value
          (recur value))))
  • 11
    (ns bubble
    
    22
      (:refer-clojure :exclude [sort]))
    
    33
    4
    (defn bubble [tanks]
    
    5
      (if (or (nil? tanks) (nil? (next tanks)))
    
    6
        [tanks false]
    
    7
        (let [[truck & [jeep & _ :as convoy]] tanks]
    
    8
          (if (<= truck jeep)
    
    9
            (let [debrief (bubble convoy)] (cons (cons truck (first debrief)) (next debrief)))
    
    10
            (cons (cons jeep (first (bubble (cons truck (next convoy))))) '(true))))))
    
    4+
    (defn bubble [[truck & [jeep & bigdogs :as convoy] :as tanks]]
    
    5+
      (cond
    
    6+
       (some nil? [truck convoy]) [tanks true]
    
    7+
       (<= truck jeep) (update-in (bubble convoy) [0] conj truck)
    
    8+
       :else [(cons jeep (first (bubble (cons truck bigdogs)))) false]))
    
    1111
    1212
    (defn sort [l]
    
    13
      (let [bubbly (bubble l)]
    
    14
        (if (second bubbly)
    
    15
          (recur (first bubbly))
    
    16
          (first bubbly))))
    
    11+
      (let [[value done?] (bubble l)]
    
    12+
        (if done?
    
    13+
          value
    
    14+
          (recur value))))
    

Recent Moves:

I use this whenever I have to add another directory to my PATH environment variable in my .bashrc. This way I don't have duplicates.

I wrote this years ago and it's hacky and kind of dumb... I'm sure it can be improved.

add_PATH() {
        oIFS=$IFS
        IFS=':'
        t=(${PATH})
        unset IFS
        t=("$1" ${t[@]%%"$1"})
        # output the new array
        IFS=':'
        echo -n "${t[*]}"
        unset t
        IFS=$oIFS
}

echo "Original Path: $PATH"
export PATH=$(add_PATH /usr/local/bin)
echo "New Path: $PATH"

"Hello Python!" script.

print "Hello Python!"