text:
Sum in each dimension
You are given a multi-dimensional array of integers. Each dimension has a fixed size (so that it would be always rectangular if it is 2D). Your program should calculate the sums in each dimension and append the sums as the new last items in that dimension.
Assume the input and output arrays are A and B, and the size of dimension i of A is ni. B would have the same number of dimensions as A and the size of dimension i would be ni+1. Bj1,j2,...,jm is the sum of Ak1,k2,...,km where:

ki = ji if ji <= ni
0 < ki <= ni if ji = ni+1

For the input:
[[1 2 3]
 [4 5 6]]

Your program (or function) should output:
[[1 2 3 6]
 [4 5 6 15]
 [5 7 9 21]]

The input contains only the array. The total number of dimensions and the size of each dimension are not given in the input. (But you can get them from the array by your own code.) You can use any convenient list formats in your language, as long as it doesn't specify the number of dimensions or dimension sizes directly.
The input has at least 1 dimension, and has at least 1 item in the array.
This is code-golf. Shortest code wins.
Test cases
Input:
[5 2 3]
Output:
[5 2 3 10]

Input:
[[1 2 3] [4 5 6]]
Outputs:
[[1 2 3 6] [4 5 6 15] [5 7 9 21]]

Input:
[[[1] [1] [1] [0]]]
Output:
[[[1 1] [1 1] [1 1] [0 0] [3 3]] [[1 1] [1 1] [1 1] [0 0] [3 3]]]

Input:
[[[[-1]]]]
Output:
[[[[-1 -1] [-1 -1]] [[-1 -1] [-1 -1]]] [[[-1 -1] [-1 -1]] [[-1 -1] [-1 -1]]]]

Will you post that 16 byte APL solution? If you won't, can I?

@Dennis You should post it.

J, 14 bytes
#@$(0|:],+/^:)

Usage:
   ]a=.i.2 3
0 1 2
3 4 5

   (#@$(0|:],+/^:)) a    NB. parens are optional
0 1 2  3
3 4 5 12
3 5 7 15

The function is equivalent to the following (0|:],+/)^:(#@$) but uses a user-defined adverb to save parens.
Explanation for the latter code from right to left:

^:(#@$)repeat ^: for the number # of dimensions $:

],+/ concatenate , to the argument ] with the sum of it on the last dimension +/
0|: rotate dimensions |: by putting the first one 0 to the end of the dimension-list

After doing the above procedure we get back the original input with sums on all dimensions.

For my older solution check revision history.
Try it online here.

Mathematica, 32 20 bytes
#/.List->({##,+##}&)&

Example:
In[1]:= #/.List->({##,+##}&)&[{{1, 2, 3}, {4, 5, 6}}]

Out[1]= {{1, 2, 3, 6}, {4, 5, 6, 15}, {5, 7, 9, 21}}

Explanation:
The full form of {{1, 2, 3}, {4, 5, 6}} is List[List[1, 2, 3], List[4, 5, 6]]. Then replace all the Lists in the expression with the function ({##,+##}&).

Python 2, 95 bytes
from numpy import*
a=copy(input())
for d in r_[:a.ndim]:a=r_[`d`,a,sum(a,d,keepdims=1)]
print a

This iterates over each dimension, concatenating its sums using NumPy.
I stumbled across NumPy's r_, which is pretty awesome for golfing. r_[:n] is shorter than range(n) and much more powerful (e.g. r_[:4, 7, 8, 10:100:10]). It can also do other things like concatenation along an arbitrary axis.
Example usage:
$ python sum.py
[[1, 2, 3], [4, 5, 6]]
[[ 1  2  3  6]
 [ 4  5  6 15]
 [ 5  7  9 21]]

APL, 16 15 bytes
{×≡⍵:∇¨⍵,+/⍵⋄⍵}

Thanks to @user23013 for golfing off 3 bytes and figuring out the proper input format.
Verify the test cases online with TryAPL.
Idea
The general idea is the same as in my CJam submission, for which APL allows a much shorter implementation. It consists of only two steps:

Sum the array across its outmost dimension.
Repeat step 1 for each subarray.

Code
{             } ⍝ Define a monadic function with argument ⍵ and reference ∇.
 ×≡⍵:           ⍝ If the depth of ⍵ is positive:
     ∇          ⍝   Apply this function...
      ¨         ⍝   to each element of...
       ⍵,       ⍝   the concatenation of ⍵...
         +/⍵    ⍝   and the sum across ⍵.
            ⋄⍵  ⍝  Else, return ⍵.

Just figured out the input format for your original code: ,⊂(,1)(,1)(,1)(,0) and ,⊂,⊂,⊂,¯1 respectively. So you can remove another character.

@user23013: So my code did work! You have to love a programming language where the input format is more difficult to get right than the actual code...

Pip, 18 15 bytes
{a-a?fMaAE$+aa}

This is an anonymous function, which takes the array as an argument and returns the result. Sample invocation, using the -p flag to obtain readable output:
C:\> pip.py -pe "( {a-a?fMaAE$+aa} [[1 2 3] [4 5 6]] )"
[[1;2;3;6];[4;5;6;15];[5;7;9;21]]

The idea is basically the same as Dennis's APL, though independently derived. More specifically:
{             }  Define a lambda function with parameter a
 a-a?            Shortest way I could find to test whether the argument is a list
                 or scalar: subtracting a number from itself gives 0 (falsy);
                 subtracting a list from itself gives a list of zeros (truthy!)
     fM          If truthy, it's a list, so map the same function (f) recursively to:
       aAE         Argument, with appended element...
          $+a      ...sum of argument (fold on +)
             a   If falsy, it's a scalar, so just return it

This method works because + (along with many other operators) functions item-wise on lists in Pip--a feature inspired by array-programming languages like APL. So when you $+ a list like [[1 2 3] [4 5 6]], the result is [5 7 9] as desired. Also used in the list-or-scalar test: [1 2 3] - [1 2 3] gives [0 0 0], which is truthy (as are all lists except the empty list).
Previous 18-byte version:
{Ja=a?a(fMaAE$+a)}

Changes:

Saved a byte on the scalar-or-list test--previous method was to join the argument (on empty string) and test whether equal to its un-joined self (works because [1 2 3] != 123);
Eliminated the parentheses. They're necessary in the original because M is lower precedence than ? (though I'm probably going to change that, especially now): without them, the code would parse as (Ja=a?af)M(aAE$+a), leading to bizarre error messages. However, the middle argument of a ternary operator can be any expression of whatever precedence, no parentheses needed. So by making the list the truthy case, I can save those two bytes.

That's an interesting language you got there. Itemwise operators are what's missing in CJam and Pyth.

@Dennis Thanks!  It's still very much a work in progress, but there are some tasks it does quite well with.

APL (25)
{N⊣{N,[⍵]←+/[⍵]N}¨⍳⍴⍴N←⍵}

APL's arrays have dimensions built-in, so this is a function that takes an n-dimensional array and then sums along each dimension.
      {N⊣{N,[⍵]←+/[⍵]N}¨⍳⍴⍴N←⍵} ↑(1 2 3)(4 5 6)
1 2 3  6
4 5 6 15
5 7 9 21

Explanation:

N←⍵: store the array in N.
⍴⍴N: get the amount of dimensions N has. (⍴ gives the dimensions, i.e. ⍴↑(1 2 3)(4 5 6) gives 2 3, so ⍴⍴ gives the dimensions of the dimensions.)
{...}¨⍳: for each number from 1 to ⍴⍴N:

+/[⍵]N: sum N along dimension ⍵
N,[⍵]←: join the result to N in that dimension

N: finally, return N.

I can't seem to make this work if the array contains singletons. How would you call this function for the third or fourth test case?

@Dennis: you need to pass the function a multidimensional array. What the ↑(1 2 3)(4 5 6) is doing is simply constructing a 2-dimensional array from 2 1-dimensional ones using ↑. It is not a built-in notation and it does not generalize the way you might think. The canonical way to construct the 3rd and 4th arrays would be 1 4 1⍴1 1 1 0 and 1 1 1 1⍴¯1, but it is also possible to construct them without referring to the sizes, e.g., the third array can also be constructed with ↑⍉⍪(,1)(,1)(,1)(,0), the fourth one can be constructed with ↑⍪⊂⍪¯1.

OK, that explains everything. My naïve implementation of a recursive approach works well for what I thought were arrays (e.g. f←{0=≡⍵:⍵⋄f¨⍵,+/⍵}⋄f((1 2)(3 4))((5 6)(7 8))), but it seems that nested vectors and arrays are different and the former doesn't differentiate scalars from singletons...

@Dennis Golfed: {×≡⍵:∇¨⍵,+/⍵⋄⍵}((1 2)(3 4))((5 6)(7 8)). Fixed: {×⍴⍴⍵:∇↓⍵,+/⍵⋄⍵}1 4 1⍴1 1 1 0. It's shorter than Mathematica now...

CJam, 36 bytes
{_`{'[<}#:D{_":"D'.e]'++~a+{S}%}&}:S

This is a recursive named function that pops an array from the stack and leaves one in return.
Try the test cases in the CJam interpreter.
Idea
Sadly, CJam does not have some automagical operator that allows to add arbitrarily nested arrays, so we have to implement it ourselves. Luckily, it does that two infix operators, : (reduce) and . (vectorize), that will prove helpful for this task.
Step one is calculating the number of dimensions. This is easy: Convert the array into its string representation and count the number of leading ['s.
Now, to reduce an array of one dimension, you usually just execute :+:
[1 2] :+ e# Pushes 3.

For an array of two dimensions, + would perform concatenation instead of addition, so we have to vectorize it:
[[1 2][3 4]] :.+ Pushes [4 6].

Now, for an array of three dimensions, .+ would operate on arrays of two dimensions and perform, once again, concatenation. This time, we have to vectorize .+:
[[[1 2][3 4]][[5 6][7 8]]] :..+ e# Pushes [[[6 8] [10 12]]].

For the general case, an array of dimension D, we have to chain one :, D - 1 .'s and one +.
Of course, this only sums the array only across its outmost dimension. We can solve this by defining a function S that computes the dimension (and does nothing if it's zero), performs the sum as indicated above and, finally, applies itself to the array's elements.
Code
{                                }:S e# Define S:
 _`                                  e#   Push a string representation of a the array.
   {'[<}#                            e#   Find the index of the first non-bracket.
         :D                          e#   Save it in D.
           {                   }&    e#   If D is positive:
            _                        e#     Push a copy of the array.
             ":"D'.e]                e#     Pad ":" with "."s to a string of length D.
                     '++~            e#     Add a "+" to the string and evaluate.
                         a+          e#     Wrap the result in a array and concatenate.
                           {S}%      e#     Apply S to the elements of the array.

Ruby (181 139 119 108 bytes)
def d a;a.push a[0].to_s['[']?a.map{|x|d x}.transpose.map{|x|x.reduce:+}:a.reduce(:+)end
p d eval ARGF.read

Assumes input is passed as JSON.

And in fact you can just write a function accepting a parsed array and returns an array, and only count the 95 bytes for d in this answer.

Java, 669 bytes
not gonna lie, I'm quite proud of myself for this one :p
import java.lang.reflect.Array;enum S{D;A s(A a){int l=Array.getLength(a),x=0;Class t=a.getClass();Class c=t.getComponentType();A r=(A)Array.newInstance(c,l+1);System.arraycopy(a,0,r,0,l);if(t==int[].class)for(;x<l;)((int[])r)[l]=((int[])r)[l]+((int[])r)[x++];else{for(;x<l;)Array.set(r,x,S.this.s(Array.get(r,x++)));Object o=Array.get(r,0);for(;--x>0;)o=s(o,Array.get(r,x));Array.set(r,l,o);}return r;}A s(A a,A b){int l=Array.getLength(a),x=0;Class t=a.getClass();A r=(A)Array.newInstance(t.getComponentType(),l);if(int[].class==t)for(;x<l;)((int[])r)[x]=((int[])a)[x]+((int[])b)[x++];else for(;x<l;)Array.set(r,x,s(Array.get(a,x),Array.get(b,x++)));return r;}}

expanded with testing:
import java.lang.reflect.Array;
import java.util.Arrays;

public enum SumOf{
    Dimensions;

    A sum(A array){ //call this method to solve the challenge
        int length=Array.getLength(array),x=0;
        Class arrayType=array.getClass();
        Class componentType=arrayType.getComponentType();
        //grow the array to include the sum element
        A result=(A)Array.newInstance(componentType,length+1);
        System.arraycopy(array,0,result,0,length);
        if(arrayType==int[].class) //one-dimensional array needs to be handled separately
            for(;x<length;) //find the sum
                ((int[])result)[length]=((int[])result)[length]+((int[])result)[x++];
        else{ //multi-dimensional array
            for(;x<length;) //find the sum for each element in this dimension's array
                Array.set(result,x,sum(Array.get(result,x++)));
            //find the total sum for this dimension's array
            Object s=Array.get(result,0);
            for(;--x>0;)
                s=_sum(s,Array.get(result,x)); //add the 2 elements together
            Array.set(result,length,s);
        }
        return result;
    }

    A _sum(A arrayA,A arrayB){ //this method is used by the previous method
        int length=Array.getLength(arrayA),x=0;
        Class arrayType=arrayA.getClass();
        A result=(A)Array.newInstance(arrayType.getComponentType(),length);
        if(int[].class==arrayType) //one-dimensional array needs to be handled separately
            for(;x<length;) //find the sum of both arrays
                ((int[])result)[x]=((int[])arrayA)[x]+((int[])arrayB)[x++];
        else
            for(;x<length;) //find the sum of both arrays
                Array.set(result,x,sum(Array.get(arrayA,x),Array.get(arrayB,x++)));
            return result;
        }

    static int[] intArray( int firstElement, int...array ) {
        if( array == null ) array = new int[0];
        array = Arrays.copyOf( array, array.length + 1 );
        System.arraycopy( array, 0, array, 1, array.length - 1 );
        array[0] = firstElement;
        return array;
    }

    static <E> E[] arrayArray( E firstElement, E...array ) {
        if( array == null ) array = (E[]) Array.newInstance( firstElement.getClass(), 0 );
        array = Arrays.copyOf( array, array.length + 1 );
        System.arraycopy( array, 0, array, 1, array.length - 1 );
        array[0] = firstElement;
        return array;
    }

    static void printIntArray( int[]array ){
        System.out.print("[ ");
        for( int x = 0; x < array.length; x++ )
            System.out.print( array[x] + " " );
        System.out.print("] ");
    }

    static  void printArray( A array ) {
        if( array.getClass() == int[].class ){
            printIntArray( (int[]) array );
        }
        else {
            System.out.print("[ ");
            int length = Array.getLength( array );
            for( int x = 0; x < length; x++ )
                printArray( Array.get( array, x ) );
            System.out.print("] ");
        }
    }

    public static void main(String[]s){
        int[] test01 = intArray( 5, 2, 3 );
        System.out.print("Input: ");
        printArray( test01 );
        System.out.print("\nOutput: ");
        printArray( SumOf.Dimensions.sum( test01 ) );
        System.out.println();

        int[][] test02 = arrayArray( intArray( 1, 2, 3 ), intArray( 4, 5, 6 ) );
        System.out.print("\nInput: ");
        printArray( test02 );
        System.out.print("\nOutput: ");
        printArray( SumOf.Dimensions.sum( test02 ) );
        System.out.println();

        int[][][] test03 = arrayArray( arrayArray( intArray( 1 ), intArray( 1 ), intArray( 1 ), intArray( 0 ) ) );
        System.out.print("\nInput: ");
        printArray( test03 );
        System.out.print("\nOutput: ");
        printArray( SumOf.Dimensions.sum( test03 ) );
        System.out.println();

        int[][][][] test04 = arrayArray( arrayArray( arrayArray( intArray( -1 ) ) ) );
        System.out.print("\nInput: ");
        printArray( test04 );
        System.out.print("\nOutput: ");
        printArray( SumOf.Dimensions.sum( test04 ) );
        System.out.println();

        int[][][] test05 = arrayArray( arrayArray( intArray( 1, 2, 3 ), intArray( 4, 5, 6 ), intArray( 7, 8, 9 ) ), arrayArray( intArray( 11, 12, 13 ), intArray( 14, 15, 16 ), intArray( 17, 18, 19 ) ), arrayArray( intArray( 21, 22, 23 ), intArray( 24, 25, 26 ), intArray( 27, 28, 29 ) ) );
        System.out.print("\nInput: ");
        printArray( test05 );
        System.out.print("\nOutput: ");
        printArray( SumOf.Dimensions.sum( test05 ) );
        System.out.println();
    }

}

running the expanded testing version prints this:
Input: [ 5 2 3 ]
Output: [ 5 2 3 10 ]

Input: [ [ 1 2 3 ] [ 4 5 6 ] ]
Output: [ [ 1 2 3 6 ] [ 4 5 6 15 ] [ 5 7 9 21 ] ]

Input: [ [ [ 1 ] [ 1 ] [ 1 ] [ 0 ] ] ]
Output: [ [ [ 1 1 ] [ 1 1 ] [ 1 1 ] [ 0 0 ] [ 3 3 ] ] [ [ 1 1 ] [ 1 1 ] [ 1 1 ] [ 0 0 ] [ 3 3 ] ] ]

Input: [ [ [ [ -1 ] ] ] ]
Output: [ [ [ [ -1 -1 ] [ -1 -1 ] ] [ [ -1 -1 ] [ -1 -1 ] ] ] [ [ [ -1 -1 ] [ -1 -1 ] ] [ [ -1 -1 ] [ -1 -1 ] ] ] ]

Input: [ [ [ 1 2 3 ] [ 4 5 6 ] [ 7 8 9 ] ] [ [ 11 12 13 ] [ 14 15 16 ] [ 17 18 19 ] ] [ [ 21 22 23 ] [ 24 25 26 ] [ 27 28 29 ] ] ]
Output: [ [ [ 1 2 3 6 ] [ 4 5 6 15 ] [ 7 8 9 24 ] [ 12 15 18 45 ] ] [ [ 11 12 13 36 ] [ 14 15 16 45 ] [ 17 18 19 54 ] [ 42 45 48 135 ] ] [ [ 21 22 23 66 ] [ 24 25 26 75 ] [ 27 28 29 84 ] [ 72 75 78 225 ] ] [ [ 33 36 39 108 ] [ 42 45 48 135 ] [ 51 54 57 162 ] [ 126 135 144 405 ] ] ]

erm for the expanded version, the line: Array.set(result,x,sum(Array.get(arrayA,x),Array.get(arrayB,x++))); in the _sum(...) method should have called _sum(...), not sum(...). my bad


text:
ASCII Art of the Day #3 - Chinese Shrines
In today's episode of AAOD, we are going to construct a Chinese Shrine of varying heights.
Consider the following examples for height (N) 1 to 6
N = 1:
       .
       |
  .   ]#[   .
   \_______/
.    ]###[    .
 \__]#.-.#[__/
  |___| |___|
  |___|_|___|
  ####/_\####
     |___|
    /_____\

