# Question
Title: Retrieve all possible marks that can be placed in a Sudoku puzzle
Given a Sudoku puzzle, find all possible marks that can be filled into each empty cell.

## Test case

Input:

```
[
    [
        // Top left:
        [
            0, 0, 0,
            3, 4, 0,
            0, 0, 2
        ],
        // Top middle:
        [
            7, 4, 0,
            0, 0, 0,
            0, 0, 3
        ],
        // Top right:
        [
            8, 0, 0,
            1, 7, 0,
            0, 0, 0
        ]
    ],
    [
        // Middle left:
        [
            9, 0, 4,
            7, 0, 0,
            1, 0, 3
        ],
        // Center:
        [
            0, 5, 0,
            0, 0, 0,
            0, 7, 0
        ],
        // Middle right:
        [
            0, 0, 0,
            6, 4, 0,
            0, 0, 0
        ]
    ],
    [
        // Bottom left:
        [
            0, 0, 7,
            6, 3, 0,
            0, 0, 0
        ],
        // Bottom middle:
        [
            0, 0, 5,
            0, 0, 0,
            9, 1, 0
        ],
        // Bottom right:
        [
            0, 0, 0,
            5, 2, 0,
            7, 0, 0
        ]
    ]
]

```

Output:

```
[
    [
        // Top left:
        [
            [5], [1, 5, 6, 9], [1, 5, 6, 9],
            [], [], [5, 6, 8, 9],
            [5, 8], [1, 5, 6, 7, 8, 9], []
        ],
        // Top middle:
        [
            [], [], [1, 2, 6, 9],
            [2, 5, 6, 8], [2, 6, 8, 9], [2, 6, 8, 9],
            [1, 5, 6, 8], [6, 8, 9], []
        ],
        // Top right:
        [
            [], [3, 5, 6, 9], [2, 3, 5, 6, 9],
            [], [], [2, 5, 6, 9],
            [4, 9], [5, 6, 9], [4, 5, 6, 9]
        ]
    ],
    [
        // Middle left:
        [
            [], [2, 6, 8], [],
            [], [2, 5, 8], [5, 8],
            [], [2, 5, 6, 8], []
        ],
        // Center:
        [
            [1, 2, 3, 6, 8], [], [1, 2, 6, 8],
            [1, 2, 3, 8], [2, 3, 8, 9], [1, 2, 8, 9],
            [2, 4, 6, 8], [], [2, 4, 6, 8, 9]
        ],
        // Middle right:
        [
            [2, 3], [1, 3, 8], [1, 2, 3, 7, 8],
            [], [], [1, 2, 3, 5, 8, 9],
            [2, 9], [5, 8, 9], [2, 5, 8, 9]
        ]
    ],
    [
        // Bottom left:
        [
            [2, 4, 8], [1, 2, 8, 9], [],
            [], [], [1, 8, 9],
            [2, 4, 5, 8], [2, 5, 8], [5, 8]
        ],
        // Bottom middle:
        [
            [2, 3, 4, 6, 8], [2, 3, 6, 8], [],
            [4, 8], [8], [4, 7, 8],
            [], [], [2, 4, 6, 8]
        ],
        // Bottom right:
        [
            [3, 4, 9], [1, 3, 6, 8, 9], [1, 3, 4, 6, 8, 9],
            [], [], [1, 4, 8, 9],
            [], [3, 6, 8], [3, 4, 6, 8]
        ]
    ]
]

```

Output visualisation; the small numbers:

## Rules

* This is a . The shortest answer in bytes (or equivalent) wins.
* Input can be in array or string format.
* Input must be in the order presented above (top-left, top-middle, top-right, etc...)
* Output can be in array or string format, as long as the output can logically represent the expected result.
* Output must be in the same order as the input (top-left, top-middle, top-right, etc...)
* Output does not need to be prettified.
* Code must be applicable to any valid incomplete Sudoku grid.
* Standard golfing rules apply.

## Additional Notes:

You get additional fake internet points if your program or function uses the result to solve the Sudoku puzzle to the point where cell values can no longer be logically solved. For example, the very first cell in the test case can only ever possibly contain the number 5, so it should be considered when filling in the other values. This is just for fun and additional challenge, otherwise the shortest answer wins regardless of whether or not this criterion is met.

# Answer
# C (gcc), 193 bytes

```
#define F(x)for(x=0;x<9;++x)
char s[99];main(k,r,c){gets(s);F(r)F(c){
int d[99]={};F(k)d[s[r*9+k]]=d[s[k*9+c]]=d[s[r/3*27+k/3*9+c/3*3+k%3]]=1;
F(k)s[r*9+c]<48&&!d[49+k]&&putchar(49+k);puts("");}}

```

Assumes input in the following format (same sudoku as above):

```
..74.8..34....17...2..3...9.4.5....7.....64.1.3.7......7..5...63....52....91.7..

```

And outputs in the following format:

```
5
1569
1569

1269

3569
23569

5689
etc

```
> 4 votes

# Answer
## JavaScript (ES6), ~~208~~ ~~196~~ ~~190~~ ~~188~~ 186 bytes

```
g=>g.map((B,i)=>[...B].map((s,x)=>+s||[..."123456789"].filter(n=>(t=i=>(k=g[i].search(n)%m)<a|k>b)(j=i%3,m=3,a=b=x%3)&t(j+3)&t(j+6)&t(j=i-j,m=9,a=x-a,b=a+2)&t(j+1)&t(j+2)&t(i,a=0,b=8))))

```

**Input**:
An array of 9 strings (one per box, from top-left to bottom-right).

**Output**:
An array of 9 arrays, where each item consists of either the original number at this position or an array of characters representing the possible digits.

### Formatted and commented

```
g => g.map((B, i) =>              // for each box B at position i in the grid:
  [...B].map((s, x) =>            // for each cell s at position x in this box:
    +s ||                         // if there already is a number at this position, use it
    [..."123456789"].filter(n =>  // else, for each digit n in [1 .. 9]:
      (t = i =>                   // t() = helper function that looks for the digit n inside
        (k = g[i].search(n) % m)  // a given box i and returns a truthy value if its
        < a | k > b               // position modulo m is not in the range [a .. b]
      )(                          //
        j = i % 3,                // test the top box in the current column, using:
        m = 3,                    // modulo = 3 and
        a = b = x % 3             // range = [x % 3 .. x % 3]
      ) &                         //
      t(j + 3) &                  // test the middle box in the current column
      t(j + 6) &                  // test the bottom box in the current column
      t(                          //
        j = i - j,                // test the left box in the current row, using:
        m = 9,                    // modulo = 9 and
        a = x - a, b = a + 2      // range = [floor(x / 3) .. floor(x / 3) + 2]
      ) &                         //
      t(j + 1) &                  // test the middle box in the current row
      t(j + 2) &                  // test the right box in the current row
      t(i, a = 0, b = 8)          // finally test the current box, using:
    )                             // modulo = 9 (unchanged) and
  )                               // range = [0 .. 8] (thus testing the entire box)
)                                 //

```

### Demo

```
let f =

g=>g.map((B,i)=>[...B].map((s,x)=>+s||[..."123456789"].filter(n=>(t=i=>(k=g[i].search(n)%m)<a|k>b)(j=i%3,m=3,a=b=x%3)&t(j+3)&t(j+6)&t(j=i-j,m=9,a=x-a,b=a+2)&t(j+1)&t(j+2)&t(i,a=0,b=8))))

console.log(f([
  "000340002",
  "740000003",
  "800170000",
  "904700103",
  "050000070",
  "000640000",
  "007630000",
  "005000910",
  "000520700"
]));
```
> 2 votes

# Answer
# Python 2, 178 bytes

```
lambda s,R=range(9):[[[(s[Y][X][i]<1)*[q+1for q in R if~-(q+1in sum([[s[j/3][X][j%3*3+i%3],s[Y][j/3][j%3+i/3*3]]for j in R],[])+s[Y][X])]for i in R]for X in R[:3]]for Y in R[:3]]

```

An anonymous function that takes a 3-dimensional array of ints and returns a 4-dimensional array of ints.
> 2 votes

# Answer
# Haskell, 135 bytes

```
(%)=mod
x!y=x-x%y
f a=[[j|j<-[1..9],and[a!!k/=j|k<-[i!3-i!9%27+p%3+p!3*3|p<-[0..8]]++[i!9..i!9+8]++[i%9,i%9+9..80]],a!!i<1]|i<-[0..80]]

```

Defines a function `f` from lists of 81 `Int`s to lists of lists of `Int`s;

IO is like orlp's answer, except it uses `[0,1,2,3,4,5,6,7,8,9]` instead of `".123456789"`.

dianne saved a couple of bytes.
> 1 votes

# Answer
## JavaScript (ES6), 185 bytes

```
a=>a.map((b,r)=>b.map((d,c)=>d.map((e,i)=>e.map((g,j)=>[1,2,3,4,5,6,7,8,9].filter(v=>a.every(b=>b[c].every(e=>e[j]-v))&b.every(d=>d[i].every(g=>g-v))&d.every(e=>e.every(g=>g-v))&!g)))))

```

Takes as input an array of three rows of an array of three columns of a three by three array of cells of integers, and returns a five-dimensional array where all the integers have been replaced by arrays.
> 1 votes

---
Tags: code-golf, puzzle-solver, sudoku
---


# Question
Title: Print a specific value in the Wythoff matrix modulo 2
The Wythoff matrix is an infinite matrix consisting of the Grundy numbers of each square on a chessboard in Wythoff's game.

Each entry in this matrix is equal to the smallest nonnegative number that does not appear anywhere above, to the left, or diagonally northwest of the position of the entry.

The top-left 20-by-20 square looks like this:

```
  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19
  1  2  0  4  5  3  7  8  6 10 11  9 13 14 12 16 17 15 19 20
  2  0  1  5  3  4  8  6  7 11  9 10 14 12 13 17 15 16 20 18
  3  4  5  6  2  0  1  9 10 12  8  7 15 11 16 18 14 13 21 17
  4  5  3  2  7  6  9  0  1  8 13 12 11 16 15 10 19 18 17 14
  5  3  4  0  6  8 10  1  2  7 12 14  9 15 17 13 18 11 16 21
  6  7  8  1  9 10  3  4  5 13  0  2 16 17 18 12 20 14 15 11
  7  8  6  9  0  1  4  5  3 14 15 13 17  2 10 19 21 12 22 16
  8  6  7 10  1  2  5  3  4 15 16 17 18  0  9 14 12 19 23 24
  9 10 11 12  8  7 13 14 15 16 17  6 19  5  1  0  2  3  4 22
 10 11  9  8 13 12  0 15 16 17 14 18  7  6  2  3  1  4  5 23
 11  9 10  7 12 14  2 13 17  6 18 15  8 19 20 21  4  5  0  1
 12 13 14 15 11  9 16 17 18 19  7  8 10 20 21 22  6 23  3  5
 13 14 12 11 16 15 17  2  0  5  6 19 20  9  7  8 10 22 24  4
 14 12 13 16 15 17 18 10  9  1  2 20 21  7 11 23 22  8 25 26
 15 16 17 18 10 13 12 19 14  0  3 21 22  8 23 20  9 24  7 27
 16 17 15 14 19 18 20 21 12  2  1  4  6 10 22  9 13 25 11 28
 17 15 16 13 18 11 14 12 19  3  4  5 23 22  8 24 25 21 26 10
 18 19 20 21 17 16 15 22 23  4  5  0  3 24 25  7 11 26 12 13
 19 20 18 17 14 21 11 16 24 22 23  1  5  4 26 27 28 10 13 25

```

There is currently no known efficient algorithm for computing an arbitrary entry in the Wythoff matrix. However, your task in this problem is to try to design a heuristic function that will tell whether the number at a specific coordinate `wythoff(x, y)` is even or odd.

Your program may not contain more than 64 KB (65,536 bytes) of source code, or use more than 2 MB (2,097,152 bytes) of working memory.

