title: Expand a C array

text:
# Question
Title: Expand a C array
In the C programming language, arrays are defined like this:

```
int foo[] = {4, 8, 15, 16, 23, 42};      //Foo implicitly has a size of 6

```

The size of the array is inferred from the initializing elements, which in this case is 6. You can also write a C array this way, explicitly sizing it then defining each element in order:

```
int foo[6];        //Give the array an explicit size of 6
foo[0] = 4;
foo[1] = 8;
foo[2] = 15;
foo[3] = 16;
foo[4] = 23;
foo[5] = 42;

```

# The challenge

You must write a program or function that expands arrays from the first way to the second. Since you are writing a program to make code longer, and you love irony, you must make your code as short as possible.

The input will be a string representing the original array, and the output will be the expanded array-definition. You can safely assume that the input will always look like this:

```
<type> <array_name>[] = {<int>, <int>, <int> ... };

```

"Type" and "array\_name" will made up entirely of alphabet characters and underscores `_`. The elements of the list will always be a number in the range -2,147,483,648 to 2,147,483,647. Inputs in any other format do not need to be handled.

The whitespace in your output must exactly match the whitespace in the test output, although a trailing newline is allowed.

# Test IO:

```
#in
short array[] = {4, 3, 2, 1};

#out
short array[4];
array[0] = 4;
array[1] = 3;
array[2] = 2;
array[3] = 1;

#in
spam EGGS[] = {42};

#out
spam EGGS[1];
EGGS[0] = 42;

#in
terrible_long_type_name awful_array_name[] = {7, -8, 1337, 0, 13};

#out
terrible_long_type_name awful_array_name[5];
awful_array_name[0] = 7;
awful_array_name[1] = -8;
awful_array_name[2] = 1337;
awful_array_name[3] = 0;
awful_array_name[4] = 13;

```

Submissions in any language are encouraged, but bonus points if you can do it *in* C.

# Leaderboard:

Here is a leaderboard showing the top answers:

```
var QUESTION_ID=77857,OVERRIDE_USER=31716;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
```

```
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
```

```
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>
```

# Answer
> 12 votes
# Pyth, 44 bytes

```
++Khcz\]lJ:z"-?\d+"1"];"VJs[ecKd~hZ"] = "N\;

```

Test suite

Regular expression and string chopping. Not particularly clever.

Explanation:

```
++Khcz\]lJ:z"-?\d+"1"];"VJs[ecKd~hZ"] = "N\;
                                                Implicit: z = input()
    cz\]                                        Chop z on ']'
   h                                            Take string before the ']'
  K                                             Store it in K
 +                                              Add to that
         :z"-?\d+"1                             Find all numbers in the input
        J                                       Store them in J
       l                                        Take its length.
+                  "];"                         Add on "];" and print.
                       VJ                       For N in J:
                         s[                     Print the following, concatenated:
                            cKd                 Chop K on spaces.
                           e                    Take the last piece (array name)
                               ~hZ              The current interation number
                                  "] = "        That string
                                        N       The number from the input
                                         \;     And the trailing semicolon.

```

# Answer
> 28 votes
# Vim, ~~54, 52, 49~~ 47 keystrokes

---

```
2wa0<esc>qqYp<c-a>6ldf @qq@q$dT]dd:%norm dwf{xwC;<CR>gg"0P

```

Explanation:

```
2wa0<esc>                     'Move 2 words forward, and insert a 0.
         qq                   'Start recording in register Q
           Yp                 'Duplicate the line
             <c-a>6l          'Increment the next number then move 6 spaces right
                    df        'Delete until the next space
                       @qq@q  'Recursively call this macro

```

Now our buffer looks like this:

```
int foo[0] = {4, 8, 15, 16, 23, 42};
int foo[1] = {8, 15, 16, 23, 42};
int foo[2] = {15, 16, 23, 42};
int foo[3] = {16, 23, 42};
int foo[4] = {23, 42};
int foo[5] = {42};
int foo[6] = {42};

```

and our cursor is on the last line.

Second half:

```
$                           'Move to the end of the line
 dT]                        'Delete back until we hit a ']'
    dd                      'Delete this whole line.
      :%norm         <CR>   'Apply the following keystrokes to every line:
             dw             'Delete a word (in this case "int")
               f{x          '(f)ind the next '{', then delete it.
                  wC;       'Move a word, then (C)hange to the end of this line,
                            'and enter a ';'

```

Now everything looks good, we just need to add the original array-declaration. So we do:

```
gg        'Move to line one
  "0P     'Print buffer '0' behind us. Buffer '0' always holds the last deleted line,
          'Which in this case is "int foo[6];"

```

# Answer
> 10 votes
# Retina, ~~108~~ ~~104~~ ~~100~~ 69 bytes

Byte count assumes ISO 8859-1 encoding.

