title: Regular ASCII Polygons

text:
# Question
Title: Regular ASCII Polygons
There are 4 regular polygons that we can construct using ASCII art:

```
                              . . .
                  . . .      . . . .
  .     . . .    . . . .    . . . . .
 . .    . . .   . . . . .   . . . . .
. . .   . . .    . . . .    . . . . .
                  . . .      . . . .
                              . . .

```

That is, a triangle, a square, a hexagon and an octagon.

Your task is to take two inputs and produce the corresponding ASCII art polygon.

## Input

The two inputs will be:

* A string/list of printable ASCII characters (i.e. with code points in the range \\$33\\$ (`!`) to \\$126\\$ (`~`)
* An indicator as to which polygon you should output. This indicator can be any \\$4\\$ distinct and consistent values (e.g. `1234`, `ABCD`, etc.), but each must be only one character long, to avoid any exploitation of this input.

The string will be a perfect fit for the polygon, meaning that, if the shape to be outputted is:

The string may have repeated characters, but will always fit the appropriate lengths for the given shape/sequence, so there is no need to worry about too many/few characters.

## Output

You should output a shape, indicated by the second input, in the format shown at the top of the challenge with the `.` replaced with the characters in the inputted string. Each character must be separated by a single space, and leading/trailing whitespace is acceptable, so long as the shape is preserved. The characters may be used in any order, but each character in the string must only appear once. For example, for a hexagon using `ABCDABC`, the following are valid:

```
 A B     B A
C D A   A B C
 B C     D C

```

as each character from the string is used once. However,

```
 A A    A B    AD
A A A  A B C   ABC
 A A    C A    BC

```

are not valid (the first only has `A`, the second doesn't have a `D` and the third doesn't have spaces between characters).

This is so the shortest code in *bytes* wins

## Test cases

These test cases use `T`, `S`, `H` and `O` to indicate which shape the output should be in. The string of characters is on the first line and the indicator on the second

```
i1+K8{^wsW
O

 i 1
+ K 8
{ ^ w
 s W

,r1~vi4l{W@+r<vzP;mq>:8gJcgg$j`$RFhDV
H

   , r 1 ~
  v i 4 l {
 W @ + r < v
z P ; m q > :
 8 g J c g g
  $ j ` $ R
   F h D V

0J++
S

0 J
+ +

Kn[Vyj
T

  K
 n [
V y j

#5~m
S

# 5
~ m

'*g(AUFV~Ou2n=172s'|S11q&j=+#
O

  ' * g
 ( A U F
V ~ O u 2
n = 1 7 2
s ' | S 1
 1 q & j
  = + #

```

# Answer
# Ruby, ~~139~~ 138 bytes

```
->s,n{w=(((s=s.chars*' ').size/n=n.hex)**0.5).to_i+k=1&~n
(0..h=w+n/5*~-w).map{|i|s.slice!(0,[w+n/6*~-w,w**k+i,w+h+~i].min*2).center w*4}}

```

Try it online!

A function taking 2 arguments: a string `s` and a shape `n` as a single character in hexadecimal of value `1`,`2`,`6` or `A`. It returns an array of strings.

**Explanation**

The input string is converted to an array, then joined back into a string with spaces between the characters. The length of this combined string is twice the length of the original string, minus 1. This is divided by a constant, square rooted and rounded to determine the side length `w` of the polygon to be drawn. The value of the constant is per the table below. For triangles, the square root is rounded down. For others, it needs to be rounded up, so we round down then add `k=1&~n` to correct.

```
 Shape   Triangle  Square  Hexagon  Octagon
 n =     1         2       6        10

```

We iterate through `h` rows of output. For the triangle and square, `h=w`. For the other shapes we need to add `w-1` for the hexagon and twice this amount for the octagon. This is done by adding `n/5*~-w`.

Each line of output is centred and padded to `w*4` characters which is enough for all cases. Chunks of `s` are removed using `slice!` and outputted. For the octagon the number of symbols to be outputted on each line is the minimum of three numbers: `w+w-1` for the centre section, `w+i` for the top section and `w+h-i-1` = `w+h+~i` for the bottom section. These formulas also work for the hexagon. Note that the numbers have to be multiplied by 2 to account for the spaces.

For the square and triangle, the width of the output is restricted to `w`. Therefore the formula for the centre section becomes `w+n/6*~-w` to cover all shapes . For the triangle, the width of the output is further restricted to `1+i`. Therefore the formula for the top section becomes `w**k+i` to cover all shapes.
> 5 votes

# Answer
# JavaScript (ES8),  ~~191 176 174~~  171 bytes

Takes input as `(type)(string)`, where the 1st parameter is `0123` instead of `TSHO` and the 2nd parameter is an array of characters.

```
i=>g=(s,n=1,p=0)=>s[o=(h=k=>k?(F=j=>j?s.slice(p,p+=w+=k&6?k&2&&1:-1).join` `.padStart(n*2+w)+`
`+F(j-1):'')(n-k%2)+h(k>>3):'')([2,4,10,106][i],w=i>1?n-1:n*i),p]?g(s,n+1):o

```

Try it online!

## How?

The shape of each polygon is encoded as groups of 3 bits, packed into a single integer.

Each group of bits is decoded as follows:

* **bit 0**: if set, repeat \\$n-1\\$ times; if cleared, repeat \\$n\\$ times
* **bits 1-2**: if both bits are cleared, decrement the width at each iteration; if only bit 1 is set, increment the width after at iteration; otherwise, leave it unchanged

The initial width of the shape is:

$$w=\cases{ 0,&\text{if $i=0$}\\ n,&\text{if $i=1$}\\ n-1,&\text{if $i\>1$} }$$

### Triangle (\\$i=0\\$)

```
..1
.1.1
1.1.1

```

One group: repeat \\$n\\$ times, increment the width → encoded as \\$2\\$

### Square (\\$i=1\\$)

```
1.1.1
1.1.1
1.1.1

```

One group: repeat \\$n\\$ times, leave the width unchanged → encoded as \\$4\\$

### Hexagon (\\$i=2\\$)

```
..1.1.1
.1.1.1.1
1.1.1.1.1
.2.2.2.2
..2.2.2

```

Two groups:

* group 1: repeat \\$n\\$ times, increment the width → encoded as \\$2\\$
* group 2: repeat \\$n-1\\$ times, decrement the width → encoded as \\$1\\$

Final encoding: \\$2+8\times1=10\\$

### Octagon (\\$i=3\\$)

```
..1.1.1
.1.1.1.1
1.1.1.1.1
2.2.2.2.2
2.2.2.2.2
.3.3.3.3
..3.3.3

```

Three groups:

* group 1: repeat \\$n\\$ times, increment the width → encoded as \\$2\\$
* group 2: repeat \\$n-1\\$ times, leave the width unchanged → encoded as \\$5\\$
* group 3: repeat \\$n-1\\$ times, decrement the width → encoded as \\$1\\$

Final encoding: \\$2+8\times5+8^2\times1=106\\$
> 4 votes

# Answer
# Charcoal, 70 bytes

```
≔⁰ζＷφ«⎚≦⊕ζ≔∨⁼θ3ζδ≔Ｅ⮌ηκφＰ⪫Ｅδ⊟φ Ｆ§⪪”;↧↷$↑Ｒ{Ｐ≧⍘”,ＩθＦ⊖ζ«Ｍ✳Ｉκ≧⁺⁻⁶ＩκδＰ⪫Ｅδ⊟φ

```

Try it online! Link is to verbose version of code. Takes input as the number of sides and the characters. Explanation:

```
≔⁰ζ

```

Keep track of the size of the polygon.

```
Ｗφ«

```

Repeat until we find a size that consumes the input. (This variable is predefined to the truthy value `1000` but I'm going to redefine it.)

Clear the previous attempt from the canvas.

```
≦⊕ζ

```

Increment the polygon size.

```
≔∨⁼θ3ζ

```

Calculate the number of characters in the first row, which is `1` for the triangle and the size for the other shapes.

```
δ≔Ｅ⮌ηκφ

```

Convert the characters from a string into a list and reverse them. This allows us to iterate over them by popping from the list, which will become empty if we pop all of them.

```
Ｐ⪫Ｅδ⊟φ

```

Print the first row of the polygon.

```
Ｆ§⪪”;↧↷$↑Ｒ{Ｐ≧⍘”,Ｉθ

```

Loop over one of four strings, `5`, `6`, `57` or `567`, depending on the number of sides. These correspond to the Charcoal directions of the left-most character in each row.

```
Ｆ⊖ζ«

```

Loop for one fewer row than the polygon size.

```
Ｍ✳Ｉκ

```

Move in the desired direction.

```
≧⁺⁻⁶Ｉκδ

```

Calculate the number of characters in this row.

```
Ｐ⪫Ｅδ⊟φ

```

Print the row.
> 2 votes

# Answer
# Python 3, ~~600~~ ~~548~~ ~~503~~ ~~458~~ ~~358~~ ~~349~~ ~~346~~ ~~326~~ 324 bytes

```
lambda n,s:p(s,q(s,(0,1,1,1.2)[n],(1,.5,3,5)[n]),n)
q=lambda s,p,q:int(p/2+(p*p/4+len(s)/q)**.5)
g=lambda s,j,i,c,n=1,l=[]:s and-~i and g(s[i:],j,i+(-1,1,0)[(2,1,n<j,(n<j*2-1)+(0<=n-j<j-1))[c]],c,n+1,l+[s[:i]])or l
p=lambda s,k,c:"\n".join([" ".join(i).center(k*(1,(2,4)[c>1])[c>0]-2)for i in g(s,(0,k)[c>1],(k,0)[c==1],c)])

```

Try it online!

I Know it is a bit long but i want to commit it and improve it over time...

The inputs are:
0 = Triangle
1 = square
2 = Hexagon
3 = Octagon

Thanks to:
\- @caird coinheringaahing for saving 2 bytes
> 2 votes

# Answer
# 05AB1E, 32 bytes

```
∞εLDN+DûsÂćNиì«yDи)¹è}.ΔO∍Q}£».c

```

Try it online!

First input is 0 for triangle, 1 for hex, 2 for oct, 3 for square. Second input is a list of characters. The program will hang forever if the list isn't of a valid length.

```
∞                       # infinite list [1, 2, 3...]
 ε                   }  # map each integer y to a polygon with side length y:
  L                     #  range 1..y (=> triangle)
   D                    #  duplicate
    N                   #  0-based iteration count (effectively y-1)
     +                  #  vectorized add, yielding y..(2y-1)
      D                 #  duplicate
       û                #  palindromize (=> hexagon)
        s               #  swap to get the other copy of y..(2y-1)
         Â              #  push a reversed copy: (2y-1)..y
          ć             #  head extract: 2y-1
           Nи           #  repeat that y-1 times
             ì          #  prepend that to the reversed list
              «         #  append it to the original list (=> octogon)
               y        #  push y
                Dи      #  repeat it y times (=> square)
                  )     #  wrap all polygons in a list
                   ¹è   #  index into the list using the first input
 .Δ   }                 # get the first polygon such that:
   O                    #  its sum
    ∍Q                  #  is equal to the length of the input
 £                      # cut the input in this shape
  »                     # join by newlines, joining sublists with spaces
   .c                   # center

```
> 2 votes

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


title: Game of Set Puzzle

text:
# Question
Title: Game of Set Puzzle
May be you know the game of Set (a wonderful game for kids btw) a card game with 81 cards, where each card has a figure on it with 4 different attributes (form , number, colour and fill). Each attribute has 3 different values:

```
form: wave, oval, diamond
colour: red, purple, and green
number: 1, 2, 3
fill: none, dashed, opaque.

```

12 cards are laid open on the table and now the challenge is to indicate sets. A set consists of three cards where every attribute value occurs 0, 1 or 3 times. having 2 cards with red figures, or opaque, or 1 number is no good. See the supplied link for a more visual explanation.

I do envision a code for a card where all attributes are encoded so

```
"WP2N"

```

stands for

```
2 Purple Waves with No fill

```

Together with for instance `OR1N` and `DG3N`

and

it is a set (3 different forms, 3 different colors, 3 different number, 1 fill).

Input is space delimited string of unique codes (randomly chosen out of 81 possible codes) representing cards.

```
"OR1N WP2N DG3N DR1D WG3S WG1N WR2D WP3N DR2O DR2D OG3O OR2D"

```

The solution must indicate all possible sets within the given collection. So

```
OR1N, WP2N, DG3N

```

must be part of the solution together with all other sets.

# Answer
## Ruby, ~~104~~ ~~98~~ ~~81~~ 80 characters

```
$*.combination(3).map{|c|puts c*?,if(0..3).all?{|i|c.map{|x|x[i]}.uniq.size!=2}}

```

Sample run (using your example data):

```
c:\a\ruby>set.rb OR1N WP2N DG3N DR1D WG3S WG1N WR2D WP3N DR2O DR1D OG3O OR2D
OR1N,WP2N,DG3N
WP2N,DR1D,OG3O
WP2N,DR1D,OG3O
DG3N,WG3S,OG3O

```

It outputs `WP2N,DR1D,OG3O` twice because you have two `DR1D`s in your sample data.

Explanation:

`$*.combination(3).map{|c|` \- each combination of 3 cards
`puts c*?,if` \- output the set, if...
`(0..3).all?{|i|` \- if all of the numbers from 0 to 3 (the indeces of the properties in the string) evaluate to `true` when passed into this block
`c.map{|x|x[i]}` \- take the `i`th index of each string
`.uniq.size!=2}` \- if the amount of unique properties (form, color, etc.) is not 2 (so, 1 or 3)
> 4 votes

# Answer
# Mathematica ~~93 92 93 82 76~~ 73

```
f={}⋃Select[StringSplit@#~Subsets~{3}, FreeQ[Tally/@(Characters@#^T),2]&]&

```

**The Logic**

`StringSplit@#~Subsets~{3}` produces a list of 3-card subsets. Each triple such as:

{{"D", "G", "3", "N"}, {"W", "G", "3", "S"}, {"O", "G", "3", "O"}}

or

is then transposed,

and `Tally/@(Characters@#^T)` tallies the number of distinct items in each row.

```
{3,1,1,3}

```

3 corresponds to "all different"; 1 corresponds to "all same".

`FreeQ[...,2]` determines whether 2 cards of the same type or in the triple. If 2 is not among the tallies, then the three cards are a "set", according to Game of Set rules.

---

**Usage**

```
f["OR1N WP2N DG3N DR1D WG3S WG1N WR2D WP3N DR2O DR1D OG3O OR2D"]

```

> {{"DG3N", "WG3S", "OG3O"}, {"OR1N", "WP2N", "DG3N"}, {"WP2N", "DR1D", "OG3O"}}
> 5 votes

# Answer
# Mathematica 73

```
f = Select[StringSplit@#~Subsets~{3}, FreeQ[Tally /@ Thread@Characters@#, 2] &] &

```

**Usage**

```
f["OR1N WP2N DG3N DR1D WG3S WG1N WR2D WP3N DR2O DR1D OG3O OR2D"]

```

> {{"OR1N", "WP2N", "DG3N"}, {"WP2N", "DR1D", "OG3O"}, {"WP2N", "DR1D", "OG3O"}, {"DG3N", "WG3S", "OG3O"}}
> 4 votes

# Answer
# Brachylog, 12 bytes

```
ṇ₁⊇Ṫz{=|≠}ᵐz

```

Try it online!

Takes input through the input variable and generates the output through the output variable.

Second test case taken from a recently closed duplicate in its encoding, since this solution doesn't really care what anything actually means.

```
                The output variable is
  ⊇             a subsequence
   Ṫ            of length 3
ṇ₁              of the input split on spaces,
    z      z    the columns of which
     {   }ᵐ     are all
       |        either
      =         the same element repeated,
        ≠       or entirely free of duplicates.

```
> 4 votes

# Answer
### GolfScript, 53 characters

```
" "/:w,,{:a,{:^,{a^]{w=}%.0\zip{.&,2=|}/!{.p}*;}/}/}/

```

Input must be provided on STDIN, example online:

```
> OR1N WP2N DG3N DR1D WG3S WG1N WR2D WP3N DR2O DR2D OG3O OR2D
["OR1N" "DG3N" "WP2N"]
["WP2N" "OG3O" "DR1D"]
["DG3N" "OG3O" "WG3S"]
["WR2D" "OR2D" "DR2D"]

```

Commented code:

```
" "/:w          # split the input at spaces and assign it to variable w
,,              # create the array [0..n-1] (n being the length of w)
{:a,{:^,{       # three nested loops: a=0..n-1, ^=0..a-1, _=0..b-1
                # (third loop has no variable assigned but just pushes on stack)
    a^]         # make an array [a,^,_] of the three loop variables
    {w=}%       # take the corresponding list items, i.e. [w[a],w[^],w[_]]
    .0\         # push zero, add duplicate of the the array
    zip         # zip transposes the array, thus [OR1N WP2N DG3N] -> [OWD RPG 123 NNN]
    {           # loop over those entries
      .&        # unique
      ,2=       # length equals 2?
      |         # "or" with top of stack (two zero pushed before)
    }/          # end of loop, on stack remains the results of the "or"s
    !{.p}*      # if no length of 2 is there, make a copy of the set and print it
    ;           # discard stack item
}/}/}/          # closing the three nested loops

```
> 3 votes

# Answer
## javascript ~~323~~ 313

```
function a(b){d=h=[];c=e=f=0;for(i in b){for(j in b){for(k in b[i]){if(b[i][k]==b[j][k]){if(c+f<4)c++;else if(c==4){h+=b[j];if(h.length=3)return h}}else{for(l in d){for(m in d[l]){g=f;if(d[l][2]==i){if(d[l][3]==k)if(b[j][k]!=d[l][0]&&b[j][k]!=d[l][1])f++;}else{continue}}if(g==f)d[e++]=[b[i][k],b[j][k],j,k]}}}}}}

```

its a function that takes a array of objects, and returns a array of objects.

DEMO fiddle (with tidy-up).
> 1 votes

# Answer
## APL(IBM), 76

```
⍉¨x/⍨{{⍵≡1⌽⍵}⍵=1⌽⍵}¨x←⊃¨(∘.,/3⍴⊂⍪¨(' '≠y)⊂y←⍞)⌷⍨¨z/⍨∧/¨2</¨z←,⍳3⍴12

```

I don't have IBM APL, but I believe this will work.

**Sample run (Emulating IBM APL in Dyalog APL)**

```
OR1N WP2N DG3N DR1D WG3S WG1N WR2D WP3N DR2O DR1D OG3O OR2D
 OR1N  WP2N  WP2N  DG3N
 WP2N  DR1D  DR1D  WG3S
 DG3N  OG3O  OG3O  OG3O

```
> 1 votes

# Answer
## Sage, 71

If `C` is a string, say `"OR1N WP2N DG3N DR1D WG3S WG1N WR2D WP3N DR2O DR1D OG3O OR2D"`, execute

```
[c for c in Subsets(C.split(),3)if{1,3}>={len(set(x))for x in zip(*c)}]

```

to get `[{'DR1D', 'OG3O', 'WP2N'}, {'DR2D', 'WR2D', 'OR2D'}, {'WG3S', 'OG3O',
'DG3N'}, {'DG3N', 'WP2N', 'OR1N'}]`

And here's a very different approach using the interpretation that a Set is a projective line in `GF(3)^4`:

```
[c for c in Subsets(C.split(),3)if sum(matrix(3,map('WODRPG123N'.find,''.join(c))))%3==0]

```

I was a little annoyed that `D` was used twice... until I figured how to abuse that. But even better, I abuse the `find` method, too. `str.find` returns -1 if a letter isn't found. Since `-1 = 2 mod 3`, the letter `S` is handled appropriately because it doesn't occur in `'WODRPG123N'`.
> 1 votes

# Answer
# Python 2, 99 bytes

```
lambda A:[a for a in combinations(A,3)if all(len(set(t))-2for t in zip(*a))]
from itertools import*

```

Try it online!
> 1 votes

---
Tags: code-golf
---


# Question
Title: Multigraphs with a given degree sequence
This challenge will give you an input of a degree sequence in the form of a partition of an even number. Your goal will be to write a program that will output the number of loop-free labeled multigraphs that have this degree sequence.

## Example

For example, given the input `[3,3,1,1]`, you should output the number of labeled multigraphs on four vertices \\$\\{v\_1, v\_2, v\_3, v\_4\\}\\$ such that \\$\deg(v\_1) = \deg(v\_2) = 3\\$ and \\$\deg(v\_3) = \deg(v\_4) = 1\\$. In this example, there are three such multigraphs:

See Gus Wiseman's links on OEIS sequence A209816 for more examples.

## Target data

```
input           | output
----------------+--------
[6,2]           | 0
[5,3,2]         | 1
[3,3,1,1]       | 3
[4,3,1,1,1]     | 6
[4,2,1,1,1,1]   | 10
[1,1,1,1,1,1]   | 15
[3,2,2,2,1]     | 15
[2,2,2,2,2]     | 22
[7,6,5,4,3,2,1] | 7757

```

# Challenge

This is so shortest code in bytes wins.

# Answer
> 5 votes
# Haskell, 57 bytes

```
f(h:t)=sum[f l|l<-mapM(\n->[0..n])t,sum t-sum l==h]
f _=1

```

Try it online!

# Answer
> 3 votes
# Haskell, 127 bytes

```
e=[]:e
h a b=mapM id$b<$a
f a=length[0|x<-h a$h a[0..maximum a],x==foldr(zipWith(:))e x,all(<1)$zipWith(!!)x[0..],map sum x==a]

```

Try it online!

Very very inefficient (superexponential), but I believe it should work in theory. Exceeds Tio's 60 second limit with `[3, 3, 1, 1]` as input, but works with `[1, 1, 1, 1]`.

Considers the adjacency matrices of the multigraphs.

`h a$h a[0..maximum a]` is a list of all square matrices with entries between `0` and `maximum a`, with size `length a`.

`x==foldr(zipWith(:))e x` checks if a matrix is symmetric.

`all(<1)$zipWith(!!)x[0..]` checks that the diagonal entries are zero, since there are no loops.

`map sum x==a` checks that each vertex has the proper degree.

# Answer
> 3 votes
# Haskell, 75 bytes

```
f(h:t)=sum$f<$>h%t
f[]=1
r%(h:t)=[h-i:x|i<-[0..r],x<-(r-i)%t]
r%_=[[]|r==0]

```

Try it online!

It's faster (and easier to understand) when `i<-[0..r]` is replaced by `i<-[0..min r h]`. Also, it's faster to give the degrees (whose order obviously doesn't matter) in increasing order.

---
Tags: code-golf, combinatorics, graph-theory, integer-partitions
---


# Question
Title: It's as easy as 1,2,3 (except you have to add them up)
Let's consider a list \\$L\\$ (initially empty) and a pointer \\$p\\$ into this list (initialized to \\$0\\$).

Given a pair of integers \\$(m,n)\\$, with \\$m\ge 0\\$ and \\$n\>0\\$:

1. We set all uninitialized values in \\$L\\$ up to \\$p+m+n\\$ (excluded) to \\$0\\$.
2. We advance the pointer by adding \\$m\\$ to \\$p\\$.
3. We create a vector \\$\[1,2,...,n\]\\$ and 'add' it to \\$L\\$ at the position \\$p\\$ updated above. More formally: \\$L\_{p+k} \gets L\_{p+k}+k+1\\$ for each \\$k\\$ in \\$\[0,..,n-1\]\\$.

We repeat this process with the next pair \\$(m,n)\\$, if any.

Your task is to take a list of pairs \\$(m,n)\\$ as input and to print or return the final state of \\$L\\$.

## Example

Input: `[[0,3],[1,4],[5,2]]`

* initialization:

```
p = 0, L = []

```
* after `[0,3]`:

```
p = 0, L = [0,0,0]
         + [1,2,3]
         = [1,2,3]

```
* after `[1,4]`:

```
p = 1, L = [1,2,3,0,0]
         +   [1,2,3,4]
         = [1,3,5,3,4]

```
* after `[5,2]`:

```
p = 6, L = [1,3,5,3,4,0,0,0]
         +             [1,2]
         = [1,3,5,3,4,0,1,2]

```

## Rules

* Instead of a list of pairs, you may take the input as a flat list \\$(m\_0,n\_0,m\_1,n\_1,...)\\$ or as two separated lists \\$(m\_0,m\_1,...)\\$ and \\$(n\_0,n\_1,...)\\$.
* You may assume that the input is non-empty.
* The output must *not* contain any trailing \\$0\\$'s. However, all intermediate or leading \\$0\\$'s *must* be included (if any).
* This is .

## Test cases

Input:

```
[[0,3]]
[[2,3]]
[[0,4],[0,5],[0,6]]
[[0,3],[2,2],[2,1]]
[[0,1],[4,1]]
[[0,3],[1,4],[5,2]]
[[3,4],[3,4],[3,4]]
[[0,1],[1,2],[2,3],[3,4]]
[[2,10],[1,5],[2,8],[4,4],[6,5]]

```

Output:

```
[1,2,3]
[0,0,1,2,3]
[3,6,9,12,10,6]
[1,2,4,2,1]
[1,0,0,0,1]
[1,3,5,3,4,0,1,2]
[0,0,0,1,2,3,5,2,3,5,2,3,4]
[1,1,2,1,2,3,1,2,3,4]
[0,0,1,3,5,8,11,14,11,14,17,20,12,0,0,1,2,3,4,5]

```

# Answer
> 5 votes
# Jelly, ~~12~~ 11 bytes

```
+ɼ0x;R}ʋ/€S

```

Try it online!

A full program that takes a list of lists of integers as its argument and returns a list of integers. Can be adapted to work as a link by resetting the register to zero after each call (as implemented in the footer on TIO).

Saved a byte now list can be non-empty.

# Answer
> 5 votes
# , 27 bytes

```
[:+/[(>:@i.@[,~0$~])"0+/\@]

```

Try it online!

Takes two separate lists for `m` an `n` \- the list for `n` is the left argument of the function, the list for `m` \- the right one.

# K (ngn/k), 42 bytes

```
{+/{x,'((|/#'x)-#'x)#'0}((+\x)#'0),'1+!'y}

```

Try it online!

Takes two separate lists for `m` an `n`

It's too long currently, I'll try to golf it.

# Answer
> 5 votes
# Java 8, ~~148~~ 147 bytes

```
N->M->{int l=M.length,s=M[l-1],p=0,L[],i=0,j;for(int n:N)s+=n;for(L=new int[s];i<l;i++)for(p+=N[i],j=s;j-->0;)L[j]-=j<p|j>=p+M[i]?0:~j+p;return L;}

```

-1 byte thanks to *@ceilingcat*.

Takes both integer-arrays as separated inputs.

Try it online.

**Explanation:**

```
N->M->{            // Method with integer-array as two parameters as well as return-type
  int l=M.length,  //  Length of the input-arrays
      s=           //  Length of the output-array,
        M[l-1],    //  starting at the last pointer-item of array `M`
      p=0,         //  Position `p` as specified in the challenge, starting at 0
      L[],         //  Output list, starting uninitialized
      i=0,j;       //  Index integers
  for(int n:N)     //  Loop over the value-list `N`:
    s+=n;          //   And add all of them to the output-length
  for(L=new int[s];//  Now initialize the output-list of size `s`, filled with 0s by default
      i<l;i++)     //  Loop `i` in the range [0, `l`):
    for(p+=N[i],   //   Increase position `p` by the `i`'th pointer of `N`
        j=s;j-->0;)//   Inner loop `j` in the range (`s`,0]:
     L[j]-=        //    Decrease the `j`'th item of the output-list by:
       j<p         //     If `j` is smaller than position `p`
       |j>=        //     or `j` is larger than or equal to
        p+M[i]?    //     pointer `p` and the `i`'th value of `M` combined
         0         //      Leave the `j`'th item of output-array the same by adding 0
       :           //     Else:
        ~j+p;      //      Decrease the `j`'th item of the output-array by `-j-1+p`
                   //      (increase it by the difference between `j` and `p`, plus 1)
  return L;}       //  And after the nested loops: return the resulting array

```

# Answer
> 5 votes
# Jelly,  ~~10~~  9 bytes

```
Ä0ẋżR}F€S

```

A dyadic Link accepting a list of integers on each side, \\$M\\$ on the left \\$N\\$ on the right, which yields a list of integers.

**Try it online!** Or see the test-suite.

### How?

```
Ä0ẋżR}F€S - Link: list of integers, M; list of integers, N
Ä         - cumulative sums (M) = [m1, m1+m2, m1+m2+m3, ...]
 0ẋ       - zero repeated = [[0]*m1,[0]*(m1+m2),[0]*(m1+m2+m3), ...]
    R}    - range (right=N) = [[[1,2,3,...,n1]],[[1,2,3,...n2]],[[1,2,3,...,n3]], ...]
   ż      - zip together = [[[0]*m1,[[1,2,3,...,n1]]],[[0]*(m1+m2),[[1,2,3,...,n2]]],[[0]*(m1+m2+m3),[[1,2,3,...,n3]]], ...]
      F€  - flatten each = [[0,0,...,0,1,2,3,...,n1],[0,0,...,0,1,2,3,...,n2],[0,0,...,0,1,2,3,...,n3], ...]
        S - sum

```

# Answer
> 4 votes
## Haskell, ~~90~~ 87 bytes

```
(foldl(%)[].).zipWith(\o p->(0<$[1..o])++[1..p]).scanl1(+)
(a:b)%(c:d)=a+c:b%d
b%d=b++d

```

Takes the input as two separate lists `[m0,m1,...]` and `[n0,n1,...]`.

Try it online!

A variant (function `%` same as above), also 87 bytes:

```
(foldl(\l(o,p)->((0<$[1..o])++[1..p])%l)[].).zip.scanl1(+)

```

# Answer
> 4 votes
# Zsh, ~~59 56~~ 54 bytes

***-3 bytes** by changing to my Bash strategy, **-2 bytes** by switching back to my original strategy, now that the rules specify the list is non-empty.*

```
for m n;for ((i=0,p+=m;i<n;a[p+i]+=++i)):
<<<${a/#%/0}

```

**Try it online:** \[Original strat handling empty case\] \[Adapted Bash strat\] **\[Current\]**

---

Setting `a[5]=1` causes `a[1]` through `a[4]` to be initialized empty. The final parameter expansion replaces all empty elements with `0`.

```
for m n                                 # implicit 'in "$@"'
    for ((i=0, p+=m; i<n; a[p+i]+=++i)) # increment p by m, add to a[p,p+n-1]
        :                               # ':' is a no-op builtin
<<<${a/#%/0}                            # the glob #% matches empty elements

```

# Answer
> 3 votes
# Python 3, ~~144~~ ~~119~~ ~~118~~ ~~111~~ ~~110~~ 106 bytes

```
def f(m,n):
 p=k=0;l=[]
 for i,j in zip(n,m):p+=j;l+=[0]*(p+i-len(l));exec("l[~k]+=i-k;k+=1;"*i)
 return l

```

Try it online!

Thanks to:
-@mypetlion for saving me 25 bytes

# Answer
> 3 votes
# Wolfram Language (Mathematica), ~~62...50~~ 45 bytes

```
Plus@@PadRight[a=1;Ramp@Range[a-=#,#2]&@@@#]&

```

Try it online!

Input a list of pairs.

# Answer
> 3 votes
# PHP, 93 bytes

```
for(;$n=$argv[++$i+1];)for($p+=$argv[$i++];$$i<$p+$n;)$l[$$i]+=$$i++<$p?0:$$i-$p;print_r($l);

```

Try it online!

Input is a flat list of `m0,n0,m1,n1,...` passed by command arguments (`$argv`) and output is string representation of `L`.

# Answer
> 3 votes
# APL (Dyalog Unicode), 19 bytes

```
1⊥0⌈(↑(⍳+)¨-⊢)∘(+\)

```

Try it online!

Uses the algorithm described in my J answer.

### How it works

```
1⊥0⌈(↑(⍳+)¨-⊢)∘(+\)  left = n's, right = m's
              ∘(+\)  m2 = cumulative sum of m's
      (⍳+)¨          Nested array of 1..(each element of n+m2)
           -⊢        Subtract each elem of m2 from each row
    (↑       )       Promote nested array to matrix
  0⌈                 Take max with 0 (change negatives to 0)
1⊥                   Sum in column direction

```

---

# APL (Dyalog Unicode), 20 bytes

```
{1⊥↑⍺{(⍵⍴0),⍳⍺}¨+\⍵}

```

Try it online!

A dyadic dfn whose left argument is the `n`s and right argument is `m`s.

### How it works

```
{1⊥↑⍺{(⍵⍴0),⍳⍺}¨+\⍵}
{                  }  ⍺ = n's, ⍵ = m's
                +\⍵   Cumulative sum of offsets (M)
    ⍺{        }¨      Zip with n's
      (⍵⍴0),⍳⍺        ... to create M zeros followed by 1..n
   ↑                  Promote to matrix, filling zeros where necessary
 1⊥                   Sum column-wise

```

# Answer
> 3 votes
# 05AB1E, 13 bytes

```
ηOÅ0s€L‚ø€˜0ζO

```

Takes two separated lists. The list of positions \\$(m\_0, m\_1, m\_2, ...)\\$ as first input and list of values \\$(n\_0, n\_1, n\_2, ...)\\$ as second input.

Try it online or verify all test cases.

**Explanation:**

```
η        # Get all prefixes of the (implicit) input-list of positions
         #  i.e. [0,1,5] → [[0],[0,1],[0,1,5]]
 O       # Sum each inner list
         #  → [0,1,6]
  Å0     # Convert each of the inner values into a list of 0s of that length
         #  → [[],[0],[0,0,0,0,0,0]]
s        # Get the second (implicit) input-list of values
 L       # And create a list in the range [1,n] of each value
         #  i.e. [3,4,2] → [[1,2,3],[1,2,3,4],[1,2]]
‚        # Pair the two lists together
         #  → [[[],[0],[0,0,0,0,0,0]],[[1,2,3],[1,2,3,4],[1,2]]]
 ø       # Zip/transpose, swapping rows/columns
         #  → [[[],[1,2,3]],[[0],[1,2,3,4]],[[0,0,0,0,0,0],[1,2]]]
  €˜     # Flatten each inner pair to a single inner list
         #  → [[1,2,3],[0,1,2,3,4],[0,0,0,0,0,0,1,2]]
    0ζ   # Zip/transpose, swapping rows/column, with 0 as trailing filler
         #  → [[1,0,0],[2,1,0],[3,2,0],[0,3,0],[0,4,0],[0,0,0],[0,0,1],[0,0,2]]
      O  # Take the sum of each inner list
         #  → [1,3,5,3,4,0,1,2]
         # (after which the result is output implicitly)

```

# Answer
> 3 votes
# Ruby, ~~92~~ ~~88~~ 84 bytes

```
->x{n,l=0,[];x.map{|a,b|0.upto(b-1+n+=a){|i|l[i]||=0};1.upto(b){|i|l[-i]+=1+b-i}};l}

```

Input is a list of pairs, in the form `[[m1, n1], [m2, m2], ...]`.

The approach is pretty much the algorithm as described.

Golfy tricks I've used include:

* `l[i]||=0` setting the value for L to 0 if it isn't already set
* That's pretty much it.

Thanks to Value Ink for

Try it online!

Ruby can be pretty terse. When the version with numbered block parameters comes out, this can be reduced by a few bytes to this (note the `@1` ins:

```
->x{n,l=0,[];x.map{|a,b|0.upto(b-1+n+=a){l[@1]||=0};1.upto(b){l[-@1]+=1+b-@1}};l}

```

# Answer
> 3 votes
# , 20 bytes

```
+/@(0>.>:@i.@+-])+/\

```

Try it online!

I guess this is quite different from both Galen Ivanov's and Jonah's answers. A dyadic train that takes `n`s as left argument and `m`s as right.

One trick was to avoid `(...)"0` (apply to each item) in favor of `...@+`. The conjunction `u@v` has the effect of `u@:v"v`. The rank-forcing effect is usually not desirable when `v` is an arithmetic verb, but it works perfectly here.

### How it works

```
+/@(0>.>:@i.@+-])+/\  Left(n): range generators ex) 3 4 2
                      Right(m): offsets ex) 0 1 5
                 +/\  cm: Cumulative sum of offsets ex) 0 1 6
             +        Add n and cm element-wise ex) 3 5 8
          i.@         Generate 0..x-1 for each x above
                      ex) 0 1 2;0 1 2 3 4;0 1 2 3 4 5 6 7
       >:@            Increment each value
                      ex) 1 2 3;1 2 3 4 5;1 2 3 4 5 6 7 8
                      (Implicit) Form a 2D array, padding with 0s where needed
              -]      Subtract each item of cm from each row of above
                      ex)  1  2  3  0  0  0  0  0
                           0  1  2  3  4 -1 -1 -1
                          -5 -4 -3 -2 -1  0  1  2
    0>.               Max with 0; Change negative numbers to 0s
+/@(            )     Take sum in column direction

```

# Answer
> 2 votes
# Bash, 77 bytes

```
for N;{
b=($N)
for((i=0,p+=b;i<p+b[1];a[i]+=++i>p?i-p:0)){ :;}
}
echo ${a[@]}

```

Try it online!

I couldn't port my first Zsh answer directly, since `${a[@]/#%/0}` doesn't work in Bash. So instead of fixing the empty elements at the end, I set all the elements with `a[i]+=0` along the way. ~~In the end, this strategy works out better for Zsh anyway!~~

# Answer
> 2 votes
# C, ~~204~~ ~~196~~ ~~195~~ ~~192~~ 185 bytes

```
*c(m,n,q,x,p,z)int*m,*n;{int i,j,*a=malloc(4);for(i=p=z=0;m[i]+1;i++){q=n[i]+(p+=m[i]);a=realloc(a,8*((x=z)>q?z:(z=q)));bzero(a+x,(z-x)*8);for(j=p;j<q;j++)a[j]+=j-p+1;}a[z]--;return a;}

```

De-golfed version:

```
* count (m, n, size_of_array, pointer_into_array, previous_size_of_array, final_element_counted_to) //all but m and n are implicitly int - return type of function is implicitly int pointer
     int* m, * n;
{
  pointer_into_array = size_of_array = 0;
  int* array = malloc(sizeof(int)); //get a pointer so we can realloc later
  for (int i = 0; m[i] + 1; i++) { //iterate through m and n, stopping at -1 sentinel value
    final_element_counted_to = n[i] + (pointer_into_array += m[i]); //update pointer, get final element counted to on this pair
    array = realloc(array, sizeof(int) * 2 * ((previous_size_of_array = size_of_array) > final_element_counted_to ? size_of_array : (size_of_array = final_element_counted_to) + 1)); //reallocate array to size of max(size_of_array, final_element_counted_to+1) * sizeof(int) * 2 [multiplying by 2 for the final statement of a[z] = -1]
    bzero(array + previous_size_of_array, (size_of_array - previous_size_of_array) * sizeof(int) * 2); //initialises new memory to zero
    for(int j = pointer_into_array; j < final_element_counted_to; j++) //do the actual counting + adding
      array[j] += j - pointer_into_array + 1;
  }
  array[size_of_array]--; //make sure it's terminated by -1
  return array;
}

```

Try it online!

Function `c` takes two arguments (rest are for free declaration) `m` and `n`, both -1 terminated arrays corresponding respectively to the two separate lists for m and n. It returns a -1 terminated array.

Please note that this requires `sizeof(int)` to be 4, and also requires the non-standard and deprecated but widely-implemented function `bzero`.

# Answer
> 2 votes
# K (ngn/k), 30 bytes

```
{+/0^(1+!'y)@'-n-\:!*|y+n:+\x}

```

Try it online!

# Answer
> 1 votes
# Java, 642 Bytes

This I think is kind of awful, but doing it with Java who knows what I was expecting. If someone could help me make this better I would really appreciate that, a bunch of bytes are taken up dealing with the fact that combiner can get two different length lists and need to add them, and also with the fact that there is a type needed for the BiConsumer lambda. I think there are a few ways, but it's getting late...

Input is n, expected to be an array of arrays.

```
    IntStream.range(0, n.length).mapToObj((x) -> new int[] { n[x][0] + (x > 0 ? n[x - 1][0] : 0), n[x][1]})
            .map((v) -> IntStream.range(0, v[0] + v[1]).map((x) -> x >= v[0] ? 1 + x - v[0] : 0).toArray())
            .collect(Collector.of(
                () -> new ArrayList<>(),
                (BiConsumer<List<Integer>, int[]>) (l, v) -> IntStream.range(0, Math.max(l.size(), v.length)).forEach((i) -> {
                    if (i >= l.size()) l.add(0);
                    if (i < v.length) l.set(i, l.get(i) + v[i]);
                }),
                (a, b) -> {
                    while (a.size() > b.size()) b.add(0);
                    while (b.size() > a.size()) a.add(0);
                    return IntStream.range(0, a.size()).mapToObj((i) -> a.get(i) + b.get(i)).collect(Collectors.toList());
                },
                Characteristics.IDENTITY_FINISH
            ));

```

Improved and golf'd by Kevin Cruijssen:

```
n->IntStream.range(0,n.length).mapToObj(x->new int[]{n[x][0]+(x>0?n[x-1][0]:0),n[x][1]}).map(v->IntStream.range(0,v[0]+v[1]).map(x->x<v[0]?0:1+x-v[0]).toArray()).collect(Collector.of(()->new Stack<>(),(java.util.function.BiConsumer<List<Integer>,int[]>)(l,v)->IntStream.range(0,Math.max(l.size(),v.length)).forEach(i->{if(i>=l.size())l.add(0);if(i<v.length)l.set(i,l.get(i)+v[i]);}),(a,b)->{while(a.size()>b.size())b.add(0);while(b.size()>a.size())a.add(0);return IntStream.range(0,a.size()).mapToObj(i->a.get(i)+b.get(i)).collect(Collectors.toList());},Collector.Characteristics.IDENTITY_FINISH))

```

# Answer
> 1 votes
# Clojure, 170 Bytes

```
(fn [a](reduce #(mapv +(concat %1(repeat 0))%2)(mapv (fn [[x y]](concat(repeat x 0)(range 1(+ 1 y))))(reduce #(conj %1(mapv +[(nth(last %1)0)0]%2))[(first a)](rest a)))))

```

Try it online!

---
Tags: code-golf, array
---


title: Spelling on a Grid

text:
# Question
Title: Spelling on a Grid
*(based on this deleted question)*

Take the English alphabet `a b c d e f g h i j k l m n o p q r s t u v w x y z` (spaces added for clarity), and split it into chunks of `X` width, padding any leftover lines with spaces if necessary for your language. For example, splitting it into width `4` results in

```
a b c d
e f g h
i j k l
m n o p
q r s t
u v w x
y z

```

Now, given a word composed of `[a-z]+`, output the path taken to spell that word when starting from `a` and using `!` to specify selecting that letter, with `D U R L` for `Down, Up, Right, Left`, respectively.

For the above `X=4` example, and the word `dog`, the output would be `R R R ! L D D D ! U U !` (spaces added for clarity and not required in output).

If `X=3`, you get a different picture of the alphabet:

```
a b c
d e f
g h i
j k l
m n o
p q r
s t u
v w x
y z

```

And a different solution for the word `dog` -- `D ! D D D R R ! L L U U !`.

## Examples

```
"dog" 4 --> R R R ! L D D D ! U U !
"dog" 3 --> D ! D D D R R ! L L U U !
"hello" 6 --> R D ! R R R U ! R D ! ! D L L L !
"codegolf" 10 --> R R ! R R D ! L U ! R ! R R ! L L D ! L L L ! U R R R R !
"acegikmoqsuwy" 2 --> ! D ! D ! D ! D ! D ! D ! D ! D ! D ! D ! D ! D !

```

## Rules

* Note that the grid *doesn't* wrap, so to get from the leftmost column to the rightmost column requires traversing the entire `X` distance.
* The output must be a shortest possible path, but doesn't necessarily need to be in a particular order. For example, for the first `dog` example you could instead produce `R R R ! D D D L ! U U !`, swapping the order of the `D`owns and the `L`eft, because that's the same length path and achieves the same character.
* Similarly, please output only one path (because there will likely be multiple), but that doesn't need to be deterministic (i.e., multiple runs of your program may produce different paths, provided they're all the shortest).
* The output doesn't have to have delimiters (like I do here with spaces), that's up to your aesthetic choice.
* You can choose input as all-lowercase or all-uppercase, but it must be consistent.
* The input number is guaranteed to be in the range `1` to `26` (i.e., a single column to a single row of letters).
* Input words are guaranteed to be at least one character long, and match `[a-z]+` with no other punctuation, spaces, etc., (i.e., you'll never receive empty string `""` as input), but it may not be an actual English word.
* Instead of `D U R L !`, you can choose five characters/numbers/arrows/etc. to represent the direction and selection. For example, you could choose `1 2 3 4 x`. This output choice must be consistent across all runs of your code, and please specify in your submission what the output is.
* Input and output can be given by any convenient method.
* You can print it to STDOUT or return it as a function result.
* Either a full program or a function are acceptable.
* Standard loopholes are forbidden.
* This is so all usual golfing rules apply, and the shortest code (in bytes) wins.

# Answer
> 6 votes
# K (ngn/k), ~~41~~ 32 bytes

```
{,/(|4,&0|,/-:\)'-':+(0,y)\x-97}

```

Try it online!

output: `0=D 1=R 2=U 3=L 4=!`

`{` `}` function with arguments `x` and `y`

`x-97` convert `"a"`..`"z"` to `0`..`25`

`(0,y)\` divmod by `y`, returns a pair of lists - one with the quotients and one with the remainders

`+` flip - make it a list of pairs

`-':` deltas - subtract each pair from the previous one; use `0 0` as an implicit pair before the first

`(` `)'` for each pair (let's call it `(Δi;Δj)`) do:

* `-:\` self and own negation: `(Δi;Δj)` -\> `((Δi;Δj);(-Δi;-Δj))`
* `,/` concatenate: -\> `(Δi;Δj;-Δi;-Δj)`
* `0|` max with 0
* `&` "where" - for instance it would turn the list `a:1 5 0 2` into `0 1 1 1 1 1 3 3`, i.e. each index `i` is repeated `a[i]` times
* `4,` prepend a 4
* `|` reverse

`,/` concatenate

# Answer
> 5 votes
# JavaScript (Node.js),  ~~112 ... 104~~  102 bytes

Takes input as `(width)(word)`, where *word* is expected in lowercase. Returns `01234` for `RLDU!`.

```
n=>w=>Buffer(w).map(g=c=>v-(c%=97)?g(c,v-=[-1,1,-n,n][d=(v-c)%n?v%n>c%n&1:v>c|2],o+=d):o+=4,o=v='')&&o

```

Try it online!

# Answer
> 4 votes
# , <sup>~~44~~</sup> 41 bytes

```
;@(2<@(_,~[:I.0>.-,-~)/\0,]#:~_,[)97|3&u:

```

Try it online!

*All credit to ngn for the best part: the self-append of the negative delta and max with 0, as a way of creating unique markers for each direction.*

*Separately, -3 bytes thanks to ngn for some line edits*

2 = D, 3 = R, 0 = U, 1 = L, _ = select

* `97|3&u:` turns the letters into numbers, with `a` = 0.
* `]#:~_,[` use a mixed base of infinity and the left arg as a way of calculating divmod
* `0,` append 0 so we'll have a delta to the first letter
* `2<@(_,~[:I.0>.-,-~)/\` calculates the deltas, then append their negative, use J's "indices" (like k's "where" -- see ngn's answer), append an infinity `_,~`, and box the result `<@`.
* `;@` remove all the boxing

# Answer
> 3 votes
# Jelly, ~~24~~ 20 bytes

```
O_97ŻdZIb1Ḥ2¦Z;€3Fḟ0

```

Try it online!

A dyadic link taking the word as the left argument and the width as the right. Returns a list of integers where:

```
-2 = L
-1 = U
 1 = R
 2 = D
 3 = Select

```

# Answer
> 2 votes
# C (gcc), ~~165~~ ~~164~~ ~~140~~ ~~138~~ ~~137~~ 135 bytes

```
#define W(b,c);for(;X b;putchar(c))
x,y,X;f(s,w)char*s;{x=y=0 W(=*s++,33){X-=97 W(%w<x,76)x--W(%w>x,82)x++W(/w<y,85)y--W(/w>y,68)y++;}}

```

Try it online!

~~1~~ ~~25~~ ~~27~~ 28 byte shaved off thanks to ceilingcat! Ungolfed:

```
int x, y, X, Y;

f(char *s, int w) {
   x = 0;                                 // Starting position is (0, 0)
   y = 0;

    while (*s) {                          // For each character
        X = (*s - 'a') % w;               // Get its x coordinate
        Y = (*s - 'a') / w;               // Get its y coordinate
        s++;

        while (X > x) putchar('R'), x++;  // Print R for each step we need to move right
        while (X < x) putchar('L'), x--;  // ...et cetera...
        while (Y > y) putchar('D'), y++;
        while (Y < y) putchar('U'), y--;

        putchar('!');                     // We are there, print !
    }
}

```

# Answer
> 2 votes
# Python 3, 126 bytes

```
lambda s,n:[abs(x//n-y//n)*'UD'[y>x]+abs(x%n-y%n)*'LR'[y%n>x%n]+'!'for x,y in zip(map(O,'a'+s),map(O,s))]
O=lambda c:ord(c)-97

```

Try it online!

# Answer
> 1 votes
# 05AB1E, 20 bytes

```
AIk0šI‰ü-εεdDNOyÄ×]»

```

Try it online!

Uses 0 for `D`, 1 for `R`, 2 for `U`, 3 for `L`, and newline for `!`. Space is used as an optional separator.

# Answer
> 0 votes
# Charcoal, ~~52~~ 48 bytes

```
Ｎθ≔⁰δＦＥＳ⌕βι«≔⁻﹪ιθ﹪δθη≔⁻÷ιθ÷δθζＦ±ηLＦ±ζUＦηRＦζD≔ιδ!

```

Try it online! Link is to verbose version of code. Edit: Saved 4 bytes by only tracking the alphabet index rather than the row and column separately. Takes input as `X` first, then the word. Explanation:

```
Ｎθ

```

Input `X`.

```
≔⁰δ

```

Start the path at the `a` with index `0`.

```
ＦＥＳ⌕βι«

```

Input the word, convert its letters to their alphabet index and loop over them.

```
≔⁻﹪ιθ﹪δθη

```

Calculate the horizontal difference.

```
≔⁻÷ιθ÷δθζ

```

Calculate the vertical difference.

```
Ｆ±ηLＦ±ζUＦηRＦζD

```

Turn those differences into a path.

```
≔ιδ

```

Update the current index.

```
!

```

Select the current letter.

The reverse program is only 23 bytes:

```
ＮθＰ⪫⪪βθ¶ＦＳ≡ι!⊞υＫＫＭ✳ι⎚↑υ

```

Try it online! Link is to verbose version of code. Explanation:

```
Ｎθ

```

Input `X`.

```
Ｐ⪫⪪βθ¶

```

Split the lowercase alphabet into substrings of length `X` and print them on separate lines without moving the cursor.

```
ＦＳ

```

Loop over the command characters.

```
≡ι!

```

If the next character is a `!`...

```
⊞υＫＫ

```

... then save the letter under the cursor in a list...

```
Ｍ✳ι

```

... otherwise move in the direction given by that character.

```
⎚↑υ

```

Remove the alphabet and output the saved letters.

---
Tags: code-golf, string, alphabet
---


title: Write a bot to play Grid Game

text:
# Question
Title: Write a bot to play Grid Game
This is the Grid Game:

It's a game based on cellular automata, where the aim is to remove all of the pieces belonging to your opponent.

How it works:

* There are two kinds of piece in the game, cities and walkers.
* Each player starts with one city (marked with C and a number, which is it's health), which will regularly send out walkers (marked with a number, initially the number 1) in a given direction.
* The player can change the direction of all of their walkers to be north, south, east or west at any time.
* When walkers can't go any further, they will stay still and can be joined by other walkers, increasing their number.
* When 10 or more walkers join up, they become another city. All new cities have 10 health.
* When walkers meet walkers or cities belonging to the opponent, they deal damage to the opponent equal to their number, and take damage equal to the opponent's number.
* Damage is dealt to all adjacent opponent pieces.
* There is no way to replenish the health of a city.
* The game ends when either player has no pieces remaining, or when a clear stale-mate is reached.

Because this question is already very long, I've attempted to write a more detailed description of the game, addressing specific queries about it in this wiki page.

## The Challenge

To write a bot to play Grid Game, and defeat as many rival bots as possible.

* A bot is some code which will be run on each turn of the game.
* It can only be JavaScript, sorry.
* The size of the code is immaterial.
* An object named `api` will be provided as an interface to the player from your bot.
* In this iteration of the challenge, there is no way for your bot to know what it's opponent is doing. The challenge is to write a proactive (not reactive) strategy.

Forbidden:

* Interacting with GridGame except via the documented api methods.

## The API

* **api.turn()** \- Returns the numbered turn the game is on.
* **api.towardsX()** \- Aim your walkers towards the opponent on the East-West axis.
* **api.towardsY()** \- Aim your walkers towards the opponent on the North-South axis.
* **api.awayX()** \- Aim your walkers away from the opponent on the East-West axis.
* **api.awayY()** \- Aim your walkers away from the opponent on the North-South axis.
* **api.random\_direction()** \- Aim your walkers in a randomly selected direction.
* **api.north()** \- Alias of awayY. North for green player, South for red player.
* **api.south()** \- Alias of towardsY. South for green player, North for red player.
* **api.east()** \- Alias of towardsX. East for green player, West for red player.
* **api.west()** \- Alias of AwayX. West for green player, East for red player.
* **api.wait(turns)** \- Your bot code will not be run again until `turns` turns after this method is called.
* **api.spawning\_turn()** \- Returns a boolean which if true if the Cities are going to send out a Walker this turn.

*Notes:*

* The last direction function called will define the next direction the walkers move in from that turn until a different direction is called.
* If no direction function is called walkers will continue in their current direction.
* Please do not set global variables, as these may conflict with those used by oponents, instead use `this.variable_name` to communicate between method calls.

## How to write a bot

*Note:* I recommend playing a manual game or two first; to do this, grab a friend to play against and select 'Manual (simple)' in the footer.

To test it:

* Select an opponent bot as the other colour (or 'Manual' if you'd like to challenge it yourself.
* Open the developer console (f12) in case of errors in your code.
* Click Start.
* Watch the game unfold.
* Click Reset and repeat the process as desired.

## How to deploy your bot

Once you've written a boss you'd like to keep:

* Go to https://gist.github.com
* Log in, if not already logged in.
* (The default page is the form to create a new gist, this is where we want to be.)
* Name the file 'bot.js'
* Copy the code into bot.js
* Save the gist
* Copy the gist ID (an alphanumeric string found after the last forward slash in the URL).

This Gist ID can now be used to import your bot into Grid Game at any time:

* Select Gist Id in a coloured box.
* Paste the ID into the field which appears.

You will need to include this gist ID in your answer.

*Note:* Grid Game will use the most recent version of bot.js in the gist, updating the gist will update your answer.

## Answer Format

Your answer will consist of:

* A Title consisting of
    + A name for your bot
    + The gist ID (which should be a link the gist).
* A brief description of the bot's strategy.
* Any notes you wish to include.

Note: I would like to include answers in the respository's code, partly to sidestep rate limiting on github's gist and partly to include more interesting bots for future users to challenge or modify. Please clearly indicate if you consent to your bot becoming a part of the game code or not.

Example answer:

```
### The Faraday Cage - d9eb9a70ad0dc0fb1885be0fce032adc

The Faraday Cage is an arrangement of four cities in the player's starting corner, which this bot will attempt to build, which then allows it to repeatedly send two 9's towards the opponent.

* This is named after Alan Faraday, the elder brother of the game creator, who discovered it while playing the game manually.
* It has proven difficult to defeat.

Please include this in the repository.

```

## The Tournament

The competition will involve running a match for every permutation of two of the available bots.

There are three possible outcomes to a match:

* Outright win - A player is completely removed from the board. 3 points to the winner.
* Timeout win - The game will end if it reaches 3,000 turns. At this point, the winner is determined by the total health count. 2 points to the winner.
* Draw - If the game reaches 3,000 and the bots have an identical total health, it's a draw. Both players get 1 point.

Notes:

* The below scores are from the very first working tournament runner. I hope to present the results better in future.
* Currently this is a single match for each permutation. There will likely be multiple matches in future to smooth out the results for bots which use random functions.
* I also want to present the results of specific matches in future.
* I'll try to run it again for new bots, please alert me to changes in existing bots to request a re-run.

## Current scores

(Run at 2019/11/12 09:15 UTC)

Detailed results (with links to replay matches) can be found at https://ajfaraday.github.io/grid\_game/results/rankings.html

```
Avi - Intercept and Destroy              60
Brilliand - Line Drive                   60
Brilliand - Galeforce                    57
Brilliand - CBC Goes With Everything     55
william porter - Twin Citites            54
Brilliand - CBC Forever                  51
Brilliand - Feint                        51
Brilliand - Cage Bar Cutter              49
Brilliand - Parry and Slice              48
Avi - Hocus Pocus(!?)                    48
Alion - Evolvor: First Encounter         47
Alion - Evolvor: Overnight               45
Brilliand - Backstabber                  42
BradC - Sweeping Endgame                 36
BradC - Quad Rush                        35
Alion - Doombeam                         33
Alion - Slideout                         31
AJFaraday - Faraday Cage                 28
Alion - Zerg Rush                        25
BradC - Double Barrel                    22
Alion - Weirdflow                        21
Alion - Rushdown                         15
AJFaraday - Rotate                       12
AllirionX - 3 Base rush                   9
AJFaraday - Orbit                         8
AJFaraday - All Towards                   3

```

(Thanks to @brilliand for correcting the unexpected interactions between bots in the tournament runner.)

——

Chat room for this challenge

# Answer
> 12 votes
### Doombeam - 496367ff51c27dc62ebdc473cd14f333

Time for a tryhard entry. Sets up a massive 12-city railgun and fires it off straight at the spawn point. Even if some of the cities get destroyed before the setup is complete, it still has enough firepower to devastate everything in its path. Additionally, after the far corner is filled with its cities to the brim, it clears up any potential leftovers, as a countermeasure to entries that escape the spawn point.

```
const turn = api.turn();
if (turn === 0) {
    this.generator = (function* () {
        yield* [[0, 30], [1, 30]];

        for (let i = 0; i < 10; ++i) {
            yield* [[2], [0, 2]];
        }

        for (let i = 0; i < 4; ++i) {
            yield* [[3], [1, 2]];
        }

        yield* [[3], [2, 4], [1, 4]];

        while (true) {
            for (let i = 0; i < 30; ++i) {
                yield* [[3], [2, 2]];
            }

            for (let i = 0; i < 3; ++i) {
                yield [1, 42];
                yield [0, 51];
            }
        }
    })();

    this.nextCall = 0;
}
if (turn === this.nextCall) {
    const [dir, delay = 1] = this.generator.next().value;
    [api.awayX, api.awayY, api.towardsX, api.towardsY][dir].bind(api)();
    this.nextCall += delay;
}

```

I **do** consent to the inclusion of this bot in the repository.

# Answer
> 6 votes
### Cage Bar Cutter - 49d7afbe8bb6d542acc871ac40d12e83

No more faraday cages!

Similar to Zerg Rush, but tuned to prevent Faraday Cages from growing at all (in either direction). In the spirit of this being a trivial bot, it makes no attempt to clean up bots that escape to the corners (but most can't manage that anyway).

```
const turn = api.turn();
const opening = "EEESSSEEESSEEEEEEEEEESSSEEESSSENEEENSNSSSSEEEEEEEEESSSEEESSEEEESE";
if(turn < opening.length) {
    switch (opening[turn]) {
        case 'W':
            api.awayX();
            break;
        case 'N':
            api.awayY();
            break;
        case 'E':
            api.towardsX();
            break;
        case 'S':
            api.towardsY();
            break;
    }
} else if(turn >= 120) {
    if(api.spawning_turn()) api.towardsY();
    else api.towardsX();
}

```

I **do** consent to the inclusion of this bot in the repository.

# Answer
> 5 votes
### Slideout - 056b16e0dc85ee2f13cc6061cf8162ca

Builds on the Faraday Cage idea by increasing the total amount of walkers generated per 3 turns to 6.

```
const turn = api.turn();
if (turn === 0) {
    this.generator = (function*() {
        yield* [0, 1, 3].map(i => [i, 30]);

        while (true) {
            yield* [[2, 25], [3, 8]];
        }
    })();

    this.nextCall = 0;
}
if (turn === this.nextCall) {
    const [dir, delay] = this.generator.next().value;
    [api.awayX, api.awayY, api.towardsX, api.towardsY][dir].bind(api)();
    this.nextCall += delay;
}

```

I do not consent to the inclusion of this bot in the repository.

# Answer
> 5 votes
### Zerg Rush - 1f8b3963656f9e15577f886e0125a343

Oh boy, here we go... Of course a Zerg Rush would work. Why wouldn't it, right? It makes me feel incredibly dirty, but it had to be done.

```
const turn = api.turn();
if (turn === 0) {
    this.generator = (function* () {
        while (true) {
            yield* [[3], [2, 2]];
        }
    })();

    this.nextCall = 0;
}
if (turn === this.nextCall) {
    const [dir, delay = 1] = this.generator.next().value;
    [api.awayX, api.awayY, api.towardsX, api.towardsY][dir].bind(api)();
    this.nextCall += delay;
}

```

I do not consent to the inclusion of this bot in the repository.

# Answer
> 5 votes
# Double Barrel - 7d0a88c1533fc89b2ee26484bbcafc59

Makes a second city and immediately opens fire diagonally, catches lots of bots during setup.

```
if (api.turn() < 29) {
   api.awayY();
} else if (api.turn() % 3 == 2) {
   api.towardsY();
} else {
   api.towardsX();
}

```

You can include this bot in your code if desired.

# Answer
> 4 votes
### Intercept and Destroy - 3dcc9463f47626a217a5a51762f02fe6

An improved version of Cage Bar Cutter, intercepting creation of Faraday Cage-like structures. After attempting interception, escape to the corner and attempt to build on the opponent's side. Aggressive attackers will not target themselves, so you can build up there. Non-aggressive builders will have been reasonably interrupted by the interception attempt. After some buildup, turn around and destroy everything.

At the moment of posting, this bot achieves a win against every other posted bot in under 1000 turns. Weirdflow has the dubious distinction of lasting the most turns (808) against this strategy.

```
const turn = api.turn();
if (turn === 0) {
    this.generator = (function*() {
        yield* [[2, 3], [3, 3], [2, 3], [3, 2], [2, 10], [3, 3], [2, 3], [3, 3], [2, 1], [1, 1], [2, 3], [1, 1], [3, 1], [1, 1], [3, 4], [2, 9], [3, 3], [2, 3], [3, 2], [2, 4], [3, 1]];
        yield* [0, 3, 2].map(i => [i, 36]);

        while (true) {
            for(let i = 0; i < 4; i++)
            {
                yield* [[2, 25], [3, 8]];
            }
            for(let i = 0; i < 4; i++)
            {
                yield* [[0, 25], [1, 8]];
            }
            yield* [[1, 50]];
        }
    })();

    this.nextCall = 0;
}
if (turn === this.nextCall) {
    const [dir, delay] = this.generator.next().value;
    [api.awayX, api.awayY, api.towardsX, api.towardsY][dir].bind(api)();
    this.nextCall += delay;
}

```

As another fun little thing, here's what happens when you run this bot against itself for 4492 turns:

I **do** consent to the inclusion of this bot in the repository.

# Answer
> 4 votes
## Twin Cities - 46b9d27b1994c35a8ef214c1b2067609

Starts off with a corner start and then makes use of how attacks work to return fire before building up it's own forces. Beats most bots, loses to others.

```
//Twin Cities
const turn = api.turn();

if (turn < 31) {
    switch(turn % 2) {
        case 0:
            api.awayY();
            break;
        case 1:
            api.awayX();
            break;
    }
} else if (turn < 80) {
    switch(turn % 3) {
        case 0:
            api.towardsY();
            break;
        case 1:
            api.towardsX();
            break;
        case 2:
            api.towardsX();
            break;
    }
} else if (turn < 127) {
    api.towardsX();
} else if (turn < 246) {
    api.towardsY();
} else if (turn < 350) {
    api.awayX();
} else if (turn < 400) {
    api.towardsY();
} else if (turn < 500) {
    api.towardsX();
} else {
    const late = turn % 200;
    if (late < 50) {
        api.awayY();
    } else if (late < 100) {
        api.awayX();
    } else if (late < 150) {
        api.towardsY();
    } else if (late < 200) {
        api.towardsX();
    }
}

```

Feel free to include it in your repository.

Edited: Simpler initial phase, also dodges feint and hocus pocus now.

# Answer
> 3 votes
### Weirdflow - 8f82f8a5fd15fc29e60b9cce4343309c

This was an attempt at a very clean bot that turned into an incredibly sloppy counter to Rushdown.

```
const turn = api.turn();
if (turn === 0) {
    this.generator = (function*() {
        for (let i = 0; i < 10; ++i) {
            yield* [[0], [2, 2]];
        }

        for (let i = 0; i < 5; ++i) {
            yield* [[1, 2], [0]];
        }

        yield* [[3, 2], [0, 4]];

        while (true) {
            for (let i = 0; i < 5; ++i) {
                yield* [[1], [3, 2]];
            }
            yield* [[2, 3], [3, 3], [0, 6]];
        }
    })();

    this.nextCall = 0;
}
if (turn === this.nextCall) {
    const [dir, delay = 1] = this.generator.next().value;
    [api.awayX, api.awayY, api.towardsX, api.towardsY][dir].bind(api)();
    this.nextCall += delay;
}

```

I do not consent to the inclusion of this bot in the repository.

# Answer
> 3 votes
# Sweeping Endgame - 3f69bdf2be37886ff396d0c485007e80

More complex bot, with a setup phase, a sweeping mid-game strategy, and an endgame that covers all corners and directions.

```
//Sweeping Endgame v2
this.t = api.turn();

//initial city setup
if (this.t < 29) {
   api.awayY();
} else if (this.t < 59) {
   api.awayX();

//mid-game loop, now attempts to put cities in the two off-corners
} else if (this.t < 400) {
  if (this.t % 200 < 14) {
     api.towardsY();
  } else if (this.t % 200 > 13 && this.t % 200 < 17) {
     api.awayX();
  } else if (this.t % 200 > 100 && this.t % 200 < 122) {
     api.towardsX();
  } else if (this.t % 200 > 121 && this.t % 200 < 126) {
     api.awayY();
  } else if ((this.t % 8) % 3 == 1) {
     api.towardsY();
  } else {
     api.towardsX();
  }

//endgame, now sequential, not random
} else {
   if (this.t % 200 < 40) {
      api.awayY()
   } else if (this.t % 200 < 50) {
      if (this.t % 2 == 0) {
        api.towardsY();
      } else {
        api.awayX();
      }
   } else if (this.t % 200 < 90) {
     api.towardsX()
   } else if (this.t % 200 < 100) {
      if (this.t % 2 == 0) {
        api.awayY();
      } else {
        api.awayX();
      }
   } else if (this.t % 200 < 140) {
     api.towardsY()
   } else if (this.t % 200 < 150) {
      if (this.t % 2 == 0) {
        api.awayY();
      } else {
        api.towardsX();
      }
   } else if (this.t % 200 < 190) {
     api.awayX()
   } else {
      if (this.t % 2 == 0) {
        api.towardsY();
      } else {
        api.towardsX();
      }
   }
}

```

v2 makes the following changes:

1. Mid-game now deliberately attempts to get a couple of cities in the off-corners. This is crucial to "get behind enemy lines" for simple bots like Quad Rush.
2. End game is no longer random, instead it goes through a prescribed sequence of straight and diagonal moves to clean up the board.

# Answer
> 3 votes
### Line Drive - 54e4de5b03423cc19a1ec0e22f32a981

Attempts to occupy an entire column of the grid, then unleash an unstoppable barrage in the x-direction.

EDIT: Now biases its barrage toward one wall and changes direction more rapidly, allowing it to beat some bots that the previous version couldn't beat.

```
const turn = api.turn();
if (turn === 0) {
    this.generator = (function* () {
        yield* [[0, 24], [1], [0], [3], [0, 3]];

        for (let i = 0; i < 9; ++i) {
            yield* [[1], [2], [0]];
        }
        yield [1, 3];

        for (let i = 0; i < 10; ++i) {
            yield* [[3], [1, 2]];
        }

        for (let i = 0; i < 4; ++i) {
            yield* [[2], [0, 2]];
        }

        yield* [[2], [3, 4], [0, 4]];

        for (let i = 0; i < 4; ++i) {
            yield* [[2], [0, 2]];
        }

        yield* [[2], [3, 2], [0], [3, 2], [0], [3, 2], [0, 3]];

        while (true) {
            for (let i = 0; i < 60; ++i) {
                yield* [[2, 2], [1]];
            }
            for (let i = 0; i < 40; ++i) {
                yield* [[3, 2], [2]];
            }
            for (let i = 0; i < 60; ++i) {
                yield* [[0, 2], [3]];
            }
            for (let i = 0; i < 40; ++i) {
                yield* [[1, 2], [0]];
            }
        }
    })();

    this.nextCall = 0;
}
if (turn === this.nextCall) {
    const [dir, delay = 1] = this.generator.next().value;
    [api.awayX, api.awayY, api.towardsX, api.towardsY][dir].bind(api)();
    this.nextCall += delay;
}

```

I **do** consent to the inclusion of this bot in the repository.

# Answer
> 3 votes
### Evolvor: First Encounter - c0382c11979adc1f47773714ffc8376f

This is the first in what I hope becomes a series of bots that result from a genetic algorithm. Does some really weird things which result in tons of cities and then... usually can't convert it into a victory.

```
switch ("WNSNNNWSNWNWNWNWWNNWWNWNNNWWWNEENNNWWNNWWWWWNWWNWNWWSWENEENNENNESSSSWSWWSWWSWWSSWSNWSWWSWSSWWSWWSWWEESESSEESESSESSESWESSEWWESWESSSSSNNWNWWSWWNNWNWWEWWSWSEWWNWEEENEESEENEEEEEEEEEEENEEEEEEEESEENESEENEEESEEEEEEENEEEEEEEESEESEENEEEEEEEEENEEEESEEENEEEEEEEEEEEEEEEEESEENEENENEEESEEEEESENEEESENEEEEEESEENEEEENEEEEESEENEEEEEENEEEESEEEEENEEENENEEEEESEENEEEEEEEEESNEEEESEEEEEEENEENEEEEEWEEENEEEEENEWSEEEENNENEENEESEENEEWNEEEEEEEEWENSEENEESEEEEENENEEESEESEENEEENESENEESEWSNEENEWSENEEEEENSEEEENEEEEEENEESENEESNENWEENENSEEEENNNEEESWESWEESENENESNEEEENSNEEESEEEEEEESSEESEEEEEEESNENEEWENENNSEENEEWEEEEENWEESENNEESENNENSENWENEENWESENENNNNEENEWSENEENEEWWEEWENNWNNEEEEWSEEWESESESEEEENNWEWSSSENSENEEESESEENNNSEEEEESESSEEENENENEWEWNWSEESSENNNESSSENNENWEEEWNWNENSEWESESSEEEEENWSENEESEWNEEEWEWSEEWNNEEEENSENNESNNESNEENSEENWNNESESSWWWENEWENNSSENEESNSWWNNNWENWNNESEENEEENEESNEWSSENWWWNEEEESESWSSEWNNENWENNWNSESEEESESNSSESENWSESENNEWENNEENEESSNENEESSNWNESNENSESWWEENWWNEEEENESSEEESWWSWWEESWWEWSEENWEWEWNNSESSSNEESESNSEESSEEEEWSSSNSNSSSNNSESESSSESNWWEWENNENNNNWWEENWSNWWWSWNWWSEEEWEEWWEWENNSSEEEESNSESWENNNWENSWWNNENEESEWEWSEESEWEEWENSWNNSNENSWNWSENNENNNESNEWSEENSNNEWEENNSEEESSNEENWEESWEEWSEWWEWWWESESSSESEWEEWEESNNSNWWSNNENSSESWEEWNESENSEEEESEENEWENWSEEEEEWWEEESSNSWSEENWSESEWEWEESSNSNNNSWNWEWSWEESWSEWSNNWNNENNNNSESENNWEENSWWENSWNESNNSENWWWNESSSSENENWNENNEEEESWSWWNSEEWNNESENSENSWNWSNWNSSSSSSESSNESEWNESEWWNEWNENNESWSSEEWEEWNSENENESWEENESWWNESNEEWSSEWENEWEESSSENNWNNNESWEWWSESWNSSNENWEWWESSESSNEENNSSSSESNWEENSWSWEWEEWEWWSSESSNEWWEENWSSENWENSSWNSENSEEWNWENWNWENEENWWWEEWNWEWWNNNSSNWENWNENENNWNNWSESSESWNNENENWSSESWEEWEESNSWENEENSSWESEENWWEWNNEEENEESWENESNWNWEEWNWEESWWEEESWENENSSWENNWSWWNSWNSESESSNEENEWEENWENNWWWNSWWEESSWNNNSWNWESEESENEESEENWNNWWESSSSESNESWNSWWNSNEWEWEENSEWSESSENSWNENSESNNSWWSWEEESSNSESNEEEWEEWNSWNEENSENSWENESEESNNNEESWSNNSNWNSSSSEEESWSSSSNSNSESENENSNESSNWNSWNSSENESSSWEWNSWENSEWWSWNNWEEESESENSNNNSWNENNSSSNEWSSWEEWWWEWNSWNNEWWWENENENWSWWWEESEENWSWENESEESWNEWEESEWEWNESEWWNWWSWWNWSEEEWNSNNSENWSWSWSSWWNWWSESSSNEESWENNEENEEWEWNSENWSNSWNNSWSWSESWEWNNSNNNEWWWNWSNNENSNENNNNWNWESWWEEWNNWWNNEEWNSNNNNSNWSSSNEWEWWENNESNWNNNSWNWEWWSSSWSEWWESEEWSNNSESEEWEEWSNWENWWWSNWSESNENNEESENSNWWNWNNWEWSSWSSSNSEESNSNNSEEWNSSWWWEEWWNNESNWENSWNEWNSEWWEWESNWWNENWWEWNEWEESNNEEESNENESWEEWNSSNESSENWSENSWWEEWSSWWEWSNESSENWESSSSWWENSSENWNNWEESWWNNNSEEESSSENSESSNSSSSSWNWENESNWNESWNSNESSENESSSWWNEWNESSENNWNEEEEEWNSWWSWWSSNEWEESSWESENSWEESNWEWNEENSENESNNSEEEWENESENWWNSESENWWSWESNSWSESEWSENEWEWEWSENESSSENSNEEWESSNNESENEWENWEEEESWWNESNESSSNNEWNNENEESEESNENSWESNNWWSENNWNNNWWEESESNNWNWENNEWSSSNSNNENNNWSSWWSNWSNEWNNWSEEWNNWESNNNWENWNSENNWENWENSWNNWNWNENNWSNNWWWWWSESWWEEEEESEENESEENEENWWNWEENESSSWSSSNNWWENSWNWWENSESSSSSSWENSNWSWENEWENNWNWNSWWNNSWSWSWWWNWEEWNNESSSWSEEENEWSNWWEWEWENWWEENESNWWNSEWNEENNSNEWSWESESSWEWWWEWWWNWNESSNNWSENWSNNSENSSESWWWSSESESWWSESSSENSENEWESSWESSNNWNSEWWWWWNWSEWSENNESWNEEWWEENNNEESWSWSESNESWNSNNSWWSENEENENSSWWWWEEEWWNEEEWENNSWEEWNWWNSNSNWSNNEENESSWEENNNEEEENNWSSWENSSNWSSNSNWNENESEWNWWEEENEEWESNESNEES"[api.turn()]) {
    case 'W':
        api.awayX();
        break;
    case 'N':
        api.awayY();
        break;
    case 'E':
        api.towardsX();
        break;
    case 'S':
        api.towardsY();
        break;
}

```

I do not consent to the inclusion of this bot in the repository.

# Answer
> 3 votes
### Hocus Pocus(!?) - 966e8f3ad189b9535c2e1fad3ffc065a

Weird strategy that I'm unable to describe - it's probably(?!) an amalgam of Feint, Two Cities (??!) and whatever else I can't remember. At the moment of posting, (I think it?) beats everything but the Evolvors and Intercept & Destroy. Uses anti-CBC at the beginning, then hocus pocus(!?) strategy. Edit: Also loses to Backstabber

```
const turn = api.turn();
if (turn === 0) {
    this.generator = (function*() {
        yield* [[3, 8], [2, 16], [3], [0], [1], [0, 27]];
        while (true) {
            yield* [[3, 36], [2, 36], [1, 36], [0, 36]];
            for (let i = 0; i < 20; ++i) {
                yield* [[2, 2], [1]];
            }
            for (let i = 0; i < 20; ++i) {
                yield* [[2, 2], [3]];
            }
            for (let i = 0; i < 20; ++i) {
                yield* [[0, 2], [1]];
            }
            for (let i = 0; i < 20; ++i) {
                yield* [[0, 2], [3]];
            }
            for (let i = 0; i < 10; ++i) {
                yield* [[1], [3, 2]];
                yield* [[2], [0, 2]];
                yield* [[3], [1, 2]];
                yield* [[0], [2, 2]];
            }
        }
    })();

    this.nextCall = 0;
}
if (turn === this.nextCall) {
    const [dir, delay = 1] = this.generator.next().value;
    [api.awayX, api.awayY, api.towardsX, api.towardsY][dir].bind(api)();
    this.nextCall += delay;
}

```

I **do** consent to the inclusion of this bot in the repository.

# Answer
> 2 votes
### Rushdown - 5a989c80bf1bbef32c848f248aa55dcb

Focuses on building up a bit of firepower and then rushes down what it expects to be the enemy base. Made as a counter to the Faraday Cage and similar. As a bonus, it looks like it's shuffling a deck of cards during the first phase.

```
const turn = api.turn();
if (turn === 0) {
    this.generator = (function*() {
        for (let i = 0; i < 5; ++i) {
            for (let j = 1; j <= 2; ++j) {
                yield* [[2, j], [0, j]];
            }
        }

        while (true) {
            yield* [[3, 34], [1, 1], [2, 16]];
        }
    })();

    this.nextCall = 0;
}
if (turn === this.nextCall) {
    const [dir, delay] = this.generator.next().value;
    [api.awayX, api.awayY, api.towardsX, api.towardsY][dir].bind(api)();
    this.nextCall += delay;
}

```

I do not consent to the inclusion of this bot in the repository.

# Answer
> 2 votes
# Quad Rush - a0a4a9f3c8b8863392f109fdfd52af00

Double barrel x2.

**EDIT**: Changed the cadence so we end up with a `[2]` runner and two `[1]` instead of four `[1]`, which makes a difference in some matchups.

```
if (api.turn() < 29) {
   api.awayY();
} else if (api.turn() < 59) {
   api.awayX();
} else if (api.turn() % 3 == 0) {
   api.towardsY();
} else {
   api.towardsX();
}

```

You can include this bot in your code if desired.

# Answer
> 2 votes
### 3 Base rush - 3f6d1a1461564ace3d7e22cedba08c20

A bot building three cities before launching an indirect attack and proceeding to lose.

```
if (api.turn() < 29) {
   api.awayX();
} else if(api.turn() < 40) {
    api.awayY();
} else if(api.turn() < 42) {
    api.awayX();
} else if(api.turn() == 42) {
    api.awayY();
} else if(api.turn() < 45) {
    api.towardsX();
} else if(api.turn()<48) {
    api.awayY();
} else if (api.turn() % 2 == 1) {
   api.towardsY();
} else {
   api.towardsX();
}

```

This bot is not to be included in the repository, as it is only a stepping stone to explore 3 cities openings.

# Answer
> 2 votes
### Galeforce - 294c357b051e6e165d18657748d02cfe

Sets up 8 cities, then sprays walkers in various directions. Looks a bit like a Doombeam followed by a Line Drive (and the Galeforce vs. Doombeam matchup comes down to persistence).

```
const turn = api.turn();
if (turn === 0) {
    this.generator = (function* () {
        yield* [[1, 24], [0], [1], [2], [1, 3]];

        for (let i = 0; i < 9; ++i) {
            yield* [[0], [3], [1]];
        }
        yield [0, 3];

        for (let i = 0; i < 10; ++i) {
            yield* [[2], [0, 2]];
        }

        for (let i = 0; i < 20; ++i) {
            yield* [[3], [2, 2]];
        }

        while (true) {
            for (let i = 0; i < 20; ++i) {
                yield* [[3, 2], [2]];
            }
            for (let i = 0; i < 20; ++i) {
                yield* [[3, 2], [0]];
            }
            for (let i = 0; i < 20; ++i) {
                yield* [[2, 2], [1]];
            }
            for (let i = 0; i < 20; ++i) {
                yield* [[2, 2], [3]];
            }
            for (let i = 0; i < 20; ++i) {
                yield* [[1, 2], [0]];
            }
            for (let i = 0; i < 20; ++i) {
                yield* [[1, 2], [2]];
            }
            for (let i = 0; i < 20; ++i) {
                yield* [[0, 2], [3]];
            }
            for (let i = 0; i < 20; ++i) {
                yield* [[0, 2], [1]];
            }
        }
    })();

    this.nextCall = 0;
}
if (turn === this.nextCall) {
    const [dir, delay = 1] = this.generator.next().value;
    [api.awayX, api.awayY, api.towardsX, api.towardsY][dir].bind(api)();
    this.nextCall += delay;
}

```

I **do** consent to the inclusion of this bot in the repository.

# Answer
> 2 votes
### Backstabber - 2d632fb11ea1a7b1b73788d396a6a45d

After making Galeforce, I got to wondering if anything could beat a *really* persistent Doombeam - one that never stopped firing. None of the existing bots seemed to be able to.

This bot can do it, though, and it beats most of the other bots too!

```
const turn = api.turn();
if (turn === 0) {
    this.generator = (function*() {
        yield* [[0, 24], [1], [0], [3], [0, 3]];

        for(let i = 0; i < 40; i++) {
            yield* [[1], [2, 2]];
        }

        while (true) {
            for(let i = 0; i < 40; i++) {
                yield* [[3, 2], [2]];
            }
            for(let i = 0; i < 40; i++) {
                yield* [[0, 2], [1]];
            }
            for(let i = 0; i < 40; i++) {
                yield* [[3], [0, 2]];
            }
            for(let i = 0; i < 40; i++) {
                yield* [[0, 2], [3]];
            }
            for(let i = 0; i < 40; i++) {
                yield* [[1], [0, 2]];
            }
        }
    })();

    this.nextCall = 0;
}
if (turn === this.nextCall) {
    const [dir, delay = 1] = this.generator.next().value;
    [api.awayX, api.awayY, api.towardsX, api.towardsY][dir].bind(api)();
    this.nextCall += delay;
}

```

I **do** consent to the inclusion of this bot in the repository.

# Answer
> 2 votes
### Evolvor: Overnight - 7512fcfcef33bff323d5cdaf1bb833ff

This is utilizing exactly the same evolution code as Evolvor: First Encounter, but with a significant increase to the time provided. As of the time of posting, this only loses to 4 entries - two of them mine (whoops) and all of them rushy. I hope to be able to fix this issue soon.

```
switch ("NEWWNSNWEWWNNEWWNNNWWWNNNNNNSWWEWNNWNWENWWNWWEWNNNNENNWWNSESSSESESSWWSNSESSSWESWNSWWENNSSESSNSWESWWSWSESWSSWSWSSSNSWEENWEWEEWWSWSSWWSWNEWWEESEESEESEESEEEENEEESEEEEEEEEEEEEENEEEEEEEENEESEEEEENEEEEEEEEEEEEEENEENEEEEEEEEEEEEEEEEENNENEEEEEEEENEEEEEEEEEEEEEENNENNENNENNNNNENEEEEENEEEEEEEEWEEEEEEEEWEENEENEEESEEWEEEESEENWESEESEENEEEEEWEEESNNNENNENNEENENEENENNEENNNNEENNENEEENNNENNEENNENNEENESEEWEEEEEEEEEEEEEENNEENESSEWSENEEWSESEESSESSESSWNNNNENNNNENNNNNENNNNNNENNENNENENNNNNENNNNNNENENNNNNNENENNENNENNNENNENENNNNNENNNNNENNNNNNENENNNWNENNNNNNENNWNENNENNNWNENNENNNNENNNSWEENWNENENNENNNWNWNNENNEWNNNWENWNNNWNEENNWWNWNSSNSNSSEESSWNWESWSSWSESESSESESSSESEESSESNESSESEESESEEESSESEESSESSNSEESEEESSSSWNEESNNNESESSSESEEESEWSSSSSESESSNSNWENESNSESSSSSSSESSSSSWSSNNWSSNESSENSSESEESEWSEENSESWSSSNWESEWENSENNENNWNSSSEWNWWSSSNSESSWSNENSEEENNNNNNENSSNWEWWSSEWSSWNEEWEENSEWNESNESWNSSWWENWSENSWNNNWNNWESESEWWNNNWNWNNEWWSNWNNSWWNWWSENWNSNSWNWSNEWNNNNNNWWWWWSNWNWSSNENWSNNNSNWSNWWNNWWNNWNNSWWNNWWNENNWWSSWWNNNSWENNWWWWWWSWSWSNWNNSSNNNNNSWENWNWWEWNWNNNNWWWNSWWENNNNWNWNSWWWNNSSWNSSNWWNENNNWNWWNNWSESNNNNWWSNNWSWSWEWWNEWWWWWWSNWNNNWWWWNNEWWSEESNSWWWNNENNWWNSNWWNNWEWSWNWEWNWWSENNNWEWWSNWENWSWWWWNNSSENWSWNSNWSWWNNNNESWWNSWNNNWNWWNSWSNNENNSSWWWENSSENWNWWSSWSWWWEWSNEWWNEWWSWWSSSNWSNWEWEEWNNSWESSEESNNWWWWNSNSSNWSSWSNNSNNWSNWNWSWWSWNWEWEEWNNWNEWNSWWWWWSWNEEWWNNNSSNWWNNWWNWSNNWWNEEWESWNNNEWWWWSWWWNNSSWWNNSWSWEWSWWNSNWNESESWWEEWESSSNWEWENWSNNWNSESEEWWWWSWNNNSWNWWNWWWESSWNWNWNWEEWENEWNWSNNSNNWWWSSNNNWNNNSWNNNWSSWEWWENWNSNENEWESWNSWNEWENENSSEWSNNSNNSNNSSWSEWESSEWWSWWNSNNNNEWNWNESEENENNWSENEWNWWSNEENNSNWNNWNNNNWWWENNNEEWWENWWNNENWNNSWNNNEEWSSSSEESWWNESWNWNSWENEESENSENNNWESSNNSNWNSESESNEEENSSWENWEWNSENEENNSNWEEWNWNNEWNENNSSWWNSWSWSENENWENNWNEWWNNWSSSSESWNESSSNSWWNEESNWNNWESWENSWWNWESSWSNEWEENWESWWWSWSEWENNNNEEESSWWWNSWSNSWNSEESSSNEEWNNSSSWSSSWSNWSSSNSWNESWENNWWENNENWSWEWSEWSNWEWWESEWEEESSNEENNSWNWWWSWESSNSSSNNEWENENWNNWSSSWWESNWWSSEWSWEWNWNWSNSNEWEWEENEEWWESSENSSNNNNESNEWSNSSWENNSNNENEWNESNWNWESSWNNSWNNSWEWESSNWEWNWENEWEWESWSNNEWSWSWNEWEWSSWNWSWNSNSWESWNNWWNWNSENWNEWSWNNWNENWNENEEWSNSSSSEWSNNESNSSESESSSWWNWSESSNSSWWWWWSNWNEWESEWNEWESSNENEESNSEEWNSNNEWWWWESESSNEWWSSSNWSSWWNSSSSEWSWWWWSSNWSNWNWEEWSEWESWSENWNSWSSSSSWNWSNEWNWSSSWEWWEWNENESNNSWSSWNWNWNWNWSSSESSSWSWSWSSWSWESWSEESWEENSNNSSNNSSSWWEWSNEWWNNEENNNWSSEWWSESSNWNSEWNWNNNWNESSSSNEEWWENNEESESSNEEWEWEWSWSEWWNEWENWNEWNWENSNNEWSENESSSEESSWENNWESESSSWNNNWWNSNWEWWWEWSWSWESSENWWSENSEWSEWNSWNEENWNWWNSEEWWSWWWWWWNESEESSWEWENNSWWSNWWNSSWWNWNWNWNEWWWSWNNEESWSWWWESSEWNWSWEEWWNSENSWSWNSWWSSEWNEWWWNSNEENEWNNWNWWNSNNSWNWSNWSNNWWEWNWWWNESESNSEWWNENNSEWWWNWWWENWWNSSSEWNWEEEENWSSESEWESWWNSSWEEEEENSNWSWSEWESESSNWNWSENSSSENWWWNWWNENSSENWNWWWEWEENEENEWEWNSENENSSSWNWWSWWSNSESENESENWSSWWEENWWWWWEWSSSWSWESNSEWSSNWSWWWSSEWWEWWWSSSNEWWWWEENNSEEWWESWSSNESEENNSNENSWNNNNEENEWWWEWSEEWWEENWNSSSSWWNNENWNEWSSNENNNENSWSESSWSNENNWSWWWSESESENSNSSENWWSEENWWNSEWSEWNNWSENSNWEWWWNSSESESWSNSSEESWNEEENEEWSNNSWSESENNNWESWSWNNWESEENWWWENWWEWSSWSESWEWENSNEEEESSNWSSWSSNEENNEEEESSWWNWENSWESEWSESNE"[api.turn()]) {
    case 'W':
        api.awayX();
        break;
    case 'N':
        api.awayY();
        break;
    case 'E':
        api.towardsX();
        break;
    case 'S':
        api.towardsY();
        break;
}

```

I *do* consent to the inclusion of this bot in the repository.

# Answer
> 2 votes
### CBC Forever - 9c65942bf924d9bb09e99d22daf0d8d0

An endless loop of inverse CBC. After a while it starts cycling walkers around behind it, to clean up any enemy cities that got into its corner.

This is partly intended as a demonstration of how to do a long inverse CBC, but of course it beats a lot of stuff in its own right.

```
const turn = api.turn();
const opening =
    "SSSEEESSSEEEEEEEEEESSEEE"+
    "SSSEEESSSEEEEEEESSEEEEEE"+
    "SSSEEESSSEEEESSEEEEEEEEE"+
    "SSSEEESSSESSEEEEEEEEEEEE";
const pattern = "NWSSSSEEESSSWNEESSEEEEEEEEEEEE";
if(turn < opening.length) {
    switch (opening[turn]) {
        case 'W':
            api.awayX();
            break;
        case 'N':
            api.awayY();
            break;
        case 'E':
            api.towardsX();
            break;
        case 'S':
            api.towardsY();
            break;
    }
} else {
    switch (pattern[(turn-opening.length)%pattern.length]) {
        case 'W':
            api.awayX();
            break;
        case 'N':
            api.awayY();
            break;
        case 'E':
            api.towardsX();
            break;
        case 'S':
            api.towardsY();
            break;
    }
}

```

I **do** consent to the inclusion of this bot in the repository.

# Answer
> 1 votes
### CBC Goes With Everything - f904da9534cf91ff2d5d399f59757ebc

Repeats the CBC pattern 5 times, then proceeds to build its own Faraday Cage and perform a stock Galeforce.

6 appears to be the maximum number before it starts losing to variants of itself for being "too persistent"; I picked 5 'cause it's a nice round number close to that.

```
const turn = api.turn();
const opening = "EEESSSEEESSEEEEEEEEEESSSEEESSSENEEENSNSSSSEEEEEEEEESSSEEESSEEEESE";
if(turn < opening.length*5) {
    switch (opening[turn%opening.length]) {
        case 'W':
            api.awayX();
            break;
        case 'N':
            api.awayY();
            break;
        case 'E':
            api.towardsX();
            break;
        case 'S':
            api.towardsY();
            break;
    }
}
if (turn === opening.length*5) {
    this.generator = (function* () {
        yield* [[0, 30], [1, 30], [2, 30]];

        for (let i = 0; i < 20; ++i) {
            yield* [[3], [2, 2]];
        }

        while (true) {
            for (let i = 0; i < 20; ++i) {
                yield* [[3, 2], [2]];
            }
            for (let i = 0; i < 20; ++i) {
                yield* [[3, 2], [0]];
            }
            for (let i = 0; i < 20; ++i) {
                yield* [[2, 2], [1]];
            }
            for (let i = 0; i < 20; ++i) {
                yield* [[2, 2], [3]];
            }
            for (let i = 0; i < 20; ++i) {
                yield* [[1, 2], [0]];
            }
            for (let i = 0; i < 20; ++i) {
                yield* [[1, 2], [2]];
            }
            for (let i = 0; i < 20; ++i) {
                yield* [[0, 2], [3]];
            }
            for (let i = 0; i < 20; ++i) {
                yield* [[0, 2], [1]];
            }
        }
    })();

    this.nextCall = turn;
}
if (turn === this.nextCall) {
    const [dir, delay = 1] = this.generator.next().value;
    [api.awayX, api.awayY, api.towardsX, api.towardsY][dir].bind(api)();
    this.nextCall += delay;
}

```

You can include this in the repository if you want to, but it's just two of my other bots grafted together.

# Answer
> 1 votes
### Feint - cb68f09d808b5de34daf5c45b46f2bea

Briefly dips into a reverse Cage Bar Cutter, then jumps to a corner and tries to get behind the opponent before switching to the main circling strategy.

```
const turn = api.turn();
if (turn === 0) {
    this.generator = (function* () {
        yield* [[3, 8], [2, 16], [3], [0], [1], [0, 27]];

        let laps = 1;
        while(true) {
            for (let i = 0; i < laps*10; ++i) {
                yield* [[3, 2], [0]];
            }
            laps++;
            for (let i = 0; i < laps*10; ++i) {
                yield* [[2, 2], [3]];
            }
            laps++;
            for (let i = 0; i < laps*10; ++i) {
                yield* [[1, 2], [2]];
            }
            laps++;
            for (let i = 0; i < laps*10; ++i) {
                yield* [[0, 2], [1]];
            }
            laps++;
        }
    })();

    this.nextCall = 0;
}
if (turn === this.nextCall) {
    const [dir, delay = 1] = this.generator.next().value;
    [api.awayX, api.awayY, api.towardsX, api.towardsY][dir].bind(api)();
    this.nextCall += delay;
}

```

I **do** consent to the inclusion of this bot in the repository.

# Answer
> 1 votes
# Orbit - 1ec7b9413c34cd8cd66d5bf28a9537ef

Just quickly threw this together on a whim but...

The concept was to have the first walker keep ringing round the first city and see what happens. Uninterrupted, it keeps a pile of quite high-value walkers floating around until they build a few cities at once. Then keeps building, gradually creeping towards the enemy.

I expect it will do very badly in the tournament. ¯\\\_(ツ)\_/¯

```
if(api.turn() == 0) {
  api.towardsX()
} else if (api.turn() == 1) {
  api.towardsY()
} else {
  var dirs = ['awayX', 'awayY', 'towardsX', 'towardsY']
  if (typeof api.dir == 'undefined') {
    api.dir = 0;
  }
  if ((api.turn() + 1) % 2) {
    //next dir
    api[dirs[api.dir]]();
    api.dir += 1;
    api.dir = api.dir % 4;
  }
}

```

I'd like this in the repo, regardless.

# Answer
> 1 votes
### Parry and Slice - 472a33460a33c1785a28190c9406e36e

Defends against CBC with a small stack of walkers, then goes for a 3-city buildup because nothing else is fast enough after spending time on shielding. It then moves into a Backstabber variant.

Lategame, it throws in an occasional buildup phase to recover from situations where one of the endless rushers *almost* finished it off.

```
const turn = api.turn();
if (turn === 0) {
    this.generator = (function*() {
        for(let i = 0; i < 5; i++) {
            yield* [[3], [1, 2]];
        }

        yield* [[0, 30]];

        for(let i = 0; i < 5; i++) {
            yield* [[1], [0, 2]];
        }

        for(let i = 0; i < 12; i++) {
            yield* [[2], [1], [2, 4]];
        }

        while (true) {
            for(let i = 0; i < 40; i++) {
                yield* [[3, 2], [2]];
            }
            for(let i = 0; i < 20; i++) {
                yield* [[1, 2], [2]];
            }
            for(let i = 0; i < 30; i++) {
                yield* [[0, 2], [1]];
            }
            for(let i = 0; i < 30; i++) {
                yield* [[3], [0, 2]];
            }
            for(let i = 0; i < 40; i++) {
                yield* [[0, 2], [3]];
            }
            for(let i = 0; i < 30; i++) {
                yield* [[1], [0, 2]];
            }
            for(let i = 0; i < 10; i++) {
                yield* [[0], [2, 2]];
            }
        }
    })();

    this.nextCall = 0;
}
if (turn === this.nextCall) {
    const [dir, delay = 1] = this.generator.next().value;
    [api.awayX, api.awayY, api.towardsX, api.towardsY][dir].bind(api)();
    this.nextCall += delay;
}

```

I **do** consent to the inclusion of this bot in the repository.

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


title: Can Jimmy escape the ghosts?

text:
# Question
Title: Can Jimmy escape the ghosts?
It is Halloween and Jimmy (`/o\`) has gone into a mysterious neighborhood for trick-or-treating (ask himself why). Now some evil ghosts are chasing him. Can Jimmy escape the ghosts?

## Challenge:

**Input:**

A board showing position of Jimmy, ghosts, solid objects and empty spaces.

An example 10x5 board, `o` is Jimmy (we needed a single character Jimmy), `g`s are ghosts, `#`s are solid objects and `.`s are empty spaces:

```
##########
......g...
#.o.......
#.....g...
##########

```

**Output:**

A truthy value if Jimmy can escape at least in one scenario, otherwise a falsy value.

## How things work:

Ghosts and Jimmy can move one space each turn. There are 4 possible movements: left, right, up, down (no diagonal movements, no skipping).

On each turn, first ghosts move one space towards Jimmy. Ghosts always select the closest path to Jimmy, if two possible moves towards Jimmy have the same cost, the move going to left or right is chosen. Ghosts **can go through solid objects**, meaning at the end of a turn a ghost can be on same space as a solid object. Multiple ghosts can stay on same space too. This basically means all the ghosts on the same space will move exactly like each other after that point (they are all like a single ghost now).

After all ghosts have moved, if any of the ghosts ends up on the same space as Jimmy, Jimmy is caught and you have to try another scenario.

If Jimmy is not caught, he moves next. You have to decide on Jimmy's moves. Jimmy **cannot go through solid objects**. If Jimmy moves to a space with a ghost, he is caught. Jimmy **cannot move into a space he has already visited**. If Jimmy has no valid moves, consider him caught.

After Jimmy has moved, if he ends up on an empty border space (i.e. a space on the edge of the grid without a ghost on it), he has escaped.

If you can find at least one scenario where Jimmy can escape, output a truthy value. Also if the input position before doing any moves is already an escape position, it is valid and you should return truthy. If Jimmy is caught or out of valid moves in all possible scenarios, then return a falsy value.

## Challenge rules:

* You can use any consistent characters that you like for Jimmy, ghosts, solid objects and empty spaces in the input. You cannot use same character for different types of items though.
* The input board is always a rectangle or square with a minimum size of 2x2 and a maximum size of 10x10.
* Input is flexible as long as you don't include anything more than initial board information (for example, you cannot include if the initial board is already an escape position or not). It can be a multi-line string, a list of strings, a 2d array or matrix of characters or numbers, etc. It can also be position of items, for example a `(x, y)` for Jimmy and two lists of `(x, y)`s for ghosts and solid objects. You can also pass board size as a separate input if you like. Basically any format and combinations of inputs that don't include more than the initial board information are allowed.
* Input is guaranteed to always have a single Jimmy.
* Input always has at least one ghost.
* Input always has at least one solid object.
* Input can never start in a position where more than one item is on same space.
* Input can start in a position which already is an escaped position for Jimmy (any input with Jimmy on a border space), you should return truthy for cases like this.

## General rules:

* This is , so shortest answer in bytes for every language wins. Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
* Standard rules apply for your answer with default I/O rules, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return-type, full programs. Your call.
* Default Loopholes are forbidden.
* If possible, please add a link with a test for your code (i.e. TIO).
* Also, adding an explanation for your answer is highly recommended.

## Test cases:

**Truthy:**

*Jimmy can move left, up, left to escape:*

```
##########
......g...
#.o.......
#.....g...
##########

```

*Jimmy is already on a border space, this is an escape:*

```
#.
og

```

*If Jimmy moves only left or only right, he escapes:*

```
#########
.........
....g....
...g.g...
....o....
...g.g...
....g....
.........

```

*Jimmy has only two ways, one of them is an escape:*

```
##########
#g.o.....#
########.#
#........#
#.########
#........#
########.#
#........#
#.########

```

**Falsy:**

*Jimmy is caught by first move of any of the ghosts:*

```
.....
..g..
.go..
.....
.....

```

*Jimmy has no valid moves:*

```
###.......
#o#......g
###.......

```

*Jimmy will run out of valid moves before ghost can catch him:*

```
#####.....
#o..#....g
#####.....

```

*Remember, ghosts can go through solid objects:*

```
g#.#
.#.#
.#.#
.#o#
.#.#
.#.#
g#.#

```

*Oh poor Jimmy! It is a dead end...*

```
##########
#...o....g
##########

```

*Jimmy!!? How did you get there in the first place?*

```
#.########
#g.......#
#....g...#
#......g.#
#..g.....#
#....g...#
#........#
#....g...#
#..g....o#
##########

```

# Answer
# Python 2, ~~236~~ ~~235~~ ~~227~~ 212 bytes

```
def f((x,y),G,M,U=[]):
 R=1-(len(M[0])-1>x>0<y<len(M)-1);H=[(u+cmp(x,u),v+cmp(y,v)*(u==x))for u,v in G];d,e=0,1
 for _ in' '*4*(R<1>((x,y)in H)):J=z,w=x+d,y+e;d,e=-e,d;R|=M[w][z]>(J in U)<f(J,H,M,U+[J])
 return R

```

Try it online!

-15 bytes thx to Bubbler

As input, takes a tuple `(x,y)` as jimmy's initial position, a list `G == [(g1x,g1y), ...]` of initial ghost positions, and a list of lists `M` which is the 2-dimensional binary matrix where cells are `0` if they contain "an object" (i.e., `#`) and `1` otherwise.

Returns `1` for truthy, `0` for falsey.

Loosely speaking, the idea here is that we're going to depth-first recurse over down, left, up, right to seek a border cell. To start,

```
R=1-(len(M[0])-1>x>0<y<len(M)-1)

```

`R` is truthy if jimmy starts on a border cell. We could just return `R` if he does, but that would add an additional `return`. So in any case, we calculate where the ghosts would move to next.

```
H=[(u+cmp(x,u),v+cmp(y,v)*(u==x))for u,v in G]

```

`cmp(a,b)` returns the sign of `a-b` as `-1,0,1`; so this updates the ghosts positions with preference for horizontal movement if possible. Next,

```
for _ in' '*4*(R<1>((x,y)in H)):

```

executes a loop 4 times (`' '*4` is shorter than `range(4)`). Note that if jimmy is on the boundary (not `R<1`) or a ghost has landed on jimmy (not `1>((x,y)in H`), then we skip the for loop and so we return `1` if jimmy has escaped, or `0` if a ghost got him.

```
    J=z,w=x+d,y+e;d,e=-e,d

```

`d,e` is the offset to jimmy's next position, starting as `0,1`; and each time through the loop, `d,e=-e,d` rotates us through the 4 possible orthogonal positions.

```
    R|=M[w][z]>(J in U)<f(J,H,M,U+[J])

```

`R` gets set to truthy if jimmy's next position `J` is not an on "object" (`M[w][z]>0`), AND we haven't visited this position before (`1>(J in U)`), AND via recursion, jimmy can escape starting at position `J` with ghosts at `H` (`0<f(J,H,M,U+[J])`).
> 8 votes

# Answer
# Python 2, 199 bytes

```
def g(I,G,W,w,h):
 u,v=I.real,I.imag;R=1-(w-1>u>0<v<h-1);H=[z+cmp(u,z.real)+cmp(v,z.imag)*(u==z.real)*1jfor z in G]
 for d in(R<1>(I in H+W))*range(4):J=I+1j**d;R|=(J in W)<g(J,H,W+[I],w,h)
 return R

```

Try it online!

Rewrite of Chas Brown's solution using complex numbers.

All the coordinates are represented as a complex number `x+y*1j`. `I` is Jimmy's position, `G` is the list of ghosts and `W` is the list of walls. `w` and `h` are the width and height of the board, respectively.

The output values and the algorithm are the same as the linked solution.
> 6 votes

# Answer
# Javascript (ES6), 208 bytes

Recursive, depth-first search. A breadth-first approach would be probably faster, but less golfy. Input: a multi line string, using `1` for ghosts, `4` for solid objects, `6` for Jimmy and `2` for empty space.

```
f=(s,l=-~s.search`
`,j=s.search(6),g=[...s],x=j%l)=>j<l|!g[j+l]|!x|x>l-3||(g[j]=6,![...g].some((a,i)=>a&1&&(g[--g[i],t=i%l,i+=t<x?1:t>x?-1:i<j?l:i>j?-l:0]|=1,i==j))&&[l,-l,1,-1].some(d=>2==g[d+=j]&&f(g,l,d)))

```

*Less golfed*

```
// using parameters with default values instead of declared variables

f = (s,  // input board (as a string at first call, then as an array)
     l = -~g.search('\n'), // line size +1, that is distance to next line
     // at first call it is calculated, for recursive calls is passed
     j = g.search(6), // position of jimmy in grid
     // at first call it is calculated, for recursive calls is passed
     grid = [...s], // modifiable copy of board (converted to char array)
     x = j % l, // x position of jimmy, always obtained from j
) =>
{
  // first, check if Jimmy is out
  if (j<l | !grid[j+l] | !x | x>l-3) // top,bottom,left,right border
  {
    return true
  }
  // move all ghosts and check if some ghost can take Jimmy
  // the loop is on a copy of grid, so I can safely modify grid during the loop
  var taken = [...grid].some( // check all ghosts
        (a,i) => a & 1 && ( // is it a ghost?
         --grid[i], // remove ghost from grid, as it will move
         t = i % l, // x position of ghost
         // move ghost towards Jimmy
         i += t < x
           ? 1
           : t > x
             ? -1
             : i < j
               ? l
               : i > j
                 ? -l
                 : 0,
         grid[i] |= 1, // put ghost on grid in its new position
         i == j // return true if it reached Jimmy
  )
  return !taken && // if taken return false immediately
  // else recurse
  [l,-l,1,-1].some( // try to move Jimmy in all directions
    d => (
      d+=j, 2==g[d] && f(grid, l, d))
    )
  )
}

```

**Test**

```
cases=['##########\n......g...\n#.o.......\n#.....g...\n##########\n'
,'#.\nog\n'
,'#########\n.........\n....g....\n...g.g...\n....o....\n...g.g...\n....g....\n.........\n'
,'##########\n#g.o.....#\n########.#\n#........#\n#.########\n#........#\n########.#\n#........#\n#.########\n'
,'.....\n..g..\n.go..\n.....\n.....'
,'###.......\n\#o#......g\n###.......\n'
,'#####.....\n#o..#....g\n#####.....\n'
,'g#.#\n.#.#\n\.#.#\n.#o#\n.#.#\n.#.#\ng#.#\n'
,'##########\n#...o....g\n##########\n'
,'#.########\n#g.......#\n#....g...#\n#......g.#\n#..g.....#\n#....g...#\n#........#\n#....g...#\n#..g....o#\n##########\n'
]

f=(s,l=-~s.search`
`,j=s.search(6),g=[...s],x=j%l)=>j<l|!g[j+l]|!x|x>l-3||(g[j]=6,![...g].some((a,i)=>a&1&&(g[--g[i],t=i%l,i+=t<x?1:t>x?-1:i<j?l:i>j?-l:0]|=1,i==j))&&[l,-l,1,-1].some(d=>2==g[d+=j]&&f(g,l,d)))

cases.forEach(x=> (
  console.log(x,
    f(x.replace(/#/g,4).replace(/\./g,2).replace(/o/,6).replace(/g/g,2|1)))
))
```
> 3 votes

# Answer
# Jelly, ~~94~~ 89 bytes

```
Ø.,U$;N$+®ŒṬ€×8+®ŒṬ¤+&7$Ç€Ẹ
&Ɱ8,2ŒṪ€Ḣ©_¥/Ṡ01¦Ạ¡€+ƲṪŒṬḤ+&13$ÑÇFṀ>8Ʋ?
|Ø.¦4Z$⁺FṀ=12ƲÇFṀ>8Ʋ?

```

Try it online!

A full program that takes an integer matrix as its argument, with 0 as space, 1 as wall, 2 as ghost and 8 as Jimmy. Returns 1 for escape and 0 for no escape.
> 1 votes

---
Tags: code-golf, decision-problem, grid, path-finding
---


title: A Nice, Simple Web Scraping Code Golf

text:
# Question
Title: A Nice, Simple Web Scraping Code Golf
**Introduction**

This is a web scraping Code Golf challenge that attempts to take stock Name and price columns from the 'Most Active' list on this New York Times URL.

**Why is this challenge interesting?**

Challenge: Scrape these figures from this NYT page and turn it into a data frame using the smallest number of bytes possible (IE: `import pandas as pd` (should you choose to use Python) would give you a score of 19 (19 bytes). The data frame must be printed or returned as output.

Shortest Code by bytes wins the challenge. That's it!

Input:

> ```
> import requests
> from bs4 import BeautifulSoup
> import pandas as pd
>
> url='https://markets.on.nytimes.com/research/markets/overview/overview.asp'
>
> def pull_active(url):
>     # your code
>     response = requests.get(url)
>     if response.status_code == 200:
>       print("Response Successful")
>     else:
>       print("Response Unsuccessful")
>       return()
>     bs_object = BeautifulSoup(response.content,'lxml')
>     st_value = bs_object.find_all('td',class_='colPrimary')
>     st_name = bs_object.find_all('a',class_="truncateMeTo1")
>     x = []
>     y = []
>     for tag in st_name:
>       x.append(tag.get_text())
>     for tag in st_value:
>       y.append(tag.get_text())
>     data = {'Name': x[0:8],
>             'Price': y[0:8]}
>     df = pd.DataFrame(data)
>     return(df)
> pull_active(url)
>
> ```

Score: 773 bytes To beat it, any code under 773 bytes.

Output:

> ```
>   Name    Price
> 0 General Electric Co 10.11
> 1 Advanced Micro Devices Inc  33.13
> 2 PG&E Corp   6.14
> 3 Fiat Chrysler Automobiles NV    14.98
> 4 Neuralstem Inc  1.83
> 5 AT&T Inc    38.20
> 6 GrubHub Inc 34.00
> 7 Twitter Inc 29.86
>
> ```

...

# Answer
> 4 votes
# Bash \+ lynx, 73

```
lynx -dump http://nyti.ms/2BY72Ph|grep -Po '\[(1[6-9]|2[0-3])]\K[^.]*...'

```

Output is as follows:

```
General Electric Co          10.11
Advanced Micro Devices Inc   33.13
PG&E Corp                    6.14
Fiat Chrysler Automobiles NV 14.98
Neuralstem Inc               1.83
AT&T Inc                     38.20
GrubHub Inc                  34.00
Twitter Inc                  29.86

```

# Answer
> 4 votes
# , 97 bytes

```
library(rvest)
matrix(html_text(html_nodes(html("http://nyti.ms/2BY72Ph"),"td"))[2:25],,3,T)[,-3]

```

Try it online!

Gets all the `td` elements of the page. We want elements 2 to 25, which gives everything we need plus the `% change`, which is removed by omitting the 3rd column of the final matrix.

Outputs as a character matrix, since this is less bytes than a data frame:

```
     [,1]                  [,2]
[1,] "General Electric Co" "10.11"
[2,] "PG&E Corp"           "6.14"
[3,] "Neuralstem Inc"      "1.83"
[4,] "GrubHub Inc"         "34.00"
[5,] "Twitter Inc"         "29.86"
[6,] "Zynga Inc"           "6.21"
[7,] "Iveric Bio Inc"      "3.56"
[8,] "Pfizer Inc"          "38.48"

```

# Answer
> 2 votes
# PHP, ~~154~~ ~~153~~ 130 bytes

```
foreach(DOMDocument::loadHTMLFile('http://nyti.ms/2BY72Ph')->getElementsByTagName(td)as$i)$x<24&&print$x++%3?"$i->nodeValue ":"
";

```

Try it online!

*-23 bytes* thx to @Night2!

```
$ php nyt.php

Agile Therapeutics Inc 1.38
Advanced Micro Devices Inc 34.05
Facebook Inc 191.82
Kraft Heinz Co 32.34
Sirius XM Holdings Inc 6.72
Apple Inc 247.40
Zynga Inc 6.24
Snap Inc 15.11

```

# Answer
> 0 votes
# F# (.NET Core), ~~271~~ ~~257~~ ~~251~~ 233 bytes

```
 let l=HtmlDocument.Load("http://nyti.ms/2BY72Ph").Descendants["td"]|>Seq.filter(fun n->n.HasClass("colText")||n.HasClass("colPrimary"))|>Seq.take 16|>Seq.map(fun n->n.InnerText())|>Seq.toList
 [for i in 0..7-> l.[i*2]+" "+l.[i*2+1]]

```

Try it online!

---
Tags: code-golf, internet
---