title: Cycle my input please

text:
# Question
Title: Cycle my input please
# Input

A string `s` of printable ASCII characters, newlines, and spaces (`0x20 ( )` to `0x7E (~)`), and a non-negative integer `n`.

# Challenge

To write a program that outputs either another program, or `s` depending on `n`. If `n = 1`, Then your code should output code which outputs `s`. If `n = 2`, Your code should output code which outputs code which outputs `s` and so on.

All outputted code should be in the same language as the language of the original submission.

# Test Cases

Format: `s, n -> output` Assuming your submission is written in JavaScript:

```
No cycles, 0 -> No cycles
Hello, 1 -> console.log("Hello");
Cycle!, 3 -> console.log("console.log(\"console.log(\\\"Cycle!\\\")\")");
:), 3 -> console.log("console.log('console.log(`:)`)')");

```

# Scoring

This is , so aim for shortest code in bytes.

# Additional Rules

* I/O format is flexible
* Default rules and standard loopholes apply.
* The output of your submission must be valid.
* You can use any language, even if it was created after this challenge, as long as it wasn't created for the purpose of this challenge
* This isn't a polyglot challenge. A JavaScript submission shouldn't output Ruby code.
* Input is guaranteed to be valid as defined in the `Input` section

# Validation

Here's a quick tip to test your answers:
For `n=0`, `output=s`
For `n=1`, `eval(output)=s`
For `n=2`, `eval(eval(output))=s`
Where `n` and `s` are inputs

# Answer
> 5 votes
# , 43 bytes

```
f=function(s,n)"if"(n,function()f(s,n-1),s)

```

Try it online!

Returns a zero-argument function that recursively calls `f` with `n` set to `n-1`. `n` successive function applications returns `s`.

# Answer
> 2 votes
# , 3 bytes

```
ÀII

```

Try it online!

Takes string as input, prepends as many `I` as stated in the first argument.

# Answer
> 2 votes
# Google Sheets, 96 bytes

```
=Join("",If(B1,ArrayFormula("="&Rept("""",2^(Row(Offset(A1,0,0,B1))-1))),),A1,Rept("""",2^B1-1))

```

Inputs are in cells `A1` (`s`) and `B1` (`n`).

<sup>(Columns D, E, and F show the result if you copy the output from the column to its left and input it as a formula.)</sup>

---

The formula concatenates 3 pieces into a single string. The first piece is the most complicated.

```
If(B1,ArrayFormula("="&Rept("""",2^(Row(Offset(A1,0,0,B1))-1))),)

```

If `If` statement drops the prefix if `n=0` so you end up with `No cycles` instead of `="No cycles`. The `ArrayFormula` creates an array of equal signs followed by some number quotes. That number is `2^(x-1)` where `x` counts up from 1 to `n` thanks to the `Row(Offset(~))` combination.

The next piece (`A1`) adds in `s` and the final piece (`Rept("""",2^B1-1)`) adds in `2^n-1` quotes at the end.

# Answer
> 1 votes
# PHP, 69 bytes

```
function($s,$n){while($n--)$s='echo'.var_export($s,1).';';return $s;}

```

Try it online!

From the documentation about `var_export`:

> var\_export — Outputs or returns a parsable string representation of a variable

This function calls `var_export` prepends `echo` and appends `;` `$n` times.

# Answer
> 1 votes
# Perl 6, 25 bytes

```
{'{Q«'x$^n~$^s~'»}'x$n}

```

Try it online!

Function returning function code. Uses `Q« »` to quote unescaped ASCII strings.

# Answer
> 0 votes
# JavaScript (Node.js), 43 bytes

*Outputs a program that outputs a program that outp.... until `b=1`*

```
f=(a,b)=>b?--b?`(f=${f})('${a}',${b})`:a:''

```

Try it online!

# Answer
> 0 votes
# Haskell, 42 bytes

```
s#n|n<1=s|0<1="main=putStr"++show(s#(n-1))

```

Try it online!

# Answer
> 0 votes
# PHP, 12+1 bytes, not competing

plain text is a valid PHP program, but, if `N` is not `0`, this fails for text containing `<?` with short tags enabled and for text containing `<?php`  or `<?=` in any case:

```
<?=$argv[1];

```

call with `php -R '<code>' '<string>' <n>`; call the output with `php -R '<code>'`

# Answer
> 0 votes
# Jelly, 2 bytes

```
Ṿ¡

```

Try it online!

# Answer
> 0 votes
# Python, 55 bytes

```
c=lambda s,n:c("(lambda:"+repr(s)+")()",n-1)if n else s

```

# Answer
> 0 votes
# C (clang), `-DA=asprintf(` `-lm` 136 bytes

```
j,*c,*e;f(a,b){A&c,"%s",a);for(;b--;){e="";for(j=1;j++<pow(2,b);A&e,"\\%s",e));A&c,"puts(%s\"%s%s\");",e,c,e);}puts(c);}

```

Try it online!

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


title: Tips for Golfing in Batch

text:
# Question
Title: Tips for Golfing in Batch
Windows Batch (CMD) is probably the least suitable language for code golfing.

**Avoid newline characters**. If you're looking for the shortest code in bytes, as opposed to characters, you will want to get rid of all unnecessary carriage returns (newline characters = 2 bytes). You can use the `&` operation to do this, trimming one byte for each command.

```
echo Hello&echo World.

```

**Setting variables**. When setting variables using switches, the `set` parser will ignore spaces.

```
set /a a+=1
set /p b="User Input: "
:: Will be handled the same as..
set/aa+=1
set/pb="User Input: "

```

Note that the same parser rules do not apply to all commands - as an example, for loops require spaces. Except between the `set, string, or command` (i.e. what is inside the brackets) and the word `do`.

```
for /f %%a in (file.txt)do ...

```

**Simple mathematical expressions**. Also, notice the expression that I used for incrementing in the `set /a` command. For simple mathematical expressions use `+= -= *= /=` instead of (for example) `set /a a=%a%+1`.

**Gathering command output**. To get the output of a command, it can sometimes be useful to output to and read from a file, where you otherwise might have used a for loop to gather the output:

```
for /f %%a in ('echo test') do set a=%%a
:: Can be shortened to
echo test>f&set/pa=<f

```

`echo test` send stdout to a file called f, `>f`, start a new command `&` and get the contents of the file in a variable `set/pa=<f`. Obviously this isn't always useful. But it can be when all you need is a single line of output.

**Command output**. When suppressing command output, use `@` before the commands, unless you need to suppress *more than 9* commands, in which case, use `@echo off` at the start of your script. `@echo off` is 9 bytes long, and therefore will generally save more bytes with longer scripts.

**Commands often do more than just what is obvious** \- think about what your commands are doing. For example; if you need to set a variable and echo another variable, instead of:

```
set a=OUTPUT
echo %a%
echo test>f
set /p b=<f

```

You can use the set command with the `/p` switch to output `%a%` for you.

```
set a=OUTPUT
echo test>f
set /p b=%a%<f

```

Completely golfed...

```
set a=OUTPUT&echo test>f&set/pb=%a%<f

```

A couple of expamples - Count sum of all digits \- Goldbach's conjecture.

Any other tips are more than appreciated - I'll keep updating this if I think of anything else.

# Answer
> 4 votes
# Counters

Whenever you have a variable that will act as a counter starting from `0` you might want to write

```
set count=0
set/acount+=1

```

; however, you can eliminate the first lines because whenever `set/a` is used with an unset variable its value is assumed to be `0`

```
set/acounter+=1

```

# Code Blocks

There a number of ways you can shave off a few bytes when you have to used blocks of code.

Whenever you open a code block, you do not need to insert a line break before the first line of code in that block. The closing parentheses does not have to be on a line of its own either.

```
If %a%==%b% (
     echo true
) else (
    echo false
)

```

can be golfed to

```
If %a%==%b% (echo true)else (echo false)

```

# Printing Without Trailing New Line

The common pattern for this is

```
echo|set/p=text

```

but, you can save 2 bytes changing `echo` to `cd`

```
cd|set/p=text

```

# Answer
> 4 votes
## Directly print the result of a numeric calculation

If the challenge requires you to output a number that needs to be calculated, you can use `cmd/c set/a` to output the result of the calculation directly instead of saving the calculation and then echoing it. Example:

```
@set/a a=%1+%2
@echo %a%

```

becomes

```
@cmd/cset/a%1+%2

```

Edit: Apparently no spaces are necessary at all, saving 2 more bytes.

# Answer
> 3 votes
# Ampersands

Although &'s make the code seem shorter, as it uses less lines, it uses just as many characters as a newline. This means that

```
echo a&echo b

```

is as long as

```
echo a
echo b

```

so your code can stay readable without wasting characters.

There may be exceptions because some text editors combine line feed and carridge return for each new line.

# Answer
> 3 votes
### Delayed Expansion

Instead of using the lengthy `setLocal enableDelayedExpansion` you can use `cmd /v on` (or `cmd/von`) which will start a new interpreter with delayed variable expansion enabled.

I have yet to implement this so I don't have any examples, but you could use this in conjunction with the `/c` switch. Example:

```
@cmd/von/cset test=test^&echo !test!

```

Notice the use of the carat before the ampersand. if you need to use multiple ampersands or any other special characters, you may be better off enclosing everything after the `/c` switch in quotation marks:

```
@cmd/von/c"set test=test&set test1=test1&echo !test! !test1!"

```

This method also has the advantage of only having to use one `@` character to mask *all* input, and can therefore be used, without `/von`, as a shorter alternative to `@echo off` (or multiple `@` symbols).

9 characters: `@echo off`
6 characters: `@cmd/c`

For more lengthy scripts, which you can't do on one line, you can do the following to save some bytes:

```
@!! 2>nul||cmd/q/v/c%0&&exit/b

```

Or, ungolfed:

```
@!! 2>nul || cmd /q /v on /c %0 && exit/b

```

Replace `@echo off&setLocal enableDelayedExpansion` with the above.