N = 2:
         .
         |
    .   ]#[   .
     \_______/
  .    ]###[    .
   \___________/
.     ]#####[     .
 \___]#.---.#[___/
  |__|_|   |_|__|
  |__|_|___|_|__|
  #####/___\#####
      |_____|
     /_______\

N = 3:
           .
           |
      .   ]#[   .
       \_______/
    .    ]###[    .
     \___________/
  .     ]#####[     .
   \_______________/
.      ]#######[      .
 \____]#.-----.#[____/
  |__|__|     |__|__|
  |__|__|_____|__|__|
  ######/_____\######
       |_______|
      /_________\

N = 4:
             .
             |
        .   ]#[   .
         \_______/
      .    ]###[    .
       \___________/
    .     ]#####[     .
     \_______________/
  .      ]#######[      .
   \___________________/
.       ]#########[       .
 \_____]##.-----.##[_____/
  |__|__|_|     |_|__|__|
  |__|__|_|_____|_|__|__|
  ########/_____\########
         |_______|
        /_________\

N = 5:
               .
               |
          .   ]#[   .
           \_______/
        .    ]###[    .
         \___________/
      .     ]#####[     .
       \_______________/
    .      ]#######[      .
     \___________________/
  .       ]#########[       .
   \_______________________/
.        ]###########[        .
 \______]###.-----.###[______/
  |__|__|___|     |___|__|__|
  |__|__|___|_____|___|__|__|
  ##########/_____\##########
           |_______|
          /_________\

N = 6:
                 .
                 |
            .   ]#[   .
             \_______/
          .    ]###[    .
           \___________/
        .     ]#####[     .
         \_______________/
      .      ]#######[      .
       \___________________/
    .       ]#########[       .
     \_______________________/
  .        ]###########[        .
   \___________________________/
.         ]#############[         .
 \_______]####.-----.####[_______/
  |__|__|__|__|     |__|__|__|__|
  |__|__|__|__|_____|__|__|__|__|
  ############/_____\############
             |_______|
            /_________\

and so on.
Construction Details
I am sure most of the details about the pattern are clear. Here are some finer details:

The door at the bottom of the shrine can at minimum be of 1 _ width and at maximum be of 5 _ width.
There will always be two . directly above the pillars around the door (two vertical |).
The stairs start with the same width as the door and increase like show in the pattern
The ]##..##[ blocks above each roof level increase in size of 2 from top to bottom.
The \__...__/ roofs levels increase in size of 4 from top to bottom.
The walls blocks around the door should at minimum contain 1 _ and at maximum, 3 _ between the two |. Priority goes to the outer wall blocks so that the one closest to the door gets a varying size for each level.
The space between the . and the ] (or [) is filled by # in the roof just above the doors.

Challenge Details

Write a function or full program that reads a positive integer greater than 0 via STDIN/ARGV/function argument or closest equivalent and outputs (to STDOUT or closest equivalent) the Nth Chinese Shrine
Trailing newline is optional.
There should either be no trailing spaces or enough trailing spaces to pad the output in the minimum bounding rectangle.
There should not be any leading spaces that are not part of the pattern.

Leaderboard
The first post of the series generates a leaderboard.
To make sure that your answers show up, please start every answer with a headline, using the following Markdown template:
# Language Name, N bytes

where N is the size of your submission. If you improve your score, you can keep old scores in the headline, by striking them through. For instance:
# Ruby, <s>104</s> <s>101</s> 96 bytes

The door width seems rather arbitrary to me - why is it 1 in the N=1 case? Why not 3 and have smaller side windows like in the N=2 case?

Also, in the N=1 case, isn't the first rooftop too long (wide)?

@Matty regarding door - if door was of width 3, then there would be no # beside the . to support the ] and [ above it. About the starting roof size - That is the roof size in each height's top roof.

I was asking about the bottom most roof just above the windows. In all other cases it is the size of the roof above it +4 (+2 on either sides). But here it is +8.

@Matty oh, you are right. Fixed.

Why do the N=2 and N=4 cases have leading spaces?

@RetoKoradi because ASCII art and markdown don't go along ? Thanks for pointing out! Fixed!

Frankly, the choices for the walls seem a little confusing. For N=5, why isn't the inner wall (next to the entrance) a length of 1? Why was 3 chosen?

@user100690 - minimum 1 _ in between the |

CJam, 200 bytes
-4'.-4'|]2/ri:M),{2af.-~[W'.I3+~']'#I)*][-2'\'_I2*4+*]]}fI~[~M)<']
M2m1e>'#*'.'-M3e<:D*][-3"|__"M*M2+M2*(e>:L<"_|"D~][_~~'_*][-3'#L)*
'/'_D*][L2+~'|'_D)*][L)~'/'_D2+*]]{{_0<{~S*}&}%s_W%1>"\/]""/\["erN}%

Newlines added to avoid scrolling. Try it online
Brief explanation:
The program builds the left half of the shrine (including the middle), then reverses it and replaces some characters to get the right half. A series of n spaces is represented as the number ~n (bitwise "not") during construction, and replaced with the actual spaces at the end.
The program starts with the top 2 lines, then for each roof level, it prepends all the previous lines with 2 spaces and adds the new roof (2 lines). The last roof is modified to add the "above door" part.
Next, the upper wall is built by repeating "|__" and truncating at the right length, followed by a fixed "_|" and spaces. The wall is then duplicated and the door spaces are replaced with underscores. Finally, the lower part is constructed line by line.

Perl, 332 316 294
$:=($w=<>)*2+6;$r=2x($m=$w>3?3:$w);$k=1x($w-3).b.4x$m;
y!a-f1-4!/.|\\[,#_ -!,/,/,s/(.*),(.*).{@{-}}/$2$1/,printf"%$:s%s
",y!/\\[!\\/]!r,(reverse=~s/.//r)for@x=(b,c,
(map{b33.3x$_.e.1x$_,"[#$k,"x/$w/.a__.22x$_}1..++$w),
_c.3x$m.f.($z=substr"|__"x$:,0,2*++$w),"_|$r,$z","d$r,".11x$w,c_.$r,d__.$r)

Try me.
C, 371
d,i,w;char s[1<<24];m(){v(w,13);}p(){puts(s+1);}
v(i,j){s[w-i]=".|]\\#/"[j%7];s[w+i]=".|[/#\\"[j%7];
while(i--)s[w-i]=s[w+i]="# _-"[j/7];}
main(l){scanf("%d",&l);d=l>3?3:l;m(w=l*2+6);p(v(0,0));
for(v(0,1);i++<=l;v(i*2+2,17))p(),v(i*2+3,7),m(p(v(i,2)));v(l+2,2);p(v(d,21));
for(m(i=w-3);i>d+1;i-=3)v(i,15);p(v(d,8));p(v(d,15));
v(w-3,4);m(p(v(d,19)));p(v(d+1,15));p(v(d+2,19));}

Try me.
JavaScript, 365
The above can be translated almost 1 to 1 into JavaScript:
s=[];r="";i=0;m=()=>v(w,13);p=()=>r+=s.join('')+"\n";
v=(i,j)=>{s[w-i]=".|]\\#/"[j%7];s[w+i]=".|[/#\\"[j%7];
while(i--)s[w-i]=s[w+i]="# _-"[j/7|0];};
f=l=>{d=l>3?3:l;m(w=l*2+6);p(v(0,0));
for(v(0,1);i++<=l;v(i*2+2,17))p(),v(i*2+3,7),m(p(v(i,2)));v(l+2,2);p(v(d,21));
for(m(i=w-3);i>d+1;i-=3)v(i,15);p(v(d,8));p(v(d,15));
v(w-3,4);m(p(v(d,19)));p(v(d+1,15));p(v(d+2,19));}

Use:
f(2);console.log(r)

The C version crashes for sizes above 12. Since it looks like you're using a fixed size string to hold temporary results, I think you'll always have an upper limit, no matter how you choose the size of s. Unless you allocate it dynamically, of course.