```
].+{((\S+ ?)+)
$#2];$1
+`((\w+\[).+;(\S+ )*)(-?\d+).+
$1¶$2$#3] = $4;

```

Beat this, PowerShell...

## Code explanation

**First line:** `].+{((\S+ ?)+)`

First, we need to keep the type, array name, and opening bracket (it saves a byte), so we don't match them. So we match the closing bracket, any number of characters, and an opening curly brace: `].+{`. Then we match the number list. Shortest I've been able to find so far is this: `((\S+ ?)+)`. We match any number of non-space characters (this includes numbers, possible negative sign, and possible comma), followed by a space, that may or may not be there: `\S+ ?`. This group of characters is then repeated as many times as needed: `(\S+ ?)+` and put into the large capturing group. Note that we don't match the closing curly brace or semicolon. Third line explanation tells why.

**Second line:** `$#2];$1`

Since we only matched a part of input, the unmatched parts will still be there. So we put the length of the list after the unmatched opening bracket: `$#2`. The replace modifier `#` helps us with that, as it gives us the number of matches a particular capturing group made. In this case capturing group `2`. Then we put a closing bracket and a semicolon, and finally our whole list.

With input `short array[] = {4, 3, 2, 1};`, the internal representation after this replacing is:

```
short array[4];4, 3, 2, 1};
```

(note the closing curly brace and semicolon)

**Third line:** `+`((\w+[).+;(\S+ )*)(-?\d+).+`

This is a looped section. That means it runs until no stage in the loop makes a change to the input. First we match the array name, followed by an opening bracket: `(\w+\[)`. Then an arbitrary number of any characters and a semicolon: `.+;`. Then we match the list again, but this time only numbers and the comma after each number, which have a space following them: `(\S+ )*`. Then we capture the last number in the list: `(-?\d+)` and any remaining characters behind it: `.+`.

**Fourth line:** `$1¶$2$#3] = $4;`

We then replace it with the array name and list followed by a newline: `$1¶`. Next, we put the array name, followed by the length of previously matched list, without the last element (essentially `list.length - 1`): `$2$#3`. Followed by a closing bracket and assigment operator with spaces, and this followed by the last element of our number list: `] = $4;`

After first replacing, the internal representation looks like this:

```
short array[4];4, 3, 2,
array[3] = 1;

```

Note that the closing curly brace and the semicolon disappeared, thanks to the `.+` at the end of third line. After three more replacings, the internal representation looks like this:

```
short array[4];
array[0] = 4;
array[1] = 3;
array[2] = 2;
array[3] = 1;

```

Since there's nothing more to match by third line, fourth doesn't replace anything and the string is returned.

**TL;DR:** First we change up the int list format a bit. Then we take the last element of the list and the name, and put them after the array initialization. We do this until the int list is empty. Then we give the changed code back.

Try it online!

# Answer
> 8 votes
# C, 215 bytes, 196 bytes

*19 bytes saved thanks to @tucuxi!*

**Golfed:**

```
char i[99],o[999],b[99],z[99];t,x,n,c;main(){gets(i);sscanf(i,"%s %[^[]s",b,z);while(sscanf(i+t,"%*[^0-9]%d%n",&x,&n)==1)sprintf(o,"%s[%d] = %d;\n",z,c++,x),t+=n;printf("%s %s[%d];\n%s",b,z,c,o);}

```

**Ungolfed:**

```
/*
 *  Global strings:
 *   i: input string
 *   o: output string
 *   b: input array type
 *   z: input array name
*/
char i[ 99 ], o[ 999 ], b[ 99 ], z[ 99 ];

/* Global ints initialized to zeros */
t, x, n, c;

main()
{
    /* Grab input string from stdin, store into i */
    gets( i );

    /* Grab the <type> <array_name> and store into b and z */
    sscanf( i, "%s %[^[]s", b, z );

    /* Grab only the int values and concatenate to output string */
    while( sscanf( i + t, "%*[^0-9]%d%n", &x, &n ) == 1 )
    {
        /* Format the string and store into a */
        sprintf( o, "%s[%d] = %d;\n", z, c++, x );

        /* Get the current location of the pointer */
        t += n;
    }

    /* Print the <type> <array_name>[<size>]; and output string */
    printf( "%s %s[%d];\n%s", b, z, c, o );
}

```

**Link:**

http://ideone.com/h81XbI

**Explanation:**

To get the `<type> <array_name>`, the `sscanf()` format string is this:

```
%s          A string delimited by a space
    %[^[]   The character set that contains anything but a `[` symbol
         s  A string of that character set

```

To extract the int values from the string `int foo[] = {4, 8, 15, 16, 23, 42};`, I essentially tokenize the string with this function:

```
while( sscanf( i + t, "%*[^0-9]%d%n", &x, &n ) == 1 )

```

where:

* `i` is the input string (a `char*`)
* `t` is the pointer location offset of `i`
* `x` is the actual `int` parsed from the string
* `n` is the total characters consumed, including the found digit

The `sscanf()` format string means this:

```
%*            Ignore the following, which is..
  [^0-9]      ..anything that isn't a digit
        %d    Read and store the digit found
          %n  Store the number of characters consumed

```

If you visualize the input string as a char array:

```
int foo[] = {4, 8, 15, 16, 23, 42};
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
00000000001111111111222222222233333
01234567890123456789012345678901234

```

with the `int` `4` being located at index 13, `8` at index 16, and so on, this is what the result of each run in the loop looks like:

```
Run 1)  String: "int foo[] = {4, 8, 15, 16, 23, 42};"
        Starting string pointer: str[ 0 ]
        Num chars consumed until after found digit: 14
        Digit that was found: 4
        Ending string pointer: str[ 14 ]

Run 2)  String: ", 8, 15, 16, 23, 42};"
        Starting string pointer: str[ 14 ]
        Num chars consumed until after found digit: 3
        Digit that was found: 8
        Ending string pointer: str[ 17 ]

Run 3)  String: ", 15, 16, 23, 42};"
        Starting string pointer: str[ 17 ]
        Num chars consumed until after found digit: 4
        Digit that was found: 15
        Ending string pointer: str[ 21 ]

Run 4)  String: ", 16, 23, 42};"
        Starting string pointer: str[ 21 ]
        Num chars consumed until after found digit: 4
        Digit that was found: 16
        Ending string pointer: str[ 25 ]

Run 5)  String: ", 23, 42};"
        Starting string pointer: str[ 25 ]
        Num chars consumed until after found digit: 4
        Digit that was found: 23
        Ending string pointer: str[ 29 ]

Run 6)  String: ", 42};"
        Starting string pointer: str[ 29 ]
        Num chars consumed until after found digit: 4
        Digit that was found: 42
        Ending string pointer: str[ 33 ]

```

# Answer
> 8 votes
# V, 37 Bytes

```
2Eé0òYp6ldf ò$dT]ddÎdwf{xwC;
gg"1P

```

V is a 2D, string based golfing language that I wrote, designed off of vim. This works as of commit 17.

Explanation:

This is pretty much a direct translation of my vim answer, albeit significantly shorter.

```
2E                               "Move to the end of 2 words forward.
  é0                             "Insert a single '0'
    ò       ò                    "Recursively do:
     Yp6ldf                      "Yank, paste, move 6 right, delete until space.
             $dT]                "Move to the end of line, delete backwards until ']'
                 dd              "Delete this line
                   Î             "Apply the following to every line:
                    dwf{xwC;<\n> "Delete word, move to '{' and delete it, Change to end of line, and enter ';'

```

Then we just have:

```
gg"1P     "Move to line 1, and paste buffer '1' behind us.

```

Since this unicode madness can be hard to enter, you can create the file with this reversible hexdump:

```
00000000: 3245 e930 f259 7001 366c 6466 20f2 2464  2E.0.Yp.6ldf .$d
00000010: 545d 6464 ce64 7766 7b78 7743 3b0d 6767  T]dd.dwf{xwC;.gg
00000020: 2231 500a                                "1P.

```

This can be run by installing V and typing:

```
python main.py c_array.v --f=file_with_original_text.txt

```

# Answer
> 7 votes
# C, ~~195~~ 180 bytes

195-byte original:

golfed:

```
char*a,*b,*c,*d;j;main(i){scanf("%ms %m[^]]%m[^;]",&a,&b,&c);
for(d=c;*d++;i+=*d==44);printf("%s %s%d];\n",a,b,i);
for(d=strtok(c,"] =,{}");j<i;j++,d=strtok(0," ,}"))printf("%s%d] = %s;\n",b,j,d);}

```

ungolfed:

```
char*a,*b,*c,*d;
j;
main(i){
    scanf("%ms %m[^]]%m[^;]",&a,&b,&c); // m-modifier does its own mallocs
    for(d=c;*d++;i+=*d==44);            // count commas
    printf("%s %s%d];\n",a,b,i);        // first line
    for(d=strtok(c,"] =,{}");j<i;j++,d=strtok(0," ,}"))
        printf("%s%d] = %s;\n",b,j,d);  // each array value
}

```

The two shortcuts are using the `m` modifier to to get scanf's `%s` to allocate its own memory (saves declaring char arrays), and using `strtok` (which is also available by default, without includes) to do the number-parsing part.

---

180-byte update:

```
char*a,*b,*c,e[999];i;main(){scanf("%ms %m[^]]%m[^}]",&a,&b,&c);
for(c=strtok(c,"] =,{}");sprintf(e,"%s%s%d] = %s;\n",e,b,i++,c),
c=strtok(0," ,"););printf("%s %s%d];\n%s",a,b,i,e);}

```

ungolfed:

```
char*a,*b,*c,e[999];
i;
main(){
    scanf("%ms %m[^]]%m[^}]",&a,&b,&c);
    for(c=strtok(c,"] =,{}");sprintf(e,"%s%s%d] = %s;\n",e,b,i++,c),c=strtok(0," ,"););
    printf("%s %s%d];\n%s",a,b,i,e);
}

```

Uses bnf679's idea of appending to a string to avoid having to count commas.

# Answer
> 6 votes
## Python 3.6 (pre-release), 133

```
m,p=str.split,print;y,u=m(input(),'[');t,n=m(y);i=m(u[5:-2],', ')
l=len(i);p(t,n+f'[{l}];')
for x in range(l):p(n+f'[{x}] = {i[x]};')

```

Makes heavy use of f-strings.

Ungolfed version:

```
y, u = input().split('[')
t, n = y.split()
i = u[5:-2].split(', ')
l = len(i)
print(t, n + f'[{l}];')
for x in range(l):
    print(n + f'[{x}] = {i[x]};')

```

# Answer
> 5 votes
# Ruby, ~~127~~ ~~110~~ ~~108~~ ~~99~~ 88 bytes

~~Anonymous function with a single argument as input.~~ Full program, reads the input from STDIN. (If you pipe a file in, the trailing newline is optional.) ~~Returns~~ Prints the output string.

Took @TimmyD bragging about their solution beating all other non-esolangs as a challenge, and finally overcome the (at the time of writing) 114 byte Powershell solution they had posted. ~~Cᴏɴᴏʀ O'Bʀɪᴇɴ's trick with splitting on `]` and splicing the second half to get the numbers helped.~~

I need to use the splat operator more. It's so useful!

Borrowed a trick from @Neil's JavaScript ES6 answer to save more bytes by scanning for words instead of using `gsub` and `split`..

```
t,n,*l=gets.scan /-?\w+/;i=-1
puts t+" #{n}[#{l.size}];",l.map{|e|n+"[#{i+=1}] = #{e};"}

```

# Answer
> 4 votes
# Pyth - ~~53~~ ~~50~~ ~~46~~ ~~45~~ 44 bytes

*2 bytes saved thanks to @FryAmTheEggman.*

```
+Jhcz\[+`]lKcPecz\{d\;j.es[ecJd`]kd\=dPb\;)K

```

Test Suite.

# Answer
> 4 votes
# 05AB1E, ~~52~~ ~~50~~ 47 bytes

Code:

```
… = ¡`¦¨¨ð-',¡©gr¨s«„];«,®v¹ð¡¦¬s\¨N"] = "y';J,

```

Uses **CP-1252** encoding. Try it online!.

# Answer
> 4 votes
## PowerShell v2+, ~~114~~ 105 bytes

```
$a,$b,$c,$d=-split$args-replace'\[]';"$a $b[$(($d=-join$d|iex|iex).length)];";$d|%{"$b[$(($i++))] = $_;"}

```

Takes input string `$args` and `-replace`s the square bracket with nothing, then performs a `-split` on whitespace. We store the first bit into `$a`, the second bit into `$b`, the `=` into `$c`, and the array elements into `$d`. For the example below, this stores `foo` into `$a` and `bar` into `$b`, and all of the array into `$d`.

We then output our first line with `"$a ..."` and in the middle transform `$d` from a an array of strings of form `{1,`,`2,`,...`100};` to a regular int array by `-join`ing it together into one string, then running it through `iex` twice (similar to `eval`). We store that resultant array back in `$d` before calling the `.length` method to populate the appropriate number in between the `[]` in the output line.

We then send `$d` through a loop with `|%{...}`. Each iteration we output `"$b..."` with a counter variable `$i` encapsulated in brackets and the current value `$_`. The `$i` variable starts uninitialized (equivalent to `$null`) but the `++` will cast it to an `int` before the output, so it will start output at `0`, all before incrementing `$i` for the next loop iteration.

All output lines are left on the pipeline, and output to the terminal is implicit at program termination.

### Example

```
PS C:\Tools\Scripts\golfing> .\expand-a-c-array.ps1 "foo bar[] = {1, 2, 3, -99, 100};"
foo bar[5];
bar[0] = 1;
bar[1] = 2;
bar[2] = 3;
bar[3] = -99;
bar[4] = 100;

```

# Answer
> 4 votes
## JavaScript (ES6), 100 bytes

```
(s,[t,n,...m]=s.match(/-?\w+/g))=>t+` ${n}[${m.length}];`+m.map((v,i)=>`
${n}[${i}] = ${v};`).join``

```

Since only the words are important, this works by just matching all the words in the original string, plus leading minus signs, then building the result. (I originally thought I was going to use `replace` but that turned out to be a red herring.)

# Answer
> 4 votes
# Pip, ~~48~~ 47 bytes

```
qR`(\S+)(. = ).(.+)}`{[b#Yd^k']';.n.b.,#y.c.y]}

```

Takes input from stdin and prints to stdout.

### Explanation

**Tl;dr:** Does a regex replacement, using capture groups and a callback function to construct the result.

The `q` special variable reads a line of input. The regex is `(\S+)(. = ).(.+)}`, which matches everything except the type (including trailing space) and the final semicolon. Using the first example from the question, the capturing groups get `foo[`, `] =` , and `4, 8, 15, 16, 23, 42`.

The replacement is the return value of the unnamed function `{[b#Yd^k']';.n.b.,#y.c.y]}`, which is called with the whole match plus the capturing groups as arguments. Thus, within the function, `b` gets capture group 1, `c` gets group 2, and `d` gets group 3.

We construct a list, the first three items of which will be `"foo["`, `6`, and `"]"`. To get the `6`, we split `d` on the built-in variable `k` = `", "`, `Y`ank the resulting list of integers into the `y` variable for future use, and take the length (`#`). `']` is a character literal.

What remains is to construct a series of strings of the form `";\nfoo[i] = x"`. To do so, we concatenate the following: `';`, `n` (a built-in for newline), `b` (1st capture group), `,#y` (equivalent to Python `range(len(y))`), `c` (2nd capture group), and `y`. Concatenation works itemwise on lists and ranges, so the result is a list of strings. Putting it all together, the return value of the function will be a list such as this:

```
["foo[" 6 "]"
 [";" n "foo[" 0 "] = " 4]
 [";" n "foo[" 1 "] = " 8]
 [";" n "foo[" 2 "] = " 15]
 [";" n "foo[" 3 "] = " 16]
 [";" n "foo[" 4 "] = " 23]
 [";" n "foo[" 5 "] = " 42]
]

```

Since this list is being used in a string `R`eplacement, it is implicitly cast to a string. The default list-to-string conversion in Pip is concatenating all the elements:

```
"foo[6];
foo[0] = 4;
foo[1] = 5;
foo[2] = 15;
foo[3] = 16;
foo[4] = 23;
foo[5] = 42"

```

Finally, the result (including the type and the final semicolon, which weren't matched by the regex and thus remain unchanged) is auto-printed.

# Answer
> 4 votes
## Perl 5.10, 73 72 68 66 + 1 (for -n switch) = 67 bytes

```
perl -nE '($t,$n,@a)=/[-[\w]+/g;say"$t $n".@a."];";say$n,$i++,"] = $_;"for@a'

```

This is a nice challenge for Perl and the shortest among general-purpose languages so far. Equivalent to

```
($t, $n, @a) = /[-[\w]+/g;
say "$t $n" . @a . "];";
say $n, $i++, "] = $_;" for @a;

```

# Answer
> 3 votes
## C,~~278~~ 280 bytes

golfed:

```
x,e,l,d;char *m,*r,*a;char i[999];c(x){return isdigit(x)||x==45;}main(){gets(i);m=r=&i;while(*r++!=32);a=r;while(*++r!=93);l=r-a;d=r-m;for(;*r++;*r==44?e++:1);printf("%.*s%d];\n",d,m,e+1);r=&i;while(*r++){if(c(*r)){m=r;while(c(*++r));printf("%.*s%d] = %.*s;\n",l,a,x++,r-m,m);}}}

```

ungolfed:

```
/* global ints
 * x = generic counter
 * e = number of elements
 * l = length of the array type
 * d = array defination upto the first '['
 */
x,e,l,d;
/* global pointers
 * m = memory pointer
 * r = memory reference / index
 * a = pointer to the start of the array type string
 */
char *m,*r,*a;
/* data storage for stdin */
char i[999];
c(x){return isdigit(x)||x=='-';}
main(){
    gets(i);
    m=r=&i;
    while(*r++!=32);                // skip first space
    a=r;
    while(*++r!=93);                // skip to ']'
    l=r-a;
    d=r-m;
    for(;*r++;*r==44?e++:1);        // count elements
    printf("%.*s%d];\n",d,m,e+1);   // print array define
    r=&i;
    while(*r++) {                   // print elements
        if(c(*r)) {                 // is char a - or a digit?
            m=r;
            while(c(*++r));         // count -/digit chars
            printf("%.*s%d] = %.*s;\n",l,a,x++,r-m,m);
        }
    }
}

```

While working on this someones posted a shorter version using sscanf for the parsing rather than using data pointers... nice one!

UPDATE: Spotted missing spaces around the equals in the element printing, IDE online link: http://ideone.com/KrgRt0 . Note this implementation does support negative numbers...

# Answer
> 2 votes
# Julia, ~~154~~ ~~134~~ 101 bytes

```
f(s,c=matchall(r"-?\w+",s),n=endof(c)-2)=c[]" "c[2]"[$n];
"join([c[2]"[$i] = "c[i+3]";
"for i=0:n-1])

```

This is a function that accepts a string and returns a string with a single trailing newline.

Ungolfed:

```
function f(s, c = matchall(r"-?\w+", s), n = endof(c) - 2)
    c[] " " c[2] "[$n];\n" join([c[2] "[$i] = " x[i+3] ";\n" for i = 0:n-1])
end

```

We define `c` to be an array of matches of the input on the regular expression `-?\w+`. It caputres the type, array name, then each value. We store `n` as the length of `c` \- 2, which is the number of values. The output is constructed as the type, name and length string interpolated, combined with each definition line separated by newlines. For whatever reason, `c[]` is the same as `c[1]`.

Saved 32 bytes with help from Dennis!

# Answer
> 2 votes
# JavaScript ES6, ~~134~~ ~~132~~ ~~130~~ 129 bytes

Saved 1 byte thanks to Neil.

```
x=>(m=x.match(/(\w+) (\w+).+{(.+)}/),m[1]+` `+(q=m[2])+`[${q.length-1}];
`+m[3].split`, `.map((t,i)=>q+`[${i}] = ${t};`).join`
`)

```

# Answer
> 2 votes
# Awk, 101 bytes

```
{FS="[^[:alnum:]_-]+";printf"%s %s[%d];\n",$1,$2,NF-3;for(i=3;i<NF;i++)printf$2"[%d] = %d;\n",i-3,$i}

```

More readably:

```
{
FS="[^[:alnum:]_-]+"
printf "%s %s[%d];\n", $1, $2, NF - 3
for (i=3; i < NF; i++)
    printf $2"[%d] = %d;\n", i-3, $i
}

```
* I set the field separator to everything except alphabets, digits, the underscore and `-`. So, the fields would be the type name, the variable name, and the numbers.
* The number of fields will be 1 (for the type) + 1 (for the name) + N (numbers) + 1 (an empty field after the trailing `};`). So, the size of the array is `NF - 3`.
* Then it's just printing a special line for the declaration, and looping over the numbers.
* I *should* assign `FS` either when invoking awk (using `-F`) or in a `BEGIN` block. In the interests of brevity, ….

# Answer
> 2 votes
# D, 197, 188 bytes

```
import std.array,std.stdio;void main(){string t,n,e;readf("%s %s] = {%s}",&t,&n,&e);auto v=e.replace(",","").split;writeln(t,' ',n,v.length,"];");foreach(i,c;v)writeln(n,i,"] = ",c,";");}

```

or ungolfed:

```
import std.array, std.stdio;

void main() {
    string type, nameAndBracket, elems;
    readf("%s %s] = {%s}", &type, &nameAndBracket, &elems);

    // remove all commas before splitting the string into substrings
    auto vector = elems.replace(",","").split();

    // writeln is shorter than fln by 1 char when filled in
    writeln(type, ' ', nameAndBracket, vector.length, "];");

    // print each element being assigned
    foreach(index, content; vector)
        writeln(nameAndBraket, index, "] = ", content, ";");
}

```

# Answer
> 2 votes
## bash, ~~133~~ 129 bytes

```
read -a l
d="${l[@]:0:2}"
e=("${l[@]:3}")
echo "${d%?}${#e[@]}];"
for i in "${!e[@]}"
{
echo "${l[0]}[$i] = ${e[$i]//[!0-9]/};"
}

```

First attempt, sure its posible to get it shorter.

# Answer
> 1 votes
## Python 2, 159 bytes

```
s=input().split()
t,n,v=s[0],s[1][:-2],''.join(s[3:])
a=v[1:-2].split(',')
print'%s %s[%d];'%(t,n,len(a))
for i in range(len(a)):print'%s[%d] = %s;'%(n,i,a[i])

```

Try it online

Thanks Kevin Lau for some golfing suggestions

# Answer
> 1 votes
## Python 3, 116 bytes

```
t,v,_,*l=input().split();v=v[:-1]+'%s]'
print(t,v%len(l)+';');i=0
for x in l:print(v%i,'= %s;'%x.strip('{,};'));i+=1

```

Splits the input into the type, name, and the list of numbers. After printing the array declaring, prints the elements by manually enumerating through the numbers, removing excess punctuation that attached to the first and last one.

A different approach in Python 2 came out to 122 bytes:

```
a,b=input()[:-2].split('] = {')
l=eval(b+',')
print a+`len(l)`+"];"
for y in enumerate(l):print a.split()[1]+'%s] = %s;'%y

```

The idea is to `eval` the list of numbers as a tuple, with a comma at the end so that a single number is recognized as a type. The enumerated list of numbers provides tuples to string-format in.

# Answer
> 1 votes
## PHP, 143 bytes

**Golfed**

```
<?$t=count($n=explode(' ',preg_replace('/[^\s\w]/','',$argv[1])))-3;echo"$n[0] {$n[1]}[$t];";for($i=2;$t>$j=++$i-3;)echo$n[1]."[$j] = $n[$i];";

```

**Ungolfed**

```
<?
$t = count(                                  // Get the number of elements for our array...
    $n = explode(' ',                            // After split the input on whitespace...
    preg_replace('/[^\s\w]/','',$argv[1])))-3;  // After removing all special characters.
echo "$n[0] {$n[1]}[$t];";                     // First line is type, name, and count.
for($i=2;                                        // Loop through array elements
    $t > $j = ++$i-3;)                         // Assign j to be the actual index for our new array
    echo $n[1]."[$j] = $n[$i];";                // Print each line

```

Input is taken through command line argument. Sample:

```
C:\(filepath)>php Expand.php "int foo[] = {4,8,15,16,23,42};"

```

Output:

```
int foo[6];foo[0] = 4;foo[1] = 8;foo[2] = 15;foo[3] = 16;foo[4] = 23;foo[5] = 42;

```

# Answer
> 0 votes
# MATL, ~~68~~ ~~64~~ 58 bytes

```
'\w+'XX2:H#)XKxXIZc'['KnV'];'v!K"I2X)'['X@qV'] = '@g';'6$h

```

This isn't C, ~~but it does use C-like `sprintf` function~~ Nah, that was wasting 4 bytes.

**Try it online!**

```
          % Take input implicitly
'\w+'XX   % Find substrings that match regex '\w+'. Gives a cell array
2:H#)     % Split into a subarray with the first two substrings (type and name), and
          % another with the rest (numbers that form the array)
XKx       % Copy the latter (numbers) into clipboard K. Delete it
XI        % Copy the former (type and name) into clipboard I
Zc        % Join the first two substrings with a space
'['       % Push this string
K         % Paste array of numbers
nV        % Get its length. Convert to string
'];'      % Push this string
v!        % Concatenate all strings up to now. Gives first line of the output
K"        % For each number in the array
  I2X)    %   Get name of array as a string
  '['     %   Push this string
  X@qV    %   Current iteration index, starting at 0, as a string
  '] = '  %   Push this string
  @g      %   Current number of the array, as a string
  ';'     %   Push this string
  5$h     %   Concatenate top 6 strings. This is a line of the output
          % Implicity end for each
          % Implicitly display

```

# Answer
> 0 votes
## Clojure, 115 bytes

```
#(let[[t n & v](re-seq #"-?\w+"%)](apply str t" "n\[(count v)"];\n"(map(fn[i v](str n"["i"] = "v";\n"))(range)v))))

```

I wasn't able to nicely merge `awful_array_name[5];` and `awful_array_name[0] = 7;` parts so that they'd re-use code :/

---
Tags: code-golf, string, parsing, c
---


title: ASCII Jigsaw Puzzle

text:
# Question
Title: ASCII Jigsaw Puzzle
This is a `3x3` ASCII jigsaw puzzle:

```
 _____ _____ _____
|    _|     |_    |
|   (_   _   _)   |
|_   _|_( )_|_   _|
| (_) |_   _| (_) |
|  _   _) (_   _  |
|_( )_|_   _|_( )_|
|    _| (_) |_    |
|   (_       _)   |
|_____|_____|_____|

```

This is also a `3x3` ASCII jigsaw puzzle:

```
 _____ _____ _____
|     |_   _|     |
|  _   _) (_   _  |
|_( )_|_   _|_( )_|
|    _| (_) |_    |
|   (_   _   _)   |
|_   _|_( )_|_   _|
| (_) |_   _| (_) |
|      _) (_      |
|_____|_____|_____|

```

Each line in a ASCII jigsaw puzzle (excluding the edge cases i.e. the pieces literally on the edges) consists of the following pattern:

```
   _           _           _
 _( )_ _   _ _( )_ _   _ _( )_
|_   _| (_) |_   _| (_) |_   _|
 _) (_   _   _) (_   _   _) (_
|_   _|_( )_|_   _|_( )_|_   _| ...
  (_)         (_)         (_)

```

Given 2 integers `H` and `W` where `H` is the height (vertical amount) and `W` is the width (horizontal amount) and `H` and `W` are `>1` output a possible `HxW` ASCII jigsaw puzzle.

# Examples

## Test Case 1

Input: `2, 4`

Output:

```
 _____ _____ _____ _____
|     |_   _|     |_    |
|  _   _) (_   _   _)   |
|_( )_|_   _|_( )_|_   _|
|    _| (_) |_   _| (_) |
|   (_       _) (_      |
|_____|_____|_____|_____|

```

## Test Case 2

Input: `4, 4`

Output:

```
 _____ _____ _____ _____
|     |_   _|     |_    |
|  _   _) (_   _   _)   |
|_( )_|_   _|_( )_|_   _|
|    _| (_) |_   _| (_) |
|   (_   _   _) (_   _  |
|_   _|_( )_|_   _|_( )_|
| (_) |_   _| (_) |_    |
|  _   _) (_   _   _)   |
|_( )_|_   _|_( )_|_   _|
|    _| (_) |_   _| (_) |
|   (_       _) (_      |
|_____|_____|_____|_____|

```

## Test Case 3

Input: `3, 5`

Output:

```
 _____ _____ _____ _____ _____
|     |_   _|     |_   _|     |
|  _   _) (_   _   _) (_   _  |
|_( )_|_   _|_( )_|_   _|_( )_|
|    _| (_) |_   _| (_) |_    |
|   (_   _   _) (_   _   _)   |
|_   _|_( )_|_   _|_( )_|_   _|
| (_) |_   _| (_) |_   _| (_) |
|      _) (_       _) (_      |
|_____|_____|_____|_____|_____|

```

## Test Case 4

Input: `2, 2`

Output:

```
 _____ _____
|    _|     |
|   (_   _  |
|_   _|_( )_|
| (_) |_    |
|      _)   |
|_____|_____|

```

# Clarifications

* The height and width for each puzzle piece should not be scaled up or down.
* With `H` and `W` being greater than one, the smallest dimensions possible are `2x2` (see IO 4).
* You can have a full program or a function.
* The input will be 2 lines with `H` on the 1st and `W` on the 2nd if you're using a function you can have them in the parameters.
* Output to stdout (or something similar).
* This is code-golf so shortest answer in bytes wins.

# Answer
# JavaScript (ES6) 272 ~~277 271~~

*Edit* bug fix

*Edit 2* saved 6 bytes thx @L.Serné

*Edit 3* bug fix again

```
(w,h,z=(s,q=3,i=h)=>'|  '.slice(0,q)+s.repeat(w).substr(i%2*6+q,w*6-q-~-q)+`  |
`.slice(~q))=>eval("t=z(' _____',0,0)+z('|_   _|     ',2,--h)+z(b=' _) (_   _  ')+z(c='|_   _|_( )_',0);for(a='|_   _| (_) ';--h;)t+=z(a,2)+z(b)+z(c,0)")+z(a,2)+z(' _) (_      ')+z('|_____',1)

```

*Less golfed*

```
(w,h,
  z=(s,q=3,i=h)=>'|  '.slice(0,q)+s.repeat(w).substr(i%2*6+q,w*6-q-~-q)+'  |\n'.slice(~q),
  a='|_   _| (_) ',
  b=' _) (_   _  ',
  c='|_   _|_( )_',
  t=z(' _____',0,0)+z('|_   _|     ',2,--h)+z(b)+z(c,0)
)=>{
  for(;--h;)
    t+=z(a,2)+z(b)+z(c,0);
  return t+z(a,2)+z(' _) (_      ')+z('|_____',1)
}

```

**Test**

```
F=
(w,h,z=(s,q=3,i=h)=>'|  '.slice(0,q)+s.repeat(w).substr(i%2*6+q,w*6-q-~-q)+`  |
`.slice(~q))=>eval("t=z(' _____',0,0)+z('|_   _|     ',2,--h)+z(b=' _) (_   _  ')+z(c='|_   _|_( )_',0);for(a='|_   _| (_) ';--h;)t+=z(a,2)+z(b)+z(c,0)")+z(a,2)+z(' _) (_      ')+z('|_____',1)

function update() {
  var w=+W.value,h=+H.value
  O.textContent=F(w,h)
}

update()
```

```
W<input id=W value=2 oninput='update()' type=number min=2>
H<input id=H value=2 oninput='update()' type=number min=2>
<pre id=O></pre>
```
> 6 votes

# Answer
# Python, 513 bytes

```
def r(m,n):
 r=3*m
 c=6*n
 l=3-(n%2)*3
 z=[1,2,3,4,5,0]
 p=zip
 return"\n".join("".join(" |_()"[[[((j%6,i%3)in[(1,0),(5,0)])*2or((j%6,i%3)in[(0,1),(0,0)])or((j%4,i%6)in[(1,1),(1,2),(3,4),(3,5)])*2or((i%6,j%12)in p(z,[10,2,10,4,8,4]))*4or((i%6,j%12)in p(z,[8,4,8,2,10,2]))*3,1,0][j in[0,c]or((j,i%6)in p([1,1,2,2],[1,2]*2)+p([c-1,c-1,c-2,c-2],[1+l,2+l]*2)or(i,j%12)in[(1,8),(1,9),(1,10),(2,8),(2,9),(2,10),(r-1,9)]or(i,j%12)==(r-1,3+6*(m%2)))*2],2*(j%6>0)or i>0][i in[0,r]]]for j in range(c+1))for i in range(r+1))

```

Perhaps more of an exercise in obfuscation than in golfing, this one works by deciding what character each `(x,y)` coordinate goes to rather than building up each pattern by string. Ungolfed it looks like

```
char_codes = " |_()"
def base(row, col):
    if col % 6 in [5] and row % 3 in [0, 2]:
        return 1
    if col % 6 in [0, 4] and row % 3 in [2]:
        return 2
    return 0

def underscores(row, col):
    if col % 4 in [0] and row % 6 in [0, 1] or col % 4 in [2] and row % 6 in [3, 4]:
        return 2
    return 0

def parentheses(row, col):
    if (row % 6, col % 12) in [(0, 9), (1, 1), (2, 9), (3, 3), (4, 7), (5, 3)]:
        return 4
    if (row % 6, col % 12) in [(0, 7), (1, 3), (2, 7), (3, 1), (4, 9), (5, 1)]:
        return 3
    return 0

def value(row, col):
    return base(row, col) + underscores(row, col) + parentheses(row, col)

def new_value(last_row, last_col, row, column):
    if row in [0, last_row]:
        return 2*(column % 6 > 0) or row>0
    if column in [0, last_col]:
        return 1
    if column in [1,2] and row % 6 in [1, 2]:
        return 0
    if column in [last_col - 1, last_col - 2] and row % 6 in [[4,5],[1,2]][last_col%12>0]:
        return 0
    if row in [1, 2] and column % 12 in [8,9,10]:
        return 0
    if row == last_row - 1 and column % 12 == 9:
        return 0
    return value(row - 1, column - 1)

def puzzle(rows, cols):
    last_row = rows * 3
    last_col = cols * 6
    return "\n".join("".join(new_value(last_row, last_col, row, col) for col in range(last_col + 1)) for row in range(last_row + 1))

```

The patterns themselves look like

we can see this as a lookup table from integers with columns taken mod 6 and rows mod 3

```
 012345
0     |
1
2_   _|

 0123
0_
1_
2
3  _
4  _
5

 0123456789AB
0       ( )
1 ) (
2       ( )
3 ( )
4       ) (
5 ( )

```

This strategy of combining different patterns has not really worked out for me here because expressing them is quite cumbersome (though I think I could have golfed more) and because the edge cases take up so many characters to fix. I'm putting this up regardless because it took me a minute and it might be of interest.
> 5 votes

# Answer
# Mathematica, 384 bytes

```
(m=#~Mod~2&;a=#~Array~Y&;s=(h="   _  ")[o="|_( )_",z="|_   _",w=" _) (_",z,p="| (_) "];l="|  _  "[o,"|    _",u="|   (_",z,p];r=h[o,q="|_    ",t=" _)   ",z,p];{X,Y}=#;a[" _____"&]<>" \n"<>Join[{a[If[#<Y,z,q]["|     "][[m@#]]&]},Table[Which[y<2,l,y<Y,s,0<1,r][[Mod[x+3y,6]]],{x,3,3X-1},{y,1,Y}],{a[If[#<2,"|     "[u],"      "[If[#<Y,w,t]]][[m[X+#]]]&],a["|_____"&]}]~Riffle~"|\n"<>"|")&

```

Unnamed function taking an ordered pair of integers as its argument, and returning a string containing appropriate newlines. With spaces and newlines added:

```
(m = Mod[#1, 2] &; a = Array[#1, Y] &;
 s = (h = "   _  ")[o = "|_( )_", z = "|_   _", w = " _) (_", z, p = "| (_) "];
 l = "|  _  "[o, "|    _", u = "|   (_", z, p];
 r = h[o, q = "|_    ", t = " _)   ", z, p];
 {X, Y} = #1;
 a[" _____" &] <> " \n" <>
 Riffle[
   Join[
     {a[If[#1 < Y, z, q]["|     "][[m[#1]]] &]},
     Table[
       Which[y < 2, l, y < Y, s, 0 < 1, r][[Mod[x + 3 y, 6]]],
       {x, 3, 3 X - 1}, {y, 1, Y}
     ],
     {a[If[#1 < 2, "|     "[u], "      "[If[#1 < Y, w, t]]][[m[X + #1]]] &],
     a["|_____" &]}
   ], "|\n"
 ] <> "|") &

```
> 2 votes

# Answer
## Batch, ~~562~~ 528 bytes

```
@echo off
set t=!  !
set w=%2
set a= _) (_!_   _! (_) !        _  !_( )_!_   _ _) (_
call:d "!     !_   _" 2 " _____ _____" 4
for /l %%j in (2,1,%1)do call:t
call:d "!_____!_____" 1 "%a:~18,6%%a:~-6%" 3
exit/b
:t
set a=%a:~24%%a:~0,24%
call:d "%a:~6,6%%a:~30,6%" 1 "%a:~0,6%%a:~24,6%" 3
call:c "%a:~12,6%%a:~36,6%" 2
exit/b
:d
call:c %3 %4
:c
set s=
for /l %%i in (%w%,-2,1)do call set s=%~1%%s%%&if %%i==1 call set s=%%s:~6%%
if %2 lss 4 set s=%s%!&call set s=%%t:~0,%2%%%%s:~%2,-%2%%%%t:~-%2%%
echo %s:!=^|%

```

Proved resistant to golfing, as the repetition tended to cost too many bytes to eliminate, for example, I manually pass in the line number mod 3 because it's too expensive to compute. Edit: Furthermore, I had inadvertently golfed extra `|`s every third line, which is incorrect. Fixing this actually saved me 2 bytes (4 bytes on my original version). Explanation: `a` contains various bits of jigsaw. The `:t` function swaps them over each set of three rows, then extracts the required substrings which the `:c` function then repeats in pairs, but deleting the first column if `w` is odd. The left and right edge cases are then handled before the row is output. ~~The other edge case is the very first row in which the `!`s are changed to spaces instead of `|`s (the code avoids `|`s because they are tricky to handle in Batch).~~
> 2 votes

# Answer
# Befunge, ~~263~~ 243 bytes

```
|_   _| (_)
 _) (_   _
|_   _|_( )_

|
|
|_____
 _____
>&:08p3*28p&:18p6*38pv
@#!`g82:,_v0+55+1p84:<_
\g82+g84<| `g83:+1,g\%*6-g852+*6/3+2g84\++%3+2\!:g84*4p85:!!+*`0%6\!*`
6/08g+2%^>>::::48g3/2%2*`\48g3/18g+2%!2*+38g\`*!48g3%0`*\::6/2%!48g\`\

```

Try it online!

The way this works is by iterating over the x,y coordinates of the area we want to output, and mapping those *x*,*y* values to *u*,*v* coordinates in the puzzle pattern (stored on the first three lines of the playfield). This mapping is achieved with the following basic formulae:

```
u = (x+(y+2)/3*6) % 12
v = (y+2)%3 + (y==0)

```

The *u* coordinate repeats every 12 columns, but also needs to be offset by 6 every 3 rows. The *v* coordinate repeats every 3 rows, but we add `y==0` to the value so the very first row can be rendered as a special case. However, to handle the edges, we need to introduce an additional boolean value, *e*, which is true for various edge locations, and which adjusts the formulae as follows:

```
u = (x+(y+2)/3*6) % (e?6:12)
v = (y+2)%3 + (y==0) + e*4

```

Thus if we're on an edge, we add 4 to the *v* coordinate so as to use the simpler edge pattern on lines 5 to 7. And we also now need to mod the *u* coordinate by 6 rather than 12, since this edge pattern repeats every 6 columns.

As for the *e* value itself, that requires a fairly complex formula, since the edge locations encompass a somewhat irregular area of the puzzle border.

```
elr = (x <= 2*y/3%2 or x >= w-2*!(y/3+cols)%2) and (y%3 > 0)
etb = (y <= !(x/6%2) or y >= h-(x/6+rows)%2) and (x%6 > 0)
e   = elr or etb

```

Without going into too much detail, the basic breakdown is that *elr* matches the edge locations along the left and right borders, while *etb* matches locations along the top and bottom borders.
> 2 votes

# Answer
## JavaScript (ES6), 285 bytes

```
f=
(h,w,a=` _) (_|_   _| (_)    _  |_( )_|_   _      |     |_____`.match(/.{6}/g),g=(l,r,j)=>a[7].slice(0,j)+(a[l]+a[r]).repeat(w).slice(j,w*6+1-j)+`  |`.slice(-j))=>[` _____`.repeat(w),g(1,7,2),...[...Array(--h*3)].map((_,i)=>g(i%6,(i+3)%6,"312"[i%3])),g(h=h%2*6,6-h,3),g(8,8,1)].join`
`
```

```
<div oninput=o.textContent=+h.value&&+w.value?f(h.value,w.value):''><input id=h type=number min=1><input id=w type=number min=1><pre id=o>
```

This is a port of my Batch answer, just to see whether it competes with @edc65's answer. The annoyingly long string contains jigsaw pieces. The first six pieces represent two rows of one column of the interior of the jigsaw. The seventh piece is used for the penultimate line of the jigsaw, in place of the fourth piece. The eighth piece is used on the second line of the jigsaw, in place of the fifth piece, and also does double duty as the left edge of the jigsaw. The ninth piece is the last line of the jigsaw.
> 1 votes

---
Tags: code-golf, ascii-art, tiling
---


title: Let's Tessellate!

text:
# Question
Title: Let's Tessellate!
### Introduction

From Wikipedia:

> A **tessellation** of a flat surface is the tiling of a plane using one or more geometric shapes, called tiles, with no overlaps and no gaps.

A fairly well known tessellation is shown below:

The rhombi are tiled in a fashion that results in no overlaps or gaps, and simulates interchanging columns of cubes.

### Task

Your task is to write a program that tessellates rhombi the same way the image does above. The input for the program will be dimensions of the tessellation: `height x width`, where width is the amount of columns and height is the amount of rows.

A single cube that is `1 x 1` (3 tiles of rhombi) is represented exactly as so:

```
    _____
  /\      \
 /  \      \
/    \ _____\
\    /      /
 \  /      /
  \/_____ /

```

So if the input/dimensions are `3 x 2`, this should be the output:

```
    _____
  /\      \
 /  \      \
/    \ _____\ _____
\    /      /\      \
 \  /      /  \      \
  \/_____ /    \ _____\
  /\      \    /      /
 /  \      \  /      /
/    \ _____\/_____ /
\    /      /\      \
 \  /      /  \      \
  \/_____ /    \ _____\
  /\      \    /      /
 /  \      \  /      /
/    \ _____\/_____ /
\    /      /\      \
 \  /      /  \      \
  \/_____ /    \ _____\
          \    /      /
           \  /      /
            \/_____ /

```

As you can see, there are 3 rows (height), and 2 columns (width). **The columns are interchanging up and down.** Your program should do this too and start higher. For example, `3 x 3` would be:

```
    _____               _____
  /\      \           /\      \
 /  \      \         /  \      \
/    \ _____\ _____ /    \ _____\
\    /      /\      \    /      /
 \  /      /  \      \  /      /
  \/_____ /    \ _____\/_____ /
  /\      \    /      /\      \
 /  \      \  /      /  \      \
/    \ _____\/_____ /    \ _____\
\    /      /\      \    /      /
 \  /      /  \      \  /      /
  \/_____ /    \ _____\/_____ /
  /\      \    /      /\      \
 /  \      \  /      /  \      \
/    \ _____\/_____ /    \ _____\
\    /      /\      \    /      /
 \  /      /  \      \  /      /
  \/_____ /    \ _____\/_____ /
          \    /      /
           \  /      /
            \/_____ /

```

### Rules

* The result must be outputted, input may be taken in whatever way you like but must correspond to height and width
* Trailing newlines are allowed
* The tessellation columns always start from above then alternate up and down
* Sides of tessellations must be shared and tessellations must be correctly placed in between the other columns with no gaps
* Your submission may be a function or a full program
* Your program must print *exactly* the output above given the same input; in other words the output must follow the same format for cubes/tessellations

### Assumptions

* You can assume that the input will always be greater than `1 x 1`, so you don't need cases where a zero is inputted

### Scoring

This is , so the shortest code in bytes wins. Standard loopholes are prohibited as well.

# Answer
## JavaScript (ES6), 243 bytes

```
f=
(h,w)=>[...Array(h*6+4)].map((_,i)=>[...Array(w*9+3)].map((_,j)=>i&&(i+j+3)%6==0&&j%9<(i>3?6:3)&&(i>3|j<w*9)&&(j>2|i<h*6)?'/':i&&(i-j+2)%6==0&&j%9<(i>h*6?j<w*9?3:0:6)?'\\':i%3==0&&j>2&&(i*3+j+14)%18%(!i|i>h*6?18:12)<4?'_':' ').join``).join`
`
```

```
<div oninput=o.textContent=+h.value&&+w.value?f(h.value,w.value):''><input id=h type=number min=1><input id=w type=number min=1><pre id=o>
```

Directly calculates all the desired characters. For `/`:

```
i&&                         Not on first row of output
(i+j+3)%6==0&&              Backward diagonals
j%9<                        Not on top (right) diamond of hexagons or
    (i>3?6:3)&&             empty spaces on top half row
(i>3|j<w*9)&&               Not on top right corner of output
(j>2|i<h*6)                 Not on bottom left corner of output

```

For `\`:

```
i&&                         Not on first row of output
(i-j+2)%6==0&&              Forward diagonals
j%9<                        Not on bottom (right) diamond of hexagons or
    (i>h*6?                 empty spaces on bottom half row or
        j<w*9?3:0:6)        bottom right corner of output

```

For `_`:

```
i%3==0&&                    Every third line
j>2&&                       Not on left two columns
(i*3+j+14)%18%              Every 18 characters
    (!i|i>h*6?18:12)<4      One or two groups

```
> 4 votes

# Answer
# Befunge, ~~277~~ 269 bytes

```
&6*4+00p&:55+*3+10p2%20pv@
6+5:g03%*54:::<<0+55p03:<<v%*54++55:\p04:**`+3g03g00`\g01+*3!g02\-*84g+3+!\%
48*+,1+:10g`!#^_$,1+:00g-|>30g:2+6%\3-!+3+g48*-\:2`\20g3*+10g\`*30g2`**40g!*+
  /\      \
 /  \      \
/    \ _____\
\    /      /
 \  /      /
  \/_____ /
    _____

```

Try it online!

This question looked deceptively easy, but the edge cases turned out to be more complicated than I had originally anticipated. The best approach I could come up with was to handle the odd and even columns as separate renderings, and then just merge the results.

So for each x,y coordinate that has to be output, we first need to determine what character should be rendered for an odd column, by mapping the *x*,*y* output coordinates to *u*,*v* coordinates in the cube diagram as follows:

```
u = x%20
v = (y+5)%6 + (y==0)

```

The addition of `(y==0)` is to handle the special case of the first line. But we also need to make sure we aren't rendering the last few lines at the bottom of the column, and the last few characters on the end of each row. This is achieved by multiplying output character with the expression:

```
(y > h-3) && (x > w-3*!(columns%2))

```

The `!(columns%2)` in the width calculation is because the amount we need to trim off the end is dependent on whether the total column count is even or odd.

We then do a second calculation to determine what character should be rendered for an even column, mapping the *u*,*v* coordinates as follows:

```
u = (x+10)%20
v = (y+2)%6 + (y==3)

```

This is the same basic calculation as used for the odd columns, but offset slightly. And as before, we need to make sure we don't render some of the characters on the boundaries - this time the first few lines at the top of the column, as well as some characters at the beginning and end of each row. The expression we multiply in this case is:

```
(y > 2) && (x > 2) && (x < w-3*(columns%2))

```

Having calculated these two potential output characters, the final value used is:

```
char1 + (char2 * !char1) + 32

```

In other words, if *char1* is zero we need to output *char2*, otherwise we output *char1*. If both are non-zero, we're just going to output *char1*, but that's fine because they'd both be the same value anyway. Also note that these character values are offset by 32 (hence the addition of 32) so that zero will always end up as a space.
> 3 votes

# Answer
# Python 2, ~~329~~ ~~326~~ 319 bytes

```
h,w=input()
a,R=[' '*10]*3,range
b='  /\      \  # /  \      \ #/    \ _____\#\    /      /# \  /      / #  \/_____ /  '.split('#')
c=['    _____    ']+b*h
e,o=c+a,a+c
k=len(e)
f=e[:]
o[3]=o[3][:10]
for x in R(1,w):
 for y in R(k):f[y]+=((e[y][3:],e[y])[y in R(4)],(o[y][3:],o[y])[y in R(k-3,k)])[x%2]
print'\n'.join(f)

```

Try it online!

Actually ~~21~~ ~~24~~ 31 bytes shorter than my previous incorrect post. Creates lists for the odd and even columns then concatenates them for each column in the width.
> 2 votes

# Answer
## Batch, 590 bytes

```
@echo off
set c=call:c
set b=\      \
set f=%b:\=/%
set s=
set u=_____
set w=%2
%c%"   " " %u%" "%s%%s%"
%c%"  " "/%b%" "%s%    "
%c%" " "/  %b%" "%s%  "
%c%"" "/    \ %u%\" " %u% "
for /l %%i in (1,1,%1)do %c%"\" "    %f%" "%b%"&%c%" \" "  %f%" "  %b%"&%c%"  \" "/%u% /" "    \ %u%\"&if %%i lss %1 %c%"  /" "%b%" "    %f%"&%c%" /" "  %b%" "  %f%"&%c%"/" "    \ %u%\" "/%u% /"
%c%"   " "" "%s%\    %f%"
%c%"  " "" "  %s%\  %f%"
%c%" " "" "    %s%\/%u% /"
exit/b
:c
set o=%~1
for /l %%j in (%w%,-2,1)do call set o=%%o%%%~2&if %%j gtr 1 call set o=%%o%%%~3
echo(%o%

```

The `:c` subroutine takes three parameters; `%3` is the difference between 1 and 2 columns, `%2` is the difference between 2 and 3 columns, `%1` is the extra prefix for the first column, so one column is `%1%2`, two columns is `%1%2%3`, three columns is `%1%2%3%2`, four columns is `%1%2%3%2%3` etc.
> 2 votes

---
Tags: code-golf, string, ascii-art, geometry, tiling
---


title: KOTH: Everybody loves tokens

text:
# Question
Title: KOTH: Everybody loves tokens
In this game two players compete to eat the most points worth of tokens, but there's a twist! Eating multiple tokens in a row of the same color gives an ever-growing bonus, but watch out, or your opponent will thwart your plans by eating the tokens you want before you can!

**Rules:**

* 1 versus 1
* n by n board (random size between 5x5 and 15x15)
* You and your opponent will spawn in the same random cell
* Throughout the board will be randomly generated numbers in some cells ranging in value from 1-3
* 2 * (the width of the board) tokens will be generated, but there can be overrides, so there may be fewer by chance.
* Each number will be one of 3 colors: Red, Green, or Blue, in hex RGB format
* Each round, player 1 moves and the board is updated, then player 2 moves, and the board is updated. So each player can effectively tell what move the previous player made based on the change in the board state. This continues until the game ends, as described later.
* You have 6 possible actions for a turn: UP, RIGHT, DOWN, LEFT, EAT, and PASS
* The 4 move commands are self-explanatory, and you CAN pass your turn. If you return a nonsensical move, we will assume you meant pass. If you try to move off the edge of the board, you will not move. The edges don't wrap.
* EAT consumes the number you are currently in the same space as
* You gain as many points as the number you consume
* If you eat 2 numbers in a row of the same color, you get +1
* If you eat 3 numbers in a row of the same color, you get +2
* If you eat m numbers in a row of the same color, you get +(m-1)
* These bonuses are added cumulatively, so getting m numbers in a row leads to m\*(m-1)/2 in total bonus by the time you eat a different color.
* Game end conditions:
    + All numbers are consumed
    + 4 * (the width of the board) turns have gone by with no effective eating (just saying “EAT” with no token where you are doesn't count) occurring by either player (any token is reachable in 2 * (the width) moves, so this bound will only be surpassed if both players have no single target token in mind)
* Your AI should take less than a second to make a move, else PASS will be assumed as your choice.

The tournament will be round robin with a large number of rounds, say 100 or 1000. A random board is generated, and each ordered pair of different players is run on that board. After the tournament completes we will rank people by their total score. So even if you are player 2 for a game, your goal is still to get as many points as possible.

**AI Submission:** The language my controller supports is Javascript. Multiple submissions are allowed. Everyone submits a constructor for an object like this:

```
function (player1) {
    this.yourMove = function (b) {
        return "MOVE";
    }
}

```

The input `player1` is a boolean saying whether you are player 1 or not. Your constructor must have the `yourMove` function, but it can have any number of additional functions or values as well. Don't define any global variables, just put them as variables on your object. A new version of your object will be created at the beginning of each match, and `yourMove` will be called on it, with the current board as input, on each of your turns, and should return a valid move.

`b`, the input to `yourMove`, is a **copy** of the current board, here are the constructors, with input examples, though you can't call them yourself:

```
function token(color, points) {
    this.color = color; //"#FF0000"
    this.points = points; //5
}

function player(pos, score, colorBonus, lastColor) {
    this.pos = pos; //[5, 5]
    this.score = score; //9
    this.colorBonus = colorBonus; //i.e. 2 if you just ate 3 blue tokens in a row
                                  //0 if you just ate two different colors.
    this.lastColor = lastColor; //"#00FF00", is "#000000" at start
}

function board(player1, player2, tokens) {
    this.player1 = player1; //new player([5, 5], 9, 2, "#00FF00")
    this.player2 = player2; //new player([5, 5], 9, 2, "#00FF00")
    this.tokens = tokens; //[[new token("#0000FF", 5), false],
                      // [new token("#0000FF", 5), false]]
}

```

The token array has "false" for any empty squares, and tokens\[a\]\[b\] is the token at x = a, y = b, numbered starting from the upper-left corner.

**Controller:** Here's a link to the controller in GitHub. It's an html file that you can run to see how the game and the round-robin works, and it comes with two AIs, a random one that moves in a random direction each turn but eats tokens at its position, and a naive algorithm that goes for the nearest token that gives the most points. I will add in each AI as it is submitted.

Below is a snippet that allows you to run the controller on the default AI. Current AIs:

* KindaRandomAI
* NaiveAI
* MirrorBot
* HungryBot

```
<!DOCTYPE html>
<html>

<body>

  <canvas id="myCanvas" width="700" height="600" style="border:1px solid #c3c3c3;">
    Your browser does not support the HTML5 canvas tag.
  </canvas>

  <script>
    // AI Array, put in at least two constructor functions as described in the
     // data file, and it will do round robin on them.
     // Also, you can adjust some variables for testing purposes only.
    var interval = 1; // in milliseconds per turn
    var matches = 10; // number of matches for each pairing
    var aiArray = [];
    myAI = function(player1) {
      this.player1 = player1;
      this.yourMove = function(b) {
        var me;
        if (this.player1) {
          me = b.player1;
        } else {
          me = b.player2;
        }
        var d = 0;
        var tokenP;
        while (tokenP == undefined) {
          var arr = this.findTokensAtDistance(me.pos, d)
          tokenP = this.findBestToken(arr, b.tokens, me);
          d += 1;
        }
        return this.startAndGoalToCommand(me.pos, tokenP);
      }
      this.findTokensAtDistance = function(p, d) {
        if (d == 0) {
          return [
            [p[0], p[1]]
          ];
        }
        var myArr = [];
        for (i = 0; i <= d; i++) {
          myArr[i] = [i, d - i];
        }
        var mySecArr = [];
        for (i = 0; i <= d; i++) {
          mySecArr[i] = [myArr[i][0] + p[0], myArr[i][1] + p[1]];
        }
        mySecArr[mySecArr.length] = [myArr[0][0] + p[0], -myArr[0][1] + p[1]];
        for (i = 1; i < myArr.length - 1; i++) {
          mySecArr[mySecArr.length] = [-myArr[i][0] + p[0], myArr[i][1] + p[1]]
          mySecArr[mySecArr.length] = [myArr[i][0] + p[0], -myArr[i][1] + p[1]]
          mySecArr[mySecArr.length] = [-myArr[i][0] + p[0], -myArr[i][1] + p[1]]
        }
        mySecArr[mySecArr.length] = [-myArr[myArr.length - 1][0] + p[0], myArr[myArr.length - 1][1] + p[1]];
        return mySecArr;
      }
      this.findBestToken = function(arr, t, player) {
        var tokenPos;
        for (i = 0; i < arr.length; i++) {
          if (arr[i][0] >= 0 && arr[i][0] < t.length && arr[i][1] >= 0 && arr[i][1] < t.length) {
            if (t[arr[i][0]][arr[i][1]] != false && ((tokenPos == undefined) || (this.tokenScore(player, t[arr[i][0]][arr[i][1]]) > this.tokenScore(player, t[tokenPos[0]][tokenPos[1]])))) {
              tokenPos = [arr[i][0],
                [arr[i][1]]
              ];
            }
          }
        }
        return tokenPos;
      }
      this.tokenScore = function(player, token) {
        if (player.lastColor == token.color) {
          return player.colorBonus + 1 + token.points;
        } else {
          return token.points;
        }
      }
      this.startAndGoalToCommand = function(start, goal) {
        var diff = [goal[0] - start[0], goal[1] - start[1]];
        if (diff[0] > 0) {
          return "RIGHT";
        } else if (diff[1] > 0) {
          return "DOWN";
        } else if (diff[1] < 0) {
          return "UP";
        } else if (diff[0] < 0) {
          return "LEFT";
        } else {
          return "EAT";
        }
      }
    }
    aiArray[0] = myAI;
     // This is a really stupid AI, used to test that the round-robin selected
     // it is the worst by far
    myStupidAI = function(player1) {
      this.player1 = player1;
      this.yourMove = function(b) {
        var me;
        if (this.player1) {
          me = b.player1;
        } else {
          me = b.player2;
        }
        if (b.tokens[me.pos[0]][me.pos[1]] != false) {
          return "EAT";
        } else {
          var dirs = this.getViableDirections(b, me.pos);
          var rand = Math.floor(Math.random() * dirs.length);
          return dirs[rand];
        }
      }
      this.getViableDirections = function(b, p) {
        var dirs = [];
        if (p[0] > 0) {
          dirs.push("LEFT");
        }
        if (p[1] > 0) {
          dirs.push("UP");
        }
        if (p[1] < b.tokens.length - 1) {
          dirs.push("DOWN");
        }
        if (p[0] < b.tokens.length - 1) {
          dirs.push("RIGHT");
        }
        return dirs;
      }
    }
    aiArray[1] = myStupidAI;
    mirrorBot = function(player1){
        this.hasStarted=0;
        this.player1 = player1;
        this.yourMove = function(b){
            this.op = this.player1 ? b.player2 : b.player1;
            var out = "EAT";
            if(this.hasStarted){
                if(this.opl.pos[0] < this.op.pos[0]) out = "LEFT";
                if(this.opl.pos[0] > this.op.pos[0]) out = "RIGHT";
                if(this.opl.pos[1] < this.op.pos[1]) out = "UP";
                if(this.opl.pos[1] > this.op.pos[1]) out = "DOWN";
            }
            this.opl = this.op;
            this.hasStarted = 1;
            return out;
        }
    }
    aiArray[2] = mirrorBot;
    hungryBot = function(first) {
  // Set up "self"
  var self = this;

  // Determine player order
  this.player = -(first - 2);
  this.enemy = first + 1;

  // Action associative array
  this.actions = ['EAT', 'LEFT', 'RIGHT', 'UP', 'DOWN'];

  //Logic handler
  this.yourMove = function(board) {
// Determine player object
var player = board['player' + self.player];
var enemy = board['player' + self.enemy];

// Point value action grid
var actions = [0, 0, 0, 0, 0]; // Associative with "this.actions"

// Board dimensions
var size = board.tokens.length;
var maxDist = size * 2;

// Colors remaining
var colors = {
  '#FF0000': 0,
  '#00FF00': 0,
  '#0000FF': 0
};

// Averaged value weight
var average = [0, 0];

// Total points
var points = 0;

// Token holder
var tokens = [];

// Token parser
for (var i = 0, x = 0, y = 0; i < size * size; i += 1, x = i % size, y = i / size | 0) {
  if (!board.tokens[x][y]) {
    continue;
  } else {
    var token = {};
    token.points = board.tokens[x][y].points;
    token.color = board.tokens[x][y].color;
    token.x = x - player.pos[0];
    token.y = y - player.pos[1];
    token.distX = Math.abs(token.x);
    token.distY = Math.abs(token.y);
    token.dist = token.distX + token.distY;
    token.distE = Math.abs(x - enemy.pos[0]) + Math.abs(y - enemy.pos[1]);
    token.value = -token.points - (player.colorBonus + 1) * (token.color == player.lastColor) * ((token.dist == 0) + 1) * 1.618 - (enemy.colorBonus + 1) * (token.color == enemy.lastColor);
    tokens.push(token);
    colors[token.color] += 1;
    points += token.points;
    average[0] += x * token.points;
    average[1] += y * token.points;
  }
}

// Determine actual average
average[0] = average[0] / points | 0;
average[1] = average[1] / points | 0;

// Pick best token
var best = 0;

// Calculate point values of tokens
for (i = 0; i < tokens.length; i++) {
  var token = tokens[i];
  // Add remaining numbers of tokens of color as factor
  token.value -= (colors[token.color] / tokens.length) * 1.618;
  // Subtract distance as a factor
  token.value += token.dist;
  // Add distance to average to value
  token.value += (Math.abs(average[0] - (token.x + player.pos[0])) + Math.abs(average[1] - (token.y + player.pos[1]))) / Math.sqrt(2);
  // Consider them higher value if we are closer, and lower if they are
  token.value += ((token.dist - token.distE) / (token.dist + token.distE + 0.001)) * token.dist;
  // Don't go for it if enemy is already there
  token.value += (token.distE == 0 && token.dist > 0) * 100;

  if (tokens[best].value > tokens[i].value || (tokens[best].value === tokens[i].value && Math.round(Math.random()))) {
    best = i;
  }
}

// Set token to best token
var token = tokens[best];

// What to respond with
var response = 'PASS';

// Find best action to get token
if (token.dist == 0) {
  response = 'EAT'; // We're on the token
} else if (token.distX >= token.distY) { // Token is more horizontal
  if (token.x < 0) { // Token is left
    response = 'LEFT';
  } else if (token.x > 0) { // Token is right
    response = 'RIGHT';
  }
} else if (token.distX < token.distY) { // Token is more vertical
  if (token.y < 0) { // Token is above
    response = 'UP';
  } else if (token.y > 0) { // Token is below
    response = 'DOWN';
  }
}

// Return response
return response;
  }
};
    aiArray[3]=hungryBot;
    for (i = 0; i < aiArray.length; i += 1) {
      Object.freeze(aiArray[i]);
    }
     // This is the actual code to run the program. You shouldn't mess with it,
     // or your AI might not work during the actual competition.
     // Also note that you can't access this code at all in your AI.
     // Feel free to make suggestions and we'll try to incorporate them,
     // and let us know if something isn't working correctly.
    Object.freeze(aiArray);
    setInterval((function() {
      function token(color, points) {
        this.color = color;
        this.points = points;
      }

      function player(pos, score, colorBonus, lastColor) {
        this.pos = pos;
        this.score = score;
        this.colorBonus = colorBonus;
        this.lastColor = lastColor;
      }

      function board(player1, player2, tokens) {
        this.player1 = player1;
        this.player2 = player2;
        this.tokens = tokens;
      }

      function copyBoard(b) {
        return new board(copyPlayer(b.player1), copyPlayer(b.player2), copyTokens(b.tokens));
      }

      function copyTokens(t) {
        var tokens = [];
        for (i = 0; i < t.length; i++) {
          tokens[i] = [];
          for (j = 0; j < t[i].length; j++) {
            tokens[i][j] = t[i][j];
          }
        }
        return tokens;
      }

      function copyPlayer(p) {
        return new player([p.pos[0], p.pos[1]], p.score, p.colorBonus, p.lastColor);
      }

      function endGame(b) {
        if (b.player1.score > b.player2.score) {
          var c = document.getElementById("myCanvas");
          var ctx = c.getContext("2d");
          ctx.font = 20 + "px Arial";
          ctx.textAlign = "left";
          ctx.fillStyle = "#000000";
          ctx.fillText("Player 1", 601, 160);
          ctx.fillText("wins!", 601, 180);
        } else if (b.player1.score < b.player2.score) {
          var c = document.getElementById("myCanvas");
          var ctx = c.getContext("2d");
          ctx.font = 20 + "px Arial";
          ctx.textAlign = "left";
          ctx.fillStyle = "#000000";
          ctx.fillText("Player 2", 601, 160);
          ctx.fillText("wins!", 601, 180);
        } else {
          var c = document.getElementById("myCanvas");
          var ctx = c.getContext("2d");
          ctx.font = 20 + "px Arial";
          ctx.textAlign = "left";
          ctx.fillStyle = "#000000";
          ctx.fillText("It's a", 601, 160);
          ctx.fillText("draw!", 601, 180);
        }
      }

      function genTokenArray(size) {
        var temp = [];
        for (i = 0; i < size; i++) {
          temp[i] = [];
          for (j = 0; j < size; j++) {
            temp[i][j] = false;
          }
        }
        return temp;
      }

      function genRandomTokenArray(size) {
        var temp = genTokenArray(size);
        for (i = 0; i < size * 2; i++) {
          var rand = Math.floor(Math.random() * temp.length);
          var points = Math.floor(Math.random() * 3 + 1);
          var rand2 = Math.floor(Math.random() * 3);
          var color;
          var rand3 = Math.floor(Math.random() * temp[rand].length);
          if (rand2 == 0) {
            color = "#FF0000"
          } else if (rand2 == 1) {
            color = "#00FF00"
          } else {
            color = "#0000FF"
          }
          temp[rand][rand3] = new token(color, points);
        }
        return temp;
      }

      function countTokens(tokenArr) {
        var x = 0;
        for (i = 0; i < tokenArr.length; i++) {
          for (j = 0; j < tokenArr[i].length; j++) {
            if (tokenArr[i][j] != false) {
              x += 1
            }
          }
        }
        return x;
      }

      function actPlayer(b, p, s) {
        if (s == "UP" && p.pos[1] > 0) {
          p.pos[1] -= 1;
        } else if (s == "RIGHT" && p.pos[0] < b.tokens.length - 1) {
          p.pos[0] += 1;
        } else if (s == "DOWN" && p.pos[1] < b.tokens.length - 1) {
          p.pos[1] += 1;
        } else if (s == "LEFT" && p.pos[0] > 0) {
          p.pos[0] -= 1;
        } else if (s == "EAT" && b.tokens[p.pos[0]][p.pos[1]] != false) {
          if (p.lastColor == b.tokens[p.pos[0]][p.pos[1]].color) {
            p.colorBonus += 1;
            p.score += p.colorBonus;
          } else {
            p.lastColor = b.tokens[p.pos[0]][p.pos[1]].color;
            p.colorBonus = 0;
          }
          p.score += b.tokens[p.pos[0]][p.pos[1]].points;
          b.tokens[p.pos[0]][p.pos[1]] = false;
        }
      }

      function drawEmptyRect() {
        var c = document.getElementById("myCanvas");
        var ctx = c.getContext("2d");
        ctx.clearRect(0, 0, 700, 600);
      }

      function drawToken(t, x, y, g) {
        drawEntity(x, y, t.points, t.color, "#000000", 300 / g, g);
      }

      function drawLittleEntity(x, y, label, fillColor, labelColor, size, cX, cY, g) {
        var delta = 600 / g;
        var x1 = x * delta + cX * delta / 4;
        var y1 = y * delta + cY * delta / 4;
        var c = document.getElementById("myCanvas");
        var ctx = c.getContext("2d");
        ctx.beginPath();
        ctx.arc(x1, y1, size / 2, 0, 2 * Math.PI);
        ctx.stroke();
        ctx.fillStyle = fillColor;
        ctx.fill();
        ctx.font = delta / 2 + "px Arial";
        ctx.textAlign = "center";
        ctx.fillStyle = labelColor;
        ctx.fillText(label, x1, y1 + delta * 3 / 16);
      }

      function drawEntity(x, y, label, fillColor, labelColor, size, g) {
        var delta = 600 / g;
        var x1 = x * delta + delta / 2;
        var y1 = y * delta + delta / 2;
        var c = document.getElementById("myCanvas");
        var ctx = c.getContext("2d");
        ctx.beginPath();
        ctx.arc(x1, y1, size, 0, 2 * Math.PI);
        ctx.stroke();
        ctx.fillStyle = fillColor;
        ctx.fill();
        ctx.font = delta + "px Arial";
        ctx.textAlign = "center";
        ctx.fillStyle = labelColor;
        ctx.fillText(label, x1, y1 + delta * 3 / 8);
      }

      function drawAllTokens(arrToken) {
        for (i = 0; i < arrToken.length; i++) {
          for (j = 0; j < arrToken[i].length; j++) {
            if (arrToken[i][j] != false) {
              drawToken(arrToken[i][j], i, j, arrToken.length);
            }
          }
        }
      }

      function drawGrid(g) {
        var delta = 600 / g;
        for (i = 0; i <= g; i++) {
          var canvas = document.getElementById("myCanvas");
          var ctx = canvas.getContext("2d");
          ctx.beginPath();
          ctx.moveTo(i * delta, 0);
          ctx.lineTo(i * delta, 600);
          ctx.stroke();
        }
        for (j = 0; j <= g; j++) {
          var canvas = document.getElementById("myCanvas");
          var ctx = canvas.getContext("2d");
          ctx.beginPath();
          ctx.moveTo(0, j * delta);
          ctx.lineTo(600, j * delta);
          ctx.stroke();
        }
      }

      function drawPlayer1(b, g) {
        drawLittleEntity(b.player1.pos[0], b.player1.pos[1], "F", "#000000", "#FFFFFF", 300 / g, 1, 1, g);
      }

      function drawPlayer2(b, g) {
        drawLittleEntity(b.player2.pos[0], b.player2.pos[1], "S", "#000000", "#FFFFFF", 300 / g, 3, 3, g);
      }

      function drawScore(b) {
        var canvas = document.getElementById("myCanvas");
        var ctx = canvas.getContext("2d");
        ctx.font = "20px Arial";
        ctx.fillStyle = "#000000";
        ctx.textAlign = "left";
        ctx.fillText("P" + indices[0] + " Score:", 601, 50);
        ctx.fillText(b.player1.score, 601, 70);
        ctx.fillText("P" + indices[1] + " Score:", 601, 100);
        ctx.fillText(b.player2.score, 601, 120);
      }

      function drawScoreNum(s, i) {
        var canvas = document.getElementById("myCanvas");
        var ctx = canvas.getContext("2d");
        ctx.font = "20px Arial";
        ctx.fillStyle = "#000000";
        ctx.textAlign = "left";
        ctx.fillText("P" + i + " Score:", 601, i * 50 + 50);
        ctx.fillText(s, 601, i * 50 + 70);
      }

      function redraw(b, g) {
        drawEmptyRect();
        drawGrid(g);
        drawScore(b);
        drawAllTokens(b.tokens);
        drawPlayer1(b, g);
        drawPlayer2(b, g);
        drawScoreNum()
      }

      function nextPair(pair, total) {
        var pairRes = [pair[0], (pair[1] + 1) % total];
        if (pairRes[1] == 0) {
          pairRes[0] = pairRes[0] + 1;
        }
        return pairRes;
      }

      function nextGameUnfair() {
        scores[indices[0]] = scores[indices[0]] + currBoard.player1.score;
        scores[indices[1]] = scores[indices[1]] + currBoard.player2.score;
        if (matchCount >= matches) {
          matchCount = 0;
          indices = nextPair(indices, aiArray.length);
          if (indices[0] == indices[1]) {
            indices = nextPair(indices, aiArray.length);
          }
          if (indices[0] >= aiArray.length) {
            return false;
          }
          player1Turn = true;
          timeWithoutEating = 0;
          firstAI = new aiArray[indices[0]](true);
          secondAI = new aiArray[indices[1]](false);
          currBoard = genBoard();
        } else {
          matchCount++;
          player1Turn = true;
          timeWithoutEating = 0;
          firstAI = new aiArray[indices[0]](true);
          secondAI = new aiArray[indices[1]](false);
          currBoard = genBoard();
        }
        return true;
      }

      function nextGameFair() {
        scores[indices[0]] = scores[indices[0]] + currBoard.player1.score;
        scores[indices[1]] = scores[indices[1]] + currBoard.player2.score;
        indices = nextPair(indices, aiArray.length);
        if (indices[0] == indices[1]) {
          indices = nextPair(indices, aiArray.length);
        }
        if (indices[0] >= aiArray.length) {
          indices = [0, 1];
          matchCount++;
          if (matchCount >= matches) {
            return false;
          }
          player1Turn = true;
          timeWithoutEating = 0;
          currBoard = genBoard();
        } else {
          player1Turn = true;
          timeWithoutEating = 0;
          currBoard = savedBoard;
        }
        firstAI = new aiArray[indices[0]](true);
        secondAI = new aiArray[indices[1]](false);
        savedBoard = copyBoard(currBoard);
        return true;
      }

      function genBoard() {
        var rand = Math.floor(Math.random() * 11 + 5);
        var randX = Math.floor(Math.random() * rand);
        var randY = Math.floor(Math.random() * rand);
        return new board(new player([randX, randY], 0, 0, "#000000"),
          new player([randX, randY], 0, 0, "#000000"),
          genRandomTokenArray(rand));
      }
      var running = true;
      var indices = [0, 1];
      var scores = []
      for (i = 0; i < aiArray.length; i++) {
        scores.push(0);
      }
      var matchCount = 0;
      var firstAI = new aiArray[0](true);
      var secondAI = new aiArray[1](false);
      var player1Turn = true;
      var currBoard = genBoard();
      var savedBoard = copyBoard(currBoard);
      var timeWithoutEating = 0;
      return function() {
        if (running) {
          var numTokens = countTokens(currBoard.tokens);
          if (numTokens <= 0) {} else if (player1Turn) {
            actPlayer(currBoard, currBoard.player1, firstAI.yourMove(copyBoard(currBoard)));
          } else {
            actPlayer(currBoard, currBoard.player2, secondAI.yourMove(copyBoard(currBoard)));
          }
          player1Turn = !player1Turn;
          redraw(currBoard, currBoard.tokens.length);
          if (numTokens > countTokens(currBoard.tokens)) {
            timeWithoutEating = 0;
          } else {
            timeWithoutEating += 1;
          }
          if (numTokens <= 0 || timeWithoutEating > 4 * currBoard.tokens.length) {
            running = nextGameFair();
          }
        } else {
          drawEmptyRect();
          for (i = 0; i < scores.length; i++) {
            drawScoreNum(scores[i], i);
          }
        }
      }
    })(), interval);
  </script>

</body>

</html>
```

# Answer
# HungryBot

Uses a point system to add weight to the value of pursuing each token. Uses a variety of different factors in its consideration, and reevaluates them each turn to ensure its following the best strategy.

```
function hungryBot(first) {
  // Set up "self"
  var self = this;

  // Determine player order
  this.player = -(first - 2);
  this.enemy = first + 1;

  // Action associative array
  this.actions = ['EAT', 'LEFT', 'RIGHT', 'UP', 'DOWN'];

  //Logic handler
  this.yourMove = function(board) {
    // Determine player object
    var player = board['player' + self.player];
    var enemy = board['player' + self.enemy];

    // Point value action grid
    var actions = [0, 0, 0, 0, 0]; // Associative with "this.actions"

    // Board dimensions
    var size = board.tokens.length;
    var maxDist = size * 2;

    // Colors remaining
    var colors = {
      '#FF0000': 0,
      '#00FF00': 0,
      '#0000FF': 0
    };

    // Averaged value weight
    var average = [0, 0];

    // Total points
    var points = 0;

    // Token holder
    var tokens = [];

    // Token parser
    for (var i = 0, x = 0, y = 0; i < size * size; i += 1, x = i % size, y = i / size | 0) {
      if (!board.tokens[x][y]) {
        continue;
      } else {
        var token = {};
        token.points = board.tokens[x][y].points;
        token.color = board.tokens[x][y].color;
        token.x = x - player.pos[0];
        token.y = y - player.pos[1];
        token.distX = Math.abs(token.x);
        token.distY = Math.abs(token.y);
        token.dist = token.distX + token.distY;
        token.distE = Math.abs(x - enemy.pos[0]) + Math.abs(y - enemy.pos[1]);
        token.value = -token.points - (player.colorBonus + 1) * (token.color == player.lastColor) * ((token.dist == 0) + 1) * 1.618 - (enemy.colorBonus + 1) * (token.color == enemy.lastColor);
        tokens.push(token);
        colors[token.color] += 1;
        points += token.points;
        average[0] += x * token.points;
        average[1] += y * token.points;
      }
    }

    // Determine actual average
    average[0] = average[0] / points | 0;
    average[1] = average[1] / points | 0;

    // Pick best token
    var best = 0;

    // Calculate point values of tokens
    for (i = 0; i < tokens.length; i++) {
      var token = tokens[i];
      // Add remaining numbers of tokens of color as factor
      token.value -= (colors[token.color] / tokens.length) * 1.618;
      // Subtract distance as a factor
      token.value += token.dist;
      // Add distance to average to value
      token.value += (Math.abs(average[0] - (token.x + player.pos[0])) + Math.abs(average[1] - (token.y + player.pos[1]))) / Math.sqrt(2);
      // Consider them higher value if we are closer, and lower if they are
      token.value += ((token.dist - token.distE) / (token.dist + token.distE + 0.001)) * token.dist;
      // Don't go for it if enemy is already there
      token.value += (token.distE == 0 && token.dist > 0) * 100;

      if (tokens[best].value > tokens[i].value || (tokens[best].value === tokens[i].value && Math.round(Math.random()))) {
        best = i;
      }
    }

    // Set token to best token
    var token = tokens[best];

    // What to respond with
    var response = 'PASS';

    // Find best action to get token
    if (token.dist == 0) {
      response = 'EAT'; // We're on the token
    } else if (token.distX >= token.distY) { // Token is more horizontal
      if (token.x < 0) { // Token is left
        response = 'LEFT';
      } else if (token.x > 0) { // Token is right
        response = 'RIGHT';
      }
    } else if (token.distX < token.distY) { // Token is more vertical
      if (token.y < 0) { // Token is above
        response = 'UP';
      } else if (token.y > 0) { // Token is below
        response = 'DOWN';
      }
    }

    // Return response
    return response;
  }
};

```
> 4 votes

# Answer
# PATH bot

Acronym stands for Pathfinding And Tree Heuristics Bot

**EDIT:** As of now, here are the rankings for the AIs, with the points

1. HungryBot (6422)
2. PATH bot (4591)
3. NaiveAI (3811)
4. KindaRandomAI (618)
5. MirrorBot (193)
6. LazyBot (25)

Link to complete controller on github

Description: Like NaiveAI, this bot finds the nearest token that will give it the most points. However, it also simulates the outcomes of each of its moves, up to 6 times.

Rationale: Because NaiveAI is already pretty good, I though I would make it better. Without looking at the code first (big mistake).

Beats: All except HungryBot
Looses to: None except HungryBot

Problems:

* Cannot simulate increased streak
* Hangs while calculating best token
* ~~Can teleport~~

I still don't know why it was teleporting, but I fixed it. Old video here: https://youtu.be/BIhSKycF9iA

Full code:

```
pathBot = function (player1)
{
    this.pathNode = function(pos,ppt,parents,par)
    {
        this.pos = pos;this.ppt = ppt;this.parents = parents;this.par=par;
        this.childs=[];
    }
    this.addChildren = function (pn,children)
    {
        pn.childs=[];
        for(var i=0; i<children.length; i=i+1)
        {
            if(pn.parents.indexOf(children[i].pos)==-1&&pn.pos!=children[i].pos)
                pn.childs.push(
                    new this.pathNode(
                        children[i].pos,
                        children[i].ppt*pn.ppt,
                        pn.parents.concat([pn.pos]),
                        pn
                    )
                );
        }
    }
    this.orderTokensByPPT = function(b,pos){
        var tokens = [];
        for(var y=0; y<b.tokens.length; y=y+1)
        {
            for(var x=0; x<b.tokens[y].length; x=x+1)
            {
                var tok = b.tokens[y][x];
                if(tok)
                {
                    tokens.push(
                        new this.pathNode(
                            [y,x],
                            (tok.points+(tok.color==this.color ? this.streak : 0)) / this.lenOfMovesTo(pos,[y,x]),
                            [],
                            undefined
                        )
                    );
                }
            }
        }
        tokens.sort(function(a,b){
            return b.ppt - a.ppt;
        });
        return tokens;
    }
    this.lenOfMovesTo = function(cur,pos)
    {
        return Math.abs(cur[0]-pos[0])+Math.abs(cur[1]-pos[1])+1;
    }
    this.startAndGoalToCommand = function (start, goal) {
        var diff = [goal[0] - start[0], goal[1] - start[1]];
        if (diff[0] > 0) { return "RIGHT"; }
        else if (diff[1] > 0) { return "DOWN"; }
        else if (diff[1] < 0) { return "UP"; }
        else if (diff[0] < 0) { return "LEFT"; }
        else { return "EAT"; }
    }
    this.color = 0;
    this.streak = 0;
    this.eatTok = function(b)
    {
        if(b.tokens[this.me.pos[0]][this.me.pos[1]].color==this.color)
        {
            this.streak++;
        }
        else{
            this.streak = 0;
            this.color = b.tokens[this.me.pos[0]][this.me.pos[1]].color;
        }
        this.bestToken = false;
        return "EAT";
    }

    this.recurLen = 6;
    this.include = 4;
    this.recurDown = function(b,pn,level)
    {
        if(level==0) return pn;
        this.addChildren(pn,this.orderTokensByPPT(b,pn.pos));
        var newChilds = [];
        for(var i=0; i<pn.childs.length&&i<this.include; i=i+1)
        {
            newChilds.push(this.recurDown(b,pn.childs[i],level-1));
        }
        pn.childs = newChilds;
        return pn;
    }
    this.findMax = function(pn)
    {
        if(pn.childs)
        {
            var maxList = [];
            for(var i=0; i<pn.childs.length; i=i+1)
                maxList.push(this.findMax(pn.childs[i]));
            maxList.sort(
                function(a,b)
                {
                    return b.ppt-a.ppt;
                }
            );
            return maxList[0];
        }
        return pn;
    }
    this.findMaxList = function(pnList)
    {
        for(var i=0; i<pnList.lenght; i=i+1)
        {
            pnList[i] = this.findMax(pnList[i]);
        }
        pnList.sort(function(a,b){return b.ppt-a.ppt;});
        return pnList[0];
    }
    this.bestToken=false;
    this.yourMove = function(b){
        this.op = player1 ? b.player2 : b.player1;
        this.me = player1 ? b.player1 : b.player2;
        if(this.bestToken)
        {
            if(b.tokens[this.bestToken.pos[0]][this.bestToken.pos[1]]==undefined)
                this.bestToken = false;
        }
        if(!this.bestToken)
        {
            var paths = this.orderTokensByPPT(b,this.me.pos);
            for(var i=0; i<paths.length; i++)
            {
                paths[i] = this.recurDown(b,paths[i],this.recurLen);
            }
            var max = this.findMaxList(paths);
            while(max.par)
            {
                max = max.par;
            }
            this.bestToken = max;
        }
        var move = this.startAndGoalToCommand(this.me.pos,this.bestToken.pos);
        if(move=="EAT") return this.eatTok(b);
        else return move;
    }
}

```
> 2 votes

# Answer
# MirrorBot

Should be called "cannon fodder"

Description: Moves the exact opposite of what the other player did

Rationale: I wanted to get comfortable programming in JS again. This should not win

Will beat: No one

Will lose to: Everyone

```
function mirror(player1) {
    this.hasStarted=false;
    this.player1 = player1;
    this.opl=[0,0];
    this.yourMove = function(b){
        this.op = this.player1 ? b.player2.pos : b.player1.pos;
        out = "EAT";
        console.log(this.op);
        console.log(this.opl);
        if(this.hasStarted){
            if(this.opl[0] < this.op[0]) out = "RIGHT";
            if(this.opl[0] > this.op[0]) out = "LEFT";
            if(this.opl[1] < this.op[1]) out = "UP";
            if(this.opl[1] > this.op[1]) out = "DOWN";
        }
        this.opl = [this.op[0],this.op[1]];
        this.hasStarted = true;
        return out;
    }
}

```
> 1 votes

# Answer
# KindaRandomAI

Every turn, do the following: If there is a token at your position, "EAT". Otherwise, move in a random viable direction, i.e. if you're at the left edge don't say "LEFT".

```
kindaRandomAI = function(player1) {
    this.player1 = player1;
    this.yourMove = function(b) {
        var me;
        if (this.player1) {
            me = b.player1;
        } else {
            me = b.player2;
        }
        if (b.tokens[me.pos[0]][me.pos[1]] != false) {
            return "EAT";
        } else {
            var dirs = this.getViableDirections(b, me.pos);
            var rand = Math.floor(Math.random() * dirs.length);
            return dirs[rand];
        }
    }
    this.getViableDirections = function(b, p) {
        var dirs = [];
        if (p[0] > 0) {
            dirs.push("LEFT");
        }
        if (p[1] > 0) {
            dirs.push("UP");
        }
        if (p[1] < b.tokens.length - 1) {
            dirs.push("DOWN");
        }
        if (p[0] < b.tokens.length - 1) {
            dirs.push("RIGHT");
        }
        return dirs;
    }
}

```
> 1 votes

# Answer
# NaiveAI

Starting with `r=0`, look at all tokens with taxicab distance `r` away from your position. If there are any, pick one that would give you the highest score if you got it right now. Otherwise, increase `r` by 1 and try again.

```
naiveAI = function(player1) {
  this.player1 = player1;
  this.yourMove = function(b) {
    var me;
    if (this.player1) {
      me = b.player1;
    } else {
      me = b.player2;
    }
    var d = 0;
    var tokenP;
    while (tokenP == undefined) {
      var arr = this.findTokensAtDistance(me.pos, d)
      tokenP = this.findBestToken(arr, b.tokens, me);
      d += 1;
    }
    return this.startAndGoalToCommand(me.pos, tokenP);
  }
  this.findTokensAtDistance = function(p, d) {
    if (d == 0) {
      return [
        [p[0], p[1]]
      ];
    }
    var myArr = [];
    for (i = 0; i <= d; i++) {
      myArr[i] = [i, d - i];
    }
    var mySecArr = [];
    for (i = 0; i <= d; i++) {
      mySecArr[i] = [myArr[i][0] + p[0], myArr[i][1] + p[1]];
    }
    mySecArr[mySecArr.length] = [myArr[0][0] + p[0], -myArr[0][1] + p[1]];
    for (i = 1; i < myArr.length - 1; i++) {
      mySecArr[mySecArr.length] = [-myArr[i][0] + p[0], myArr[i][1] + p[1]]
      mySecArr[mySecArr.length] = [myArr[i][0] + p[0], -myArr[i][1] + p[1]]
      mySecArr[mySecArr.length] = [-myArr[i][0] + p[0], -myArr[i][1] + p[1]]
    }
    mySecArr[mySecArr.length] = [-myArr[myArr.length - 1][0] + p[0], myArr[myArr.length - 1][1] + p[1]];
    return mySecArr;
  }
  this.findBestToken = function(arr, t, player) {
    var tokenPos;
    for (i = 0; i < arr.length; i++) {
      if (arr[i][0] >= 0 && arr[i][0] < t.length && arr[i][1] >= 0 && arr[i][1] < t.length) {
        if (t[arr[i][0]][arr[i][1]] != false && ((tokenPos == undefined) || (this.tokenScore(player, t[arr[i][0]][arr[i][1]]) > this.tokenScore(player, t[tokenPos[0]][tokenPos[1]])))) {
          tokenPos = [arr[i][0],
            [arr[i][1]]
          ];
        }
      }
    }
    return tokenPos;
  }
  this.tokenScore = function(player, token) {
    if (player.lastColor == token.color) {
      return player.colorBonus + 1 + token.points;
    } else {
      return token.points;
    }
  }
  this.startAndGoalToCommand = function(start, goal) {
    var diff = [goal[0] - start[0], goal[1] - start[1]];
    if (diff[0] > 0) {
      return "RIGHT";
    } else if (diff[1] > 0) {
      return "DOWN";
    } else if (diff[1] < 0) {
      return "UP";
    } else if (diff[0] < 0) {
      return "LEFT";
    } else {
      return "EAT";
    }
  }
}

```
> 1 votes

# Answer
# LazyBot

Only eats something if he spawns on it. This has no chance to win, but the challenge didn't have one of these, so why not.

```
lazyBot = function (player1) {
    this.yourMove = function(b) {
        return "EAT";
    }
}

```
> 1 votes

# Answer
# OneTarget

Finds the token that will give the most points in the least time and will go for that one. Ranks same color tokens a little higher because of the cumulative effect.

```
function (player1) {
    this.yourMove = function (b) {
        var me = player1? b.player1: b.player2;
        var him= player1? b.player2: b.player1;
        var x = me.pos[0];
        var y = me.pos[1];
        var maxVal = -1;
        var maxX = 0;
        var maxY = 0;
        for(var i = 0;i < b.tokens.length;i++){
            for(var j = 0;j < b.tokens.length;j++){
                if(b.tokens[i][j]){
                    var dist = Math.abs(x-i) + Math.abs(y-j);
                    var val = this.valueOf(b.tokens[i][j]);
                    val /= (dist + 1);
                    if(val > maxVal){
                        maxVal = val;
                        maxX = i;
                        maxY = j;
                    }
                }
            }
        }
        if(maxY < y)
            return "UP";
        if(maxX < x)
            return "LEFT";
        if(maxY > y)
            return "DOWN";
        if(maxX > x)
            return "RIGHT";
        return "EAT";
    }
    this.valueOf = function(t){
        //how many points would it give you?
        return t.points + (this.lastColor == t.color? 2 * this.colorBonus + 1 : 0);
    }
}

```
> 0 votes

# Answer
## QuantityPlayer

All QuantityPlayer cares about is the amout of dots he eats, not the value or color of the dots. He know that even though all dots are different, they should be treated the same.

```
QuantityBot = function(playernum) {

this.dist = function(token) {
    return (Math.abs(token[0])+Math.abs(token[1]))
}

this.yourMove = function(game_board) {

    board_size = game_board.tokens.length
    board_area = board_size * board_size
    fete = board_size = size * 2

    token_list = []
    count = curr_x = curr_y = 0
    while(count < board_area) {
        if(game_board.tokens[x][y]) {
        token_list.push([x-player.pos[0],y-player.pos[1]])
        }
        count++; x = count % board_size; y = Math.floor(count / size)
    }

    closest_token = token_list[0]
    count = 1
    while(count < token_list.length) {
        curr_token = token_list[count]
        if(dist(curr_token) < dist(closest_token)){closest_token = curr_token}

        count++
    }

    if(dist(closest_token)==0){return 'EAT'}
    else{
    if(closest_token[0] >= closest_token[1]) {if(closest_token[0]<0) {return 'LEFT'} {return 'RIGHT'}}
    else{if(closest_token[1]<0) {return 'UP'} {return 'DOWN'}}
    }

}

}

```
> 0 votes

---
Tags: grid, king-of-the-hill, javascript
---