When you first run your script `!!` will not expand at all, so you recieve an error because `"!!"` is not a command. The error output is then piped to nul (`2>nul`). When this first 'command' fails (`||`), it calls a new instance of cmd, which calls the batch file itself (using `/v (on)` to enable delayed expansion, and `/q` to turn echo off). Then `!!` will expand to nothing, as there is no variable called `<NULL>`. The rest of your script then runs. After which it will return to the original instance of cmd, and (`&&`) exit with the `/b` condition to keep the window open (the exit is so it doesn't continue to run through your script in the context of the first cmd instance, with echo on and delayed expansion off).

# Answer
> 2 votes
## Start of a string

The notation `%var:~start,end%` extracts a substring of the variable `var`. However if `start` is `0` then you can omit it entirely. We already know that you can omit `,end` if you want the rest of the string, which makes `%var:~%` an almost useless synonym for `%var%`, except that it returns `~` when `%var%` is empty. (Perhaps you could use it in a test: `if %var:~%==~`?)

# Answer
> 1 votes
## Repetitive strings

Set repetitive code blocks in variables, where the number of bytes used to set the variable + the number of bytes to output the variable are less than the number of bytes to just call the code directly.

For an example, see: Draw the combinations that add up to 100

You save 1 byte per usage of the set command, if you create a variable (named with one character, like "s") which contains `set<space>`. This only generates value if you use the set command more than 12 times. (Note there is a character at the end of the string `set s=set`).

```
set s=set
%s%a=1
%s%b=2
%s%c=3
%s%d=4
%s%e=5
%s%f=6
%s%g=7
%s%h=8
%s%i=9
%s%j=10
%s%k=11
%s%l=12
%s%m=13

```

The above is 1 byte shorter than..

```
set a=1
set b=2
set c=3
set d=4
set e=5
set f=6
set g=7
set h=8
set i=9
set j=10
set k=11
set l=12
set m=13

```

This is probably a pretty poor example - but it gets the point across.

# Answer
> 1 votes
# Shortening `IF EQU` statements

```
if %a% equ %b% do_something
if %a%==%b% do_something

```

Using `==` instead of  `equ`  saves **3** bytes.

---

# Shortening quotes in `IF` statements

This is a traditional so-called "safer" `if` comparsion.

```
if "%a%"=="%b%" do_something

```

To shorten this statement, do the following when the input can only be **alphanumerical**/**empty**:

```
if %a%.==%b%. do_something

```

Saving a total of **2** bytes.

---

# Challenges that require output

If the question says something like:

> Outputs at least 1 visible character.

then you could just do this:

```
cd

```

The `cd` shows the current directory to `STDOUT`.

---

# `GOTO`ing a label

Here's some methods of `goto`ing a label, ordered in descending order of bytes.

```
goto :l
goto l
goto:l

```

The above method saves **1** byte.

# Answer
> 1 votes
## Omitting space between command and parameters with slashes

Sorry about the uninformative title. What I'm trying to get at is that for some (not all) Windows command, you can omit the space in between the command/program name and the parameter, as long as that parameter starts with a slash. For example:

```
for /f %%G in ...

```

becomes

```
for/f %%G in ...

```

-1 Byte!

# Piping output instead of using ERRORLEVEL

Using ERRORLEVEL to determine whether a command ran correctly is not the shortest or most elegant method. Instead, you can pipe output. This works as follows (remember that any command after the `&&` operator only executes if the command before the `&&` ran without errors. Any command after the `||` operator, on the other hand, will run only if the command before it did NOT run properly. My example is:

```
net session>nul
if %errorlevel%==0 (echo 1) else (echo 0)

```

This could be replaced with:

```
net session>nul&&echo 1||echo 0

```

-26 Bytes, wow! Note that this does not work with commands like `choice`, where the ERRORLEVEL has a special value according to some input.

Regards,
Gabe

# Answer
> 1 votes
# Using parentheses effectively

Hi again,

Sorry to post a second answer but I felt this one deserved it. I have noticed that people often use one of the following methods to display command output without displaying that pesky `C:\Windows\System32>echo foo` line before each command.
The first method (using `echo off`):

```
@echo off
echo foo
echo bar
echo foobar
echo barfoo

```

The second method:

```
@echo foo
@echo bar
@echo foobar
@echo barfoo

```

However, neither of these methods are as short as the following:

```
@(echo foo
echo bar
echo foobar
echo barfoo)

```

Pretty handy, right? On another note, this can be used to pipe multiple lines of output to a file or device easily. For example, this lengthy code:

```
echo foo>file.txt
echo bar>file.txt
echo foobar>file.txt
echo barfoo>file.txt

```

becomes significantly shorter:

```
(echo foo
echo bar
echo foobar
echo barfoo)>file.txt

```

Thanks for reading this rather lengthy answer, and I hope this helps you. Regards,
Gabe

---
Tags: code-golf, tips
---


# Question
Title: Output the anti-clockwise inward spiral of a 2D array
From this stackoverflow question

Given a 2D array of size \\$ M \times N \\$, output the values in a anti-clockwise fashion. The output must start from the outside to the inside and the initial point always is going to be \\$(0,0)\\$.

**Example** Given:

$$ \begin{bmatrix} \color{blue}1&\color{red}2&\color{red}3&\color{red}4 \\ \color{red}5&6&7&\color{red}8 \\ \color{red}9&10&11&\color{red}{12} \\ \color{red}{13}&\color{red}{14}&\color{red}{15}&\color{red}{16}\end{bmatrix} $$

The edge values in counterclockwise is then \\$ 1,5,9,13,14,15,16,12,8,4,3,2 \\$.

Now we repeat the process for the inner values. This will end up with a matrix like the following

$$ \begin{bmatrix} \color{blue}6&\color{red}7 \\ \color{red}{10}&\color{red}{11} \end{bmatrix}$$

And the inner values is then \\$ 6,10,11,7 \\$

The final result will be then \\$ 1,5,9,13,14,15,16,12,8,4,3,2,6,10,11,7 \\$

---

**Rules**

* Assume non-empty input
* Assume matrix values as positive integers
* Standard I/O Methods apply
* Standard rules and winning criteria apply

---

**Some test cases**

```
Input
[
  [1, 2, 3, 4, 5, 6, 7],
  [8, 9, 10,11,12,13,14],
  [15,16,17,18,19,20,21]
]
Output
1,8,15,16,17,18,19,20,21,14,7,6,5,4,3,2,9,10,11,12,13

--------------------------------------------------------

Input
[
    [1,2,3],
    [3,2,1],
    [4,5,6],
    [6,5,4],
    [7,8,9],
    [9,8,7]
]
Output
1,3,4,6,7,9,8,7,9,4,6,1,3,2,2,5,5,8

-----------------------------------------------------
Input
[
    [1]
]
Output
1
-----------------------------------
Input
[
    [1, 2],
    [2, 1]
]
Output
1,2,1,2
-----------------------------------------------------
Input
[
    [1,2,3,6,7],
    [2,4,3,2,1],
    [3,2,4,5,6],
    [6,5,6,5,4],
    [10,4,7,8,9],
    [12,4,9,8,7]
]
Output
1,2,3,6,10,12,4,9,8,7,9,4,6,1,7,6,3,2,4,2,5,4,7,8,5,5,2,3,4,6

```

# Answer
# , 54 bytes

Several bytes saved by @Giuseppe and @J.Doe.

```
f=function(m)if(ncol(m))c(m[,1],f(t(m[nrow(m):1,-1])))

```

Try it online!

Recursively strip off the first column and row-reverse/transpose (making the bottom row the new first column) the rest of the matrix until you end up with only one column. Ungolfed "traditional" version:

```
f <- function(m) {
 if(ncol(m) == 1) {
    m
  } else {
    c(m[,1], f(t(m[nrow(m):1,-1])))
  }
}

```

It was pointed out that `ncol(m)` could be golfed to `sum(m)` to save another byte because we are allowed to assume positive integer matrix values. But I'll leave it like this since it works for all matrices (even matrices of strings!)
> 12 votes

# Answer
# Python 2, 52 bytes

```
f=lambda a:a and zip(*a)[0]+f(zip(*a[::-1])[1:])or()

```

Try it online!
> 10 votes

# Answer
# Pyth, 9 bytes

```
shMM.utC_

```

Try it here!

### How?

```
shMM.utC_     Full program. Takes a 2D array (matrix) from STDIN.
    .u        Until a result that has occurred before is found, loop and collect...
        _     Reverse the matrix (reverse the order of its rows).
       C      Transpose.
      t       Remove first element.
 hMM          For each element in the resulting 3D array, get the heads of its elements.
s             Flatten.

```
> 7 votes

# Answer
# Stax, 7 bytes

```
ôQÖG·í<

```

Run and debug it

It takes an array of rows on one line, and produces newline-separated output.

Unpacked, ungolfed, and commented, it looks like this.

```
W       repeat the rest of the program until cancelled explicitly
  rM    rotate matrix *clock-wise* (yes, this is the opposite of the challenge)
  |c    assert matrix is truthy. (has rows) cancel otherwise.
  B     remove the top row of the matrix, and push separately to main stack
  rm    reverse the top row (this fixes the rotation direction), and print each value

```

Run this one
> 5 votes

# Answer
# Pyth, 20 bytes

```
J.TQWJ=+YhJ=J_.TtJ)Y

```

Try it here

### Explanation

```
J.TQWJ=+YhJ=J_.TtJ)Y
J.TQ                    Call the transposed input J.
    WJ            )     While J is not empty...
      =+YhJ             ... put the top row into Y (initially [])...
           =J   tJ      ... remove the top row...
             _.T        ... reverse and transpose (rotate clockwise).
                   Y    Output the result.

```
> 4 votes

# Answer
# oK, 12 bytes

```
*+,/(1_+|:)\

```

Try it online!

This abuses the fact that oK doesn't seem to care too much about shape for transposition. In k this would be **13 bytes**: `*:',/(1_+|:)\`.

```
       +|:   /reverse, then transpose (rotate right)
     1_      /remove first line
    (     )\ /fixpoint of the above, keeping intermediate results (scan)
  ,/         /concatenate all the rows
*+           /get the first element of each row

```
> 4 votes

# Answer
# Clean, 69 bytes

```
import StdEnv,StdLib
? =transpose
@[h:t]=h++ @(reverse(?t))
@_=[]

```

#

```
@o?

```

Try it online!

Moves the next row/column to the head of the list so it can pattern matched in the argument.

For the first example in the challenge, this looks like:

```
@o? [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]
@ h=:[1, 5, 9, 13] t=:[[2, 6, 10, 14], [3, 7, 11, 15], [4, 8, 12, 16]]
[1, 5, 9, 13] ++ @ h=:[14, 15, 16] t=:[[10, 11, 12], [6, 7, 8], [2, 3, 4]]
[1, 6, 9, 13, 14, 15, 16] ++ @ h=:[12, 8, 4] t=:[[11, 7, 3], [10, 6, 2]]
[1, 6, 9, 13, 14, 15, 16, 12, 8, 4] ++ @ h=:[3, 2] t=:[[7, 6], [11, 10]]
[1, 6, 9, 13, 14, 15, 16, 12, 8, 4, 3, 2] ++ @ h=:[6, 10] t=:[[7, 11]]
[1, 6, 9, 13, 14, 15, 16, 12, 8, 4, 3, 2, 6, 10] ++ @ h=:[11, 7] t=:[]
[1, 6, 9, 13, 14, 15, 16, 12, 8, 4, 3, 2, 6, 10, 11, 7] ++ @ []

```
> 3 votes

# Answer
# Julia 0.7, 47 bytes

```
f(m)=[m[:,1];sum(m)<1?[]:f(rotr90(m[:,2:end]))]

```

Try it online!

Julia has a convenient built-in to rotate the matrix by 90 degrees eliminating the need for transpose-reverse operations.

As you can see from the compiler warnings, it insists that all components of the ternary conditional should be separated by spaces, and in v. 1.0 this has been actually enforced.

Oddly enough, in this situation the shortest way I found to break out of recursion was to use a try-catch block:

## Julia 1.0, 50 bytes

```
f(m)=[m[:,1];try f(rotr90(m[:,2:end]))catch;[]end]

```

Try it online!
> 3 votes

# Answer
# JavaScript (Node.js), 89 bytes

```
f=a=>a>[]?[...a.map(x=>x[0]),...f(a[0].map((_,i)=>a.map(y=>y[i]).reverse()).slice(1))]:[]

```

Try it online!

Takes the first column, transpose the remaining one then reverse each row (= rotate the matrix 90 degrees CW), and then repeat until the array has no more entries.
> 2 votes

# Answer
# 05AB1E, ~~13~~ ~~11~~ 10 bytes

```
ΔRøćRˆ}¯˜þ

```

-2 bytes thanks to *@Emigna*.

Try it online or verify all test cases.

**Explanation:**

```
Δ         # Loop until the stack no longer changes:
 R        #  Reverse the order of the rows
          #   i.e. [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]
          #    → [[13,14,15,16],[9,10,11,12],[5,6,7,8],[1,2,3,4]]
  ø       #  Zip, swapping rows and column
          #   → [[13,9,5,1],[14,10,6,2],[15,11,7,3],[16,12,8,4]]
   ć      #  Head extracted
          #   → [[14,10,6,2],[15,11,7,3],[16,12,8,4]] and [13,9,5,1]
    R     #  Reverse this row
          #   → [1,5,9,13]
     ˆ    #  Pop and push it to the global array
}         # After the loop:
 ¯        #  Push the global array
          #   i.e. [[1,5,9,13],[14,15,16],[12,8,4],[3,2],[6,10],[11],[7],"",""]
  ˜       #  Flatten it
          #   → [1,5,9,13,14,15,16,12,8,4,3,2,6,10,11,7,"",""]
   þ      #  Remove all empty string by only leaving all digits
          #   → ["1","5","9","13","14","15","16","12","8","4","3","2","6","10","11","7"]
          # (and output it implicitly)

```
> 2 votes

# Answer
# APL (Dyalog), ~~24~~ 22 bytes

```
{×≢⍵:⍵[;1],∇⍉⊖0 1↓⍵⋄⍬}

```

Try it online!

# How?

```
{×≢⍵:⍵[;1],∇⍉⊖0 1↓⍵⋄⍬}
{                    } - a function
 ×≢⍵:                  - if non-empty:
     ⍵[;1]             - the left column
          ,∇⍉⊖0 1↓⍵    - repeat this function without the left column, rotated counter clockwise
                   ⋄⍬  - otherwise, return an empty vector

```
> 2 votes

# Answer
# Jelly, 9 bytes

```
ZḊUƊƬḢ€€Ẏ

```

Try it online!
> 1 votes

# Answer
# Charcoal, 25 bytes

```
≔⮌ＥＡ⮌ιθＷθ«≔Ｅ§θ⁰⮌Ｅθ§μλθＩ⊟θ

```

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

```
≔⮌ＥＡ⮌ιθ

```

Rotate the input by 180°. This is for two reasons: a) the last row is the easiest to remove, and b) it's easier to loop if the row is removed at the end of the loop. (I did try reflecting and outputting clockwise but that took an extra byte.)

```
Ｗθ«

```

Repeat until the array is empty.

```
≔Ｅ§θ⁰⮌Ｅθ§μλθ

```

Rotate the array by 90°.

```
Ｉ⊟θ

```

Remove the last row of the array and print the element as strings on separate lines.
> 1 votes

# Answer
# Ruby, 65 bytes

```
->a{x,*a=a.transpose;(w,*a=a.transpose.reverse;x+=w)while a[0];x}

```

Try it online!
> 1 votes

# Answer
# PowerShell, 266 bytes

Yeah.. PowerShell isn't the best for handling matrices. But, the algorithm is basically the same as the above.. Each row is represented as a comma-separated string, and we basically do a rotation and transposition for each layer. I can probably shave more off, but... I *am* already in my pajamas...

```
Filter F{$a=$_-replace"],|]|\s",''-split'\['|?{$_-ne''};$b=@();while($a-ne $null){$N=($a[0]-split',').Count-1;$a=0..$N|%{$i=$_;($a|%{($_-split',')[$i]})-join','};if($d){[array]::Reverse($a)}if($N-gt0){$b+=$a[0];$a=$a[1..$N]}else{$b+=$a;$a=$null};$d=$true}$b-join','}

```

Try it online!
> 1 votes

---
Tags: code-golf, matrix
---


title: Chiral three dimensional texts

text:
# Question
Title: Chiral three dimensional texts
Two dimensional chiral objects are not chiral in three dimensional space. This is because you can flip them over which is equivalent to taking the mirror image unlike in two dimensions where only rotations in the plane of the object are allowed which cannot reproduce the effect of a mirror operation. In this challenge, we will be deciding whether three dimensional texts are chiral.

## Some definitions

* **Three dimensional text**: A rectangular three dimensional array of characters. In this challenge, programs will only need to handle nonwhitespace printable ASCII (`!` through `~`).
* **Mirror operation**: The operation of reversing the order of characters along a single axis of the three dimensional text.

Rotations can be thought of intuitively, but here is an explicit definition for those who will eventually ask.

* **90-degree rotation**: The operation of transposing each plane perpendicular to a specific axis (say \\$i\\$), then applying a mirror operation to an axis other than \\$i\\$.
* **Rotation**: A succession of 90-degree rotations.
* **Chiral**: A three dimensional text is chiral if after applying any single mirror operation, there does not exist a rotation of the new text that reproduces the original text. A text is not chiral if after applying a single mirror operation the new text can be rotated back to the original text.

A slightly more concise definition of chirality is lack of existence of an improper rotation under which an object is invariant.

## Task

In whatever format you prefer, take a three dimensional text as input.

Output one of two consistent values, one indicating that the text is chiral and one indicating that it is not.

Shortest code wins.

## Examples

In each section, the vertical pipes (`|`) separate the test cases. Within each test case, layers of the three dimensional texts are separated by blank lines.

**Not chiral**

```
Z--Z    |    i~    |    Qx    |    a    |    abaLIa
----    |    >>    |    xx    |    b    |    N#)*@"
Z--Z    |          |          |         |    }-3}#k
        |    >>    |    QQ    |    d    |    ../..'
Z--Z    |    ~i    |    QQ    |    e    |
----    |          |          |         |
Z--Z    |          |          |    f    |
        |          |          |    g    |

```

**Chiral**

```
Z--Z    |    *k    |    Qxxx    |    a*
----    |    <0    |    xxxx    |    **
Z---    |          |            |
        |    l7    |    QQQQ    |    **
Z---    |    GB    |    QQQQ    |    a*
----    |          |            |
Z--Z    |    q~    |            |    **
        |    ]J    |            |    *a

```

# Answer
# Haskell, ~~97~~ ~~96~~ 95 bytes

* -1 byte thanks to nimi

```
f s=all(r s/=)$foldr($)s<$>mapM(\_->[id,g,map g])[1..6]
g=r.foldr(zipWith(:))e
r=reverse
e=[]:e

```

Try it online!

## Explanation

Ok, this is a bit mathy. It is well known that the group of rotations as described in the challenge (i.e. the group generated by rotations of 90 degrees around one of the three principal axes) is isomorphic to the symmetric group \\$S\_4\\$, as described here. It is also well known that \\$S\_4\\$ is generated by the elements \\$(1\\, 2\\, 3\\, 4),(1\\, 3\\, 2\\, 4)\\$.

What I am trying to say is this: fix two *distinct* axes, and call the 90 degrees rotations about those axes \\$r\_1\\$ and \\$r\_2\\$. Then we can generate all the rotations by repeatedly applying \\$r\_1\\$ and \\$r\_2\\$. A bit of bruteforce shows that we only need up to 6 applications of \\$r\_1\\$ and \\$r\_2\\$.

Thus we have the following algorithm: given a three-dimensional text \\$s\\$, we apply all possible rotations to \\$s\\$ and check whether any of those matches \\$s\\$ flipped along an axis. The rotations are generated by composing up to six 90 degrees rotations about two fixed axes.

---

```
g=r.foldr(zipWith(:))e
e=[]:e

```

`g` is a 90 degrees rotation of a 2D list (also works on 3D lists, as those can be seen as 2D lists of 1D lists). The `foldr(zipWith(:))e` is simply `transpose` from `Data.List`, but shorter.

---

```
f s=all(r s/=)$foldr($)s<$>mapM(\_->[id,g,map g])[1..6]

```

`f` checks whether its argument `s` is chiral.

* `mapM(\_->[id,g,map g])[1..6]` generates a list of all sequences of length 6 whose elements are any of `id` (the identity transformation, i.e. do nothing), `g` (90 degrees rotation about an axis), `map g` (90 degrees rotations about a different axis).
* given a list `[f1,f2,...,f6]` of transformations, `foldr($)s` computes `f1(f2(...f6(s)...)`, and `(r s/=)` checks whether the result is equal to `s` reversed (i.e. a mirror image of `s`).

So what `f` does is check if any rotation of `s` matches its mirror image, returning `False` if it does and `True` otherwise.
> 6 votes

# Answer
# APL (Dyalog Classic), 28 bytes

```
~⊂∘⌽∊(⊢∪2 0 1∘⍉¨∪⌽∘⍉⍤2¨)⍣≡∘⊂

```

Try it online!
> 2 votes

# Answer
# K (ngn/k), 36 bytes

```
{^*({?x,((++:')'x),(|+:)'x}/,x)?,|x}

```

Try it online!
> 1 votes

---
Tags: code-golf
---


title: Yeah But No But Yeah

text:
# Question
Title: Yeah But No But Yeah
My colleague recently sent me the following piece of JavaScript as a joke:

```
let butScript = (nrOfButs) => {
    for(var i = 0; i < nrOfButs; i++){
        if(i % 3 == 0){
            console.log("Yeah")
        }
        if(i % 2 == 0){
            console.log("But")
        }
        if(i % 3 == 1){
            console.log("No")
        }
    }
}

```

Since the code was written during work hours, it was obviously a huge waste of company resources. To prevent similar occurrences in the future, we must minimize the waste of worked hours. And since it is common knowledge that a shorter program is faster to write, we must golf this code to be as short as possible!

## Input

A single non-negative integer. You must not handle faulty input.

## Output

Your program must produce output identical to that of the script above. You should output one word per line, and the number of words should be consistent with the original script.

It is permissible to include non-newline whitespace characters at the end of each line (but not at the beginning) since they are invisible. One additional newline character is permissible at the very end of the output.

## Examples

```
Input: 0
Output:

Input: 1
Output:
Yeah
But

Input: 2
Output:
Yeah
But
No

Input: 10
Output:
Yeah
But
No
But
Yeah
But
No
Yeah
But
No
But
Yeah

```

# Answer
# Excel, 78 bytes

Assumes input in cell A1, and that Wordwrap formatting is turned on for cell. Use Alt+Enter to add line feeds within the string and note the whitespace. Only handles input up to 3570 due to limit of REPT function (Good luck getting a cell to be that tall, though).

```
=LEFT(REPT("Yeah
But
No
But
Yeah
But
No
",595),A1*9)

```

Reprinting, with periods for whitespace

```
=LEFT(REPT("Yeah
But
No......
But.....
Yeah....
But
No...........
",595),A1*9)

```

How it works: The pattern repeats every 6 numbers:

```
0 = Yeah and But      Yeah + linefeed + But + linefeed
1 = No                No + 6 whitespace + line feed
2 = But               But + 5 whitespace + linefeed
3 = Yeah              Yeah + 4 whitespace + linefeed
4 = But and No        But + linefeed + No + 3 whitespace
5 = Blank             8 whitespace + linefeed

```

Each of these can be expressed with 9 characters, so a string is made of 54 characters (9 * 6), then repeated as large as Excel will allow. Then it takes the left 9 * (number of input) characters as the output.

Linefeed for the "but and no" one is placed after the blank so that the Yeah for #6, #12, (etc) is formatted to the left rather than the right, and so that there is no blank linefeed added every 6th line for that item.
> 49 votes

# Answer
# JavaScript (ES6), ~~59~~ 57 bytes

```
f=n=>n?f(n-1)+[s=n&1?`But
`:'',`Yeah
`+s,s+`No
`][n%3]:''

```

Try it online!

### How?

We use a recursive function which goes from \\$n\\$ to \\$1\\$ rather than from \\$0\\$ to \\$n-1\\$.

As a result, the tests are off by \\$1\\$ compared to the reference code:

* if \\$n\equiv1\pmod 3\\$, output *"Yeah"*
* if \\$n\equiv1\pmod 2\\$, output *"But"*
* if \\$n\equiv2\pmod 3\\$, output *"No"*

This allows us to store the simpler case \\$n\equiv0\pmod 3\\$ as the first entry of our lookup array, where we can define \\$s\\$: a variable holding either `"But\n"` or an empty string.

The two other entries are defined as `"Yeah\n" + s` and `s + "No\n"` respectively.

*Note:* By iterating from \\$n-1\\$ to \\$0\\$, we could define \\$s\\$ in the first entry just as well, but that would cost two extra parentheses.

### Commented

```
f = n =>            // n = input
  n ?               // if n is not equal to 0:
    f(n - 1) +      //   prepend the result of a recursive call with n - 1
    [               //   define our lookup array:
      s = n & 1 ?   //     1st entry: if n is odd:
        `But\n`     //       set s to "But"
      :             //     else:
        '',         //       set s to an empty string
      `Yeah\n` + s, //     2nd entry: "Yeah" followed by s
      s + `No\n`    //     3rd entry: s followed by "No"
    ][n % 3]        //   append the correct entry for this iteration
  :                 // else:
    ''              //   return an empty string and stop recursion

```
> 20 votes

# Answer
# LOLCODE, 257 bytes

```
HAI 1.2
I HAS A B
GIMMEH B
B IS NOW A NUMBR
I HAS A C ITZ 0
IM IN YR L UPPIN YR C TIL BOTH SAEM B AN C
I HAS A D ITZ MOD OF C AN 3
D
WTF?
OMG 0
VISIBLE "Yeah"
OIC
MOD OF C AN 2
WTF?
OMG 0
VISIBLE "But"
OIC
D
WTF?
OMG 1
VISIBLE "No"
OIC
IM OUTTA YR L
KTHXBYE

```

Try it online!
> 19 votes

# Answer
# Whitespace, ~~315~~ ~~304~~ ~~300~~ ~~277~~ 276 bytes

Thanks to *@JoKing* for -11 bytes (reducing the amount of labels used from 8 to 7), and -24 more bytes (changing the general flow of the program and reducing the amount of labels used from 7 to 5 in the process).

```
[S S S N
_Push_0][T  N
T   T   _Read_STDIN_as_integer][N
S S N
_Create_Label_LOOP][S S S N
_Push_0][T  T   T   _Retrieve][N
T   S S N
_If_negative_jump_to_Label_PRINT][S S S N
_Push_0][T  T   T   _Retrieve][S S S T  T   N
_Push_3][T  S T T   _Modulo][S S S T    S N
_Push_2][T  S S T   _Subtract][N
T   T   T   N
_If_negative_jump_to_Label_SKIP_NO][S S T   T   S T T   T   T   S N
_Push_-94_\n][S S S T   T   T   N
_Push_7_o][S S T    T   T   S T S N
_Push_-26_N][N
S S T   N
_Create_Label_SKIP_NO][S S S N
_Push_0][T  T   T   _Retrieve][S S S T  S N
_Push_2][T  S T T   _Modulo][N
T   S S S N
_If_0_jump_to_Label_SKIP_BUT][S S T T   S T T   T   T   S N
_Push_-94_\n][S S S T   T   S S N
_Push_12_t][S S S T T   S T N
_Push_13_u][S S T   T   S S T   T   S N
_Push_-38_B][N
S S S S N
_Create_Label_RETURN_FROM_BUT][S S S N
_Push_0][S N
S _Duplicate_0][S N
S _Duplicate_0][T   T   T   _Retrieve][S S S T  N
_Push_1][T  S S T   _Subtract][T    T   S _Store][T T   T   _Retrieve][S S S T  T   N
_Push_3][T  S T T   _Modulo][N
T   S S T   N
_If_0_jump_to_Label_YEAH][N
S N
N
_Jump_to_Label_LOOP][N
S S S T N
_Create_Label_YEAH][S S T   T   S T T   T   T   S N
_Push_-94_\n][S S S N
_Push_0_h][S S T    T   T   T   N
_Push_-7_a][S S T   T   T   N
_Push_-3_e][S S T   T   T   T   T   N
_Push_-15_Y][N
S N
N
_Jump_to_Label_LOOP][N
S S S N
_Create_Label_PRINT][S S S T    T   S T S S S N
_Push_104][T    S S S _Add][T   N
S S _Print_as_character][N
S N
N
_Jump_to_Label_LOOP]

```

Letters `S` (space), `T` (tab), and `N` (new-line) added as highlighting only.
`[..._some_action]` added as explanation only.

**Try it online** (with raw spaces, tabs and new-lines only).

Whitespace is definitely not the right language for this challenge.. In Whitespace both loops and if-statements are made with labels and jumps to labels, and since they aren't if-elseif-else cases but multiple if-cases, ~~it means I will have to jump back after every if, making it quite long~~ it means I will have to slightly modify the checks to skip over some prints (thanks *@JoKing*).

**Explanation in pseudo-code:**

```
Read STDIN as integer, and store it in the heap
Start LOOP:
  Integer i = retrieve integer from heap
  If(i is negative):
    Call function PRINT
  If(i modulo-3 is NOT 2):
    Jump to Label SKIP_NO
  Push "\noN" to the stack
  Label: SKIP_NO
  If(i modulo-2 is 0):
    Jump to Label SKIP_BUT
  Push "\ntuB" to the stack
  Label: SKIP_BUT
  i = i - 1
  Replace i in the heap with this updated value
  If(i modulo-3 is 0):
    Call function YEAH
  Go to next iteration of LOOP

function YEAH:
  Push "\nhaeY" to the stack
  Go to next iteration of LOOP

function PRINT:
  Print top of the stack as character to STDOUT
  Go to next iteration of LOOP (which will enter the if and then
                                comes back to this PRINT again)

```

**Additional explanation:**

In general, it loops from the input down to 0, pushing a newline and the word reversed (so in the order "\noN", "\ntuB", "\nhaeY" instead of "Yeah\n", "But\n", "No\n"). And after the input has looped down to 0 and all the characters are on the stack, it will print those characters in reverse (so the correct output order).

More in depth however: Although we need to print words in the range `(input, 0]`, it will loop in the range `[input, 0)` instead. Because of this, we can use the check `if(i%3 == 2)` for "\noN" (or actually, `if(i%3 != 2)` skip the pushing of "\noN"), and we use the check `if(i%2 != 1)` for "\ntuB" (or actually, `if(i%2 == 0)` skip the pushing of "\ntuB"). Only after these two checks we decrease the iteration `i` by 1. And then do the check `if(i%3 == 0)` to push "\nhaeY", similar as in the JS example code in the challenge description. Skipping with if-not checks instead of going to a label and return from the label with if-checks saved 23 bytes.

Also, in Whitespace character values are stored in the stack as their unicode values (i.e. `10` for new-lines, `65` for 'A', `97` for 'a', etc.). Since I already need to loop over the stack to print the characters, I am also able to use my Whitespace tip to lower the byte-count by adding a constant to the number values, before printing them as characters.
This constant is `104` in this case, which is generated with this Java program that I've also used to golf another Whitespace answer of mine before. That's also the reason why this part of the code:

```
[S S T  T   S T T   T   T   S N
_Push_-94_\n][S S S T   T   T   N
_Push_7_o][S S T    T   T   S T S N
_Push_-26_N]

```

has the values `-94` for the newline, `7` for the 'o', and `-26` for the 'N'. Because adding the constant of `104` will correctly give our unicode values `10`, `111`, and `78` for these characters respectively.
> 13 votes

# Answer
# Python 3, ~~85~~ 82 bytes

```
def f(n):
 for i in range(n):yield from['Yeah'][i%3:]+['But'][i%2:]+['No'][i%3^1:]

```

Try it online!

---

# Python 3, ~~79~~ 76 bytes

Port of Keeta's Excel answer.

```
lambda n:(f"""Yeah
But
No
But
Yeah
But
No{'':11}
"""*n)[:9*n]

```

Try it online!
> 12 votes

# Answer
# Perl 6, ~~63~~ 50 bytes

```
{<<"Yeah But"No But Yeah"But No">>[^$_ X%6].words}

```

Try it online!

Anonymous code block that takes a number and returns a list of lines

### Explanation:

```
{                                                }   # Anonymous code block
 <<"Yeah But"No But Yeah"But No">>  # Create the list of strings:
                                     # Yeah But
                                     # No
                                     # But
                                     # Yeah
                                     # But No
                                  [       ]  # Index into this list
                                   ^$_  # The range from 0 to n-1
                                       X%6  # All modulo 6
                                           .words  # Convert the list to a string
                                                   # Which joins by spaces
                                                   # And split by whitespace

```
> 11 votes

# Answer
# C (gcc), 75 bytes

```
f(o,_){for(_=0;o-_;_++%3-1||puts("No"))_%3||puts("Yeah"),1&_||puts("But");}

```

Try it online!

---

# C (gcc), 60 + 11 = 71 bytes (using `-D$=||puts(`)

```
f(o,_){for(_=0;o-_;_++%3-1 $"No"))_%3 $"Yeah"),1&_ $"But");}

```

Try it online!
> 8 votes

# Answer
# 05AB1E (legacy), ~~27~~ ~~25~~ 24 bytes

Saved 1 byte thanks to *Kevin Cruijssen*.

```
F”¥æ€³€¸”#N3ÖNÈN3%‚‚˜Ï`»

```

Try it online!

**Explanation**

```
F                          # for N in [0 ... input] do:
 ”¥æ€³€¸”#                 # push ['Yeah', 'But', 'No']
          N3Ö              # push N % 3 == 0
             NÈ            # push N % 2 == 0
               N3%         # push N % 3
                  ‚‚˜      # add the 3 numbers to a list
                     Ï     # keep only the strings whose corresponding value
                           # in the int list is true (1)
                      `»   # push strings separately to stack and join stack on newlines

```
> 8 votes

# Answer
# Python 2, 73 bytes

```
lambda n:'\n'.join((["Yeah\nBut","No","But","Yeah","But\nNo"]*n)[:n-n/6])

```

Try it online!
> 7 votes

# Answer
# Python 2, ~~97~~ ~~95~~ ~~92~~ ~~90~~ ~~83~~ 81 bytes

```
lambda n:[w for i in range(n)for w in'Yeah','But','No'if('N'in w)==i%(3-(w<'N'))]

```

Try it online!

-2 bytes, thanks to ovs

---

# Python 3, ~~92~~ ~~90~~ ~~85~~ 83 bytes

```
lambda n:[w for i in range(n)for w in['Yeah','But','No']if('N'in w)==i%(3-(w<'N'))]

```

Try it online!

-4 bytes, thanks to ovs

-4 bytes, thanks to Jo King
> 6 votes

# Answer
# Canvas, 27 bytes

```
｛╷⌐３％‽YeahＰ｝２％‽ButＰ｝３％╷‽NoＰ

```

Try it here!
> 6 votes

# Answer
# Groovy (function), 79 bytes

Since initially submitting my answer, I've looked through some historic discussions here about what constitutes a suitable answer. Since it seems commonly accepted to provide just a method in Java (including return type and parameter declarations), here is a shorter, Groovy, method which has the method return value be the answer. Use of `def` means that the return type is inferred.

```
def a(int n){n?a(--n)+(n%3?'':'Yeah\n')+(n%2?'':'But\n')+(n%3==1?'No\n':''):''}

```

Unlike the original answer below, which loops from 0 up to n-1, this one calls itself from n down to 1, but decrements the input for the rest of the line in the recursive call.

Try it online!

# Groovy (program), 87 bytes

Groovy scripts don't require certain common imports, so this can be a program printing the answer to Java's STDOUT without having to declare `System.out.` before `print`. It also provides some common utility methods, such as this `toLong()` which allows us to parse the input argument reasonably consicely.

Essentially the Java 10 answer, but leveraging Groovy's shorter loop syntax and ability to evaluate truthy statements.

```
args[0].toLong().times{print((it%3?'':'Yeah\n')+(it%2?'':'But\n')+(it%3==1?'No\n':''))}

```

Try it online!
> 6 votes

# Answer
# Java 10, ~~100~~ 99 bytes

```
n->{for(int i=0;i<n;)System.out.print((i%3<1?"Yeah\n":"")+(i%2<1?"But\n":"")+(++i%3>1?"No\n":""));}

```

-1 byte thanks to *@OlivierGrégoire*.

Try it online.

**Explanation:**

```
n->{                   // Method with integer parameter and no return-type
  for(int i=0;i<n;)    //  Loop `i` in the range [0, `n`)
    System.out.print(  //   Print to STDOUT:
      (i%3<1?          //    If `i` is divisible by 3:
        "Yeah\n"       //     Print "Yeah" with newline
      :"")+(i%2<1?     //    If `i` is even:
        "But\n"        //     Print "But" with newline
      :"")+(++i%3>1?   //    If `i` modulo-3 is 1:
        "No\n"         //     Print "No" with newline
      :                //    If none of the above three if's applied to the current `i`:
       ""));}          //     Print nothing for the current `i`

```
> 5 votes

# Answer
# Retina 0.8.2, 45 bytes

```
.+
$*
1
$`Yeah¶$`But¶$`11No¶
+`11B
B
111

A`1

```

Try it online! Explanation:

```
.+
$*

```

Convert the input to unary.

```
1
$`Yeah¶$`But¶$`11No¶

```

For each integer `0...n-1`, generate three lines of text, one for each word, each with `i` `1`s before it, except for `No`, which has two extra `1`s so that we calculate `(i+2)%3==0` which is equivalent to `i%3==1`.

```
+`11B
B

```

Remove pairs of `1`s before `B`s.

```
111

```

Remove `1`s in groups of three everywhere else.

```
A`1

```

Delete all lines that still have a `1`.
> 5 votes

# Answer
# Powershell, ~~75~~ ~~74~~ ~~72~~ ~~67~~ 66 bytes

*-1 byte thanks TessellatingHeckler*

```
param($n)(" Yeah
But No But Yeah But
No "*$n-split' ')[1..$n]-ne''

```

Test script and explanation:

```
$f = {

param($n)(" Yeah
But No But Yeah But
No "*$n-split' ')[1..$n]-ne''

# 1. repeat the string $n times
# 2. split by space
# 3. get elements from 1 to $n
# some elements are multiline strings, some elements are $null:
# ($null,"Yeah`nBut","But","No","But","Yeah","But`nNo",$null,...)
# 4. remove $null elements from result array

}

# Output results
@(
    0,1,2,10
) | % {
    &$f $_
    "======"
}

# Advanced test
@(
    ,(0,'')
    ,(1,'Yeah But')
    ,(2,'Yeah But No')
    ,(3,'Yeah But No But')
    ,(4,'Yeah But No But Yeah')
    ,(5,'Yeah But No But Yeah But No')
    ,(6,'Yeah But No But Yeah But No')
    ,(7,'Yeah But No But Yeah But No Yeah But')
    ,(8,'Yeah But No But Yeah But No Yeah But No')
    ,(9,'Yeah But No But Yeah But No Yeah But No But')
    ,(10,'Yeah But No But Yeah But No Yeah But No But Yeah')
    ,(20,'Yeah But No But Yeah But No Yeah But No But Yeah But No Yeah But No But Yeah But No Yeah But No')
) | % {
    $n,$e = $_
    $r = &$f $n
    $r = $r-split"`n"       # simplify test string
    "$($e-eq$r): $n : $r"
}

```

Output:

```
======
Yeah
But
======
Yeah
But
No
======
Yeah
But
No
But
Yeah
But
No
Yeah
But
No
But
Yeah
======
True: 0 :
True: 1 : Yeah But
True: 2 : Yeah But No
True: 3 : Yeah But No But
True: 4 : Yeah But No But Yeah
True: 5 : Yeah But No But Yeah But No
True: 6 : Yeah But No But Yeah But No
True: 7 : Yeah But No But Yeah But No Yeah But
True: 8 : Yeah But No But Yeah But No Yeah But No
True: 9 : Yeah But No But Yeah But No Yeah But No But
True: 10 : Yeah But No But Yeah But No Yeah But No But Yeah
True: 20 : Yeah But No But Yeah But No Yeah But No But Yeah But No Yeah But No But Yeah But No Yeah But No

```

Straightforward script, 72 bytes:

```
$args|?{$_}|%{0..--$_|%{@('Yeah')[$_%3]
@('But')[$_%2]
@{1='No'}[$_%3]}}

```
> 5 votes

# Answer
# C# (Visual C# Interactive Compiler), ~~105~~ ~~99~~ ~~94~~ ~~96~~ 89bytes

```
i=>{for(int x=0;x<i;)Write((x%3<1?"Yeah\n":"")+(x%2<1?"But\n":"")+(x++%3==1?"No\n":""));}

```

Try it online!
> 4 votes

# Answer
# Haskell, 71 bytes

```
f n=[1..n]>>=(3?1)"Yeah"<>(2?1)"But"<>(3?2)"No"
(a?b)c n=[c|n`mod`a==b]

```

Try it online!

### Explanation

Pretty simple, saved two bytes by using `[1..n]` instead of `[0..n-1]` and adjusted the remainders: The operator `(?)` tests takes four arguments, returning an empty list or the provided string as a singleton if the result is correct.

By currying the fourth argument of `(?)` we can make use of `(<>)` to concatenate the results of each function, ie.:

```
(3?1)"Yeah" <> (2?1)"But" <> (3?2)"No" ≡ \i-> (3?1)"Yeah" i ++ (2?1)"But" i ++ (3?2)"No" i

```
> 4 votes

# Answer
# Pip, ~~37~~ ~~35~~ 33 bytes

```
"But
Yeah
No
"<>5@:^[t2io02x]@<a

```

(Note the space after `But`.) Takes input as a command-line argument. Try it online!

### Explanation

*This explanation is for the previous version--see below for changelog*

Inspired by Jo King's Perl 6 answer. We construct this list:

```
[
 "Yeah
 But
 ";
 "No
 ";
 "But
 ";
 "Yeah
 ";
 "But
 No
 ";
 ""
]

```

and output the first `a` elements of it using cyclic indexing.

```
[t2io02x]R,3["But""Yeah""No"].n@<:a
                                     i is 0; o is 1; t is 10; x is ""; n is newline;
                                     a is 1st cmdline arg (implicit)
[       ]                            Construct this list of scalars:
 t                                    10
  2                                   2
   i                                  0
    o                                 1
     02                               02
       x                              <empty string>
         R                           Treating each of these as a string, we're going to
                                     replace:
          ,3                          0, 1, and 2 (respectively)
                                     with the corresponding values from this list:
            ["But""Yeah""No"].n       These strings, each with a newline appended
                                     We now have constructed the list shown above
                               @<:a  Take the first a elements from this list, with
                                     cyclical indexing (the : is for parsing reasons)
                                     Concatenate them together and print (implicit)

```

**Update:** I realized that I don't need to use replace to change 0/1/2 into strings--I can use those numbers to index into a list directly. To do this, we have to make sure the multi-digit numbers are split into lists of their digits (otherwise, we'll be selecting index 10 instead of indexes 1 and 0). Fortunately, using an arbitrarily nested list as an index in Pip works as expected, giving a (nested) list of results. For input of 3, we get this data progression (where `_` represents a newline):

```
"But _Yeah_No_"<>5                       ["But _"; "Yeah_"; "No_"]
                     [t2io02x]           [10; 2; 0; 1; 02; ""]
                              @<a        [10; 2; 0]
                    ^                    [[1; 0]; [2]; [0]]
                  @:                     [["Yeah_"; "But _"]; ["No_"]; ["But _"]]

```

As before, the final result is concatenated together and autoprinted.
> 4 votes

# Answer
# Attache, 48 bytes

```
Flat##{Mask[_%3'2'3=0'0'1,$Yeah'$But'$No]}=>Iota

```

Try it online!

## Explanation

```
Flat##{Mask[_%3'2'3=0'0'1,$Yeah'$But'$No]}=>Iota   input: an integer
      {                                  }=>Iota   over each number from 0 to that integer exclusive
       Mask[             ,$Yeah'$But'$No]          select values from that array according to:
            _%3'2'3                                    whether or not the input mod 3, 2, 3
                   =0'0'1                              is 0, 0, 1
Flat##                                             flatten the intermediate results

```
> 4 votes

# Answer
# C (gcc), ~~77~~ ~~71~~ ~~74~~ ~~72~~ 69 bytes

There's already a better **C** answer here but this one is recursive and it took me some time to get straight so I'm posting it.

Down to 69 bytes thanks to both @ceilingcat and @JonathanFrech

(I never think to use n-~-i in place of n-i+1)

```
i;f(n){i=n&&n-i>=~n/6&&f(n,i++,puts(i%7%4?i%7%2?"But":"No":"Yeah"));}

```

Try it online!
> 4 votes

# Answer
# sed -E, ~~179~~ 150 bytes

```
/^0/!s:$:g:
:l;y:abcdefg:bcdefga:
/[ae]/iYeah
/[bdf]/iBut
/[cg]/iNo
s:.$:-&:;:s;s:0-:-9:;ts;h
y:123456789:012345678:;G
s:.*(.)-.*\n(.*).-:\2\1:;tl;c\

```

The hardest part was not to construct the list but to actually parse the decimal number.

2 bytes may be saved if the newline at the end is not required: `c\``d`.

Still requires optimization.

Try it online.

### Explanation

```
/^0/!                            | if the input number doesn`t begin with a '0'…
     s:$:g:                      | …then append a 'g' to it and proceed
                                 |
:l;                              | loop label 'l':
   y:abcdefg:bcdefga:            | shift all occurences of [abcdef] 1 letter forward, and all 'g'-s to 'a'-s
                                 |
/[ae]/                           | if there`s an 'a' or 'e' in the input…
      iYeah                      | …output 'Yeah'
                                 |
/[bdf]/                          | if there`s a 'b' or 'd' or 'f' in the input…
       iBut                      | …output 'But'
                                 |
/[cg]/                           | if there`s a 'c' or 'g' in the input…
      iNo                        | …output 'No'
                                 |
s:.$:-&:;                        | insert '-' before the last character
         :s;                     | loop label 's':
            s:0-:-9:;            | transform the next consecutive '0' in the end of the number to '9', if any
                     ts;         | loop to 's' if more consecutive zeroes are available
                        h        | copy the result to the temporary buffer
                                 |
y:123456789:012345678:;          | decrement all digits except '0' (N.B.: digits, not numbers)
                       G         | append the temporary buffer to the result
                                 |
s:.*(.)-.*\n(.*).-:\2\1:;        | cut and replace the digit left to the last consecutive 0 in the original
                                 | number pasted from the temporary buffer, then discard all other digits decremented
                         tl;     | …then loop to 'l' if the number is ≥0
                            c\   | insert a carriage return and exit

```
> 3 votes

# Answer
# Ruby, 69 ~~72~~ ~~74~~ Bytes

```
->y{puts *(1..y).map{|i|[i%3==1&&:Yeah,i%2>0&&:But,i%3>1&&:No]-[!0]}}

```

Very straight-forward answer, checking for a shorter, recursive method right now.

Saved two bytes thanks to @BWO :)

Saved another three bytes by using symbols instead of strings
> 3 votes

# Answer
# Python 3, 93 bytes

```
[print("Yeah\n"*(i%3<1)+"But\n"*(i%2<1)+"No\n"*(i%3==1),end="")for i in range(int(input()))]

```

This isn't exactly the best solution but it's my take on it.

Try it online!
> 3 votes

# Answer
## R, 65 bytes

```
cat(c("yeah","but","no")[c(3,1:3,2,1,2)][1:scan()%%7+1],sep="\n")

```

Due to the fact that we are replicating a slightly flawed program (it misses out every fourth "but" — it should have used `%4 == 1` and `%4 == 3` rather than `%3` conditions), we have to use an awkward call to `c` and work in base seven. Still, it's shorter than LOLCODE...

(I was hoping that (3,1,2,3,2,1,2) or a similar permutation might appear in the `lh` dataset somewhere but it doesn't look like it)
> 3 votes

# Answer
# Python 2, ~~93~~ ~~92~~ 83 bytes

```
lambda i:''.join('Yeah\n'*(x%3<1)+'But\n'*(x%2<1)+'No\n'*(x%3==1)for x in range(i))

```

Try it online!

A massive 9 bytes saved with thanks to @Jonathan Frech
> 2 votes

# Answer
# Clean, 116 bytes

```
import StdEnv,Data.List
r=cycle
$n=[e\\_<-[1..n]&a<-r["Yeah","",""]&b<-r["But",""]&c<-r["","No",""],e<-[a,b,c]|e>""]

```

Try it online!
> 2 votes

# Answer
# VBA (Excel), ~~105, 101,~~ 99 Bytes

Edit: -4 bytes from Keeta! Thanks!

Edit 2: -2 bytes from Chronocidal! Woot! (Realized that test cases only worked for 10. Fixed now)

**Yeah, Excel beat VBA this time. Whatever.** (We're coming for you)

```
d=vbCr:For i=1To[a1]:a=i Mod 3:?IIf(a=1,"Yeah"+d,"")IIf(i/2=i\2,"","But"+d)IIf(a=2,"No"+d,"");:Next

```

^This is pasted into the Immediate window and outputs to the debug window

Ungolfed

```
d = vbCr
'For 1 to the value in A1 (using 0 gave extra values, and VBA skips the for loop if 0)
For i = 1 To [a1]    'aka: Range("A1").value
    a = i mod 3
    '? is the same as Print (Debug.Print when not in the Immediate Window)
    Print IIf(a = 1, "Yeah" + d, "") _ '<-- Just a line continuation
          'Keeta taught me that the \ operator is division with truncation,
          '     so if they are equal then there is no remainder!
          IIf(i / 2 = i \ 2, "", "But" + d) _
          IIf(a = 2, "No" + d, "");
    'Print usually prints a newline, but it still outputs if the string is blank...
    '   So we append a newline -if true- and use a semi-colon to kill the newline
Next

```
> 2 votes

# Answer
## F#, 108 106 bytes

```
let v p=seq{for i=1 to p do
 if i%3=1 then yield"Yeah"
 if i%2=1 then yield"But"
 if i%3=2 then yield"No"}

```

Try it online!

-2 bytes changing from `i=0 to p-1` to `i=1 to p` and adjusting modulos. Apart from that, pretty straight-forward.
> 2 votes

# Answer
# PHP, ~~65~~ 68 bytes

```
while($i<$argn)echo["Yeah
"][$i%3],["But
"][$i%2],["No
"][~-$i++%3];

```

Run as pipe with `-nR` or try it online.
> 2 votes

# Answer
# Jelly, 22 bytes

```
5Rż7FṚṁị“'⁴\ÆẓNƇ»ḲŒP¤Ẏ

```

A monadic Link yielding a list of lines (which seems to have been allowed in comments)

**Try it online!** (the footer calls the Link using `Ç` and joins with newlines using `Y` since implicit printing in Jelly smashes everything together if it can)

### How?

First note that we have a period of \\$2\times3=6\\$ due to the modulo definition.

Now note that the first six values are:

```
["Yeah", "But"]
["No"]
["But"]
["Yeah"]
["But", "No"]
[]

```

So the resulting list of lines should be these values repeated (or truncated) to length `n` concatenated together.

Now note that the power-set of `"Yeah", "But", "No"` is:

```
[]
["Yeah"]
["But"]
["No"]
["Yeah", "But"]
["Yeah", "No"]
["But", "No"]
["Yeah", "But", "No"]

```

So each period is these 1-indexed values of the power-set of `"Yeah", "But", "No"`:

```
5, 4, 3, 2, 7, 1

```

The code makes this list, moulds it to length `n`, indexes into the power-set, and then removes the inner lists (which also removes the empty strings, since strings are lists in Jelly)...

```
5Rż7FṚṁị“'⁴\ÆẓNƇ»ḲŒP¤Ẏ - Link: integer, n   e.g. 10
5                      - literal five            5
 R                     - range                   [1,2,3,4,5]
   7                   - literal seven           7
  ż                    - zip together            [[1,7],[2],[3],[4],[5]]
    F                  - flatten                 [1,7,2,3,4,5]
     Ṛ                 - reverse                 [5,4,3,2,7,1]
      ṁ                - mould like (n)          [5,4,3,2,7,1,5,4,3,2]
                    ¤  - nilad followed by link(s) as a nilad:
        “'⁴\ÆẓNƇ»      -   compressed string     "Yeah But No"
                 Ḳ     -   split at spaces       ["Yeah","But","No"]
                  ŒP   -   power-set             [[],["Yeah"],["But"],["No"],["Yeah","But"],["Yeah","No"],["But","No"],["Yeah","But","No"]]
       ị               - index into              [["Yeah","But"],["No"],["But"],["Yeah"],["But","No"],[],["Yeah","But"],["No"],["But"],["Yeah"]]
                     Ẏ - tighten                 ["Yeah","But","No","But","Yeah","But","No","Yeah","But","No","But","Yeah"]

```
> 2 votes

# Answer
# Python 3, ~~154 153 85~~ 90 bytes

```
n=10
print(''.join(('Yeah\n'*(i%3==0)+'But\n'*(i%2==0)+'No\n'*(i%3==1))for i in range(n)))

```

Try it online!
> 2 votes

# Answer
# Vim, 67 bytes

```
<C-a>A@m<Return>Yeah_But<Return>No<Return>But<Return>Yeah<Return>But_No<Esc>qm5kYGpqD@"Dgg6dj:%s,_,<C-v><Return>,|%s,\n$<Return>

```

Assuming the file contains only the input and the cursor is at the beginning.

Some explanations:

```
<C-a>                  Increment the input, because running 0@m do not work as expected
A@m<Return>            Write @m after the input
Yeah_But<Return>
No<Return>
But<Return>
Yeah<Return>
But_No<Esc>
qm5kYGpq               Record macro m
D                      Cut the text pasted just before, into "
@"                     Execute the macro "
D                      Remove the last line (because I incremented the input)
gg6dj                  Remove the 6 first lines
:%s,_,<C-v><Return>,|%s,\n$<Return>       Replace _ by a newline and remove empty lines

```
> 1 votes

# Answer
# MBASIC, ~~127~~ ~~118~~ 116 bytes

First time, hope I'm doing this right.

```
1 INPUT X:FOR I=0 TO X-1:IF I MOD 3=0 THEN PRINT"Yeah
2 IF I MOD 2=0 THEN PRINT"But
3 IF I MOD 3=1 THEN PRINT"No
4 NEXT

RUN
? 10
Yeah
But
No
But
Yeah
But
No
Yeah
But
No
But
Yeah

```
> 1 votes

# Answer
# JavaScript (Node.js), 92 bytes

```
f=(n,i=0,l=console.log)=>{for(;i<n;i++){0==i%3&&l('Yeah');0==i%2&&l('But');1==i%3&&l('No')}}

```

Try it online!
> 1 votes

# Answer
# Julia 1.0, 80 bytes

```
f(i,p=println)=(i%3<1&&p("Yeah");i%2<1&&p("But");i%3==1&&p("No"))
g(n)=f.(0:n-1)

```

Called as `g(2)` for example.

Try it online!
> 1 votes

# Answer
# ORK, ~~1065~~ ~~1188~~ 1185 bytes

*+123 bytes to account for an input of 0.*

*-3 bytes because using "my" to refer to an object's variable is redundant inside the object itself.*

```
There is such a thing as a y
A y can Y a number
A y can W a number
A y has a l which is a number

When a y is to Y a number:
I am to W the number
I have a mathematician called M
M's first operand is the number
M's second operand is 1
M is to add
The number is M's result
M's first operand is the number
M's second operand is l
M is to compare
If M says it's less then I am to loop

When a y is to W a number:
I have a mathematician called M
M's first operand is the number
M's second operand is 3
M is to modulo
M's first operand is M's result
M's second operand is 1
M is to compare
I have a mathematician called N
N's first operand is the number
N's second operand is 2
N is to modulo
N's first operand is N's result
N's second operand is 1
N is to compare
I have a scribe called W
If M says it's less then W is to write "Yeah\n"
If N says it's less then W is to write "But\n"
If M says it's equal then W is to write "No\n"

When this program starts:
I have a inputter called I
I have a number called n
I is to read n
I have a y called Y
Y's l is n
I have a mathematician called M
M's first operand is n
M's second operand is 0
M is to compare
If M says it's greater then Y is to Y 0

```

Try it online!

**O**bjects **R** **K**ool. They are kool indeed. But looping is hell. It's nice that the mathematicians' results are reusable, though.
> 1 votes

# Answer
# Stax, 21 bytes

```
ë╗ô┤z‼╔@qgx╕π♣►Ü~Y↓├Φ

```

Run and debug it
> 1 votes

# Answer
# Python 3, 89

```
f=lambda n:f(n-1)+'Yeah\n'*((n-1)%3<1)+'But\n'*((n-1)%2<1)+'No\n'*((n-1)%3==1)if n else""

```
> 1 votes

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


# Question
Title: (Javascript) itertools.groupBy, e.g. [0,0,1,1,0] -> [[0,0],[1,1],[0]]
(language-specific challenge)

## Specification:

Language: ECMAScript, any version\[1\]

Challenge: Somewhat like python's itertools.groupBy: Your function `Array.group(f)` should take as input an "equivalence function" `f` whose output defines our notion of an "equivalence key" for array elements (like a sort key). The return value of `.group(f)` should be an array of arrays in the same order, split whenever the value of the keyfunc parameter changes (in the `===` sense).

```
Object.defineProperties(Array.prototype, {
    group: {
        value: function(f) {/*
            CODE GOES HERE
        */}
    }
});

