text:
Golf my "pre-golfed" C
Background
For my code-golf submissions in C, I need a processing tool. Like in many other languages, whitespace is mostly irrelevant in C source (but not always!) -- still makes the code much more comprehensible for humans. A fully golfed C program that doesn't contain a single redundant whitespace often is barely readable.
Therefore, I like to write my code in C for a code-golf submission including whitespace and sometimes comments, so the program keeps a comprehensible structure while writing. The last step is to remove all comments and redundant whitespace. This is a tedious and mindless task which really should be done by an intern a computer program.
Task
Write a program or function that eliminates comments and redundant whitespace from some "pre-golfed" C source according to the following rules:

A \ (backslash) as the very last character in a line is a line continuation. If you find this, you must treat the following line as part of the same logical line (you could for example remove the \ and the following \n (newline) completely before doing anything else)
Comments will only use the one-line format, starting with //. So to remove them, you ignore the rest of the logical line wherever you encounter // outside a string literal (see below).
Whitespace characters are  (space), \t (tab) and \n (newline, so here the end of a logical line).
When you find a sequence of whitespace, examine the non-whitespace characters surrounding it. If

both of them are alphanumeric or underscore (range [a-zA-Z0-9_]) or
both are + or
both are - or
the preceeding one is / and the following one is *

then replace the sequence with a single space () character.
Otherwise, eliminate the sequence completely.
This rule has some exceptions:

Preprocessor directives must appear on their own lines in your output. A preprocessor directive is a line starting with #.
Inside a string literal or character literal, you shouldn't remove any whitespace.  Any " (double-quote) / ' (single-quote) that isn't directly preceeded by an odd number of backslashes (\) starts or ends a string literal / character literal. You're guaranteed that string and character literals end on the same line they started. string literals and character literals cannot be nested, so a ' inside a string literal, as well as a " inside a character literal don't have any special meaning.

I/O specification
Input and output must be either character sequences (strings) including newline characters or arrays/lists of strings that don't contain newline characters. If you choose to use arrays/lists, each element represents a line, so the newlines are implicit after each element.
You may assume the input is a valid C program source code. This also means it only contains printable ASCII characters, tabs and newlines. Undefined behavior on malformed input is allowed.
Leading and trailing whitespace / empty lines are not allowed.
Test cases

input
main() {
    printf("Hello, World!"); // hi
}

output
main(){printf("Hello, World!");}

input
#define max(x, y) \
    x > y ? x : y
#define I(x) scanf("%d", &x)
a;
b; // just a needless comment, \
        because we can!
main()
{
    I(a);
    I(b);
    printf("\" max \": %d\n", max(a, b));
}

output
#define max(x,y)x>y?x:y
#define I(x)scanf("%d",&x)
a;b;main(){I(a);I(b);printf("\" max \": %d\n",max(a,b));}

input
x[10];*c;i;
main()
{
    int _e;
    for(; scanf("%d", &x) > 0 && ++_e;);
    for(c = x + _e; c --> x; i = 100 / *x, printf("%d ", i - --_e));
}

output
x[10];*c;i;main(){int _e;for(;scanf("%d",&x)>0&&++_e;);for(c=x+_e;c-->x;i=100/ *x,printf("%d ",i- --_e));}

input
x;
#include <stdio.h>
int main()
{
    puts("hello // there");
}

output
x;
#include<stdio.h>
int main(){puts("hello // there");}

input (a real-world example)
// often used functions/keywords:
#define P printf(
#define A case
#define B break

// loops for copying rows upwards/downwards are similar -> macro
#define L(i, e, t, f, s) \
        for (o=i; o e;){ strcpy(l[o t], l[o f]); c[o t]=c[s o]; }

// range check for rows/columns is similar -> macro
#define R(m,o) { return b<1|b>m ? m o : b; }

// checking for numerical input is needed twice (move and print command):
#define N(f) sscanf(f, "%d,%d", &i, &j) || sscanf(f, ",%d", &j)

// room for 999 rows with each 999 cols (not specified, should be enough)
// also declare "current line pointers" (*L for data, *C for line length),
// an input buffer (a) and scratch variables
r, i, j, o, z, c[999], *C, x=1, y=1;
char a[999], l[999][999], (*L)[999];

// move rows down from current cursor position
D()
{
    L(r, >y, , -1, --)
    r++ ? strcpy(l[o], l[o-1]+--x), c[o-1]=x, l[o-1][x]=0 : 0;
    c[y++] = strlen(l[o]);
    x=1;
}

// move rows up, appending uppermost to current line
U()
{
    strcat(*L, l[y]);
    *C = strlen(*L);
    L(y+1, <r, -1, , ++)
    --r;
    *l[r] = c[r] = 0;
}

// normalize positions, treat 0 as max
X(b) R(c[y-1], +1)
Y(b) R(r, )

main()
{
    for(;;) // forever
    {
        // initialize z as current line index, the current line pointers,
        // i and j for default values of positioning
        z = i = y;
        L = l + --z;
        C = c + z;
        j = x;

        // prompt:
        !r || y/r && x > *C
            ? P "end> ")
            : P "%d,%d> ", y, x);

        // read a line of input (using scanf so we don't need an include)
        scanf("%[^\n]%*c", a)

            // no command arguments -> make check easier:
            ? a[2] *= !!a[1],

            // numerical input -> have move command:
            // calculate new coordinates, checking for "relative"
            N(a)
                ? y = Y(i + (i<0 | *a=='+') * y)
                    , x = X(j + (j<0 || strchr(a+1, '+')) * x)
                :0

            // check for empty input, read single newline
            // and perform <return> command:
            : ( *a = D(), scanf("%*c") );

        switch(*a)
        {
            A 'e':
                y = r;
                x = c[r-1] + 1;
                B;

            A 'b':
                y = 1;
                x = 1;
                B;

            A 'L':
                for(o = y-4; ++o < y+2;)
                    o<0 ^ o<r && P "%c%s\n", o^z ? ' ' : '>', l[o]);
                for(o = x+1; --o;)
                    P " ");
                P "^\n");
                B;

            A 'l':
                puts(*L);
                B;

            A 'p':
                i = 1;
                j = 0;
                N(a+2);
                for(o = Y(i)-1; o<Y(j); ++o)
                    puts(l[o]);
                B;

            A 'A':
                y = r++;
                strcpy(l[y], a+2);
                x = c[y] = strlen(a+2);
                ++x;
                ++y;
                B;

            A 'i':
                D();
                --y;
                x=X(0);
                // Commands i and r are very similar -> fall through
                // from i to r after moving rows down and setting
                // position at end of line:

            A 'r':
                strcpy(*L+x-1, a+2);
                *C = strlen(*L);
                x = 1;
                ++y > r && ++r;
                B;

            A 'I':
                o = strlen(a+2);
                memmove(*L+x+o-1, *L+x-1, *C-x+1);
                *C += o;
                memcpy(*L+x-1, a+2, o);
                x += o;
                B;

            A 'd':
                **L ? **L = *C = 0, x = 1 : U();
                y = y>r ? r : y;
                B;

            A 'j':
                y<r && U();
        }
    }
}

output
#define P printf(
#define A case
#define B break
#define L(i,e,t,f,s)for(o=i;o e;){strcpy(l[o t],l[o f]);c[o t]=c[s o];}
#define R(m,o){return b<1|b>m?m o:b;}
#define N(f)sscanf(f,"%d,%d",&i,&j)||sscanf(f,",%d",&j)
r,i,j,o,z,c[999],*C,x=1,y=1;char a[999],l[999][999],(*L)[999];D(){L(r,>y,,-1,--)r++?strcpy(l[o],l[o-1]+--x),c[o-1]=x,l[o-1][x]=0:0;c[y++]=strlen(l[o]);x=1;}U(){strcat(*L,l[y]);*C=strlen(*L);L(y+1,<r,-1,,++)--r;*l[r]=c[r]=0;}X(b)R(c[y-1],+1)Y(b)R(r,)main(){for(;;){z=i=y;L=l+--z;C=c+z;j=x;!r||y/r&&x>*C?P"end> "):P"%d,%d> ",y,x);scanf("%[^\n]%*c",a)?a[2]*=!!a[1],N(a)?y=Y(i+(i<0|*a=='+')*y),x=X(j+(j<0||strchr(a+1,'+'))*x):0:(*a=D(),scanf("%*c"));switch(*a){A'e':y=r;x=c[r-1]+1;B;A'b':y=1;x=1;B;A'L':for(o=y-4;++o<y+2;)o<0^o<r&&P"%c%s\n",o^z?' ':'>',l[o]);for(o=x+1;--o;)P" ");P"^\n");B;A'l':puts(*L);B;A'p':i=1;j=0;N(a+2);for(o=Y(i)-1;o<Y(j);++o)puts(l[o]);B;A'A':y=r++;strcpy(l[y],a+2);x=c[y]=strlen(a+2);++x;++y;B;A'i':D();--y;x=X(0);A'r':strcpy(*L+x-1,a+2);*C=strlen(*L);x=1;++y>r&&++r;B;A'I':o=strlen(a+2);memmove(*L+x+o-1,*L+x-1,*C-x+1);*C+=o;memcpy(*L+x-1,a+2,o);x+=o;B;A'd':**L?**L=*C=0,x=1:U();y=y>r?r:y;B;A'j':y<r&&U();}}}

This is code-golf, so shortest (in bytes) valid answer wins.

related, related

Let us continue this discussion in chat.

