text:
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

Can we return a list of lines?

@JoKing if your language allows it. I'm not 100% sure on the rules, but I think it's permissible to have a function return a list of lines in Python, which can then be joined in the footer.

It must entertaining to work with such a funny chap! :s On a slightly more serious note: the nrOfButs variable is rather poorly-named and misleading. Nice simple challenge anyway.

@Arnauld I contemplated renaming the variable before posting the challenge, but I wanted to stay true to the source.

Do we get a bonus if the last line is "God can't believe you just said that!"

Shouldn't the output be "Yeah / No / But / Yeah / But / Yeah..."?

@EriktheOutgolfer the ifs fall trough and continue in the current loop if their condition was satisfied.

The most Australian codegolf yet? Except it should be "nah"

@Nacht This is surely a Little Britain reference, no? That was my assumption, anyway.

Has anyone noticed yet that this script is not only hideously verbose but also incorrect? The actual number of buts is only half of the demanded nrOfButs! (except for input 1)

We must not handle faulty input? So I disqualify if I do?

@IngoBürk Darn it, you got me. Now I'll have to disqualify you

In the input=10 example, there is a "No" immediately followed by a "Yeah". Is that intended?

@JDL yes and no. My colleague wrote the code in a slack post, probably without ever running it himself. I chose to keep the code as is, which makes it "intended", I guess.

okay --- so we are reproducing specifically that code, not the first n words of "yeah but no but" repeated ad infinitum.

@JDL Exactly! I've had quite a few answers that didn't look at the code above, but instead just printed n lines of "Yeah But No". Those are not valid answers, as the challenge is to accurately imitate the code above.

@maxb One more serious note: "And since it is common knowledge that a shorter program is faster to write..." Here it is common knowledge that in code golfing, a shorter program is slower to write.

@trolley813 it should be faster to write, since the only limiting factor is the number of keystrokes. No I understand your point, I was just being sarcastic.

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.

I have no way of verifying this, but your description makes it seem correct. Can you add some example input/output pairs? One of the more ridiculous languages, but great answer nonetheless.

@maxb Can't be all that ridiculous when it is beating other languages.

Great explanation and very cool technique. Works in LibreOffice Calc as well but might need some playing with the formatting. +1

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

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!

It looks awesome (I would hate to code this!), but in test case 10 the 2nd "No" and 3rd "But" get flipped... So Yeah, but no :D

Whoops, thought I could optimize there. This is a tricky pattern. I fixed it now.

I love the way it reads

Does VISIBLE "But" refer to the program's lack of trousers?

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.

I most certainly did not expect a Whitespace answer. Good job!

@maxb Thanks! Unfortunately it's quite a bit longer than expected due to the 8 labels it requires.. But I'm already happy it's working. :)

Couldn't you halve the labels by skipping to the next if statement if the condition is false? e.g. if i modulo-3 != 1 jump to next if else push NO

@JoKing In Whitespace unfortunately not. Whitespace only has three types of jumps for labels: "Jump unconditionally" (this is usually used for loops, or to return from a conditional jump), "Jump if the top of the stack is 0" (which is what I mainly used in my answer with the modulos), "Jump if top of the stack is negative" (which is what I've used to stop the outer loop in this case). Unfortunately there isn't any "Jump if top of the stack is positive" or "Jump if top of the stack is NOT 0/negative" available.. (PS: The i%3==1 case is done by subtracting 1 and using the "Jump if 0".)

Okay, throwing stuff at the wall to see what sticks. Can you jump straight from the end of the Yeah function to the start of the loop? Can you move the check if printing time to the yeah function (since that's always last), thereby allowing you to move the i = i-1 lower in the loop and utilise the method I mentioned before for the first two push sections?

@JoKing That first suggestion is indeed a great one. Instead of going to the RETURN_FROM_YEAH and then going to the next iteration of the LOOP, I can jump directly to the next iteration of the LOOP from the YEAH function. Will do that in a moment.

@JoKing As for your second suggestion I'm not sure I follow. One concern is that it's not guaranteed to enter the functions for every iteration, so putting i = i-1 inside the YEAH function for iteration i = 9 for example would mean it will never decrease i and gets stuck in an infinite loop. Also, the range in the challenge is [0, n) (or (n, 0] in my case since I loop backwards), so doing the i = i-1 at the end of the loop iteration would mean it changes to [n, 0] instead, making the input inclusive.

i meant moving it to after the return from BUT label. Theoretically you could then change the first if to if i%3 -2 < 0 jump to return from NO and the second to if i%2 == 0 jump to return from BUT. Then you could sub the corresponding functions inside without having to jump around

It's really hard to edit existing whitespace code, but something like this?

@JoKing That does indeed look very promising and quite a bit shorter. I only see two small issues, but both are easily fixed. You now do if(i is 0) call PRINT first before retrieving i from the heap (probably by accident), so simply changing that order should fix it. And the other is with input = 10 the range should be (10,0) (excluding on both ends) but is [10,0) (including input) now. But I have a solution in mind. Will start trying to implement your pseudo-code and see what the total byte-count will become. :)

@JoKing Ah wait, I misunderstood a part of your pseudo-code. My first issue about not retrieving i before the if(i is 0) call PRINT is true, but your other is checking the i before subtracting it and skipping over the prints. Pretty smart actually. Will continue implementing it.

@JoKing Thanks! -23 bytes right there. :D

Would jumping to the start of the loop instead of jumping to the print label save bytes? Also, can't you have an empty label?

@JoKing What do you mean by the first part? The Loop puts all the values in reverse on the stack, and the Print-loop prints them one by one (by adding a constant). When would I need to jump to the start of the loop when printing? And I already use an empty label. :) The five labels I now use are: PRINT (3x): empty label; LOOP (3x): label S; SKIP_NO (2x): label T; SKIP_BUT (2x): label SS; YEAH (2x): label ST.

Well, if you jump to the start of the loop, it will run the if statement again and jump straight back to the print function. Maybe this saves a byte if you change the loop label to the empty label

@JoKing Oh, that's what you mean. Hmm, that does sound like it could work indeed (EDIT: It indeed does. :D). Then it will go from PRINT to LOOP to PRINT again since the if-statement is still the same, to LOOP, etc. saving 1 byte with this detour due to the empty LOOP label we go to, instead of the 1-byte S (PRINT) label we go to directly. Smart!

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!

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

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!

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

Dang, you beat me to it.. Was about to post an answer. Yours is shorter anyway, so +1 from me.. Nice use of ×, hadn't thought about that!

Wow, I'd love an explanation on this one. My personal best was 44 bytes in CJam.

@maxb: I will of course add an explanation. I'm just checking to see if I can golf it down some more first ;)

You can remove the Θ now that you're no longer using ×, since Ï will only look at 1s only, so it ignores the 2 (and 0 of course).

@KevinCruijssen: Thanks! Not sure how I missed that :P

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

Try it online!

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

86 bytes by combining the two and returning as a list of lines

@JoKing Thanks, didn't  know that I could return instead of printing when wrote it.

82 bytes: len(w)<3 -> 'N'in w, 81 bytes : len(w)%2 -> (w<'N')

Canvas, 27 bytes
｛╷⌐３％‽YeahＰ｝２％‽ButＰ｝３％╷‽NoＰ

Try it here!

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!