```

## Examples / test cases:

```
> ['a','c','E','G','n'].group(x => x==x.toUpperCase())
[['a','c'], ['E','G'], ['n']]

> [1,1,'1'].group(x=>x)
[[1,1],['1']]

> [3,1,'1',10,5,5].group(x=>x+2)
[[3], [1], ['1'], [10], [5,5]]

> [{a:1,b:2,c:3}, {b:2,a:1,c:0}, {c:5}].group(x => JSON.stringify([x.a, x.b]))
[[{a:1,b:2,c:3},{b:2,a:1,c:0}], [{c:5}]]

> [].group(x=>x)
[]

```

## Scoring criteria:

score = # of characters that replace comment above (lower is better), with easements that:

1. whitespace and statement-separating semicolons don't count towards total\[2\]
2. variable names and keywords each count as exactly 1 characters towards total per use\[3\]; this includes builtins, so `Array.map.apply` would be 5 'characters' (however, builtins count their full length as tiebreakers)
3. -5 bonus points if `f` being undefined has same result as the identity function `x=>x`
4. you may modify the construct `function(f) {...}` for recursion/combinator purposes while keeping it as a `function` respecting rule #5, but must subtract from your score the extra characters incurred (i.e. imagine the scoring began earlier)

## Disallowances:

5. no side-effects which affect anything other than your code (such as modifying `this`, `window`, the prototype, etc.); as a corollary, all definitions must stay local to the `.group` function (e.g. `x=5` would be disallowed, but `var x=5` is fine)

minor notes:

\[1\] draft specs fine if in any major browser, proprietary extensions fine if in 2+ major browsers;
\[2\] as long as you don't try to compile a few megabytes-long whitespace ;-)
\[3\] as long as reflection is not used to abuse code-in-variable-names ;-)

---

## Errata:

Answer may do anything reasonable with regards to sparse arrays. e.g. `arr=[1,1]; arr[4]=1; arr` -\> `[1, 1, empty × 2, 1]`. Possibilities include ignoring them (like `.map` and friends do), or treating them as `undefined` (like an incremental for-loop would), or anything reasonable. For example `arr.group(x=>x)` might return `[[1,1],[undefined,undefined],[1]]`, or `[[1,1,1]]`, or even more dubious things like `[[1,1],null,[1]]` if it makes sense. You may also assume sparse arrays do not exist.

edit: #2 now applies to keywords.

You may find the following snippet useful to estimate score (the rules supercede this snippet though):

```
var code = `......`;
console.log('score estimate:', code.replace(/\w+/g,'X').replace(/[\s;]/g,'').replace(/X(?=X)/g,'X ').length, '-5?');