Pip, 148 135 133 138 bytes
aRM"\
"R`("|').*?(?<!\\)(\\\\)*\1`{lPBaC:++i+191}R[`//.*``#.*`{X*aJw.`(?=`}.')M[A`\w`RL2"++""--""/*"]w`¶+`'·C(192+,#l)][x_WR'¶{aRw'·}xnsl]

Bytes are counted in CP-1252, so ¶ and · are one byte each. Note that this expects the C code as a single command-line argument, which (on an actual command line) would require the use of copious escape sequences. It's much easier at Try it online!
Explanation of slightly ungolfed version
The code does a bunch of replacement operations, with a couple tricks.
Backslash continuations
We RM all occurrences of the literal string
"\
"

that is, backslash followed by newline.
String and character literals
We use a regex replacement with a callback function:
`("|').*?(?<!\\)(\\\\)*\1`

{
 lPBa
 C(++i + 191)
}

The regex matches a single or double quote, followed by a non-greedy .*? that matches 0 or more characters, as few as possible. We have a negative lookbehind to ensure that the previous character was not a backslash; then we match an even number of backslashes followed by the opening delimiter again.
The callback function takes the string/character literal and pushes it to the back of the list l. It then returns a character starting with character code 192 (À) and increasing with each literal replaced. Thus, code is transformed like so:
printf("%c", '\'');

printf(À, Á);

These replacement characters are guaranteed not to occur in the source code, which means we can unambiguously back-substitute them later.
Comments
`//.*`

x

The regex matches // plus everything up to the newline and replaces with x (preset to the empty string).
Preprocessor directives
`#.*`

_WR'¶

Wraps runs of non-newline characters starting with a pound sign in ¶.
Spaces that should not be eliminated
{
 (
  X*a J w.`(?=`
 ) . ')
}
M
[
 A`\w` RL 2
 "++"
 "--"
 "/*"
]

{
 a R w '·
}

There's a lot going on here. The first part generates this list of regexes to replace:
[
 `(?a)\w\s+(?=(?a)\w)`  Whitespace surrounded by [a-zA-Z_]
 `\+\s+(?=\+)`          Whitespace surrounded by +
 `\-\s+(?=\-)`          Whitespace surrounded by -
 `\/\s+(?=\*)`          Whitespace surrounded by / *
]

Note the use of lookaheads to match, for example, just the e  in define P printf. That way this match doesn't consume the P, which means the next match can use it.
We generate this list of regexes by mapping a function to a list, where the list contains
[
 [`(?a)\w` `(?a)\w`]
 "++"
 "--"
 "/*"
]

and the function does this to each element:
(X*aJw.`(?=`).')
 X*a              Map unary X to elements/chars a: converts to regex, escaping as needed
                  Regexes like `\w` stay unchanged; strings like "+" become `\+`
    J             Join the resulting list on:
     w             Preset variable for `\s+`
      .`(?=`       plus the beginning of the lookahead syntax
(           ).')  Concatenate the closing paren of the lookahead

Once we have our regexes, we replace their occurrences with this callback function:
{aRw'·}

which replaces the run of whitespace in each match with ·.
Whitespace elimination and cleanup
[w `¶+` '·]

[x n s]

Three successive replacements substitute remaining runs of whitespace (w) for empty string (x), runs of ¶ for newline, and · for space.
Back-substitution of string and character literals
C(192+,#l)

l

We construct a list of all the characters we used as substitutions for literals by taking 192 + range(len(l)) and converting to characters. We then can replace each of these with its associated literal in l.
And that's it! The resulting string is autoprinted.

Great, I'm impressed (+1)! Including a // inside a string literal is definitely a good idea for a test case, I'll add one tomorrow.

Uhm ... now I found a subtle bug here as well...

I'm going to pick a winner after 14 days (end of next week) and your solution would be the first candidate if you find time to fix this bug. Right now, you have the lowest score :)

@FelixPalmen Fixed!

Haskell, 327 360 418 394 bytes
g.(m.w.r.r=<<).lines.f
n:c:z="\n#_0123456789"++['A'..'Z']++['a'..'z']
(!)x=elem x
f('\\':'\n':a)=f a
f(a:b)=a:f b
f a=a
m('#':a)=c:a++[n]
m a=a
g(a:'#':b)=a:[n|a/=n]++c:g b
g(a:b)=a:g b
g a=a
s=span(!" \t")
r=reverse.snd.s
l n(a:b)d|a==d,n=a:w(snd$s b)|1>0=a:l(not$n&&a=='\\')b d
w('/':'/':_)=[]
w(a:b)|a!"\"'"=a:l(1>0)b a|(p,q:u)<-s b=a:[' '|p>"",a!z&&q!z||[a,q]!words"++ -- /*"]++w(q:u)
w a=a

Try it online!
This was a lot of fun to write! First the f function comes through and removes all the backslashes at the end of lines then lines breaks it into a list of strings at the newlines. Then we map a bunch of functions onto the lines and concatenate them all back together. Those functions: strip whitespace from the left (t) and from the right (r.t.r where r is reverse); remove whitespace from the middle, ignoring string and character literals as well as removing comments (w); and finally adds a newline character to the end if the line starts with a #. After all the lines are concatenated back together g looks for # characters and ensures they are preceded by a newline.
w is a little complex so I'll explain it further. First I check for "//" since in w I know I'm not in a string literal I know this is a comment so I drop the rest of the line. Next I check if the head is a delimiter for a string or character literal. If it is I prepend it and pass the baton to l which runs through the characters, tracking the "escape" state with n which will be true if there have been an even number of consecutive slashes. When l detects a delimiter and isn't in the escape state it passes the baton back to w, trimming to eliminate whitespace after the literal because w expects the first character to not be whitespace. When w doesn't find a delimiter it uses span to look for whitespace in the tail. If there's any it checks if the characters around it are cannot be brought into contact and inserts a space if so. Then it recurs after the whitespace is ended. If there was no whitespace no space is inserted and it moves on anyway.
EDIT: Thanks a lot to @DLosc for pointing out a bug in my program that actually led to a way for me to shorten it as well! Hooray for pattern matching!
EDIT2: I'm an idiot who didn't finish reading the spec! Thanks again DLosc for pointing that out!
EDIT3: Just noticed some annoying type reduction thing that turned e=elem into Char->[Char]->Bool for some reason, thus breaking on e[a,q]. I had to add a type signature to force it to be correct.  Does anyone know how I could fix that? I've never had this problem in Haskell before. TIO
EDIT4: quick fix for bug @FelixPalmen showed me. I might try to golf it down later when I have some time.
EDIT5: -24 bytes thanks to @Lynn! Thank you! I didn't know you could assign things on the global scope using pattern matching like n:c:z=... that's really cool! Also good idea making an operator for elem wish I'd thought of that.

I squeezed out 24 bytes.

You are running into the dreaded monomorphism restriction; defining e x y=elem x y (or even e x=elem x) solves your problem. (I renamed e to an operator, (!).)

C, 497 494 490 489 bytes
Since we're processing C, let's do it using C!  Function f() takes input from char pointer p and outputs to pointer q, and assumes that the input is in ASCII:
#define O*q++
#define R (r=*p++)
#define V(c)(isalnum(c)||c==95)
char*p,*q,r,s,t;d(){isspace(r)?g():r==47&&*p==r?c(),g():r==92?e():(O=s=r)==34?b():r==39?O=R,a():r?a():(O=r);}a(){R;d();}b(){((O=R)==34?a:r==92?O=R,b:b)();}c(){while(R-10)p+=r==92;}e(){R-10?s=O=92,O=r,a():h();}j(){(!isspace(R)?r==47&&*p==r?c(),j:(t=r==35,d):j)();}f(){t=*p==35;j();}i(){V(s)&&V(r)||s==47&&r==42||(s==43||s==45)&&r==s&&*p==s?O=32:0;d();}h(){isspace(R)?g():i();}g(){(r==10?t?O=r,j:*p==35?s-10?s=O=r,j:0:h:h)();}

We assume that the file is well-formed - string and character literals are closed, and if there's a comment on the final line, there must be a newline to close it.
Explanation
The pre-golfed version is only slightly more legible, I'm afraid:
#define O *q++=
#define R (r=*p++)
#define V(c)(isalnum(c)||c=='_')
char*p,*q,r,s,t;
d(){isspace(r)?g():r=='/'&&*p==r?c(),g():r=='\\'?e():(O s=r)=='"'?b():r=='\''?O R,a():r?a():(O r);}
a(){R;d();}
b(){((O R)=='"'?a:r=='\\'?O R,b:b)();}
c(){while(R!='\n')p+=r=='\\';}
e(){R!='\n'?s=O'\\',O r,a():h();}
j(){(!isspace(R)?r=='/'&&*p==r?c(),j:(t=r=='#',d):j)();}
f(){t=*p=='#';j();}
i(){V(s)&&V(r)||s=='/'&&r=='*'||(s=='+'||s=='-')&&r==s&&*p==s?O' ':0;d();}
h(){isspace(R)?g():i();}
g(){(r=='\n'?t?O r,j:*p=='#'?s!='\n'?s=O r,j:0:h:h)();}

It implements a state machine by tail recursion.  The helper macros and variables are

O for output
R to read input into r
V to determine valid identifier characters (since !isalnum('_'))
p and q - I/O pointers as described
r - last character to be read
s - saved recent non-whitespace character
t - tag when working on a preprocessor directive

Our states are

a() - normal C code
b() - string literal
c() - comment
d() - normal C code, after reading r
e() - escape sequence
f() - initial state (main function)
g() - in whitespace
h() - in whitespace - dispatch to g() or i()
i() - immediately after whitespace - do we need to insert a space character?
j() - initial whitespace - never insert a space character

Test program
#define DEMO(code)                              \
    do {                                        \
        char in[] = code;                       \
        char out[sizeof in];                    \
        p=in;q=out;f();                         \
        puts("vvvvvvvvvv");                     \
        puts(out);                              \
        puts("^^^^^^^^^^");                     \
    } while (0)

#include<stdio.h>
#include<stdlib.h>
int main()
{
    DEMO(
         "main() {\n"
         "    printf(\"Hello, World!\"); // hi\n"
         "}\n"
         );
    DEMO(
         "#define max(x, y)                               \\\n"
         "    x > y ? x : y\n"
         "#define I(x) scanf(\"%d\", &x)\n"
         "a;\n"
         "b; // just a needless comment, \\\n"
         "        because we can!\n"
         "main()\n"
         "{\n"
         "    I(a);\n"
         "    I(b);\n"
         "    printf(\"\\\" max \\\": %d\\n\", max(a, b));\n"
         "}\n"
         );
    DEMO(
         "x[10];*c;i;\n"
         "main()\n"
         "{\n"
         "    int _e;\n"
         "    for(; scanf(\"%d\", &x) > 0 && ++_e;);\n"
         "    for(c = x + _e; c --> x; i = 100 / *x, printf(\"%d \", i - --_e));\n"
         "}\n"
         );
    DEMO(
         "// often used functions/keywords:\n"
         "#define P printf(\n"
         "#define A case\n"
         "#define B break\n"
         "\n"
         "// loops for copying rows upwards/downwards are similar -> macro\n"
         "#define L(i, e, t, f, s) \\\n"
         "        for (o=i; o e;){ strcpy(l[o t], l[o f]); c[o t]=c[s o]; }\n"
         "\n"
         "// range check for rows/columns is similar -> macro\n"
         "#define R(m,o) { return b<1|b>m ? m o : b; }\n"
         "\n"
         "// checking for numerical input is needed twice (move and print command):\n"
         "#define N(f) sscanf(f, \"%d,%d\", &i, &j) || sscanf(f, \",%d\", &j)\n"
         "\n"
         "// room for 999 rows with each 999 cols (not specified, should be enough)\n"
         "// also declare \"current line pointers\" (*L for data, *C for line length),\n"
         "// an input buffer (a) and scratch variables\n"
         "r, i, j, o, z, c[999], *C, x=1, y=1;\n"
         "char a[999], l[999][999], (*L)[999];\n"
         "\n"
         "// move rows down from current cursor position\n"
         "D()\n"
         "{\n"
         "    L(r, >y, , -1, --)\n"
         "    r++ ? strcpy(l[o], l[o-1]+--x), c[o-1]=x, l[o-1][x]=0 : 0;\n"
         "    c[y++] = strlen(l[o]);\n"
         "    x=1;\n"
         "}\n"
         "\n"
         "// move rows up, appending uppermost to current line\n"
         "U()\n"
         "{\n"
         "    strcat(*L, l[y]);\n"
         "    *C = strlen(*L);\n"
         "    L(y+1, <r, -1, , ++)\n"
         "    --r;\n"
         "    *l[r] = c[r] = 0;\n"
         "}\n"
         "\n"
         "// normalize positions, treat 0 as max\n"
         "X(b) R(c[y-1], +1)\n"
         "Y(b) R(r, )\n"
         "\n"
         "main()\n"
         "{\n"
         "    for(;;) // forever\n"
         "    {\n"
         "        // initialize z as current line index, the current line pointers,\n"
         "        // i and j for default values of positioning\n"
         "        z = i = y;\n"
         "        L = l + --z;\n"
         "        C = c + z;\n"
         "        j = x;\n"
         "\n"
         "        // prompt:\n"
         "        !r || y/r && x > *C\n"
         "            ? P \"end> \")\n"
         "            : P \"%d,%d> \", y, x);\n"
         "\n"
         "        // read a line of input (using scanf so we don't need an include)\n"
         "        scanf(\"%[^\\n]%*c\", a)\n"
         "\n"
         "            // no command arguments -> make check easier:\n"
         "            ? a[2] *= !!a[1],\n"
         "\n"
         "            // numerical input -> have move command:\n"
         "            // calculate new coordinates, checking for \"relative\"\n"
         "            N(a)\n"
         "                ? y = Y(i + (i<0 | *a=='+') * y)\n"
         "                    , x = X(j + (j<0 || strchr(a+1, '+')) * x)\n"
         "                :0\n"
         "\n"
         "            // check for empty input, read single newline\n"
         "            // and perform <return> command:\n"
         "            : ( *a = D(), scanf(\"%*c\") );\n"
         "\n"
         "        switch(*a)\n"
         "        {\n"
         "            A 'e':\n"
         "                y = r;\n"
         "                x = c[r-1] + 1;\n"
         "                B;\n"
         "\n"
         "            A 'b':\n"
         "                y = 1;\n"
         "                x = 1;\n"
         "                B;\n"
         "\n"
         "            A 'L':\n"
         "                for(o = y-4; ++o < y+2;)\n"
         "                    o<0 ^ o<r && P \"%c%s\\n\", o^z ? ' ' : '>', l[o]);\n"
         "                for(o = x+1; --o;)\n"
         "                    P \" \");\n"
         "                P \"^\\n\");\n"
         "                B;\n"
         "\n"
         "            A 'l':\n"
         "                puts(*L);\n"
         "                B;\n"
         "\n"
         "            A 'p':\n"
         "                i = 1;\n"
         "                j = 0;\n"
         "                N(a+2);\n"
         "                for(o = Y(i)-1; o<Y(j); ++o)\n"
         "                    puts(l[o]);\n"
         "                B;\n"
         "\n"
         "            A 'A':\n"
         "                y = r++;\n"
         "                strcpy(l[y], a+2);\n"
         "                x = c[y] = strlen(a+2);\n"
         "                ++x;\n"
         "                ++y;\n"
         "                B;\n"
         "\n"
         "            A 'i':\n"
         "                D();\n"
         "                --y;\n"
         "                x=X(0);\n"
         "                // Commands i and r are very similar -> fall through\n"
         "                // from i to r after moving rows down and setting\n"
         "                // position at end of line:\n"
         "\n"
         "            A 'r':\n"
         "                strcpy(*L+x-1, a+2);\n"
         "                *C = strlen(*L);\n"
         "                x = 1;\n"
         "                ++y > r && ++r;\n"
         "                B;\n"
         "\n"
         "            A 'I':\n"
         "                o = strlen(a+2);\n"
         "                memmove(*L+x+o-1, *L+x-1, *C-x+1);\n"
         "                *C += o;\n"
         "                memcpy(*L+x-1, a+2, o);\n"
         "                x += o;\n"
         "                B;\n"
         "\n"
         "            A 'd':\n"
         "                **L ? **L = *C = 0, x = 1 : U();\n"
         "                y = y>r ? r : y;\n"
         "                B;\n"
         "\n"
         "            A 'j':\n"
         "                y<r && U();\n"
         "        }\n"
         "    }\n"
         "}\n";);
}

This produces

main(){printf("Hello, World!");}

#define max(x,y)x>y?x:y
#define I(x)scanf("%d",&x)
a;b;main(){I(a);I(b);printf("\" max \": %d\n",max(a,b));}

x[10];*c;i;main(){int _e;for(;scanf("%d",&x)>0&&++_e;);for(c=x+_e;c-->x;i=100/ *x,printf("%d ",i- --_e));}

#define P printf(
#define A case
#define B break
#define L(i,e,t,f,s)for(o=i;o e;){strcpy(l[o t],l[o f]);c[o t]=c[s o];}
#define R(m,o){return b<1|b>m?m o:b;}
#define N(f)sscanf(f,"%d,%d",&i,&j)||sscanf(f,",%d",&j)
r,i,j,o,z,c[999],*C,x=1,y=1;char a[999],l[999][999],(*L)[999];D(){L(r,>y,,-1,--)r++?strcpy(l[o],l[o-1]+--x),c[o-1]=x,l[o-1][x]=0:0;c[y++]=strlen(l[o]);x=1;}U(){strcat(*L,l[y]);*C=strlen(*L);L(y+1,<r,-1,,++)--r;*l[r]=c[r]=0;}X(b)R(c[y-1],+1)Y(b)R(r,)main(){for(;;){z=i=y;L=l+--z;C=c+z;j=x;!r||y/r&&x>*C?P"end> "):P"%d,%d> ",y,x);scanf("%[^\n]%*c",a)?a[2]*=!!a[1],N(a)?y=Y(i+(i<0|*a=='+')*y),x=X(j+(j<0||strchr(a+1,'+'))*x):0:(*a=D(),scanf("%*c"));switch(*a){A'e':y=r;x=c[r-1]+1;B;A'b':y=1;x=1;B;A'L':for(o=y-4;++o<y+2;)o<0^o<r&&P"%c%s\n",o^z?' ' :'>',l[o]);for(o=x+1;--o;)P" ");P"^\n");B;A'l':puts(*L);B;A'p':i=1;j=0;N(a+2);for(o=Y(i)-1;o<Y(j);++o)puts(l[o]);B;A'A':y=r++;strcpy(l[y],a+2);x=c[y]=strlen(a+2);++x;++y;B;A'i':D();--y;x=X(0);A'r':strcpy(*L+x-1,a+2);*C=strlen(*L);x=1;++y>r&&++r;B;A'I':o=strlen(a+2);memmove(*L+x+o-1,*L+x-1,*C-x+1);*C+=o;memcpy(*L+x-1,a+2,o);x+=o;B;A'd':**L?**L=*C=0,x=1:U();y=y>r?r:y;B;A'j':y<r&&U();}}}

