# Question
Title: Shortest a -> b -> (a -> b) function in Haskell
I got the following question at a test:

> Write a function `f` with the following type `a -> b -> (a -> b)`. `a` and `b` should not be bound in any sense, the shorter the code, the better.

I came up with `f a b = \x -> snd ([a,x],b)`. Can you find something tinier?

**Currently the winner is: `f _=(.f).const`**

# Answer
Your example can be shrunk by getting rid of the anonymous function on the right-hand side:

```
f a b x = snd ([a,x],b)

```

This works because the type `a -> b -> a -> b` is equivalent to `a -> b -> (a -> b)` in Haskell.
> 12 votes

# Answer
The function `f _=(.f).const` is actually of a more general type than `f :: a -> b -> (a -> b)`, namely `f :: a -> b -> (c -> b)`. If no type signature is given, the type inference system infers a type of `f :: a -> b -> (a -> b)`, but if you include the type signature `f :: a -> b -> (c -> b)` with the exact same definition, Haskell will compile it without issue and will report consistent types for the partial applications of f. There is probably some deep reason why the type inference system is stricter than the type checking system in this case, but I don't understand enough category theory to come up with a reason as to why this should be the case. If you are unconvinced, you are welcome to try it yourself.
> 5 votes

# Answer
Given `ScopedTypeVariables`, I came up with this:

```
f (_::a) b (_::a) = b

```

If you shrink down both my function and yours, mine is a hair shorter:

```
f(_::a)b(_::a)=b
f a b x=snd([a,x],b)

```

Of course, you're probably not allowed to rely on `ScopedTypeVariables` :P.
> 4 votes

---
Tags: code-golf, functional-programming, haskell
---


title: Produce a Simple Station Model

text:
# Question
Title: Produce a Simple Station Model
A station model is a diagram for recording the weather at a certain place and time.

# Challenge

You must write the shortest code possible to graphically output a simplified (explained later) station model.

# Ticks

A tick is a line on the wind barb. A 50 knot tick is a triangle. A 10 knot tick is a line. A 5 knot tick is half the length of a 10 knot tick. The windspeed is indicated by summing the ticks, using the largest value symbols whenever possible. The ticks start at the end of the line and are arranged in descending order of size toward the circle. An exception is 5 knots, where the tick is placed a short distance away from the end (to avoid ambiguity with 10 knots.)

Here is some pseudocode to calculate the ticks required

```
set f=int(s/5)
set t=int(f/2)
f=f-(t*2)
set ft = int(t/5)
t=t-(ft*5)

```

Where f is the number of 5 knot ticks, t is the number of 10 knot ticks and ft is the number od 50 knot ticks. (This rounds down to the nearest 5, but your code should round up or down, whichever is nearer.) Note that there is only ever one 5 knot tick.

# Other

You may only display two things on your station model: wind speed and direction. These must be supplied by the user: hardcoding is not permitted. The wind speed must be a positive integer in knots while the wind direction must be in letters (e.g. NNE, W, ESE). 16 points of the compass will be considered (up to three letters.) See http://en.wikipedia.org/wiki/Points\_of\_the\_compass

The 50 knots tick must be as in the picture above.

Set cloud cover to clear (the circle must be empty.) The highest wind speed allowed is 201 knots (round it to 200).

Since the wind ticks only increase in imcrements of 5, round all wind speeds to the nearest 5.

As always, since this is code golf, the shortest code wins.

# Examples

All of the following have a cloud cover of clear.

20 knots, SW (225°)

15 knots, N (0°)

# Test cases

50 knots, NNE
0 knots
12 knots S
112 knots WNW

# Answer
> 2 votes
# BBC BASIC, 273 ASCII characters (not golfed yet)

Emulator at http://www.bbcbasic.co.uk/bbcwin/bbcwin.html

Parsing the direction is a dirty hack. I simply take a walk through a cartesian grid for each letter input. They aren´t echoed to the screen, and the input is terminated when a space is received.

As this is codegolf, I don't bother to normalise the direction vector. Therefore the size of the symbol drawn is dependent on the number of characters input. The proportions are the same for all inputs, however. Also, for the 3-letter inputs the angle is 4 degrees closer to the diagonal than it should be. For example, NNE is atan(0.5)=26.57 degrees instead of the correct 22.5 degrees, but it is barely noticeable. Both these points could be corrected for about 20-30 characters.

After the direction, the speed is input (this is echoed to the screen and terminated with a newline.)

```
  x=0
  y=0
  REPEAT
    d=GET                             :REM get character from keyboard
    x+=(d=87)-(d=69)                  :REM d=87 evaluates to -1 if "W", d=69 is -1 if "E"
    y+=(d=83)-(d=78)                  :REM d=83 evaluates to -1 if "S", d=69 is -1 if "N"
  UNTILd=32
  x*=20                               :REM boost the sizes of x and y
  y*=20                               :REM normalization code would go here
  INPUTs
  s=INT(s/5+.5)                       :REM divide s by 5 and round to nearest int. 50-tick=10, 10-tick=2, 5-tick=1
  MOVE600,500                         :REM move to centre of circle
  PLOT145,x,y                         :REM draw circle centred at 600,500 with 600+x,500+y on its edge. cursor remains at the latter position.
  IFs=0END                            :REM exit if wind=0
  DRAWBY 9*x,9*y                      :REM draw the shaft of the arrow, 9 units long, from current position
  IFs>1 MOVEBY x,y                    :REM if rounded windspeed >5 move one more space out.
  WHILEs>1                            :REM while there are still 50-ticks and 10-ticks to draw
    MOVEBY 2*y,-2*x                   :REM move 2 units clockwise of the shaft
    PLOT1-(s>9)*80,-2*y-x,2*x-y       :REM draw a diagonal line back to the shaft. If s is 10 or over, plot mode 81 will take the last 2 positions of the graphics cursor and draw a triangle.
    s-=2-(s>9)*8                      :REM Decrement s by 2 or 10, according to the last barb drawn.
  ENDWHILE
  IFs MOVEBY -x,-y:DRAWBY x/2+y,y/2-x :REM If s=1 draw the 5-tick. Unlike the other ticks, it is drawn from its root outwards.

```

**Output**

All the test cases from the quesion are shown, plus two more to illustrate 2-letter directions:

```
50 knots, NNE
0 knots
12 knots S
112 knots WNW
195 knots SE
5 knots SW

```

In order to show them all together, I didn't clear the screen between runs. The different sizes (but constant proportions) of the arrows can be seen.

---
Tags: code-golf, graphical-output
---


# Question
Title: Generate the outline of an island from a seed
The challenge is to draw the outline of an 'island', generated using a seed as input.

* Input (seed): string of 6 characters (exactly) allowing only lowercase letters (i.e. abcdefghijklmnopqrstuvwxyz) - examples: 'island', 'aaaaaa', 'jhgcfj'
* Each seed is to give a unique island (i.e. no two seeds will give the same output)
* No output is to be a transformation of another seed's output. That's translation, reflection, rotation, scaling or any combination thereof.
* Using the same seed should always give the same output
* Output: 600px by 600px image

A valid island is drawn using a single line, which:

* forms a closed loop
* is 1px thick with no smoothing, blurring etc.
* is continuous (i.e. after drawing a pixel the next pixel will be in one of the 8 adjoining spaces that isn't occupied)
* does not cross itself at any point
* does not leave the boundaries of the image
* is black (#000), on a background of white (#FFF)
* has no lines of reflective symmetry
* must enclose white space

Source code has a limit of 500 bytes.

Aside from that, popularity decides; most votes wins.

# Answer
# BBC basic

Here's a very simple algorithm, which could be refined for more realism. If there are further changes in the rules I'm willing to change / delete.

take the 6 character string and add `}@` to ensure asymmetry (this particular choice of characters gives islands that vaguely resemble Antarctica)

draw a line that connects 8 points at 45 degree intervals, with distance from the centre determined by the ASCII code.

```
  INPUT a$
  a$=a$+"}@"
  MOVE 364,300
  FOR i=1 TO 8
    r=4*ASC(MID$(a$,i))-192
    DRAW 300+r*COS(i*PI/4),300+r*SIN(i*PI/4)
  NEXT

```
> 3 votes

# Answer
# Algoid

Algoid is a language similar to LOGO or Turtle and is *almost* entirely graphics based.

```
algo.hide()
algo.setBgColor(15)
algo.setStroke(1)
algo.setColor(0)
algo.goTo(-400,100)
set seed="put seed here".lower()
set letters = "abcdefghijklmnopqrstuvwxyz"
set sides=seed.length()
for (set i=0;i<sides-(sides/6);i++) {
    set letter = seed.getChar(i%seed.length())
    set value = letters.indexOf(letter)*5
    set turn = 360/seed.length()
    algo.go(math.sin(value)*(1500/seed.length()))
    algo.turnRight(turn)
}
algo.lineTo(-400,100)

```

## Seed: `supercalifragilisticexpialiadocious even though the sound of it is rather quite atrocious`

## Seed: `islands in the stream`
> 0 votes

---
Tags: popularity-contest, graphical-output
---


title: Another Euler Brick in the Wall

text:
# Question
Title: Another Euler Brick in the Wall
A Euler Brick is a cuboid where the length of all the edges are integers and all of the diagonals of the faces are integers as well. All sides must also be different.

Your program has to find as many different Euler Bricks where the sides are less than L within the time M (L and M will be defined later).

All of your calculated bricks have to be unique. This means that if your dimensions are the same, just in a different order, it must not be counted.

To calculate a brick means to find the lengths of the edges and the lengths of the diagonals of the faces of a valid Euler Brick.

Your bricks must also be indivisible by each other. In the same way that the Pythagorean triplet `6, 8, 10` is divisible by `3, 4, 5`, your bricks must ***not*** be divisible by each other.

To test your program, I will need to the following:

1. The language your code is written in
2. A command to run your code
3. Your code

Your score will be the average number of bricks your program calculates (running the program five times). To do this, I will run your program and end it after M minutes have elapsed. Once you have submitted your answer, I will add a comment on your answer telling what your score is. If you make an edit to your code, please notify me directly so I can find your score again.

For that reason, I need your program to print the number of bricks either at throughout the running or at the end. This can be done like so (in Python it would help if people told me how to do this in other languages for this example):

```
try:
    # Calculation goes here

except KeyboardInterrupt: # I will use Ctrl-C
    print(numberofbricks)
    exit()

```

For this challenge `L=10^30` and `M=2 minutes`. In the event of a tie, the actual time taken to calculate all of the bricks will be used. The lower time wins.

I will find your time using the script below. All programs will be tested on the same machine.

```
import time, subprocess
command = # How do you run your program?
s=time.time()
subprocess.Popen(command, shell=True)
e=time.time()
print(e-s)

```

## Leaderboard

```
1. Peter Taylor  - 5731679685.5 bricks per minute
2. Steve Verrill - 680262303 bricks per minute
3. Beta Decay    - 0.5 bricks per minute

```

# Answer
> 10 votes
## C using Saunderson's parameterisation and Berggren's tree

In 1740, Saunderson found the parameterisation that if `(a, b, c)` is a Pythagorean triple (i.e. `a^2 + b^2 = c^2`) then `(a(2b-c)(2b+c), b(2a-c)(2a+c), 4abc)` is a *rational cuboid* (this was before Euler studied them) with diagonals `(c^3, a(5b^2+a^2), b(5a^2+b^2))`. This doesn't generate all Euler bricks. Note that if the brick is primitive iff the Pythagorean triple is primitive.

If `(x, y, z)` is an Euler brick then so is `(xy, xz, yz)`. Applying this once to a Saunderson brick creates a new brick which isn't Saunderson and which can be made primitive with division by `ab`. Applying the same transformation a second time gives the non-primitive `xyz(x, y, z)`.

In 1934, Berggren discovered that the primitive Pythagorean triples form a ternary tree rooted at `(3, 4, 5)` which can be generated by a simple matrix multiplication and which contains each triple precisely once.

This implementation generates primitive Pythagorean triples and stores them in a stack, limiting the memory usage to 1.5GB. An earlier version used a circular buffer, but the stack gives much better results. This is probably a combination of fewer values being discarded and better cache locality.

Thanks to Steve Verrill for pointing out some bugs and for suggesting the use of a stack instead of a circular buffer. I've also followed him in removing the conjugate bricks for speed: previously the search space (minus the discarded branches) was exhausted within the two minutes, and there was value in spending time to get a few conjugates. But the new version can easily run for 5 minutes (as I discovered in the process of learning the value of the `volatile` keyword!), and most of the conjugates overflow, so on average the tests are wasted time.

```
#include <stdlib.h>
#include <inttypes.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>

// Stack size. This is 1.5GB of memory.
#define N 33554432

typedef unsigned __int128 scalar;

typedef struct {
    scalar a, b, c;
} triple;

// Stack operations
#define take(st) st[--stp];
#define offer(A,B,C) if (stp < N) { st[stp].a=(A); st[stp].b=(B); st[stp].c=(C); stp++; }

volatile sig_atomic_t stop;

void handler(int sig, siginfo_t *siginfo, void *context) {
    stop = 1;
}

int main(int argc, char **argv) {
    // Register interrupt handler
    stop = 0;
    struct sigaction act;
    memset(&act, 0, sizeof(act));
    act.sa_sigaction = &handler;
    act.sa_flags = SA_SIGINFO;
    if (sigaction(SIGINT, &act, NULL) < 0) return 1;

    // L = 10^30
    const scalar L = ((scalar)0xc9f2c9cd0UL << 64) + 0x4674edea40000000UL;
    const scalar T = (scalar)1 << 64;   // used in an anti-overflow test

    // To avoid the optimiser removing the calculation of the bricks.
    int writeToStdOut = argc > 1;

    triple *st = (triple *)malloc(N * sizeof(triple));
    if (!st) return 2;

    uint32_t stp = 1; // Index of first empty space in stack
    st[0].a = 3; st[0].b = 4; st[0].c = 5;
    uint64_t count = 0;

    while (stp > 0) {
        if (stop) break;
        triple t = take(st);

        // Extend queue of Pythagorean triples
        offer(t.a + ((t.c - t.b) << 1), ((t.a + t.c) << 1) - t.b, ((t.a - t.b + t.c) << 1) + t.c)
        offer(t.a + ((t.c + t.b) << 1), ((t.a + t.c) << 1) + t.b, ((t.a + t.b + t.c) << 1) + t.c)
        offer(-t.a + ((t.c + t.b) << 1), ((-t.a + t.c) << 1) + t.b, ((-t.a + t.b + t.c) << 1) + t.c)

        // Saunderson brick
        scalar x = t.b * ( ((t.a << 1) >= t.c) ? ((t.a << 1) - t.c) : (t.c - (t.a << 1)) ) * ((t.a << 1) + t.c);
        scalar y = t.a * ((t.b << 1) - t.c) * ((t.b << 1) + t.c);
        scalar z = t.a * t.b * t.c << 2;
        scalar u = t.c * t.c * t.c;
        scalar v = t.b * (t.b * t.b + 5 * t.a * t.a);
        scalar w = t.a * (t.a * t.a + 5 * t.b * t.b);
        count++;
        if (writeToStdOut) {
            printf("Sides: 0x%016"PRIx64"%016"PRIx64, (uint64_t)(x >> 64), (uint64_t)x);
            printf(", 0x%016"PRIx64"%016"PRIx64, (uint64_t)(y >> 64), (uint64_t)y);
            printf(", 0x%016"PRIx64"%016"PRIx64, (uint64_t)(z >> 64), (uint64_t)z);
            printf("; diags 0x%016"PRIx64"%016"PRIx64, (uint64_t)(u >> 64), (uint64_t)u);
            printf(", 0x%016"PRIx64"%016"PRIx64, (uint64_t)(v >> 64), (uint64_t)v);
            printf(", 0x%016"PRIx64"%016"PRIx64"\n", (uint64_t)(w >> 64), (uint64_t)w);
        }
    }

    printf("%ld\n", count);

    return 0;
}

```

Compiles with `gcc -O3 euler_brick.c -o euler_brick` and handles `SIGINT` (Ctrl-C). On my computer the earlier circular buffer version ran out of usably small Pythagorean triples after 85 seconds having found `843035517` (0.843 thousand million) Euler bricks. The new version runs to the two minutes (tested with `timeout -sINT 2m ./euler_brick`) and finds about 9.1 thousand million bricks. Exact numbers vary from run to run; the highest I've observed is `9113459216`.

Note that this is single-threaded code. The process is embarrassingly parallel - just start each thread going down a different branch of the tree - and so the limitation to scaling it to multicore would be the shared memory bus.

# Answer
> 5 votes
# C using Saunderson's parameterisation and a different tree generation method.

This is heavily influenced by Peter Taylor's answer, and by the following page: https://sites.google.com/site/tpiezas/0021. For consistency, my variable naming convention largely follows Peter's.

Instead of using a buffer, I use recursion to generate the three children of each node of the tree. The tree I generate is equivalent to Berggren's tree, but I use a two-parameter method (mainly for interest and variation.) The parameters `p` and `q` for all integers generate a pythagorean triple `a=p^2-q^2, b=2pq, c=p^2+q^2`. If we want to limit this to primitive triples only, we start with the vector (2,1) and multiply by the 2x2 matrices below. This is equivalent to Berggren's / Barning's method, in which we start with the vector (3,4,5) and multiply by the 3x3 matrices below. See http://en.wikipedia.org/wiki/Tree\_of\_primitive\_Pythagorean\_triples .

```
Barning's matrices                       2x2 matrices
1 -2  2      1  2  2     -1  2  2        2 -1    2  1    1  2
2 -1  2      2  1  2     -2  1  2        1  0    1  0    0  1
2 -2  3      2  2  3     -2  2  3

```

It can be seen from Barning's matrices that the hypotenuse `c` of the second child of each node will be between 3 and 7 times larger than that of its parent (more advanced treatment would narrow this range.) the growth rates of the other branches are rather slower.

In practice it was necessary to limit the depth of recursion in order to avoid stack overflow (segmentation fault.) However, it seems likely that only a few bricks were lost. Peter's program runs on my machine in about 6 minutes and generates `843035517` Euler bricks. My program takes just over twice as long and generates `1688135295` bricks with recursion depth limited to `5000`, or `1671621046` bricks with depth limited to `1000`. Therefore the rate of generation is about the same. With depth limited to `40`, `1134616080` bricks are generated, of which 1131433861 are Saunderson and only 3182219 are conjugate. And the program runs about twice as fast with the code for generating conjugate bricks commented out!

Instead of generating the conjugate brick of `(x,y,z)` as `(yz,xz,xy)` I generate a conjugate brick `ab` times smaller. To do this intermediate values `x',y',u',v'` are stored during the calculation of `x,y,z,u,v,w`.

```
#include <inttypes.h>

int writeStdOut,count=0;

typedef __int128 scalar;

scalar L=(scalar)1000000*1000000*1000000*1000000*1000000,T=(scalar)1<<124;

f(scalar p, scalar q, int depth){
  scalar p2,q2,
         a,b,c,a2,b2,c2,
         uprime,vprime,u,v,w,
         xprime,yprime,x,y,z;

  p2=p*p;q2=q*q;
  a=p2-q2;b=p*q<<1;c=p2+q2;

  z=a*b*c<<2;
  if(z<L){
    a2=a*a;b2=b*b;c2=c*c;

    xprime=(b2<<2)-c2;yprime=(a2<<2)-c2;
    if(xprime<0)xprime=-xprime;if(yprime<0)yprime=-yprime;
    x=a*xprime;y=b*yprime;

    uprime=b2*5+a2;vprime=a2*5+b2;
    u=a*uprime;v=b*vprime; w=c2*c;

    count++;
    if (writeStdOut) {
      printf("Sides: 0x%016"PRIx64"%016"PRIx64, (uint64_t)(x >> 64), (uint64_t)x);
      printf(", 0x%016"PRIx64"%016"PRIx64, (uint64_t)(y >> 64), (uint64_t)y);
      printf(", 0x%016"PRIx64"%016"PRIx64, (uint64_t)(z >> 64), (uint64_t)z);
      printf("; diags 0x%016"PRIx64"%016"PRIx64, (uint64_t)(u >> 64), (uint64_t)u);
      printf(", 0x%016"PRIx64"%016"PRIx64, (uint64_t)(v >> 64), (uint64_t)v);
      printf(", 0x%016"PRIx64"%016"PRIx64"\n", (uint64_t)(w >> 64), (uint64_t)w);
    }
    if(T/a/c>xprime && T/b/c>yprime){
      x=a*c*xprime<<2;y=b*c*yprime<<2; if(x<0 | y<0)puts("overflow");
      if(x<L && y<L){

        z=xprime*yprime;
        u=uprime*yprime;v=vprime*xprime;w=c2*c2<<2;
        count++;
        if (writeStdOut) {
          printf("SIDES: 0x%016"PRIx64"%016"PRIx64, (uint64_t)(x >> 64), (uint64_t)x);
          printf(", 0x%016"PRIx64"%016"PRIx64, (uint64_t)(y >> 64), (uint64_t)y);
          printf(", 0x%016"PRIx64"%016"PRIx64, (uint64_t)(z >> 64), (uint64_t)z);
          printf("; diags 0x%016"PRIx64"%016"PRIx64, (uint64_t)(u >> 64), (uint64_t)u);
          printf(", 0x%016"PRIx64"%016"PRIx64, (uint64_t)(v >> 64), (uint64_t)v);
          printf(", 0x%016"PRIx64"%016"PRIx64"\n", (uint64_t)(w >> 64), (uint64_t)w);
        }

      }
    }
    if(depth<40){f((p<<1)-q,p,depth+1);f((p<<1)+q,p,depth+1);f(p+(q<<1),q,depth+1);}
  }
}

main(int argc, char **argv){
  writeStdOut=argc>1;
  f(2,1,0);
  printf(" %d bricks",count);
}

```

# Answer
> 1 votes
# Python 3 - Brute forcing it

## Edit: This produces a measly 0.5 bricks per minute...

To get the ball rolling again, I decided to write a simple entry. As always with brute force methods, it's extremely slow.

```
def mult(x,y):
    c=0
    for i in range(len(x)):
      if y[i]%x[i]==0:c+=1
    if c==3:return True
    return False

pyth=lambda x,y:True if (x**2+y**2)**0.5==int((x**2+y**2)**0.5) else False
prev=[]
ymax=245
zmax=269
try:
    for x in range(44,10**30):
        for y in range(117,ymax):
            ymax+=1
            for z in range(240,zmax):
                zmax+=1
                curr=[x,y,z]
                eq=0
                ml=0
                for i in range(3):
                    for j in range(3):
                        if i!=j:
                            if curr[i]==curr[j]:
                                eq+=1
                for k in prev:
                    if mult(curr, k):
                        ml+=1
                if eq==0 and ml==0:
                    f=pyth(curr[0],curr[1])
                    s=pyth(curr[0],curr[2])
                    b=pyth(curr[1],curr[2])
                    if f and s and b:
                        prev.append(curr)
except KeyboardInterrupt:
    print('\n\n'+str(len(prev)))

```

---
Tags: code-challenge, math, fastest-code
---


title: Drawing in Slashes

text:
# Question
Title: Drawing in Slashes
Write a program that takes in a rectangular block of text made up of `X`'s and `.`'s, such as this rough `A`:

```
......
..XX..
.X..X.
.XXXX.
.X..X.
.X..X.

```

Output a representation of this grid rotated 45 degrees counterclockwise by drawing a slash — forward or backward depending on context — everywhere an `X` borders a `.` or the side of the grid (with spaces filling in the rest):

```
 /\/\
/ /\ \
\/ /  \
/\/ /\ \
\  /  \/
 \ \
  \ \
   \/

```

The number of trailing and leading spaces (and newlines) doesn't matter as long as the shape of the `X`'s in the input is maintained by the slashes. It's ok to trim extra rows or columns of `.`'s.

For I/O you may use any combination of stdin/stdout/files/command line parameters. For example your script might take in a file name of the `X.` pattern and rewrite the file with the slash pattern. Or your script might take in the `X.` pattern from stdin line by line (pressing `d` when done) and output the result to stdout.

The input may be arbitrarily large, but you may assume it is always well formatted.

No characters besides `/ \` and newlines should be in any output.

# Scoring

The shortest code in bytes wins. Use https://mothereff.in/byte-counter as a byte counter if you use non-ASCII characters.

**Bonus:** Minus 50 bytes if you can change (replace, not remove) one character in your program so it outputs the slash grid rotated 45 degrees *clockwise*, e.g.:

```
   /\/\
  / /\ \
 /  \ \/
/ /\ \/\
\/  \  /
    / /
   / /
   \/

```

# Input Samples

```
XXXXXXXXX
X.......X
X.XXXXX.X
X.X...X.X
X.X.X.X.X
X.X...X.X
X.XXXXX.X
X.......X
XXXXXXXXX

XXX...XXX....XXX...XXX
X..X..X..X..X.....X...
XXX...XXX...X.....X.XX
X.....X.....X.....X..X
X.....X......XXX...XXX

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX...X
X...X...............X...............X...........X...................X...X
X...X...XXXXXXXXX...X...XXXXX...XXXXXXXXX...XXXXX...XXXXX...XXXXX...X...X
X...............X.......X...X...........X...........X...X...X.......X...X
XXXXXXXXX...X...XXXXXXXXX...XXXXXXXXX...XXXXX...X...X...X...XXXXXXXXX...X
X.......X...X...............X...........X...X...X...X...X...........X...X
X...X...XXXXXXXXXXXXX...X...X...XXXXXXXXX...XXXXX...X...XXXXXXXXX...X...X
X...X...............X...X...X.......X...........X...........X.......X...X
X...XXXXXXXXXXXXX...XXXXX...XXXXX...X...XXXXX...XXXXXXXXX...X...XXXXX...X
X...........X.......X...X.......X...X.......X...........X...X...........X
X...XXXXX...XXXXX...X...XXXXX...X...XXXXXXXXX...X...X...X...XXXXXXXXXXXXX
X.......X.......X...X...X.......X.......X.......X...X...X.......X.......X
XXXXXXXXXXXXX...X...X...X...XXXXXXXXX...X...XXXXX...X...XXXXX...XXXXX...X
X...........X...X...........X.......X...X.......X...X.......X...........X
X...XXXXX...X...XXXXXXXXX...XXXXX...X...XXXXX...XXXXX...XXXXXXXXXXXXX...X
X...X.......X...........X...........X.......X...X...X...............X...X
X...X...XXXXXXXXX...X...XXXXX...XXXXXXXXX...X...X...XXXXXXXXXXXXX...X...X
X...X...........X...X...X...X...X...........X...............X...X.......X
X...XXXXXXXXX...X...X...X...XXXXX...XXXXXXXXX...XXXXXXXXX...X...XXXXXXXXX
X...X.......X...X...X...........X...........X...X.......X...............X
X...X...XXXXX...XXXXX...XXXXX...XXXXXXXXX...XXXXX...X...XXXXXXXXX...X...X
X...X...................X...........X...............X...............X...X
X...XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

```

<sup>(maze source)</sup>

*Related Questions:*
Draw the Hilbert curve using slashes
Align a horizontally-aligned, right-angled ASCII shape along a diagonal

# Answer
> 10 votes
# Python 2 - ~~236, 228, 226, 221, 250, 248~~ 246 - 50 = 196

```
s=input().split()
s=zip(*s[::-1])
X=len(s[0])+2
d=('.',)
B=[d*X]
s=B+[d+tuple(l)+d for l in s]+B
Y=len(s)
for x in range(X,-Y,-1):print' '*abs(x)+''.join(' \\'[s[y-1][x+y-1]!=s[y-1][x+y]]+' /'[s[y-1][x+y]!=s[y][x+y]]for y in range(1,Y)if 0<x+y<X)

```

I added the optional bonus feature that switches the direction from clockwise to counterclockwise. Basically, the second line simply rotates the input by 90 degrees. To switch between both options, replace `s=zip(...)` by something like `S=zip(...)` (i.e. assign to a variable that won't be used again).

```
.XX.X....X...XX.X.X
X...X...X.X.X...X.X
.X..X...XXX..X..XXX
..X.X...X.X...X.X.X
XX..XXX.X.X.XX..X.X

                 /\           /\/\
                 \ \          \/\ \
               /\ \ \         /\ \/
               \ \/  \     /\ \/   /\
             /\ \  /\ \    \ \/\  / /
            / /  \ \ \/     \/\/ / /
            \/    \ \           / /
            /\/\/\ \/          / /
            \/\/\/             \ \    /\/\
        /\/\    /\              \ \  / /\/
        \/\ \  / /               \/ /  \/\
        /\/  \ \/                  / /\  /
        \  /\ \                    \/ / / /\/\
         \ \ \/                      / /  \/\ \
   /\     \ \                        \/   /\ \/
   \ \     \/                          /\ \/   /\
 /\ \ \  /\                            \ \/\  / /
/ /  \ \/ /                             \/\/ / / /\
\/    \  /                                  /  \/ /
/\/\/\ \/                                  / /\  /
\/\/\/                                     \/ / /
    /\                                       / /
   / /                                       \/
   \/

```

# Answer
> 7 votes
# MATLAB - 286 - 50 = 236

**Minified:**

```
S=input('');x=rot90(reshape(input('','s'),S),1);S=size(x);D=sum(S);[r,c]=ind2sub(S,find(x==88));A=zeros(D);f=@(o,p)sub2ind([D D],r+c+o-1,c-r+S(1)+p);A(f(1,1))=1;t=f(0,0);A(t)=A(t)+1;A(f(1,0))=3;t=f(0,1);A(t)=A(t)+3;fprintf('%s',char([(1-mod(A,2))*32+(A==1)*47+(A==3)*92,ones(D,1)*13]'))

```

**Expanded:**

```
S = input('');
x = rot90( reshape( input('','s'), S ), 1 );
S = size( x );
D = sum( S );
[r,c] = ind2sub( S, find( x==88 ) );
A = zeros( D );
f = @(o,p) sub2ind( [D D], r+c+o-1, c-r+S(1)+p );

A(f(1,1)) = 1;
t = f(0,0); A(t) = A(t)+1;
A(f(1,0)) = 3;
t = f(0,1); A(t) = A(t)+3;

fprintf( '%s', char( [(1-mod( A, 2 ))*32 + (A==1)*47 + (A==3)*92, ones( D, 1 )*13]' ) )

```

The code can be further reduced by 6 characters (to tie the current lead) by eliminating the cast to type `char`, but this results in a warning from MATLAB, and I wasn't sure if that was allowed.

It can be reduced by an additional 13 characters if the input is required to have a "marked up" format such as `['X..';'.X.';'..X']`, but I didn't figure this was allowed either. Currently the script just accepts two numbers (row and column dimensions) and then reads in a single string of grid characters.

**Bonus**

By changing the `1` in the call `x = rot90( ..., 1 );` to a `0`, the transformation changes from a CCW 45° rotation to a CW 45° rotation. In fact, all possible 45° + n·90° rotations are possible by stepping this parameter from `0` to `3`.

**Sample Outputs:**

```
XXX...XXX....XXX...XXX
X..X..X..X..X.....X...
XXX...XXX...X.....X.XX
X.....X.....X.....X..X
X.....X......XXX...XXX

                     /\
                    / /
                   / / /\
                   \/ /  \
                   /\ \/\ \
                   \ \  / /
               /\   \ \/ /
              / /    \/\/
             / /
             \/
             /\    /\
             \ \  / /
              \ \/ /
        /\/\   \/\/
       / /\/
      / / /\
      \ \/ /
       \  /
        \ \
  /\/\   \ \
 / /\/    \/
/ / /\
\ \/ /
 \  /
  \ \
   \ \
    \/

    /\
   /  \
  / /\ \
 /  \ \/
/ /\ \/\
\/  \/\/
          /\
         /  \
        / /\ \
       /  \ \/
      / /\ \/\
      \/  \/\/

               /\/\
              / /\ \
             / /  \ \
             \/    \/
             /\
             \ \
              \ \    /\/\
               \/   / /\ \
                   / /  \ \
                   \/ /\ \/
                   /\ \ \
                   \ \/ /
                    \  /
                     \/

```

# Answer
> 3 votes
# Perl - 409

```
while(<>){$a[$.]=[/./g]}$l=$#a<($g=@{$a[1]})?$#a:$g;$r=$#a+$g-1;for$d(1..$r){for$e(1..$l){if(($b=$a[$c=($d>$g?$d-$g:0)+$e][$n=-($d-$c+1)])&&$n<0){$h[$d][$e]=$b;}}$h[$d]=[(0)x(($l-{@$h[$d]})/2),@{$h[$d]}];}sub z{"\0"x((reverse(1..$g),(2..$r-$g+1))[int($q++/2)-1]).join'',map{$_ eq'X'?($q%2?'/\\':'\/'):"\0\0"}@_}@i="\0"x2x$l;for$f(@h){$i[$#i]=(z@$f)^$i[$#i];$i[$#i+1]=z@$f}for$j(@i){print$j=~s/[\0s]/ /gr."\n"}

```

Reads from stdin and prints to stdout.

Example outputs:

```
XXX
X..
XXX
..X
XXX

     /\
    / /
   / / /\
   \ \/  \
    \  /\ \
     \/ / /
       / /
       \/

XXXXXXXXX
X........
X.XXXXXXX
X.X.....X
X.X..X..X
X.XXXX..X
X...X...X
XXXXXXXXX
           /\
          / /
         / / /\
        / / /  \
       / / / /\ \
      / / / /  \ \
     / / / /    \ \
    / / / / /\   \ \
   / / / /  \ \  / /
   \ \ \ \  / / / /
    \ \ \ \/  \/ /
     \ \ \  /\  /
      \ \ \/ / /
       \ \  / /
        \ \/ /
         \  /
          \/

```

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


title: write an undefined behavior

text:
# Question
Title: write an undefined behavior
**Header:**
this question has a very close duplicate, but the other question requires a difference between versions of the languages, instead of a difference between different implementation. this means that ***all*** answers from the almost-duplicate are invlid here.
this is also my first question, so please don't be harsh.

# the question:

in this challenge you will be writing code that runs differently on at least two different implementations of your language, such as jython / ironPython for python. different versions of the same implementation don't count.

your code should be runnable on all existing implementations (code that doesn't compile on one implementation or halts with an error isn't valid).
your code should be well-defined in the scope of each one of the implementations you chose (your code should always do the same thing when run on the same implementation, even on different computers/OS's etc.)
also, code isn't allowed to check the implementation directly.

this is a popularity contest so try to be creative, most upvoted answer wins.

# Answer
> 1 votes
# C++

This should print `6.28319` on all *compliant* compilers of C++..and `3.14159` for the Visual C++ compiler.

```
#include <iostream>
#if compl-1
#define oddNewPi =6.28318530718,compl
#else
#define twoPlusTwoIsFive
#endif
int main(int twoPlusTwoIsFive, char **warIsPeace){
    double goodOlPi = -3.14159265359,
    bitand oddNewPi = goodOlPi;

    int J = 42;
    float k = (compl+J)/-40.0f;

    goodOlPi *= -1;
    if(k > 1.0f){
        twoPlusTwoIsFive oddNewPi *= compl-3;
    }

    std::cout << goodOlPi << std::endl;
}

```

How this works: `compl` is equivalent to the operator `~`, thus, `compl-1` is `0`. However, for the Visual C++ compiler, `compl` is not treated as an operator (if you include `<ciso686>`, then it is a macro that expands to `~`), therefore, `#if compl-1` is treated as `#if 0-1`, or `#if -1`.

`bitand` is equivalent to `&`, but in the code here, the Visual C++ compiler treats it as a variable name instead.

When `compl-1` evaluates as false, the code expands to

```
#include <iostream>
int main(int, char **warIsPeace){
    double goodOlPi = -3.14159265359,
          &oddNewPi = goodOlPi;

    int J = 42;
    // equal to 43/40.0f
    float k = (~ +J)/-40.0f;

    goodOlPi *= -1;
    if(k > 1.0f){ // always true
        oddNewPi *= ~ -3; // equal to two
    }

    // prints 6.28319
    std::cout << goodOlPi << std::endl;
}

```

whereas if `compl-1` evaluates as true, the code expands to

```
#include <iostream>
int main(int twoPlusTwoIsFive, char **warIsPeace){
    double goodOlPi = -3.14159265359,
           bitand   = 6.28318530718,
           compl    = goodOlPi;

    int J = 42;
    // equal to (-3.1415.. + 42)/-40.0f: about -1
    float k = (compl + J)/-40.0f;

    goodOlPi *= -1;
    if(k > 1.0f){ // always false
        twoPlusTwoIsFive = 6.28318530718, compl *= compl - 3;
    }

    // prints 3.14159
    std::cout << goodOlPi << std::endl;
}

```

# Answer
> 1 votes
# JavaScript (ES6)

In ES5 and possibly older versions, prefixing a number with `0x` would cause the number to be treated as hexadecimal.

In ES6, prefixing a number with `0b` causes the number to treated as binary.

The `Number` constructor attempts to evaluate the argument as a number and if it is unable to do so, returns `NaN`. For strings, the evaluation syntax describes a positive/negative sign with decimal digits OR `0x` followed by hexadecimal digits (optionally surrounded by whitespace). The JavaScript engine in Firefox and Chrome appear to have different implementations when a string is passed beginning with `0b`:

### Firefox 32

```
Number('11'); // 11
Number('011'); // 11
Number('0b11'); // NaN
Number('0x11'); // 17

Number(11); // 11
Number(011); // 9
Number(0b11); // 3
Number(0x11); // 17

```

### Chrome 37

```
Number('11'); // 11
Number('011'); // 11
Number('0b11'); // 3
Number('0x11'); // 17

Number(11); // 11
Number(011); // 9
Number(0b11); // 3
Number(0x11); // 17

```

I'm assuming that the Chromium dev team will fix the bug sooner or later, but these are the latest stable versions of the browsers at this point in time.

Neither Node.js nor Internet Explorer's JavaScript implementation supports this feature of ES6, so it would not be fair to test on those platforms.

I should also note that the ES6 specification is still a draft, so perhaps strings beginning with "0b" may be allowed in the evaluation syntax some time in the future.

# Answer
> 0 votes
## C++

I'm not sure this is exactly what the question asked for, but this came up as a side-question in an interview once:

```
#include <iostream>

#define f(a, b) a * b

int main(int argc, char **argv)
{
    int i = 3;

    std::cout << f(i++, i++) << std::endl;
    std::cin.ignore();

    return 0;
}

```

VC++ returns the answer as `3 * 3 = 9`. compileonline.com (which uses g++) returns the answer as `3 * 4 = 12` (those are all the compilers I have access to right now). I can't imagine that there's any more possible answers than those two. Try it out for yourself and see what you get!

---
Tags: popularity-contest
---


# Question
Title: Find a criminal from his ear, finger, and head
Prior to the discovery of fingerprints and DNA testing, the British police used an anthropometric system to identify repeat offenders. Certain parts of the bodies of criminals were measured and stored in records -- these parts of the body were assumed to not change in size after adulthood. This system was known as *bertillonnage*.

The diagram below shows a filing system used by the police to access these records quickly.

*Diagram 1: A filing system with numbered drawers.*
Note: if you cannot see the image, try the imgur mirror or compile it yourself.

The filing cabinet consists of 81 numbered drawers. Each drawer contains cards, and each card has measurements of particular parts of a criminal's body:

* The length of their head (`H`)
* The breadth of their head (`B`)
* The width of their right ear (`E`)
* The length of their index finger (`F`)

Each measurement is classified as either small, medium or large.

For example, drawer 56 contains cards with the following characteristics: small H, large B, medium E, and small F. This can be notated using the letters `S`, `M`, and `L` in place of small, medium, and large:

```
SH,LB,ME,SF

```

Note that the size letter goes first, then what the measurement is. In addition, an exclamation point `!` may be placed in front to cause a negative:

```
!SH,LB,!ME,SF

```

This indicates cards that have the following characteristics: *not* small H, large B, *not* medium E, and small F. There are four drawers that contain cards with these characteristics -- 58, 60, 61, and 63.

Your task is to write a program, that, when given a string notating some characteristics, outputs all of the drawers that contain cards with those characteristics. If there are no drawers that contain cards with the given characteristics, output `0`.

Here are some sample inputs and outputs.

1. Input: `SH,LB,ME,SF`
Output: `56`
2. Input: `!SH,LB,!ME,SF`
Output: `58,60,61,63`
3. Input: `SB,!MF,!LF`
Output: `1,2,3,4,5,6,7,8,9`
4. Input: `MH,!MH`
Output: `0`

This is code golf, so the shortest entry wins. Ask questions in the comments if the specification is not clear.

# Answer
## GolfScript 95 (DEMO)

```
','/:r;81,{r{1$[[.9%3/\.3%\.27/\9/3%]{'SML'=}%'HEBF']zip{''+}%\.,3=\1${(;}*@?)!!=},!\;},{)}%0or

```
> 1 votes

# Answer
## Ruby 1.9.3 - ~~173 157~~ 143

```
x=(1..81).select{|j|$*[0].split(?,).all?{|y|i=j-1
z='SML'
[z[i%9/3]+?H,z[i%3]+?E,z[i/27]+?B,z[i/9%3]+?F].member?(y[-2,2])^y[?!]}}
p x==[]?[0]:x

```

Edit:

* applied Three If By Whiskey's tips.
* taken parameters from the command line to save some more chars

Online demo: http://ideone.com/lodTLt
> 6 votes

# Answer
# Scala - 951

Definitely won't win this one, mainly due to the names of built in functions I think.

```
def m(a: List[Int]) = 0 to 8 flatMap (x => a map (_ + 9*x)) toSet
var SH = m(List(1,2,3))
var MH = m(List(4,5,6))
var LH = m(List(7,8,9))
var SE = m(List(1,4,7))
var ME = m(List(2,5,8))
var LE = m(List(3,6,9))
var SB = 1 to 27 toSet
var MB = 28 to 54 toSet
var LB = 55 to 81 toSet
def l(a: List[Int]) = 0 to 2 flatMap (x => a map (_+27*x)) toSet
var SF = l(1 to 9 toList)
var MF = l(10 to 18 toList)
var LF = l(19 to 27 toList)

var j = Map(("LH",LH),("MH",MH),("SH",SH),("LB",LB),("MB",MB),("SB",SB),("LF",LF),("MF",MF),("SF",SF),("LE",LE),("ME",ME),("SE",SE))

def f(x : String) = {
  def h(i : List[String], k : Set[Int]) : Set[Int] = {
      if(i isEmpty) k
      else if(i.head.startsWith("!")) h(i.tail, k filterNot (j(i.head.replace("!","")) contains _))
      else h(i.tail, k intersect j(i.head))
  }
  h(x split "," toList, 1 to 81 toSet) mkString ","
}

```

Argument is passed into the function `f`

`f("SH,LB,ME,SF")` = `56`
> 2 votes

# Answer
# T-SQL - ~~547~~ 544

Not a winning entry, but suited to this type of problem.

## Grid Table Setup - 254

```
SELECT ROW_NUMBER()OVER(ORDER BY (SELECT $))I,LEFT(Z,1)E,RIGHT(Z,1)H,LEFT(Y,1)F,RIGHT(Y,1)B INTO G FROM(VALUES('SS'),('MS'),('LS'),('SM'),('MM'),('LM'),('SL'),('ML'),('LL'))FB(Y),(VALUES('SS'),('MS'),('LS'),('SM'),('MM'),('LM'),('SL'),('ML'),('LL'))EH(Z)

```

## Query - ~~293~~ 290

```
DECLARE @S CHAR(400)='SELECT ISNULL(SUBSTRING(O,2,99),0)FROM (SELECT CONCAT('','',I)FROM G WHERE '+REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REVERSE(@i),',',' AND '),'S!','!S'),'M!','!M'),'L!','!L'),'S','=''S'''),'M','=''M'''),'L','=''L''')+' FOR XML PATH(''''))O(O)';EXEC(@S)

```

Input is done by declaring @i before the query

```
DECLARE @I VARCHAR(50) = 'SB,!MF,!LF';

```

I could save a further 89 characters if the output doesn't have to be comma delimited row

```
DECLARE @S CHAR(400)='SELECT I FROM G WHERE '+REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REVERSE(@i),',',' AND '),'S!','!S'),'M!','!M'),'L!','!L'),'S','=''S'''),'M','=''M'''),'L','=''L''')

```
> 2 votes

# Answer
# Mathematica ~~191~~ 235

Represents each cell number in base 3. Each digit position represents a bodily feature. The value of the digit, {0,1,2}, represents "Small","Medium","Large", respectively.

The features correspond to the digits as follows:

> {"breadthOfHead", "IndexFingerLength", "LengthOfHead", "WidthOfRightEar"}

For example, the input,

```
{"SH","LB","ME","SF"}

```

signifies:

> "LB" implies breadthOfHead = 2 (large)
>
> "SF" implies IndexFingerLength = 0 (small)
>
> "SH" implies LengthOfHead = 0 (small)
>
> "ME" implies WidthOfRightEar = 1 (medium)

`2001`in base 3 is 55 in base 10.

We need to add one because we are counting cells from 1, not zero.

---

## Code

```
c=Characters;t=Table[IntegerDigits[k,3,4],{k,0,80}];
f@i_:=1+FromDigits[#,3]&/@Intersection@@(Cases[t,#]&/@(ReplacePart[{_,_,_,_},{#}]&/@(c/@i
/.Thread[c@"BFHESML"-> {1,2,3,4,0,1,2}]/.{{"!",v_,n_}:> (n-> Except[v]),{v_Integer,n_}:> n-> v})))
/.{}:>0

```

---

## Test Cases

```
f[{"SH","LB","ME","SF"}]

```

> {56}

---

```
f[{"!SH","LB","!ME","SF"}]

```

> {58, 60, 61, 63}

---

```
f[{"SB","!MF","!LF"}]

```

> {1, 2, 3, 4, 5, 6, 7, 8, 9}

---

```
f[{"MH","!MH"}]

```

> 0
> 1 votes

# Answer
# Python 2 - 194

```
from itertools import*
n=map(set,['012']*4)
for x in raw_input().split(','):n['BFHE'.find(x[-1])]&=set(`'SML'.find(x[-2])`)^set('012'*(x<'"'))
print[1+int(''.join(x),3)for x in product(*n)]or[0]

```

Output has brackets, and don't care about order of output
Some suggestions from Falko, and a couple from myself to take off 10 chars.
> 1 votes

# Answer
# Python 3 - 192 - Try it!

```
from itertools import*
S=input().split(',')
print([i+1for i in range(81)if eval('*'.join('(list(product(*["SML"]*4))[i][%d]%s="%s")'%('BFHE'.find(s[-1]),'!='[s[0]>'!'],s[-2])for s in S))]or 0)

```
> 1 votes

---
Tags: code-golf, math
---


title: Can you beat the optimizer?

text:
# Question
Title: Can you beat the optimizer?
This is an optimization/algorithms challenge. Given two sets of points X and Y, which are to be thought of as points on a circle of circumference T, the challenge is to find the rotation which minimizes the distance from the set X to the set Y. Here the distance is just the sum of the absolute distance from each point in X to its closest point in Y. Here closest is really just the minimum distance you need to travel along the circle to reach a point in Y (remembering that you can go clockwise or anti-clockwise). Note that this measure of distance is **not** symmetric.

In order to be able to create the test data, you will need to be able to run Python, but your answer can be in any language of your choosing that is available without cost to run on Linux. You can also use any libraries you choose as long as they are easy to install on Linux and available without cost.

The test data will be created using the following Python code. It outputs two lines to standard out. The first is circle X and the second is circle Y.

```
import numpy as np
#Set T to 1000, 10000, 100000, 1000000, 10000000, 1000000000
T = 1000
N = int(T/5)

#Set the seed to make data reproducible
np.random.seed(seed = 10)

timesY = np.sort(np.random.uniform(low = 0.0, high = T, size = N))
indices = np.sort(np.random.randint(0,N, N/10))
rotation =  np.random.randint(0,T, 1)[0]
timesX = [(t + rotation + np.random.random()) % T for t in timesY[indices]]

for tX in timesX:
    print tX,
print
for tY in timesY:
    print tY,

```

For those who don't run python, I have also uploaded some test files. Each file has three lines. The first line is the points for circle X, the second is the points for circle Y, and the last is the score you get from the generic optimizer in the python code below. This score will be in no way optimal and you should do much better.

```
http://wikisend.com/download/359660/1000.txt.lzma
http://wikisend.com/download/707350/10000.txt.lzma
http://wikisend.com/download/582950/100000.txt.lzma
http://wikisend.com/download/654002/1000000.txt.lzma
http://wikisend.com/download/416516/10000000.txt.lzma

```

Here is also a toy **worked example** of the distance between two sets of point to make the distance function clear.

Let `timesX = [2, 4, 98]` and `timesY = [1, 7, 9, 99]`. Let us assume the circumference of the circle is `100`. As it stands the distance is `(2-1)+(7-4)+(99-98) = 5`. Now if we rotate `timesX` by `3` we get `[5, 7, 1]` which has total absolute distance `2` to `timesY`. In this case this appears to be the optimal solution.

Here is some sample code which assumes that the circles are called `timesX` and `timesY`, and outputs the minimum distance it finds. It doesn't, however, do a very good job, as you will see.

```
from bisect import bisect_left
from scipy.optimize import minimize_scalar
def takeClosest(myList, myNumber, T):
    """
    Assumes myList is sorted. Returns closest value to myNumber in a circle of circumference T.
    """
    pos = bisect_left(myList, myNumber)
    if (pos == 0 and myList[pos] != myNumber):
        before = myList[pos - 1] - T
        after = myList[0]
    elif (pos == len(myList)):
        before = myList[pos-1]
        after = myList[0] + T
    else:
        before = myList[pos - 1]
        after = myList[pos]
    if after - myNumber < myNumber - before:
        return after
    else:
        return before

def circle_dist(timesX, timesY):
    dist = 0
    for t in timesX:
        closest_number = takeClosest(timesY, t, T)
        dist += np.abs(closest_number - t)
    return dist

def dist(x):
    timesX_rotated = [(tX+x) % T for tX in timesX]
    return circle_dist(timesX_rotated, timesY)

#Now perform the optimization
res = minimize_scalar(dist, bounds=(0,T), method='bounded', options={ 'disp':True})
print res.fun

```

**Scoring**

You should run your code for T = 1000, 10000, 100000, 1000000, 10000000. Your code should output both the optimum rotation and the distance you get for it so that it can be checked. The scoring criterion is as follows.

* You should calculate the sum of the distances you find for the five values of T. Low is better and the best possible is 0. You aren't allowed to cheat by looking at what rotation was used to create the data in the first place.
* Then you should calculate `551431.326508571/(the sum you just calculated)` and report that as your score.

---

**Edit 1**. Changed score so that high is better and removed time restriction so you can just run it on your own computer.

**Edit 2** Note that the function `dist` can be used as a verifier. Just put the points for circle X in `timesX` and the points for circle Y in `timesY` and set `x` to be the rotation you want to test. It will return a score which you can compare to what you get.

**Edit 3** Fixed the data creation code which wasn't exactly the code I had used to create the data.

# Answer
> 8 votes
## C++, 10.60236

If we assume nothing about the data then it seems unlikely that we can do much better than brute force/Monte Carlo plus maybe some local minimization. The distance/rotation graphs for *T=1,000* and *T=10,000* are already pretty noisy:

However, assuming this is fair game, taking into account the fact that *X* is simply a rotated subset of *Y* with some small error, recovering the approximate rotation and minimizing locally is easy:

Compile with `g++ mindist.cpp -omindist -std=c++11 -O3`.

Run with `./mindist T < dataset` (e.g. `./mindist 1000 < 1000.txt`).

```
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>
#include <iterator>
#include <tuple>
#include <cmath>

using namespace std;

/* Positive modulo */
template <typename T>
T mod(T x, T y) { x = fmod(x, y); return x >= 0 ? x : x + y; }

/* Less-than comparison with a margin. Can be used to search for elements
 * within +-epsilon. */
template <typename T>
struct epsilon_less {
    T epsilon;
    bool operator()(const T& x, const T& y) const { return x < y - epsilon; }
};

/* Calculates the distance between X and Y on a circle with circumference T,
 * where X is rotated by `rotation`. */
template <typename P, typename Ps>
P distance(P T, const Ps& X, const Ps& Y, P rotation) {
    P dist = 0;
    for (P x : X) {
        x = mod(x + rotation, T);
        auto l = lower_bound(Y.begin(), Y.end(), x);
        auto r = prev(l);
        dist += min(*l - x, x - *r);
    }
    return dist;
}

/* Minimizes a function f on the interval [l, r]. f is assumed to be "well-
 * behaved" within this range. This is a simple n-iterations binary search
 * based on the sign of the derivative of f. */
template <typename T, typename F>
T minimize(F f, T l, T r, int n = 32) {
    auto fl = f(l), fr = f(r);
    for (; n; --n) {
        T m = (l + r) / 2;
        auto fm = f(m);
        T dm = (r - l) / 1e5;
        auto fm2 = f(m + dm);
        auto df_dm = (fm2 - fm) / dm;
        (df_dm < 0 ? tie(l, fl) : tie(r, fr)) = make_tuple(m, fm);
    }
    return (l + r) / 2;
}

int main(int argc, const char* argv[]) {
    typedef double point;

    const point T = stod(argv[1]);
    const point error_margin = /*+-*/1;

    // Read input. Assumed to be sorted.
    vector<point> X, Y(1);
    for (auto* P : {&X, &Y}) {
        string line; getline(cin, line);
        stringstream s(line);
        copy(
            istream_iterator<point>(s), istream_iterator<point>(),
            back_inserter(*P)
        );
    }
    // Add wrap-around points to Y to simplify distance calculation
    Y[0] = Y.back() - T; Y.push_back(Y[1] + T);

    for (point y : Y) {
        // For each point y in Y we rotation X so that the last point in X
        // aligns with y.
        auto rotation = mod(y - X.back(), T);
        // See if the rest of X aligns within the error margin
        if (all_of(
            X.begin(), X.end(), [=, &Y] (point x) {
                return binary_search(
                    Y.begin(), Y.end(), mod(x + rotation, T),
                    epsilon_less<point>{error_margin}
                );
            }
        )) {
            // We found a rotation. Minimize the distance within the error
            // margin.
            rotation = minimize(
                [&] (point r) { return distance(T, X, Y, r); },
                rotation - error_margin, rotation + error_margin
            );
            // Print results and exit.
            cout.precision(12);
            cout << "Rotation: " << rotation << endl;
            cout << "Distance: " << distance(T, X, Y, rotation) << endl;
            return 0;
        }
    }
    // We didn't find a rotation. Something must have went wrong!
    return 1;
}

```

The program assumes *X* is a rotated subset of *Y* with an error margin of *±1* for each point in *X*. It tries to rotate *X* such that it aligns with *Y* within this error margin (that is, s.t. each point in *X* is at distance at most *1* from *Y*.) The reason that we can do this efficiently is that we don't have to try arbitrary rotations: It's enough to choose an arbitrary point *x* in *X* and rotate *X* such that *x* aligns with each of the points in *Y*. For one such rotation it's guaranteed that *X* and *Y* align within the error range; for every other rotation, it's very unlikely that even two points will align, so we can abandon nonoptimal rotations very quickly. It's extremely unlikely that two different rotations will both align *X* and *Y*, so once the program finds a rotation that does it doesn't bother to look any further. Once a rotation is found, it's adjusted within the error margin to minimize the overall distance.

Results:

```
T           Rotation         Distance
     1,000        494.64423       5.59189
    10,000      6,967.55630      45.03235
   100,000     24,454.48700     471.71127
 1,000,000    974,011.50572   4,671.75611
10,000,000  2,720,706.49829  46,816.15372

Total distance: 52,010.24535
Score: 10.60236

```

# Answer
> 4 votes
## Mathematica, 1.04834

Okay, maybe people just need to be shown how simple it is to perform better than the reference implementation.

So here is a random implementation. I'm simply trying out some 10,000 random rotations (basically, as many as I care to wait for) and pick the best one I find.

```
First@SortBy[(
  r = RandomReal[t];
  f =
   Nearest[Flatten[{First[z = Sort@Mod[y + r, t]] + t, z,
      Last@z - t}]];
  {r, Total[Abs[# - f[#][[1]]~Mod~t] & /@ x]}
  ) & /@ Range@100, Last@# &]

```

This assumes `t` to be the circumference, `x` to be the X list and `y` to be the Y list.

Results:

```
T          rotation   dist       Reference dist
1000       494.669    5.59189    33.0305
10000      6967.74    53.6250    429.212
100000     24452.5    2774.90    4676.23
1000000    974013.    27023.3    49149.0
10000000   9315070    496149.    497144.
                      =======
               Sum:   526006.

               Score: 1.04834

```

Unfortunately, T = 107 takes too long to run more than 600 trials, such that I can hardly beat the reference implementation there (and even more unfortunately, this dominates the score). This still shows that there is a lot of improvement possible.

Fun fact: I actually wanted to submit a *proper* solution, by using one of Mathematica's minimisers on the distance function, but somehow I couldn't convince Mathematica to use my compound statement as a function to be minimised (and I wasn't patient enough to figure out why it didn't work), so I thought - well, then let's just Monte Carlo it.

# Answer
> 4 votes
# Java - 10.60236

As promised, Lembik:

```
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;

public final class SpinDots {

public static void main( String[] sArgs ) {
    final int T = Integer.parseInt( sArgs[0] );
    List<Double> LDX = new LinkedList<>(),
        LDY = new LinkedList<>();

    double RS = 0.;

    try( BufferedReader BR = new BufferedReader( new FileReader( T + ".txt" ), 65536 ) ) {
        String SX = BR.readLine();
        StringTokenizer STX = new StringTokenizer( SX );

        while( STX.hasMoreTokens() )
            LDX.add( Double.parseDouble( STX.nextToken() ) );

        String SY = BR.readLine();
        StringTokenizer STY = new StringTokenizer( SY );

        while( STY.hasMoreTokens() )
            LDY.add( Double.parseDouble( STY.nextToken() ) );

        RS = Double.parseDouble( BR.readLine() );
        BR.close();
    } catch( IOException ioe ) {
        System.err.println( "Unable to read contents of file: " + T + ".txt" );
        System.exit( 1 );
    }

    final int NX = LDX.size(),
        NY = LDY.size(),
        RNY = 2*NY+3;

    final double[] DX = new double[NX],
        DY = new double[RNY];

    final int[] X = new int[NX],
        Y = new int[RNY];
    int[] YS = new int[RNY],
        YSP = new int[RNY];

    int dx = 0;
    for( Double dx_ : LDX ) {
        DX[dx] = dx_;
        X[dx] = (int)Math.round( dx_ );
        dx++;
    }
    Arrays.sort( X );
    Arrays.sort( DX );

    int dy = 1;
    for( Double dy_ : LDY ) {
        DY[dy] = dy_;
        DY[dy+NY] = dy_+T;
        Y[dy] = (int)Math.round( dy_ );
        Y[dy+NY] = Y[dy] + T;
        dy++;
    }
    DY[0] = DY[NY] - T;
    DY[2*NY+1] = DY[1] + 2*T;
    DY[2*NY+2] = DY[2] + 2*T;
    Y[0] = Y[NY] - T;
    Y[2*NY+1] = Y[1] + 2*T;
    Y[2*NY+2] = Y[2] + 2*T;

    System.out.println( "Computing optimum shift for: |X| = " + NX + ", |Y| = " + NY + ", T = " + T );

    int DO_ = scoreForShiftFirstPass( X, Y, YSP );
    List<Integer> LXO = new LinkedList<>(),
        LDXO = new LinkedList<>();

    LXO.add( 0 );
    LDXO.add( DO_ );
    for( int iShift = 1; iShift < T; iShift++ ) {
        int D_ = scoreForShift( X, Y, iShift, YSP, YS );
        int[] YT = YSP;
        YSP = YS;
        YS = YT;
        if( D_ < DO_ ) {
            DO_ = D_;
            Iterator<Integer> I = LXO.iterator(),
                DI = LDXO.iterator();

            while( DI.hasNext() ) {
                I.next();
                if( DI.next() > DO_ + NX ) {
                    DI.remove();
                    I.remove();
                }
            }
        }
        if( D_ <= DO_ + NX && LXO.size() < 100 ) {
            LXO.add( iShift );
            LDXO.add( D_ );
        }

        if( iShift %(T/100) == 0 )
            System.out.println( "Completed " + (iShift*100/T) + "% of coarse pass." );
    }

    System.out.println( "Completed 100% of coarse pass. Coarse optimum is: " + DO_ );
    System.out.println( "Identified " + LXO.size() + " fine filtering candidates." );

    double ddoo = 0.;
    double DDOO_ = Double.MAX_VALUE;
    for( int iShift : LXO ) {
        double DDO_ = doubleScoreForShiftFirstPass( DX, DY, iShift-1, YSP );
        double ddo = iShift;

        for( int iFineShift = -999; iFineShift < 1000; iFineShift++ ) {
            double dd = iShift + iFineShift/1000.0;
            double DD_ = doubleScoreForShift( DX, DY, dd, YSP, YS );
            int[] YT = YSP;
            YSP = YS;
            YS = YT;
            if( DD_ < DDO_ ) {
                DDO_ = DD_;
                ddo = dd;
            }
        }
        if( DDO_ < DDOO_ ) {
            DDOO_ = DDO_;
            ddoo = ddo;
        }
    }

    System.out.println( "Fine optimum is: " + DDOO_ );

    double ddooo = ddoo-1e-3;
    double DDOOO_ = doubleScoreForShiftFirstPass( DX, DY, ddoo-1e-3, YSP );
    for( int iHyperFineShift = -999; iHyperFineShift < 1000; iHyperFineShift++ ) {
        double dd = ddoo + iHyperFineShift/1.e6;
        double DD_ = doubleScoreForShift( DX, DY, dd, YSP, YS );
        int[] YT = YSP;
        YSP = YS;
        YS = YT;
        if( DD_ < DDOOO_ ) {
            DDOOO_ = DD_;
            ddooo = dd;
        }
    }
    System.out.println( "Optimal forward rotation in X: " + ddooo );
    System.out.println( "Optimal score: " + DDOOO_ );
    System.out.println( "Reference score: " + RS );
}

static int scoreForShift( int[] X, int[] Y, int iShift, int[] YSP, int[] YS ) {
    int D_ = 0;
    for( int x = 0; x < X.length; x++ ) {
        int x_ = X[x]+iShift;
        int y = YSP[x],
            y_ = Y[y];

        int D = x_ < y_ ? y_ - x_ : x_ - y_;
        int y_nx_ = Y[y+1];
        int D_nx = x_ < y_nx_ ? y_nx_ - x_ : x_ - y_nx_;
        while( D_nx <= D ) {
            D = D_nx;
            y_nx_ = Y[++y+1];
            D_nx = x_ < y_nx_ ? y_nx_ - x_ : x_ - y_nx_;
        }
        YS[x] = y;
        D_ += D;
    }
    return D_;
}

static int scoreForShiftFirstPass( int[] X, int[] Y, int[] YS ) {
    int D_ = 0;
    int y = 0;
    for( int x = 0; x < X.length; x++ ) {
        int x_ = X[x];
        int y_ = Y[y];

        int D = x_ < y_ ? y_ - x_ : x_ - y_;
        int y_nx_ = Y[y+1];
        int D_nx = x_ < y_nx_ ? y_nx_ - x_ : x_ - y_nx_;
        while( D_nx <= D ) {
            D = D_nx;
            y_nx_ = Y[++y+1];
            D_nx = x_ < y_nx_ ? y_nx_ - x_ : x_ - y_nx_;
        }
        YS[x] = y;
        D_ += D;
    }
    return D_;
}

static double doubleScoreForShift( double[] X, double[] Y, double d_Shift, int[] YSP, int[] YS ) {
    double D_ = 0;
    for( int x = 0; x < X.length; x++ ) {
        double x_ = X[x]+d_Shift;
        int y = YSP[x];
        double y_ = Y[y];

        double D = x_ < y_ ? y_ - x_ : x_ - y_;
        double y_nx_ = Y[y+1];
        double D_nx = x_ < y_nx_ ? y_nx_ - x_ : x_ - y_nx_;
        while( D_nx <= D ) {
            D = D_nx;
            y_nx_ = Y[++y+1];
            D_nx = x_ < y_nx_ ? y_nx_ - x_ : x_ - y_nx_;
        }
        YS[x] = y;
        D_ += D;
    }
    return D_;
}

static double doubleScoreForShiftFirstPass( double[] X, double[] Y, double d_Shift, int[] YS ) {
    double D_ = 0;
    int y = 0;
    for( int x = 0; x < X.length; x++ ) {
        double x_ = X[x]+d_Shift;
        double y_ = Y[y];

        double D = x_ < y_ ? y_ - x_ : x_ - y_;
        double y_nx_ = Y[y+1];
        double D_nx = x_ < y_nx_ ? y_nx_ - x_ : x_ - y_nx_;
        while( D_nx <= D ) {
            D = D_nx;
            y_nx_ = Y[++y+1];
            D_nx = x_ < y_nx_ ? y_nx_ - x_ : x_ - y_nx_;
        }
        YS[x] = y;
        D_ += D;
    }
    return D_;
}
}

```

My approach is similar to Ell's in that it does a grid search over all potentials (first at integer resolution, then at a resolution of 1/1,000ths, then at a resolution of 1/1,000,000ths). Unlike Ell's approach, mine doesn't require or make use of the fact that the error in `X` is tightly bounded. I literally evaluate all 10,000,000 possibilities during coarse filtering in the `T = 10,000,000` case and store a list of candidates with distance small enough to be within "fine filtering" distance of the optimum.

Modular arithmetic is slow, and Java doesn't support template methods for native types. Hence my implementation "unwinds" `Y` to avoid the use of remainder operators, and the four working methods are near-identical clones of each other with differing types and 1-2 lines of code that would be handled in C/C++ using templates and macros.

I compute shifts sequentially, which allows the nearest neighbour search to incrementally tweak values from the previous shift. As a result, the routine completes in about 2 hours, which was acceptable since I slept through it. ;)

My outcomes are technically better than Ell's since I search to a higher resolution, but the improvement is utterly negligible, and probabilistic to boot. In particular, a higher resolution search only yields an improved score if the number of shifted `X` values falling in the set of intervals `[Y-eps,Y]` is different from the number of shifted `X` values falling in the set of intervals `[Y,Y+eps]`, where `eps` is the coarser resolution (`0.000001`, in the case of Ell's implementation). I don't know if this is the case for any of the datasets in this problem. In any event, his code should "win" since it predates mine.

**Output**

```
Optimal forward rotation in X: 494.64500000000004
Optimal score: 5.591890690289915
Reference score: 33.0305238422

Optimal forward rotation in X: 6967.556309
Optimal score: 45.032350687407416
Reference score: 429.211871389

Optimal forward rotation in X: 24454.487003000002
Optimal score: 471.7112722703896
Reference score: 4676.23391624

Optimal forward rotation in X: 974011.505734
Optimal score: 4671.756109326729
Reference score: 49148.9676631

Optimal forward rotation in X: 2720706.498309
Optimal score: 46816.15372609813
Reference score: 497143.882534

```

# Answer
> 4 votes
## C++, Optimal, O(|X|\*|Y|\*log|X|)

Where X = T / 50 and Y = T / 5. It may take about 2 days on my laptop to finish the T = 10000000 case.

Given two set of points `X` and `Y`. We denote the function `f(x)` to be:

```
f(x) = min(|x - y| for y in Y)

```

And then answer we want is:

```
dist = min(sum(f(x + t) for x in X) for t in [0, T))

```

However, it's impossible and unnecessary to try all the values of `t`. Instead we try the `t` values on "key points". My approach is a scanning from t = 0 to t = T with the help of a priority queue. There will have `|X| * |Y|` key points and trying each will need `O(log|X|)` operations. So the overall time complexity is `O(|X|*|Y|*log|X|)`.

### Score

```
               T            angle             dist         ref_dist
          1000.0     494.64422766       5.59189069      33.03052384
         10000.0    6967.55630010      45.03235069     429.21187139
        100000.0   24454.48700190     471.71127227    4676.23391624
       1000000.0  974011.50572340    4671.75610935   49148.96766310
      10000000.0  (still running...)

```

### Code

```
#include <iostream>
#include <cstdio>
#include <cassert>
#include <string>
#include <sstream>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;

struct Answer {
    double angle;
    double dist;
};

double check(double T, const vector<double>& xs, const vector<double>& ys, Answer answer) {
    double dist = -answer.dist;
    double angle = answer.angle;
    for(double x : xs) {
        double x1 = x + angle;
        while(x1 > T) x1 -= T;
        int i = upper_bound(ys.begin(), ys.end(), x1) - ys.begin();
        double d;
        if(i == 0) {
            d = min(ys[0] - x1, x1 - (ys.back() - T));
        } else if(i == ys.size()) {
            d = min(ys[0] + T - x1, x1 - ys.back());
        } else {
            d = min(ys[i] - x1, x1 - ys[i - 1]);
        }
        dist += d;
    }
    return dist;
}

Answer solve(double T, const vector<double>& xs, vector<double> ys) {
    assert(ys.size() >= 1);

    sort(ys.begin(), ys.end());
    vector<double> ps;
    ps.push_back(ys.back() - T);
    for(int i = 0; i < ys.size(); i++) {
        ps.push_back((ps.back() + ys[i]) / 2);
        ps.push_back(ys[i]);
    }
    ps.push_back((ps.back() + ys.front() + T) / 2);
    ps.push_back(ys.front() + T);

    struct X {
        double npd;
        int sign;
        int j;
        bool operator<(const X& rhs)const {
            return npd > rhs.npd;
        }
    };
    priority_queue<X> que;
    int count = 0;
    Answer ans, cur;
    cur.angle = 0;
    cur.dist = 0;

    for(int i = 0; i < xs.size(); i++) {
        double x = xs[i];
        int j = upper_bound(ps.begin(), ps.end(), x) - ps.begin();
        assert(j > 0 && j < ps.size());
        X q;
        q.j = j;
        q.sign = j % 2 == 1 ? 1 : -1;
        if(q.sign == 1) {
            cur.dist += x - ps[j - 1];
        } else {
            cur.dist += ps[j] - x;
        }
        count += q.sign;
        q.npd = ps[j] - x;
        que.push(q);
    }

    ans = cur;
    while(cur.angle < T) {
        X q = que.top(); que.pop();
        double da = q.npd - cur.angle;
        cur.dist += da * count;
        cur.angle += da;
        assert(cur.dist >= 0);

        if(cur.dist < ans.dist) {
            ans = cur;
        }
        count -= q.sign * 2;
        q.sign *= -1;
        if(q.j == ps.size() - 1) {
            q.j = 3;
        } else {
            q.j ++;
        }
        int j = q.j;
        q.npd = cur.angle + ps[j] - ps[j - 1];
        que.push(q);
    }
    double d_dist = check(T, xs, ys, ans);
    cerr << "check: " << d_dist << endl;
    ans.dist += d_dist;

    return ans;
}

vector<double> read_nums() {
    stringstream ss;
    string line;
    while(line.empty()) getline(cin, line);
    ss << line;
    vector<double> xs;
    while(ss) {
        double x;
        if(ss >> x)
            xs.push_back(x);
    }
    return xs;
}

int main() {
#ifdef DEBUG
    freopen("1000.txt", "r", stdin);
#endif
    double T;
    cin >> T;
    vector<double> xs = read_nums();
    vector<double> ys = read_nums();
    double ref_dist;
    cin >> ref_dist;

    Answer ans = solve(T, xs, ys);

    printf("%16s %16s %16s %16s\n", "T", "angle", "dist", "ref_dist");
    printf("%16.1f %16.8f %16.8f %16.8f\n", T, ans.angle, ans.dist, ref_dist);
}

```

### A bit of details

The function `f(x)` is something like:

So the graph of sum `d(t) = sum(f(x + t) for x in X)` is will be a set of connected segments. We need to try each `t` on the connecting points, with the help of a priority queue.

---
Tags: code-challenge
---


title: Write a functioning bare-bones IRCd

text:
# Question
Title: Write a functioning bare-bones IRCd
A bit of an unusual one, but hey, why not? :)

**The objective:** Write a functioning IRC daemon in your language of choice that provides barebones functionality, in as few characters as possible. As long as it fulfills the criteria below, it does *not* have to fully comply with the IRC RFCs (this would make the challenge significantly less fun), it just needs to work.

**Requirements:**

* Clients must be able to connect on port 6667 and use it. At least irssi and XChat must be able to connect to it successfully with a default configuration.
* Users must be able to specify their own nickname, change it while already connected, join channels, leave channels, and exit cleanly (ie. `QUIT`).
* Channels should be created like normal - joining a channel with no users in it 'creates' it. They do not have to be persistent.
* Users must be able to send both channel messages and private messages (ie. to other users).
* The `WHOIS` command must be implemented, as well as `PING`/`PONG`, `LIST`, and `NAMES` (mostly in order to keep clients happy).

**Restrictions:**

* You may not use any third-party libraries (that includes non-core evented I/O libraries). Only standard libraries that come with the platform you use, are permitted.
* If your implementation includes explicit support for IRC in the standard library, you may not use that either. Standard-library network functionality is, of course, fine.
* Your submission must be able to run independently. No being clever with mIRC scripting :)

Modes, kicks, etc. do not have to be implemented (unless required to make it work with the above clients). SSL isn't necessary either. Just the above barebones functionality, to keep the challenge short and fun.

More information on what IRC is here, RFCs are 1459 and 2812 (I can't link to them directly due to my lack of reputation). Shortest functional and requirements-compliant submission wins!

# Answer
# C++ (partially golfed) 5655 (with CRLF counting for 1)

This compiles in VS 2013 (uses auto, lambdas and winsock) It seemed to be working before I golfed it so unless I mucked it up it should still be ok. One of the reasons it is so big is that the numeric replies I am returning include the text specified in the RFC - I don't know if that is necessary or not. I tested it with KVirc because it runs portably (not allowed to install software on my PC!) KVirc seems to work with my server but I don't know about other clients - I did what I thought the RFC said but a lot of it is underspecified so hopefully I understood it right.

The server handles DIE, KILL, NICK, USER, MODE, WHOIS, WHO, JOIN, PART, TOPIC, LIST, NAMES, PRIVMSG, USERS, PING, PONG and QUIT to varying degrees. For most of them I return the required responses including doing most of the checks needed to return the specified error replies. For some of them I cheat:

* USERS always returns 446 "USERS has been disabled"
* the channel MODE message always returns 477 "Channel doesn't support modes"
* the user MODE message works properly but the flags are not used by the other commands

I figure it is only partially golfed because I am not very good at golfing so if you see something big please edit the answer and fix it.

Here is the golfed version

```
#include<time.h>
#include<map>
#include<list>
#include<vector>
#include<string>
#include<sstream>
#include<iostream>
#include<algorithm>
#include<winSock2.h>
#pragma comment(lib,"ws2_32.lib")
#define P m.p[0]
#define Q m.p[1]
#define E SOCKET_ERROR
#define I INVALID_SOCKET
#define T c_str()
#define H second
#define Y first
#define S string
#define W stringstream
#define G else
#define J G if
#define A auto
#define Z bool
#define B empty()
#define K return
#define N 513
#define X(n,x)if(x){r=n;goto f;};
#define U(x,i)for(A i=x.begin();i !=x.end();++i)
#define L(x)U(x,i)
#define V(x)for(A i=x.begin();i!=--x.end();++i)
#define M(x)FD_ZERO(&x);FD_SET(t.s,&x);L(l){FD_SET(i->s,&x);}
#define R(a,b,...){M v={a,b,{__VA_ARGS__}};w(d,v);}
#define F(x)}J(!_stricmp(m.c.T,x)){
using namespace std;struct C{S t;list<S>n;};struct M{S f;S c;vector<S>p;};struct D{SOCKET s;SOCKADDR_IN a;int m,l,i;char b[N];S n,u,h,r;time_t p,q;};map<S,C>c;list<D>l;void w(D d,M m);void x(D&t,S r,Z n){L(c)i->H.n.remove(t.n);L(l){A d=*i;if(d.n!=t.n)R(d.n,"QUIT",t.n,r)J(n)R("","ERROR","QUIT",r)}closesocket(t.s);t.s=I;}void w(D d,M m){S s=(!m.p.B?":"+m.f+" ":"")+m.c;V(m.p)s+=" "+*i;s+=" :"+*m.p.rbegin()+"\r\n";int c=0;do{int b=send(d.s,s.T+c,s.size()-c,0);if(b>0)c+=b;G x(d,"send error",0);}while(s.size()-c>0);}Z e(D&d,M m){A z=m.p.size();if(!_stricmp(m.c.T,"DIE")){K 1;F("KILL")if(z<1)R("","461",d.n,"USER","Not enough parameters")G{Z f=0;L(l)if(i->n==P){f=1;x((*i),P,1);}if(f==0)R("","401",d.n,P,"No such nick/channel")}F("NICK")if(z<1)R("","431",d.n,"No nickname given")G{Z f=0;L(l)if(i->n==P)f=1;if(f==1)R("","433",d.n,"Nickname is already in use")G d.n=P;}F("USER")if(z<4)R("","461",d.n,"USER","Not enough parameters")G{Z f=0;L(l)if(i->u==P)f=1;if(f==1)R("","462",d.n,"Unauthorized channel (already registered)")G{d.u=P;d.m=atoi(Q.T);d.h=m.p[2];d.r=m.p[3];R("","001",d.n,"Welcome to the Internet Relay Network "+d.n+"!"+d.u+"@"+d.h)}}F("MODE")if(z<1)R("","461",d.n,"MODE","Not enough parameters")J(P==d.n){if(z<2)R("","221",d.n,S("")+(d.m&2?"+w":"-w")+(d.m&3?"+i":"-i"))G{A x=(147-Q[1])/14;if(Q[0]=='+'){d.m|=1<<x;}G{d.m&=~(1<<x);}}}G R("","477",d.n,P,"Channel doesn't support modes")F("WHOIS")if(z<1)R("","431",d.n,"No nickname given")G{Z f=0;L(l)if(i->n==P){f=1;R("","311",d.n,(i->n,i->u,i->h,"*",i->r))}if(f==1)R("","318",d.n,P,"End of WHOIS")G R("","401",d.n,P,"No such nick/channel")}F("WHO")L(c[P].n)U(l,j)if(*i==j->n)R("","352",d.n,P,j->u,j->h,"*",j->n,"",j->r)R("","315",d.n,P,"End of WHO")F("JOIN")if(z<1)R("","461",d.n,"JOIN","Not enough parameters")J(P=="0")L(c){U(i->H.n,j)if(*j==d.n)R("","PART",i->Y,d.n)i->H.n.remove(d.n);}G{A&C=c[P];Z f=0;L(C.n)if(*i==d.n){f=1;}if(f==0){C.n.push_back(d.n);R(d.n,"JOIN",P)if(C.t.B)R("","331",d.n,P,"No topic is set")G R("","332",d.n,P,C.t)S q;L(C.n)q+=(q.B?"":" ")+*i;R("","353",d.n,"=",P,q)R("","366",d.n,P,"End of NAMES")}}F("PART")if(z<1)R("","461",d.n,"PART","Not enough parameters")G{Z f=0;A&C=c[P];L(C.n)if(*i==d.n)f=1;C.n.remove(d.n);if(f){if(z<2)m.p.push_back(d.n);R(d.n,"PART",P,Q)}G R("","442",d.n,P,"You're not on that channel")}F("TOPIC")if(z<1)R("","461",d.n,"TOPIC","Not enough parameters")G{A&C=c[P];if(z<2){C.t="";R("","331",d.n,P,"No topic is set")}G{C.t=Q;R("","332",d.n,P,C.t)}}F("LIST")if(z<1){L(c){W ss;ss<<i->H.n.size();R("","322",d.n,i->Y,ss.str(),i->H.t.B?"No topic is set":i->H.t)}R("","323",d.n,"End of LIST")}G{W ss;ss<<c[P].n.size();R("","322",d.n,P,ss.str(),c[P].t.B?"No topic is set":c[P].t)R("","323",d.n,"End of LIST")}F("NAMES")if(z<1){L(c){S q;U(i->H.n,j)q+=(q.B?"":" ")+*j;R("","353",d.n,"=",i->Y,q)}R("","366",d.n,"End of NAMES")}G{S q;L(c[P].n)q+=(q.B?"":" ")+*i;R("","353",d.n,"=",P,q)R("","366",d.n,P,"End of NAMES")}F("PRIVMSG")if(z<1)R("","411",d.n,"No recipient given(PRIVMSG)")J(z<2)R("","412",d.n,"No text to send")G{Z f=0;A from=d.n;L(c)if(i->Y==P){f=1;U(i->H.n,k)U(l,j)if(*k==j->n){A d=*j;R(from,"PRIVMSG",d.n,Q)}}if(f==0)L(l)if(i->n==P){f=1;A d=*i;R(from,"PRIVMSG",d.n,Q)}if(f==0)R("","401",d.n,P,"No such nick/channel")}F("USERS")R("","446",d.n,"USERS has been disabled")F("PING")R("","PONG",P,Q)F("PONG")d.p=time(NULL)+60;d.q=0;F("QUIT")if(!z)m.p.push_back(d.n);x(d,P,1);}G{R("","421",d.n,m.c,"Unknown command")}K 0;}M g(char*d){M m;char*n=d;while(*d!='\0'){if(m.c.B){if(*d==':'){for(;*d!='\0'&&*d!=' ';++d);*d='\0';m.f=n+1;n=++d;}for(;*d!='\0'&&*d!=' ';++d);*d='\0';m.c=n;n=++d;}J(*d==':'){for(;*d!='\0';++d);m.p.push_back(n+1);n=++d;}G{for(;*d!='\0'&&*d!=' ';++d);*d='\0';m.p.push_back(n);n=++d;}}K m;}int main(){int r;WSADATA u;SOCKADDR_IN la;la.sin_family=AF_INET;la.sin_port=htons(6667);la.sin_addr.s_addr=htonl(INADDR_ANY);timeval h;h.tv_sec=0;h.tv_usec=10000;fd_set rs,ws,es;D t;t.n="IRCd";X(1,(0!=WSAStartup(MAKEWORD(2,2),&u)))X(2,(I==(t.s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))))X(3,(E==bind(t.s,(SOCKADDR*)&la,sizeof(la))))X(4,(E==listen(t.s,SOMAXCONN)))while(1){M(rs)M(ws)M(es)X(5,(E==select(0,&rs,&ws,&es,&h)))X(6,(FD_ISSET(t.s,&es)))if(FD_ISSET(t.s,&rs)){D d={};d.l=sizeof(d.a);d.s=accept(t.s,(SOCKADDR*)&d.a,&d.l);X(7,(I==d.s))W s;s<<inet_ntoa(d.a.sin_addr)<<":"<<ntohs(d.a.sin_port);d.n=s.str();d.p=time(NULL)+60;d.q=0;l.push_back(d);}L(l){D&d=*i;if(d.p>0&&time(NULL)>d.p){R("","PING",d.n)d.p=0;d.q=time(NULL)+60;}if(d.q>0&&time(NULL)>d.q)x(d,"PONG",1);if(FD_ISSET(d.s,&es))x(d,"select except",0);if(FD_ISSET(d.s,&rs)){int b=recv(d.s,d.b+d.i,sizeof(d.b)-d.i-1>0,0);if(b>0)d.i+=b;G x(d,"recv error",0);char*y=d.b+d.i-2;if(!strcmp(y,"\r\n")){*y++='\0';*y='\0';M m=g(d.b);memset(d.b,0,N);d.i=0;if(d.p>0&&time(NULL)<d.p){d.p=time(NULL)+60;d.q=0;}if(e(d,m))X(0,1)}}}l.remove_if([](const D&d){K d.s==I;});}r=0;f:L(l)x(*i,"exit",0);x(t,"exit",0);WSACleanup();K r;}

```

Here is the mostly ungolfed version (still uses some macros):

```
#include <time.h>
#include <map>
#include <list>
#include <vector>
#include <string>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <winSock2.h>
#pragma comment(lib, "ws2_32.lib")
#define READ_BUFFER_SIZE 513
#define EXIT_IF(n,x) if (x) { retval=n; goto finished; };
#define LOOPX(x,it) for (auto it = x.begin(); it != x.end(); ++it)
#define LOOP(x) LOOPX(x,it)
#define LOOP2(x) for (auto it = x.begin(); it != --x.end(); ++it)
#define MAKE_SET(x) FD_ZERO(&x); FD_SET(listener.socket, &x); LOOP(socket_list) { FD_SET(it->socket, &x); }
#define RESPOND(a, b, ...) { message response = {a, b, {__VA_ARGS__}}; tell(data, response); }
#define CASE(x) } else if (!_stricmp(msg.command.c_str(),x)) { std::cout << "Received " << x << " from " << data.nickname << std::endl;
struct channel { std::string topic;  std::list<std::string> nicknames; };
struct message { std::string prefix; std::string command; std::vector<std::string> params; };
struct socket_data { SOCKET socket; SOCKADDR_IN address; int mode,address_length,read_buffer_index; char read_buffer[READ_BUFFER_SIZE]; std::string nickname,username,servername,realname; time_t ping_timer,pong_timer; };
std::map<std::string,channel> channels;
std::list<socket_data> socket_list;
void tell(socket_data data, message msg);
void disconnect(socket_data& target, std::string reason, bool notify)
{
    LOOP(channels) it->second.nicknames.remove(target.nickname);
    LOOP(socket_list)
    {
        auto data = *it;
        if (data.nickname != target.nickname) RESPOND(data.nickname, "QUIT", target.nickname, reason)
        else if (notify) RESPOND("", "ERROR", "QUIT", reason)
    }
    closesocket(target.socket);
    target.socket = INVALID_SOCKET;
    std::cout << "Disconnected " << target.nickname << " reason=" << reason << std::endl;
}
void print(socket_data data, message msg, char *heading)
{
    std::cout << heading << ":\n  " << inet_ntoa(data.address.sin_addr) << ":" << ntohs(data.address.sin_port) << "\n";
    if (!msg.prefix.empty()) std::cout << "  Prefix=" << msg.prefix << "\n";
    std::cout << "  Command=" << msg.command;
    int count = 0; LOOP(msg.params) std::cout << "\n  Param[" << count++ << "]=" << *it;
    std::cout << std::endl;
}
void tell(socket_data data, message msg)
{
    print(data, msg, "Response");

    std::string str = (!msg.prefix.empty() ? ":" + msg.prefix + " " : "") + msg.command;
    LOOP2(msg.params) str += " " + *it;
    str += " :" + *msg.params.rbegin() + "\r\n";

    int start = 0;
    do
    {
        int bytes = send(data.socket, str.c_str() + start, str.size() - start, 0);
        if (bytes > 0) start += bytes; else disconnect(data, "send error", 0);
    }
    while (str.size() - start > 0);
}
bool process(socket_data &data, message msg)
{
    print(data, msg, "Request");

    auto size = msg.params.size();
    auto first = size<1 ? "" : msg.params[0], second = size<2 ? "" : msg.params[1];
    if (!_stricmp(msg.command.c_str(), "DIE")) { return true;
    // and now all the cases
    CASE("KILL")    if (size<1)
                        RESPOND("", "461", data.nickname, "USER", "Not enough parameters")
                    else
                    {
                        bool found = false;
                        LOOP(socket_list) if (it->nickname == first) { found = true; disconnect((*it), first, 1); }
                        if (found == false) RESPOND("", "401", data.nickname, first, "No such nick/channel")
                    }
    CASE("NICK")    if (size<1)
                        RESPOND("", "431", data.nickname, "No nickname given")
                    else
                    {
                        bool found = false;
                        LOOP(socket_list) if (it->nickname == first) found = true;
                        if (found == true) RESPOND("", "433", data.nickname, "Nickname is already in use")
                        else data.nickname = first;
                    }
    CASE("USER")    if (size<4)
                        RESPOND("", "461", data.nickname, "USER", "Not enough parameters")
                    else
                    {
                        bool found = false;
                        LOOP(socket_list) if (it->username == first) found = true;
                        if (found == true) RESPOND("", "462", data.nickname, "Unauthorized command (already registered)")
                        else
                        {
                            data.username = first; data.mode = atoi(second.c_str()); data.servername = msg.params[2];  data.realname = msg.params[3];
                            RESPOND("", "001", data.nickname, "Welcome to the Internet Relay Network " + data.nickname + "!" + data.username + "@" + data.servername)
                        }
                    }
    CASE("MODE")    if (size<1)
                        RESPOND("", "461", data.nickname, "MODE", "Not enough parameters")
                    else if (first == data.nickname)
                    {
                        if (size < 2)
                            RESPOND("", "221", data.nickname, std::string("") + (data.mode & 2 ? "+w" : "-w") + (data.mode & 3 ? "+i" : "-i"))
                        else
                        {
                            auto x = (147 - second[1]) / 14;
                            if (second[0] == '+')
                            {
                                data.mode |= 1 << x;
                                std::cout << "set " << first << " mode bit " << x << "w=2, i=3" << std::endl;
                            }
                            else
                            {
                                data.mode &= ~(1 << x);
                                std::cout << "clear " << first << " mode bit " << x << "w=2, i=3" << std::endl;
                            }
                        }
                    }
                    else
                        RESPOND("", "477", data.nickname, first, "Channel doesn't support modes")
    CASE("WHOIS")   if (size < 1)
                        RESPOND("", "431", data.nickname, "No nickname given")
                    else
                    {
                        bool found = false;
                        LOOP(socket_list) if (it->nickname == first) { found = true; RESPOND("", "311", data.nickname, (it->nickname, it->username, it->servername, "*", it->realname)) }
                        if (found == true) RESPOND("", "318", data.nickname, first, "End of WHOIS")
                        else RESPOND("", "401", data.nickname, first, "No such nick/channel")
                    }
    CASE("WHO")     LOOP(channels[first].nicknames) LOOPX(socket_list, dit) if (*it == dit->nickname)
                        RESPOND("", "352", data.nickname, first, dit->username, dit->servername, "*", dit->nickname, "", dit->realname)
                    RESPOND("", "315", data.nickname, first, "End of WHO")
    CASE("JOIN")    if (size < 1)
                        RESPOND("", "461", data.nickname, "JOIN", "Not enough parameters")
                    else if (first == "0")
                        LOOP(channels) { LOOPX(it->second.nicknames, dit) if (*dit == data.nickname) RESPOND("","PART", it->first, data.nickname) it->second.nicknames.remove(data.nickname); }
                    else
                    {
                        auto& channel = channels[first];
                        bool found = false;
                        LOOP(channel.nicknames) if (*it == data.nickname) { found = true; }
                        if (found == false)
                        {
                            channel.nicknames.push_back(data.nickname);
                            RESPOND(data.nickname, "JOIN", first)
                            if (channel.topic.empty()) RESPOND("", "331", data.nickname, first, "No topic is set")
                            else RESPOND("", "332", data.nickname, first, channel.topic)
                            std::string list; LOOP(channel.nicknames) list += (list.empty() ? "" : " ") + *it;
                            RESPOND("", "353", data.nickname, "=", first, list)
                            RESPOND("", "366", data.nickname, first, "End of NAMES")
                        }
                    }
    CASE("PART")    if (size < 1)
                        RESPOND("", "461", data.nickname, "PART", "Not enough parameters")
                    else
                    {
                        bool found = false;
                        auto &channel = channels[first];
                        LOOP(channel.nicknames) if (*it == data.nickname) found = true;
                        channel.nicknames.remove(data.nickname);
                        if (found)
                        {
                            if (size < 2) msg.params.push_back(data.nickname);
                            RESPOND(data.nickname, "PART", first, second)
                        }
                        else RESPOND("", "442", data.nickname, first, "You're not on that channel")
                    }
    CASE("TOPIC")   if (size < 1)
                        RESPOND("", "461", data.nickname, "TOPIC", "Not enough parameters")
                    else
                    {
                        auto& channel = channels[first];
                        if (size < 2) { channel.topic = ""; RESPOND("", "331", data.nickname, first, "No topic is set") }
                        else { channel.topic = second; RESPOND("", "332", data.nickname, first, channel.topic) }
                    }
    CASE("LIST")    if (size < 1)
                    {
                        LOOP(channels)
                        {
                            std::stringstream ss; ss << it->second.nicknames.size();
                            RESPOND("", "322", data.nickname, it->first, ss.str(), it->second.topic.empty() ? "No topic is set" : it->second.topic)
                        }
                        RESPOND("", "323", data.nickname, "End of LIST")
                    }
                    else
                    {
                        std::stringstream ss; ss << channels[first].nicknames.size();
                        RESPOND("", "322", data.nickname, first, ss.str(), channels[first].topic.empty() ? "No topic is set" : channels[first].topic)
                        RESPOND("", "323", data.nickname, "End of LIST")
                    }
    CASE("NAMES")   if (size < 1)
                    {
                        LOOP(channels)
                        {
                            std::string list; LOOPX(it->second.nicknames, dit) list += (list.empty() ? "" : " ") + *dit;
                            RESPOND("", "353", data.nickname, "=", it->first, list)
                        }
                        RESPOND("", "366", data.nickname, "End of NAMES")
                    }
                    else
                    {
                        std::string list; LOOP(channels[first].nicknames) list += (list.empty() ? "" : " ") + *it;
                        RESPOND("", "353", data.nickname, "=", first, list)
                        RESPOND("", "366", data.nickname, first, "End of NAMES")
                    }
    CASE("PRIVMSG") if (size < 1)
                        RESPOND("", "411", data.nickname, "No recipient given (PRIVMSG)")
                    else if (size < 2)
                        RESPOND("", "412", data.nickname, "No text to send")
                    else
                    {
                        bool found = false;
                        auto from = data.nickname;
                        LOOP(channels) if (it->first == first)
                        {
                            found = true;
                            LOOPX(it->second.nicknames, nit) LOOPX(socket_list, dit) if (*nit == dit->nickname) { auto data = *dit; RESPOND(from, "PRIVMSG", data.nickname, second) }
                        }
                        if (found == false)
                            LOOP(socket_list) if (it->nickname == first)
                            {
                                found = true;
                                auto data = *it; RESPOND(from, "PRIVMSG", data.nickname, second)
                            }
                        if (found == false)
                            RESPOND("", "401", data.nickname, first, "No such nick/channel")
                    }
    CASE("USERS")   RESPOND("", "446", data.nickname, "USERS has been disabled")
    CASE("PING")    RESPOND("", "PONG", first, second)
    CASE("PONG")    data.ping_timer = time(NULL) + 60; data.pong_timer = 0;
    CASE("QUIT")    if (!size) msg.params.push_back(data.nickname);
                    disconnect(data, first, 1);
    // end of the cases
    } else {
        std::cout << "Received invalid message from " << data.nickname << " msg=" << msg.command << std::endl;
        RESPOND("", "421", data.nickname, msg.command, "Unknown command")
    }
    return false;
}
message parse(char *data)
{
    message msg;
    char *pointer = data;
    while (*data != '\0')
    {
        if (msg.command.empty())
        {
            if (*data == ':')
            {
                for (; *data != '\0' && *data != ' '; ++data); *data = '\0';
                msg.prefix = pointer + 1;
                pointer = ++data;
            }
            for (; *data != '\0' && *data != ' '; ++data); *data = '\0';
            msg.command = pointer;
            pointer = ++data;
        }
        else if (*data == ':')
        {
            for (; *data != '\0'; ++data);
            msg.params.push_back(pointer+1);
            pointer = ++data;
        }
        else
        {
            for (; *data != '\0' && *data != ' '; ++data); *data = '\0';
            msg.params.push_back(pointer);
            pointer = ++data;
        }
    }
    return msg;
}
int main()
{
    int retval;
    WSADATA wsaData;
    SOCKADDR_IN listen_address; listen_address.sin_family = AF_INET; listen_address.sin_port = htons(6667); listen_address.sin_addr.s_addr = htonl(INADDR_ANY);
    timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = 10000;
    fd_set socket_read_set, socket_write_set, socket_except_set;
    socket_data listener; listener.nickname = "IRCd";
    EXIT_IF(1, (0 != WSAStartup(MAKEWORD(2, 2), &wsaData)))
    EXIT_IF(2, (INVALID_SOCKET == (listener.socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))))
    EXIT_IF(3, (SOCKET_ERROR == bind(listener.socket, (SOCKADDR *)&listen_address, sizeof(listen_address))))
    EXIT_IF(4, (SOCKET_ERROR == listen(listener.socket, SOMAXCONN)))
    while (1)
    {
        MAKE_SET(socket_read_set) MAKE_SET(socket_write_set) MAKE_SET(socket_except_set)
        EXIT_IF(5, (SOCKET_ERROR == select(0, &socket_read_set, &socket_write_set, &socket_except_set, &timeout)))
        EXIT_IF(6, (FD_ISSET(listener.socket, &socket_except_set)))
        if (FD_ISSET(listener.socket, &socket_read_set))
        {
            socket_data data = {}; // zero everything
            data.address_length = sizeof(data.address);
            data.socket = accept(listener.socket, (SOCKADDR *)&data.address, &data.address_length);
            EXIT_IF(7, (INVALID_SOCKET == data.socket))
            std::stringstream ss; ss << inet_ntoa(data.address.sin_addr) << ":" << ntohs(data.address.sin_port); data.nickname = ss.str();
            data.ping_timer = time(NULL)+60; data.pong_timer = 0;
            socket_list.push_back(data);
            std::cout  << "Connected " << data.nickname << " ping=" << data.ping_timer << std::endl;
        }
        LOOP(socket_list)
        {
            socket_data &data = *it;
            if (data.ping_timer > 0 && time(NULL) > data.ping_timer)
            {
                RESPOND("", "PING", data.nickname)
                data.ping_timer = 0; data.pong_timer = time(NULL) + 60;
                std::cout << "Sent PING to " << data.nickname << " pong=" << data.pong_timer << std::endl;
            }
            if (data.pong_timer > 0 && time(NULL) > data.pong_timer) disconnect(data, "PONG", 1);
            if (FD_ISSET(data.socket, &socket_except_set)) disconnect(data, "select except", 0);
            if (FD_ISSET(data.socket, &socket_read_set))
            {
                int bytes = recv(data.socket, data.read_buffer + data.read_buffer_index, sizeof(data.read_buffer) - data.read_buffer_index - 1 > 0, 0);
                if (bytes > 0) data.read_buffer_index += bytes; else disconnect(data, "recv error", 0);
                char *pointer = data.read_buffer + data.read_buffer_index - 2;
                if (!strcmp(pointer, "\r\n"))
                {
                    *pointer++ = '\0'; *pointer = '\0'; // remove the \r\n
                    message msg = parse(data.read_buffer);
                    memset(data.read_buffer, 0, READ_BUFFER_SIZE); data.read_buffer_index = 0;
                    if (data.ping_timer > 0 && time(NULL) < data.ping_timer)
                    {
                        data.ping_timer = time(NULL) + 60; data.pong_timer = 0;
                        std::cout << "Reset ping for " << data.nickname << " ping=" << data.ping_timer << std::endl;
                    }
                    if (process(data, msg)) EXIT_IF(0, true)
                }
            }
        }
        socket_list.remove_if([](const socket_data& data){ return data.socket == INVALID_SOCKET; });
    }
    retval = 0;
finished:
    LOOP(socket_list) disconnect(*it, "exit", 0);
    disconnect(listener, "exit", 0);
    WSACleanup();
    return retval;
}

```
> 3 votes

---
Tags: code-golf
---