```

# Answer
# JavaScript, 47 points (53 tiebreaker)

```
Array.prototype.group = function(f){
    const r = []
    let k = r
    for(const i of this)
        k !== (k = f ? f(i) : i) ? r.push(a = [i]) : a.push(i)
    return r
}

```
* Body: `+52`
* Identity comparison: `-5`
* Full-length built-ins: `+6`

### Try it:

```
Array.prototype.group = function(f){
    const r = []
    const k = r
    for(const i of this)
        k!==(k=f?f(i):i)?r.push(a=[i]):a.push(i)
    return r
}

console.log(
    ['a','c','E','G','n'].group(x => x==x.toUpperCase()),
    [1,1,'1'].group(x=>x),
    [3,1,'1',10,5,5].group(x=>x+2),
    [{a:1,b:2,c:3}, {b:2,a:1,c:0}, {c:5}].group(x => JSON.stringify([x.a, x.b])),
    [].group(x=>x)
)
```

---

# JavaScript, 48 points (56 tiebreaker)

More traditional code golf-y solution.

```
Array.prototype.group = function(f,r=[],k=r){
    this.map(i=>k!==(k=f?f(i):i)?r.push(a=[i]):a.push(i))
    return r
}

```
* Signature: `+9`
* Body: `+44`
* Identity comparison: `-5`
* Full-length built-ins: `+8`

### Try it:

```
Array.prototype.group = function(f,r=[],k=r){
    this.map(i=>k!==(k=f?f(i):i)?r.push(a=[i]):a.push(i))
    return r
}