In particular for memory usage, this means that the maximum resident set size of your program may not exceed 2 MB more than the maximum resident set size of an empty program in that language. In the case of an interpreted language, it would be the memory usage of the interpreter / virtual machine itself, and in the case of a compiled language, it would be the memory usage of a program that executes the main method and does nothing.

Your program will be tested on the `10000 x 10000` matrix for row values in `20000 <= x <= 29999` and column values in `20000 <= y <= 29999`.

The score of your program is the accuracy rate (number of correct guesses) your program achieves, with shorter code acting as a tiebreaker.

# Answer
> 6 votes
# Python; accuracy = 54,074,818; size = 65,526 bytes

*Previous scores: 50,227,165; 50,803,687; 50,953,001*

```
#coding=utf-8
d=r'''<65,400 byte string>'''
def f(x,y):
 a=max(x,y)-20000;b=min(x,y)-20000;c=(a*(a+1)//2+b)%523200
 return(ord(d[c//8])>>(c%8))&1

```

This approach divides all unique entries of the matrix into 523,200 groups and reads the best guess for the group **(x, y)** from a binary string. You can download the full source code from Google Drive.

I've used @PeterTaylor's parities to generate the string and to compute the accuracy.

# Answer
> 4 votes
## CJam (accuracy 50016828/100000000, 6 bytes)

```
{+1&!}

```

(In ALGOL-style pseudocode for non-CJammers: `return ((x + y) & 1) == 0`).

This performs better than any of the other two dozen simple heuristics I've tried. It's even better than any combination with the next two best ones.

---

The score assumes that my calculated section of the matrix is correct. Independent verification welcomed. I'm hosting the calculated parity bits at http://cheddarmonk.org/codegolf/PPCG95604-parity.bz2 (8MB download, extracts to 50MB text file: since the matrix is symmetric about the main diagonal, I've only included each line starting from the main diagonal, so you have to offset, transpose, and bitwise OR to get the full square).

The code which I used to calculate it is Java. It uses the definition fairly straightforwardly, but with a set data structure which run-length encodes the ranges so that it's quick to skip to the next permitted value. Further optimisation would be possible, but it runs on my moderately old desktop in about two hours and 1.5GB of heap space.

```
import java.util.*;

public class PPCG95604Analysis
{
    static final int N = 30000;

    public static void main(String[] args) {
        Indicator[] cols = new Indicator[N];
        Indicator[] diag = new Indicator[N];
        for (int i = 0; i < N; i++) {
            cols[i] = new Indicator();
            diag[i] = new Indicator();
        }

        int maxVal = 0;

        for (int y = 0; y < N; y++) {
            Indicator row = new Indicator(cols[y]);

            for (int x = y; x < N; x++) {
                Indicator col = cols[x];
                Indicator dia = diag[x - y];

                Indicator.Result rr = row.firstCandidate();
                Indicator.Result rc = col.firstCandidate();
                Indicator.Result rd = dia.firstCandidate();

                while (true) {
                    int max = Math.max(Math.max(rr.candidateValue(), rc.candidateValue()), rd.candidateValue());
                    if (rr.candidateValue() == max && rc.candidateValue() == max && rd.candidateValue() == max) break;

                    if (rr.candidateValue() != max) rr = rr.firstCandidateGreaterThan(max - 1);
                    if (rc.candidateValue() != max) rc = rc.firstCandidateGreaterThan(max - 1);
                    if (rd.candidateValue() != max) rd = rd.firstCandidateGreaterThan(max - 1);
                }

                if (y >= 20000 && x >= 20000) System.out.format("%d", rr.candidateValue() & 1);
                maxVal = Math.max(maxVal, rr.candidateValue());
                rr.markUsed();
                rc.markUsed();
                rd.markUsed();
            }
            if (y >= 20000) System.out.println();
        }
    }

    static class Indicator
    {
        private final int INFINITY = (short)0xffff;
        private final int MEMBOUND = 10000;

        private short[] runLengths = new short[MEMBOUND];

        public Indicator() { runLengths[1] = INFINITY; }

        public Indicator(Indicator clone) { System.arraycopy(clone.runLengths, 0, runLengths, 0, MEMBOUND); }

        public Result firstCandidate() {
            // We have a run of used values, followed by a run of unused ones.
            return new Result(1, 0xffff & runLengths[0], 0xffff & runLengths[0]);
        }

        class Result
        {
            private final int runIdx;
            private final int runStart;
            private final int candidateValue;

            Result(int runIdx, int runStart, int candidateValue) {
                this.runIdx = runIdx;
                this.runStart = runStart;
                this.candidateValue = candidateValue;
            }

            public int candidateValue() {
                return candidateValue;
            }

            public Result firstCandidateGreaterThan(int x) {
                if (x < candidateValue) throw new IndexOutOfBoundsException();

                int idx = runIdx;
                int start = runStart;
                while (true) {
                    int end = start + (0xffff & runLengths[idx]) - 1;
                    if (end > x) return new Result(idx, start, x + 1);

                    // Run of excluded
                    start += 0xffff & runLengths[idx];
                    idx++;
                    // Run of included
                    start += 0xffff & runLengths[idx];
                    idx++;

                    if (start > x) return new Result(idx, start, start);
                }
            }

            public void markUsed() {
                if (candidateValue == runStart) {
                    // Transfer one from the start of the run to the previous run
                    runLengths[runIdx - 1]++;
                    if (runLengths[runIdx] != INFINITY) runLengths[runIdx]--;
                    // May need to merge runs
                    if (runLengths[runIdx] == 0) {
                        runLengths[runIdx - 1] += runLengths[runIdx + 1];
                        for (int idx = runIdx; idx < MEMBOUND - 2; idx++) {
                            runLengths[idx] = runLengths[idx + 2];
                            if (runLengths[idx] == INFINITY) break;
                        }
                    }

                    return;
                }

                if (candidateValue == runStart + (0xffff & runLengths[runIdx]) - 1) {
                    // Transfer one from the end of the run to the following run.
                    if (runLengths[runIdx + 1] != INFINITY) runLengths[runIdx + 1]++;
                    if (runLengths[runIdx] != INFINITY) runLengths[runIdx]--;
                    // We never need to merge runs, because if we did we'd have hit the previous case instead
                    return;
                }

                // Need to split the run. From
                //   runIdx: a+1+b
                // to
                //   runIdx: a
                //   runIdx+1: 1
                //   runIdx+2: b
                //   runIdx+3: previous val at runIdx+1
                for (int idx = MEMBOUND - 1; idx > runIdx + 2; idx--) {
                    runLengths[idx] = runLengths[idx - 2];
                }
                runLengths[runIdx + 2] = runLengths[runIdx] == INFINITY ? INFINITY : (short)((0xffff & runLengths[runIdx]) + runStart - 1 - candidateValue);
                runLengths[runIdx + 1] = 1;
                runLengths[runIdx] = (short)(candidateValue - runStart);
            }
        }
    }
}

```

# Answer
> 3 votes
# J, accuracy = 50022668/108 = 50.0227%, 4 bytes

```
2|*.

```

Takes the coordinates as two arguments, computes the LCM between them and takes it modulo 2. A `0` means it is even and a `1` means it is odd.

The performance is based on the parity bits provided by @Peter Taylor.

The PRNG version before for 7 bytes, `2|?.@#.` had an accuracy of 50010491/108.

## Explanation

```
2|*.  Input: x on LHS, y on RHS
  *.  LCM(x, y)
2|    Modulo 2

```

---
Tags: code-challenge, classification, test-battery, binary-matrix
---


# Question
Title: A sign showing grouped opening hours of a cafe
You have probably seen these signs on the doors of various shops:

> ### OPENING HOURS
>
> mon-fri 0900-1800
> sat-sun 1100-1530

The task here is to generate a sign like that, grouping consecutive days with the same opening hours, from a list of opening hours for the whole week. Note that the week "wraps around" for what is considered consecutive.

## Input:

* 7 elements, representing the opening hours for each day in a week, starting with Monday.
* Each element is a string, on the form XXXX-XXXX
* Example input:

```
0900-1800 0900-1800 0930-1730 0930-1730 0900-1500 1100-1500 1100-1500

```
* It's ok to send the input as an array (for instance as input to a function if you don't read from stdin)

## Output:

* A list of opening hours, where consecutive days with the same opening hours are shown as a range. Note that sunday (the last day) and monday (the first day) also are consecutive days.
* A day where the day doesn't have similar opening hours to the days before or after is printed by itself
* Days are specified as three lowercase letters: *mon tue wed thu fri sat sun*
* Remember that first element in the input corresponds to mon, next to tue etc.
* Opening hours are shown as in the input
* Two examples

```
mon-fri 0900-1800, sat-sun 1100-1500
mon-wed 1030-1530, thu 100-1800, fri-sun 1200-1630

```
* **The output should be sorted, so ranges appear in the order the days do in the week.** Monday is preferred to be first, but it may happen it is not first in a group because the week wraps. So in this case tue is the first range.

```
tue-fri 0900-1800, sat-mon 1100-1500

```
* Don't group unless consecutive, here wednesday and friday have same opening hours but are separated by a Thursday with different opening hours so they are listed by themselves.

```
mon-tue 1000-1200, wed 0900-1500, thu 1000-1800, fri 0900-1500, sat-sun 1000-1500

```
* The output can be either comma-separated as the examples here, or separated by a newline as in the example on top.

## Test cases

First line is input, second line is expected output

```
0900-1800 0900-1800 0900-1800 0900-1800 0900-1800 1100-1500 1100-1500
mon-fri 0900-1800, sat-sun 1100-1500

0900-1800 0900-1800 0900-1800 0930-1700 0900-1800 1100-1500 1100-1500
mon-wed 0900-1800, thu 0930-1700, fri 0900-1800, sat-sun 1100-1500

1100-1500 0900-1800 0900-1800 0900-1800 0900-1800 1100-1500 1100-1500
tue-fri 0900-1800, sat-mon 1100-1500

1100-1500 1100-1500 0900-1800 0900-1800 0900-1800 0900-1800 1100-1500
wed-sat 0900-1800, sun-tue 1100-1500

1200-1500 1100-1500 0900-1800 0900-1800 0900-1800 0900-1800 1100-1500
mon 1200-1500, tue 1100-1500, wed-sat 0900-1800, sun 1100-1500

```

### Rules

This is code-golf, so the shortest answer in bytes wins.

# Answer
> 7 votes
## JavaScript (ES6), ~~182~~ ~~173~~ ~~170~~ ~~163~~ 157 bytes

*Saved 6 bytes with the help of edc65*

Takes input as an array of strings and directly prints the result to the console:

```
h=>{for(D="montuewedthufrisatsun".match(/.../g),d=c=i=j=0;j<8;y=d)h[i]==h[6]?i++:(v=h[d=(i+j++)%7])!=c&&(j>1&&console.log(D[x]+(x-y?'-'+D[y]:''),c),x=d,c=v)}

```

### Formatted and commented

```
h => {                               // input = list h of opening hours
  for(                               //
    D = "montuewedthufrisatsun"      // D = list of abbreviated names of days
        .match(/.../g),              //
    d =                              // d = current day of week
    c =                              // c = current opening hours
    i =                              // i = first day of week to process
    j = 0;                           // j = day counter
    j < 8;                           // stop when 7 days have been processed
    y = d                            // update y = last day of current day range
  )                                  //
  h[i] == h[6] ?                     // while the opening hours of day #i equal the opening
    i++                              // hours of sunday: increment i
  : (v = h[d = (i + j++) % 7]) != c  // else, if the new opening hours (v) of the current
    && (                             // day (d) doesn't match the current opening hours (c):
      j > 1 &&                       //   if this is not the first iteration:
        console.log(                 //     print:
          D[x] +                     //     - the first day of the current day range (x)
          (x - y ?                   //     - followed by either an empty string
            '-' + D[y]               //       or a '-' and the last day of the range
          : ''),                     //       (if they differ)
          c                          //     - the corresponding opening hours
        ),                           //   (endif)
      x = d,                         //   update x = first day of current day range
      c = v                          //   update c = current opening hours
    )                                // (endif)
}                                    // (end)

```