Welcome to PPCG! Great first answer! I haven't coded any Groovy myself, but might I suggest running your code on TIO? That way, it can be validated by others, and enjoyed by all.

@maxb Thanks! I've added one :)

Nice first answer and also welcome to PPCG.

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`

++i%3>1 will likely save you a byte

@OlivierGrégoire Ah, of course. Thanks!

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 1s before it, except for No, which has two extra 1s so that we calculate (i+2)%3==0 which is equivalent to i%3==1.
+`11B
B

Remove pairs of 1s before Bs.
111

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

Delete all lines that still have a 1.

Oh, now that I see 11No¶ to calculate (i+2)%3==0 (so all three are if-checks for ==0) it looks so obvious, but I wouldn't have thought of that myself, so it's actually quite ingenious. +1 from me, nice 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]}}

Great answer! Would it be possible to add some output to the answer, since it doesn't include an online interpreter?

The answer scriptblock does not return ======. It generates Yeah,But,No strings only. The test script shows a separator for easier reading of the results only.

That hashtable usage is clever. I'm going to need to remember that.

@maxb - a tio.run online interpreter link for the 67 byte answer

@mazzy I can reformulate yours, but still can't beat 67 (replace the two \n with real newlines) (" Yeah\nBut No But Yeah But\nNo "*($j="$args")|% s*t 32)[1..$j]-ne''

nice split. it saves a byte.

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!

Removing the interpolation like this saves 7 bytes.

@Emigna Thanks for the tip, changed the answer

x++%3==1? can be ++x%3>1?. Someone else just tipped it for my Java answer, but the same applies to your C# 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

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.

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

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!

@JonathanFrech Nice but doesn't work for zero, or 5

@cleblanc Oh, sorry. Did not realize ... At least removing j saved you two bytes.

70 bytes -- incorporating @ceilingcat's one saved byte.

n-~-i is equivalent to n-i+1 -- not i<n+1 -- and so does not actually save any bytes ...

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

Can you add some explanations please ?

@user285259 Done.

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

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!

If you already have an expression you can use in a list comprehension but your list comprehension only exists to evoke that expression's side effects, a plain for loop requires less bytes.

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)

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

You could use string repetition instead of tuple indexing -- ('','Yeah\n')[x%3<1] is equivalent to "Yeah\n"*(x%3<1).

@JonathanFrech - very cool! Similar technique can be applied to the other cases as well. Many thanks!

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!

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

@Keeta good idea, but no... If you look at my first code, I use [a1] which means Range/cell .value :) I should've made it more clear that was an explanation though, sorry :/

Yeah, I saw that and tried to delete the comment.  How about using i/3=i\3 instead of i mod 3 = 0 (and same for mod 2 = 0).  Haven't tried it, but would it work?

@Keeta I've never seen the \ operator before... I don't think so though, it returns the value of division without the remainder... like the opposite of Mod I think

One is integer division and one is floating point.  7/3 = 2.3333 where 7\3 = 2 (truncate division).  6/3 should be 2, and 6\3 should also be 2 so it should work whenever remainder is zero (I think).

@Keeta Oh... yeah, but no, but yeah! Nice!

VBA will automatically concatenate function outputs, so you can drop the & between eachIIf(..) for an extra 2 bytes

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.

I get some kind of build error for the TIO link, perhaps a syntax error in the testing code?

Thanks for that. My original solution printed directly to the console, but then I tried returning a sequence and it turned out to be shorter by about 2 bytes. So I changed the code in the TIO but forgot to update the footer - which was still expecting the v function to print everything out.

Shave 2 bytes with i=1 to p (and adjusting moduli, naturally). Reverse ranges are empty. :)

Nice! I've added that. Thanks! :)

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"]

I doubt it's going to get any shorter than this. Fantastic answer, and a great explanation, well done!

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!

Nice answer! But if you're using python, you have to include the n=5 in the byte count, or use a function or lambda expression

@maxb ah, didn't realise, thanks

85 bytes

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.

It looks good, but it produces an extra newline in the middle for n=10

@maxb Thanks for the hint. I could have fixed it with 9 extra bytes; but the other approach is shorter.

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

I have no way of validating this (if I open Vim I'll never get out of there), but your logic looks correct. Nice 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

Welcome to PPCG! Great first answer, might I suggest adding a link to tio.run? If you haven't done it before, I'll suggest an edit in a short while.

@maxb I am afraid TIO does not support MBASIC.

I'm not really familiar with BASIC, but the script ran just fine in MY-BASIC

That may only work for simple programs. Would it help if I linked to the MBASIC reference manual?

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!

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!
Objects R Kool. They are kool indeed. But looping is hell. It's nice that the mathematicians' results are reusable, though.

I've never heard of this language! Even though I really like the submission, I must point out that it produces incorrect output for input 0. It should produce an empty string (or whitespace only).

My mistake. Thanks for adding 123 bytes to the program, though :P

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!

Stax, 21 bytes
ë╗ô┤z‼╔@qgx╕π♣►Ü~Y↓├Φ

Run and debug it

One of the shortest answers, nicely done!

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""

Welcome to PPCG -- 82 bytes.


text:
Block-sorting rows and columns in a 2D array
Given a 2D array of integers, let's sort its rows and columns in blocks. This means that you only have to sort a given row or column, but applying the transformations needed for sorting it to every other row or column in the 2D array.
Rules

Input will be a 2D array of integers and a 1-indexed integer. This integer will represent the row to be sorted if the number is positive, or the column to be sorted if the number is negative (or the other way round you want). Example: Given a 4x3 (rows x columns) array you can sort the second column with a -2 argument or the third row with a 3 argument. This second argument will never be zero and its absolute value will never be greater than the corresponding dimension of the array.
Output will be also a 2D array of integers with the needed transformations applied to sort the given row or column. Alternatively you can just write the array to STDOUT.
The output array will have the specified row or column sorted in ascending order. Just note that when you need to swap two numbers in a row, the whole columns where the numbers lay will be swapped. And when you need to swap two numbers in a column, the whole rows where the numbers lay will be swapped.
In the case in which the same number appears several times in the row/column to be sorted, there will be several solutions possible according to the way you swap the values, just do accordingly with the rest of rows/columns to be swapped.

Examples
Positive indices for rows and negative indices for columns

[5  8  7  6                                  [1  3  2  4
 1  3  2  4   order by -3 (3rd column)  -->   9  6  3  0
 9  6  3  0]                                  5  8  7  6]

[5  8  7  6                                  [9  6  3  0
 1  3  2  4   order by -4 (4th column)  -->   1  3  2  4
 9  6  3  0]                                  5  8  7  6]

[5  8  7  6                                  [5  7  8  6
 1  3  2  4     order by 2 (2nd row)  -->     1  2  3  4
 9  6  3  0]                                  9  3  6  0]

[5  8  7  6                                  [6  7  8  5
 1  3  2  4     order by 3 (3rd row)  -->     4  2  3  1
 9  6  3  0]                                  0  3  6  9]

[1  2                                    [1  2     [3  2
 3  2]   order by -2 (2nd column)  -->    3  2] or  1  2]  (both are valid)

[7  5  9  7                                  [5  7  7  9     [5  7  7  9
 1  3  2  4     order by 1 (1st row)  -->     3  1  4  2  or  3  4  1  2
 9  6  3  0]                                  6  9  0  3]     6  0  9  3]

This is code-golf, so may the shortest code for each language win!

This comes from the sandbox.

Can we change the integer representation? negative for rows and positive for columns?

@LuisfelipeDejesusMunoz yes, that is stated in the question.

Can a row/column contain duplicated numbers?

@KevinCruijssen yes, see last examples and last point of the rules.

R, 55 bytes
function(x,n)`if`(n>0,x[,+x[n,]],x[+x[,-n],])
`+`=order

Try it online!
Reassigns the + operator (actually a function in R) to the order function, which returns the indices of a vector from smallest to largest. Then it's just array manipulation.

It's just as short as a recursive function :-)

Matlab, 73 62 47 bytes
@(m,i){sortrows(m,-i) sortrows(m',i)'}{(i>0)+1}

Try it Online!
-11 bytes thanks to @Giuseppe.
-15 bytes thanks to @LuisMendo.

R, 55 bytes
f=function(m,i)"if"(i<0,t(f(t(m),-i)),m[,order(m[i,])])

Try it online!
Alternative to ngm's answer; a recursive function which was inspired by DimChtz's answer

Japt, 18 17 bytes
negative for rows and positive for columns
>0?VñgUÉ:ßUa Vy)y

Try it online!

This fails when U is negative - the previous 17 byte version works, though.

@Shaggy My bad, I though it would work anyway, didnt check at all

Not a bad idea, though, passing a function as the first argument of ß that automatically gets applied to U. It could create issues with trying to pass literal strings, but post a suggestion to the GitHub repo anyway for further investigation.

JavaScript (ES6), 90 bytes
t=m=>m[0].map((_,x)=>m.map(r=>r[x]))
f=(m,k)=>k<0?m.sort((a,b)=>a[~k]-b[~k]):t(f(t(m),-k))

Try it online!
How?
JS has no native transposition method, so we need to define one:
t = m =>              // given a matrix m[]
  m[0].map((_, x) =>  // for each column at position x in m[]:
    m.map(r =>        //   for each row r in m[]:
      r[x]            //     map this cell to r[x]
    )                 //   end of map() over rows
  )                   // end of map() over columns

Main function:
f = (m, k) =>         // given a matrix m[] and an integer k
  k < 0 ?             // if k is negative:
    m.sort((a, b) =>  //   given a pair (a, b) of matrix rows, sort them:
      a[~k] - b[~k]   //     by comparing a[-k - 1] with b[-k - 1]
    )                 //   end of sort
  :                   // else:
    t(f(t(m), -k))    //   transpose m, call f() with -k and transpose the result

Example with \$k=2\$:
$$M=\pmatrix{5&8&7&6\\1&3&2&4\\9&6&3&0}\rightarrow
t(M)=\pmatrix{5&1&9\\8&3&6\\7&2&3\\6&4&0}\rightarrow
f(t(M),-2)=\pmatrix{5&\mathbf{\color{red}1}&9\\7&\mathbf{\color{red}2}&3\\8&\mathbf{\color{red}3}&6\\6&\mathbf{\color{red}4}&0}\\f(M,2)=t(f(t(M),-2))=\pmatrix{5&7&8&6\\\mathbf{\color{red}1}&\mathbf{\color{red}2}&\mathbf{\color{red}3}&\mathbf{\color{red}4}\\9&3&6&0}$$

05AB1E, 25 24 14 bytes
diø}Σ¹Ä<è}¹diø