@RetoKoradi, Yes you are right, I posted version with a small buffer by mistake. But in the end, unless it is dynamically allocated there always will be a limit.

Python 2, 356 352 347 344 bytes
n=input()
A,B,C,D,E,F,G,H,I='_ |\/#.]['
def p(*S):
 for s in S:print(5+2*n-len(s)/2)*B+s
p(G,C,'.   ]#[   .')
for i in range(n):b=B*(4+i);p(D+A*(7+4*i)+E,G+b+H+F*(3+2*i)+I+b+G)
d=2*min(3,n)-1
a=A*(2+i)
f=F*(1+i-d/2)
j=4+2*i-d/2
w=('|__'*n)[:j-1]+A+C
v=w[::-1]
p(D+a+H+f+G+'-'*d+G+f+I+a+E,w+B*d+v,w+A*d+v,F*j+E+A*d+D+F*j,C+A*(d+2)+C,E+A*(d+4)+D)

This basically builds the shrine line by line. The function p prints a string with the spaces needed to center it.
I used python 2 to save lots of bytes, because the python 3 map object doesn't trigger. I guess I should always golf in python 2, just saves a few more bytes (even if it's just to not have to parse the input to int).
Hehehe, it's not like code's pretty for golfing in the first place.
Edit: and of course, I now don't need the map anymore...
Here's the code in ungolfed form:
n = int(input())