### Test cases

```
let f =

h=>{for(D="montuewedthufrisatsun".match(/.../g),d=c=i=j=0;j<8;y=d)h[i]==h[6]?i++:(v=h[d=(i+j++)%7])!=c&&(j>1&&console.log(D[x]+(x-y?'-'+D[y]:''),c),x=d,c=v)}

f(["0900-1800", "0900-1800", "0900-1800", "0900-1800", "0900-1800", "1100-1500", "1100-1500"]);
console.log('-');
f(["0900-1800", "0900-1800", "0900-1800", "0930-1700", "0900-1800", "1100-1500", "1100-1500"]);
console.log('-');
f(["1100-1500", "0900-1800", "0900-1800", "0900-1800", "0900-1800", "1100-1500", "1100-1500"]);
console.log('-');
f(["1100-1500", "1100-1500", "0900-1800", "0900-1800", "0900-1800", "0900-1800", "1100-1500"]);
console.log('-');
f(["1200-1500", "1100-1500", "0900-1800", "0900-1800", "0900-1800", "0900-1800", "1100-1500"]);
```

# Answer
> 3 votes
## Batch, 334 bytes

```
@echo off
set/af=l=w=0
set h=%7
call:l mon %1
call:l tue %2
call:l wed %3
call:l thu %4
call:l fri %5
call:l sat %6
call:l sun %7
if not %w%==0 set l=%w%
if %f%==0 set f=mon
call:l 0 0
exit/b
:l
if not %h%==%2 (
if %f%==0 (set w=%l%)else if %f%==%l% (echo %f% %h%)else echo %f%-%l% %h%
set f=%1
set h=%2
)
set l=%1

```

Takes input as command-line parameters, outputs each group on a separate line. Works by comparing each day's hours to the previous day, tracking `f` as the first day in the group, `h` as the hours for that group, `l` as the last day in the group and `w` for when the last group wraps back to the start of the week. When a mismatch is found the previous group is printed unless week wrapping is in effect. Finally when all the days are processed the last group is adjusted for any week wrapping and whether all the hours turned out to be the same before being output. `0` is used as a placeholder because empty strings cost more bytes to compare in Batch.

# Answer
> 2 votes
# Jelly, ~~87 84 80~~ 75 bytes

* 4bytes with the kind help of @Dennis (fixed a hack I used with the `'` quick, "flat")

Pretty sure there is a better way but for now:

```
Ṫ2ị$€;@µ+\µżṙ1’$Ṗị“ḅạṄMḤ9\E¥LḃɓṅÐĿ;$»s3¤Q€j€”-
ṙ7Ḷ¤Œr'€Ėµ2ịLµÐṂḢ
ÇṪḢ€ż@ÇÑ$G

```

**TryiItOnline**

### How?

```
            “ḅạṄMḤ9\E¥LḃɓṅÐĿ;$» - compressed string "montuewedthufrisatsun"
                  v  v
Ṫ2ị$€;@µ+\µżṙ1’$Ṗị -- s3¤Q€j€”- - Link 1, getDayStrings: [offset, groupedList]
Ṫ                               - Tail: get groupedList
 2ị$€                           - second index of each: get group sizes, e.g. mon-thu is 4
     ;@                         - concatenate (reversed arguments): prepend with offset
       µ                        - monadic chain separation
        +\                      - cumulative reduce with addition: start indexes
          µ                     - monadic chain separation
           ż                    - zip with
               $                - last two links as a monad
            ṙ1                  -     rotated left by one
              ’                 -     decrement:  end indexes
                Ṗ               - pop: remove last one, it's circular
                 ị              - index into
                        ¤       - last two links as a nilad
                    --          -     compressed string of weekdays (as shown at the top)
                      s3        -     split into 3s
                        Q€      - unique items for each: [tue,tue] -> [tue]
                          j€    - join each with
                            ”-  - literal string "-"

ṙ7Ḷ¤Œr'€Ėµ2ịLµÐṂḢ - Link 2: CalculateGroupingData: list of time strings
   ¤              - last two links as a nilad
ṙ                 -    rotate time strings list left by
 7Ḷ               -    range 7: [0,1,2,3,4,5,6]
       €          - for each
    Œr            -     run length encode
      '           -     flat - i.e. don't vectorise
        Ė         - enumerate [[1,[groupsFromMon]],[2,[groupsFromTue], ...]
         µ        - monadic chain separation
              ÐṂ  - filter for minimum of
             L    -     length of
          2ị      -     item at index 2: The number of groupings
                Ḣ - head: get the first occurring minimal (i.e Mon, or Tue, ...)

ÇṪḢ€ż@ÇÑ$G - Main link: list of time strings
Ç          - call last link (1) as a monad: get the offset and grouping
 Ṫ         - tail: get the grouping
  Ḣ€       - head each: get the time information
        $  - last two links as a monad
      Ç    -      call last link (1) as a monad: get the offset and grouping
       Ñ   -      call the next link as a monad: get the day strings
    ż@     - zip (with reversed arguments)
         G - arrange as a group (performs a tabulation to nicely align the result)

```

# Answer
> 1 votes
## JavaScript (ES6), ~~171~~ 169 bytes

```
a=>a.map((e,d)=>(d='montuewedthufrisatsun'.substr(d*3,3),e!=h&&(f?o(f):w=l,f=d,h=e),l=d),f='',l=w='sun',h=a[6],o=f=>console.log((f==l?l:f+'-'+l)+' '+h))&&o(f||'mon',l=w)

```

Takes input as an array and outputs to the console on separate lines. This is almost exactly a port of my Batch answer; `f` now defaults to an empty string of course, while I can also default `l` and `w` to `'sun'` (using a sentinel value saved me 3 bytes in Batch because I was able to merge the initialisation into the `set/a`).

# Answer
> 1 votes
# **BaCon, ~~514~~ ~~496~~ 455 bytes**

The BASIC program below is shown with its indentation. But without the indentation it consists of 455 bytes.

The idea is to use the time schedules as indexes to an associative array. Then, each day represents a bit: Monday = bit 0, Tuesday = bit 1, Wednesday = bit 2 and so on. The actual values for the members of the associative array are calculated by the respective bits of the days using a binary OR.

After that, it is a matter of checking how many consecutive bits are present in the associative array members, starting with bit 0.

In case bit 0 and also bit 6 are set, there is a week wrap. In that case, start looking for the start of the next sequence of bits, memorizing this start position. Print the rest of the sequences, and as soon bit 6 is reached, the day range should be ended with the memorized position earlier.

```
LOCAL n$[]={"mon","tue","wed","thu","fri","sat","sun"}
GLOBAL p ASSOC int
SUB s(VAR t$ SIZE a)
    FOR i = 0 TO a-1
        p(t$[i])=p(t$[i])|BIT(i)
    NEXT
    LOOKUP p TO c$ SIZE o
    b=e=0
    REPEAT
        FOR i=0 TO o-1
            IF p(c$[i])&BIT(b) THEN
                IF b=0 AND p(c$[i])&65=65 THEN
                    WHILE p(c$[i])&BIT(b)
                        INCR b
                    WEND
                    e=b
                    BREAK
                FI
                ?n$[b];
                r=b
                REPEAT
                    INCR b
                UNTIL NOT(p(c$[i])&BIT(b))
                IF e AND b>6 THEN
                    ?"-",n$[e-1];
                ELIF b-r>1 THEN
                    ?"-",n$[b-1];
                FI
                ?" ",c$[i]
            FI
        NEXT
    UNTIL b>6
    FREE p
ENDSUB

```

Using the following calls to invoke the SUB:

```
s("0900-1800", "0900-1800", "0900-1800", "0900-1800", "0900-1800", "1100-1500", "1100-1500")
PRINT "======"
s("0900-1800", "0900-1800", "0900-1800", "0930-1700", "0900-1800", "1100-1500", "1100-1500")
PRINT "======"
s("1100-1500", "0900-1800", "0900-1800", "0900-1800", "0900-1800", "1100-1500", "1100-1500")
PRINT "======"
s("1100-1500", "1100-1500", "0900-1800", "0900-1800", "0900-1800", "0900-1800", "1100-1500")
PRINT "======"
s("1200-1500", "1100-1500", "0900-1800", "0900-1800", "0900-1800", "0900-1800", "1100-1500")

```

**Output**:

```
mon-fri 0900-1800
sat-sun 1100-1500
======
mon-wed 0900-1800
thu 0930-1700
fri 0900-1800
sat-sun 1100-1500
======
tue-fri 0900-1800
sat-mon 1100-1500
======
wed-sat 0900-1800
sun-tue 1100-1500
======
mon 1200-1500
tue 1100-1500
wed-sat 0900-1800
sun 1100-1500

```

---
Tags: code-golf
---


title: The shifting dot

text:
# Question
Title: The shifting dot
Your program has to print out a number of spaces, followed by a dot and a newline. The number of spaces is the x position of your dot defined with 0 \< x \< 30

Every new line is a turn. Your program runs for 30 turns. Your program starts with a random x position and every turn shifts this position randomly by 1 to the left or right, while staying inside the defined area. Every turn your dot has to change its position by 1.

Your score is the number of characters. You get 10 bonus points, if every printed line consists of exactly 30 characters (and newline). You get 50 bonus points, if, while random, your program tends to stay in the middle of the defined area.

**Edit:** The 50 bonus points are intended to pull your dot to the middle. For example, this apply's if your dot is at x=20 and has a chance of 66% to go left and 33% to go right. This has to be independent from starting point and should only happen by altering the percentage value of left/right dynamically.

No input of any kind allowed, output has to be on the executing console!

For better understanding, here is a readable example in java, that would give you a score of 723:

```
public class DotJumper{
    public static void main(String[] args){
        int i = (int)(Math.random()*30);
        int max = 29;
        int step = 1;
        int count = 30;
        while(count>0){
            if(i<=1){
                i+=step;
            }else if(i>=max){
                i-=step;
            }else{
                if(Math.random() > 0.5){
                    i+=step;
                }else{
                    i-=step;
                }
            }
            print(i);
            count--;
        }
    }
    public static void print(int i){
        while(i>0){
            System.out.print(' ');
            i--;
        }
        System.out.println('.');
    }
}

```

# Answer
# APL, 39 – 10 – 50 = –21

```
0/{⎕←30↑'.',⍨⍵↑''⋄⍵+¯1*⍵>.5+?28}/31/?29

```

Tested on Dyalog with `⎕IO←1` and `⎕ML←3` but it should be quite portable.

**Explanation**

```
                   ?29  take a random natural from 1 to 29
                31/     repeat it 31 times
              }/        reduce (right-fold) the list using the given function:
          ⍵↑''          . make a string of ⍵ (the function argument) spaces
     '.',⍨              . append a dot to its right
⎕←30↑                   . right-pad it with spaces up to length 30 and output
                ◇       . then
             ?28        . take a random natural from 1 to 28
          .5+           . add 0.5, giving a number ∊ (1.5 2.5 ... 27.5 28.5)
        ⍵>              . check whether the result is <⍵ (see explanation below)
     ¯1*                . raise -1 to the boolean result (0 1 become resp. 1 -1)
   ⍵+                   . add it to ⍵ and return it as the new accumulator value
0/{                     finally ignore the numeric result of the reduction

```

At every step, this code decides whether to move the dot to the left or to the right depending on the probability that a random number chosen among (1.5 2.5 ... 27.5 28.5) is less than the current dot position.

Therefore, when the current dot position (number of spaces to the left) is 1 the increment is always +1 (all of those numbers 1.5 ... 28.5 are \> 1), when it's 29 it's always -1 (all of those numbers are \< 29); otherwise it's chosen randomly between +1 and -1, with a probability that's a linear interpolation between those extremes. So the dot is always moving and always more likely to move towards the center than towards the sides. If it's exactly in the middle, it has a 50% chance to move to either side.

The reduction (right-fold) of a replicated value `{...}/a/b` is just a trick I came up with to repeat a function `a-1` times, starting with value `b` and having the result of each iteration be the accumulator () argument to the next. The second and next input arguments () as well as the final result are ignored. It turns out to be way shorter than a regular recursive call with guard.