Whopping -10 bytes thanks to @Emigna.
Uses a positive integer-input to sort the rows, negative for columns.
Try it online or verify all test cases.
Explanation:
di }      # If the (implicit) integer input is positive:
  ø       #  Swap the rows and columns of the (implicit) matrix input
          #   i.e. 3 and [[5,8,7,6],[1,3,2,4],[9,6,3,0]]
          #    → [[5,1,9],[8,3,6],[7,2,3],[6,4,0]]
Σ    }    # Sort the rows of this matrix by:
 ¹Ä       #  Take the absolute value of the input
          #   i.e. -3 → 3
   <      #  Decreased by 1 to make it 0-indexed
          #   i.e. 3 → 2
    è     #  And index it into the current row
          #   i.e. [5,8,7,6] and 2 → 7
          #   i.e. [5,1,9] and 2 → 9
          #  i.e. [[5,1,9],[8,3,6],[7,2,3],[6,4,0]] sorted by [9,6,3,0]
          #   → [[6,4,0],[7,2,3],[8,3,6],[5,1,9]]
          #  i.e. [[5,8,7,6],[1,3,2,4],[9,6,3,0]] sorted by [7,2,3]
          #   → [[1,3,2,4],[9,6,3,0],[5,8,7,6]]
¹di       # And if the integer input was positive:
   ø      #  Swap the rows and columns back again now that we've sorted them
          #   i.e. 3 and [[6,4,0],[7,2,3],[8,3,6],[5,1,9]]
          #    → [[6,7,8,5],[4,2,3,1],[0,3,6,9]]
          # (And implicitly output the now sorted matrix)

I got diø}Σ¹Ä<è]¹diø which is a subset of yours, so I'm not posting a separate answer.

@Emigna Dang, you make it look so easy.. Now that I see it I can't believe I hadn't thought about that myself, but it's ingenious at the same time.. Thanks! A whopping 10 bytes saved thanks to you.

MATL, 17 bytes
y0>XH?!]w|2$XSH?!

Try it online!
Or verify all test cases
Explanation
y       % Implicit inputs: number n, matrix M. Duplicate from below: pushes n, M, n
0>      % Greater than 0?
XH      % Copy into clipboard H
?       % If true
  !     %   Transpose matrix. This way, when we sort the rows it will correspond
        %   to sorting the columns of the original M
]       % End
w       % Swap: moves n to top
|       % Absolute value
2$XS    % Two-input sortrows function: sorts rows by specified column
H       % Push contents from clipboard H
?       % If true
  !     %   Transpose again, to convert rows back to columns
        % Implicit end
        % Implicit display

APL (Dyalog Classic), 23 bytes
{⍺<0:⍉(-⍺)∇⍉⍵⋄⍵[;⍋⍺⌷⍵]}

Try it online!

Python 2, 71 70 bytes
f=lambda m,n:n<0and sorted(m,key=lambda l:l[~n])or zip(*f(zip(*m),-n))

Try it online!

If n is negative, the rows are sorted based on column n.
Otherwise the matrix is transposed, sorted the same way, and transposed back again.

Jelly, 12 bytes
ZṠ}¡
çị@ÞA}ç

Try it online!

Java (OpenJDK 8), 326 bytes
(a,b)->{int l=a.length,w=a[0].length,k,m,t,i;if(b>0){for(i=0;i<w;i++){for(k=1;k<(w-i);k++){if(a[b-1][k-1]>a[b-1][k]){for(m=0;m<l;m++){t=a[m][k];a[m][k]=a[m][k-1];a[m][k-1]=t;}}}}}else{b*=-1;for(i=0;i<l;i++){for(k=1;k<(l-i);k++){if(a[k-1][b-1]>a[k][b-1]){for(m=0;m<w;m++){t=a[k][m];a[k][m]=a[k-1][m];a[k-1][m]=t;}}}}}return a;}