Limitation
This breaks definitions such as
#define A (x)

by removing the space that separates the name from expansion, giving
#define A(x)

with an entirely different meaning.  This case is absent from the test sets, so I'm not going to address it.
I suspect I might be able to produce a shorter version with a multi-pass in-place conversion - I might try that next week.

You can save one byte by removing the = at the end of the definition of O and change the space that follows each call to O into a =.

This is great ;) About the "limitation", see also my comment on the question itself -- detecting this would add just too much complexity.

@Zachary - thanks for that - I forgot when I changed the general code to ASCII-specific that O'\\' and O' ' both acquired a space.

464 bytes

Perl 5, 250+3 (-00n), 167+1 (-p) bytes
$_.=<>while s/\\
//;s,(//.*)|(("|')(\\.|.)*?\3)|/?[^"'/]+,$1|$2?$2:$&=~s@(\S?)\K\s+(?=(.?))@"$1$2"=~/\w\w|\+\+|--|\/\*/&&$"@ger,ge;$d++&&$l+/^#/&&s/^/
/,$l=/^#/m if/./

Try it online

Yes I just put a non-optimal solution. I've just added the tio link, I will look to golf it when i have time.

preprocessor directive are on their own line when are placed before code, as in the test cases however if it's required i will add change

fixed see update

C,  705   663  640 bytes
Thanks to @Zacharý for golfing 40 bytes and thanks to @Nahuel Fouilleul for golfing 23 bytes!
#define A(x)(x>47&x<58|x>64&x<91|x>96&x<123)
#define K if(*C==47&(C[1]==47|p==47)){if(p==47)--G;for(c=1;c;*C++-92||c++)*C-10||--c;if(d)p=*G++=10,--d;
#define D if(!d&*C==35){d=1;if(p&p-10)p=*G++=10;}
#define S K}if((A(p)&A(*C))|(p==*C&l==43|p==45)|p==47&*C==42|p==95&(A(*C)|*C==95)|*C==95&(A(p)|p==95))p=*G++=32;}
#define W*C<33|*C==92
#define F{for(;W;C++)
c,d,e,p,l;g(char*C,char*G)F;for(;*C;*C>32&&*C-34&&*C-39&&(p=*G++=*C),*C-34&&*C-39&&C++){l=e=0;if(*C==34)l=34;if(*C==39)l=39;if(l)for(*G++=l,p=*G++=*++C;*C++-l|e%2;e=*(C-1)-92?0:e+1)p=*G++=*C;K}D if(d){if(W)F{*C-92||++d;*C-10||--d;if(!d){p=*G++=10;goto E;}}S}else{if(W)F;S}E:D}*G=0;}

Try it online!

Can for(;W;C++){} become for(;W;C++);?

@Zacharý that was never asked for. It's a toool for the very last step: remove redundant whitespace and comments.

I was referring to his code, not the challenge.

@Zacharý haha I see ... weird when code and input are the same language ;)

Would this work for 665 bytes? https://goo.gl/E6tk8V

Already been hopelessly outgolfed in C though

-23 bytes, && and || by & and | where possible,when no side effect tio

Python 2, 479 456 445 434 502 497 bytes
e=enumerate
import re
u=re.sub
def f(s):
 r=()
 for l in u(r'\\\n','',s).split('\n'):
	s=p=w=0;L=[]
	for i,c in e(l):
	 if(p<1)*'//'==l[i:i+2]:l=l[:i]
	 if c in"'\""and w%2<1:
		if p in(c,0):L+=[l[s:i+1]];s=i+1
		p=[0,c][p<1]
	 w=[0,w+1]['\\'==c]
	r+=L+[l[s:]],
 S=''
 for l in r:s=''.join([u('. .',R,u('. .',R,u('\s+',' ',x))).strip(),x][i%2]for i,x in e(l));S+=['%s','\n%s\n'][s[:1]=='#']%s
 print u('\n\n','\n',S).strip()
def R(m):g=m.group(0);f=g[::2];return[f,g][f.isalnum()or f in'++ -- /*']

Try it online!
Edit: Fixed to include - -,+ +, and / *

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


text:
First-price sealed-bid auction
Final Result
The competition is over. Congratulations to hard_coded!
Some interesting facts:

In 31600 out of 40920 auctions (77.2%), the winner of the first round won the most rounds in that auction.

If example bots are included in the competition, the top nine places won't change except that AverageMine and heurist will swap their positions.

Top 10 results in an auction:

[2, 2, 3, 3] 16637
[0, 3, 3, 4] 7186
[1, 3, 3, 3] 6217
[1, 2, 3, 4] 4561
[0, 1, 4, 5] 1148
[0, 2, 4, 4] 1111
[2, 2, 2, 4] 765
[0, 2, 3, 5] 593
[1, 1, 4, 4] 471
[0, 0, 5, 5] 462

Tie count (number of auctions that the i-th round had no winner): [719, 126, 25, 36, 15, 58, 10, 7, 19, 38].

Average winning bid of the i-th round: [449.4, 855.6, 1100.8, 1166.8, 1290.6, 1386.3, 1500.2, 1526.5, 1639.3, 3227.1].

Scoreboard
Bot count: 33
hard_coded            Score: 16141  Total: 20075170
eenie_meanie_more     Score: 15633  Total: 18513346
minus_one             Score: 15288  Total: 19862540
AverageMine           Score: 15287  Total: 19389331
heurist               Score: 15270  Total: 19442892
blacklist_mod         Score: 15199  Total: 19572326
Swapper               Score: 15155  Total: 19730832
Almost_All_In         Score: 15001  Total: 19731428
HighHorse             Score: 14976  Total: 19740760
bid_higher            Score: 14950  Total: 18545549
Graylist              Score: 14936  Total: 17823051
above_average         Score: 14936  Total: 19712477
below_average         Score: 14813  Total: 19819816
Wingman_1             Score: 14456  Total: 18480040
wingman_2             Score: 14047  Total: 18482699
simple_bot            Score: 13855  Total: 20935527
I_Dont_Even           Score: 13505  Total: 20062500
AntiMaxer             Score: 13260  Total: 16528523
Showoff               Score: 13208  Total: 20941233
average_joe           Score: 13066  Total: 18712157
BeatTheWinner         Score: 12991  Total: 15859037
escalating            Score: 12914  Total: 18832696
one_upper             Score: 12618  Total: 18613875
half_in               Score: 12605  Total: 19592760
distributer           Score: 12581  Total: 18680641
copycat_or_sad        Score: 11573  Total: 19026290
slow_starter          Score: 11132  Total: 20458100
meanie                Score: 10559  Total: 12185779
FiveFiveFive          Score: 7110   Total: 24144915
patient_bot           Score: 7088   Total: 22967773
forgetful_bot         Score: 2943   Total: 1471500
bob_hater             Score: 650    Total: 1300
one_dollar_bob        Score: 401    Total: 401

In this game, we will simulate a sealed-bid auction.
Each auction is a 4-player game, consists of 10 rounds. Initially, players have no money. At the start of each round, each player will get $500, and then make their own bids. The bid can be any non-negative integer less or equal than the amount they have. Usually, one who bid the highest win the round. However, to make things more interesting, if several players bid the same price, their bid won't be taken into account (thus can't win the round). For example, if four players bid 400 400 300 200, the one bids 300 wins; if they bid 400 400 300 300, no one wins. The winner should pay what they bid.
Since it is a "sealed-bid" auction, the only information player will know about the bidding is the winner and how much they paid when next round starts (so player can know how much everyone has).

Scoring
One auction will be held for every possible 4-player combination. That is, if there are N bots in total, there will be NC4 auction. The bot which wins the most rounds will be the final winner. In the case that there's a tie, the bot which paid the least in total will win. If there's still a tie, in the same way as the bidding, those ties will be removed.

Coding
You should implement a Python 3 class with a member function play_round (and __init__ or others if you need). play_round should take 3 arguments (including self). The second and third argument will be, in order: the id of winner of the previous round, followed by how much they paid. If no one wins or it is the first round, they will both be -1. Your id will always be 0, and id 1–3 will be other players in an order only determined by the position on this post.