console.log(
    ['a','c','E','G','n'].group(x => x==x.toUpperCase()),
    [1,1,'1'].group(x=>x),
    [3,1,'1',10,5,5].group(x=>x+2),
    [{a:1,b:2,c:3}, {b:2,a:1,c:0}, {c:5}].group(x => JSON.stringify([x.a, x.b])),
    [].group(x=>x)
)
```
> 2 votes

# Answer
# JavaScript (Node.js), 90 bytes, 82 points

```
return((o,p,O)=>this.map(v=>(O=o,(o=f?f(v):v)===O?p.push(v):p=[v])))(0/0).filter(x=>x.pop)

```

Try it online!

> 90 - 3 (`this` counts as 1 bytes) - 5 (default `f` as `x=>x`) = 82 points
> 1 votes

---
Tags: code-golf, javascript
---


title: Partially-Observable Connect-4

text:
# Question
Title: Partially-Observable Connect-4
# The Game

You will be playing an (almost) standard game of Connect-4. Unfortunately, it is a correspondence game and someone has placed black tape on every second row starting from the bottom, so that you cannot see any of your opponent's moves within these rows.

Any moves within already-full columns will count as passing your turn, and if a game runs for longer than `6 * 7` turns it will be adjudicated as a draw.

# Challenge Specification

Your program should be implemented as a Python 3 function. The first argument is a 'view' of the board, representing the known board state as a 2D list of rows from bottom to top where `1` is a move by the first player, `2` a move by the second player, and `0` an empty position or a hidden move by your opponent.

The second argument is a turn number indexed from `0`, and its parity tells you which player you are.

The final argument is an arbitrary state, initialized to `None` at the beginning of each game, which you can use to preserve state between turns.

You should return a 2-tuple of the column index you wish to play, and the new state to be returned to you next turn.

# Scoring

A win counts as `+1`, a draw as `0`, and a loss as `-1`. Your goal is to achieve the highest average score in a round-robin tournament. I will try to run as many matches as required to identify a clear winner.

# Rules

Any competitor should have at most one competing bot at any one time, but it is OK to update your entry if you make improvements. Please try to limit your bot to ~1 second of thinking time per turn.

# Testing

Here is the source code for the controller, together with a few non-competing example bots for reference:

```
import itertools
import random