Try it online!
Well guys, this question was very frustrating for me, and I posted my answer KNOWING I was forgetting something, luckily we have legends like Kevin Cruijssen out here to help us out :)
Java (OpenJDK 8), 281 bytes
a->b->{int l=a.length,w=a[0].length,k,m,t,i;if(b>0)for(i=0;i<w;i++)for(k=0;++k<w-i;)for(m=0;a[b-1][k-1]>a[b-1][k]&m<l;a[m][k]=a[m][k-1],a[m++][k-1]=t)t=a[m][k];else for(b*=-1,i=0;i<l;i++)for(k=0;++k<l-i;)for(m=0;a[k-1][b-1]>a[k][b-1]&m<w;a[k][m]=a[k-1][m],a[k-1][m++]=t)t=a[k][m];}

Try it online!

I haven't looked at the actual algorithm yet, but you can save 35 bytes by removing all the brackets and putting everything inside the loops (including the inner if-statement). Try it online: 291 byte EDIT: Here with space indentations so you can more clearly see the changes I did.

@KevinCruijssen I knew I was missing something

In addition, you can make it a currying input a->b-> instead of (a,b)-> and remove the return-statement, since you are modifying the input-array. 281 bytes Still a nice answer, though. +1 from me. I did the challenge in 05AB1E, but wouldn't even have tried it in Java this time. ;)

270 bytes

C# (.NET Core), 186 bytes
(x,y)=>{Func<int[][],int[][]>shift=a=> a[0].Select((r,i)=>a.Select(c=>c[i]).ToArray()).ToArray();return y>0?shift(shift(x).OrderBy(e=>e[y-1]).ToArray()):x.OrderBy(e=>e[-y-1]).ToArray();}

Try it online!
Ungolfed:
    private static int[][] Blocksort0a(int[][] array, int sortingInstruction)
    {
        Func<int[][], int[][]> shift = a => a[0].Select((r, i) => a.Select(c => c[i]).ToArray()).ToArray();

        sortingInstruction++;

        array = sortingInstruction < 0 ?
        shift(shift(array).OrderBy(e => e[-sortingInstruction]).ToArray())
             :
        array.OrderBy(e => e[sortingInstruction]).ToArray();

        return null;
    }

The shift function we'll use twice, so a function variable will save space. The function iterates through the horizontal dimension of the array on index, and adds every item on that index in of each horizontal array to a new output array (horizontally) - much the same as in Arnoud's JS solution.
Now the ordering is simple, order horizontal array by number-at-index (argument -1), optionally shifting the array before and after sorting.
Seen how the question talks about arrays specifically, we convert to array a few times (very, very wasteful). Feeling a bit silly to use such a verbose language in code golf hehe.

C# (.NET Core), 142/139 138/135 bytes (and yet another -1 by Kevin)
(a,s)=>s<0?a.OrderBy(e=>e[~s]).ToArray():a.Select(f=>a[s-1].Select((v,j)=>new{v,j}).OrderBy(e=>e.v).Select(e=>f[e.j]).ToArray()).ToArray()

Try it online!
Ungolfed:
    private static int[][] Blocksort0b(int[][] array, int sortingInstruction)
    {
        if (sortingInstruction < 0) { return array.OrderBy(e => e[-sortingInstruction - 1]).ToArray(); }
        var rowIndices = array[sortingInstruction - 1].Select((value, index) => (value, index)).OrderBy(e => e.value);
        var newRow = new int[array[0].Length];
        for (var i = 0; i < array.Length; i++)
        {
            int horizontalIndexer = 0;
            foreach (var e in rowIndices)
            {
                newRow[horizontalIndexer++] = array[i][e.index];
            }
            array[i] = newRow.ToArray();
        }
        return array;
    }

New all-inline approach; negative answer still orders arrays by element-at-index. Otherwise, a collection of value-index-pair is created of the array-at-index and sorted by value. This effectively creates a collection of indices in order of having-to-be-added. Then for each array, the elements in the predetermined positions are selected. Quite some trimming of code and ugly, ugly, ugly **silently sobs** reuse of input parameters is involved, and there you go ... 142 bytes.
Again, the arrays argument is strictly enforced, adding quite some overhead for .ToArray() calls.
135 bytes claim, eh?! C# 7.2 inferred value-tuples would trim an additional three bytes, but tio.run doesn't allow. Therefor, this is the answer i decided to post for easy verification.

Nice answer. There are a few small things to golf. (a,s)=> can be a currying a=>s=>. (s<0)? doesn't need the parenthesis, and -s-1 can be ~s. Try it online: 137 bytes

Sweet! I never would've through of letting the function return yet another function to save a character, i am pleasantly surprised. Thanks!
Also a strong case of blatantly overlooking the not operator and parenthesis. I updated the not and parentheses, but will leave you all the honour for the function-returning-function.

Clean, 95 bytes
import StdEnv,Data.List,Data.Func
$n#f=if(n>0)transpose id
=f o sortBy(on(<)\u=u!!(abs n-1))o f

Try it online!

Red, 190 185 bytes
func[b n][t: func[a][c: length? a/1 a: to[]form a
d: copy[]loop c[append/only d extract a c take a]d]d: does[if n > 0[b: t b]]d
m: absolute n sort/compare b func[x y][x/(m) < y/(m)]d b]

Try it online!
Explanation:
f: func [ b n ] [
    t: func [ a ] [                            ; helper transpose function
        c: length? a/1                         ; c is the length of the rows
        a: to-block form a                     ; flatten the list
        d: copy []                             ; an empty block (list)
        loop c [                               ; do as many times as the number of columns
            append/only d extract a c          ; extract each c-th element (an entire column)
                                               ; and append it as a sublist to d
            take a                             ; drop the first element
        ]
        d                                      ; return the transposed block (list of lists)
    ]
   d: does [ if n > 0 [ b: t b ] ]             ; a helper function (parameterless) to transpose
                                               ; the array if positive n
   d                                           ; call the function
   m: absolute n                               ; absolute n
   sort/compare b func[ x y ] [ x/(m) < y/(m) ]; sort the array according to the chosen column
   d                                           ; transpose if positive n
   b                                           ; return the array
]

My actual solution is 175 bytes long, but it doesn't work in TIO. Here it is, working normalyl in the Red console:
Red, 175 bytes
func[b n][d: does[if n > 0[c: length? b/1 a: to-block form b
t: copy[]loop c[append/only t extract a c take a]b: t]]d
m: absolute n sort/compare b func[x y][x/(m) < y/(m)]d b]

Kotlin, 192 bytes
{m:Array<Array<Int>>,s:Int->if(s<0){m.sortBy{it[-s-1]}}else{val a=Array(m[0].size){c->Array(m.size){m[it][c]}}
a.sortBy{it[s-1]}
(0..m.size-1).map{r->(0..m[0].size-1).map{m[r][it]=a[it][r]}}}}

Try it online!

Ruby, 69 bytes
->a,n{f=->x{[0,x.transpose,x][n<=>0]};f[f[a].sort_by{|x|x[n.abs-1]}]}

Try it online!

VBA (Excel), 205 bytes
Yay! 2nd longest byte count! I didn't completely lose :D
Golfed:
Sub d(a)
With ActiveSheet.Sort
  .SortFields.Clear
  .SortFields.Add Key:=IIf(a<0,ActiveSheet.Columns(Abs(a)),ActiveSheet.Rows(Abs(a)))
  .SetRange ActiveSheet.UsedRange
  .Orientation=IIf(a<0,1,2)
  .Apply
End With
End Sub