Additional rules
1. Deterministic:
The behavior of your function should depend only on the input arguments within an auction. That is, you can't access files, time, global variables or anything that will store states between different auctions or bots. If you want to use a pseudorandom generator, it's better to write it by yourself (to prevent affecting others' programs like random in Python lib), and make sure you have it reset with a fixed seed in __init__ or the first round.
2. Three Bots per Person:
You're allowed to submit at most 3 bots, so you can develop a strategy to make your bots "cooperate" in some way.
3. Not Too Slow:
Since there will be many auctions, make sure that your bots won't run too slow. Your bots should be able to finish at least 1,000 auctions in a second.

Controller
Here's the controller I'm using. All bots will be imported and added to bot_list in the order on this post.
# from some_bots import some_bots

bot_list = [
    #one_bot, another_bot,
]

import hashlib

def decide_order(ls):
    hash = int(hashlib.sha1(str(ls).encode()).hexdigest(), 16) % 24
    nls = []
    for i in range(4, 0, -1):
        nls.append(ls[hash % i])
        del ls[hash % i]
        hash //= i
    return nls

N = len(bot_list)
score = [0] * N
total = [0] * N

def auction(ls):
    global score, total
    pl = decide_order(sorted(ls))
    bots = [bot_list[i]() for i in pl]
    dollar = [0] * 4
    prev_win, prev_bid = -1, -1
    for rounds in range(10):
        bids = []
        for i in range(4): dollar[i] += 500
        for i in range(4):
            tmp_win = prev_win
            if prev_win == i: tmp_win = 0
            elif prev_win != -1 and prev_win < i: tmp_win += 1
            bid = int(bots[i].play_round(tmp_win, prev_bid))
            if bid < 0 or bid > dollar[i]: raise ValueError(pl[i])
            bids.append((bid, i))
        bids.sort(reverse = True)
        winner = 0
        if bids[0][0] == bids[1][0]:
            if bids[2][0] == bids[3][0]: winner = -1
            elif bids[1][0] == bids[2][0]: winner = 3
            else: winner = 2
        if winner == -1:
            prev_win, prev_bid = -1, -1
        else:
            prev_bid, prev_win = bids[winner]
            score[pl[prev_win]] += 1
            total[pl[prev_win]] += prev_bid
            dollar[prev_win] -= prev_bid

for a in range(N - 3):
    for b in range(a + 1, N - 2):
        for c in range(b + 1, N - 1):
            for d in range(c + 1, N): auction([a, b, c, d])

res = sorted(map(list, zip(score, total, bot_list)), key = lambda k: (-k[0], k[1]))

class TIE_REMOVED: pass

for i in range(N - 1):
    if (res[i][0], res[i][1]) == (res[i + 1][0], res[i + 1][1]):
        res[i][2] = res[i + 1][2] = TIE_REMOVED
for sc, t, tp in res:
    print('%-20s Score: %-6d Total: %d' % (tp.__name__, sc, t))

Examples
If you need a pseudorandom generator, here is a simple one.
class myrand:
    def __init__(self, seed): self.val = seed
    def randint(self, a, b):
        self.val = (self.val * 6364136223846793005 + 1) % (1 << 64)
        return (self.val >> 32) % (b - a + 1) + a

class zero_bot:
    def play_round(self, i_dont, care): return 0

class all_in_bot:
    def __init__(self): self.dollar = 0
    def play_round(self, winner, win_amount):
        self.dollar += 500
        if winner == 0: self.dollar -= win_amount
        return self.dollar

class random_bot:
    def __init__(self):
        self.dollar = 0
        self.random = myrand(1)
    def play_round(self, winner, win_amount):
        self.dollar += 500
        if winner == 0: self.dollar -= win_amount
        return self.random.randint(0, self.dollar)

class average_bot:
    def __init__(self):
        self.dollar = 0
        self.round = 11
    def play_round(self, winner, win_amount):
        self.dollar += 500
        self.round -= 1
        if winner == 0: self.dollar -= win_amount
        return self.dollar / self.round

class fortytwo_bot:
    def play_round(self, i_dont, care): return 42

Result
all_in_bot           Score: 20     Total: 15500
random_bot           Score: 15     Total: 14264
average_bot          Score: 15     Total: 20000
TIE_REMOVED          Score: 0      Total: 0
TIE_REMOVED          Score: 0      Total: 0

The winner is all_in_bot. Note that zero_bot and fortytwo_bot have the same score and total, so they're removed.
These bots will not be included in the competition. You can use them if you think they are great.

The final competition will be held at 2017/11/23 14:00 (UTC). You can make any change to your bots before that.

Do they get 500 dollars each round, or each auction (that lasts 10 rounds)?

So just to make sure, between the 10 rounds you can store state right?

@StewieGriffin they'll get 500 dollar each round.

@HyperNeutrino yes (or you won't even know how much you have). There's no winner in an auction. Overall winner should win the most rounds in all auctions.

If I make multiple bots, should they all be in one answer, or should I have separate answers?

@KamilDrakari both are okay.

One more, what happens if an error occurs? For example, your controller raises a ValueError if an invalid bid is provided. Will the offending bot be disqualified while the remainder bots get to continue or would the entire competition need to be restarted?

@KamilDrakari competition will restart with the offending bot removed from the list.

Having to put the bot's code into an answer where everyone can see seems like there's a significant advantage to waiting until the last minute to post since I would think there's a lot to be gained from knowing your opponents' strategies.

@Shufflepants True, but this is always the case with KotH challenges. In the past some people indeed made a bot near the end to counter all bots up to that point. But it's just part of the KotH-style challenge. And the way most KotH-challenges work, this one included, the advantage won't be that great. You can only counter so many bots at the same time.. Nice first challenge, Colera Su, and welcome to PPCG! Looking forward to the results. :)

Can a bid of 0 win if all other players tie out?

@thegreatemu yes.

Will these example bots take part in the competition?

@Zaid no. It's mentioned in the post.

Here's a test run on TIO with all of the current bots.

This challenge might be more interesting if different rounds had weighted values, and the weight of rounds you had won counted proportionally towards your final score. That way there would be an extra layer of strategy to how much to bid.

@mypetlion that's a good idea. Maybe I can use it in further challenges (not this one, since it will make a big difference).

It's a tight race at the moment...

hard_coded
class hard_coded:
  def __init__(self):
    self.money = 0
    self.round = 0

  def play_round(self, did_i_win, amount):
    self.money += 500
    self.round += 1
    if did_i_win == 0:
      self.money -= amount
    prob = [500, 992, 1170, 1181, 1499, 1276, 1290, 1401, 2166, 5000][self.round - 1]
    if prob > self.money:
      return self.money
    else:
      return prob

This bot is the results of genetic training against a lot of other pseudo-random bots (and some of the bots in other answers). I've spent some time fine-tuning at the end, but its structure is actually very simple.
The decisions are based only on a fixed set of parameters and not on the outcome of previous rounds.
The key seems to be the first round: you have to go all-in, bidding 500 is the safe move. Too many bots are trying to outsmart the initial move by bidding 499 or 498. Winning the first round gives you a big advantage for the rest of the auction. You are only 500 dollars behind, and you have time to recover.
A safe bet in the second round is a little over 990, but even bidding 0 gives some good result. Bidding too high and winning could be worse than losing this round.
In the third round, most bots stop escalating: 50% of them have less than 1500 dollars by now, so there is no need to waste money on this round, 1170 is a good tradeoff. Same thing in the fourth round. If you lost the first three, you can win this one very cheap, and still have enough money for the next.
After that, the average money required to win a round is 1500 dollars (which is the logical conclusion: everyone wins a round out of four by now, bidding less to win later is just wasting money, the situation has stabilized and it's just round-robin from now on).
The last round must be all-in, and the other parameters are fine-tuned to win the last round by bidding as low as possible until then.
A lot of bots try to win the ninth round by bidding more than 2000 dollars, so I took that into account and try to overbid them (I can't win both the last two rounds anyway, and the last will be harder).

Well, that's one way to win. Congratulations!

But I gotta admit that I like other submissions more, because there went another form of thought into. Not trying out how I would win against those other bots, but what could be a good tactic against any random bot.

I can understand, I liked (and upvoted) some other submissions, but this is a problem on a finite domain, and a lot of submissions are just too complex.  The core of the problem is generating a sequence of 10 numbers, so I chose to optimize for a specific domain instead of finding a general procedure. I am an engineer, not a mathematician.

Fair enough, the problem is pretty finite... Here, take my upvote, you convinced me :p

Grazie mille und arrivederci. :-)

@LucaH the apparent simplicity of the approach belies the amount of work required to arrive at this particular set of numbers. I was attempting a similar thing with my own bot from a statistical viewpoint, and it wasn't easy

@Zaid of course there is a lot of work going into it, but brute forcing is just so... brute ;)

Above Average
Bids above the average amount of money the other players have. Bids everything in the last round.
class above_average:
  def __init__(self):
    self.round = 0
    self.player_money = [0] * 4
  def play_round(self, winner, winning_bid):
    self.round += 1
    self.player_money = [x+500 for x in self.player_money]
    if winner != -1:
      self.player_money[winner] -= winning_bid
    if self.round == 10:
      return self.player_money[0]
    bid = sum(self.player_money[1:]) / 3 + 1
    if bid > self.player_money[0]:
      return self.player_money[0]
    return min(self.player_money[0], bid)

I Don't Even
class I_Dont_Even:
	def __init__(self):
		self.money = 0
		self.round = 0
	def play_round(self, loser, bid):
		self.money += 500 - (not loser) * bid
		self.round += 1
		return self.money * (self.round & 1 or self.round == 10)

Only participates in odd rounds and the last round.

The forgetful bot doesn't know how much money he has, so he just puts in the money he was given for this round. If he finds he has some money at the end, he just donates it to a charity.
class forgetful_bot:
  def play_round(self, winner, amt):
    return 500

I'm not the downvoter, but maybe it is 'cause you did not put any effort into your bot

This is one of the first answers. Something is needed to get the ball rolling.

I didn't downvote, but maybe it's because even though something needed to get the ball rolling, maybe do something slightly more interesting? Especially since this is practically identical to One Dollar Bob which was used to get it kind of started

Patient Bot
class patient_bot:
    def __init__(self):
        self.round = 0
        self.money = 0
    def rand(self, seed, max):
        return (394587485 - self.money*self.round*seed) % (max + 1)
    def play_round(self, winner, amount):
        self.round += 1
        self.money += 500
        if winner == 0:
            self.money -= amount
        if self.round < 6:
            return 0
        else:
            bid = 980 + self.rand(amount, 35)
            if self.money < bid or self.round == 10:
                bid = self.money
            return bid

Bids nothing for the first five rounds, then bids ~1000 dollars for the next four rounds, and finally bids everything it has in the last round.

One Upper
I don't know much about Python, so I might make some kind of error
class one_upper:
    def __init__(self):
        self.money = 0
        self.round = 0
    def play_round(self, winner, win_amount):
        self.money += 500
        if winner == 0: self.money -= win_amount
        self.round += 1
        bid = win_amount + 1
        if self.money < bid or self.round == 10:
            bid = self.money
        return bid

bids 1 higher than the previous winning bid, or goes all-in during the last round.
I may in the future decide on a different strategy for when win_amount is -1

Copycat Or Sad
Third and final bot.
This bot will bid exactly the same amount as the previous winner (including itself). However, if it doesn't have enough cash to do so it will be sad, and will bid a measly 1 dollar bill with his tear on it instead. In the final round it will go all-in.
class copycat_or_sad:
  def __init__(self):
    self.money = 0
    self.round = -1
  def play_round(self, winner, win_amount):
    # Default actions:
    #  Collect 500 dollars
    self.money += 500
    #  If it was the winner: subtract the win_amount from his money
    if winner == 0:
      self.money -= win_amount
    #  One round further
    self.round += 1

    # If it's the final round: bid all-in
    if self.round == 9:
      return self.money
    # Else-if there was no previous winner, or it doesn't have enough money left: bid 1
    if win_amount < 1 or self.money < win_amount:
      return 1
    # Else: bid the exact same as the previous winner
    return win_amount

I never program in Python, so if you see any mistakes let me know..

This bids -1 on the first auction.

Test run
I've edited a previous test run put together by Steadybox adding in the newest submissions.
I'm posting it here so there is a place where the link can be updated with more recent versions, this post is a community wiki so feel free to update it if you post a new submission, modify an old one, or simply see something new from some other submission!
Here's the link to the test run! (TIO)

should I be depressed that my bot that was meant to be disruptive beats out my two "real" submissions?

@thegreatemu It's interesting to see how the bots interact with each other. A single new bot could dramatically change the rankings. Something interesting I found is that if histocrat's deleted blacklist bot participates, my two bots move to the top of the rankings. :)

Half In
This bot always bids half of what it has left, except in the final round where it will go all in.
class half_in:
  def __init__(self):
    self.money = 0
    self.round = -1
  def play_round(self, winner, win_amount):
    # Default actions:
    #  Collect 500 dollars
    self.money += 500
    #  If it was the winner: subtract the win_amount from his money
    if winner == 0:
      self.money -= win_amount
    #  One round further
    self.round += 1

    # If it's the final round: bid all in
    if self.round == 9:
      return self.money
    # Else: Bid half what it has left:
    return self.money / 2