def get_strides(board, i, j):
    yield ((i, k) for k in range(j + 1, 7))
    yield ((i, k) for k in range(j - 1, -1, -1))
    yield ((k, j) for k in range(i + 1, 6))
    yield ((k, j) for k in range(i - 1, -1, -1))
    directions = [(1, 1), (-1, -1), (1, -1), (-1, 1)]
    def diag(di, dj):
        i1 = i
        j1 = j
        while True:
            i1 += di
            if i1 < 0 or i1 >= 6:
                break
            j1 += dj
            if j1 < 0 or j1 >= 7:
                break
            yield (i1, j1)
    for d in directions:
        yield diag(*d)

DRAWN = 0
LOST = 1
WON = 2
UNDECIDED = 3

def get_outcome(board, i, j):
    if all(board[-1]):
        return DRAWN
    player = board[i][j]
    strides = get_strides(board, i, j)
    for _ in range(4):
        s0 = next(strides)
        s1 = next(strides)
        n = 1
        for s in (s0, s1):
            for i1, j1 in s:
                if board[i1][j1] == player:
                    n += 1
                    if n >= 4:
                        return WON
                else:
                    break
    return UNDECIDED

def apply_move(board, player, move):
    for i, row in enumerate(board):
        if board[i][move] == 0:
            board[i][move] = player
            outcome = get_outcome(board, i, move)
            return outcome
    if all(board[-1]):
        return DRAWN
    return UNDECIDED

def get_view(board, player):
    view = [list(row) for row in board]
    for i, row in enumerate(view):
        if i % 2:
            continue
        for j, x in enumerate(row):
            if x == 3 - player:
                row[j] = 0
    return view

def run_game(player1, player2):
    players = {1 : player1, 2 : player2}
    board = [[0] * 7 for _ in range(6)]
    states = {1 : None, 2 : None}
    for turn in range(6 * 7):
        p = (turn % 2) + 1
        player = players[p]
        view = get_view(board, p)
        move, state = player(view, turn, states[p])
        outcome = apply_move(board, p, move)
        if outcome == DRAWN:
            return DRAWN
        elif outcome == WON:
            return p
        else:
            states[p] = state
    return DRAWN

def get_score(counts):
    return (counts[WON] - counts[LOST]) / float(sum(counts))

def run_tournament(players, rounds=10000):
    counts = [[0] * 3 for _ in players]
    for r in range(rounds):
        for i, player1 in enumerate(players):
            for j, player2 in enumerate(players):
                if i == j:
                    continue
                outcome = run_game(player1, player2)
                if outcome == DRAWN:
                    for k in i, j:
                        counts[k][DRAWN] += 1
                else:
                    if outcome == 1:
                        w, l = i, j
                    else:
                        w, l = j, i
                    counts[w][WON] += 1
                    counts[l][LOST] += 1
        ranks = sorted(range(len(players)), key = lambda i: get_score(counts[i]), reverse=True)
        print("Round %d of %d\n" % (r + 1, rounds))
        rows = [("Name", "Draws", "Losses", "Wins", "Score")]
        for i in ranks:
            name = players[i].__name__
            score = get_score(counts[i])
            rows.append([name + ":"] + [str(n) for n in counts[i]] + ["%6.3f" % score])
        lengths = [max(len(s) for s in col) + 1 for col in zip(*rows)]
        for i, row in enumerate(rows):
            padding = ((n - len(s)) * ' ' for s, n in zip(row, lengths))
            print(''.join(s + p for s, p in zip(row, padding)))
            if i == 0:
                print()
        print()

def random_player(view, turn, state):
    return random.randrange(0, 7), state

def constant_player(view, turn, state):
    return 0, state

def better_random_player(view, turn, state):
    while True:
        j = random.randrange(0, 7)
        if view[-1][j] == 0:
            return j, state

def better_constant_player(view, turn, state):
    for j in range(7):
        if view[-1][j] == 0:
            return j, state

players = [random_player, constant_player, better_random_player, better_constant_player]

run_tournament(players)

```

Happy KoTHing!

# Provisional Results

```
Name                    Draws Losses Wins  Score

zsani_bot:              40    5377   94583  0.892
better_constant_player: 0     28665  71335  0.427
constant_player:        3     53961  46036 -0.079
normalBot:              38    64903  35059 -0.298
better_random_player:   192   71447  28361 -0.431
random_player:          199   75411  24390 -0.510