**Example run**

```
0/{⎕←30↑'.',⍨⍵↑''⋄⍵+¯1*⍵>.5+?28}/31/?29
                   .
                    .
                   .
                  .
                 .
                .
               .
                .
               .
                .
               .
              .
             .
              .
             .
              .
               .
              .
               .
                .
                 .
                  .
                 .
                  .
                 .
                  .
                 .
                .
               .
                .

```
> 18 votes

# Answer
## Mathematica 138 - 10 - 50 = 78

I'm not posting this because I think it's particularly well golfed, but for other reasons. It uses a Markov Process definition with a transition matrix designed to get the ball "centered".

The use of a Markov process in Mathematica allows us to calculate some useful statistics, as you will see below.

First the code (spaces not needed):

```
r = Range@28/28;
s = DiagonalMatrix;
ListPlot[RandomFunction[DiscreteMarkovProcess[RandomInteger@#, r~ s ~ -1 + s[29/28- r, 1]],
                                              #], PlotRange -> #] &@{1, 29}

```

Some outputs:

The transition matrix I used is:

```
MatrixPlot[s[r, -1] + s[29/28 - r, 1]]

```

But as I said, the interesting part is that using `DiscreteMarkovProcess[]` allows us to grab a good picture of what's happening.

Let's see the probability of the ball being at `15` at any time `t` *starting from a particular random state*:

```
d = DiscreteMarkovProcess[RandomInteger@29, s[r, -1] + s[29/28 - r, 1]];
k[t_] := Probability[x[t] == 15, x \[Distributed] d]
ListLinePlot[Table[k[t], {t, 0, 50}], PlotRange -> All]

```

You can see it fluctuates between 0 and a value near 0.3, that is because depending on the starting state you can only reach 15 on an odd or even number of steps :)

Now we can do the same thing, but telling Mathematica to consider the statistic starting from all possible initial states. What is the probability of being at `15` after a time `t`?:

```
d = DiscreteMarkovProcess[Array[1 &, 29]/29, s[r, -1] + s[29/28 - r, 1]];
k[t_] := Probability[x[t] == 15, x \[Distributed] d]
ListLinePlot[Table[k[t], {t, 0, 100}], PlotRange -> All]

```

You can see it also oscillates ... why? The answer is simple: in the interval `[1, 29]` there are more odd than even numbers :)

The oscillation is almost gone if we ask for the probability of the ball being at `14 OR 15`:

And you could also ask for the limit (in the Cesaro sense) of the state probabilities:

```
ListLinePlot@First@MarkovProcessProperties[d, "LimitTransitionMatrix"]

```

Oh, well, perhaps I deserve some downvotes for such an off-topic answer. Feel free.
> 12 votes

# Answer
# Bash, score 21 (81 bytes - 50 bonus - 10 bonus)

```
o=$[RANDOM%28];for i in {D..a};{ printf " %$[o+=1-2*(RANDOM%29<o)]s.%$[28-o]s
";}

```

In this answer, the dot is "pulled" back to the middle. This can be tested by hardcoding the starting point at 0 or 30.
> 7 votes

# Answer
# Smalltalk, 161 159 145-60 = 85

all columns are 30chars long (operating in mutable string b);

random movement chance is adjusted by biasing rnd value with p (rnd(0..29)-p), taking the sign (-1/0/1) and then adjusting to (-1/+1) via (-1|1), which is taken as move delta (effectively computes: x sign\<=0 ifTrue:-1 ifFalse:1). As ST uses 1-based indexing, I have to adjust all string refs by +1 (plz appreciate the -1|1 bit fiddling hack ;-) ).

```
p:=((r:=Random)next*29)rounded.(b:=String new:30)at:p+1put:$..0to:29do:[:i|b at:p+1put:$ .p:=(p+(((r next*29)-p)sign-1|1))min:29max:0.b at:p+1put:$..b printCR]

```

stealing an idea from Ruby version (thanx&Up @fipgr), I can get rid of the min/max check:

```
p:=((r:=Random)next*29)rounded.(b:=String new:30)at:p+1put:$..1to:30 do:[:i|b at:p+1put:$ .p:=p+((r next-(p/29))sign-1|1).b at:p+1put:$.;printCR]

```

output: (I have manually added the col-numbers and vertical bars afterwards; the code above does not generate them)

```
 012345678901234567890123456789
|                     .        |
|                    .         |
|                   .          |
|                  .           |
|                 .            |
|                  .           |
|                 .            |
|                  .           |
|                 .            |
|                .             |
|                 .            |
|                .             |
|               .              |
|                .             |
|                 .            |
|                  .           |
|                 .            |
|                  .           |
|                 .            |
|                  .           |
|                 .            |
|                .             |
|               .              |
|                .             |
|               .              |
|                .             |
|               .              |
|              .               |
|               .              |
|              .               |
 012345678901234567890123456789

```
> 5 votes

# Answer
## Ruby 69 66 64-60 = 4

```
i=rand(30);30.times{a=' '*30;a[i]=?.;puts a;i+=rand>i/29.0?1:-1}

```

**Sample:**

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

```
> 5 votes

# Answer
## C, 86

Assuming that seeding the `rand()` function is not required.

```
k=30;main(i){i=rand()%k;while(k--){printf("%*c\n",i+=i==30?-1:i==1||rand()%2?1:-1,46);}}

```

Explanation:

In C, in `"%*c"` the `*` means that the length of the output will have a minimum length, and this minimum length is determined by the argument of the function call (in this case, it is `i+=i==30?-1:i==1||rand()%2?1:-1`. The `c` means the next argument (`46`) is a character (the dot).

As for the boundary check, I apologise that I forgot about that. I have now added this to the answer, at the cost of 15 chars. The ternary operator works as follows: `boolean_condition?value_if_true:value_if_false`. Note that in C true is 1 and false is 0.
> 4 votes

# Answer
# Java: ~~204~~ ~~183~~ ~~182~~ ~~176~~ 175 characters - 10 - 50 = 115

```
class K{public static void main(String[]y){int k,j=0,i=(int)(29*Math.random());for(;j++<30;i+=Math.random()*28<i?-1:1)for(k=0;k<31;k++)System.out.print(k>29?10:k==i?'.':32);}}

```

First, the dot position must be `0 < x < 30`, i.e. \[1-29\]. This generates a number between 0 and 28 uniformly distributed, and for the purposes of this program \[0-28\] has the same effect as \[1-29\]:

```
i=(int)(29*Math.random());

```

I personally preferred if it would be normally distributed around 14, but my answer would be longer:

```
i=0;for(;j<29;j++)i+=(int)(2*Math.random());

```

Second, this code ensures that it tends to be in the middle:

```
i+=Math.random()*28<i?-1:1

```

The probability to get +1 is larger as smaller is the value of `i`, and we have the opposite for -1. If `i` is 0, the probability of getting +1 is 100% and the probability of getting -1 is 0%. If `i` is 28, the opposite to that will happen.

Third, by replacing the `32` at the end by `'_'` to see the output easier, we see that each line has 30 characters plus a new line:

```
__________.___________________
_________.____________________
________._____________________
_________.____________________
__________.___________________
___________.__________________
__________.___________________
_________.____________________
________._____________________
_________.____________________
________._____________________
_________.____________________
__________.___________________
_________.____________________
__________.___________________
___________.__________________
__________.___________________
_________.____________________
__________.___________________
___________.__________________
____________._________________
_____________.________________
____________._________________
_____________.________________
______________._______________
_____________.________________
______________._______________
_______________.______________
______________._______________
_____________.________________

```

Thanks to @VadimR (now, user2846289) for pointing out a misunderstanding in a prior version.

Thanks to @KevinCruijssen for shaving out 6 characters, even after more than two and a half years after this answer was initially posted.
> 4 votes

# Answer
# PHP, 118 113 112 111 (, -10 bonus points = 101)

*(second try, with horribly predictable `rand()` behavior, and a little more efficiency)*

```
for($n=30,$i=rand(1,29),$t=$s=pack("A$n",'');$n--;$i+=$i<2|rand()%2&$i<28?1:-1,$t=$s){$t[$i-1]='.';echo"$t\n";}

```

Possible result:

```
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________

```

# PHP, 130 (, -10 bonus points = 120)

*(first try)*

This could probably still be much more efficient:

```
for($n=30,$i=rand(1,29),$t=$s=str_repeat(' ',$n)."\n";$n--;$i=$i<2?2:($i>28?28:(rand(0,1)?$i+1:$i-1)),$t=$s){$t[$i-1]='.';echo$t;}

```

If I replace the space with an underscore (for display purposes), this is a possible result:

```
________._____________________
_______.______________________
______._______________________
_______.______________________
________._____________________
_______.______________________
______._______________________
_______.______________________
______._______________________
_______.______________________
________._____________________
_______.______________________
________._____________________
_________.____________________
__________.___________________
___________.__________________
__________.___________________
___________.__________________
__________.___________________
_________.____________________
________._____________________
_________.____________________
________._____________________
_______.______________________
______._______________________
_____.________________________
____._________________________
_____.________________________
____._________________________
___.__________________________

```

Oddly enough, if I replace `rand(0,1)` with `rand()%2` (PHP 5.4, on Windows XP), the random result always switches from odd to even, and vice versa, on each next iteration, making `rand()` worryingly predictable, in that sense, all of a sudden. This 'bug' appears to be one that has been known since 2004. Not entirely sure whether it's exactly the same 'bug' though.
> 3 votes

# Answer
# Mathematica 157-10-50 = 97

A random number from 1-30 is used for starting. All the remaining column numbers from the dot are chosen via `RandomChoice[If[c > 15, {2, 1}, {1, 2}] -> {-1, 1}] + c`, which translates to: "If the prior column number was greater than 15, select one number from the set {-1,1}, with -1 weighted 2:1 with respect to 1; otherwise, flip the weights and choose from the same set.

`ReplacePart` replaces the element in a list of 30 blank spaces that corresponds to the column of interest.

```
f@c_ := Switch[d = RandomChoice[If[c > 15, {2, 1}, {1, 2}] -> {-1, 1}] + c, 1, 2, 30, 29, d, d]
Row@ReplacePart[Array["_" &, 29], # -> "."] & /@ NestList[f, RandomInteger@29+1, 30] // TableForm

```
> 3 votes

# Answer
# \>\<\>, 358 - 10 = 348

This won't win at codegolf, but it works. (On windows 7 with this interpreter, which implements the "p" instruction differently than the esolang page defines it)

```
1v        >a"                              "v
v<      0<} vooooooooooooooooooooooooooooooo<
&  _>   v : >$" "@p1+:2f*(?v;
  |x1>  v^}!               <
  |xx2> v p
  |xxx3>v
  |xxxx4v $