I never program in Python, so if you see any mistakes let me know..

AverageMine
This player calculates the percentage (bid / total money) for the winner of each round and bids his (total money * average winning percentage + 85) unless he has more money than all the other players, then he bids 1 more than the highest competitor. Starts with a bid of 99.0% of the starting amount.
class AverageMine:
    nplayers = 4
    maxrounds = 10
    def __init__(self):
        self.money = [0] * self.nplayers
        self.wins = [0] * self.nplayers
        self.round = 0
        self.average = 0
    def play_round(self, winner, win_amt):
        self.round += 1
        for i in range(self.nplayers):
            if i == winner:
                self.average = (self.average * (self.round - 2) + (win_amt / self.money[i])) / (self.round - 1)
                self.money[i] -= win_amt
                self.wins[i] += 1
            self.money[i] += 500
        if self.round == 1:
            return int(0.990 * self.money[0])
        elif self.round < self.maxrounds:
            if self.money[0] > self.money[1] + 1 and self.money[0] > self.money[2] + 1 and self.money[0] > self.money[3] + 1:
                return max(self.money[1],self.money[2],self.money[3]) + 1
            bid = int(self.average * self.money[0]) + 85
            return min(self.money[0],bid)
        else:
            bid = self.money[0]
            return bid

Graylist
class Graylist:
  def __init__(self):
    self.round = 0
    self.player_money = [0] * 4
    self.ratios = {1}
    self.diffs = {0}
  def play_round(self, winner, winning_bid):
    self.round += 1
    if winner != -1:
      if winner >0 and winning_bid>0:
        self.ratios.add(self.player_money[winner]/winning_bid)
        self.diffs.add(self.player_money[winner]-winning_bid)
      self.player_money[winner] -= winning_bid
    self.player_money = [x+500 for x in self.player_money]
    tentative_bid = min(self.player_money[0],max(self.player_money[1:])+1, winning_bid+169, sum(self.player_money[1:])//3+169)
    while tentative_bid and (tentative_bid in (round(m*r) for m in self.player_money[1:] for r in self.ratios)) or (tentative_bid in (m-d for m in self.player_money[1:] for d in self.diffs)):
      tentative_bid = tentative_bid - 1
    return tentative_bid

Inspired by the blacklist submission by histocrat, this bot keeps in memory all the previous winning bets of other players as both the ratio of money they bet compared to their full money and the difference between their bet amount and the full amount. In order to avoid losing to a tie (which apparently is actually a big factor in this competition) it then avoids betting any number that could give the same results given its opponents' current moneys.
EDIT: as the starting value for the bid now uses the minimum between: its current money, 1 more than the money of the richest opponent, X more than the last winning bet, or Y more than the average money of its opponents. X and Y are constants that will probably be modified before the end of the competition.

Eenie Meanie More
This player is identical to Meanie, except for one variable. This version bids more aggressively and causes some players to spend more than meanie thinks the auction is worth.
class eenie_meanie_more:
    def __init__(self):
        self.money = [0] * 4
        self.rounds = 11
        self.total_spent = 0

    def play_round(self, winner, winning_bid):
        self.money = [x+500 for x in self.money]
        self.rounds -= 1
        if winner != -1:
            self.money[winner] -= winning_bid
            self.total_spent += winning_bid
        bid = 500
        if self.rounds > 0 and self.total_spent < 20000:
            bid = int((20000 - self.total_spent)/self.rounds/4)+440
        return min(bid, max(self.money[1:])+1, self.money[0])

Beat the Winner
Bid 1 more than the player with the most wins so far
class BeatTheWinner:
    nplayers = 4
    maxrounds = 10
    def __init__(self):
        self.money = [0] * self.nplayers
        self.wins = [0] * self.nplayers
        self.round = 0

    def play_round(self, winner, win_amt):
        self.round += 1
        for i in range(self.nplayers):
            self.money[i] += 500
            if i == winner:
                self.money[i] -= win_amt
                self.wins[i] += 1
        mymoney = self.money[0]
        for w,m in sorted(zip(self.wins, self.money),reverse=True):
            if mymoney > m:
                return m+1
        #if we get here we can't afford our default strategy, so
        return int(mymoney/10)

Are your m,w in the correct order?

Minus One
class minus_one:
    def __init__(self):
        self.money = 0
    def play_round(self, winner, amount):
        self.money += 500
        if winner == 0:
            self.money -= amount
        return self.money - 1

Bid Higher
class bid_higher:
    def __init__(self):
        self.dollar = 0
        self.round = 0
    def play_round(self, winner, win_amount):
        self.dollar += 500
        self.round += 1
        inc = 131
        if winner == 0: self.dollar -= win_amount
        if self.round == 10: return self.dollar
        if win_amount == 0: win_amount = 500
        if self.dollar > (win_amount + inc):
            return win_amount + inc
        else:
            if self.dollar > 1:
                return self.dollar -1
            else:
                return 0

Still learning python; bid a bit higher than the last winner.

Welcome to PPCG! It seems that your bot gets even better a score if you change inc = 100 to inc = 101.

I'm really going against my own interests here, but you could easily improve your score by keeping track of the turns and going all-in on the final round ;)

Thanks for the suggestions; I added a last-round all-in, fine-tuned the increment, and added a couple of wingmen bots to give this bot a boost..

Hi, I hope you don't mind, but I was putting together a testbench with all the current submission and I've found out that your code was sometimes returning invalid values on the last round, so I've fixed the bug by rearranging the order a couple of lines. Sorry if I changed anything you wouldn't have, feel free to revert the changes and fix the bug in another way!

@Leo:No problem, thanks for taking an interest..

Distributer
When this bot loses a round, he distributes the excess cash among all of the next rounds. He puts in $499 on the first round thinking that the others will tie with $500 and be eliminated.
class distributer:
  def __init__(self):
    self.money = 0
    self.rounds = 11
  def play_round(self, winner, amt):
    self.money += 500
    self.rounds -= 1
    if self.rounds == 10:
      return 499
    if winner == 0:
      self.money -= amt
    return ((self.rounds - 1) * 500 + self.money) / self.rounds

Meanie
This player takes the total cash that will enter play to get the mean bid across the number of players and remaining rounds. If this target is more than all other players currently hold it lowers its bid to the balance of its greatest competitor plus one. If the player cannot afford its target, it is all-in.
class meanie:
    def __init__(self):
        self.money = [0] * 4
        self.rounds = 11
        self.total_spent = 0

    def play_round(self,winner,winning_bid):
        self.money = [x+500 for x in self.money]
        self.rounds -= 1
        if winner != -1:
            self.money[winner] -= winning_bid
            self.total_spent += winning_bid
        bid = 500
        if self.rounds > 0 and self.total_spent < 20000:
            bid = int((20000 - self.total_spent)/self.rounds/4)+1
        return min(bid,max(self.money[1:])+1,self.money[0])

FiveFiveFive
Skips the first round and bids $555 on remaining rounds. In last round, will go all in unless 2 other bots have the same amount (and will presumably tie out).
class FiveFiveFive:
    nplayers = 4
    maxrounds = 10
    def __init__(self):
        self.money = [0] * self.nplayers
        self.wins = [0] * self.nplayers
        self.round = 0

    def play_round(self, winner, win_amt):
        self.round += 1
        for i in range(self.nplayers):
            self.money[i] += 500
            if i == winner:
                self.money[i] -= win_amt
                self.wins[i] += 1
        if self.round == 1:
            return 0
        elif self.round < self.maxrounds:
            return min(555, self.money[0])
        else:
            bid = self.money[0]
            return bid if self.money.count(bid) < 3 else bid-1

Almost All In
class Almost_All_In:
	def __init__(self):
		self.money = 0
		self.round = 0
	def play_round(self, loser, bid):
		self.money += 500 - (not loser) * bid
		self.round += 1
		return self.money - self.round % 3 * 3 - 3

Always bids slightly less than it has.

HighHorse
This player bids all his money minus the current round number, except on the last round, where he goes all in.
class HighHorse:
    maxrounds = 10
    def __init__(self):
        self.money = 0
        self.round = 0
    def play_round(self, winner, win_amt):
        self.round += 1
        if 0 == winner:
            self.money -= win_amt
        self.money += 500
        if self.round < self.maxrounds:
            return self.money - self.round
        else:
            bid = self.money
            return bid

Below Average
Similar to above average, but goes a bit lower
class below_average:
  def __init__(self):
    self.round = 0
    self.player_money = [0] * 4
  def play_round(self, winner, winning_bid):
    self.round += 1
    self.player_money = [x+500 for x in self.player_money]
    if winner != -1:
      self.player_money[winner] -= winning_bid
    if self.round == 10:
      return self.player_money[0]
    bid = sum(self.player_money[1:]) / 3 - 2
    if bid > self.player_money[0]:
      return self.player_money[0]
    return min(self.player_money[0], bid)

Modular Blacklist
class blacklist_mod:
  def __init__(self):
    self.round = 0
    self.player_money = [0] * 4
    self.blacklist = {0, 499}
  def play_round(self, winner, winning_bid):
    self.round += 1
    self.player_money = [x+500 for x in self.player_money]
    if winner != -1:
      self.player_money[winner] -= winning_bid
      self.blacklist.add(winning_bid % 500)
      self.blacklist |= {x % 500 for x in self.player_money[1:]}
    tentative_bid = self.player_money[0]
    autowin = max(self.player_money[1:])+1
    if tentative_bid < autowin:
      while tentative_bid and (tentative_bid % 500) in self.blacklist:
        tentative_bid = tentative_bid - 1
    else:
      tentative_bid = autowin
    self.blacklist.add(tentative_bid % 500)
    return tentative_bid

Bets the highest amount it can that isn't congruent modulo 500 to any numbers it's seen before.
Edited to not apply the blacklist when it can get a guaranteed win.

Curiously, it seems that the latest update to your other bot is affecting this bot negatively. Currently, blacklist_mod is fifth on the leaderboard, whereas blacklist is in the second place. If the older version of blacklist is used instead, blacklist falls to the sixth place, but blacklist_mod takes the lead!

Throwing blacklist out altogether seems to give blacklist_mod even a more solid lead, but that's inconclusive.

Oh, thanks, that makes sense--they're close to the same algorithm early on without the old special-case logic, so they step on each others' toes. I think I'll just remove the original bot; I can't think of a good reason to keep it around.

Showoff
This is that guy who shows off his math ability in situations that truly do not require anything so complicated. Until the last round (in which he goes all-in), he uses a logistic model to determine his bid, more if his enemies have a greater portion of their money remaining.
class Showoff:
  def __init__(self):
      self.moneys = [0, 0, 0]
      self.roundsLeft = 10
  def play_round(self, winner, winning_bid):
      import math
      self.moneys = [self.moneys[0] + 500,
                     self.moneys[1] + 1500,
                     self.moneys[2] + 1500]
      self.roundsLeft -= 1
      if winner > 0:
          self.moneys[1] -= winning_bid
      if winner == 0:
          self.moneys[0] -= winning_bid
      if self.roundsLeft == 0:
          return self.moneys[0]
      ratio = self.moneys[1] / self.moneys[2]
      logisticized = (1 + (math.e ** (-8 * (ratio - 0.5)))) ** -1
      return math.floor(self.moneys[0] * logisticized)

The logistic curve used is f(x)=1/(1+e-8(x-0.5)), where x is the ratio of current enemy-money to the round's total potential enemy-money. The more the others have, the more he bids. This has the possible benefit of bidding almost-but-not-quite $500 the first round.

Escalating Quickly
Bids increasing fractions of its money each round (please let me know if any errors, a while since I used Python)
class escalating:
  def __init__(self):
    self.money = 0
    self.round = 0
  def play_round(self, winner, win_amount):
    # Default actions:
    #  Collect 500 dollars
    self.money += 500
    #  If it was the winner: subtract the win_amount from his money
    if winner == 0:
      self.money -= win_amount
    #  One round further
    self.round += 1

    # bid round number in percent times remaining money, floored to integer
    return self.money * self.round // 10

Swapper
Alternates between bidding one under his max and going all in.
class Swapper:
    def __init__(self):
        self.money = 0
        self.round = 0
    def play_round(self, loser, bid):
        self.money += 500 - (not loser) * bid
        self.round += 1
        if self.round & 1:
            return self.money - 1
        return self.money

I figured I needed to find something that could beat Steadybox's minus_one. :)

Heurist
The Heurist treats this game as one of repeatable probability, so it knows where to draw the line.
It is also miserly, so it bids the bare minimum required for a win when it can.
class heurist:
    def __init__(self):
        self.money = 0
        self.round = -1
        self.net_worth = [0] * 4
    def play_round(self, winner, bid):
        self.round += 1
        self.money += 500
        if winner == 0: self.money -= bid
        if winner != -1: self.net_worth[winner] -= bid
        self.net_worth = [x+500 for x in self.net_worth]
        max_bid = [498,1000,1223,1391,1250,1921,2511,1666,1600,5000][self.round]
        if self.money > max_bid:
            return 1 + min(max_bid,max(self.net_worth[1:3]))
        else:
            return self.money

Disclaimer: max_bid is subject to change

bob_hater
This bot does not like Bob and thus will always bid 2$ to win against Bob.
class bob_hater:
    def play_round(bob,will,loose):
        return 2

AntiMaxer
Match the highest amount we can afford of all player's money. Will cause any bot going for all-in on that round to tie out.
class AntiMaxer:
    nplayers = 4
    maxrounds = 10
    def __init__(self):
        self.money = [0] * self.nplayers
        self.wins = [0] * self.nplayers
        self.round = 0

    def play_round(self, winner, win_amt):
        self.round += 1
        for i in range(self.nplayers):
            self.money[i] += 500
            if i == winner:
                self.money[i] -= win_amt
                self.wins[i] += 1
        return max((m for m in self.money[1:] if m<=self.money[0]),
                   default=0)

Simple Bot
class simple_bot:
    def __init__(self):
        self.round = 0
        self.money = 0
    def rand(self, seed, max):
        return (394587485 - self.money*self.round*seed) % (max + 1)
    def play_round(self, winner, amount):
        self.round += 1
        self.money += 500
        if winner == 0:
            self.money -= amount
        bid = 980 + self.rand(amount, 135)
        if self.money < bid or self.round == 10:
            bid = self.money
        return bid

Almost the same as Patient Bot, but not as patient. Gets a much better score than it, though.

Wingman 1
Provide a wingman for bid_higher, as protection. (Same algorithm, just slightly lower increment.)
class Wingman_1:
    def __init__(self):
        self.dollar = 0
        self.round = 0
    def play_round(self, winner, win_amount):
        self.dollar += 500
        self.round += 1
        inc = 130
        if win_amount == 0: win_amount = 500
        if winner == 0: self.dollar -= win_amount
        if self.round == 10: return self.dollar
        if self.dollar > win_amount + inc:
            return win_amount + inc
        else:
            if self.dollar > 1: return self.dollar -1
            else:
                return 0

Your code won't work because you need indentation for the stuff in the class

Thanks for pointing that out; I haven't got the hang of the {} code editing yet.

Clever, I'd been worried the best answer was going to be sniped at the finish line by a duplicate but this form of protection works for at least some bots.

@Steadybox:Thanks, fixed the all-in code.

Wingman 2
If one wingman is good, two must be better ?
class wingman_2:
    def __init__(self):
        self.dollar = 0
        self.round = 0
    def play_round(self, winner, win_amount):
        self.round += 1
        self.dollar += 500
        inc = 129
        if win_amount == 0: win_amount = 500
        if winner == 0: self.dollar -= win_amount
        if self.round == 10: return self.dollar
        if self.dollar > win_amount + inc:
            return win_amount + inc
        else:
            if self.dollar > 1: return self.dollar -1
            else:
                return 0

Your code won't work because you need indentation for the stuff in the class

Interestingly, both of your wingmen seem to beat your original bot (the pastebin link contains the TIO link, which is too long for posting in a comment and even too long for URL shorteners...)

I found the results were very sensitive to the pool of other bots; minor changes in the increment value seem to have disproportionate results.

average_joe
I'm not sure if I'm allowed to use a utility class or not, its below the bot class. (it's Tracker) Anyway, the bot bets 475 on the first round, and goes all in on the last round. In all the other rounds, it randomly chooses between beating the average winning bid, or beating the average current balance between all other bots.
MONEY_PER_ROUND = 500
NUM_ROUNDS = 10

class Random:
    def __init__(self, seed):
        self.val = seed
    def randint(self, a, b):
        self.val = (self.val * 6364136223846793005 + 1) % (1 << 64)
        return (self.val >> 32) % (b - a + 1) + a
    def choice(self, arr):
        return arr[self.randint(0,len(arr)-1)]

class average_joe:
    running_sum = 0

    def __init__(self):
        self.random = Random(42)

    def play_round(self, winner, winning_bid):
        if winner == -1 and winning_bid == -1:
            self.tracker = Tracker()
            self.tracker.next_round(money=MONEY_PER_ROUND)
            return 475
        else:
            self.tracker.next_round(money = MONEY_PER_ROUND)
            self.tracker.update_balance(winner, winning_bid)
            self.running_sum += winning_bid
            if self.tracker.rounds == NUM_ROUNDS:
                balance = self.tracker.get_balance(0)
                return balance
            else:
                strategy = self.random.choice([self.beat_mean_history, self.beat_mean_balance])
                return strategy()

    def beat_mean_history(self):
        mean = self.running_sum // self.tracker.rounds
        return max(min(mean + 2, self.tracker.get_balance(0)),0)

    def beat_mean_balance(self):
        mean = self.tracker.get_average_balance()
        return max(min(mean+2, self.tracker.get_balance(0)),0)

# Tracker utility class
class Tracker:
    def __init__(self):
        self.rounds = 0
        self.player_balance = dict.fromkeys(range(4), 0)

    def get_values(self):
        return [self.player_balance[player] for player in self.player_balance.keys()]

    def next_round(self, money=500):
        self.rounds += 1
        for player in self.player_balance.keys():
            self.player_balance[player] += money

    def get_balance(self, player):
        return self.player_balance[player]

    def update_balance(self, player, expense):
        self.player_balance[player] -= expense

    def get_average_balance(self):
        values = self.get_values()[1:]
        return round(sum(values) / len(values))

Right, my bad. Fixed. Thanks for the input!

class one_dollar_bob:
  def play_round(x,y,z):
    return 1

Slow Starter
This bot starts with a bid of 0 in the first round, then 200, then 400, etc. It bids 200 more every round, or plays all-in if it doesn't have enough left anymore. It will also go all in in the final round.
class slow_starter:
  def __init__(self):
    self.money = 0
    self.round = -1
  def play_round(self, winner, win_amount):
    # Default actions:
    #  Collect 500 dollars
    self.money += 500
    #  If it was the winner: subtract the win_amount from his money
    if winner == 0:
      self.money -= win_amount
    #  One round further
    self.round += 1

    # If it's the final round or if it doesn't have enough money left: bid all in
    if self.round == 9 or self.round * 200 > self.money:
      return self.money
    # Else: bid 200 multiplied with the current round we're playing
    #  (Note: It bids 0 the first round)
    return self.round * 200

I never program in Python, so if you see any mistakes let me know..

Your check for the final round will fire on round 11, not 10. Same with your Half In bot.

@JeremyWeirich Thanks! Fixed.

source: Stack Exchange

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

sort: votes


text:
How long should my microwave run?
I'm hungry. Let's microwave something. Given a numerical input of between 1 and 4 digits, output the number of seconds that the microwave should run.
Details
The trick is figuring out if the user is inputting seconds or a combination of seconds and minutes. The ones and the tens places should be interpreted as seconds and the hundreds and thousands places should be minutes. For example, the value 1234 should be interpreted as 12 minutes, 34 seconds and 9876 should be 98 minutes, 76 seconds. Typing 130 and 90 should both result in a cook time of 90 seconds.
Here are a few other inputs and outputs:

1 = 1
11 = 11
111 = 71
1111 = 671
9 = 9
99 = 99
999 = 639
9999 = 6039

Rules
This is code-golf, so the shortest program in bytes wins. Standard loopholes are not allowed. The winning entry must return the right answer when given any integer input from 1 to 9999.

@WheatWizard, I'm happy to edit the question. Do you have a suggestion for what I should say in the Details section? Maybe I could make this sentence clearer: "The ones and the tens places should be interpreted as seconds and the hundreds and thousands places should be minutes."

@WheatWizard I just added more detail, let me know if you think I should add more.

Does that work with an input of 9876?

Strange, I was about to sandbox this exact challenge haha

What would the output be for 190?

@OldBunny2800 Most likely 150, 1 minute and 90 seconds

Python 2, 19 bytes
lambda t:t-t/100*40

Try it online!

im confused about the order of operations...

@Hippopotomonstrosesquipedalian I'm unsure about the source of the confusion, but maybe a fully parenthesized version helps: t-((t/100)*40). The / is integer division in Python 2.

this also works in python 3

No in Python 3 it would have to be t-t//100*40

Japt, 6 bytes
ìL ì60

Test it online! ìL converts to base-100, and ì60 converts back to base 60, resulting in floor(n/100)*60 + n%100. Also works with hours (10000 -> 3600, the number of seconds in an hour).

Exactly what I had :)

Pyth - 9 8 bytes
Converts input to base 100, then interprets that as a base 60 number.
ijQ*TT60

Test Suite.

TI-Basic (83 series), 8 bytes
Ans-40int(sub(Ans

Requires OS version 1.15 or higher.

C, C++, Java, C#, D : 36 bytes
D : 35 bytes
C : 28 bytes
First time i have an answer that short !
int r(int i){return i/100*60+i%100;}

D can have a special optimization because of the golfy template system :
T r(T)(T i){return i/100*60+i%100;}

C has a special optimization with the implicit int :
r(i){return i/100*60+i%100;}

Code to test
In C ( have to include stdio.h ) :
int main() {
    int testArr[] = {1,11,111,1111,9,99,999,9999};
    for(int i=0;i<8; ++i) {
        printf("%d = %d\n",testArr[i],r(testArr[i]));
    }
    return 0;
}

TIO Link
In C++ ( have to include iostream ) :
int main() {
    std::initializer_list<int> testList{
        1,11,111,1111,9,99,999,9999
    };

    for (auto x : testList) {
        std::cout << r(x) << '\n';
    }
}

Try it online!
In Java :
public class MainApp {

    int r(int i){return i/100*60+i%100;}

    public static void main(String[]a) {
        MainApp m = new MainApp();
        int testArr[] = new int[]{
                1,11,111,1111,9,99,999,9999
        };

        for (int v : testArr) {
            System.out.println(v + " = " + m.r(v));
        }
    }
}

Try it online!
In C#
class Program {
    int r(int i){return i/100*60+i%100;}
    static void Main(string[] args) {
        var p = new Program();
        int[] testArr = new int[8]
        {
            1,11,111,1111,9,99,999,9999
        };
        foreach(int a in testArr) {
            Console.WriteLine(a + " = " + p.r(a));
        }
    }
}

In D ( have to import std.stdio ) ( exactly, i have no idea how to use arrays in D ) :
void main() {
    int[] arr = [1,11,111,1111,9,9,999,9999];
    for(int i = 0; i < arr.length; i++)
        writeln(arr[i]," = ",r(arr[i]));
}

TIO Link

The D test code be the footer of this TIO: https://tio.run/##LYvBCoMwDIbP7VMEYdDO4trLQLq9hTfxIOi2gLYj67aD@OxdlJF8JD/5MmScn5ESvNJQMRh9boBUo1UDqBca05sC4MlZezzbEg@8@DV/Ig4w9xiUhkUKDKntoCeCK7TOuK13nKm3qnfqzktxi6RYB2TVeh6X7a@axnBPD85lqaUQX8I0TkHxqcXOFCwXhv5Ray9XyD8, and I see you've learned the template system :). (There is a foreach in D, I just forgot how to use it sadly)

C can be golfed to 28 bytes using C89 implicit-int.

You should post all these as separate answers.

dc, 10 bytes
?9A~r60*+p

Try it online!
Explanation: in dc when you push sth. on the stack it goes on top
?         # read and push the input number on the stack
9A        # push 100: 9 * 10^1 + A[10] * 10^0 :D
~         # divide 2nd nr. by the top nr., push quotient, then remainder
r60*      # swap top 2 nr., then multiply the top by 60
+p        # add top 2 nr., then print result

Bash bc + sed, 30 28 bytes
-2 bytes thanks to @seshoumara.
bc<<<0`sed 's/..\?$/*60+&/'`

Try it online!
Takes input from stdin. Went for a more creative approach: inserts *60+ before the last 1 or 2 digits, and prepends a 0 to the beginning to account for inputs with only 1 or 2 digits. The result is then passed to bc.

If you remove -r and use \?, you can loose 2 bytes.

Perl 5, 15+1(-p) bytes
/..$/;$_-=40*$`

-l switch not counted because for tests readability

Try it online

Jelly, 5 bytes
As a monadic link (thanks for the heads-up, caird!):
b³ḅ60

Try it online!
... Or as a full program:
bȷ2ḅ60

This can be ported easily to 05AB1E, so:
05AB1E, 5 bytes
тв60β

Try it online!
Simply converts the input integer to base 100 and then converts the result from base 60 to integer. Hence, it is equivalent to Input % 100 + 60 * ⌊Input / 100⌋

As a function, 5 bytes

@cairdcoinheringaahing I think you meant this, but thanks for the heads-up anyway

C (gcc), 50 bytes
t;f(){scanf("%d",&t);printf("%d",t%100+t/100*60);}

Try it online!

28 bytes: f(t){return t%100+t/100*60;}. Functions are allowed to take input as arguments and output via their return values.

25 bytes f(i,x){x=i/100*60+i%100;}

21 bytes f(i,x){x=i-i/100*40;}

Java 8, 13 bytes
n->n-n/100*40

Port of @ovs' amazing Python 2 formula.
Try it here.

PowerShell, 38 33 bytes
-5 bytes thanks to mazzy
$args|%{$_-40*($_-replace'..?$')}

Try it online!
Uses the same formula popularizes by ovs. Truncating is still expensive in PowerShell. Now uses a better regex to instead rip the last one or two characters off to division.

? Try it online!

@mazzy Brilliant!

JavaScript, 21 bytes
a=>(a/100^0)*60+a%100

Try it online!

Save 4 bytes by using ovs's trick - a-(a/100^0)*40

@IanF1. Thanks, but I think it would be literally stealing their idea.

yeah you're right. Too enthusiastic, sorry.

@ThePirateBay You don't really live up to your name then ;)

J, 12 bytes
-40*&<.%&100

It's ovs' Python 2 solution expressed in J. It consist of a hook and a fork:
┌─┬───────────────────────┐
│-│┌──┬────────┬─────────┐│
│ ││40│┌─┬─┬──┐│┌─┬─┬───┐││
│ ││  ││*│&│<.│││%│&│100│││
│ ││  │└─┴─┴──┘│└─┴─┴───┘││
│ │└──┴────────┴─────────┘│
└─┴───────────────────────┘

       %&100  - divides the number by 100
   *&<.       - finds the floor of the left argument and multiplies it to the left arg.
 40           -
-             - subtracts the result of the above fork from the input

Try it online!

Same byte count as 60#.0 100#:].

@FrownyFrog - your solution looks prettier, cheers!

Galen, I think it might be because Frowny's has a smiley :]

@RGS Yes, indeed!

Batch, 23 bytes
@cmd/cset/a%1-%1/100*40

Pushy, 10 9 bytes
Kevin outgolfed me in my own language... (using the approach from ovs' answer)
2dH/40*-#

Try it online!
10 bytes
sjvj60*^+#

Try it online!
s             \ Split input into digits
 jvj          \ Join the first two and the last two
    60*       \ Multiply the first by 60
       ^+     \ Add the values
         #    \ Print

11 bytes
For one byte more we can use the Input % 100 + 60 * ⌊Input / 100⌋ approach:
H2d%}/60*+#

Try it online!

9 bytes by creating a port of @ovs' Python 2 answer: 2dH/40*-#. Never programmed in Pushy before, but it seems like a pretty cool language. :)

@KevinCruijssen it's quite a generic stack based language, I guess the only  slightly different thing it brings to the table is the double stack... but thank you, and thanks for the golf :)

bash, 20 bytes
echo $[$1-$1/100*40]

Try it online

Haskell, 18 bytes
f t=t-t`div`100*40

Try it online!
Anotha port.
Pointfree solution, 21 bytes
(-)<*>(*40).(`div`40)

Retina, 11 bytes
.{100}
60$*

Try it online!
Input and output in unary. The test suite converts from and to decimal for convenience.
Doing this kind of base conversion for only up to two digits is surprisingly simple to do in unary. We just match runs of 100 1s and replace them with 60 1s. Anything that's left over would correspond to the last two digits in the decimal representation and remains unchanged.

Alice, 19 bytes
/o
\i@/.'d%~'d:'<*+

Try it online!
Explanation
Too bad I removed divmod from the language, I guess...
/o
\i@/...

This is just the usual framework for linear programs with decimal I/O operating purely in Cardinal (arithmetic) mode.
.     Duplicate input.
'd%   Mod 100.
~     Swap with other copy.
'd:   Divide by 100.
'<*   Multiply by 60.
+     Add.

Labyrinth, 19 bytes
?:_100%}#00/_60*{+!

Try it online!
Explanation
?      Read input.
:      Duplicate.
_100%  Mod 100.
}      Move off to auxiliary stack.
#00/   Divide by 100, using the stack depth to get a 1, instead of _1.
_60*   Multiply by 60.
{+     Retrieve the earlier result and add it.
!      Print.

The IP then hits a dead end and starts moving backward. When it reaches the / it attempts a division by zero which terminates the program.

Excel VBA, 29 Bytes
Anonymous VBE immediate window function that takes input from range [A1] and outputs to the VBE immediate window.
?[A1]Mod 1E2+60*[Int(A1/100)]

APL (Dyalog), 11 10 bytes
60⊥0 100⊤⊢

Try it online!
How?
0 100⊤ - encode in base 100, stopping at the second LSB, effectively producing n ÷ 100, n % 100.
60⊥ - decode in base 60

PARI/GP, 16 bytes
Straightforward:
n->n\100*60+n%100

Unfortunately this nice method is simply too long to use:
n->[60,1]*divrem(n,100)

R, 21 bytes
x=scan();x-x%/%100*40

Try it online!

I created my own solution in R and it was far less elegant than this.

You can cut the scan since most of the answers just assume the variable is already defined.

The rules are so inconsistent with regards to that. One most other challenges you have to have a function or scan to capture the value.

Common Lisp, 34 bytes
(lambda(n)(- n(*(floor n 100)40)))

Try it online!
Another port of @ovs' formula.

Symbolic Python, 66 48 46 bytes
Thanks to Jo King for -16 bytes!
__=-~-~_-_
_-=_/(__<<__^__)**__*(__-~__<<-~__)

Try it online!

Explanation
                      # input is initially in _
__=-~-~_-_            # set __ to (2+input-input) = 2
_-=                   # subtract from _:
   _/                 # _ divided by:
     (__<<__^__)**__  # (2<<2 ^ 2) ** 2 = (8^2)**2 = 100
    *                 # multiplied by
     (__-~__<<-~__)   # (2 - ~2 << -~2) = 5 << 3 = 40
                      # value in _ is the implicit output

You can use *= and -= for 59 bytes. Or change to generating 5 on the second line for -1 more

Or generate 10 for 49 bytes

@JoKing Thanks for the suggestions! I was able to get it one byte shorter by not defining ___.

Husk, 7 bytes
B60B100

Try it online! Not very exciting, just converts to base 100 and back from base 60.

This is neat! Husk and other golf-oriented languages make my brain hurt, but in a good way.

GAP, 45 bytes
Try it online!
f:=function(t) return t-QuoInt(t,100)*40;end;

Nibbles, 4 bytes (8 nibbles)
`@60`@@

    `@      # convert input in command-line arg to base
      @     # 100 (default value for @ when no input from STDIN)
`@          # and convert from base
  60        # 60

Julia 1.0, 14 bytes
~x=x-x÷100*40

Try it online!
Uses the same algorithm as Misha Lavrov's TI-Basic solution.
Julia supports implicit multiplication (40x instead of 40*x), but it takes precedence over most other operators.

05AB1E, 9 bytes
т÷60*¹т%+

Try it online!
Explanation:
т÷60*¹т%+

т         // Push number 100
 ÷        // Integer division with the input
  60      // Push number 60
    *     // Multiply with the previous result
     ¹    // Push input
      т   // Push 100 again
       %  // Modulo
        + // Add the first and the second result

Probably there is some trick with base conversions which can be achieved in 05AB1E, but I couldn't find it.

REXX, 25 bytes
arg t
say t%100*60+t//100

(Just another translations of @ovs)

05AB1E, 7 bytes
т‰ć60*+

Try it online!
Explanation
         command                              current stack
т‰ć60*+  full program. push input implicitly  [1234]
т        push 100                             [1234] [100]
 ‰       push divmod                          [12, 34]
  ć      push head extracted (n[1:], n[0])    [34] [12]
   60*   multiply by 60                       [34] [720]
      +  add and display implicitly           [754]

Milky Way, 10 bytes
':Z/v40*-!

usage: ./mw code.mwg -i 9999
Explanation:
code       explanation                          stack

'          push input to stack                  [input]
 :         duplicate ToS                        [input, input]
  Z        push 100                             [input, input, 100]
   /v      integer division (divide and floor)  [input, ⌊input/100⌋]
     40    push 40                              [input, ⌊input/100⌋, 40]
       *   multiply                             [input, ⌊input/100⌋*40]
        -  subtract                             [input - ⌊input/100⌋*40]
         ! print

Arturo, 16 bytes
$->t->t-40*t/100

Try it
Another port of ovs' Python answer.

Rattle, 14 bytes
|s/100R1*40$-~

Try it Online!
Explanation
|                  parse input
 s                 save input to memeory
  /100             divide by 100
      R1           convert to int
        *40        multiply by 40
           $       swap with value in memory
            -~     subtract value in memory from top of stack, print implicitly

Rattle, 18 bytes
|s/100R1*60$%100+~

Try it Online!
There's probably some room to reduce the byte count if someone were to pass 100 as a hard-coded argument using 100&\| instead of just |. Yes, that's a challenge!
Explanation
|                         parse input
 s                        save input to memory slot 0 (also kept on top of the stack)
  /100                    divide by 100
      R1                  reformat to int (e.g. 1.52 -> 1)
        *60               multiply by 60
           $              swap value with the value in storage
            %100          mod 100
                +~        add this value to the value in storage, print implicitly

Desmos, 20 bytes
f(x)=x-40floor(.01x)

Try it on Desmos!
Port of ovs's Python 2 answer

SageMath, 29 bytes
Run it on SageMathCell!
def f(t):return t-(t//100)*40

Thunno 2, 5 bytes
ɦB60ḋ

Try it online!
Port of Mr. Xcoder's Jelly answer
Explanation
ɦB60ḋ  # Implicit input
ɦB     # To base 100
  60ḋ  # From base 60
       # Implicit output

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


text:
Minimum rectangle cover
Rectangle covers
Suppose you have a matrix of bits, for example the following.
1 1 0 0 0 1 1 0
1 1 1 1 0 1 1 1
0 1 1 1 0 1 1 1
1 1 0 1 1 1 1 0
1 1 0 1 1 1 0 1

We would like to find a rectangle cover for this matrix.
It is a set of rectangular subsets of the matrix that don't contain any 0s, but together contain all the 1s.
The subsets are not required to be disjoint.
Here is an example of a rectangle cover for the above matrix.
+----+         +----+
|1  1| 0  0  0 |1  1| 0
|    |         |    |
|  +-|-----+   |    |+-+
|1 |1| 1  1| 0 |1  1||1|
+----+     |   |    || |
   |       |   |    || |
 0 |1  1  1| 0 |1  1||1|
   +-------+   |    |+-+
+----+   +-----|-+  |
|1  1| 0 |1  1 |1| 1| 0
|    |   |     +----+
|    |   |       |   +-+
|1  1| 0 |1  1  1| 0 |1|
+----+   +-------+   +-+

The number of rectangles in this cover is 7.
The task
Your input is a rectangular matrix of bits, taken in any reasonable format.
You can assume it contains at least one 1.
Your output is the minimum number of rectangles in a rectangle cover of the matrix.
The lowest byte count wins.
Standard code-golf rules apply.
Test cases
[[1]] -> 1
[[1,1]] -> 1
[[1],[1]] -> 1
[[1,0,1]] -> 2
[[1,0],[0,0]] -> 1
[[1,0],[0,1]] -> 2
[[1,0],[1,1]] -> 2
[[1,1,1],[1,0,1]] -> 3
[[0,1,0],[1,1,1],[0,1,0]] -> 2
[[1,1,1],[1,0,1],[1,1,1]] -> 4
[[1,1,0],[1,1,1],[0,1,1]] -> 2
[[1,0,1,0],[1,1,1,1],[1,0,1,0]] -> 3
[[1,1,1,0],[1,0,1,0],[1,1,1,1],[0,0,1,0]] -> 4
[[1,1,1,0],[1,0,1,0],[1,1,1,1],[0,0,1,1]] -> 5
[[1,1,1,0],[1,0,1,0],[1,1,1,1],[0,1,1,1]] -> 4
[[1,1,0,0],[1,1,1,0],[0,1,1,1],[0,0,1,1]] -> 3
[[0,1,0,0],[0,1,1,1],[1,1,1,0],[0,0,1,0]] -> 4
[[0,0,1,0,0],[0,1,1,1,0],[1,1,1,1,1],[0,1,1,1,0],[0,0,1,0,0]] -> 3

Is this inspired by Karnaugh map?

@ThePirateBay More by nondeterministic communication complexity.

@ThePirateBay for a k-map all the rectangles should have power-of-two dimensions.

@Sparr. Yes, I know it. I just asked was it maybe the inspiration for this challenge.

Useful test case for greedy approaches: [[0,1,0,0],[0,1,1,1],[1,1,1,0],[0,0,1,0]], 4.

Note that this Rectilinear Image Compression problem is known to be NP-hard (Garey & Johnson, SR25).

Python 2, 318 315 271 bytes
Mr.Xcoder, ovs and Jonathan Frech saved a lot of bytes
p=range
def f(x,i=0,j=-1):z=len(x[0]);j+=1;i+=j/z;j%=z;return i<len(x)and(x[i][j]and-~min([f([[v,v[:j]+[2]*(r-j)+v[r:]][i<=y<=e]for y,v in enumerate(x)],i,j)for e in p(i,len(x))for r in p(j+1,z+1)if all(all(k[j:r])for k in x[i:e+1])]+[f(x,i,j)-1]*(x[i][j]>1))or f(x,i,j))

Try it online!

Jelly,  25  24 bytes
FJ‘ṁ×⁸ẆZ€Ẇ€ẎŒPFQP$$ÐṀL€Ṃ

Try it online! A typical golf-complexity solution, don't even bother with larger test cases, they will time out (the power set of all possible rectangles is inspected*)
How?
Forms all the possible rectangles that may be made. Takes the power-set of those rectangles and inspects them only keeping those sets which both contain no zeros and contain each of the ones at least once.
To achieve the "keeping those sets which both contain no zeros and contain each of the ones at least once" part the code first coerces the ones to a set of distinct integers greater than one, leaving the zeros as they are so that it becomes "finding the maxima of the product of the unique values".
FJ‘ṁ×⁸ẆZ€Ẇ€ẎŒPFQP$$ÐṀL€Ṃ - Link: list of lists of ones and zeros, M
F                        - flatten M into a single list
 J                       - range of length = [1,2,3,...,len(flattened(M))]
  ‘                      - increment       = [2,3,4,...,len(flattened(M))+1]
   ṁ                     - mould like M - reshapes it just like M again
     ⁸                   - chain's left argument, M
    ×                    - multiply (vectorises) - unique integers > 1 at M's 1s and 0s at M's 0s
      Ẇ                  - non-empty sublists - i.e. row selections
       Z€                - transpose €ach
         Ẇ€              - non-empty sublists of €ach - column selections of those
           Ẏ             - tighten - a flat list of all of the rectangles
            ŒP           - power-set - all possible selections of rectangles
                   ÐṀ    - filter keep those for which the following is maximal:
                  $      -   last two links as a monad:
              F          -     flatten
                 $       -     last two links as a monad:
               Q         -       de-duplicate
                P        -       product
                     L€  - length of €ach - # of rectangles used by each full-cover
                       Ṃ - minimum

* For an n by m matrix that's ways(n,m) = 2^(T(n)×T(m)), so...
ways(3,2) = 2^((3+2+1)×(2+1)) = 2^18 = 262,144 (the TIO link)
ways(3,3) = 2^((3+2+1)×(3+2+1)) = 2^36 = 68,719,476,736
ways(3,4) = 2^((3+2+1)×(4+3+2+1)) = 2^60 = 1,152,921,504,606,846,976
ways(5,5) = 2^225 ~= 5.4e+67 (the largest test case)
ways(8,5) = 2^540 ~= 3.6e+162 (the example)

Would FJṁ×⁸ẆZ€Ẇ€ẎŒPFQS$$ÐṀL€Ṃ work for -1? No time to test rn.

No, because a cover that neglected (only) the one coerced to 1 would have the same product as a valid cover (e.g. turn the eight by five example half a turn and it would (in theory) return 6 as it would neglect to cover the top-left cell and consider it valid.)

...even easier - the test case [[1,0],[0,1]] would return 1 rather than 2.

JavaScript, 434 bytes
Code:
for(_='),d=...-1||(,Ad<=a,u[o][n]=d,    =0,(e,r,C,m))&&()=>.map((h((A,n,on<e|o<r|n>C|o>mf=u=>(q(s=(e>C[e,C]=[C,e]r>m[r,m]=[m,r]lk=1,k&=!!A)kl|=&1,=2k&lh=f=>uA,$ABf(B,$))))(($,Bae=r=C=m=,d=to-Bt=n$&n>$e   C=nn+1~ee   C=ttn-$t=oB&o>Br    m=oo+1~rr   m=tq+=sg=[],h((ca||g.push(c)gigb,j(p=1,q+=i<j&&s(b)q)';G=/[-]/.exec(_);)with(_.split(G))_=join(shift());eval(_)

Hexdump (because of unprintable characters):
66 6F 72 28 5F 3D 27 29 2C 13 13 64 3D 12 2E 2E 2E 11 2D 31 10 7C 7C 28 0F 2C 41 0F 64 3C 3D 0E 61 2C 0C 75 5B 6F 5D 5B 6E 5D 0B 3D 64 2C 09 3D 30 2C 08 28 65 2C 72 2C 43 2C 6D 07 29 29 13 06 26 26 28 05 29 3D 3E 04 2E 6D 61 70 28 28 03 68 28 28 41 2C 6E 2C 6F 04 02 02 6E 3C 65 7C 6F 3C 72 7C 6E 3E 43 7C 6F 3E 6D 0F 01 66 3D 75 3D 3E 28 71 08 28 73 3D 07 04 28 65 3E 43 05 5B 65 2C 43 5D 3D 5B 43 2C 65 5D 13 72 3E 6D 05 5B 72 2C 6D 5D 3D 5B 6D 2C 72 5D 13 6C 08 6B 3D 31 2C 01 6B 26 3D 21 21 41 29 13 6B 05 01 6C 7C 3D 0B 26 31 2C 0B 3D 32 06 6B 26 6C 13 68 3D 66 3D 3E 75 03 41 2C 24 04 41 03 0C 42 04 66 28 0C 42 2C 24 29 29 29 29 28 28 0C 24 2C 42 04 61 10 0F 65 3D 72 3D 43 3D 6D 3D 10 2C 64 3D 74 08 02 6F 2D 42 0F 74 3D 6E 0E 24 26 6E 3E 24 05 65 09 43 3D 6E 10 12 6E 2B 31 06 7E 65 0F 65 09 43 3D 74 12 74 08 02 6E 2D 24 0F 74 3D 6F 0E 42 26 6F 3E 42 05 72 09 6D 3D 6F 10 12 6F 2B 31 06 7E 72 0F 72 09 6D 3D 74 13 71 2B 3D 73 07 06 67 3D 5B 5D 2C 68 28 28 0C 11 63 04 61 10 7C 7C 67 2E 70 75 73 68 28 63 29 13 67 03 0C 69 04 67 03 62 2C 6A 04 28 70 3D 31 2C 71 2B 3D 69 3C 6A 26 26 73 28 11 0C 11 62 29 06 71 29 27 3B 47 3D 2F 5B 01 2D 13 5D 2F 2E 65 78 65 63 28 5F 29 3B 29 77 69 74 68 28 5F 2E 73 70 6C 69 74 28 47 29 29 5F 3D 6A 6F 69 6E 28 73 68 69 66 74 28 29 29 3B 65 76 61 6C 28 5F 29

Try it online!
It is not very golfy, but at least it works very fast. All test cases can be computed in few milliseconds.
Ungolfed
f=mat=>(
  iterate=f=>mat.map((A,x)=>A.map((a,y)=>f(a,y,x))),
  fill=(x1,y1,x2,y2)=>(
    x1>x2&&([x1,x2]=[x2,x1]),
    y1>y2&&([y1,y2]=[y2,y1]),
    isFilled=0,

    canBeFilled=1,
    iterate((A,X,Y)=>X<x1|Y<y1|X>x2|Y>y2||(
      canBeFilled&=!!A
    )),

    canBeFilled&&(
      iterate((A,X,Y)=>X<x1|Y<y1|X>x2|Y>y2||(
        isFilled|=mat[Y][X]&1,
        mat[Y][X]=2
      ))
    ),

    canBeFilled&isFilled
  ),

  rectangles=0,

  iterate((a,x,y)=>a-1||(
    x1=y1=x2=y2=-1,

    start=end=0,
    iterate((A,X,Y)=>Y-y||(
      end=X,
      A||(
        start<=x&X>x&&(x1=start,x2=X-1),
        start=X+1
      )
    )),
    ~x1||(x1=start,x2=end),

    start=end=0,
    iterate((A,X,Y)=>X-x||(
      end=Y,
      A||(
        start<=y&Y>y&&(y1=start,y2=Y-1),
        start=Y+1
      )
    )),
    ~y1||(y1=start,y2=end),

    rectangles+=fill(x1,y1,x2,y2)
  )),

  ones=[],
  iterate((a,...c)=>a-1||ones.push(c)),
  ones.map((a,i)=>ones.map((b,j)=>(
    M=1,
    rectangles+=i<j&&fill(...a,...b)
  ))),

  rectangles
)

Explanation
It uses similar algorithm like for solving Karnaugh maps. Firstly it tries to find at least one 1 which can be part of exactly one non-extensible rectangle. By non-extensible I mean if we extend it in any direction (up, left, right, down) it will include at least one 0 (or will go beyond the matrix bounds). When such 1 is found, find the biggest rectangle that includes it and flag all 1s in that rectangle. Repeat until there is no more non-flagged 1s that satisfy these conditions.
In some cases (like in the 16th test case) there are 1s that left over after applying the first step. Then enumerate all these 1s and apply some kind of enhanced brute-force search. This step is rarely applied, and even in these cases, we need to brute-force check only one or two combinations, so it should work very fast even for larger test cases.

Python 3+Numpy, 253 bytes
from numpy import*
from itertools import*
R=range
P=product
def f(A):s=A.shape;r=random.rand(*s);return[N for N in R(1,sum(A)+1)for m in P(*[[(A*r)[a:b+1,c:d+1]for a,c,b,d in P(*[*map(R,s)]*2)]]*N)if len({e*all(b)for b in m for e in b.flat})==sum(A)][0]

Try it online!
This is quite slow due to generating more than the full power set of all rectangles. I also have an optimized version to test the slower test cases, which makes three optimizations:

Uses combinations of N rectangles instead of cartesian product to avoid duplicate rectangles
Uses next(...) instead of [...][0] to terminate as soon as a single covering is found with minimal number of rectangles
Prunes out rectangles that are subsets of larger rectangles containing only 1s (96% reduction in rectangles for the largest test case)

Semi-ungolfed
from numpy import*
from itertools import*
R=range
# P is the itertools product
P=product

def f(A):
    # take input as a numpy array A
    s = A.shape;
    # r is a weight matrix that gives a distinct value to each entry in A
    # (probability 1)
    # Longer alternative (can be inlined): r=~reshape(range(h*w),(h,w))
    r = random.rand(*s);
    return [
        # We're finding number of rectangles N
        N
        # In the range [1..sum(A)] where sum(A) is the number of 1s (upper bound for # rectangles)
        for N in R(1, sum(A)+1)
        # m is a combination of N possible rectangles
        for m in P(
            # (this is Cartesian product instead of combinations, but duplicates
            # provide no benefit)
            # P(*[...]*N) === product(..., repeat=N)
            *[
                [
                    # A*r is modified array such that each 1 is given
                    # a distinct value and all 0s remain 0

                    # all rectangles in A*r
                    (A*r)[a:b+1, c:d+1]
                    for a,c,b,d in P(*[*map(R,s)]*2)
                ]
            ]*N
        )
        # Test that each rectangle contains no 0s and the combination of rectangles covers all 1s:
        if len({e*all(b) for b in m for e in b.flat})==sum(A)
    # Get the first N with a valid covering
    # must be min N because N is generated in order
    ][0]