```

# Answer
This bot takes all sure wins, and falls back to block the rivals, second guess them vertically and horizontally or make random moves.

```
import pprint, math, collections, copy
def zsani_bot_2(view, turn, state):
    if state == None: #first own turn - always for for middle
        state = (1, 2) if turn == 0 else (2, 1) #(my_symbol, your symbol)
        #print(pprint.pformat(view) + ' Turn: ' + str(turn) + ' Player: ' + str(state[0]))
        return 3, state

    #locate obvious points
    for i in range (1, 6):              #skip first row
        for j in range(len(view[i])):   #TODO: Optimise with zip. Go for clarity now
            if view[i][j] != 0 and view[i-1][j] == 0:
                view[i-1][j] = state[1]
    enemy_points = math.floor(turn/2)
    ++enemy_points if state[0] == 2 else enemy_points
    known_points = sum([i.count(state[1]) for i in view])
    missing_points = enemy_points - known_points

    #get sure wins in any direction
    for j in range(0, 7): #every column
        for i in range(4, -1, -1):
            if view[i][j] !=0:
                break #find highest known filled point
        if (not missing_points or i+1 in {1, 3, 5}):
            view1 = copy.deepcopy(view)
            attempt = apply_move(view1, state[0], j)
            if attempt == WON:
               # print(pprint.pformat(view) + ' Turn: ' + str(turn) + ' Player: ' + str(state[0]) + ' winner move')
                return j, state

    #block sure enemy wins in any direction
    for j in range(0, 7):
        for i in range(4, -1, -1):
            if view[i][j] !=0:
                break #find highest known filled point
        if (not missing_points or (i+1 in {1, 3, 5})):
            view1 = copy.deepcopy(view)
            attempt = apply_move(view1, state[1], j)
            if attempt == WON:
              #  print(pprint.pformat(view) + ' Turn: ' + str(turn) + ' Player: ' + str(state[0]) + ' saving move')
                return j, state

    #block walls
    for i in range(0, 3): #impossible to get 4 in a row when the column is full
        for j in range(0, 6):
            if view[i][j] != 0 and view[i][j] == view[i+1][j] and view[i+2][j] == view[i+3][j] == 0:
             #   print(pprint.pformat(view) + ' Turn: ' + str(turn) + ' Player: ' + str(state[0]) + ' column move')
                return j, state

    #block platforms if posessing perfect information on row below and drop point
    for i in range(0, 5):
        for j in range(0, 3):
            stats = collections.Counter([view[i][j], view[i][j+1], view[i][j+2], view[i][j+3]])
            if stats[0] == 2 and (stats[state[0]] == 2 or stats[state[0]] == 2):
                for k in range(0, 3):
                    if view[i][j+k] == 0:
                        break
                if (i == 0 or view[i-1][j+k] != 0) and (not missing_points or i in {1, 3, 5}):
                    #print(pprint.pformat(view) + ' Turn: ' + str(turn) + ' Player: ' + str(state[0]) + ' platform move')
                    return j+k, state
                else:
                    for l in range (k, 3):
                        if view[i][j+l] == 0:
                            break
                        if (i == 0 or view[i-1][j+l] != 0) and (not missing_points or i in {1, 3, 5}):
                     #       print(pprint.pformat(view) + ' Turn: ' + str(turn) + ' Player: ' + str(state[0]) + ' platform move')
                            return j+l, state

    #fallback -> random
    while True:
        j = random.randrange(0, 7)
        if view[-1][j] == 0:
            #print(pprint.pformat(view) + ' Turn: ' + str(turn) + ' Player: ' + str(state[0]) + ' random move')
            return j, state

```

Thank you for fixing run\_game!

Changelog:

* v2 adds horizontal blocking - if, in a row of 4, there are two empty spots and two spots filled by the same player, it will attempt to fill one of them to have three in a row/block the opponents row, which will hopefully be capitalized upon in the following turns.
> 6 votes

# Answer
normalBot plays upon the assumption that spots in the middle are more valuable than spots on the ends. Thus, it uses a normal distribution centered in the middle to determine its choices.

```
def normalBot(view, turn, state):
    randomNumber = round(np.random.normal(3, 1.25))
    fullColumns = []
    for i in range(7):
        if view[-1][i] != 0:
            fullColumns.append(i)
    while (randomNumber > 6) or (randomNumber < 0) or (randomNumber in fullColumns):
        randomNumber = round(np.random.normal(3, 1.25))
    return randomNumber, state

```
> 2 votes

# Answer
This is obviously non-competing, but nonetheless very useful for debugging... and surprisingly fun, if you know your bot well enough to cheat :D so I'm posting in the hopes of inspiring more submissions:

```
import math, pprint
def manual_bot(view, turn, state):
    if state == None:
        state = (1, 2) if turn == 0 else (2, 1) #(my_symbol, your symbol)

#locate obvious points
    for row in range (1, 6):
        for j in range(len(view[row])):
            if view[row][j] != 0 and view[row-1][j] == 0:
                view[row-1][j] = state[1]

#if you're second, the opponent has one more point than half the turns
    enemy_points = math.ceil(turn/2)
    known_points = sum([row.count(state[1]) for row in view])
    missing_points = enemy_points - known_points

    print(pprint.pformat(view) + ' Turn: ' + str(turn) + ' Player: ' + str(state[0]) + ' Missing points: ' + str(missing_points))
    while True:
        try:
            move = int(input("What is your move?(0-6) "))
        except ValueError:
            continue
        if move in {0, 1, 2, 3, 4, 5, 6}:
            return move, state

```

The grid is upside down(the bottom row is highest). To get the winner announcements, you need to patch the game controller, adding a print statement before returning the win:

```
elif outcome == WON:
    print(pprint.pformat(board) + ' Turn: ' + str(turn) +' Winner: '+ str(p))
    return p

```

```
[[0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0]] Turn: 0 Player: 1 Missing points: 0
What is your move?(0-6) 3
[[0, 0, 0, 1, 0, 0, 0],
 [0, 0, 0, 2, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0]] Turn: 2 Player: 1 Missing points: 0
What is your move?(0-6) 2
[[0, 0, 1, 1, 0, 0, 0],
 [0, 0, 0, 2, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0]] Turn: 4 Player: 1 Missing points: 1
What is your move?(0-6) 4
[[0, 0, 1, 1, 1, 0, 0],
 [0, 0, 0, 2, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0]] Turn: 6 Player: 1 Missing points: 2
What is your move?(0-6) 1
[[2, 1, 1, 1, 1, 2, 0],
 [0, 0, 0, 2, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0]] Turn: 6 Winner: 1
[[0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0]] Turn: 1 Player: 2 Missing points: 1
What is your move?(0-6) 2
[[0, 0, 2, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0]] Turn: 3 Player: 2 Missing points: 2
What is your move?(0-6) 3
[[0, 0, 2, 1, 0, 0, 0],
 [0, 0, 1, 2, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0]] Turn: 5 Player: 2 Missing points: 1
What is your move?(0-6) 4
[[0, 0, 2, 1, 2, 0, 0],
 [0, 0, 1, 2, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0]] Turn: 7 Player: 2 Missing points: 2
What is your move?(0-6) 1
[[0, 2, 2, 1, 2, 0, 0],
 [0, 0, 1, 2, 0, 0, 0],
 [0, 0, 1, 0, 0, 0, 0],
 [0, 0, 1, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0]] Turn: 9 Player: 2 Missing points: 1
What is your move?(0-6) 2
[[0, 2, 2, 1, 2, 0, 0],
 [0, 0, 1, 2, 0, 0, 0],
 [0, 0, 1, 0, 0, 0, 0],
 [0, 0, 1, 0, 0, 0, 0],
 [0, 0, 2, 0, 0, 0, 0],
 [0, 0, 1, 0, 0, 0, 0]] Turn: 11 Player: 2 Missing points: 1
What is your move?(0-6) 4
[[0, 2, 2, 1, 2, 0, 0],
 [0, 0, 1, 2, 2, 0, 0],
 [0, 0, 1, 0, 0, 0, 0],
 [0, 0, 1, 0, 0, 0, 0],
 [0, 0, 2, 0, 0, 0, 0],
 [0, 0, 1, 0, 0, 0, 0]] Turn: 13 Player: 2 Missing points: 2
What is your move?(0-6) 4
[[0, 2, 2, 1, 2, 0, 0],
 [0, 1, 1, 2, 2, 0, 0],
 [0, 0, 1, 0, 1, 0, 0],
 [0, 0, 1, 0, 2, 0, 0],
 [0, 0, 2, 0, 0, 0, 0],
 [0, 0, 1, 0, 0, 0, 0]] Turn: 15 Player: 2 Missing points: 1
What is your move?(0-6) 3
[[0, 2, 2, 1, 2, 0, 0],
 [0, 1, 1, 2, 2, 0, 0],
 [0, 0, 1, 2, 1, 0, 0],
 [0, 0, 1, 0, 2, 0, 0],
 [0, 0, 2, 0, 0, 0, 0],
 [0, 0, 1, 0, 0, 0, 0]] Turn: 17 Player: 2 Missing points: 2
What is your move?(0-6) 5
[[0, 2, 2, 1, 2, 1, 1],
 [0, 1, 1, 2, 2, 2, 1],
 [0, 0, 1, 2, 1, 0, 0],
 [0, 0, 1, 0, 2, 0, 0],
 [0, 0, 2, 0, 0, 0, 0],
 [0, 0, 1, 0, 0, 0, 0]] Turn: 19 Player: 2 Missing points: 0
What is your move?(0-6)
What is your move?(0-6) 6
[[0, 2, 2, 1, 2, 1, 1],
 [0, 1, 1, 2, 2, 2, 1],
 [0, 0, 1, 2, 1, 0, 2],
 [0, 0, 1, 0, 2, 0, 0],
 [0, 0, 2, 0, 0, 0, 0],
 [0, 0, 1, 0, 0, 0, 0]] Turn: 21 Player: 2 Missing points: 1
What is your move?(0-6) 1
[[0, 2, 2, 1, 2, 1, 1],
 [0, 1, 1, 2, 2, 2, 1],
 [0, 2, 1, 2, 1, 0, 2],
 [0, 1, 1, 0, 2, 0, 0],
 [0, 0, 2, 0, 0, 0, 0],
 [0, 0, 1, 0, 0, 0, 0]] Turn: 23 Player: 2 Missing points: 1
What is your move?(0-6) 3
[[0, 2, 2, 1, 2, 1, 1],
 [0, 1, 1, 2, 2, 2, 1],
 [0, 2, 1, 2, 1, 0, 2],
 [0, 1, 1, 2, 2, 0, 0],
 [0, 0, 2, 0, 0, 0, 0],
 [0, 0, 1, 0, 0, 0, 0]] Turn: 25 Player: 2 Missing points: 2
What is your move?(0-6) 6
[[0, 2, 2, 1, 2, 1, 1],
 [0, 1, 1, 2, 2, 2, 1],
 [0, 2, 1, 2, 1, 0, 2],
 [0, 1, 1, 2, 2, 0, 2],
 [0, 0, 2, 1, 0, 0, 0],
 [0, 0, 1, 1, 0, 0, 0]] Turn: 27 Player: 2 Missing points: 1
What is your move?(0-6) 5
[[1, 2, 2, 1, 2, 1, 1],
 [1, 1, 1, 2, 2, 2, 1],
 [0, 2, 1, 2, 1, 2, 2],
 [0, 1, 1, 2, 2, 0, 2],
 [0, 0, 2, 1, 0, 0, 0],
 [0, 0, 1, 1, 0, 0, 0]] Turn: 29 Player: 2 Missing points: 0
What is your move?(0-6) 5
[[1, 2, 2, 1, 2, 1, 1],
 [1, 1, 1, 2, 2, 2, 1],
 [0, 2, 1, 2, 1, 2, 2],
 [0, 1, 1, 2, 2, 2, 2],
 [0, 0, 2, 1, 0, 0, 0],
 [0, 0, 1, 1, 0, 0, 0]] Turn: 29 Winner: 2
Round 1 of 1

Name         Draws Losses Wins Score

manual_bot:  0     0      2     1.000
zsani_bot_2: 0     2      0    -1.000

```
> 0 votes

---
Tags: king-of-the-hill, python, board-game
---


title: Gerrymandering with Logic Gates

text:
# Question
Title: Gerrymandering with Logic Gates
The majority function is a boolean function which takes three boolean inputs and returns the most common. For instance if `maj(x,y,z)` is the majority function and `T` denotes true and `F` denotes false then:

```
maj(T,T,T) = T
maj(T,T,F) = T
maj(T,F,F) = F
maj(F,F,F) = F

```

This question concerns writing boolean functions as compositions of majority functions. An example of a 5-ary composition of majority functions is `(x1,x2,x3,x4,x5) => maj(x1,x2,maj(x3,x4,x5))`. This function returns the following output on these sample input vectors:

```
(T,T,F,F,F) => maj(T,T,maj(F,F,F)) = maj(T,T,F) = T
(T,F,T,T,F) => maj(T,F,maj(T,T,F)) = maj(T,F,T) = T
(T,F,T,F,F) => maj(T,F,maj(T,F,F)) = maj(T,F,F) = F
(F,F,F,T,T) => maj(F,F,maj(F,T,T)) = maj(F,F,T) = F

```

## Task

Write a program which inputs a positive integer n and a list of length n vectors of booleans and outputs a tree of majority gates that returns true on all of the given vectors if possible. The function may return either true or false on vectors not in the list of constraints.

* The list of vectors may be input in any format you like. If you prefer, instead of inputting the vector, you may input the list of true positions in the vector. So for instance, `[TTF,TFT,FTT]` or `[[T,T,F],[T,F,T],[F,T,T]]` or `[[1,2],[1,3],[2,3]]` (list of true positions) are all fine.
* Output can be any valid tree format. For instance, `maj(maj(x1,x2,x3),x4,x5)` works. You will probably want to use single numbers as stand-ins for variables, as in `[[1,2,3],4,5]`. Reverse polish `123m45m` is also okay, for instance.
* If there is no function that works, your program should generate an error or output a falsey value.
* If there are multiple functions that work, your program can return any of them. The function does not need to be simplified. For instance, `maj(x1,x1,x2)` or `x1` are equivalent.

## Scoring

This is code golf: Shortest solution in bytes wins.

## Test cases:

Note that there are many possible outputs for each of these cases, so you should write a checker script that converts your output to a function and check that your function returns true on each of the specified input vectors.

```
Input: 3, [TFF]
Output: 1 or [1,1,2] or [1,[1,2,2],[1,1,3]] or other equivalent