This sorts all the data on the open (active) worksheet using UsedRange... which can be buggy, but should only contain cells that have been edited.
UnGolfed:
Sub d(a)
  'Clear any Sort preferences that already exists
  ActiveSheet.Sort.SortFields.Clear
  'Use the column if A is negative, the row if A is positive
  ActiveSheet.Sort.SortFields.Add Key:=IIf(a < 0, ActiveSheet.Columns(Abs(a)), ActiveSheet.Rows(Abs(a)))
  'Set the area to sort
  ActiveSheet.Sort.SetRange ActiveSheet.UsedRange
  'Orient sideways if sorting by row, vertical if by column
  ActiveSheet.Sort.Orientation = IIf(a < 0, xlTopToBottom, xlLeftToRight)
  'Actually sort it now
  ActiveSheet.Sort.Apply
End Sub

If you assume that the activesheet is sheet1, then you can get this down to 169 bytes as Sub d(a)
With Sheet1.Sort
.SortFields.Clear
.SortFields.Add IIf(a<0,Columns(Abs(a)),Rows(Abs(a)))
.SetRange Sheet1.UsedRange
.Orientation=(a<0)+2
.Apply
End With
End Sub

Also, I think that you can safely assume that there are no .SortFields Defined so you can remove the .Sortfields.Clear line as well.

Perl 6, 43 bytes
{($!=$_>0??&[Z]!!*[])o*.sort(*[.abs-1])o$!}

Try it online!
Curried function.
Explanation
{                                         } # Block returning function composed of
                                       o$!  # 1. Apply $! (transpose or not)
                     o*.sort(*[.abs-1])     # 2. Sort rows by column abs(i)-1
     $_>0??&[Z]                             # 3. If i > 0 transpose matrix
               !!*[]                        #    Else identity function
 ($!=               )                       #    Store in $!

Physica, 45 bytes
Very similar to Arnauld's JS answer.
F=>n;m:n<0&&Sort[->u:u{~n};m]||Zip@F#Zip@m#-n

Try it online!
How it works?
A more elaborate and visual explanation can be found in the linked answer.
F=>n;m:           // Create a function F that takes two arguments, n and m.
       n<0&&      // If n < 0 (i.e. is negative)
Sort[->u{~n};m]   // Sort the rows u of m by the result of the function u[~n].
                  // In short, sort by indexing from the end with n.
||    F#Zip@m#-n  // Else, apply F to Zip[m] and -n. Uses a new feature, binding.
  Zip@            // And transpose the result.