# A function to print strings centered
half_width = 5 + 2*n
def p(string):
    spaces = ' ' * (half_width - len(string) // 2)
    print(spaces + string)

# The rooftops
p('.')
p('|')
p('.   ]#[   .')
for i in range(n):
    p('\\' + '_'*(7 + 4*i) + '/')
    p('.{0}]{1}[{0}.'.format(' '*(i + 4), '#'*(3 + 2*i)))

# The bottom rooftop
door_width = 2 * min(3, n) - 1
# (11+4i - (3+2i) - 4) / 2 = (4 + 2i) / 2 = 2 + i
p('\{0}]{1}.{2}.{1}[{0}/'.format('_'*(2 + i), '#'*(1 + i - door_width // 2), '-'*door_width))

# The windows
w = '|__'*n
w = w[:4 + 2*i  - door_width // 2]
if w[-1] == '|':
    w = w[:-1] + '_'
w += '|'
p(w + ' '*door_width + w[::-1])
p(w + '_'*door_width + w[::-1])

# The foundation and the stairs
w = '#'*(4 + 2*i - door_width // 2)
p(w + '/' + '_'*(door_width) + '\\' + w)

# The remaining stairs
p('|' + '_'*(door_width + 2) + '|')
p('/' + '_'*(door_width + 4) + '\\')

Since you're using Python 2 you can change print(B*(5+2*n-len(s)//2)+s) into print B*(5+2*n-len(s)/2)+s (remove parentheses and change // into /).

Thanks @ace, didn't know python2 ignored float division.

@Matty It doesn't ignore float division. You're performing division on integers, so the result is an integer. It only does float division if one or more operands is a float.

If you rearrange the order of print B*(5+2*n-len(s)/2)+s to print(5+2*n-len(s)/2)*B+s, you can remove the space after print.

JavaScript (ES6), 440
Edit Fixed lintel bug
A function whith height as a parameter, output to console.
Using template string a lot, all newlines are significant and counted.
Run snippet to test in Firefox (with console output)

f=x=>{R=(n,s=0)=>' #_-'[s][Z='repeat'](n),M=c=>R(2)+'|__'[Z](z+1).slice(0,z-1)+'_|'+R(y,c)+'|_'+'__|'[Z](z+1).slice(1-z)
for(z=x+x+(x<2)+(x<3),y=x>2?5:x>1?3:1,l=-1,o=`${t=R(x+x+5)}.
${t}|
`;l++<x;)o+=`${t=R(x+x-l-l)}.${u=R(l+3)}]${R(l*2+1,1)}[${u}.
 ${t}\\${l-x?R(7+l*4,2):`${t=R(x+1,2)}]${u=R(x<3||x-2,1)}.${R(y,3)}.${u}[${t}`}/
`;console.log(`${o+M(0)}
${M(2)}
${R(2)}${t=R(z,1)}/${u=R(y,2)}\\${t}
${R(1+z)}|__${u}|
${R(z)}/____${u}\\`)}

// TEST
f(1),f(2),f(3),f(4),f(5),f(6)
Output 1 to 6 in console

Ungolfed version for interactive test:

// Not so golfed

f=x=>{
  R=(n,s=0)=>' #_-'[s].repeat(n); // base building blocks
  M=c=>R(2)+'|__'.repeat(z+1).slice(0,z-1)+'_|'+R(y,c)+'|_'+'__|'.repeat(z+1).slice(1-z); // manage door level

  z=x+x+(x<2)+(x<3); // door and stairs surroundings
  y=x>2?5:x>1?3:1; // door and stairs width

  o = `${R(x+x+5)}.\n${R(x+x+5)}|\n`; // top
  for(l=-1;l++<x;)
    o += `${ // even row
      t=R(x+x-l-l) // left padding
    }.${
      u=R(l+3)
    }]${
      R(l*2+1,1)
    }[${
      u
    }.\n ${ // end even row, start odd row
      t // left padding
    }\\${
      l-x?R(7+l*4,2)
      :`${t=R(x+1,2)}]${u=R(x<3||x-2,1)}.${R(y,3)}.${u}[${t}` // if last row before the door, insert lintel
    }/\n`;

  o += `${
    M(0) // door level row 1
  }\n${
    M(2) // door level row 2
  }\n${
    R(2)}${t=R(z,1)}/${u=R(y,2)}\\${t  // stairs row 1
  }\n${
    R(1+z)}|__${u  // stairs row 2
  }|\n${
    R(z)}/____${u // stairs row 3
  }\\`;

  out(o)
}

out=x=>O.innerHTML=x

f(3)
<input id=I value=3><button onclick='f(+I.value)'>-></button>

Vyxal, 280 bytes
d5+\.꘍,d5+\|꘍,(n-d:£\.꘍3n+\]꘍\#nd›*\[3n+\.꘍Ṡ,¥›\\꘍ndd7+\_*\/Ṡ,)\.?3+꘍\]\#?d›*\[?3+\.꘍Ṡ,ð\\?›\_*\]?2-1∴\#*\.?d‹5∵-\.?2-1∴\#*\[?›\_*\/Ṡ,3<[⟨0|⟨3⟩|⟨2|1⟩⟩$i|3/⌊d2w$ẋf`013`?3%iIJ';]\_*Ṅðpð+ð\|Vðdp:£3?∵꘍øm,¥3?∵\_*+øm,4<[3+|d]\#*:£ðdp\/\_?d‹5∵*\\¥Ṡ,¥L›\|꘍\_?d‹5∵⇧*\|Ṡ,¥L\/꘍\_?d‹5∵4+*\\Ṡ,

Try it Online!
No, I'm not explaining this.

Charcoal, 404 bytes
≔Ｎν≔⁺⁵×²νη≔× ⁻η⁻∕¹¦²¦¹τ⁺⁺⁺⁺⁺τ.¶τ|¶× ⁻η⁻∕¹²¦²¦¹“±∨N"G:Ｗ⮌+”Ｆν«≔⁺⁺\×_⁺⁷×⁴ι/ε≔× ⁻η⁻∕Ｌε²¦¹τ⁺⁺τε¶≔⁺⁺⁺⁺.× ⁺ι⁴]×#⁺³×²ι⁺⁺[× ⁺ι⁴.ε≔× ⁻η⁻∕Ｌε²¦¹τ⁺⁺τε¶»≔⁻×²⌊⟦³ν⟧¹δ≔∕δ²ζ≔×#⁺¹⁻νζσ≔⁺⁺⁺⁺⁺\×_⁺ν¹]σ.⁺×-δ⁺.⁺σ⁺[⁺×_⁺ν¹/ε≔× ⁻η⁻∕Ｌε²¦¹τ⁺⁺τε¶≔×|__νε≔⁻⁻⁺⁴×²νζ¹τ≔✂ε⁰τ¦¦ε≔Ｌεα≔⁻Ｌε¹β¿⁼✂εβα¦¦|«≔⁺✂ε⁰β¦¦_ε»≔⁺✂ε⁰α¦¦|ε≔⁺⁺ε× δ⮌εα≔⁺⁺ε×_δ⮌εβＭ⁼ν¹¦⁰⁺⁺⁺⁺  α¶¦  βＭ±⁼ν¹¦⁰Ｍ±Ｌα⁰≔×#⁻⁺⁴×²⁻ν·⁵ζε⁺¶⁺⁺ε⁺/⁺⁺×_δ\ε¶≔⁻⁻⁺⁴×²⁻ν·⁵ζ¹ψ⁺× ψ⁺|⁺×_⁺δ²|¶⁺× ⁻ψ¹⁺/⁺×_⁺δ⁴\

Try it online!

Haskell, 473 bytes
g '\\'='/'
g '/'='\\'
g '['=']'
g ']'='['
g x=x
z=reverse
d=min 3
m n s=putStrLn$(6+2*n+1-length s)#' '++map g(z s)++tail s
n#c=replicate n c
t 0=".";t n=n#'#'++"["++(2+n)#' '++"."
r 0="|";r n=(2+2*n)#'_'++"/"
q n=d n#'-'++"."++max(n-2)1#'#'++"["++(n+1)#'_'++"/"
e i n=d n#i++"|_"++z(take(max(n+2)(2*n-1))(cycle"|__"))
b n=d n#'_'++"\\"++max(2*n)(3+n)#'#'
w i n=(d n+1+i)#'_'++["|","\\"]!!i
f n=mapM_(m n)$[u k|k<-[0..n],u<-[t,r]]++(t(n+1):map($n)[q,e ' ',e '_',b,w 0,w 1])

OK thanks. Looks correct now

I think it's OK now. btw, the base in your N=1 shrine has one more #

Yup, works now. Fixed that extra unintended #

Vyxal, 120 113 bytes
3∵£\.\|?›ƛ⇧\.$꘍\[+\#n*+\\\_n›d*+";f÷?⇧Ẏ\]+?⇩1∴\#*+\.+¥-`|__`?:3>[d‹|⇧]Ẏ‛_|+¥꘍:ð\_VȮȧL‹\#*\/+‛|/fJ2ʀ¥+\_*+÷WvøMøĊ⁋

Try it Online!
Posting this as a separate answer because it's so golfed, and uses the latest version of Vyxal.
Explanation
----------------- TOP ------------
3∵£                                  # Store min(input, 3) into the register for later use
   \.\|                              # Push a . and a |
       ?›ƛ                       ;   # Map 1...input+1 to
          ⇧\.$꘍                      # That+2 spaces after a dot
               \[+                   # Append a [
                  \#n*+              # Append that many #
                         \_n›d*      # That+1 underscores
                       \\      +"    # Appended to a \ and paired with the previous
                                  f÷ # All of that flattened and each pushed to the stack
------------------- Doorway ------------------
?⇧Ẏ                                            # To the last of what was pushed in the previous, take the first input+2 characters
   \]+                                         # Append a ]
      ?⇩1∴\#*+                                 # Append min(input-2,1) hashes
              \.+                              # Append a .
                 ¥-                            # Append min(input,3) -
                        ?:3>[d‹|⇧]             # Input*2-1 if input>3 else input+2
                   `|__`          Ẏ            # Repeat '|__' to that length
                                   ‛_|+        # Append '_|'
                                       ¥꘍      # Append min(input,3) spaces
                                         :ð\_V # Make a copy, and replace spaces with underscores

---------- Entrance ------------
ȮȧL‹\#*\/+
ȮȧL                      # Length of top part of doorway with whitespace removed
   ‹\#*\/+               # That-1 #, plus a /
          ‛|/fJ          # Append ['|','/']
               2ʀ¥+      # [a,a+a,a+2] where a = min(3,input)
                   \_*+  # That many underscores appended to each of previous
                       ÷ # Iterate out those on the stack

- Final magic bit -
W       # Get the stack
 vøM    # Palindromise each, mirroring brackets
    øĊ  # Center each
      ⁋ # Join on newlines

C, 660 bytes
The pattern just seemed to be too irregular to come up with anything fancy, particularly in a language without string processing. So here is my brute force approach:
m,d,w,k,j;r(n,c){for(j=0;j++<n;)putchar(c);}c(char*s){for(;*s;)putchar(*s++);}f(n){m=n*2;d=n<3?m-1:5;w=m-d/2+2;r(m+5,32);c(".\n");r(m+5,32);c("|\n");for(;;){r(m-k*2,32);c(".");r(k+3,32);c("]");r(k*2+1,35);c("[");r(k+3,32);c(".\n");if(k==n)break;r(m-k*2+1,32);c("\\");r(k++*4+7,95);c("/\n");}c(" \\");r(n+1,95);c("]");r(n-d/2,35);c(".");r(d,45);c(".");r(n-d/2,35);c("[");r(n+1,95);c("/\n");for(k=0;k<2;){c("  ");for(j=0;j<w/3;++j)c("|__");c("|_|"-w%3+2);r(d,k++?95:32);c(!w%3?"|":w%3<2?"|_":"|_|");for(j=0;j<w/3;++j)c("__|");c("\n");}c("  ");r(w,35);c("/");r(d,95);c("\\");r(w,35);c("\n");r(w+1,32);c("|");r(d+2,95);c("|\n");r(w,32);c("/");r(d+4,95);c("\\\n");}

Before golfing:
#include <stdio.h>

void r(int n, int c) {
    for (int i = 0; i++ < n; )
        putchar(c);
}

void c(char* s) {
    for (; *s; ++s) putchar(*s);
}

int f(int n) {
    int m = n * 2;
    int d = n < 3 ? m - 1 : 5;
    int w = m - d / 2 + 2;

    r(m + 5, 32);
    c(".\n");

    r(m + 5, 32);
    c("|\n");

    for (int k = 0; ; ++k) {
        r(m - k * 2, 32);
        c(".");
        r(k + 3, 32);
        c("]");
        r(k * 2 + 1, 35);
        c("[");
        r(k + 3, 32);
        c(".\n");

        if (k == n) break;

        r(m - k * 2 + 1, 32);
        c("\\");
        r(k * 4 + 7, 95);
        c("/\n");
    }

    c(" \\");
    r(n + 1, 95);
    c("]");
    r(n - d / 2 , 35);
    c(".");
    r(d, 45);
    c(".");
    r(n - d / 2 , 35);
    c("[");
    r(n + 1, 95);
    c("/\n");

    for (int k = 0; k < 2; ++k) {
        c("  ");
        for (int j = 0; j < w / 3; ++j)
            c("|__");
        c("|_|" - w % 3 + 2);
        r(d, k ? 95 : 32);
        c(!w % 3 ? "|" : w % 3 < 2 ? "|_" : "|_|");
        for (int j = 0; j < w / 3; ++j)
            c("__|");
        c("\n");
    }

    c("  ");
    r(w, 35);
    c("/");
    r(d, 95);
    c("\\");
    r(w, 35);
    c("\n");

    r(w + 1, 32);
    c("|");
    r(d + 2, 95);
    c("|\n");

    r(w, 32);
    c("/");
    r(d + 4, 95);
    c("\\\n");

    return 0;
}

Not much to explain here. It just goes line by line, and generates the necessary count of each character. I tried to keep the code itself compact, but it still adds up. d is the width of the door, w the width of each brick wall.

c(char*s){for(;*s;)putchar(*s++);} ==> #define c printf; r(n,c){for(j=0;j++<n;)putchar(c);} ==> r(n,C){while(n--)putchar(C);}

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Tips for golfing in K
K is a programming language in the APL family designed by Arthur Whitney. While the official interpreter is closed-source and commercial, a trial version with a workspace limit of 32 bits of addressing space (which shouldn't pose problems for code golf) can be found at the Kx Systems website. This version bundled as part of the kdb+ database is colloquially known as "K4". There are also open-source K implementations available, including Kona, which is based on K3, and my own interpreter called oK, which is based on K5 and has a browser based REPL.
Kx Systems has a wiki with K4/kdb+/Q information, and the Kona GitHub page also has an excellent collection of reference materials. I have begun writing a manual for oK/k5 which may be a useful reference.
Like J and APL, K is a very terse and powerful language, and can often make a good showing in code golf. Please share tips, tricks and idioms you discover, and if you haven't tried K before consider giving it a spin! Post one tip per answer, please!

Calling a Dyad
Assuming you had a dyadic (2-argument) function f:
f: {x+2*y}

You would ordinarily call it like so:
f[3;47]

You can save a character by instead currying in the first argument and then applying the resulting partial function to the second argument by juxtaposition:
f[3]47

The same naturally works for array indexing:
  z: (12 17 98;90 91 92)
(12 17 98
 90 91 92)

  z[1;2]
92

  z[1]2
92

Ranges
Normally if you want to create a vector of sequential numbers you use !:
  !5
0 1 2 3 4

If you want to create a range that starts at a number other than zero, you'd then add an offset to the resulting vector:
  10+!5
10 11 12 13 14

There are a few unusual approaches which could work better for a particular situation. For example, if your base and offset are already members of a list, you could use "where" twice:
  &10 5
0 0 0 0 0 0 0 0 0 0 1 1 1 1 1
  &&10 5
10 11 12 13 14

For slower-growing sequences, consider combining "where" with "take":
  5#2
2 2 2 2 2
  &5#2
0 0 1 1 2 2 3 3 4 4

If you want to create a range of multiples, you could multiply the result of ! or you could scan (\) a list of copies of the step size:
  2*!5
0 2 4 6 8
  +\5#2
2 4 6 8 10

If you're trying to avoid parentheses, the former is better if the length of the sequence is variable and the step size is fixed, while the latter is better if the step size is what tends to vary. Picking the right variation can save 1 or 2 characters. The off-by-one difference could also work in your favor.

Another clever trick from @ngn with situational usefulness is to use e.g. 2|^x instead of (#x)#2.

Printing newlines
If your output must have a newline, you may be tempted to do this:
`0:whatever,"\n"

Don't. K2 (and likely other versions) has a neat feature where you can print a list of lines:
  `0:("abc";"def")
abc
def

So, if you need to append a newline to the output, just do:
`0:,whatever

Trainify (x;f x) and x f g x
Works in ngn/k
You can use "n-times-scan" 1 f\x for this. It is slightly (likely just 1 byte) longer but more reliable than converge scan f\x because it is guaranteed to return the two-item list (x;f x) even if x~f x or ~x~f f x.
For example, if you want to extract the first and last items of a list:
{(*x;*|x)}   /10 bytes
{*'(x;|x)}
{*'1|:\x}    /9 bytes
*'1|:\       /6 bytes (8 if you need enclosing parens)

Note that *'|:\ doesn't always work because the reverse might be identical to itself, in which case a 1-item list is returned instead of two.
This trick extends to the case x f g x, which can be translated to f/(x;g x) and then f/1 g\x, though it actually saves bytes only if g does not require (...) in g\.
For sorting a list of lists by the result of -/ of each row:
{<x!-/'x}   /9 bytes, or 10 with `@`
<!/1-/'\    /8 bytes, or 10 with `(...)`

Both are real examples from this answer.

Sometimes f\ works unconditionally in place of 1 f\.
/absolute value
{x|-x}
|/-:\

x f x is shorter to trainify as f/2#, than f/1::\.
/equality table
{x=/:x}
=/:/2#,

(f x)g x is only one byte longer than x g (f x) as a train: g/|1 f\.
/extract first interval based on the indices computed by f
{*(f x)_x}
{*f[x]_x}
*_/|1 f\

Cyclic Permutations
Dyadic ! in K2/K3 is "rotate":
  2!"abcd"
"cdab"
  -1!"abcd"
"dabc"

When "scan" (\) is provided with a monadic verb, it acts as a fixed-point operator. In K, fixed point operators repeatedly apply their verb to a value until the initial value is revisited or the value stops changing. Combining rotate with fixed-point scan provides a very convenient way of computing a set of cyclic permutations of a list:
  ![1]\1 2 4 8
(1 2 4 8
 2 4 8 1
 4 8 1 2
 8 1 2 4)

You can either curry ! via brackets or parenthesize to create the verb train (1!):
![1]\
(1!)\

(Note that 1!\ has an entirely different behavior!) Each of these is equivalent in length but the former may be more desirable if the rotation stride is something other than 1; in this case the brackets delimit a parenthesized subexpression "for free".
As an example, here is a short program which tests via brute force whether a string x contains the substring y (cyclically!):
{|/(y~(#y)#)'![1]\x}

K5 users beware! K5 has changed the meaning of dyadic !, so this technique isn't so easy. It will work as expected in Kona.

Casts from strings are expensive. Just use eval. This:
0.0$a

can become just this:
. a

In K5, it's a byte shorter:
.a

Each Right
Occasionally you may find yourself writing (or arriving at by simplification) a parenthesized expression applied via each-monad:
  (2#)'3 4 5
(3 3
 4 4
 5 5)

It is one character shorter to convert this pattern into an application of each-right:
  2#/:3 4 5
(3 3
 4 4
 5 5)

On the flip side, if the left-hand side expression requires parenthesis, it can save a byte to convert an each-right to an each by fixing one of the args. E.g. (x,y)in/:z to in[x,y]'z.

Lists of Strings
Some challenges call for a hardcoded list of strings, e.g.:
("qwertyuiop";"asdfghjkl";"zxcvbnm")

Sometimes, a few bytes can be saved using an alternative form, i.e.:
";"\:"qwertyuiop;asdfghjkl;zxcvbnm"

k4 (and several other variants) can take advantage of the symbol datatype, so long as the hardcoded strings lack spaces. For example:
$`qwertyuiop`asdfghjkl`zxcvbnm

Handling unicode characters (ngn/k only)
Originally from Bubbler.
Putting unicode characters inside a string turns them into a byte sequence:
 "⍺⍴⍵"
0xe28dbae28db4e28db5

this often hinders the ability to use them as individual characters. However, you can use symbols instead:
 `⍺`⍴`⍵
`0xe28dba`0xe28db4`0xe28db5

Which will group them into appropriate characters. You can then retrieve the byte sequences with $, and concatenate them into the correct string.

Avoid Conditionals
K has a conditional construct (:[) which is equivalent to a Lisp-style cond:
:[cond1;result1; cond2;result2; cond3;result3; default]

You can have as many conditions as you like, and if none match the default value is returned.
Sometimes (as in recursive programs or programs that otherwise rely on a sequence of side effects), there's no getting around using one of these. However, in situations where you can afford to do a bit of extra work, you can often replace a "cond" with list indexing.
Consider the infamous fizzbuzz program. Written in a conventional imperative programming style, we might go with:
{:[~x!15;"FizzBuzz";~x!3;"Fizz";~x!5;"Buzz";x]}'1+!100

There's quite a bit of repetition here in the divisibility tests. A different approach recognizes that there are 4 cases (a number, divisibility by only 3, divisibility by only 5, divisibility by 3 and 5) and attempts to directly compute an index which chooses one of these cases from a list:
{(x;"Fizz";"Buzz";"FizzBuzz")@+/1 2*~x!/:3 5}'1+!100

Two characters shorter, and a better use of the language. Knowing that list literals are evaluated right to left, we also gain some additional golfing opportunities for combining reused subexpressions. We couldn't have easily done this in the cond-based version, since the string cases aren't evaluated at all if they aren't selected:
{(x;4#t;4_ t;t:"FizzBuzz")@+/1 2*~x!/:3 5}'1+!100

Now we've saved 5 characters overall. Incidentally, this particular example works out even nicer in k5, since we have the "pack" overload for / to handle the step of multiplying by a vector of coefficients and summing:
{(x;4_t;4#t;t:"FizzBuzz")@2 2/~3 5!\:x}'1+!100

Also note that the behavior of "find" (?), which produces an index past the end of the key list if the item is not found, is specifically designed to support handling a "default" case in this kind of indexing. Consider this fragment to convert vowels to uppercase:
{("AEIOU",x)"aeiou"?x}'

Versus one of:
{t:"aeiou"?x;:[t<5;"AEIOU"t;x]}'
{:[~4<t:"aeiou"?x;"AEIOU"t;x]}'

(I know which I'd rather read, too!)

Uses of $
This tip is written with ngn/k in mind, parts might apply to other versions

$x string applied on a string converts each character into its own string, making $x one byte shorter than ,'x or ++x.

This transformation can be useful when replacing some characters with spaces in a string: Given a string x and a boolean vector y of the same length, ($x)@'y inserts spaces at the indices of 1's in the boolean vector.
  ($"Hello")@'0 1 1 0 1
"H  l "

i$C truncates strings if i is less than the length of string. On strings that case is identical to i#C, but when given lists of strings, $ always applies to individual strings, potentially saving some 's.

  3$("Hello, ";"World")
("Hel";"Wor")

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
Gode-Colf: Wipping Flords around
Here is another short string related code-golf. You must write a full program that reads a string (from STDIN or as command line arguments, as long as you specify which) and wips the flords around (flips the words around). A valid flord wip must

Flip all of the beginning consonants. (All of the leading consonants up to the first vowel) For example, "Flipping Words" does not become "Wlipping Fords" because this only flips the first letter of each. Instead, it becomes "Wipping Flords"

Never flip a vowel. For example, "Eating Breakfast" becomes "Breating Eakfast"

Capitalize the first letter of each output word, and no more. For example 'Stack Overflow' becomes 'Ack Stoverflow', not 'ack StOverflow'.

Your input:

Will have the first letter of every word capitalized, and all the other letters lowercase.

Will consist entirely of upper and lowercase letters and spaces.
There will not be any extra or leading spaces.

There will be no strange consonant only words. For the purposes of this challenge, "y" is a consonant.

Will have at least 2 words, each separated with a single space. If there are an even number of words, you must flip the first word with the second, the third with the fourth, the fifth with the sixth and so on and so forth. If there are an odd number of words, the same rules apply, and the last word is skipped.

Here are some sample inputs and outputs.

Bunny Rabbit ---> Runny Babbit
Programming Puzzles And Code Golf ---> Pogramming Pruzzles Cand Ode Golf
The Cake Is A Lie ---> Ce Thake Is A Lie ("Is" and "A" both start with a vowel, so nothing changes. "Lie" is the last odd-word-out so nothing changes)
May The Best Golfer Win ---> Thay Me Gest Bolfer Win

CJam, 62 53 bytes
This is too long for now. Will add explanations once I am done golfing.
qS%2/{{el__"aeiou"&0=#_2$<@@>}%(a+2/Wf%~}%{s(eu\+}%S*

Try it online here


text:
Finding the Deadlock
Finding the Deadlock
When programming a multithreading application one must take good care to avoid deadlocking the various threads when accessing shared resources. A deadlock occurs when a thread attempts to access a resource that's locked in another thread at the same time that the other thread is trying to access a resource locked by the first. This is the simple case, but it can get more complex with longer resource chains.
The challenge
You should write a program or function that can detect a possible deadlock situation in a list of the resources accessed by each thread. This is code-golf, so shortest answer in bytes wins.
Every thread is started at the same time, but after that they can run at any combination of interleaving. If there are 2 threads with 4 actions each, it could be run as (where each number is an action taken by the thread with that id) 1,1,1,1,2,2,2,2, 2,2,2,2,1,1,1,1, 1,2,1,2,1,2,1,2, 1,1,2,2,2,2,1,1, or any other possible combination.
Input
You will receive, via STDIN, function parameter, or closest alternative, a list of strings. Each string will be in the format +a -b. Every one of this strings represents the locking(+)/unlocking(-) of a resource by the thread. Between every thread will be a --- separator.
It is guaranteed that a thread won't try to lock a resource it already has locked, and that all threads will explicitly unlock all the resources they have locked before exiting.
Following is an example to demonstrate:
+a    # Lock resource a
+b    # Lock resource b
-a    # Unlock resource a
-b    # Unlock resource b
---   # Thread separator
+b    # Lock resource b
-b    # Unlock resource b

Output
The output shall be falsy if the input doesn't contain any deadlock possibility, and truthy if it contains a possible deadlock situation. For example:

true
false
1
0

are all valid outputs, but anything clearly defined as truthy/falsy will be accepted.
Examples
+a
-a
---
+a
-a

Output: false

+a
+b
-b
-a
---
+b
+a
-a
-b

Output true
Deadlock when trying to acquire b,a respectively for threads 1,2

+a
+b
-a
-b
---
+a
+b
-b
-a

Output false

+a
+b
-b
-a
---
+b
+c
-c
-b
---
+c
+a
-a
-c

Output: true
Deadlock in threads 1,2,3 when trying to acquire b,c,a respectively.

http://pastebin.com/vMYRZxtW
Output false

http://pastebin.com/V5MVgNgS
Output true
Deadlock in threads 1,2,3 when trying to aquire b,d,a respectively.

Of course this could get a lot more complex, with more threads, more resources for each one, and so on, but I believe these tests cover the basics.
Bonus
Since it's very very sad when you find deadlock situations when writing a program, there is a -8 byte bonus to answers outputting :( and :) as truthy/falsy respectively.

I am just assuming this, but it would be nice to clarify that the actions of each thread (starting from top of the thread) are run parallely and correspond to the same system time

The actions are run concurrently, but the time in which every action is run can't be assumed. It could occur that the threads are actually run strictly one after the other or completely interleaved. It could be that the first half of thread 1 is run, then thread 2 is run entirely, then thread 1 runs it's second half. And so on. I've updated the question to clarify that.

Ah okay, so the task is to figure out that given any possible combination of thread run times, whether a deadlock is possible.

Yes, sorry, I didn't think that could leave doubts. Actually in the last example this is demonstrated since thread 2 doesn't try to use resource d until later.

Can locks/unlocks interleave in the input? E.g. +a +b -a -b. Your examples never contain this.

Yes, they could. Sorry, I forgot to include one that had this. I'll add one now.

@rcrmn are you sure :) shouldn't be for false and :( for true?

Yes, you are right! fixed

Python 2 - 227
Basically makes sure there are no loops of 'precedence'. For example in the second test, the first thread has a a(b) precedence and the second thread has a b(a) precedence.
I was thinking about rewriting this in Pyth as I think it would work well with all the itertools operations, but converting the regex will take some work so for now I'll post this and maybe try to convert it and post another answer later.
from itertools import*
import re
f=lambda t:any(re.search(r"(.)((.)\3)+\1",''.join(p))for i in product(*[[m.group(1)+m.group(2)for m in re.finditer(r"(\w).*(\w).*\2.*\1",e,16)]for e in t.split('---')])for p in permutations(i))

This answers false to http://pastebin.com/V5MVgNgS

@Tyilo It outputs True for me; how exactly are you running it?

oh it was only reading one line for me. How are you supposed to run it?

@Tyilo I changed the format to be a function which takes a multiline string as input

Python - 586 539 524 501 485 bytes - 8 = 477
Indentation levels:
1: 1 space
2: 1 tab
3: 1 tab + 1 space
4: 2 tabs

--
import sys
V=set()
t=[[[]]]
for r in sys.stdin:
 r=r.strip()
 if'---'==r:t.append([[]])
 else:v=r[1:];V.add(v);l=t[-1][-1];t[-1].append(l+[v]if'+'==r[0]else filter(lambda x:x!=v,l))
s=lambda l:s(l[1:])+map(lambda x:(l[0],x),l[1:])if 1<len(l)else[]
E=reduce(set.union,map(lambda x:set(sum(map(s,x),[])),t),set())
for v in V:
 k=set();q=[v]
 while 0<len(q):
    u=q.pop(0)
    if u in k:continue
    k.add(u)
    for x,y in E:
     if u==x:
        if y in k:print':(';sys.exit()
        else:q.append(y)
print':)'

Use ; to combine lines that are indented to save characters. Likewise, make your statements one liners.

@isaacg and ace, Thanks! I think I improved it as much as I could using your tips.

BTW if you don't mind piping the input from a file (or pressing Ctrl+D twice) then you can do for r in sys.stdin instead of for r in sys.stdin.readlines()

@ace I don't see any different behavior between using just sys.stdin or sys.stdin.readlines(), so I have changed it, thanks again.

You can remove the spaces between print and ':)'


text:
Block Building Bot Flocks!
The contest is over!
Intro
This is an interactive king-of-the-hill contest where the controller is fully contained in a Stack Snippet at the bottom of the question. The controller automatically reads the answers and plays through games. Anyone can run it at any time right in their browser.
The mechanics of this contest are very similar to those of Red vs. Blue - Pixel Team Battlebots. Except the game being played, while still grid based, is entirely different. Each game is 1 vs. 1 and there are no teams. Each entry is fighting for itself and only one will be the final champion.
The controller uses JavaScript, and as JavaScript is the only client-side scripting language most browsers support, all answers must be written in JavaScript too.
In this spec, italicized text is used to indicate the formal term for a game mechanic or property. These terms are used throughout to help maintain a cohesive and clear way of referring to the different parts of the game.
Gameplay
Basics
Every answer to this question represents a player. A game is a competition between two players, P1 and P2. Each player controls a flock of 8 bots, numbered 0 through 7. Games takes place in the grid, a 128×64 cell arena whose bottom 8 rows start out as walls (the 'blocks') and other rows start as air. Cells outside the grid bounds are considered air.
The grid's x coordinate ranges from 0 on the left to 127 on the right, and y ranges from 0 at the top to 63 at the bottom.
Sample starting grid:

Bots always stay aligned to the grid cells and multiple bots may occupy the same cell. Bots can only occupy air cells. P1's bots always start in a line 0-7 at the very left of the row above the walls and P2's bots always start in a line 7-0 at the very right.
The neighbors of a bot or cell are the 8 cells directly orthogonal and diagonal to it.
The field of view (FOV) of a bot is the 13×13 cell square centered on a bot. A cell or enemy bot is said to be in a player's FOV if it is in the FOV of at least one of the player's bots.
Moves & Actions
During a game, each player gets to move 1000 times. P1 moves first, then P2, then P1 and so on until 2000 total moves have been made, at which point the game ends.
During a move, each player receives information about the game state and the grid cells and enemy bots in their FOV, and uses it to decide on an action for each of their bots to take.
The default action is do nothing, where the bot does not move or interact with the grid.
The other actions are move, grab, and place:

A bot can move to one of its neighboring cells C if:

C is not out of bounds,
C is air (i.e. not a wall),
and at least one of C's neighbors is a wall.

If successful, the bot will move to C.
A bot can grab one of its neighboring cells C if:

C is not out of bounds,
C is a wall,
and the bot is not already carrying a wall.

If successful, C will become air and the bot will now be carrying a wall.
A bot can place to one of its neighboring cells C if:

C is not out of bounds,
C is air,
no bots of either player occupy C,
and the bot is carrying a wall.

If successful, C will become a wall and the bot will no longer be carrying a wall.

Unsuccessful actions result in a do nothing.
A cell occupied by at least one wall-carrying bot has a small wall-colored square drawn over it. Bots start without walls.
Memory
During a move, a player can access and change their memory, an initially empty string that lasts throughout the game and can be used to store strategic data.
Goal
The cell in the yellow crosshair is the goal, which starts in a random position. Each player has a score that starts at 0. When a player's bot moves to the goal, that player's score increases by 1 and the goal is randomly repositioned before the next turn. The player with the highest score at the end of a game wins. It's a tie if the scores are equal.
If multiple bots move to the goal during a move, the player still only gets one point.
If the goal has been in the same place for 500 moves, it is randomly repositioned again. Any time the goal is randomly positioned, it is guaranteed to not be placed on a cell occupied by a bot.
What to Program
Write a body for this function:
function myMove(p1, id, eid, move, goal, grid, bots, ebots, getMem, setMem) {
    //body goes here
}

It will be called once every time your player moves and needs to return the actions you want each of your bots to take during that move.
You can use the Baseline code as a starting point.
Parameters

p1 is a bool that's true if you are P1 and false if you are P2
id is an integer that is the answer ID of your answer.

You can find the ID of an answer by clicking the 'share' link below it and looking for the number right after a/ in the URL.
The ID of the Test Entry is -1.

eid is an integer that is the answer ID of your enemy's answer.
move is an integer from 1 to 1000 that says what move you are on.
goal is an object with x and y properties. These are the goal's coordinates. They are given even if the goal is out of your FOV.
grid is a function that takes in x and y arguments, e.g. grid(x,y). It returns:

-1 for 'unknown' if the arguments aren't two integers or if x,y is not in your FOV.
0 for 'air' if x,y is out of bounds or if the cell at x,y is air.
1 for 'wall' if the cell at x,y is a wall.

bots is an array of your 8 bots. Its elements are objects with properties x, y, and hasWall:

x and y are the bot's coordinates.
hasWall is true if the bot is carrying a wall and false if not.

bots is always ordered normally, the Nth index corresponds to bot number N.
ebots is an array of objects with x, y, and hasWall properties just like bots. Only the enemy bots in your FOV are in ebots. So it would have length 0 if if there are no enemy bots in your FOV. It is ordered randomly.
getMem is a function with no arguments that returns your memory.
setMem is a function that takes one argument M. If M is a string of 256 characters or less, your memory is updated to M, otherwise nothing happens.

The browser console object is available for the Test Entry alone.
Return Value
Your function needs to return an array of exactly 8 integers, each ranging from 0 to 24. The value at index N is the action that bot number N will take.
All your bots will do nothing if your function:

Throws an error of any kind. (error)
Takes longer than 20 milliseconds to execute. (timeout)
Doesn't return an array of 8 integers ranging from 0 to 24. (malformed)

For convenience, the number of errors, timeouts, and malformed actions are displayed when a game ends.
Each of the numbers from 0 to 24 corresponds to a particular bot action:

0 is for doing nothing.
1-8 are for moving.
9-16 are for grabbing.
17-24 are for placing.

Each of the 8 values for moving, grabbing, and placing corresponds to one of the bot's neighboring cells, as shown here:

So, for example, 15 is the action for grabbing the cell below the bot.
Bot actions are handled in the order bot 0 to bot 7. For example, if during one move bot 0 is told to place a wall in the same air cell bot 1 was told to move to, the air cell will become a wall before bot 1's action is handled and bot 1 will be unsuccessful.
Unsuccessful actions become do nothings and are said to have failed. Failed action counters are also displayed when the game ends.
Rules
I may temporarily or permanently disqualify users or answers that don't follow these rules. Disqualified entries are not eligible to win.

When declaring variables or functions, you must use the var keyword.
 e.g. var x = 10 or var sum = function(a, b){ return a + b }
Things declared without var become global and could interfere with the controller. Steps have been taken so that this interference should be impossible, but do this to make sure.
Your code shouldn't run slowly or waste time.
It's impossible to stop JavaScript functions mid-execution, so each player's code is run to completion. If your code takes a long time to run, everyone running your player will notice and be annoyed. Ideally, entries will always run well within the 20ms limit.
You must use code compatible with ECMAScript 5 in the latest version of Firefox as this is where I'll be running it. Do not use features from ECMAScript 6 as it is not yet supported in many browsers.
You may answer up to 3 times, but only if each of your strategies is considerably different. You can edit answers as much as desired.
You may not attempt to have any sort of memory except through the use of getMem and setMem.
You may not attempt to access or modify the controller, other player's code, or external resources.
You may not attempt to modify anything built into JavaScript.
Answers need not be deterministic. You may use Math.random.

Answer Format
#EntryName

Notes, etc.

    //function body
    //probably on multiple lines

More notes, etc.

The first multiline code block must contain your function body.
The entry name is limited to 20 characters.
Your entry will show up in the controller with the title EntryName - Username [answer ID], plus [DQ] if it's disqualified.
Winning
When the question has been up for at least 3 weeks and once answering has settled down, I will crown the champion.
I'll use the controller's autorun feature. In an autorun round, every non-disqualified player plays two games with every other, one as P1, one as P2 (a double round-robin).
I'll autorun as many rounds as I can in the period of a few hours. This will depend on how many submissions there are and how time intensive they are. But rest assured, I'm committed to getting an accurate final leaderboard. The player with the most wins is the champion and their answer will be accepted.
I'll be using Firefox on a laptop with Windows 8.1 64-bit, 4 GB ram, and a 1.6GHz quad-core processor.
Prize
I will write and post a PPCG challenge specifically dedicated to the champion. It will somehow involve their username or avatar or something about them. I'll privately decide on what the challenge will be about when this contest is over. I'll write it to the best of my ability and try to make sure it becomes a Hot Network Question.
Controller
Run this snippet or go to this JSFiddle to use the controller. It starts with random players selected. I've only thoroughly tested it in Firefox and Chrome.

Loading entries...

Block Building Bot Flocks

 vs.
<canvas id=canvas>Canvas unsupported!</canvas>
0 | 0 | 0

<button id=runPause type=button onclick=runPause()>Run</button> <button id=moveOnce type=button onclick=moveOnce()>Move Once</button> <button type=button onclick=newGame()>New Game</button>

<input id=delay size=4 value=20> ms delay <input id=showNumbers type=checkbox onclick=toggleNumbers()>Show bot numbers <input id=showLOS type=checkbox onclick=toggleLOS()>Show field of view

Player 1

<select id=p1Select onchange=changeSelect(!0)></select>

Answer Link

Player 2

<select id=p2Select onchange=changeSelect(!1)></select>

Answer Link

Test Entry

<textarea id=testEntry rows=8 cols=64>return [0,0,0,0,0,0,0,0]</textarea>

<button type=button onclick=autorun()>Autorun N Rounds</button> N = <input id=N size=4 value=1> <input id=arTestEntry type=checkbox>Include Test Entry

<input id=debug type=checkbox onclick=toggleDebug()>Console debug messages | Scale: <input id=sc1 type=radio name=sc value=1>Micro<input id=sc3 type=radio name=sc value=3>Small<input id=sc6 type=radio name=sc value=6 checked>Normal<input id=sc9 type=radio name=sc value=9>Large | Colors: <input id=normalCo type=radio name=co value=normal checked>Normal<input id=pastelCo type=radio name=co value=pastel>Pastels<input id=neonCo type=radio name=co value=neon>Neon  <button type=button onclick=reload()>Reload</button>

No entry name/code found:

Autorun in progress. Running game .

Autorun Results

Players:
Rounds:
Games per round:
Total games:

Leaderboard:

(W = wins, T = ties, L = losses, G = total goals, E = errors, I = timeouts, M = malformed actions, F = failed actions)

Player vs. Player Statistics:

The top row has the ID's of P1.
The left column has the ID's of P2.
Every other cell not on the diagonal has the form "[P1 win count] [tie count] [P2 win count]".

<button type=button onclick=closeAutorun()>Close</button>

This question has its own chatroom. I'll post leaderboards there every few days.

+1 Excessively long.

Thanks to the buttons to adjust the size of the grid, I can run the Stack Snippet on my phone :)

Lots of love (codegolf.stackexchange.com/questions/50768/) but that's not easy

This is mesmerizing to watch.

I notice that the previous challenge prohibited modifying the algorithms once they'd been posted, but this doesn't.  Does that mean posting an initial answer and then improving on it is allowed/encouraged this time?

@Stephen Yes. Rule bullet 4: "You can edit answers as much as desired."

I love that these challenges can be run and played right in the browser using Javascript. If I created my own puzzle based off the code you've created for the JSFiddle - would that be okay? I'd mostly be using it for example, I'll be sure to give credit.

@DoubleDouble Go for it.

Neighboring cell. Is that 4 or 8? Also a bot can grab the only block near it. nd what are the s"teps [that] have been taken so that this interference should be impossible"?

Black Knight
The bot's name comes from an early plan to have it be able to move like a chess knight: over two, up one, etc, which would be faster in some cases.
var moves = new Array(8),
    mem = getMem(), newMem = '';

var decodeMem = function(){
  //mmtxy
  for(var ind = 0; ind < 8; ind++){
    var sub = mem.substr(ind * 5, 5)
    bots[ind].lastMove = parseInt(sub[0], 36);
    bots[ind].last2Move = parseInt(sub[1], 36);
    bots[ind].timesStill = sub.charCodeAt(2) - 48;
    bots[ind].lastX = sub.charCodeAt(3) - 187;
    bots[ind].lastY = sub.charCodeAt(4) - 187;
  }
}
decodeMem();

var distanceTo = function(fromX, fromY, toX, toY){
  // Chebyshev distance
  return Math.max(Math.abs(fromX - toX),
                  Math.abs(fromY - toY));
}

var direction = function(from, to){ // Math.sign()
  var diff = to - from;
  return diff > 0 ? 1 : (diff < 0 ? -1 : 0);
}

var dirs = [
  [1, 2, 3],
  [4, 0, 5],
  [6, 7, 8]
];

var moveTo = function(from, to){
  var prioritiesWall = [
    [0],
    [1, 2, 4, 17, 18, 20, 19, 22, 23, 21, 3, 6, 5, 7, 24, 8],
    [2, 3, 1, 17, 19, 18, 23, 22, 24, 4, 5, 20, 21, 6, 8, 7],
    [3, 2, 5, 19, 18, 21, 17, 24, 23, 20, 1, 8, 4, 7, 22, 6],
    [4, 1, 6, 22, 17, 20, 21, 24, 19, 2, 7, 18, 23, 3, 8, 5],
    [5, 3, 8, 24, 19, 21, 20, 22, 17, 2, 7, 18, 23, 1, 6, 4],
    [6, 4, 7, 22, 20, 23, 17, 24, 18, 21, 1, 8, 2, 5, 19, 3],
    [7, 8, 6, 22, 24, 23, 18, 17, 19, 4, 5, 20, 21, 1, 3, 2],
    [8, 5, 7, 24, 21, 23, 19, 22, 18, 20, 3, 6, 2, 4, 17, 1]
  ];
  var prioritiesNoWall = [
    [9, 10, 11, 12, 13, 14, 15, 16, 0],
    [1, 2, 4, 9, 16, 10, 12, 3, 6, 11, 14, 5, 7, 13, 15, 8],
    [2, 3, 1, 10, 15, 14, 16, 4, 5, 12, 13, 9, 11, 6, 8, 7],
    [3, 2, 5, 11, 14, 10, 13, 1, 8, 9, 16, 4, 7, 12, 15, 6],
    [4, 1, 6, 12, 13, 16, 11, 2, 7, 10, 15, 9, 14, 3, 8, 5],
    [5, 3, 8, 13, 12, 14, 9, 2, 7, 10, 15, 11, 16, 1, 6, 4],
    [6, 4, 7, 14, 11, 12, 15, 1, 8, 9, 16, 2, 5, 10, 13, 3],
    [7, 8, 6, 15, 10, 9, 11, 4, 5, 12, 13, 14, 16, 1, 3, 2],
    [8, 5, 7, 16, 9, 13, 15, 3, 6, 11, 14, 2, 4, 10, 12, 1]
  ];

  var dir = dirs[direction(from.y, to.y) + 1][direction(from.x, to.x) + 1],
      method = from.hasWall ? prioritiesWall[dir] : prioritiesNoWall[dir];

  if(distanceTo(from.x, from.y, goal.x, goal.y) === 1){
    method.splice(1,2);
  }

  for(var i=0; i<method.length; i++){
    var attempt = method[i];
    if(checkMove(from, attempt)) return attempt;
  }
  return 0;
}

var numWalls = function(x, y, indexes){
  var allCoords = [
    [x - 1, y - 1],
    [x,     y - 1],
    [x + 1, y - 1],
    [x - 1, y    ],
    [x + 1, y    ],
    [x - 1, y + 1],
    [x,     y + 1],
    [x + 1, y + 1],
  ];
  var allTypes = allCoords.map(function(e){
    return grid(e[0], e[1]); // air = 0, wall = 1
  });
  var justWalls = allTypes.filter(function(e){
    return e === 1;
  }).length;

  return indexes ? allTypes : justWalls;
}

var checkMove = function(coords, moveCode){
  var x = coords.x, y = coords.y,
      baseX = [0, -1, 0, 1, -1, 1, -1, 0, 1],
      baseY = [0, -1, -1, -1, 0, 0, 1, 1, 1],
      targetX = x + baseX[(moveCode - 1) % 8 + 1],
      targetY = y + baseY[(moveCode - 1) % 8 + 1];

  if((targetX > 127 || targetX < 0 || targetY > 63 || targetY < 0) || // Don't bother if it's out of bounds
     (coords.timesStill > 2 && x == coords.lastX && y == coords.lastY && (moveCode == coords.lastMove || moveCode == coords.last2Move)))
    // Or is doing the same moves and not moving
    return false;

  var targetGrid = grid(targetX, targetY), enemyNear = false, couldStrandEnemy = false,
      eWallDirMove, hasNeighbor = numWalls(targetX, targetY) > 0;

  ebots.forEach(function(ebot){
    // Don't place a wall where an enemy can take it
    if(distanceTo(targetX, targetY, ebot.x, ebot.y) === 1 && !ebot.hasWall && (y != ebot.y || x != ebot.x))
      enemyNear = true;

    // Don't move if you can strand an enemy
    var eWallDir = numWalls(ebot.x, ebot.y, true).indexOf(1) + 1,
        wallX = ebot.x + baseX[eWallDir], wallY = ebot.y + baseY[eWallDir];

    if(!coords.hasWall && numWalls(ebot.x, ebot.y) === 1 &&
       distanceTo(x, y, wallX, wallY) === 1){
      eWallDirMove = dirs[direction(y, wallY) + 1][direction(x, wallX) + 1] + 8;
      couldStrandEnemy = true;
    }
  })

  if(targetX == goal.x && targetY == goal.y && targetGrid === 0){
    targetGrid = 2 // Don't place a wall in the goal
  } else {
    ebots.concat(bots).forEach(function(bot){
      // Ensure target cell doesn't have a bot in it
      if(bot.x == targetX && bot.y == targetY) targetGrid = 2;
    });
  }

  return ((moveCode < 9 && targetGrid !== 1 && hasNeighbor && !couldStrandEnemy) || // Move
          (moveCode > 8 && moveCode < 17 && targetGrid === 1 && !coords.hasWall && (!couldStrandEnemy || (couldStrandEnemy && eWallDirMove == moveCode))) || // Grab
          (moveCode > 16 && targetGrid === 0 && coords.hasWall && !enemyNear)) // Place
}

var goalClosest = {dist: Infinity}, rescuers = {};
bots.forEach(function(bot, index){

  // Check if bot is stranded
  bot.stranded = false;
  if(numWalls(bot.x, bot.y) / 8 == bot.hasWall){
    bot.stranded = true;
    rescuers[index] = -1;
  }
});

bots.forEach(function(bot, index){
  if(!bot.stranded){
    // Find which bot is closest to the goal
    var goalDist = distanceTo(bot.x, bot.y, goal.x, goal.y);

    if(goalDist < goalClosest.dist){
      goalClosest.dist = goalDist;
      goalClosest.index = index;
    }
  }
});

bots.forEach(function(bot, index){
  var destination = {
    x: 14 + (index % 4) * 32 + 3 * (index > 3),
    y: index > 3 ? 55 : 27
  }
  if(index == goalClosest.index){
    destination = goal;
  }

  moves[index] = moveTo(bot, destination);

  if(moves[index] == bot.lastMove || moves[index] == bot.last2Move) bot.timesStill++;

  newMem += moves[index].toString(36) +
    bot.lastMove.toString(36) +
    String.fromCharCode(bot.timesStill + 48) +
    String.fromCharCode(bot.x + 187) +
    String.fromCharCode(bot.y + 187);
});

setMem(newMem);

return moves;

Explanation
Determining which move to make for each bot can be divided into two main tasks: figuring out where to go and how to get there.
Where to go
The basic task of figuring out where to go is easy: go towards the goal if you're closest, or otherwise try to position yourself as far away from teammates. It first goes through each bot and determines if it is stranded (i.e. it has no blocks surrounding it and isn't holding a wall, or it is surrounded by walls and holds a wall).  It then loops through the bots again to find the non-stranded bot closest to the goal. All other bots make their way towards being spaced out, with the bottom row on the surface of the blocks (y=55) and the top row at y=27. Once it knows where to go, it hands it off to the moveTo function.
How to get there
Deciding how to get to the destination is far more difficult because the bots must always be adjacent to a wall to move. It first figures out the direction code (1–8) of the destination relative to its current position. For example, if a bot were at the bottom-left corner and it wanted to go to the top right, it would use the direction code 3. For each direction, I hardcoded a list of moves, with the first being the ideal, top-priority move, and the last being the last resort. This is separated by whether or not the bot has a wall, because you cannot use a place move without a wall or use a grab move while already having a wall.
Of course, using the ideal move doesn't always work, and it would result in a lot of failed actions. This is where checkMove comes in. This function checks the potential move against every requirement, to prevent the bot from moving out of bounds or into a wall, for example. If a nearby enemy bot can be stranded (it has only one adjacent wall that can be taken by the bot), that becomes its priority, so the function will return false for an otherwise legitimate move so it can skip to the grab moves and take out the enemy. The function prevents several other stupid moves like placing a wall in the goal or another bot.
The memory string
Sometimes the bot will not be actually stranded but will keep trying the same move and not end up moving (usually picking up a wall and putting it down, picking it up and putting it down, etc). To prevent this, it uses the memory string to remember its last two moves, its last x and y position, and how many times it has been still. Each datum is encoded as a single character for easy splitting. (The string has to be 256 characters, not bytes, so using multibyte Unicode characters isn't a problem, as it is with typical golfing challenges.)
For example, say a bot grabbed the wall on its left (code 12) this turn, replaced it to its left (code 20) in its previous turn, and has been at the coordinates (107, 3) for the past 16 turns. The memory string for this instance would be encoded as follows:

ck: The two latest action codes are converted to base36 to make the two-digit numbers a single letter.
@: The number of times it has been still is represented as the ASCII character with that code + 48 to skip over unprintable characters and so the first nine times still shows the actual number (String.fromCharCode(0 + 48) → 0).
Ħ¾: The x and y coordinates are also represented as as the character with that value, this time offset by the somewhat-arbitrary value of 187 to avoid problematic characters.

A typical memory string during the game might be 53äÇØb7¼ðÌ00ßĉÖ7m±ĪÚ00ĝÌò00Ĝìò00ĖČò00ĈĬò, with a group of five characters for each of the eight bots.

If a player is in a game against itself, then either Player 1 or Player 2 can win, with no apparent bias. This answer is the exception, as Player 1 nearly always wins by a large margin. I can't see a reason why - it's intriguing.

@trichoplax I imagine it's because P1 moves before P2, so P1 will strand P2 before it can do the same.

The challenge is over and the results are in! After 30 rounds, Black Knight had 204 wins, and the next best entry, Seekers, only had 147. Congratulations NinjaBearMonkey! The you specific challenge is on the way.

Absolutely ninja! Thank you

Outposts
The 8 bots each take a 32 by 32 square and run to the centre of it (I offset the centres slightly otherwise they end up pairing up and travelling vertically with one wall block between them, so one of them gets stranded).
Each bot will stay in the centre of its square unless the goal is within 32 cells of its respective centre, in which case it will run to the goal and then back to its centre.
This still uses the Baseline method of reaching its target (goal or centre) so does not move diagonally. Just a starting point...
var encodeAction = function(type, dx, dy) {
    var d
    if (dx === -1 && dy === -1) d = 1
    else if (dx === 0 && dy === -1) d = 2
    else if (dx === 1 && dy === -1) d = 3
    else if (dx === -1 && dy === 0) d = 4
    else if (dx === 1 && dy === 0) d = 5
    else if (dx === -1 && dy === 1) d = 6
    else if (dx === 0 && dy === 1) d = 7
    else if (dx === 1 && dy === 1) d = 8
    else return 0
    return 8 * type + d
}

var getNeighborCell = function(x, y, wallState) {
    if (x > 0 && y > 0 && grid(x - 1, y - 1) === wallState) return { x: x - 1, y: y - 1 }
    if (y > 0 && grid(x, y - 1) === wallState) return { x: x, y: y - 1 }
    if (x < 127 && y > 0 && grid(x + 1, y - 1) === wallState) return { x: x + 1, y: y - 1 }
    if (x > 0 && grid(x - 1, y) === wallState) return { x: x - 1, y: y }
    if (x < 127 && grid(x + 1, y) === wallState) return { x: x + 1, y: y }
    if (x > 0 && y < 63 && grid(x - 1, y + 1) === wallState) return { x: x - 1, y: y + 1 }
    if (y < 63 && grid(x, y + 1) === wallState) return { x: x, y: y + 1 }
    if (x < 127 && y < 63 && grid(x + 1, y + 1) === wallState) return { x: x + 1, y: y + 1 }
    return null
}

var moveBot = function(n) {
    var assignedX = (n % 4) * 32 + 14 + Math.floor(n/4) * 4
    var assignedY = (Math.floor(n / 4)) * 32 + 16
    if (Math.abs(goal.x - assignedX) < 33 && Math.abs(goal.y - assignedY) < 33) {
        assignedX = goal.x
        assignedY = goal.y
    }
    var b = bots[n], moveX = b.x !== assignedX, x = b.x, y = b.y, type
    if (moveX) {
        x += b.x < assignedX ? 1 : -1
    } else {
        y += b.y < assignedY ? 1 : -1
    }
    if (grid(x, y) === 1) {
        if (b.hasWall) {
            type = 2 //place
            var c = getNeighborCell(b.x, b.y, 0)
            if (!c) { //stuck holding wall with walls all around
                return 0
            }
            x = c.x
            y = c.y
        } else {
            type = 1 //grab
        }
    } else if (grid(x, y) === 0) {
        if (getNeighborCell(x, y, 1)) {
            type = 0 //move
        } else {
            if (b.hasWall) {
                type = 2 //place
                if (moveX) {
                    y += y > 0 ? -1 : 1
                } else {
                    x += x > 0 ? -1 : 1
                }
            } else {
                type = 1 //grab
                var c = getNeighborCell(b.x, b.y, 1)
                if (!c) { //stuck without wall in midair
                    return 0
                }
                x = c.x
                y = c.y
            }
        }
    } else {
        return 0 //should never get here
    }
    return encodeAction(type, x - b.x, y - b.y)
}

var actions = []
for (var i = 0; i < 8; i++) {
    actions[i] = moveBot(i)
}

return actions

I know this is just the start, but one thing I noticed while watching the (uneven) battle with the baseline: If the goal is within reach of multiple centers, they all run towards the goal. Might be better to only choose the closest one, and keep the others at their "ideal" position? Fun to watch, btw.

Thanks! Yes that would definitely be an improvement. There's a long list of others to think about too, and a variety of different strategies to use. I'm looking forward to seeing which strategies others choose and how they interact...

Baseline
This is the simplest consistently functioning bot flock controller I could think of. It will be my only non-disqualified answer and will serve as a baseline to judge other answers by. It is technically in the running to win the contest, but beating it should not be difficult.
Any of the code here may be copied and used in another answer, no attribution required.
var encodeAction = function(type, dx, dy) {
    var d
    if (dx === -1 && dy === -1) d = 1
    else if (dx === 0 && dy === -1) d = 2
    else if (dx === 1 && dy === -1) d = 3
    else if (dx === -1 && dy === 0) d = 4
    else if (dx === 1 && dy === 0) d = 5
    else if (dx === -1 && dy === 1) d = 6
    else if (dx === 0 && dy === 1) d = 7
    else if (dx === 1 && dy === 1) d = 8
    else return 0
    return 8 * type + d
}

var getNeighborCell = function(x, y, wallState) {
    if (x > 0 && y > 0 && grid(x - 1, y - 1) === wallState) return { x: x - 1, y: y - 1 }
    if (y > 0 && grid(x, y - 1) === wallState) return { x: x, y: y - 1 }
    if (x < 127 && y > 0 && grid(x + 1, y - 1) === wallState) return { x: x + 1, y: y - 1 }
    if (x > 0 && grid(x - 1, y) === wallState) return { x: x - 1, y: y }
    if (x < 127 && grid(x + 1, y) === wallState) return { x: x + 1, y: y }
    if (x > 0 && y < 63 && grid(x - 1, y + 1) === wallState) return { x: x - 1, y: y + 1 }
    if (y < 63 && grid(x, y + 1) === wallState) return { x: x, y: y + 1 }
    if (x < 127 && y < 63 && grid(x + 1, y + 1) === wallState) return { x: x + 1, y: y + 1 }
    return null
}

var moveBot = function(n) {
    var b = bots[n], moveX = b.x !== goal.x, x = b.x, y = b.y, type
    if (moveX) {
        x += b.x < goal.x ? 1 : -1
    } else {
        y += b.y < goal.y ? 1 : -1
    }
    if (grid(x, y) === 1) {
        if (b.hasWall) {
            type = 2 //place
            var c = getNeighborCell(b.x, b.y, 0)
            if (!c) { //stuck holding wall with walls all around
                return 0
            }
            x = c.x
            y = c.y
        } else {
            type = 1 //grab
        }
    } else if (grid(x, y) === 0) {
        if (getNeighborCell(x, y, 1)) {
            type = 0 //move
        } else {
            if (b.hasWall) {
                type = 2 //place
                if (moveX) {
                    y += y > 0 ? -1 : 1
                } else {
                    x += x > 0 ? -1 : 1
                }
            } else {
                type = 1 //grab
                var c = getNeighborCell(b.x, b.y, 1)
                if (!c) { //stuck without wall in midair
                    return 0
                }
                x = c.x
                y = c.y
            }
        }
    } else {
        return 0 //should never get here
    }
    return encodeAction(type, x - b.x, y - b.y)
}

var actions = []
for (var i = 0; i < 8; i++) {
    actions[i] = moveBot(i)
}

return actions

Each of the 8 bots independently follows the same basic method. They tend to clump together because of this, unless they get separated by something external. The bots never care about where teammates or enemies are, they only attempt to move toward the goal. They only move orthogonally, first matching their x with the goal x, then their y. Never moving diagonally means they waste a lot of time in travel.
The movement algorithm of each bot is as follows:
If my X is not equal to the goal's X
    P = position to my left or right that is closer to the goal
    Make a note that I'm trying to move horizontal
Else
    P = position above or below me that is closer to the goal
    Make a note that I'm trying to move vertical

If P is a wall
    If I'm holding a wall
        Place my wall in any neighboring air cell
    Else
        Grab the wall at P
Else if P is air
    If P has a wall neighboring it (i.e. if I can move to P)
        Move to P
    Else
        If I'm holding a wall
            If I'm trying to move horizontal
                Place my wall above or below P
            Else if I'm trying to move vertical
                Place my wall to the left or right of P
        Else
            Grab wall from any neighboring wall cell

Seekers
Stll work in progress.
I have many ideas, but almost none of them do work.
Above all, big problem with failed actions. Solved!
var action=[], myGrid=[], goalSort=[], i, j, curBot, curAction, goalSeek;

var check = function(x,y) {
  return (myGrid[[x,y]] || (myGrid[[x,y]] = grid(x,y)))|0;
};

var setGrid = function(x,y,v) {
  myGrid[[x,y]] = v + '';
};

var orGrid = function(x,y,v) {
  myGrid[[x,y]] |= v;
};

var encodeDir = function(dx, dy) {
    return dx < 0 && dy < 0 ? 1
    : dx === 0 && dy < 0 ? 2
    : dx > 0 && dy < 0 ? 3
    : dx < 0 && dy === 0 ? 4
    : dx > 0 && dy === 0 ? 5
    : dx < 0 && dy > 0 ? 6
    : dx === 0 && dy > 0 ? 7
    : dx > 0 && dy > 0 ? 8
    : 0;
};

var distance = function(p1, p2) {
  return Math.max(Math.abs(p1.x-p2.x),Math.abs(p1.y-p2.y));
};

var cellNearWall = function(x,y)
{
  var r = check(x,y) == 1 ? 0
  : check(x-1,y-1) == 1 ? 1
  : check(x,y-1) == 1 ? 2
  : check(x+1,y-1) == 1 ? 3
  : check(x-1,y) == 1 ? 4
  : check(x+1,y) == 1 ? 5
  : check(x-1,y+1) == 1 ? 6
  : check(x,y+1) == 1 ? 7
  : check(x+1,y+1) == 1 ? 8
  : 0;
  return r;
};

var cellNearBot = function(x,y,m)
{
  return check(x-1,y-1) & m ? 1
  : check(x,y-1) & m ? 2
  : check(x+1,y-1) & m ? 3
  : check(x-1,y) & m ? 4
  : check(x+1,y) & m ? 5
  : check(x-1,y+1) & m ? 6
  : check(x,y+1) & m ? 7
  : check(x+1,y+1) & m ? 8
  : 0;
};

var tryGrabWall = function(x, y)
{
  var dx, dy, r = 8;
  for(dy = -1; dy < 2; ++dy)
  {
    for(dx = -1; dx < 2; ++dx)
    {
      if (dx|dy)
      {
        ++r;
        if (check(x+dx, y+dy) == 1)
        {
          setGrid(x+dx, y+dy, 0); // remember that the wall is not there anymore
          return r;
        }
      }
    }
  }
  return 0;
};

var tryDropWall= function(x, y)
{
  var dx, dy, r = 16;
  for(dy = -1; dy < 2; ++dy)
  {
    for(dx = -1; dx < 2; ++dx)
    {
      if (dx|dy)
      {
        ++r;
        if (x+dx>=0 & x+dx < 128 & y+dy >= 0 & y+dy < 64 && check(x+dx, y+dy) == 0)
        {
          setGrid(x+dx, y+dy, 1); // remember that the wall is there
          return r;
        }
      }
    }
  }
  return 0;
};

var approach = function(bot, target)
{
  var dx, dy, tx, ty, r = 0, wallPos;

  var checkDrop = function(dx,dy)
  {
    var x = bot.x+dx, y = bot.y+dy;
    if (check(x,y) == 0 && cellNearBot(x,y,8) == 0)
    {
      setGrid(x, y, 1);
      return 16 + encodeDir(dx, dy);
    }
  };

  dy = target.y - bot.y;
  dy = dy < 0 ? -1 : dy > 0 ? 1 : 0;
  dx = target.x - bot.x;
  dx = dx < 0 ? -1 : dx > 0 ? 1 : 0;
  tx = bot.x+dx;
  ty = bot.y+dy;

  if ((dx|dy) === 0)
  {
    if (!bot.hasWall) {
      return tryGrabWall(bot.x, bot.y);
    }
    return 0;
  }

  if (cellNearWall(tx,ty))
  {
    setGrid(tx, ty, 2);
    return encodeDir(dx, dy);
  }

  if (dx === 0)
  {
    if (cellNearWall(bot.x-1,ty))
    {
      setGrid(bot.x-1, ty, 2);
      return encodeDir(-1, dy);
    }
    if (cellNearWall(bot.x+1,ty))
    {
      setGrid(bot.x+1, ty, 2);
      return encodeDir(1, dy);
    }
    if (bot.hasWall)
    {
      if (wallPos = checkDrop(1,dy)) { return wallPos; }
      if (wallPos = checkDrop(-1,dy)) { return wallPos; }
      if (wallPos = checkDrop(1,0)) { return wallPos; }
      if (wallPos = checkDrop(-1,0)) { return wallPos; }
    }
  }
  else if (dy === 0)
  {
    if (cellNearWall(tx,bot.y-1))
    {
      setGrid(tx, bot.y-1, 2);
      return encodeDir(dx, -1);
    }
    if (cellNearWall(tx,bot.y+1))
    {
      setGrid(tx, bot.y+1, 2);
      return encodeDir(dx, 1);
    }
    if (bot.hasWall)
    {
      if (wallPos = checkDrop(dx,1)) { return wallPos; }
      if (wallPos = checkDrop(dx,-1)) { return wallPos; }
      if (wallPos = checkDrop(0,1)) { return wallPos; }
      if (wallPos = checkDrop(0,-1)) { return wallPos; }
    }
  }
  else
  {
    if (cellNearWall(tx,bot.y))
    {
      setGrid(tx, bot.y, 2);
      return encodeDir(dx, 0);
    }
    if (cellNearWall(bot.x,ty))
    {
      setGrid(bot.x, ty, 2);
      return encodeDir(0,dy);
    }
    if (bot.hasWall) {
      if (wallPos = checkDrop(dx,0)) { return wallPos; }
      if (wallPos = checkDrop(0,dy)) { return wallPos; }
      if (wallPos = checkDrop(dx,dy)) { return wallPos; }
    }
  }

  if (!bot.hasWall)
  {
  if (check(tx, ty) == 1)
  {
      setGrid(tx, ty, 0); // remember that the wall is not there anymore
      return 8 + encodeDir(dx, dy);
    };
    return tryGrabWall(bot.x, bot.y);
  }
  else
  {
    return tryDropWall(bot.x, bot.y);
  }
};

for (i=0; curBot=ebots[i]; i++)
{
  setGrid(curBot.x, curBot.y, curBot.hasWall ? 4 : 8);
}

var goalDistance=[]

for (i=0; curBot=bots[i]; i++)
{
  orGrid(curBot.x, curBot.y, 2);
  goalDistance[i] = distance(curBot, goal);
}
var sorted = goalDistance.slice().sort(function(a,b){return a-b})
var ranks = goalDistance.slice().map(function(v){ return sorted.indexOf(v)});

var tt = p1
? [ { x:32, y:20 },{ x:32, y:55 },{ x:64, y:20 },{ x:64, y:55 },
   { x:96, y:20 },{ x:96, y:55 },{ x:16, y:30 },{ x:112, y:30 }]
: [ { x:96, y:20 },{ x:96, y:55 },{ x:64, y:20 },{ x:64, y:55 },
   { x:32, y:20 },{ x:32, y:55 },{ x:112, y:30 },{ x:16, y:30 }]

var goalSeek = 3;

for (i=0; curBot=bots[i]; i++)
{
  if (ranks[i] < goalSeek)
  {
    curAction = approach(curBot, goal);
    if (curAction == 0) goalSeek += 1;
  }
  else
    curAction = approach(curBot, tt[i]);

  action[i] = curAction;
}

return action;

Teamplayer
At the moment, this submission is far from perfect. It has a similar strategy like Outposts, but only 6 bots are "in the air". The other 2 bots supply them with walls if they got stolen. Edit: The supporter bots perform much better now.
var outside = function(x,y) {
    return x < 0 || x > 127 || y < 0 || y > 127
}

var distance = function(x1, y1, x2, y2){
  return Math.sqrt(Math.pow(x1-x2, 2) + Math.pow(y1-y2, 2));
}

var isStuck = function(bot) {
    if (bot.hasWall) {
        for (var i=-1; i<=1; i++) {
            for (var j=-1; j<=1; j++) {
                if ((i != 0 || j != 0) && grid(bot.x+i,bot.y+j) == 0 && !outside(bot.x+i,bot.y+j))
                    return false
            }
        }
        return true
    }
    for (var i=-1; i<=1; i++) {
        for (var j=-1; j<=1; j++) {
            if (grid(bot.x+i, bot.y+j) == 1)
                return false
        }
    }
    return true
}

var isPlayer = function(x,y) {
    for (var i = 0; i < bots.length; i++) {
        if (bots[i].x == x && bots[i].y == y)
            return true
    }
    for (var i = 0; i < ebots.length; i++) {
        if (ebots[i].x == x && ebots[i].y == y)
            return true
    }
    return false
}

var encodeAction = function(type, dx, dy) {
    var d
    if (dx === -1 && dy === -1) d = 1
    else if (dx === 0 && dy === -1) d = 2
    else if (dx === 1 && dy === -1) d = 3
    else if (dx === -1 && dy === 0) d = 4
    else if (dx === 1 && dy === 0) d = 5
    else if (dx === -1 && dy === 1) d = 6
    else if (dx === 0 && dy === 1) d = 7
    else if (dx === 1 && dy === 1) d = 8
    else return 0
    return 8 * type + d
}

var surrounding = function(x,y) {
    var cell = {hasStone:false, cells: []}
    for (var i=-1; i<=1; i++) {
        for(var j=-1; j<=1; j++) {
            if ((i != 0 || j != 0) && !outside(x+i,y+j)) {
                cell.cells.push({x:x+i, y:y+j})
                if (grid(x+i,y+j) == 1) {
                    cell.hasStone = true
                }
            }
        }
    }
    return cell
}

var hunt = function(i, destination) {
    destination = destination || {x: 31+((i-2)%3)*32, y: 20+((i-2)%2)*21}, bot = bots[i]
    if (i < 5 && i > 1) {
        destination.x -= 2
    }
    if (bot.isStuck) {
        return 0
    }
    if ((p1 && destination.x >= move + i) || (!p1 && 127 - destination.x > move - i)) {
        destination.y = bot.y
    }
    if (i == bestBotId && move > 50) {
        destination.x = goal.x
        destination.y = goal.y
    }
    var dx = destination.x > bot.x ? 1 : destination.x == bot.x ? 0 : -1, newX = bot.x + dx
    var dy = destination.y > bot.y ? 1 : destination.y == bot.y ? 0 : -1, newY = bot.y + dy
    var surr = surrounding(newX, newY), botSurr = surrounding(bot.x, bot.y)
    if (grid(newX, newY) == 0) {
        if (surr.hasStone) {
            return encodeAction(0, dx, dy)
        } else {
            if (bot.hasWall) {
                for (var i=0; i<surr.cells.length; i++) {
                    var cell = surr.cells[i];
                    if (Math.abs(cell.x - bot.x) <= 1 && Math.abs(cell.y - bot.y) <= 1 && grid(cell.x, cell.y) == 0 && !isPlayer(cell.x, cell.y)) {
                        return encodeAction(2, cell.x - bot.x, cell.y - bot.y)
                    }
                }
            } else {
                if (bot.walls.length == 1) {
                    return encodeAction(1, bot.walls[0].x - bot.x, bot.walls[0].y - bot.y)
                } else {
                    for (var i=0; i<bot.walls.length; i++) {
                        var wall = bot.walls[i], canUseWall = true
                        for (var j=0; j<bots.length; j++) {
                            if (bots[j].walls.length == 1 && bots[j].walls[0].x == wall.x && bots[j].walls[0].y == wall.y) {
                                canUseWall = false
                            }
                        }
                        if (canUseWall) {
                            return encodeAction(1, wall.x - bot.x, wall.y - bot.y)
                        }
                    }
                }
            }
        }
    } else {
        if (bot.hasWall) {
            for (var i=0; i<botSurr.cells.length; i++) {
                var cell = botSurr.cells[i];
                if (grid(cell.x, cell.y) == 0 && !isPlayer(cell.x, cell.y) && !outside(cell.x, cell.y)) {
                    return encodeAction(2, cell.x - bot.x, cell.y - bot.y)
                }
            }
        } else {
            return encodeAction(1, dx, dy)
        }
    }
    return 0 //hopefully never happens
}

var help = function(i) {
    if (bots[i].isStuck) {
        return 0
    }
    var bot = bots[i], destination = helpDestinations[i]
    if (destination.stuckBot == -1) {
        if (bot.walls.length >= 2 || (bot.hasWall && bot.walls.length == 1)) {
            var stuckId = -1
            for (var j = 0; j < bots.length; j++) {
                if (j != helpDestinations[(i+1)%2].stuckBot && bots[j].isStuck)
                    stuckId = j
            }
            if (stuckId != -1) {
                destination.stuckBot = stuckId
                destination.x = bots[stuckId].x
                destination.y = bots[stuckId].y
                return 0
            } else {
                return hunt(i, destination)
            }
        } else if (bot.x == destination.x && bot.y == destination.y) {
            if (move % 2 == 0)
                destination.y += 1
            else
                destination.x -= 1
            return hunt(i, destination)
        } else {
            return hunt(i, destination)
        }
    } else if (bots[destination.stuckBot].isStuck) {
        if (bot.walls.length < 2 && !(bot.hasWall && bot.walls.length == 1)) {
            destination.stuckBot = -1
            destination.x = i == 0 ? 42 : 85
            destination.y = 55
            return hunt(i, destination)
        }
        var dx = destination.x > bot.x ? 1 : destination.x == bot.x ? 0 : -1, newX = bot.x + dx
        var dy = destination.y > bot.y ? 1 : destination.y == bot.y ? 0 : -1, newY = bot.y + dy
        var surr = surrounding(newX, newY), botSurr = surrounding(bot.x, bot.y), surrWalls = 0
        for (var i = 0; i < surr.cells.length; i++) {
            var cell = surr.cells[i]
            if (grid(cell.x,cell.y) == 1)
                surrWalls++
        }
        if (grid(newX, newY) == 0) {
            if (surrWalls >= 2 || (surr.hasWall && bot.hasWall)) {
                return encodeAction(0, dx, dy)
            } else {
                if (bot.hasWall) {
                    for (var i=0; i<surr.cells.length; i++) {
                        var cell = surr.cells[i];
                        if (Math.abs(cell.x - bot.x) <= 1 && Math.abs(cell.y - bot.y) <= 1 && grid(cell.x, cell.y) == 0 && !isPlayer(cell.x, cell.y)) {
                            return encodeAction(2, cell.x - bot.x, cell.y - bot.y)
                        }
                    }
                } else {
                    if (bot.walls.length == 1) {
                        return encodeAction(1, bot.walls[0].x - bot.x, bot.walls[0].y - bot.y)
                    } else {
                        for (var i=0; i<bot.walls.length; i++) {
                            var wall = bot.walls[i], canUseWall = true
                            for (var j=0; j<bots.length; j++) {
                                if (bots[j].walls.length == 1 && bots[j].walls[0].x == wall.x && bots[j].walls[0].y == wall.y) {
                                    canUseWall = false
                                }
                            }
                            for (var j=0; j<surr.cells.length; j++) {
                                if (surr.cells[j].x == wall.x && surr.cells[j].y == wall.y)
                                    canUseWall = false
                            }
                            if (canUseWall) {
                                return encodeAction(1, wall.x - bot.x, wall.y - bot.y)
                            }
                        }
                    }
                }
            }
        } else {
            if (bot.hasWall) {
                for (var i=0; i<botSurr.cells.length; i++) {
                    var cell = botSurr.cells[i];
                    if (grid(cell.x, cell.y) == 0 && !isPlayer(cell.x, cell.y)) {
                        return encodeAction(2, cell.x - bot.x, cell.y - bot.y)
                    }
                }
            } else {
                return encodeAction(1, dx, dy)
            }
        }
    } else {
        destination.stuckBot = -1
        destination.x = i == 0 ? 42 : 85
        destination.y = 55
        return hunt(i, destination)
    }
    return 0 //hopefully never happens
}

var moves = new Array(8)
var mem = getMem(), helpDestinations = []
if (mem.length == 0) {
    mem = "42,55,-1 85,55,-1"
}
mem = mem.split(" ")
for (var i = 0; i < mem.length; i++) {
    var cell = mem[i].split(",")
    helpDestinations.push({x: parseInt(cell[0]), y: parseInt(cell[1]), stuckBot: parseInt(cell[2])})
}

for (var i = 0; i < 8; i++) {
    var bot = bots[i]
    var surr = surrounding(bot.x, bot.y)
    bot.walls = []
    for (var j = 0; j < surr.cells.length; j++) {
        if (grid(surr.cells[j].x, surr.cells[j].y) == 1) {
            bot.walls.push(surr.cells[j])
        }
    }
}

bots.forEach(function(bot, index) {
    if(isStuck(bot)) {
        bot.isStuck = true
    }
})

var bestDistance = 1000
var bestBotId = -1
for (var i=2; i<8; i++) {
    var dist = distance(bots[i].x, bots[i].y, goal.x, goal.y)
    if (dist < bestDistance && !bots[i].isStuck) {
        bestDistance = dist
        bestBotId = i
    }
}

for (var i=0; i<8; i++) {
    if (i < 2) {
        moves[i] = help(i)
    } else {
        moves[i] = hunt(i)
    }
}

setMem(helpDestinations[0].x + "," + helpDestinations[0].y + "," + helpDestinations[0].stuckBot + " " + helpDestinations[1].x + "," + helpDestinations[1].y + "," + helpDestinations[1].stuckBot)

return moves

The supporter idea (nice) seems difficult to implement.

@edc65 It is basically just moving with 2 walls instead of one. But the communication between the two support bots and finding new walls was rather hard to implement :)