>!|xxx< v }
  |xxxx6v }
  |xxx7>v @
  |xx8> v :
  |x9v  < @>  5)?v$:67*)?vv
   _>>&?v!@^     >$:b(?v v
  v }"."< :        v+ 1<  <
  >a+b+00}^0}}${"."< <- 1<

```

The name of this language can't be googled, so here's its esolang article for the curious.
> 3 votes

# Answer
## Python 2.7: ~~126~~ 109 -10-50 = 49

Got rid of the hard-coded starting point - now starts at random point. Because of this, I needed randint, so I decided to use that instead of choice for the offset. Used the (-1)\**bool trick for that.

```
from random import randint as r;p=r(0,29)
for i in range(30):
 print' '*p+'.'+' '*(29-p);p+=(-1)**(r(0,29)<p)

```

Some great answers here. First attempt in Python, thinking about improvements. Not helped by the need for an import.

-10 - yes 30 chars + \n on each line

-50 - the further away from the centre, the more likely a move the other way (accomplished by building a list with a different number of +/i offsets)

Previous attempt:

```
from random import choice;p,l=15,[]
for i in range(30):
 q=29-p;l+=[' '*p+'.'+' '*q];p+=choice([1]*q+[-1]*p)
print'\n'.join(l)

```
> 3 votes

# Answer
## J 42 characters - 50 -10 = -18

```
'_.'{~(|.~((I.%<:@#)*@-?@0:))^:(<@#)1=?~30

```

Explanation, starting from the right (some knowledge about trains comes in handy):

```
init=: 0=?~30          NB. where is the 0 in the random permutation of [0,29]
rep =: ^:(<@#)         NB. repeat as many times as the array is long, showing each step

rnd =: ?@0:            NB. discards input, generates a random number between 0 and 1

signdiff =: *@-        NB. sign of the difference (because this works nicely with
                       NB. the shift later on).

left_prob =: (I.%<:@#) NB. probability of shifting left. The position of the one (I.) divided by the length -1.

shift =: |.~           NB. x shift y , shifts x by y positions to the left.

output =: {&'_.'       NB. for selecting the dots and bars.

NB. Piecing things together:
output (shift (left_prob signdiff rnd))rep init

```

Center tendency, -50, example over 1000 runs:

```
NB. Amounts of ones in each column (sum)
   ]a=:+/ (|.~((I.%<:@#)*@-?@0:))^:(<1000)0=?30
0 0 0 0 0 0 2 6 10 12 25 60 95 121 145 161 148 99 49 27 19 13 6 1 1 0 0 0 0 0
   +/a NB. check the number of ones in total
1000
   |. |:(<.a%10) #"0 1] '*' NB. plot of those values
           *
           *
          ***
          ***
         ****
         ****
         ****
        ******
        ******
        ******
       *******
       *******
       ********
       ********
      **********
    **************

```

Example run, outputting exactly 30 bytes each line

```
_______________.______________
________________._____________
_______________.______________
________________._____________
_______________.______________
________________._____________
_______________.______________
________________._____________
_______________.______________
________________._____________
_______________.______________
______________._______________
_______________.______________
________________._____________
_________________.____________
________________._____________
_______________.______________
______________._______________
_____________.________________
____________._________________
___________.__________________
__________.___________________
___________.__________________
__________.___________________
___________.__________________
__________.___________________
___________.__________________
____________._________________
_____________.________________
______________._______________

```
> 3 votes

# Answer
# Java - ~~198~~ 183 characters

This is just a plain, simple, direct and uncreative golf of the example that you had given in the question.

```
class A{public static void main(String[]y){int c,j,i=(int)(Math.random()*30);for(c=30;c>0;c--)for(j=i+=i<2?1:i>28?-1:Math.random()>0.5?1:-1;j>=0;j--)System.out.print(j>0?" ":".\n");}}

```
> 2 votes

# Answer
## D - ~~167~~, ~~162~~, 144 ( 154 - 10 )

**Golfed**:

```
import std.stdio,std.random;void main(){int i=uniform(1,30),j,k;for(;k<30;++k){char[30]c;c[i]='.';c.writeln;j=uniform(0,2);i+=i==29?-1:i==0?1:j==1?1:-1;}}

```

**Un-golfed**:

```
import std.stdio, std.random;

void main()
{
    int i = uniform( 1, 30 ), j, k;

    for(; k < 30; ++k )
    {
        char[30] c;
        c[i] = '.';
        c.writeln;
        j = uniform( 0, 2 );
        i += i == 29 ? -1 : i == 0 ? 1 : j == 1 ? 1 : -1;
    }
}

```

**EDIT 1** \- I'm not quite sure if my code qualifies for the -50 bonus or not. `i` doesn't always start in the middle, but during the `for` loop, the dot never moves more than like 3 places either direction, so when `i` *does* start near the middle, the whole thing tends to stay there as well.

**EDIT 2** \- Code now qualifies for the -10 bonus, as it prints an array of 29 characters followed by LF for a total of exactly 30 chars per line.
> 2 votes

# Answer
## Javascript 125 73 72 60 (120 - 50 - 10)

```
i=0;r=Math.random;s=r()*30|0;do{a=Array(30);a[s=s>28?28:s?r()<s/30?s-1:s+1:1]='.';console.log(a.join(' '))}while(++i<30)

```

**EDIT:** Fix for 50 point bonus and 10 point bonus.

**EDIT 2:** Even shorter!
> 2 votes

# Answer
## Batch - (288 Bytes - 10) 278

```
@echo off&setlocal enabledelayedexpansion&set/ap=%random%*30/32768+1&for /l %%b in (1,1,30)do (set/ar=!random!%%2&if !r!==1 (if !p! GTR 1 (set/ap-=1)else set/ap+=1)else if !p! LSS 30 (set/ap+=1)else set/ap-=1
for /l %%c in (1,1,30)do if %%c==!p! (set/p"=."<nul)else set/p"=_"<nul
echo.)

```

Un-golfed:

```
@echo off
setlocal enabledelayedexpansion
set /a p=%random%*30/32768+1
for /l %%b in (1,1,30) do (
    set /a r=!random!%%2
    if !r!==1 (
        if !p! GTR 1 (set /a p-=1) else set /a p+=1
    ) else if !p! LSS 30 (set /a p+=1) else set /a p-=1
    for /l %%c in (1,1,30) do if %%c==!p! (set /p "=."<nul) else set /p "=_"<nul
    echo.
)

```

To output spaces instead of underscores - **372 Bytes** -

```
@echo off&setlocal enabledelayedexpansion&for /f %%A in ('"prompt $H &echo on&for %%B in (1)do rem"')do set B=%%A
set/ap=%random%*30/32768+1&for /l %%b in (1,1,30)do (set/ar=!random!*2/32768+1&if !r!==1 (if !p! GTR 1 (set/ap-=1)else set/ap+=1)else if !p! LSS 30 (set/ap+=1)else set/ap-=1
for /l %%c in (1,1,30)do if %%c==!p! (set/p"=."<nul)else set/p"=.%B% "<nul
echo.)

```

Looking for some help with the following logic, surely this isn't the most space efficient method (!r! will expand to either 1 or 2) -

```
if !r!==1 (
    if !p! GTR 1 (set /a p-=1) else set /a p+=1
) else if !p! LSS 30 (set /a p+=1) else set /a p-=1

```

*It golfs down to: `if !r!==1 (if !p! GTR 1 (set/ap-=1)else set/ap+=1)else if !r! LSS 30 (set/ap+=1)else set/ap-=1`*
> 2 votes

# Answer
### R, 107 characters - 60 points bonus=47

```
s=sample;i=s(29,1);for(j in 1:30){a=rep(' ',30);i=i+s(c(-1,1),1,p=c(i-1,29-i));a[i]='.';cat(a,'\n',sep='')}

```

`i` is the index of the dot. `a` is the array of 30 spaces. Starting point is random (uniformly from 1 to 29). At each iteration we randomly add -1 or +1 to `i` with weighted probabilities: `i-1` for `-1` and `29-i` for `+1` (values fed as probabilities don't need to sum to one), meaning that it tends to orient the dot towards the center while preventing it from below 1 or above 29 (since their probability fall to 0 in both case).

Example run with `_` instead of spaces for legibility:

```
> s=sample;i=s(1:30,1);for(j in 1:30){a=rep('_',30);i=i+s(c(-1,1),1,p=c(i-1,29-i));a[i]='.';cat(a,'\n',sep='')}
_______________________.______
______________________._______
_____________________.________
______________________._______
_____________________.________
______________________._______
_____________________.________
______________________._______
_____________________.________
____________________._________
_____________________.________
______________________._______
_____________________.________
______________________._______
_____________________.________
____________________._________
___________________.__________
____________________._________
___________________.__________
__________________.___________
_________________.____________
________________._____________
_______________.______________
______________._______________
_______________.______________
________________._____________
_________________.____________
________________._____________
_______________.______________
______________._______________

```
> 2 votes

# Answer
## C# 184 - 10 - 50 = 123

```
using System;namespace d{class P{static void Main(){var r=new Random();int p=r.Next(30);for(int i=0;i<30;i++){Console.WriteLine(".".PadLeft(p+1).PadRight(29));p+=r.Next(30)<p?-1:1;}}}}

```

**Output**

`space` replaced with `_` for legibility.

```
____________.________________
___________._________________
__________.__________________
___________._________________
____________.________________
_____________._______________
______________.______________
_____________._______________
______________.______________
_______________._____________
______________.______________
_______________._____________
______________.______________
_______________._____________
______________.______________
_____________._______________
____________.________________
___________._________________
____________.________________
_____________._______________
______________.______________
_____________._______________
____________.________________
___________._________________
____________.________________
___________._________________
____________.________________
___________._________________
__________.__________________
___________._________________

```
> 2 votes

# Answer
## J, 42 characters, no bonuses

```
' .'{~(i.30)=/~29<.0>.+/\(-0&=)?(,2#~<:)30

```

Example run:

```
          ' .'{~(i.30)=/~29<.0>.+/\(-0&=)?(,2#~<:)30
                       .
                      .
                     .
                      .
                     .
                      .
                     .
                      .
                       .
                      .
                     .
                    .
                     .
                    .
                     .
                    .
                     .
                      .
                       .
                        .
                       .
                        .
                       .
                      .
                     .
                      .
                       .
                      .
                     .
                    .

```
> 2 votes

# Answer
## Python 2.7 (126 - 10 (fix length) - 50 (Center Tendency) = 66)

The following program have a center tendency over a larger sample

```
s=id(9)%30
for e in ([[0,2][s>15]]*abs(s-15)+map(lambda e:ord(e)%2*2,os.urandom(30)))[:30]:
    s+=1-e;print" "*s+"."+" "*(28-s)

```

**Demo**

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

```
> 2 votes

# Answer
**PowerShell, 77 - 10 - 50 = 17**

```
$x=random 30
1..30|%{$x+=random(@(-1)*$x+@(1)*(29-$x))
'_'*$x+'.'+'_'*(29-$x)}

```

Output

```
_.____________________________
__.___________________________
___.__________________________
____._________________________
___.__________________________
____._________________________
_____.________________________
______._______________________
_______.______________________
______._______________________
_____.________________________
______._______________________
_______.______________________
________._____________________
_________.____________________
__________.___________________
___________.__________________
__________.___________________
___________.__________________
____________._________________
___________.__________________
__________.___________________
_________.____________________
__________.___________________
_________.____________________
________._____________________
_________.____________________
________._____________________
_________.____________________
__________.___________________

```
> 2 votes

# Answer
# JavaScript ES6 125 - 10 (30 character lines) - 50 (shifts toward middle) = 65

I had an epiphany going up the lift to my unit, so I had to get it down before it left my memory...

```
z=(j=Array(t=29).join`_`)+"."+j;x=(r=Math.random)()*t;for(i=30;i--;)console.log(z.substr(x=(x+=r()<x/t?-1:1)>t?t:x<0?0:x,30))

```

A little variable positional shuffling and a little creativity for calculating the shift probability indicated by `x/t`... (Thanks Kostronor for pointing it out!) I now gain the -50 bonus for shift to the middle, and I also made the starting position within the full range of the line, which allowed me to shave two bytes!

```
....5....0....5....0....5....0 <-- Ruler
_.____________________________
__.___________________________
___.__________________________
__.___________________________
___.__________________________
__.___________________________
_.____________________________
__.___________________________
___.__________________________
__.___________________________
___.__________________________
____._________________________
_____.________________________
______._______________________
_______.______________________
________._____________________
_______.______________________
______._______________________
_______.______________________
________._____________________
_______.______________________
________._____________________
_________.____________________
__________.___________________
_________.____________________
__________.___________________
___________.__________________
____________._________________
_____________.________________
______________._______________

```
> 1 votes

# Answer
## Javascript, 125 (135 - 10)

```
q=Math.random,p=~~(q()*31)+1;for(i=0;i++<30;){s='',d=j=1;for(;j++<31;)s+=j==p?'.':" ";p+=q()<.5?1:-1;p-=p>28?2:p<2?-2:0;console.log(s)}

```

Comments and advice is welcome.
> 1 votes

# Answer
# k, 53 - 10 - 50 = -7

**Solution 1**

```
{{a:30#" ";a[x]:".";a}'{x+$[*x<1?!30;1;-1]}\[x;*1?x]}

```

### Usage

```
{{a:30#" ";a[x]:".";a}'{x+$[*x<1?!30;1;-1]}\[x;*1?x]}30

"      .                       "
"       .                      "
"      .                       "
"       .                      "
"      .                       "
"       .                      "
"        .                     "
"         .                    "
"        .                     "
"         .                    "
"        .                     "
"         .                    "
"          .                   "
"           .                  "
"            .                 "
"             .                "
"              .               "
"               .              "
"              .               "
"             .                "
"            .                 "
"           .                  "
"          .                   "
"         .                    "
"        .                     "
"       .                      "
"        .                     "
"         .                    "
"          .                   "
"         .                    "
"          .                   "

```

**Solution 2**

```
{r::x;{a:r#" ";a[x]:".";a}'{a:r#0b;a[x?r]:1b;x+$[a@*1?r;-1;1]}\[x;*1?x]}[30]

```
> 1 votes

# Answer
**PHP**

With the centring bonus: 82 - 50 = 32

```
$i=rand(0,29);for($c=0;$c++<30;rand(0,28)<$i?$i--:$i++)echo pack("A$i",'').".\n";

```

For this version (old versions below), removed the min/max checking as that's taken care of in the centring code. `rand(1,28)` becomes important here as it allows for the `$i++` to push itself up to 29 (actual max).

edit: unnecessary parenthesis, moved shifting code

---

Simple algorithm for centring: generates a new number between 0 and 29 and compares it to the current one. Takes advantage of the "probability" of getting a number on the bigger side to draw towards the centre.

Actual result: (line numbering added afterwards)

```
01|        .
02|       .
03|        .
04|         .
05|          .
06|           .
07|            .
08|           .
09|            .
10|             .
11|              .
12|             .
13|            .
14|             .
15|            .
16|             .
17|            .
18|             .
19|              .
20|               .
21|              .
22|             .
23|              .
24|               .
25|                .
26|               .
27|                .
28|                 .
29|                .
30|               .

```

Archived:

`$i=rand(0,29);for($c=0;$c++<30;){($i<1?$j=1:($i>28?$j=28:$j=rand(0,29)));($j<$i?$i--:$i++);echo pack("A$i",'').".\n";}` 119 characters

`$i=rand(0,29);for($c=0;$c++<30;){($i<1?$i++:($i>28?$i--:(rand(0,29)<$i?$i--:$i++)));echo pack("A$i",'').".\n";}` 112 characters
> 1 votes

# Answer
## Racket 227 bytes (-10 for 30 characters, -50 for shift to midline = 167)

At each step, dot is twice more likely to move towards midline than away from it:

```
(let lp((r(random 1 31))(c 0)(g(λ(n)(make-string n #\space))))(set! r
(cond[(< r 1)1][(> r 30)30][else r]))(printf"~a~a~a~n"(g r)"*"(g(- 29 r)))
(when(< c 30)(lp(+ r(first(shuffle(if(> r 15)'(-1 -1 1)'(1 1 -1)))))(add1 c)g)))

```

Ungolfed:

```
(define (f)
    (let loop ((r (random 1 31))
               (c 0)
               (g (λ (n) (make-string n #\space))))
      (set! r (cond
                [(< r 1) 1]
                [(> r 30) 30]
                [else r] ))
      (printf "~a~a~a~n" (g r) "*" (g (- 29 r)))
      (when (< c 30)
        (loop (+ r
                 (first
                  (shuffle
                   (if (> r 15)
                       '(-1 -1 1)
                       '(1 1 -1)))))
              (add1 c)
              g))))

```

Testing:

```
(println "012345678901234567890123456789")
(f)

```

Output:

```
"012345678901234567890123456789"
                       *
                      *
                       *
                        *
                         *
                        *
                       *
                      *
                     *
                      *
                     *
                    *
                     *
                      *
                     *
                    *
                   *
                  *
                 *
                *
               *
                *
                 *
                *
                 *
                *
                 *
                *
                 *
                *
               *

```
> 1 votes

# Answer
# Scala, 95 - 10 = 85 bytes

```
def r=math.random
Seq.iterate(r*30,30){n=>println(("#"*30)updated(n.toInt,'.'))
(r*2-1+n)round}

```

I'm still thinking about the 50 byte bonus.

Explanation:

```
def r=math.random //define a shortcut for math.random, which returns a number 0 <= n < 1
Seq.iterate(      //build a sequence,
  r*30,             //starting with a random number bewteen 0 and 29
  30                //and containing 30 elements.
){n=>             //Calculate each element by applying this function to the previous element
  println(        //print...
    (" "*30)             //30 spaces
    updated(n.toInt,'.') //with the n-th char replaced with a dot
  )               //and a newline.
                  //The next element is
  (r*2-1+n)       //an random number between -1 and 1 plus n
  round           //rounded to the nearest integer.
}

```
> 1 votes

# Answer
# JavaScript

### 114 chars - 10 (30 char lines) - 50 (pull dot towards the middle) = 54

```
for(f=Math.random,a=[],i=30,j=k=f()*i|0;i--;a[j]='.',a[j+=29-k]='\n',j+=k+=f()>k/29?1:-1);console.log(a.join('-'))

```

However, I noticed that a 10 character reward for filling up the lines to 30 chars may be a bad deal; so:

## 102 chars - 50 (pull dot towards the middle) = 52

```
for(f=Math.random,a=[],i=30,j=k=f()*i|0;i;i--,a[j]='.\n',j+=k+=f()>k/29?1:-1);console.log(a.join('-'))

```

Kudos to @WallyWest for the simplified pull direction conditional `f()>k/29?1:-1`, my first draft used two nested conditionals.
> 1 votes

---
Tags: code-golf
---


title: Let's do the Wave!

text:
# Question
Title: Let's do the Wave!
**Input:**

* A string (the wave-snippet) with a length `>= 2`.
* A positive integer *n* `>= 1`.

**Output:**

We output a single-line wave. We do this by repeating the input string *n* times.

**Challenge rules:**

* If the first and last character of the input string matches, we only output it once in the total output (i.e. `^_^` of length 2 becomes `^_^_^` and not `^_^^_^`).
* The input string won't contain any whitespaces/tabs/new-lines/etc.
* If your language doesn't support non-ASCII characters, then that's fine. As long as it still complies to the challenge with ASCII-only wave-input.

**General rules:**

* This is , so shortest answer in bytes 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, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters, full programs. Your call.
* Default Loopholes are forbidden.
* If possible, please add a link with a test for your code.
* Also, please add an explanation if necessary.

**Test cases:**

```
_.~"(              length 12
_.~"(_.~"(_.~"(_.~"(_.~"(_.~"(_.~"(_.~"(_.~"(_.~"(_.~"(_.~"(

'°º¤o,¸¸,o¤º°'     length 3
'°º¤o,¸¸,o¤º°'°º¤o,¸¸,o¤º°'°º¤o,¸¸,o¤º°'

-__                length 1
-__

-__                length 8
-__-__-__-__-__-__-__-__

-__-               length 8
-__-__-__-__-__-__-__-__-

¯`·.¸¸.·´¯         length 24
¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯

**                 length 6
*******

String & length of your own choice (be creative!)

```

# Answer
> 7 votes
## Pyke, ~~15~~ ~~14~~ 10 bytes

```
tQQhQeq>*+

```

Try it here!

```
  QhQeq    -    input_1[0] == input_1[-1]
 Q     >   -   input_1[^:]
        *  -  ^ * V
t          -   input_2 - 1
         + - input_1 + ^

```

# Answer
> 23 votes
## Python 3, 32 bytes

```
lambda s,n:s+s[s[0]==s[-1]:]*~-n

```

Concatenates `n` copies of the string, removing the first character from all copies but the first if the first character matches the last one.

# Answer
> 14 votes
# 05AB1E, 13 bytes

Uses CP-1252 encoding.

```
D¬U¤XQi¦}I<×J

```

Try it online!

**Explanation**

`-___-` and `3` used as input for example.

```
D              # duplicate input string
               # STACK: "-___-", "-___-"
 ¬U¤X          # push copies of the first and last element of the string
               # STACK: "-___-", "-___-", "-", "-"
     Q         # compare for equality
               # STACK: "-___-", "-___-", 1
      i¦}      # if true, remove the first char of the copy of the input string
               # STACK: "-___-", "___-"
         I<    # push input number and decrease by 1
               # STACK: "-___-", "___-", 2
           ×   # repeat the top string this many times
               # STACK: "-___-", "___-___-"
            J  # join with input string
               # STACK: "-___-___-___-"
               # implicitly output

```

# Answer
> 11 votes
## JavaScript (ES6), 47 bytes

```
f=
(s,n)=>s+s.slice(s[0]==s.slice(-1)).repeat(n-1)
;
```

```
<div oninput=o.textContent=n.value&&f(s.value,n.value)><input id=s><input id=n type=number min=1><div id=o>
```

# Answer
> 8 votes
## Perl, 29 bytes

**28 bytes code + 1 for `-p`.**

Thanks to @Dada for helping me shave off a few bytes!

```
s/^((.).*?)(\2?)$/$1x<>.$3/e

```

### Usage

```
perl -pe 's/^((.).*?)(\2?)$/$1x<>.$3/e' <<< "'°º¤o,¸¸,o¤º°'
3"
'°º¤o,¸¸,o¤º°'°º¤o,¸¸,o¤º°'°º¤o,¸¸,o¤º°'
perl -pe 's/^((.).*?)(\2?)$/$1x<>.$3/e' <<< '**
6'
*******

```

Online example.

# Answer
> 5 votes
# Perl, 23 bytes

Includes +1 for `-p`

Give input string followed by number on separate lines on STDIN

```
wave.pl <<< "'°º¤o,¸¸,o¤º°'
3"

```

`wave.pl`:

```
#!/usr/bin/perl -p
$_ x=<>;s/(.)\K
\1?//g

```

If the first character in the word is not a regex special character this 22 bytes version works too:

```
#!/usr/bin/perl -p
$_ x=<>;/./;s/
$&?//g

```

# Answer
> 4 votes
## Retina, 29 bytes

Lines 2 and 5 have a trailing space.

```
 .+
$*
 $

 $`
(.) +\1?
$1

```

Try it online! (The first line enables a linefeed-separated test suite.)

# Answer
> 4 votes
## Batch, 117 bytes

```
@set/ps=
@set t=%s%
@if %s:~0,1%==%s:~1% set t=%s:~1%
@for /l %%i in (2,1,%1)do @call set s=%%s%%%%t%%
@echo %s%

```

Takes the number of repetitions as a command-line parameter and reads the string from STDIN.

# Answer
> 4 votes
# MATL, ~~19~~ ~~17~~ 14 bytes

```
ttP=l):&)liX"h

```

This works for ASCII on the online interpreter and for both unicode and ASCII when run using MATLAB.

**Try it Online!**

**Explanation**

```
        % Implicitly grab the input as a string
        %   STACK:  {'abcdea'}
        %
tt      % Make two copies and push them to the stack
        %   STACK:  {'abcdea'    'abcdea'    'abcdea'}
        %
P       % Flip the second copy around
        %   STACK:  {'abcdea'    'abcdea'    'aedcba'}
        %
=       % Perform an element-wise comparison. Creates a boolean array
        %   STACK:  {'abcdea'    [1 0 0 0 1]}
        %
l)      % Get the first element. If the first and last char are the same this will be
        % TRUE (1), otherwise FALSE (0)
        %   STACK:  {'abcdea'    1 }
        %
:       % Create an array from [1...previous result]. If the first char was repeated,
        % this results in the scalar 1, otherwise it results in an empty array: []
        %   STACK: {'abcdea'    1 }
        %
&)      % Break the string into pieces using this index. If there were repeated
        % characters, this pops off the first char, otherwise it pops off
        % an empty string
        %   STACK: {'a'    'bcdea'}
        %
li      % Push the number 1 and explicitly grab the second input argument
        %   STACK: {'a'    'bcdea'    1    3}
        %
X"      % Repeat the second string this many times
        %   STACK: {'a'    'bcdeabcdeabcdea'}
        %
h       % Horizontally concatenate the first char (in case of repeat)
        % or empty string (if no repeat) with the repeated string
        %   STACK: {'abcdeabcdeabcdea'}
        %
        % Implicitly display the result

```

# Answer
> 3 votes
# Pyth, 13 bytes

```
+z*@tBzqhzezt

```

Test suite!

Explanation to follow.

# Answer
> 3 votes
# Gema, 41 characters

```
* *=@subst{\? \$1=\?\; =;@repeat{$2;$1 }}

```

Sample run:

```
bash-4.3$ gema '* *=@subst{\? \$1=\?\; =;@repeat{$2;$1 }}' <<< '_.~"( 12'
_.~"(_.~"(_.~"(_.~"(_.~"(_.~"(_.~"(_.~"(_.~"(_.~"(_.~"(_.~"(

bash-4.3$ gema '* *=@subst{\? \$1=\?\; =;@repeat{$2;$1 }}' <<< "'°º¤o,¸¸,o¤º°' 3"
'°º¤o,¸¸,o¤º°'°º¤o,¸¸,o¤º°'°º¤o,¸¸,o¤º°'

bash-4.3$ gema '* *=@subst{\? \$1=\?\; =;@repeat{$2;$1 }}' <<< '** 6'
*******

```

# Answer
> 3 votes
# PowerShell v2+, 48 bytes

```
Param($s,$n)$s+$s.Substring($s[0]-eq$s[-1])*--$n

```

Outputs the whole string once, followed by n-1 copies of the string or substring, depending on if the first and last characters match.

The `.Substring()` method outputs from the index supplied to the end of the string, so if `$s[0]-eq$s[-1]` evaluates to false (0), we get the whole string. If that statement is true (1), We get the substring starting at the second character.

# Answer
> 3 votes
# VBA 119 bytes

New to this game and vba wins with the highest bytes :P

PS: can't believe vba stands close to JAVA **HAHA**

```
Function l(s,x)
l=s: s=IIf(Left(s,1)=Right(s,1),Mid(s,2,Len(s)),s)
z: x=x-1: If x>0 Then l=l & s: GoTo z:
End Function

```

Explanation:

```
+------------------------------------------------------------+-----------------------------------------------------------------------------------+
|                            code                            |                                     function                                      |
+------------------------------------------------------------+-----------------------------------------------------------------------------------+
| l=s                                                        | input string s is saved to base                                                   |
| s = IIf(Left(s, 1) = Right(s, 1), Right(s, Len(s) - 1), s) | checks whether 1 and last char is equal,                                          |
|                                                            | if yes removes the first char from s and that s will be used to for further joins |
| z:                                                         | z: is a label                                                                     |
| x = x - 1:                                                 | decreases looping round                                                           |
| If x > 0 Then l = l & s: GoTo z:                           | join strings until no more rounds to do                                           |
+------------------------------------------------------------+-----------------------------------------------------------------------------------+

```

# Answer
> 3 votes
## K, 12 Bytes

```
{,/[y#(,)x]}

/in action
{,/[y#(,)x]}["lollol";4]
"lollollollollollollollol"
{,/[y#(,)x]}["-_";10]
"-_-_-_-_-_-_-_-_-_-_"

/explanation (read function from right to left)
x is the string and y is the number of repetitions
(,)y    --enlist x so it becomes 1 value (rather than a list)
y#x     --take y many items of x
,/      --coalesce the list ,/[("-_";"-_")] --> "-_-_"

```

Thanks

# Answer
> 2 votes
# Java 11, ~~123~~ ~~111~~ ~~109~~ ~~107~~ ~~102~~ ~~100~~ ~~79~~ 58 bytes

```
s->n->s+s.substring(s.matches("(.).*\\1")?1:0).repeat(n-1)

```

Try it online.

I'll of course try to answer my own question. ;)
-5 bytes thanks to *@dpa97*.
-21 bytes converting from Java 7 to 10.
-21 bytes converting from Java 10 to 11.

**Explanation:**

```
s->n->             // Method with String & integer parameters and String return-type
  s                //  Return the input-String as result
   +               //  Appended with:
    s.subtring(    //   A substring of the input-String:
      s.matches("(.).*\\1")?
                   //    If the first and last characters are the same:
       1           //     Remove the first character in the substring-call
      :            //    Else:
       0)          //     Use the input-String as is
     .repeat(n-1)  //   Repeated the input-integer minus 1 amount of times

```

# Answer
> 2 votes
# PHP, 72 Bytes

```
<?=($a=$argv[1]).str_repeat(substr($a,$a[0]==substr($a,-1)),$argv[2]-1);

```

with PHP 7.1 it could be reduce to 65 Bytes

```
<?=($a=$argv[1]).str_repeat(substr($a,$a[0]==$a[-1]),$argv[2]-1);

```

# Answer
> 2 votes
# CJam, ~~16~~ 15 bytes

```
l]li*{(s@)@|@}*

```

Try it online

Explanation:

```
l]li*            Create a list of n-times the input string.
{(s@)@|@}*       Fold this list by taking out the last character of the first
                 argument and the first character of the second argument and
                 replacing them by their unique set union.
                 e.g.: "aba" "aba" -> "ab" 'a"a"| "ba" -> "ab" "a" "ba"
                       "abc" "abc" -> "ab" 'c"a"| "bc" -> "ab" "ca" "bc

```

# Answer
> 2 votes
## Pip, 18 bytes

Regex solution, taking advantage of the "no spaces in input" rule. Takes the string from stdin and the number as a command-line argument.

```
(q.s)XaR`(.) \1?`B

```

Try it online!

Explanation:

```
 q.s                Read from stdin and append a space
(   )Xa             String-multiply by first cmdline arg
       R            Replace
        `(.) \1?`     Regex: char followed by space followed by (optional) same char again
                 B    Callback function, short for {b}: return 1st capturing group

```

Thus, `a b` turns into `ab`, `a a` turns into `a`, and the space at the end of the string is removed. Then the result is autoprinted.

# Answer
> 2 votes
# Haskell, 59 bytes

```
a%b=concat$replicate a b
a@(s:z)#n|s/=last z=n%a|1<2=s:n%z

```

### Ungolfed version:

```
-- Helper: Appends str to itself n times
n % str = concat (replicate n str)

-- Wave creating function
(x:xs) # n
 -- If start and end of wave differ,
 | x /= last xs = n%(x:xs)
 | otherwise   = x:(n%xs)

```

# Answer
> 1 votes
# Javascript ES6, 49 chars

```
(s,n)=>s.replace(/(.).*?(?=\1?$)/,m=>m.repeat(n))

```

Test:

```
f=(s,n)=>s.replace(/(.).*?(?=\1?$)/,m=>m.repeat(n))
console.log(document.querySelector("pre").textContent.split(`
`).map(s=>s.split` `).every(([s,n,k])=>f(s,n)==k))
```

```
<pre>_.~"( 12 _.~"(_.~"(_.~"(_.~"(_.~"(_.~"(_.~"(_.~"(_.~"(_.~"(_.~"(_.~"(
'°º¤o,¸¸,o¤º°' 3 '°º¤o,¸¸,o¤º°'°º¤o,¸¸,o¤º°'°º¤o,¸¸,o¤º°'
-__ 1 -__
-__ 8 -__-__-__-__-__-__-__-__
-__- 8 -__-__-__-__-__-__-__-__-
¯`·.¸¸.·´¯ 24 ¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯
** 6 *******</pre>
```

# Answer
> 1 votes
## QBIC, 65 bytes

```
;:~left$$|(A,1)=right$$|(A,1)|A=left$$|(A,len(A)-1)][1,a|B=B+A]?B

```

I guess I should add LEFT$ and RIGHT$ to QBIC...

Explanation:

```
;          make the first cmd line parameter into A$
:          make the second cmd line parameter into a (num)
~left..]   Drop the last char if equal to the first char
[1,a...]   FOR the given number of repetitions, concat A$ to B$ (starts out empty)
?B         print B$

```

# Answer
> 1 votes
# C#, 79 bytes

```
(s,n)=>s+new string('x',n-1).Replace("x",s[0]==s[s.Length-1]?s.Substring(1):s);

```

A bit of an absurd method of repeating a string. Create a new string of the desired repeat length and then replace each character with the string to repeat. Other than that, looks like pretty much the same strategy as many others.

```
/*Func<string, int, string> Lambda =*/ (s, n) =>
    s                                      // Start with s to include first char at start
    + new string('x', n - 1).Replace("x",  // Concatenate n-1 strings of...
        s[0] == s[s.Length - 1]            // if first/last char are the same
            ? s.Substring(1)               // then skip the first char for each concat
            : s                            // else concat whole string each time
    )
;

```

# Answer
> 1 votes
# SpecBAS - 68 bytes

```
1 INPUT a$,n: l=LEN a$: ?IIF$(a$(1)<>a$(l),a$*n,a$( TO l-1)*n+a$(l))

```

Uses inline-`IF` to check if first and last characters are the same. If not, print string `n` number of times. Otherwise, splice the string to length-1, repeat that and put last character at end.

Can only accept ASCII characters (or characters built into SpecBAS IDE)

# Answer
> 1 votes
# APL, 19 bytes

```
{⍺,∊1↓⍵⍴⊂⍺↓⍨⊃⍺=⊃⌽⍺}

```

Usage:

```
      '^_^' {⍺,∊1↓⍵⍴⊂⍺↓⍨⊃⍺=⊃⌽⍺} 5
^_^_^_^_^_^

```

Explanation:

* `⊃⍺=⊃⌽⍺`: see if the first character matches the last character
* `⍺↓⍨`: if this is the case, drop the first character
* : enclose the result
* `⍵⍴`: replicate it  times
* `1↓`: drop the first one (this is shorter than `(⍵-1)⍴`)
* : get all the simple elements (undo the boxing)
* `⍺,`: add one instance of the whole string to the front

# Answer
> 1 votes
# Postscript, 98 bytes

```
exch/s exch def/l s length 1 sub def s 0 get s l get eq{/s s 0 l getinterval def}if{s print}repeat

```

...but you might need a ' flush' tacked onto that to get your PS interpreter to flush the comm buffer, another six bytes :(

# Answer
> 1 votes
# Common Lisp (LispWorks), 176 bytes

```
(defun f(s pos)(if(equal(elt s 0)(elt s #1=(1-(length s))))(let((s1(subseq s 0 1))(s2(subseq s 0 #1#)))(dotimes(j pos)(format t s2))(format t s1))(dotimes(j pos)(format t s))))

```

Usage:

```
    CL-USER 130 > (f "_.~~\"(" 12)
    _.~"(_.~"(_.~"(_.~"(_.~"(_.~"(_.~"(_.~"(_.~"(_.~"(_.~"(_.~"(
    NIL

    CL-USER 131 > (f "'°o¤o,??,o¤o°'" 3)
    '°o¤o,??,o¤o°'°o¤o,??,o¤o°'°o¤o,??,o¤o°'
    NIL

    CL-USER 132 > (f "-__" 1)
    -__
    NIL

    CL-USER 133 > (f "-__" 8)
    -__-__-__-__-__-__-__-__
    NIL

    CL-USER 134 > (f "ˉ`·.??.·′ˉ" 24)
    ˉ`·.??.·′ˉ`·.??.·′ˉ`·.??.·′ˉ`·.??.·′ˉ`·.??.·′ˉ`·.??.·′ˉ`·.??.·′ˉ`·.??.·′ˉ`·.??.·′ˉ`·.??.·′ˉ`·.??.·′ˉ`·.??.·′ˉ`·.??.·′ˉ`·.??.·′ˉ`·.??.·′ˉ`·.??.·′ˉ`·.??.·′ˉ`·.??.·′ˉ`·.??.·′ˉ`·.??.·′ˉ`·.??.·′ˉ`·.??.·′ˉ`·.??.·′ˉ`·.??.·′ˉ
    NIL

    CL-USER 135 > (f "**" 6)
    *******
    NIL

```

Explanation:

```
~~ =>   ~

\" =>   "

```

Ungolf:

```
    (defun f (s pos)
      (if (equal (elt s 0) (elt s (1- (length s))))
          (let ((s1 (subseq s 0 1)) (s2 (subseq s 0 (1- (length s)))))
            (dotimes (j pos)
              (format t s2))
            (format t s1))
        (dotimes (i pos)
          (format t s))))

```

# Answer
> 1 votes
# Vim, 17 bytes

The easy way to do this is to use a back-reference regex that can tell if the first and last chars match. But long regexes are long. We don't want that.

```
lDg*p^v$?<C-P>$<CR>hd@aP

```

The wave to repeat is in the buffer. I'm assuming the number to be repeated is in the register `"a` (type `qaNq` with N as the number to set it up). The idea is:

* If the first and last bytes match, delete everything up to the last character.
* If the first and last bytes *don't* match, delete all the characters.

Then `P` the deleted text `@a` times.

* `lDg*`: This maneuver creates a regex that matches any first character, regardless of whether it needs to be escaped or not, or whether it's a word or not. (`*` would be enough to make the properly escaped regex, but would add unwanted `\<\>` garbage if it was a word character, like `_`.)
* `p^`: Last step was messy. Clean up to the original position, beginning of the line.
* `v$`: In visual mode, `$` by default moves to *after* the end of the line.
* `?<C-P>$<CR>hd`: If the previous regex exists at the end of the line, this search will move to it; otherwise, stay beyond the end of the line. Move left from there and we accomplish the (tedious) delete we need.
* `@aP`: Run the number repeat as a macro to be used as an argument to `P`.

# Answer
> 1 votes
# Ruby, 38 bytes

```
->s,n{s[0]==s[-1]?s[0..-2]*n+s[0]:s*n}

```

I think this is pretty self-explanatory. I'm still wondering if there's a more concise way to represent the `s[0..-2]` block, but I haven't found it yet.

# Answer
> 0 votes
# Java (117 bytes)

```
String w(String a,int b){String c=a;for(;b>0;b--)c+=b+a.substring(a.charAt(a.length()-1)==a.charAt(0)?1:0);return c;}

```

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


title: Print this tic-tac-toe board!

text:
# Question
Title: Print this tic-tac-toe board!
Here is a tic-tac-toe board:

```
   a     b     c
      |     |
1  -  |  -  |  -
 _____|_____|_____
      |     |
2  -  |  -  |  -
 _____|_____|_____
      |     |
3  -  |  -  |  -
      |     |

```

Given a set of moves, print the board with the tokens on.

Input will be taken in as moves separated by spaces, with each move being:

* First, the token that's going
* Next, the letter of the column it is moving on
* Last, the number of the row it is moving on

Note that normal tic-tac-toe rules don't matter.

Also, there is no need to print the letters and numbers.

For example, the input `Ob2 Xc2 Ob3 Xa1` would result in

```
     |     |
  X  |  -  |  -
_____|_____|_____
     |     |
  -  |  O  |  X
_____|_____|_____
     |     |
  -  |  O  |  -
     |     |

```

Remember, this is , so the code with the smallest number of bytes wins.

## Leaderboards

Here is a Stack Snippet to generate both a regular leaderboard and an overview of winners by language.

To make sure that your answer shows up, please start your answer with a headline, using the following Markdown template:

```
# Language Name, N bytes

```

where `N` is the size of your submission. If you improve your score, you *can* keep old scores in the headline, by striking them through. For instance:

```
# Ruby, <s>104</s> <s>101</s> 96 bytes

```

If there you want to include multiple numbers in your header (e.g. because your score is the sum of two files or you want to list interpreter flag penalties separately), make sure that the actual score is the *last* number in the header:

```
# Perl, 43 + 2 (-p flag) = 45 bytes

```

You can also make the language name a link which will then show up in the leaderboard snippet:

```
# [><>](http://esolangs.org/wiki/Fish), 121 bytes

```

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

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

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

# Answer
> 7 votes
## JavaScript (ES6), ~~136~~ ~~133~~ 129 bytes

```
let f =

i=>eval("for(y=9,s='';y--;s+=`\n`)for(x=18;--x;)s+=x%6-3|y%3-1?' __|'[x%6?y/3:3]||' ':i[i.search('cba'[x/6|0]+(10-y)/3)-1]||'-'")

console.log(f("Ob2 Xc2 Ob3 Xa1"))
```

# Answer
> 5 votes
# Python (2.7), ~~188~~ 180 bytes

```
def f(s):a,b=3*[' '*5],3*['_'*5];c,d,e=[['  '+dict((m[1:],m[0])for m in s.split(' ')).get(x+y,'-')+'  'for x in'abc']for y in'123'];print'\n'.join(map('|'.join,[a,c,b,a,d,b,a,e,a]))

```

# Answer
> 4 votes
## Python 2, 112 bytes

```
s=input()+'- '
r=3;exec"print'|'.join([' '*5,'  %s  '%s[s.find(c+`r/3`)-1],'_'*5][r%11%3]for c in'abc');r+=1;"*9

```

Nine rows are printed corresponding to row indices `r`. The row index is counted up from `3` to `11` in an `exec` loop. Each row consists of vertical lines `|` joining three 5-character segments that cycle between:

* Five spaces
* Two spaces, a player symbol, then two spaces
* Five underscores

The type is made to cycle with `r%3`, except the last row has spaces rather than underscores, achieved with `r%11%3`.

To find the player symbol for the current cell, we look at the row number `r/3` and the column letter `c` from `"abc"`. We concatenate them to make a two-character string like `b3`, find the index of it in the input string, and then take the symbol (`X` or `O`) one index earlier. If neither player played there, the `find` will default to `-1`, which decrements to `-2`. We hack `s[-2]` to be `-` by appending two characters when we take input.

# Answer
> 1 votes
## Batch, ~~341~~ ~~339~~ ~~305~~ 287 bytes

```
@for %%a in (a1 a2 a3 b1 b2 b3 c1 c2 c3)do @set %%a=-
@for %%a in (%*)do @set s=%%a&call call set %%s:~1%%=%%s:~0,1%%
@set s="     |     |     "
@for %%l in (%s% "  %a1%  |  %b1%  |  %c1%" %s: =_% %s% "  %a2%  |  %b2%  |  %c2%" %s: =_% %s% "  %a3%  |  %b3%  |  %c3%" %s%)do @echo %%~l

```

Assumes consistent output. Edit: Saved 2 bytes by removing unnecessary spaces. Saved 34 bytes by writing the output using a `for` loop. Saved 18 bytes by eliminating the subroutine.

# Answer
> 1 votes
# Java, 138 bytes

**Edit:**

* ***-2** bytes off. Thanks to @Kevin Kruijssen*

Snipet:

```
m->{char[][]o=new char[3][3];for(char[]a:m)o[a[1]-'a'][a[2]-'0']=a[0];for(char[]a:o)System.out.println(a[0]+'|'+a[1]+'|'+a[2]+"\n-----");}

```

Code:

```
public static void tictactoe(char[][]moves){
  char[][]o=new char[3][3];
  for(char[]a:moves){
    o[a[1]-79][a[2]-48]=a[0];
  }
  for(char[]a:o){
    System.out.println(a[0]+'|'+a[1]+'|'+a[2]+"\n-----");
  }
}

```

# Answer
> 1 votes
# PHP, 187 Bytes

```
<?for(;$i++<162;)$s.=$i%18?($i%6?($i<144&&$i%54>36?"_":($i<144&&$i%54>18&&$i%6==3?"-":" ")):"|"):"\n";foreach(explode(" ",$_GET[a])as$t)$s[20+6*(1+($t[1]<=>b))+54*($t[2]-1)]=$t[0];echo$s;

```

Takes the input as string. If I could use an array it can be reduce to `$_GET[a]` instead of `explode(" ",$_GET[a])`

207 Bytes

```
<?foreach(explode(" ",$_GET[a])as$t)$a[(1+($t[1]<=>b))+3*($t[2]-1)]=$t[0];for(;$i++<162;)$s.=$i%18?($i%6?($i<144&&$i%54>36?"_":" "):"|"):"\n";for(;$x<9;)$s[18+54*(($x/3)^0)+2+6*($x%3)]=$a[+$x++]??"-";echo$s;

```

The simplest idea to create this 194 Bytes

```
<?for(;++$i<10;)$s.=($i==9||$i%3?($i%3==2?"  -  |  -  |  -  ":"     |     |     "):"_____|_____|_____")."\n";foreach(explode(" ",$_GET[a])as$t)$s[20+6*(1+($t[1]<=>b))+54*($t[2]-1)]=$t[0];echo$s;

```

# Answer
> 1 votes
# Mathematica, 205 bytes

```
StringReplacePart[a="     |     |
";b="  -  |  -  |  -
";c="_____|_____|_____
";{a,b,c,a,b,c,a,b,a}<>"",##]&@@Transpose[{#,{#,#}&[54LetterNumber@#2+6FromDigits@#3-39]}&@@@Characters/@StringSplit@#]&

```

This would be way shorter if I could use the built-in... (92 bytes)

```
Grid@SparseArray[{LetterNumber@#2,FromDigits@#3}->#&@@@Characters/@StringSplit@#,{3,3},"-"]&

```

# Answer
> 0 votes
# Autovim, 110 bytes (not competing)

Test driving Autovim... This is pretty much a Vimscript answer. Not competing because Autovim is still being developed.

```
ñ5i ␛a|␛ÿp3hr-phv0r_⌥v$kkyPPy2jPP$⌥vG$xGđkÿjp
…nsplit(@m)
ñğ0(@n[2]*3-2)j((char2nr(@n[1])-96)*6-4)lr(@n[0])
e…

```

To run it:

```
./bin/autovim run tictactoe.autovim -ni -@m "Ob2 Xc2 Ob3 Xa1"

```

Ungolfed:

```
execute "normal 5i \<esc>a|\<esc>yyp3hr-phv0r_\<c-v>$kkyPPy2jPP$\<c-v>G$xGddkyyjp"
for @n in split(@m)
execute "normal gg0".(@n[2]*3-2)."j".((char2nr(@n[1])-96)*6-4)."lr".(@n[0]).""
endfor

```

Explanation to follow if there is interest :)

# Answer
> 0 votes
# Groovy, 174 Bytes

```
{s->def r=0,o,t=[:];s.split(' ').each{t[it[1..2]]=it[0]};9.times{y->o='';17.times{x->o+=x%6==5?'|':y in [2,5]?'_':x%6==2&&y%3==1?t['abc'[r++%3]+(y+2)/3]?:'-':' '};println o}}

```

ungolfed:

```
{s->
    def r=0, o, t=[:];
    s.split(' ').each{
        t[it[1..2]]=it[0]
    };
    9.times{y->
        o='';
        17.times{x->
            o+= x%6==5 ? '|' : y in [2,5]? '_' : x%6==2 && y%3==1 ? t['abc'[r++%3]+(y+2)/3]?:'-' : ' '
        };
        println o
    }
}

```

# Answer
> 0 votes
# CJam, 62 bytes

```
" -_ -_ - "_'-Ser_+_@\]3*sqS/{)~\)'a-F*@+3*G+\t}/9/5/'|9*a*zN*

```

Try it online

Explanation:

```
" -_ -_ - "_'-Ser_+_@\]3*s e# Build a 135 character string representing the
                           e# columns of the board (top to bottom, left to right)
qS/{)~\)'a-F*@+3*G+\t}/    e# Process the input, put the tokens (O,X) in the string
                           e# The tokens have to placed at indexes
                           e# [19 22 25 64 67 70 109 112 115]
                           e# This is done with the formula 3*(15x+y)+16,
                           e# where x is the code point of the column letter
                           e# (minus 'a') and y is the row number.
9/5/'|9*a*zN*              e# Split into its parts, add the column separators, zip
                           e# and join with newlines.

```

---
Tags: code-golf, ascii-art, tic-tac-toe
---