J, 32 bytes
f=.[/:({"1~<:)
g=.(f&.|:|)`f@.(0<])

Try it online!
Note: The g=. of the main verb doesn't count.
An explicit version for the same bytes
J, 32 bytes
4 :'y(]/:{"1)&.(|:^:(x<0))~<:|x'

Try it online!

Clojure, 91 bytes
(fn f[A i](if(< i 0)(sort-by #(nth %(- -1 i))A)(apply map list(f(apply map list A)(- i)))))

Argh, apply map list * 2.

source: Stack Exchange

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

sort: votes


text:
Let's play some Reaper - Closed for Submissions
NOTE: The winner of this competition is Jack!!!. No more submissions will be accepted.
Here is the chat room for this king-of-the-hill challenge. This is my first one so I'm open to suggestions!
Reaper is a game concept developed by the Art of Problem Solving which involves patience and greed. After modifying the game to fit a KOTH style contest (Thanks to @NathanMerrill and @dzaima for your suggestions and improvements), here is the challenge.
The game works as the following: we have a value known as the Reap that multiplies by a given constant every tick. After each tick, each bot has the option of "reaping", which means adding the current value of Reap to one's score, and reducing Reap down to 1.
However, there's a fixed number of ticks that a bot must wait in between "reaps", and a fixed number of points necessary to win the game.
Simple enough? Here are your inputs:
I/O
You are to write a function in Python 3 that takes 3 inputs. The first is self, used for referencing class objects (shown later). The second is the Reap, the current value of the Reap that you would earn if you were to "reap". The third is prevReap, a list of the bots that reaped during the previous tick.
Other objects you can access in your function:
self.obj: An object for your use to store information between ticks.
self.mult: The multiplier that Reap is multiplied by each tick
self.win: The score you need to win
self.points: Your current set of points
self.waittime: The amount of ticks that you must wait between reaps during the game
self.time: The number of ticks since your last reap
self.lenBots: The number of bots (including you) in the game.
self.getRandom(): Use to produce a random number between 0 and 1.

You MUST not edit any of the contents of these objects, except for self.obj.
You must output 1 to reap, and anything else (or nothing) to not reap. Note that if you reap when you haven't waited enough ticks, I'll ignore the fact that you have chosen to reap.
Rules
The parameters I will be using are winning_score=10000, multiplier=1.6-(1.2/(1+sqrt(x))), waittime = floor(1.5*x) where x is the number of bots in the KOTH.

The game ends when a player (or multiple) reach the winning score.
When multiple bots ask to reap at once, priority is given to the bots who have waited longer(in case of ties, the bots that have waited the max time all are allowed to reap and gain the points in the Reap)
Your bot must take no more than 100 ms on average across 5 ticks.
If you want to import libraries, ask! I'll try to add any libraries that I can run on my desktop version of Python (math is already imported: feel free to use it)
All of the standard loopholes for KoTHs, such as duplicate bots, 1-up bots, etc, are similarly banned.
Any bots that use any sort of randomness must use the getRandom function I've provided.

You can find the controller in the TIO link below. To use it, add the name of your function to BotList as a string, and then add the function to the code. Modify multiplier to change what the Reap is multiplied by each tick, modify winning_score to change what score is necessary to end the game, and modify waittime to change the number of ticks to wait between reaps.
For your convenience, here are some sample (and rather silly) bots. Submitting bots similar to these will not be permitted. However, they demonstrate how the controller works.
def Greedybot(self,Reap, prevReap):
    return 1
def Randombot(self,Reap, prevReap):
    if self.obj == None:
        self.obj=[]
    self.obj.append(prevReap)
    if self.getRandom()>0.5:
        return 1

For those interested, here is the Controller with the 15 submissions built into it: Try it Online
FINAL RESULTS
WOO THEY ARE FINALLY HERE! Check the TIO Link above to see what code I used to generate the final standings. The results are not terribly interesting. Over the 1000 runs I did with different random seeds, the results were
1000 wins - Jack
0 wins - everyone else

Congratulations to the Bounty winner Jack!! (aka @Renzeee)

Let's say two bots reap at the same time, and the one with the longest waiting time wins. Will the other bot also have its waiting time enabled despite that it wasn't able to actually reap this round, basically wasting its 'reap'? And what happens when two bots reap at the same time, with the same waiting time?

Ignore the second question, I see in this part of the code: waitmax = max([i.time for i in Reapers])  SuccReaps = [i for i in Reapers if i.time==waitmax]  for i in SuccReaps:  i.time=0  i.points+=self.Reap that the max waiting time is determined and all bots will get the point equal to this max. So if both bots with the exact same max waiting time reap at the same time, both will get the same reap.

If there's a greedy bot, the pot is never going to grow past multiplier^waittime.

Just to verify: all bots will play at the same time, so the x (amount of bots in play) depends on the amount of answers given (+2 for your two example bots)?

@Omegastick as I said, that bot will not be permitted. that would ruin the fun, no?

@KevinCruijssen That's correct!

It is allowed to use len(BotList)?

@Renzeee Ooo didn't think about that! I'll make a quick modification.

@Renzeee Oh, that's certainly something useful to consider. Might make a second bot similar to my Every 50, but with actual calculations in the bot itself, instead of what I did in my description based on 25 bots in play. Will first wait a bit too see other people's bots however. Rushabh Mehta, will there be a deadline / final date when all the bots will be run and a winner is determined?

Haven't set one yet.  Prob 1-2 weeks then I'll close this competition

Is it okay to read other bots' waittime and points vairables?

@Triggernometry that's a definite no

@Triggernometry I don't even think it's possible? But please don't even try to.  It's simply not allowed

@Rushabh Mehta Gotcha, I'll refrain. I just asked b/c I was independently tracking other bots' scores and waittimes in order to snipe them, and I am lazy. :)

It really bugs me that you don't follow PEP. eg. lenBots instead of len_bots and prevReap instead of prev_reap, many more

@Quintec didn't realize that's a thing.  Oops

@RushabhMehta I'm not sure what the rules are regarding changing bots, but I have changed my bot to perform better. It will now outperform each bot, but maybe changing the bot to outperform the current set of bots is illegal? I don't know. If so, then I can change it back to the original.

@Renzeee I have no objection to bot changes! As long as its before I deem the competition closed (which I haven't yet)

Request: obj is initalized as {}.

@Blacksilver Right now, it's initialized as a blank object (i.e.,class Obj: pass;self.obj=Obj()). You can easily add a dictionary/set by something like if not hasattr(self.obj,'reap'):self.obj.reap={}

in that case, the code in the post is wrong; it shows it initialized as None.

@Blacksilver That is correct, I will fix that. I would recommend checking out the code in the TIO link, that's up to date

@RushabhMehta I feel like we should be able to see other bots scores, just like in a real game of reaper. (Totally not asking just because I'm too lazy to code it ;p)

@Quintec hmm alright, I'll add it later (kinda out rn)

(FYI: TIO link is missing some bots, and you forgot to change 0.5 to 0.2 in the mess bot.)

@Quintec Thank you for pointing that out! I'll fix both of those things when I'm back from work!

Will prevReap only contain the successful Reaps? So if a bot is still in its waiting time but returns 1 regardless, it won't be in the prevReap list, right?

@KevinCruijssen That's correct

@RushabhMehta tio and bots still not updated...

@Quintec Since I've received a lot of bot update requests, I intend on doing them tomorrow after I close the competition. Feel free to edit your bots till then.

Indecisive Twitchy Mess
def mess(self, Reap, prevReap):
    if not hasattr(self.obj, "start"):
            self.obj.start = False
    if self.time < self.waittime:
        return 0
    if self.points + Reap >= self.win:
            return 1
    if Reap >= self.waittime / (self.lenBots + 2):
        self.obj.start = True
    if self.obj.start:
        return 1 if self.getRandom() > 0.2 else 0
    return 1 if self.getRandom() > 0.8 else 0

This bot does the usual checks first(Can I reap, can I win?) and then looks for a target value before it reaps. However, it's indecisive, so after it reaches the target, it wonders how much longer it can wait and doesn't reap immediately. In addition, it's twitchy, so it might accidentally "hit the button" and reap before the target.
Fun fact: This is basically how I play reaper as a human.

Nice bot +1. I'll take a closer look at it in a bit.  Join the chat if u haven't already

@RushabhMehta Now with less indecision ;p

I'll add your changes when I can!

Sniper
A bot fueled by spite. Keeps track of opponent's cooldowns and scores. Attempts to keep others from winning. Pretty much never actually wins, but makes the game frustrating to play for others.
EDIT:

If reaping would cause it to win, reap.
If no one is >= 70% of the winning score:

If everyone else is on their cooldown, wait until the last possible moment to reap.
If anyone else would win by reaping the current value, and they are active now or would be active next turn, reap.
If at least half of the other users are on their cooldown, attempt to reap. This makes it difficult to target specific opponents, and so was removed.
Otherwise, reap 25% of the time (essentially to guarantee that this bot does reap SOMETIMES, just in case something weird happens, like everyone is waiting several turns).

If someone IS >= 70% of the winning score:

If Sniper can win a tiebreaker, and next round would be above the average Reap value for the highest scoring opponent, reap
If highest scoring opponent will leave their cooldown next turn, reap.

def Sniper(self, Reap, prevReap):
    # initialize opponents array
    if not hasattr(self.obj, "opponents"):
        self.obj.opponents = {}

    # initialize previous Reap value
    if not hasattr(self.obj, "lastReap"):
        self.obj.lastReap = 0

    # increment all stored wait times to see who will be "active" this turn
    for opponent in self.obj.opponents:
        self.obj.opponents[opponent]["time"] += 1

    # update opponents array
    for opponent in prevReap:
        # don't track yourself, since you're not an opponent
        if opponent != "Sniper":
            # initialize opponent
            if opponent not in self.obj.opponents:
                self.obj.opponents[opponent] = {"time": 0, "points": 0, "num_reaps": 0, "avg": 0}
            self.obj.opponents[opponent]["time"] = 0
            self.obj.opponents[opponent]["points"] += self.obj.lastReap
            self.obj.opponents[opponent]["num_reaps"] += 1
            self.obj.opponents[opponent]["avg"] = self.obj.opponents[opponent]["points"] / self.obj.opponents[opponent]["num_reaps"]

    # done "assigning" points for last round, update lastReap
    self.obj.lastReap = Reap

    # get current 1st place(s) (excluding yourself)
    winner = "" if len(self.obj.opponents) == 0 else max(self.obj.opponents, key=lambda opponent:self.obj.opponents[opponent]["points"])

    # you are ready now
    if self.time >= self.waittime:
        # current Reap is sufficient for you to win
        if self.points + Reap >= self.win:
            return 1

        if (
                # a 1st place exists
                winner != ''
                # if current 1st place is close to winning
                and self.obj.opponents[winner]["points"] / self.win >= .7
        ):
            if (
                    # next round's Reap value will be above opponent's average Reap
                    (Reap * self.mult >= self.obj.opponents[winner]["avg"])
                    # we have been waiting at least as long as our opponent (tiebreaker)
                    and self.time >= self.obj.opponents[winner]["time"]
            ):
                return 1

                # current 1st place opponent will be active next round
            if self.obj.opponents[winner]["time"] + 1 >= self.waittime:
                return 1

        else:
            if (
                    # everyone is waiting for their cooldown
                    all(values["time"] < self.waittime for key, values in self.obj.opponents.items())
                    # and we're tracking ALL opponents
                    and len(self.obj.opponents) == self.lenBots - 1
                    # at least one person will be ready next turn
                    and any(values["time"] + 1 >= self.waittime for key, values in self.obj.opponents.items())
            ):
                return 1

            if (
                    # opponent will be active next round
                    any( (values["time"] + 1 >= self.waittime)
                         # current Reap value would allow opponent to win
                         and (values["points"] + Reap >= self.win) for key, values in self.obj.opponents.items())
            ):
                return 1

            if (
                    # a 1st place exists
                    winner != ''
                    # current 1st place opponent will be active next round
                    and (self.obj.opponents[winner]["time"] + 1 >= self.waittime)
                    # next round's Reap value will be above their average Reap
                    and (Reap * self.mult >= self.obj.opponents[winner]["avg"])

            ):
                return 1

            # # at least half of opponents are waiting for their cooldown
            # if sum(values["time"] < self.waittime for key, values in self.obj.opponents.items()) >= (self.lenBots - 1) / 2:
            #     return 1

            # 25% of the time
            if self.getRandom() <= .25:
                return 1

    # default return: do not snipe
    return 0

Bored
Just for fun, this bot was brought along by a friend and doesn't actually want to be here. They roll a d16 until they get a number in 1-9, then they attempt to reap anytime a number contains the chosen digit. (Going to look for a d10 would disrupt the game, which is rude, and 0 is just too easy!)
def Bored(self, Reap, prevReap):
    # if this is the first round, determine your fav number
    if not hasattr(self.obj, "fav_int"):
        r = 0

        while r == 0:
            # 4 bits are required to code 1-9 (0b1001)
            for i in range(0, 4):
                # flip a coin. Puts a 1 in this bit place 50% of the time
                if self.getRandom() >= .50:
                    r += 2**i
            # if your random bit assigning has produced a number outside the range 1-9, try again
            if not (0 < r < 10):
                r = 0

        self.obj.fav_int = r

    # you are ready now
    if self.time >= self.waittime:
        # current Reap is sufficient for you to win
        if self.points + Reap >= self.win:
            return 1
        # do you like this value?
        if str(self.obj.fav_int) in str(Reap):
            return 1
        # do you like your wait time?
        if self.time % int(self.obj.fav_int) == 0:
            return 1

    # default return: do not reap
    return 0

Nice bot! +1. It'll be interesting to see how this does.

I think you should use self.obj.opponents[opponent]["time"] += 1 in the first for-loop and self.obj.lastReap at the end of the second for-loop. Besides that, nice ideas. I'm curious how it would work out against a lot of other bots. When I'm using a lot of greedy and random bots it will just reap asap because most of the time half of the bots cannot reap. But of course those are not realistic competitors.

@Triggernometry You should join the chat. Also, check the edits I've posted. Please ensure that the changes I made to your bot are correct.

Jack
This is a simple bot with 4 rules:

Don't reap when it doesn't do anything
Always reap when reaping lets us win
Also reap when there has not been reaped for 3 ticks
Otherwise do nothing

I have optimized the 3 ticks versus the current existing bots (Sniper, grim_reaper, Every50, mess, BetterRandom, Averager, some more).
def Jack(self, Reap, prevReap):
    if self.time < self.waittime:
        return 0
    if self.win - self.points < Reap:
        return 1
    if self.mult ** 3 <= Reap:
        return 1
    return 0

I have tried to stay with my old solution (5 ticks) but also reap if you haven't reap for longer than X ticks, and then reap after fewer ticks have been passed during non-reaping (i.e. 5, if waited longer than self.waittime + 5, also reap if not been reaped for 4 ticks). But this didn't improve just always reaping after 4 ticks instead of 5.

Every 50
This bots will reap every time the Reap amount is above 50.
Why 50?
If I make the assumption there will be 25 bots in play, it means the multiplier = 1.6-(1.2/(1+sqrt(25))) = 1.4 and the waittime = floor(1.5*25) = 37. Since the Reap starts at 1, it will go up like this:
Round: 1  2    3     4      5      6      7      8       9       10      11      12      13      14      15       16       17       18       19       20       etc.
Reap:  1  1.4  1.96  2.744  ~3.84  ~5.39  ~7.53  ~10.54  ~14.76  ~20.66  ~28.92  ~40.50  ~56.69  ~79.37  ~111.12  ~155.57  ~217.79  ~304.91  ~426.88  ~597.63  etc.

As you can see, it reaches above 50 after 13 ticks. Since the Reap will reset to 1 every time a bot reaps, and the waittime for a bot that reaps is 37, the likelihood a bot reaps sooner than later is pretty high, especially with bots similar to the example GreedyBot, which will reap as soon as their waittime is available again. At first I wanted to do 200 which is the 17th tick, somewhat in the middle of the 37 waiting time ticks, but with the assumption there are 25 bots in play there is a pretty high chance someone else snatches the Reap before me. So I lowered it to 50. It's still a nice rounded number, but especially because it's the 13th tick (with 25 bots), and 13 and 'reaping' also fit a bit in that same 'evil' genre.
Code:
The code is laughable trivial..
def Every50(self, Reap, prevReap):
  return int(Reap > 50)

Notes:
This bot is pretty bad with low amount of bots in play. For now I will leave it, and I might make a better bot actually calculating the best time to Reap. With an extremely low amount of bots in play the waittime is much lower as well of course, so even GreedyBot might win quite easily from this bot if the waittime is low enough.
Hopefully more people will add a lot more bots. ;p

def Every49(self, Reap, prevReap):   return Reap > 49
Your move.

@Quintec Hehe. With 25 bots in play it would mean it's still the 13th tick and we both win the Reap, so I don't mind sharing the victory with you, lol. ;p

You might want to put int around the inequality, since 1 is the real command

@Quintec i'm aware ur kidding,  but I won't allow 1-up or duplicate bots

@RushabhMehta I don't program in Python very often, so was indeed already doubting whether I should add the cast to make the True an explicit 1. Figured the True == 1 check would still return True for my bot adding it to the lists of Reapers in your next function, but I added the cast to int anyway as you suggested.

Averager
def Averager(self,Reap,prevReap):
    returner = 0
    if not hasattr(self.obj,"last"):
        self.obj.last = Reap
        self.obj.total = 0
        self.obj.count = 0
        returner = 1
    else:
        if len(prevReap) > 0:
            self.obj.total += self.obj.last
            self.obj.count += 1
        self.obj.last = Reap
    if self.obj.count > 0 and Reap > self.obj.total / self.obj.count:
        returner = 1
    return returner

This bot tries to reap any time the current Reap value is above the average Reaped value.

Very Nice bot! +1

I'm both extremely annoyed and impressed that such a simple algorithm beats everyone so handily. Great job!

Grim Reaper
This bot keeps a running average of the values of all the previous reaps as well as the time each bot has been waiting.  It reaps when it has been waiting longer than 3/4 of the other bots and the reap is at least 3/4 the size of the average reap seen so far.  The goal is to grab a lot of reasonably sized, low risk reaps.
def grim_reaper(self, Reap, prevReap):
    if self.obj == None:
        self.obj = {}
        self.obj["reaps"] = []
        self.obj["prev"] = 1
        self.obj["players"] = {i:0 for i in range(math.ceil(self.waittime / 1.5))}
    if Reap == 1 and len(prevReap) > 0:
        self.obj["reaps"].append(self.obj["prev"])
        for player in prevReap:
            self.obj["players"][player] = 0

    retvalue = 0
    if (len(self.obj["reaps"]) > 0
         and Reap > sum(self.obj["reaps"]) / len(self.obj["reaps"]) * 3. / 4.
         and sum([self.time >= i for i in self.obj["players"].values()]) >= len(self.obj["players"].values()) * 3 / 4):
        retvalue = 1

    for player in self.obj["players"]:
        self.obj["players"][player] += 1
    self.obj["prev"] = Reap
    return retvalue

Edit: Fixed some embarrassing syntax errors.
Try it Online

You should use self.obj.reaps instead of self.reaps and self.obj instead of self.object and prevReap instead of prevLeap and add () after self.obj.players.values twice. And I think self.obj.reaps = [] won't work unless self.obj is an object. I'm not completely sure if everything then still works as intended and if all of what I said is true, but after these changes and using a dummy Object for self.obj when it doesn't exists yet, your code compiles for me.

@ZacharyColton You don't need to import math. It's already imported

@RushabhMehta I added class Object(object): [newline] pass on top and used self.obj = Object() in the if not hasattr(..) (if I remember correctly).

@Renzeee aha ic

@ZacharyCotton You should join chat.

BetterRandom
def BetterRandom(self,reap,prevReap):
    return self.getRandom()>(reap/self.mult**self.waittime)**-0.810192835

The bot is based on the assumption that the chance to reap should be proportional to the reap size because a point is a point, no matter when it's gotten. There is always a very small chance to reap, this keeps the behavior exploitable. First I thought it would be directly proportional and assumed the proportionality constant to be around 1/mult^waittime (the maximum reap assuming at least one bot plays greedy) after running some simulations I found that this was indeed the optimal constant. But the bot was still outperformed by Random so I concluded the relation wasn't directly proportional and added a constant to calculate what the relation was. After some simulations I found that against my test set of bots -1.5 was optimal. This actually corresponds to an inversely proportional relationship between the reap chance and reap*sqrt(reap) which is surprising. So I suspect this is highly depended on the specific bots so a version of this bot that calculates k while playing would be better. (But I don't know if you are allowed to use data from previous rounds).
EDIT: I made program to find the kind of proportionality automatically. On the test set ["myBot("+str(k)+")","Randombot","Greedybot","Every50","Jack","grim_reaper","Averager","mess"] I found the new value.

i'll add some new stats using your bot soon

It looks like (reap/self.mult**self.waittime)**-0.810192835 is always above 1, i.e. self.getRandom() is never higher.

@fejfo you also are allowed to use data from previous rounds. That's what self.obj is for. To see some examples on how to use it, look at some other bots that are using it.

Target
def target(self,Reap,prevReap):
    if not hasattr(self.obj, "target_time"):
        self.obj.target_time = -1
        self.obj.targeting = False
        self.obj.target = None
    if self.obj.target_time >= 0:
        self.obj.target_time += 1

    if self.time < self.waittime:
            return 0
    if self.points + Reap >= self.win:
        return 1
    if len(prevReap) > 0:
        if not self.obj.targeting:
            self.obj.target_time = 0
            self.obj.target = prevReap[int(self.getRandom() * len(prevReap))]
            self.obj.targeting = True
    if self.waittime <= self.obj.target_time + 1:
        self.obj.targeting = False
        self.obj.target = None
        self.obj.target_time = -1
        return 1
    return 0

My chances of winning with mess are almost none now, so time to mess up all the other bots in as many ways as possible! :)
This bot functions similar to sniper. Whenever someone reaps, it picks a random target from whoever reaped. Then, it simply waits until that target almost can reap again and snipes it. However, it doesn't change focus - once you've been chosen and locked on, you can't escape :)

Ongoing: My project to extend T4T to every open KOTH.
Tit for Tat
def t4t(self, r, p):
    if(not hasattr(self.obj,"last")): self.obj.last = self.win
    if(p):
        self.obj.last = r
        return 0

    # The usual checks
    if self.time < self.waittime:
        return 0
    if self.points + r >= self.win:
        return 1

    if(r >= self.obj.last):
        return 1

Tit for n Tats
def t4nt(self, r, p):
    n = 5 # Subject to change
    if(not hasattr(self.obj,"last")): self.obj.last = [self.win]*n

    if(p):
        self.obj.last.append(r)
        self.obj.last.pop(0)
        return 0

    # The usual checks
    if(self.time < self.waittime):
        return 0
    if(self.points + r >= self.win):
        return 1

    if(r >= self.obj.last[0]):
        return 1

Kevin
Just to keep you on your toes.
def kevin(just, a, joke):
    return 0

Make sure to remember, self.last isn't a thing, but you can make self.obj.last a thing!. Anyways, I'll add all three of your bots for the memes +1

Yep, I'm an idiot. Fixed.

@RushabhMehta Just went through and made them actually work. pls edit.

sounds good! Join the GC, I'll post some partial results there

EveryN
I guess it's time for my second bot right before the deadline.
This bot will:

Skip when it's still in its waiting time for the last Reap
Reap when it can win
Reap when no one reaped for at least n rounds, where n is calculated with n = 3 + ceil(self.waittime / self.lenBots)

Code:
def every_n(self, Reap, prevReap):
    # Initialize obj fields
    if not hasattr(self.obj, "roundsWithoutReaps"):
        self.obj.roundsWithoutReaps = 0

    # Increase the roundsWithoutReaps if no bots reaped last round
    if len(prevReap) < 1:
        self.obj.roundsWithoutReaps += 1
    else
        self.obj.roundsWithoutReaps = 0

    # Skip if you're still in your waiting time
    if self.time < self.waittime:
        return 0
    # Reap if you can win
    if self.win - self.points < Reap:
        return 1

    # i.e. 25 bots: 3 + ceil(37 / 25) = 5
    n = 3 + math.ceil(self.waittime / self.lenBots)

    # Only reap when no bots have reaped for at least `n` rounds
    if self.obj.roundsWithoutReaps >= n:
        self.obj.roundsWithoutReaps = 0
        return 1

    return 0

I don't program in Python very often, so if you see any mistakes let me know.

Holy long variable name. (Also, PEP: https://www.python.org/dev/peps/pep-0008)

@Quintec Changed the 2-space indentation to 4; shortened the subsequentRoundsWithoutReaps to roundsWithoutReaps; used lowercase with underscores for the method name; and removed the parenthesis at the if-statements. Thanks.

No problem! (Technically it should be rounds_without_reaps, but that’s not really an issue since this challenge also uses mixedCamelCase so it doesn’t really matter)

@Quintec Ah ok. I looked at the prevReap and lenBots and such and assumed variables are camelCase like in Java. ;) Ah well, whatever case we use, it should work anyway. The 2 instead of 4 indented spaces would probably have caused some problems though, so thanks either way.

Average Joe
I got inspired by Averager and created a bot which calculates on average how many turns it takes before someone reaps and tries to reap one turn prior to that.
def average_joe(self, Reap, prevReap):

    if not hasattr(self.obj, "average_turns"):
        self.obj.turns_since_reap = 1
        self.obj.total_turns = 0
        self.obj.total_reaps = 0
        return 1

    if len(prevReap) > 0:
        self.obj.total_turns = self.obj.total_turns + self.obj.turns_since_reap
        self.obj.total_reaps += 1
        self.obj.turns_since_reap = 0
    else:
        self.obj.turns_since_reap += 1

    # Don't reap if you are in cooldown
    if self.time < self.waittime:
        return 0

    # Reap if you are going to win
    if self.win - self.points < Reap:
        return 1

    # Reap if it is one turn before average
    average_turns = self.obj.total_turns / self.obj.total_reaps

    if average_turns - 1 >= self.obj.turns_since_reap:
        return 1
    else:
        return 0

I'll add this in tomorrow.

HardCoded
Yes, it is.
def HardCo(self,reap,prevReap):
    return reap > 2

Instead of averaging on the past reaps, use a pre-calculated average on a typical run. It's not going to get better with time anyway.

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