Input: 3, [TFF,FTF]
Output: Falsey or error (it's not possible)

Input: 3, [TTF,TFT]
Output: [1,2,3] or 1 or other equivalent

Input: 3, [TTF,TFT,FTT]
Output: [1,2,3] or [1,3,2] or other equivalent

Input: 4, [TTFF,TFTF,FFTT]
Output: Falsey or error

Input: 4, [TTTF,TTFT,TFTT,FTTT]
Output: [1, 2, 3] or [2,3,4], or many other options

Input: 5, [TTTFF,FTTFT,TFFFT]
Output: [1,[1,[1,2,5],[2,4,5]],3] or many other options

Input: 6, [TTTFFF,FTFTTF,TFFTFT]
Output: [1, 2, 4] or [1, [1, 2, 4], [2, 3, 4]] or others

Input: 5, [TTTFF,TTFTF,TTFFT,TFTTF,TFTFT,TFFTT,FTTTF,FTTFT,FTFTT,FFTTT]
Output: [[1, [1, 3, 5], 4], [1, 2, [2, 4, 5]], [2, 3, [3, 4, 5]]] or others

Input: 7, [TTTTFFF,TTTFTFF,TTTFFTF,TTTFFFT,TTFTTFF,TTFTFTF,TTFTFFT,TTFFTTF,TTFFTFT,TTFFFTT,TFTTTFF,TFTTFTF,TFTTFFT,TFTFTTF,TFTFTFT,TFTFFTT,TFFTTTF,TFFTTFT,TFFTFTT,TFFFTTT,FTTTTFF,FTTTFTF,FTTTFFT,FTTFTTF,FTTFTFT,FTTFFTT,FTFTTTF,FTFTTFT,FTFTFTT,FTFFTTT,FFTTTTF,FFTTTFT,FFTTFTT,FFTFTTT,FFFTTTT]
Output: [[[1, [1, [1, 4, 7], 6], 5], [1, [1, 3, [3, 6, 7]], [3, 5, [5, 6, 7]]], [3, 4, [4, [4, 5, 7], 6]]], [[1, [1, [1, 4, 7], 6], 5], [1, 2, [2, [2, 5, 7], 6]], [2, [2, 4, [4, 6, 7]], [4, 5, [5, 6, 7]]]], [[2, [2, [2, 4, 7], 6], 5], [2, 3, [3, [3, 5, 7], 6]], [3, [3, 4, [4, 6, 7]], [4, 5, [5, 6, 7]]]]]

```

# Answer
# JavaScript (ES6), 260 bytes

Takes input as an array of arrays of booleans. Returns a tree of 1-indexed majority gates or throws a recursion error (1) if no solution exists.

The main function **f()** recursively attempts to find a solution by calling the solver **F()** and incrementing the maximum nesting level **m** at each iteration.

*(1) after a **long** time, and assuming infinite memory*

```
f=(a,m)=>(F=(a,d,I=a[i=0].map(_=>++i),g=(a,b)=>b[1]?b.reduce((s,i)=>s+g(a,i),0)>1:a[b-1])=>I.find(i=>a.every(a=>g(a,i)))||d&&(I.reduce((a,x)=>[...a,...a.map(y=>[...y,x])],[[]]).some(b=>r=b.length==3&&F(a.map(a=>[...a,g(a,b)]),d-1,[...I,b]))&&r))(a,m)||f(a,-~m)

```

### Demo

```
f=(a,m)=>(F=(a,d,I=a[i=0].map(_=>++i),g=(a,b)=>b[1]?b.reduce((s,i)=>s+g(a,i),0)>1:a[b-1])=>I.find(i=>a.every(a=>g(a,i)))||d&&(I.reduce((a,x)=>[...a,...a.map(y=>[...y,x])],[[]]).some(b=>r=b.length==3&&F(a.map(a=>[...a,g(a,b)]),d-1,[...I,b]))&&r))(a,m)||f(a,-~m)

test = a => console.log(JSON.stringify(f(a.split(',').map(s => [...s].map(c => c == 'T')))))

test('TFF')
test('TTF,TFT')
test('TTF,TFT,FTT')
test('TTTF,TTFT,TFTT,FTTT')
test('TTTFF,FTTFT,TFFFT')
test('TTTFFF,FTFTTF,TFFTFT')
test('TTTFF,TTFTF,TTFFT,TFTTF,TFTFT,TFFTT,FTTTF,FTTFT,FTFTT,FFTTT')
```

### Example

Below is a validation table of the solution found for the last test case of the demo.

```
12345 | [5,[1,2,4],[3,4,[1,2,3]]]
------+-------------------------------------------------------------
TTTFF | [F,[T,T,F],[T,F,[T,T,T]]] --> [F,T,[T,F,T]] -> [F,T,T] --> T
TTFTF | [F,[T,T,T],[F,T,[T,T,F]]] --> [F,T,[F,T,T]] -> [F,T,T] --> T
TTFFT | [T,[T,T,F],[F,F,[T,T,F]]] --> [T,T,[F,F,T]] -> [T,T,F] --> T
TFTTF | [F,[T,F,T],[T,T,[T,F,T]]] --> [F,T,[T,T,T]] -> [F,T,T] --> T
TFTFT | [T,[T,F,F],[T,F,[T,F,T]]] --> [T,F,[T,F,T]] -> [T,F,T] --> T
TFFTT | [T,[T,F,T],[F,T,[T,F,F]]] --> [T,T,[F,T,F]] -> [T,T,F] --> T
FTTTF | [F,[F,T,T],[T,T,[F,T,T]]] --> [F,T,[T,T,T]] -> [F,T,T] --> T
FTTFT | [T,[F,T,F],[T,F,[F,T,T]]] --> [T,F,[T,F,T]] -> [T,F,T] --> T
FTFTT | [T,[F,T,T],[F,T,[F,T,F]]] --> [T,T,[F,T,F]] -> [T,T,F] --> T
FFTTT | [T,[F,F,T],[T,T,[F,F,T]]] --> [T,F,[T,T,F]] -> [T,F,T] --> T

```
> 3 votes

# Answer
# Mathematica, 121 bytes

An anonymous function which takes its second argument as a list of the lists of true positions in the vector of booleans.

```
f[n_][s_]:=If[n<3,(Intersection@@s)[[1]],{#/. 2->1,#2/.{2->1,3->2},#3}&@@(1+f[n-1]/@(s-1/.{{0->1},{1->2,0->1},{0->2}}))]

```

Formatted slightly nicer:

```
f[n_][s_] := If[n < 3, (Intersection @@s)[[1]],
   {# /. 2 -> 1, #2 /. {2 -> 1, 3 -> 2}, #3} & @@
    (1 + f[n - 1] /@ (s - 1 /. {{0 -> 1}, {1 -> 2, 0 -> 1}, {0 -> 2}}))]

```

\\$\def\maj{\mathrm{maj}}\def\T{\mathrm{True}}\def\F{\mathrm{False}}\\$ If there are fewer than three variables, intersect the constraint vectors to see if there is a common "True" in all of the constraints. If there is one, then the constant function (x\_1,x\_2) --\> x\_i works, otherwise it is impossible (and will throw an error by trying to take the first element of an empty list).

Otherwise, substitute \\$f\_1=f(x\_1,x\_1,x\_2,x\_3,\ldots,x\_{n-1})\\$, \\$f\_2=f(x\_1,x\_2,x\_2,x\_3,\ldots,x\_{n-1})\\$, and \\$f\_3=f(x\_1,x\_2,x\_1,x\_3,\ldots,x\_{n-1}))\\$, recursively solve each of these, then set \\$f=\maj(f\_1(x\_1,x\_3,x\_4,\ldots,x\_n), f\_2(x\_1,x\_2,x\_4,\ldots,x\_n),f\_2(x\_2,x\_3,x\_4,\ldots,x\_n))\\$.

### Explanation:

This is a recursive algorithm that reduces the problem of finding a solution of an \\$n\\$ variable problem to finding three solutions to \\$n-1\\$ variable problems. The key observation that makes this work is that for \\$f\\$ one of the functions we are looking for we have: \\$f(x\_1,\ldots,x\_n)=\maj(f(x\_1,x\_1,x\_3,x\_4,\ldots,x\_n),f(x\_1,x\_2,x\_2,\ldots),f(x\_3,x\_2,x\_3,\ldots))\\$

In the first position, we replaced \\$x\_2\\$ with \\$x\_1\\$, in the second position \\$x\_3\\$ with \\$x\_2\\$ and in the third position \\$x\_1\\$ with \\$x\_3\\$.

Once you know this identity, the algorithm is clear: when there are two or fewer variables, the problem is trivial. Otherwise, recursively solve the three problems of representing \\$f(x\_1,x\_1,x\_3,x\_4,\ldots,x\_n)\\$, \\$f(x\_1,x\_2,x\_2,x\_4,\ldots,x\_n)\\$, and \\$f(x\_3,x\_2,x\_3,x\_4,\ldots,x\_n))\\$ and take the majority of them.

Why is this true? Well the majority function satisfies two properties:

1. It is "complementary". That is, if \\$!x\\$ is the negation of \\$x\\$, then \\$\maj(!x,!y,!z)=!\maj(x,y,z)\\$. As a consequence, every function we can build out of the majority function is complementary.
2. It is monotonic. That is, \\$\maj(x,y,\F)\leq \maj(x,y,\T)\\$. In general, if we say that \\$\F\leq \T\\$ and say \\$(x\_1,\ldots,x\_n)\leq (y\_1,\ldots, y\_n)\\$ if \\$x\_i\leq y\_i\\$ for all \\$i\\$, then I say a function \\$f\\$ is monotonic if \\$(x\_1,\ldots x\_n)\leq(y\_1,\ldots, y\_n)\\$ implies \\$f(x\_1,\ldots x\_n)\leq f(y\_1,\ldots, y\_n)\\$. The composition of monotonic functions is monotonic so every function we can build out of the majority function is monotonic.

It turns out that complementary monotonic functions are exactly the class of functions that can be built out of majority gates.

Now, we show that for \\$f\\$ a complementary monotonic function, our identity holds: \\$f(x\_1,\ldots,x\_n)=\maj(f(x\_1,x\_1,x\_3,x\_4,\ldots,x\_n),f(x\_1,x\_2,x\_2,x\_4,\ldots,x\_n),f(x\_3,x\_2,x\_3,x\_4,\ldots,x\_n))\\$

Let's set \\$f\_1(x\_1,x\_2,x\_3,\ldots,x\_n)=f(x\_1,x\_1,x\_3,x\_4,\ldots,x\_n)\\$, \\$f\_2(x\_1,\ldots,x\_n)=f(x\_1,x\_2,x\_2,x\_4,\ldots,x\_n)\\$ and \\$f\_3(x\_1,\ldots,x\_n)=f(x\_3,x\_2,x\_3,x\_4,\ldots,x\_n)\\$. To show that \\$f=\maj(f\_1,f\_2,f\_3)\\$, we need to show that for any input, at least two of \\$f\_1\\$, \\$f\_2\\$, and \\$f\_3\\$ are equal to \\$f\\$. We divide up into cases based on the values of \\$x\_1\\$, \\$x\_2\\$ and \\$x\_3\\$. If \\$x\_1=x\_2=x\_3\\$ then \\$f\_1=f\_2=f\_3=f\\$.

Suppose not all of \\$x\_1\\$, \\$x\_2\\$, and \\$x\_3\\$ are the same. By permuting the variables of \\$f\\$, we can assume that \\$x\_1=x\_2\\$ and \\$x\_3\\$ is different and because \\$f\\$ is complementary, it suffices to deal with the case \\$x\_1=x\_2=\F\\$ and \\$x\_3=\T\\$. In this case, \\$(x\_1,x\_1,x\_3)=(\F,\F,\T)=(x\_1,x\_2,x\_3)\\$, \\$(x\_1,x\_2,x\_2)=(\F,\F,\F)\leq (x\_1,x\_2,x\_3)\\$ and \\$(x\_3,x\_2,x\_3)=(\T, \F, \T) \geq (x\_1,x\_2,x\_3)\\$. By monotonicity we deduce that \\$f\_2\leq f\_1=f\leq f\_3\\$. If \\$f=\F\\$ then \\$f\_2\leq \F\\$ implies \\$f\_2=\F=f\\$ and if \\$f=\T\\$ then \\$f\_3\geq \T\\$ implies \\$f\_3=\T\\$. Thus, at least two of \\$f\_1\\$, \\$f\_2\\$, and \\$f\_3\\$ are equal to \\$f\\$ in all cases so \\$f=\maj(f\_1,f\_2,f\_3)\\$.
> 3 votes

---
Tags: code-golf, logic-gates, logic
---