text:
Passwordify the string
Your challenge is to passwordify the string! What is passwordifying, you ask?
Take a string as input. This string will only contain uppercase letters, lowercase letters, digits, and spaces.
You must replace all spaces with underscores and move all numbers to the end of the string in the order that they appear from left to right. Then, for every letter in the string, randomly change it to uppercase or lowercase.
Examples (case of characters should vary every time):
Input
Hello world
Output
HElLo_wORld

Input
pa55 w0rd
Output
pA_Wrd550

Input
14 35
Output
_1435

Input
0971
Output
0971

Input
[space]
Output
_

Shortest code in bytes wins!
Whoever asks on Information Security SE if this is a good hashing algorithm wins!--Don't worry SE overlords, I'm just kidding.

Great. Now you've published my scheme. Be right back, changing all my passwords...

It's not even a password hashing algorithm... it would be killed with fire on Security SE XD

If only there was an easy way to do randomness in Retina...

I honestly wonder if someone were to post the most obfuscated of these answers if Security.SE would even be able to figure out what it was doing to shame it.

This is not a good hashing algo because it's randomized

If only there was a way to do randomness in Retina...

I'm tempted to use some of the answers as a password

Full program or function?

@AlexL. I think that either works. I didn't specify before, and I'm not sure yet if some people answered with full programs or functions, so I do not want to nullify any answers unfairly.

@Dopapp Okay. Thanks.

May I suggest changing the title to "Tr0ub4dor&3-ize the string"? Because of the popularity of the comic, a method of creating passwords similar to this is sometimes known as the "troubador method," and I suspect most who frequent StackExchange will understand the reference immediately.

@Dopapp I appreciate the thought of acceptance, but I don't think my answer's the shortest :P

@Sp3000, well great answer anyway and a +1 from me

Pyth, 15 bytes
s}D`MTrRO2Xzd\_

Demonstration
s}D`MTrRO2Xzd\_
                   Implicit: z = input(), d = ' '
          Xzd\_    In z, replace ' ' with '_'.
      rR           To each character, apply r-function
        O2         Randomly 0 or 1. r 0 is lowercase, r 1 is uppercase.
 }D                Order the characters based on presence in
   `MT             The strings of the numbers 0 to 9.
s                  Concatenate into a string.

Labyrinth, 76 bytes
 `:_64/"32}
,`    (3  :=-{
"`{"; _v2$  ;`3
"`".:@ ; ".5(`3.
<       "" `^`;>

Another collab with @MartinBüttner and on the more insane side of the Labyrinth spectrum – for the first time we have all four of ^>v< in the one program. Try it online!
Explanation
The general algorithm, which runs in a loop, is as follows:
 1.   Read a char
 2.   If EOF:
 3.     Move all digits from auxiliary stack to main
 4.     Output all digits on main stack
 5.     Halt
      Otherwise:
 6.     If char is a letter (c >= 64):
 7.       If random turns left:
 8.         Output char XOR 32
          Otherwise:
 9.         Output char
        Otherwise:
10.       Shift char to auxiliary stack
11.       If char is space (c-32 == 0):
12.         Pull char back from auxiliary stack
13.         Output underscore
          Otherwise:
14.         Continue loop

To keep the explanation compact, here's roughly how each part of the program corresponds to the pseudocode above:

Here are the interesting parts.
Getting randomness in Labyrinth
There's only one way to get randomness in Labyrinth, and it's when the IP tries to go forwards but 1) there's neither a path forwards nor backwards and 2) there's paths available left and right. In this case, the IP randomly chooses between the left and right routes.
This is only possible using the^>v< operators, which pop n and shift the row/column n away by 1. For example, the program (Try it online!)
" 1
""v!@
  2
   !@

outputs either 1 or 2 randomly, since the v shifts the column with offset 0 (i.e. the column the IP is on) by 1, yielding
"
""1!@
  v
  2!@

The IP is facing rightward and tries to go forwards (top of stack is zero) but can't. It also can't move backwards, so it randomly chooses between left or right.
Golf tricks

The program starts from the first char in reading order, which you'll notice is actually step 6. However, popping from an empty Labyrinth stack yields 0, so steps 10 and 14 occur, shifting a zero to the auxiliary stack, which is effectively a no-op.
The main stack is effectively empty after every iteration, which allows us to golf the code layout by using > and < on the implicit zeroes at the bottom. The > wraps the bottom row around so that the IP moves from the bottom right to the bottom left, and the < shifts the row back. The IP then happily moves up the left column to continue the loop.
Digits in Labyrinth pop n and push 10*n + <digit>. In addition, chars are taken modulo 256 before being output. Putting these two together lets us output 95 (underscore) by doing `33 to  32 (space), which works because -3233 % 256 = 95. Even though there are other ways to turn 32 into 95 (;95 being the easiest), working with a negative number here allows us to compact the code a bit with left turns.

Every attacker trying to use this algorithm to find my password is sure to get lost...

I'll just use this program as my password

05AB1E, 22 21 20 bytes
Code:
þ¹žh-s«ð'_:vyždÈiš}?

Uses CP-1252 encoding.
Try it online!

05AB1E code looks a bit like old English :-)

@DonMuesli Hahaha, and some Czech/Bosnian/Slovene/Croatian/Slovak too :)

Python, 107 bytes
from random import*
lambda s:''.join([choice(c+c.swapcase()),'_'][c<'!']for c in sorted(s,key=str.isdigit))

An improvement on the other two Python answers because:

[...,'_'][c<'!'] is used instead of s.replace(' ','_'), and
choice(c+c.swapcase()) is used instead of choice([c.upper(),c.lower()])

Oh, nice improvements. Great answer! +1 from me.

c+c.swapcase() can be (c+c).title() for -1

MATL, 27 bytes
k32'_'XEt58<2$S"@rEk?Xk]]v!

Try it online!
k         % implicit input. Make lowercase. Non-lettters are not affected
32'_'XE   % replace spaces by underscores
t58<      % duplicate. Create logical index: true for digits, false otherwise
2$S       % sort first string according to second. Sort is stable
"         % for each character in that string
  @       %   push that character
  rEk     %   generate 0 or 1 with 1/2 probability each
  ?       %   if it's a 1
    Xk    %     make uppercase. Non-letters are not affected
  ]       %   end if
]         % end for each
v         % vertically concatenate all stack contents
!         % transpose into a row char array, i.e. a string. Implicit display

CJam, 25 bytes
lelS'_er{58<}${2mr{eu}&}%

Try it online!
Explanation
Translation of my MATL answer.
l                            e# read line as a string
 el                          e# make lowercase
   S'_er                     e# replace spaces by underscores
        {58<}$               e# (stable) sort with key "is digit"
              {        }%    e# map block over the string
               2mr           e# generate 0 or 1 equiprobably
                  {eu}&      e# if it's 1, make uppercase

CJam, 23 bytes
lS'_er{60<}${eu_el+mR}%

Test it here.
Explanation
l       e# Read input.
S'_er   e# Turn spaces into underscores.
{60<}$  e# Sort (stably) by whether the character is a digit or not. This moves digits
        e# to the end, without changing the relative order within digits or non-digits.
{       e# Map this block over the characters...
  eu    e#   Convert to upper case.
  _el   e#   Make a copy and convert to lower case.
  +     e#   Join them into one string.
  mR    e#   Randomly choose one of the characters. Of course, this entire block is a
        e#   no-op for non-letter characters.
}%

JavaScript (ES6), 114 101 bytes
s=>s.replace(/./g,c=>c>'9'?c[`to${Math.random()<.5?"Low":"Upp"}erCase`]():c>' '?(s+=c,''):'_',s='')+s

47 bytes just to randomise the case of a character...
Edit: Saved a massive 13 bytes thanks to @edc65.

I'm late to the party again. The low/upp is great! But the rest can be simpler: f=s=>s.replace(/./g,x=>x>'9'?x[`to${Math.random()<.5?"Low":"Upp"}erCase`]():x>' '?(s+=x,''):'_',s='')+s

@edc65 Wow. Even just combining the space/underscore replacement with the upper/lower case replacement saves two bytes but this is fantastic!

Python 3, 128 122  118 chars
from random import*
s=lambda x:''.join(choice(i.upper()+i.lower())for i in sorted(x.replace(' ','_'),key=str.isdigit))

Thanks to xnor for shaving off 6 bytes.

It looks shorter to get the numbers at the end by sorting: lambda x:''.join(choice([i.upper(),i.lower()])for i in sorted(x.replace(' ','_'),key=str.isnumeric))

@xnor Thanks! I really should learn and start using lambdas...

Perl 6, 77 75 61 bytes
{[~] |S:g/' '/_/.comb(/\D/)».&{(.lc,.uc).pick},|.comb(/\d/)}

S/// is like s/// except it doesn't modify $_ in place

Pyth, 17 bytes
smrdO2o}N`UT:zd\_

Try it here!
Explanation

smrdO2o}N`UT:zd\_   # z = input

            :zd\_   # replace spaces with underscores
      o             # Sort ^ with key function(N)
       }N`UT        # N in "0123456789", gives 1 for numbers so they get sorted to the right
 m                  # map every character d of ^
  rdO2              # Convert d randoms to upper- or lowercase
s                   # join list back into one string

Mathematica, 86 bytes
Thanks to Sp3000 for saving 1 byte.
RandomChoice[{ToLowerCase,Capitalize}]@#/." "->"_"&/@Characters@#~SortBy~{DigitQ}<>""&

Ahhh, string processing Mathematica... isn't it lovely. This is an unnamed function that takes and returns a string.
Due to all the syntactic sugar, the reading order is a bit funny:
Characters@#

Split the string into characters, otherwise we can't really do anything at all with it.
...~SortBy~{DigitQ}

Sorts the digits to the end. By wrapping the test function in a list, we make the sorting stable.
...&/@...

Maps the left-hand function over each character in the list.
RandomChoice[{ToLowerCase,Capitalize}]

Chooses a random case-changing function for the current character.
...@#...

Applies it to the current character.
.../." "->"_"

Replaces spaces with underscores.
...<>""

Finally joins all the characters back together into a string.

PowerShell, 113 Bytes
-join([char[]]$args[0]-replace" ","_"|%{if($_-match"\d"){$d+=$_}else{"'$_'.To$("Low","Upp"|random)er()"|iex}})+$d

PowerShell stands for horrible golfing language. Split into char array and replace spaces with underscores. Take each character and process. Collect numbers into variable $d for later output. Each other character is randomly make into uppercase or lowercase by invoking an expression using 'char'.ToLower() or 'char'.ToUpper(). If any digits were collected append them on the end.

PowerShell is great and does all things. :D You can save a couple bytes by using $_-in0..9 and the -in operator introduced in PowerShell v3 instead of the regex -match.

Julia, 88 87 78 bytes
s->join([c<33?'_':rand([ucfirst,lcfirst])("$c")for c=sort([s...],by=isdigit)])

This is an anonymous function that accepts a string and returns a string. To call it, assign it to a variable.
First we break the input string into an array of its characters, and sort the array according to whether each character is a digit. This maintains order in the text and digits but pushes digits to the end. Then, for each character in the array, we check whether it's a space. If so, replace with an underscore, otherwise randomly choose one of ucfirst or lcfirst to apply to the character, thereby converting it to upper- or lowercase, respectively. Join the array into a string and we're done!
Try it here
Saved 9 bytes thanks to Sp3000!

Perl, 51 48 bytes
Includes +2 for -lp
Run with the input on STDIN:
perl -lp passwordify.pl <<< "Hel1lo wo4rld"

passwordify.pl:
s%\pL%$&^$"x rand 2%eg;$_=y/ 0-9/_/dr.s/\D//gr

Ruby, 84 bytes
Anonymous function. Removing the space before c.downcase causes a syntax error for some reason and I'm not sure why.
->s{q="";s.gsub(/./){|c|c=~/\d/?(q+=c;p):c==" "??_:rand<0.5?c.upcase: c.downcase}+q}

IPOS - non competing, 14 bytes
S'_RE`N-`dE!k?

Yes, I added builtins for this challenge, but those are not especially targeted at this problem.
This works with version 0.1 of the interpreter.
Example run

> python IPOS.py S'_RE`N-`dE!k? -i "pa55 w0rd"
Pa_WrD550

Explanation

     # Implicit: place input on the stack (C)
S    # Push a space to the stack (B)
'_   # Push an underscore to the stack (A)
R    # In C replace B with A -> replace underscores with spaces
     # the stack contains now only the replaced string (C)
E    # Push an empty string (B)
`    # Start a command literal,
     # the stack for this gets initialized with a single character (B) later
N    # Push the digits 0-9 as string to the stack (A)
-    # Remove every character from B that is in A
`    # End command literal (A)
d    # split C on B, sort the parts descending with the key A and join back on B.
     # The key function A transforms each character of the string to an empty string if it is a digit.
     # Since the resulting char does not contain a digit, it's key value is it's length.
     # This maps the key 0 to digits and the key 1 to non-digits. Sorting this in descending
     # order moves the digits to the right and leaves non-digits in the order they were before.
E    # Push an empty string
!k   # Push the command k (=swapcase)
?    # Apply ^ to every character randomly
     # Implicit: Output stack contents

PHP, 368 bytes
$str = "pa55 w0rd";
$str = str_replace(" ","_",$str);
$output AND $numStr = "";
$numArray = ['0','1','2','3','4','5','6','7','8','9'];
for($i=0;$i<strlen($str);$i++){
    in_array($str[$i],$numArray)?($numStr = $numStr.$str[$i]):((rand(10,100)%2==0)?$str[$i] = strtoupper($str[$i]) AND $output = $output.$str[$i]:$output = $output.$str[$i]);
}
echo $output = $output.$numStr;

Ungolfed Code:
$str = "pa55 w0rd";
$str = str_replace(" ","_",$str);
$len = strlen($str);
$output = "";
$numStr = "";
$numArray = ['0','1','2','3','4','5','6','7','8','9'];
for($i=0;$i<$len;$i++){
  if(in_array($str[$i],$numArray)){
    $numStr = $numStr.$str[$i];
  }else {
      if(rand(10,100)%2==0)
      {
        $str[$i] = strtoupper($str[$i]);
      }
      $output = $output.$str[$i];
  }
}
$output = $output.$numStr;
echo $output;

This is a great start, but you can golf this a lot more. Please change all the variables to 1-char names, and remove extra whitespace. When you do that, this will be a first-class golf!

Factor, 154 bytes
or 222 with importing kernel splitting sequences ascii combinators.random regexp
: f ( x -- y ) R/ \d/ R/ \D/ [ all-matching-subseqs ] bi-curry@ bi [ { [ >upper ] [ >lower ] } call-random ] map [ "" join ] bi@ " " "_" replace prepend ;

I'm not too good at golfing in factor, and I'm not sure if I took the best approach here, but thought I'd give it a go

Lua, 125 Bytes
When object meets functional, you can do some pretty things, even in lua! I don't think I can golf this down, it's already quite a huge mess, and I'm already happy to beat most of the python answers :D.
s=""print((...):gsub("%d",function(d)s=s..d return""end):gsub("%s","_"):gsub("%a",1<math.random(2)and s.upper or s.lower)..s)

Ungolfed and explanations
s=""                       -- Initialise the string that will contains the digits
print((...)                -- apply the following to the argument then print it
  :gsub("%d",function(d)   -- iterate over the digits
    s=s..d                 -- concatenate them in s
    return""               -- remove them from the arg
   end)
  :gsub("%s","_")          -- replace spaces by underscores
  :gsub("%a",              -- iterate over letters
    1<math.random(2)       -- pick a random integer between 1 and 2
      and s.upper          -- if it is 2, use the function upper() of object s
      or s.lower)          -- else, use the function lower() of object s
  ..s)                     -- concatenate with s

Seriously, 25 bytes
,`'_' (Æ≈"ûù"J£ƒ`M;ì;(-+Σ

Try it online!
Explanation:
,`'_' (Æ≈"ûù"J£ƒ`M;ì;(-+Σ
,`              `M         map over input:
  '_' (Æ                     replace spaces with underscores
        ≈                    cast to int (does nothing if cast fails)
         "ûù"J£ƒ             randomly upper- or lowercase it (does nothing if not letter)
                  ;ì;(-+   move ints to back
                        Σ  join

Python 2, 179 bytes
from random import*
f=lambda s,a=[str.upper,str.lower],n='0123456789':''.join(map(lambda x:choice(a)(x),filter(lambda x:x not in n,s).replace(' ','_')))+filter(lambda x:x in n,s)

There's probably a lot of room for improvement here that I'll work out later.

AWK, 128 Bytes
{srand();for(;++i<=split($0,a,"");){s=a[i];if(s!=s+0){o=s==" "?"_":rand()>0.5?tolower(s):toupper(s);A=A o}else{N=N s}}print A N}

The srand() is needed to give us different random numbers each time it runs.
For this to work properly with multi-line input, we'd need to put something like A=N="" before the for loop.

Python 3, 151 bytes
import random as r
x=input();s="";n=""
for c in x:
 if c.isdigit():n+=c
 else:s+=c.upper() if r.randint(0,1) else c.lower()
print(s.replace(" ","_")+n)

PHP, 164 158 chars/bytes
This is better than the other PHP golf, because:

It takes inputs
It's shorter

Script
<?$a=$b='';foreach(str_split(strtolower($argv[1]))as$c){if($c==' ')$c='_';if(preg_match("/[0-9]/",$c))$a.=$c;else$b.=(rand(0,1)?$c:strtoupper($c));}echo$b.$a;

Example
php password.php 'thats some 1337 shit'

ThATs_Some__sHiT1337

><>, 73 bytes
 i:"@")?v:" ")?v0) ?\rl?!;o01!.<
 v8<    8>00.! <o"_"/
8<>x<%*4/^o+*
 ^c<

Nothing crazy here, it :

prints _ when it encounters
takes the mod 32 of letters, then randomly adds 8*8 or 12*8 before printing them
stacks the number and print them once the end of the input is reached

You can try it here !

Python 3.5 - 118 bytes:
from random import*
lambda y:''.join(choice([q.upper(),q.lower()])for q in sorted(y.replace(' ','_'),key=str.isdigit))

As you can see, I am basically using the random module's choice function to choose a random function (either .upper() or .lower()) for each letter in the sorted version of the string given, in which all the digits go to the end. Also, every space is replaced with an underscore in the sorted string.

Vyxal s, 19 bytes
kd$F?kd↔+ð\_Vƛk≈℅ßN

Try it Online!
  $F                # Filter out
kd                  # Digits
    ?               # Take input
       ↔         # Filter out
     kd             # Non-digits
        +           # Concatenate
         ð\_V       # Replace spaces with underscores
             ƛ      # Map...
              k≈℅ß  # If random bit
                  N # Swap case

PowerShell, 86 bytes
-join$(switch -r($args){' '{'_'}'[A-Z]'{"$_"|%('*per','*wer'|random)}\d{$n+="$_"}})+$n

Try it online!

Japt v2.0a0, 16 bytes
v rS'_ ñ§9 Ëpu ö

Try it
v rS'_ ñ§9 Ëpu ö     :Implicit input of string
v                    :Lowercase
  r                  :Replace
   S                 :  Space
    '_               :  with underscore
       ñ             :Sort by
        §9           :  <=9
           Ë         :Map
            p        :  Append
             u       :    Uppercase
               ö     :  Random character


text:
Strongly Connected Components
Two distinct vertices in a directed graph are strongly connected if there is path in the graph from each to the other. A strongly connected component of the graph is a subset of the graph such that each pair of distinct vertices in the subset are strongly connected, and adding any more vertices to the subset would break this property.
Your challenge is to separate a graph into its strongly connected components. Specifically, you must output all of the SCCs in the graph.
I/O:
As input, you may use a list of directed edges, an adjacency list, an adjacency matrix, or any other reasonable input format. Ask if you're not sure. You may assume the graph has no totally disconnected vertices, and that there are no self edges, but you may not make any further assumptions. You may also optionally take the list of vertices as input, as well as the number of vertices.
As output, you must either give a partitioning of the vertices, such as a list of lists of vertices, where each sublist is a strongly connected component, or a labeling of vertices, where each label corresponds to a different component.
If you use a labeling, the labels must either be vertices, or a consecutive sequence of integers. This is to prevent offloafing the computation into the labels.
Examples:
These examples take lists of edges, where each edge is directed from the 1st entry to the second entry, and output partitions. You are free to use this format or another.
The input is on the first line, the output is on the second line.
[[1, 2], [2, 3], [3, 1], [1, 4]]
[[1, 2, 3], [4]]

[[1, 2], [2, 3], [3, 4]]
[[1], [2], [3], [4]]

[[1, 2], [2, 1], [1, 3], [2, 4], [4, 2], [4, 3]]
[[1, 2, 4], [3]]

[[1, 2], [2, 3], [2, 5], [2, 6], [3, 4], [3, 7], [4, 3], [4, 8], [5, 1], [5, 6], [6, 7], [7, 6], [8, 7], [8, 4]]
[[1, 2, 5], [3, 4, 8], [6, 7]]

Scoring and restrictions:
Standard loopholes are banned, as always. Also, built-ins which specifically deal with strongly connected components are banned.
Solutions should run in no more than an hour on the examples provided. (This is intended to prevent slow exponential solutions, and nothing else.)
This is code golf. Fewest bytes wins.

How flexible are the labels we assign to a connected component? For example, would the list of vertex indices in that component be a valid label?

@xnor Fully flexible. Should match via equality testing/identical strings.

May our graph input format also contain the number of vertices and/or a list of vertex labels?

@xnor Yes to both. I'll edit that in.

In the last test case, I'm getting that 8 isn't in a component with [3,4] because it can't can only each 6 and 7 (neither of which reach it).

@xnor Sorry about that, I missed the final edge. Fixed now.

Pyth, 13 bytes
.gu+Gs@LQG.{k

Demonstration, Test suite
Input is an adjacency list, represented as a dictionary which maps vertices to the list of vertices it has edges to (its directed neighbors). Output is a partition.
The essence of the program is that we find the set of vertices that are reachable from each vertex, and then group the vertices by those sets. Any two vertices in the same SCC have the same set of vertices reachable from them, because each is reachable from the other, and reachability is transitive. Any vertices in different components have different reachable sets, because neither's set contains the other.
Code explanation:
.gu+Gs@LQG.{k
                  Implicit: Q is the input adjacency list.
.g           Q    Group the vertices of Q by (Q is implicit at EOF)
  u       .{k     The fixed point of the following function,
                  starting at the set containing just that vertex
   +G             Add to the set
     s            The concatenation of
      @LQG        Map each prior vertex to its directed neighbors

Python 2 using numpy, 71 62 bytes
import numpy
def g(M,n):R=(M+M**0)**n>0;print(R&R.T).argmax(0)

Takes input as a numpy matrix representing adjacency and the number of nodes. Produces output as a numpy row matrix that labels each vertex by the lowest vertex number in its component.
For an adjacency matrix M, the matrix power M**n counts the number of n-step paths from each start vertex to each end vertex. Adding the identity to M via M+M**0 modifies the adjacency matrix to add a self-loop to every edge. So, (M+M**0)**n counts paths of length at most n (with redundancy).
Since any path has length at most n, the number of nodes, any (i,j) where vertex j can be reached from i corresponds to a positive entry of (M+M**0)**n. The reachability matrix is thenR=(M+M**0)**n>0, where the >0 works entrywise.
Computing the entrywise and as R&R.T, where R.T is the transpose, then gives a matrix indicating the pairs of mutually reachable vertices. It's ith row is an indicator vector for vertices in the same strongly connected component as it. Taking its argmax of each row gives the index of the first True in it, which is the index of the smallest vertex in its component.

JavaScript (ES6), 125 bytes
a=>a.map(([m,n])=>(e[m]|=1<<n|e[n],e.map((o,i)=>o&1<<m?e[i]|=e[m]:0)),e=[])&&e.map((m,i)=>e.findIndex((n,j)=>n&1<<i&&m&1<<j))

Takes a list of directed pairs as an argument, while the result is a array for each vertex giving the first vertex strongly connected to it, which I believe counts as a valid labelling. For example, with the input [[1, 2], [2, 3], [2, 5], [2, 6], [3, 4], [3, 7], [4, 3], [4, 8], [5, 1], [5, 6], [6, 7], [7, 6], [8, 7], [8, 4]] it returns [, 1, 1, 3, 3, 1, 6, 6, 3] (there is no vertex 0; vertexes 1, 2 and 5 have label 1; 3, 4 and 8 have label 3 while 6 and 7 have label 6).

MATL, 26 22 bytes
tnX^Xy+HMY^gt!*Xu!"@f!

This uses the same approach as @xnor's answer.
Works in current version (15.0.0) of the language.
Input is the adjacency matrix of the graph, with rows separated by semicolons. The first and last test cases are
[0 1 0 1; 0 0 1 0; 1 0 0 0; 0 0 0 0]

[0 1 0 0 0 0 0 0; 0 0 1 0 1 1 0 0; 0 0 0 1 0 0 1 0; 0 0 1 0 0 0 0 1; 1 0 0 0 0 1 0 0; 0 0 0 0 0 0 1 0; 0 0 0 0 0 1 0 0; 0 0 0 1 0 0 1 0]

Try it online!
t     % implicitly input adjacency matrix. Duplicate
n     % number of elements
X^    % square root
Xy    % identity matrix of that size
+     % add to adjacency matrix
HM    % push size again
Y^    % matrix power
g     % convert to logical values (0 and 1)
t!*   % multiply element-wise by transpose matrix
Xu    % unique rows. Each row is a connected component
!     % transpose
"     % for each column
  @   %   push that column
  f!  %   indices of nonzero elements, as a row
      % end for each. Implicitly display stack contents

source: Stack Exchange

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

sort: votes


text:
Fun with flags!
Write a full program with a source code of 256 bytes or less that looks at an image of a flag and determines what country that flag is from. A zip file containing the 196 different flags in the challenge can be downloaded from here. Source: [Flagpedia]. These 196 flag images are the only inputs your program has to handle.
Your program will take no input. The flag image will be in the same directory as your program and named "f.png". Your program will open this file, identify it, and print the two letter abbreviation for that country. If you use a language that can't open files, it's also acceptable to run your program as ./program < f.png.
Each flag file is named the same as the expected output. All output above 2 letters will be ignored.
Here is a list of all the outputs/filenames:
ad, ae, af, ag, al, am, ao, ar, at, au, az, ba, bb, bd, be, bf, bg, bh, bi, bj,
bn, bo, br, bs, bt, bw, by, bz, ca, cd, cf, cg, ch, ci, cl, cm, cn, co, cr, cu,
cv, cy, cz, de, dj, dk, dm, do, dz, ec, ee, eg, eh, er, es, et, fi, fj, fm, fr,
ga, gb, gd, ge, gh, gm, gn, gq, gr, gt, gw, gy, hn, hr, ht, hu, id, ie, il, in,
iq, ir, is, it, jm, jo, jp, ke, kg, kh, ki, km, kn, kp, kr, ks, kw, kz, la, lb,
lc, li, lk, lr, ls, lt, lu, lv, ly, ma, mc, md, me, mg, mh, mk, ml, mm, mn, mr,
mt, mu, mv, mw, mx, my, mz, na, ne, ng, ni, nl, no, np, nr, nz, om, pa, pe, pg,
ph, pk, pl, pt, pw, py, qa, ro, rs, ru, rw, sa, sb, sc, sd, se, sg, si, sk, sl,
sm, sn, so, sr, st, sv, sy, sz, td, tg, th, tj, tl, tm, tn, to, tr, tt, tv, tw,
tz, ua, ug, us, uy, uz, va, vc, ve, vn, vu, ws, ye, za, zm, zw,

Scoring
Here is a short python script that I will use to score each submission.
import os
import subprocess
import random

botlist = []
with open("bots.txt") as bots:
    for line in bots:
        line = line.split(", ")
        if len(line) >= 2:
            botLine = line + [0]
            botlist.append(botLine)

files = os.listdir(os.getcwd() + "/flags")
random.shuffle(files)

def test(bot_command):
    score = 0
    for filename in files:
        command = "COPY flags\\{} f.png".format(filename)
        os.system(command)

        print bot_command

        result = subprocess.check_output(bot_command, shell = True)
        if result[:2] == filename[:2]:
            score += 1

    return score

for i in range(len(botlist)):
    command = botlist[i][1]
    botlist[i][2] = test(command)

with open("output.txt", "w+") as output:
    for bot in botlist:
        output.write("{} got a score of {}.".format(bot[0], bot[2]))

os.system("del f.png")

Your score is the total number of flags correctly identified. In case of a tie, the earlier submission wins.
Rules

For my testing convenience, any language with a freely available interpreter/compiler for Windows 10 or Ubuntu can be used.
Image processing libraries are allowed, but any builtins related to flags or countries are not allowed. (cough Mathematica cough)
Please provide the full command needed to run your program along with links to any necessary libraries.
Submissions may not interact with any file except "f.png".
I don't have any hard time-limit on submissions, but please keep it relatively quick. I don't want the scoring script to take hours.

The byte limit is really low. Just storing the 196 two-letters codes uncompressed requires 392 bytes

@edc65 The point is that you're only going to get a small number of the flags.

@edc65 I intentional picked a number that would make a perfect score of 196 basically impossible. It's more about compression of recognizing images then codegolf.

Just double checking - can we only use the ./program < f.png option if the language has no way of reading files, or can we also use it even if the language can read files? (Apparently CJam can read from files, which I didn't know)

These 196 flag images are the only inputs your program has to handle then you say Your program will take no input. Does that mean that the one file f.png will be one of the those 196. So the program cannot reference those zipped files? Just f.png

@Matt No, it means that one of the files will be copied over to "f.png" before your program is callled, then this will be repeated for each of the 196 flag images.

CJam, 139 141
There's a lot of unprintables in the code, so here's the xxd hexdump:
00000000: 7132 3925 3162 226d cec5 9635 b14b 69ee  q29%1b"m...5.Ki.
00000010: d9d0 66e8 97b8 e88d 2366 7857 9595 1c73  ..f.....#fxW...s
00000020: 9324 11b2 ddb8 7a3f 19ed bd37 07c0 cb86  .$....z?...7....
00000030: 394e b34a ecf0 8c9b f300 a216 2e2e 594a  9N.J..........YJ
00000040: 9a6b 3b2f 250a 9a25 783b 0e49 3e9c 6ab9  .k;/%..%x;.I>.j.
00000050: 8d6d d729 42d0 85f3 657b 7d86 af48 c6cb  .m.)B...e{}..H..
00000060: f7ff 980f b81c dd5e e8cb 4e34 d8ec edca  .......^..N4....
00000070: 6646 1b4d 7605 8937 ed58 2302 1cc1 ebfd  fF.Mv..7.X#.....
00000080: 16d3 b53e 3e2c d879 fe33 feef dd65 d49f  ...>>,.y.3...e..
00000090: 5d73 7ced 92e6 9526 c186 00bf d2a8 ffaa  ]s|....&........
000000a0: 65a0 3001 f42a 94d7 592f ebe7 8bdf 97a7  e.0..*..Y/......
000000b0: 0681 8ee1 9e0e 424b f6a1 4c50 1c8a 8de5  ......BK..LP....
000000c0: 481a 388c 6eaa 0c43 e1db 69df 567b 323f  H.8.n..C..i.V{2?
000000d0: 2573 c4ce b348 6fff 37e0 55b4 7c9a 7e7d  %s...Ho.7.U.|.~}
000000e0: 73a4 ef74 2b99 b765 2a2d d99f 986a 355c  s..t+..e*-...j5\
000000f0: db22 3236 3362 3236 6227 6166 2b32 2f3d  ."263b26b'af+2/=

This is exactly 256 bytes, with the program doing:
q29%                          Read input and keep every 29th char
    1b                        Sum code points
      "..."                   Push long string
           263b               Convert long string to base 263
               26b            Convert result to base 26
                  'af+        Add 'a to each element in the resulting array
                      2/      Split into chunks of length 2
                        =     Index sum cyclically to extract output

Run the program with the command
java -Dfile.encoding=ISO-8859-1 -jar cjam-0.6.5.jar flags.cjam < f.png

Thanks to @Dennis for help with getting this submission working.

I'm amazed anyone got this many. 139/196 = 70.9%.You scraped an A grade!

Could you make the binary dump an xxd -r-reversible one? Cygwin should have xxd

@tac Had to poke around a bit, but I didn't realise Cygwin did have it - I just had to select it manually for installation. I'll update it when I next update the answer.

I tried using the same technique as for Morse code, but the best I've been able to get is 129 flags, and I haven't even checked whether that fits in the 256-byte limit. Well done for finding such a good hash.

Python 2, Score = 68 89
This solution uses the hash of the flag image file to create an index into a list of the country abbreviations. If more than one flag hashed to an index, only the first abbreviation will be returned (so it will fail some of those tests with more than one country in a hash bucket). This algorithm does however guarantee one correct answer for every non-empty hash bucket.
i=hash(open('f.png').read())%99*2
print'kgmviruasefridusvakpsmbtgrpwcdsdauninrsyalsg--game--espyscmtyebhgqom--kh--inhudjbw--ltroilbicv--jonaugke--svhtbg--simcknbnpelcplgncmmacimytnttlytgcflirsvemhtzuyqaerbfbepa--uzaenearcl--jmbbphkzrwieet'[i:i+2]

This program is 247 characters.
A more readable version:
encoded = 'kgmviruasefridusvakpsmbtgrpwcdsdauninrsyalsg--game--espyscmtyebhgqom--kh--inhudjbw--ltroilbicv--jonaugke--svhtbg--simcknbnpelcplgncmmacimytnttlytgcflirsvemhtzuyqaerbfbepa--uzaenearcl--jmbbphkzrwieet'
index = hash(open('f.png').read())%99 * 2
print encoded[index : index+2]

Building the encoded string
To build the encoded string, I use a function to read in the flag files
as strings, generate a hash from the string, and reduce the hash to a
limited number of hash buckets:
def encode(buckets):
    lookup = {}
    for fn in os.listdir('flags'):
        name = fn[:2]
        signature = hash(open('flags/'+fn).read()) % buckets
        lookup[signature] = lookup.get(signature, '')+name
    return lookup

to return a dictionary of countries that match each signature, then use
some code to convert the dictionary into a lookup string:
encoded = ''.join(lookup.get(v, '--')[:2] for v in range(buckets))

I needed to experiment a bit with which values of buckets gives the best results.

Is this just taking the average color of the flag?

@AshwinGupta, the program reads in the file then takes a hash of it. This large hash number is reduced to an index in a string list by using a modulo operator.

Not sure if it'll help, but you can do print'...'[...:][:2]. Also, maybe a lookup table with >> and & for some basic compression?

@Sp3000, the double index idea looks interesting but I can't see where is would save any bytes here. I had not considered bit manipulation functions for compression, but that could offer an advantage. Hmmmm.

Double indexing saves 3 bytes because you don't need to save to a variable i, but whether or not you can make use of those extra bytes is a different question :P

@Sp3000, thanks - I did not see that.

89/196 = 45%. Very impressive, a pass grade but only just. This is a hard course.

@LevelRiverSt, this is indeed a hard course (but not as hard as compiler design and CPU architecture). I am still happy with my result as everybody else has dropped out except the amazing Sp3000 who seems to speak fluent binary ;-) .

Don't suppose you can try to explain in more detail how the file hash relates to your "encoded" string. I don't understand the relationship?

@Matt, I have added some more explanation in my answer. I hope this helps.

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


text:
Display "Happy Easter!"
Your task is to print the following ASCII Art:
 _     _                            _______                           _
| |   | |                          (_______)          _              | |
| |__ | | ____ ____  ____  _   _    _____   ____  ___| |_  ____  ____| |
|  __)| |/ _  |  _ \|  _ \| | | |  |  ___) / _  |/___)  _)/ _  )/ ___)_|
| |   | ( ( | | | | | | | | |_| |  | |____( ( | |___ | |_( (/ /| |    _
|_|   |_|\_||_| ||_/| ||_/ \__  |  |_______)_||_(___/ \___)____)_|   |_|
              |_|   |_|   (____/

Remember, this is code-golf, so the code with the smallest amount of bytes wins.
Good luck.

@FryAmTheEggman this is quite different from the supposed duplicate Rickroll. Only a few symbols are used: |()/\_ which leads to completely different forms of compression. We have had similar ASCII art challenges before, but I'd like to see this question run to see if anyone takes advantage of the geometry. On the other hand it's not hugely remarkable, and you'r right, we don't need an Easter tag.

@FryAmTheEggman The best solution to a [tag:kolmogorov-complexity] depends heavily on the structure of the output. This isn't text, so it isn't a dupe.

@lirtosiast The limited character set might matter, but I feel like this will almost certainly be dominated by the same techniques as in the text based questions. That's just my opinion though, the community gets to decide which of our views to enforce, after all.

Possible duplicate of Minecraft Mirrored

This is different, as there is no input, and so it is not necessary to take input and analyze it.

@MarkWright A subset is still a duplicate

Hi Mego!! Nice to meet you!!! Anyway, what I was thinking is that, since the program doesn't need to parse input, and there is only one possible output, you can use new languages and different ways to print it, for example, my BF code, while valid for this question, would be extremely hard to write for Minecraft Mirrored.

You should use [tag:string] along with [tag:kolmogorov-complexity] for large strings.

Bytes not chars. The accepted answer just exploits using Unicode chars. -1

Please stop adding the easter tag. It isn't a relevant tag for this site as challenges will not meaningfully involve some random holiday to the point that a tag should exit for it.

Bubblegum, 130 bytes
0000000: 758f b579 0530 18c4 7a4f a1d2 7fe5 8102  u..y.0..zO......
0000010: 5ae4 760f 5de8 91ee b3cc 8400 f523 2c3c  Z.v.]........#,<
0000020: 4656 0850 3f60 5b86 5fe4 8290 15a2 84a0  FV.P?`[._.......
0000030: 5a61 4d0b b64f 2b35 c476 eb1e 844e c841  ZaM..O+5.v...N.A
0000040: 08c8 731d 1a02 ead0 1547 1d70 beba 9fd6  ..s......G.p....
0000050: 31bf 5fdb 6c72 1d7b 1051 ed8a a884 7c76  1._.lr.{.Q....|v
0000060: 0fa7 db91 1503 c43c 9b18 124f cdb3 4220  .......<...O..B
0000070: 9631 716b a71c 3bd6 ed8b 0b62 7ebd 55cf  .1qk..;....b~.U.
0000080: 7a07                                     z.

Try it online.
Compressed using zopfli --deflate --i10000.

Isn't this 588 bytes?

@MarkWright What quartata posted is a hexdump of the actual code

JavaScript (ES6), 377 373 360 359 345 bytes
Thanks to @Neil for a one byte savings, and to @edc65 for another 14!
Figured I'd give it a shot. Compresses common repeating patterns in the text.
_____ (5 underscores) is stored as _5
      (5 spaces) is stored as  5
 | | | | | (5 of the  | pattern) is stored as ~5

console.log(` _ 5_ 28_7 27_
|~ 2~2 26(_7) 10_ 13~2
|~_2~2 _4 _4 2_4 2_ 3_ 4_5 3_4 2_3|~_ 2_4 2_4|~
| 2_2)|~/ _ ~ 2_ \\| 2_ \\|~3 ~ 2_3) / _ ~/_3) 2_)/ _ 2)/ _3)_|
|~ 2~ ( (~9_|~ ~2_4( (~2_3~2_( (/ /|~ 4_
|_| 2~_|\\_|2_|~|_/|~|_/ \\_2 ~ ~_7)_|2_(_3/ \\_3)_4)_| 2~_|
 13~_| 2~_| 3(_4/`.replace(/(.)(\d+)/g,(_,a,b)=>a.repeat(b)).replace(/~/g,' |'))

Note the ES6 =>.

Seems like bytes might be saved by RLEing _s.

@CatsAreFluffy What do you mean by that? It compresses runs of _ with an _ followed by how many there are in the run

Oops, I was still on the 377 byte version.

~1 or _2 hardly seems worth it. (Why not use |2 for instance?)

@Neil ~1 doesn't save anything, doesn't waste anything. it's the same as <space>|. didn't matter, so I just left it in. Same deal with _2, it's the same length as __. Not sure what you mean by using |2... could you clarify?

I think  14|~1 can be replaced with  13~2 for a saving of a byte.

@Neil Ooh, nice one! Thanks.

Using the most naive way to find the base string to apply this method, I got 346. I'll make a js fiddle

I was off by 1,it's 345 https://jsfiddle.net/d7a4d6xe/1/

@edc65 Looks good, thanks :D

Why use console.log when you could use an arrow function, or at least alert?

@MamaFunRoll alert messes up the spacing and the OP specified that the program should "print" the output. I suppose whether or not those options are valid is up to the OP though.

Oh. Well, it was worth a try.

BinaryFuck, 565 378 bytes
This basically stores the characters used in the array, then navigates through the array, printing them accordingly. Currently quite long, will shorten it up.
1000010000000000000000110011110001010010000011011111010010110001011011000000010010111011001111011110010010010000010000010000000000000010000010000000000010000010000000000011011011011011011011011011001111010010000000000110001010000000000000000010000000000011011111010010001010001001001001010010001010000000000000000000000000000010001001001001010000000000000000000000000000000011011011011100010100011100100100100100010100011100100100100100100100100100100100100100100100100100100100100100100100100100100100100010100100100100100100100011100100100100100100100100100100100100100100100100100100100100100100100100100100100010100011100010010010010100011011011011011100010100011100010100100100011100010100011100010100100100100100100100100100100100100100100100100100100100100100100100100100100011011100010010010100100100100100100100010100011011100100100100100100100100100100010100011100100100100100100100100100100100100100100011100010100011100010010010010010100011011011011011100010100011100010010100100011100011100010100011100010100010100100100100011100010100100100100011100100010100100100100011100100010100011100100100010100011100100100100010100100100100100011100100100010100100100100011100100010100100100011011100010100011100010010100011100100010100100100100011100100010100100100100011011100010100011100010010010010010100011011011011011100010100100010100100010100011011011100010100011100011011100010010010100010100011100100011100010100100010100011100010010010100011011011011100010100100010100011100010010010100011011011011100010100011100010100011100010100011100010100100011100010100100010100100100010100011011100011011011100010010010100010100011100100011100011011100010010010010100100100010100011011100100010100010100011011011011011100010010010100010100011100100010010100011011011011011100010010010100010100100100010100011100011011100010010010010010100011011011011011100010100011100010100100100011100010100011011100010010100011011100010010100011100010100011100010100011100010100011100010100011100010100011100010100011100010100011100010100011100010010100011011100010100011100010100100011100010100011100010010100100100100011011011100010010100011011100010010100011100010100011100010010100100100011100011100010100011100010010100011011011100010010100011011100011100010010010100011011011100010010100010100011100010100100100100010100011100010010010010100011011011011011100010010100011011100010100100100011100010010100011011100010010010010100011011100011011100100010010100011011100010100011100100010010100011011011011100010010100010100011100100010010100011011011011100010010010100010010010100011011100100011100100011100010100100011100010010100100100100100100100010100011100011011100100010010100011011011100010010010100100100011011011011100010010010100010010010100011011100100100010100011100100100100010100011100011011100010100100100011100010010100011011100010010010010010100011011011011100100100100100100100100100100100100100100011100010010100011011100010100100100011100010010100011011100010100100100011011100010010010100100100100011011011011100

Here is the ungolfed code:
+>+++++[<[->>+<<]>>[-<<++>>]<-]<
[>>>+>+>++++>+>+++>+>+++<<<<<<<<<-]
>>+++[->+++++>+++<<]>>->---->>->+++++++++>---->++++++++++
<<<<.>.<.....>.<............................>.......<...........................>.<.>>>>.<<<<<.>.<.>...<.>.<.>..........................<<.>>>.......>.<<..........>.<..............<.>.<.>>>>>.<<<<<.>.<.>>..<.<.>.<.>.>....<.>....<..>....<..>.<...>.<....>.....<...>....<..>...<<.>.<.>>.<..>....<..>....<<.>.<.>>>>>.<<<<<.>..>..>.<<<.>.<.<<.>>>.>.<..<.>..>.<.>>>.<<<<.>..>.<.>>>.<<<<.>.<.>.<.>.<.>..<.>..>...>.<<.<<<.>>>.>.<..<.<<.>>>>...>.<<..>.>.<<<<<.>>>.>.<..>>.<<<<<.>>>.>...>.<.<<.>>>>>.<<<<<.>.<.>...<.>.<<.>>.<<.>>.<.>.<.>.<.>.<.>.<.>.<.>.<.>.<.>.<.>>.<<.>.<.>..<.>.<.>>....<<<.>>.<<.>>.<.>.<.>>...<.<.>.<.>>.<<<.>>.<<.<.>>>.<<<.>>.>.<.>....>.<.>>>>.<<<<<.>>.<<.>...<.>>.<<.>>>>.<<.<<..>>.<<.>.<..>>.<<<<.>>.>.<..>>.<<<<.>>>.>>>.<<..<..<.>..<.>>.......>.<.<<..>>.<<<.>>>...<<<<.>>>.>>>.<<...>.<....>.<.<<.>...<.>>.<<.>>>>>.<<<<..............<.>>.<<.>...<.>>.<<.>...<<.>>>....<<<<.

EDIT: by rearranging the order of the characters in the cells, I saved 186 bytes!

Welcome to PPCG! By my count this is 1507 bytes of source code. Also it seems to print two leading spaces instead of just one, which means that the first line isn't aligned with the rest.

There are 1507 characters of source code. However, since there are only 3 bits in a Brainfuck character, and 8 bits in a byte, you get 1507*3/8 = 565.15 then I rounded up.

@MartinBüttner Thank you, I have fixed it, and saved a byte! Thank you.

That's not how a byte count works. If you can't pass the exact sequence of bytes to the interpreter, you can't claim that number of bytes as your byte count.

If there is a BF-interpreter which takes in 3-bits/char. Please add a link to the interpreter and a hexdump/pastebin of the encoded code, if you wish to claim 565 bytes.

Yes, there is a 3-bit brainfuck interpreter. Add a link to this in your answer along with a hexdump/binary representation of your code. The language wouldn't be brainfuck anymore so you'd have to specify "CompressedFuck" in the header. I recommend keeping it as-is as when seeing brainfuck people don't expect it to be very short.

This doesn't look like a valid BinaryFuck program; it doesn't start with a 1. Please provide a link to an interpreter and the hexdump of the source code so your results can be reproduced.

I have included a link to a compiler/interpreter.

Since this is a trivial BF derivative, why not just answer in BF?

I originally answered in BF, however others complained that each BF character was 1 byte. I switched it to Binaryf*** because it apparently saves bytes.

@MarkWright That's 2,378 bytes of BinaryFuck. I'm not sure where you're getting 379 from.

There are 2378 bits, and 8 bits in a byte, so 2387 bits / 8 = 298 bytes.

If you're going to claim 3 bits per instruction as per Binaryfuck, you need to post the Binaryfuck source code (probably in a hex dump or base64-encoded) and calculate bytes based off of that. As it stands, this submission is a brainfuck submission with 1012 bytes, of which 3 are extraneous (the newlines).

Please remove the extraneous whitespace and fix the byte count which is 1012 bytes.

@piercingarrow Doorknob, a Moderator, told you that's not how bytes are counted.

It is up to the community that bytes are counted with e.g https://mothereff.in/byte-counter, and mods enforce the standards decided by the community, eg http://meta.codegolf.stackexchange.com/questions/8176/proposal-of-new-measure-for-byte-count-in-code-golf. It's not really up to the challenge writer what bytes are, it's up to the challenge writer how entries are scored but since this is code-golf, your entry will be scored in bytes.

Your update is 6,202 bits and 775.25 octets, which is significantly longer than 378, and you haven't specified that those are bits and there are 776 bytes, etc

@cat sorry, sed wildcard messed up my find + replace. I fixed it. It is now the correct number of bytes. Also, I don't need to mention those are bits, because the language itself is inherently written in bits, the same way quartata, using Bubblegum, didn't need to mention that he was using hex.

There are no programming languages that look like hexdumps in their normal form. When someone who knows what a hexdump looks like sees a hexdump, they know they are looking at a program containing unprintables. Also, Bubblegum has a reputation of being unprintable, but looking at this answer, I don't know it's supposed to be a binary representation of BrainFuck. That esolang page you linked to provides an ascii representation of binaryfuck, perhaps you should use that?

@cat I changed my language to BinaryFuck, is that better? Also, since I fixed the bytecount, could you please remove your downvote?

JavaScript (ES6), 380 bytes
For completeness this is my effort to use a different compression method, although as it turns out it's not as efficient as run length encoding. Each digit specifies that the last N already generated characters are repeated. Subsequent digits can repeat already repeated characters, e.g. | 23 turns into | |  |. I only wish I could compress a run of three characters.

f=(s=` _  26  2479__23   2499_
| 2  6  2379(__23)   25_  237|2
| |__ |2 __25  __2  _ 4   ___2   __2  ___| |_  ___6_| |
|  __)| |/ _  |  _ \\6| 24 |  ___) / _  |/___)  _)/ _  )/ ___)_|
| 2  | (2 |248 |_| 23|__2( 2| |___ |2_( (/ /| 2   _
|_|   |_|\\_||_| ||_/6 \\__  |3__23)_||_(___/ \\___)_5|   |_|
  237|_|6   (__2/`,r=s.replace(/(.*?)(\d)/,(_,p,n)=>p+p.slice(-n)))=>r==s?r:f(r)

o.textContent = f()

C, 517 427 407 bytes

saved few bytes, thanks to @ceilingcat

c,i;main(m){for(char*s=" _ 4_ 999_6 998_ 1\n|B 2|B 997(_6) 9_ 94|B \n| |_1C _3 _3 1_3 1_ 2_ 3_4 2_3 1_2|B_ 1_3 1_3|B \n| 1_1)|B/ _ 1\\| 1_ \\| 1_E 1| 1_2) / _ 1|/_2) 1_)/ _ 1)/ _2)_| \n|B 2| ( (J_|B 1|B_3( (C_2C_( (/ /|B 3_ 1\n|_| 2|_|\\_||_|B1_/|B1_/ \\_1 1| 1|_6)_|1_(_2/ \\_2)_3)_| 2|_| \n 94|_| 2|_| 2(_3/\n";*s;s++)for(i=isdigit(*s)?c=m,*s-48:isalpha(*s)?c=0,*s-65:(c=*s,1);i--;)printf(c?m=c,&c:" |");}

Ungolfed Try Online
#include <stdio.h>
#include <stdint.h>

char m = 0;

void g(char c, int i)
{
    while(i--) c ? m=putchar(c) : printf(" |");
}

void p(char* s)
{
    while(*s)
        isdigit(*s) // golfed if-else-if
        ? g(m,*s-48)
        : isalpha(*s)
          ? g(0,*s-65)
          : g(*s,1)
        ,
        s++;
}

int main()
{
    p(" _ 4_ 999_6 998_ 1\n|B 2|B 997(_6) 9_ 94|B \n| |_1C _3 _3 1_3 1_ 2_ 3_4 2_3 1_2|B_ 1_3 1_3|B \n| 1_1)|B/ _ 1\\| 1_ \\| 1_E 1| 1_2) / _ 1|/_2) 1_)/ _ 1)/ _2)_| \n|B 2| ( (J_|B 1|B_3( (C_2C_( (/ /|B 3_ 1\n|_| 2|_|\\_||_|B1_/|B1_/ \\_1 1| 1|_6)_|1_(_2/ \\_2)_3)_| 2|_| \n 94|_| 2|_| 2(_3/\n");
    return 0;
}

Perl 5, 286 bytes
perl -M5.01 happy.pl, where happy.pl is:
$_='u5u28 7_27u
~~x~~25 (7_)10u7x~~
~p_ ~~4_ 4_x4_x_3u4 5_3 4_x3_~px4_x4_~~
~u_)~|/ux~u \~u \4~ ~ 3_) /ux|/3_)x_)/ux)/ 3_)_|
~~x~( ( 8~p~~ ~|4-( ( ~p__ ~p( (/ /~~3u
p~xp|\_|p~|p/~|p/ \__x~ p6_)_|p(3_/ \3_)4_)_~xp|
14 p~xp~x(4_/';s/u/ _/g;s/\d+(.)/$1x$&/ge;s/x/  /g;s/~/| /g;s/p/|_/g;say

Thanks to Dom Hastings (in a comment hereon) for an idea that saved me two bytes and led to another idea of mine that saved four more.

Surely you should use L as the shorthand for |_ ;-)

, 72 chars / 209 bytes
`Эć훼쎧漤詼媰਀㻆僚픈耊Ⓢኍ⋱쬝ᇑ덆䖇䂊՛樥첾㨭쯠ཁ톇:덱螟醮䖉⥊覂削ꇉ漈涹႘챘ඕ꼳⁒᭷Ừ䒕鶀놜㆝〢ﱱꎀ쎴䋈㗂䅉Ⴄቀ쳵菨ⶩ∉툲耀

Try it here (Firefox only).
Well, at least the char count is great, but we can't use the custom code page. It's just an LZString-decompression. I'm also working on another solution - more on that later.

JavaScript, 297 bytes
console.log(` 29 288999002889 3
19 18899 500_)82891
1__ 1 0_ 02022 290_2 02012020_1
|3_)162|3 \\|3 \\1 19|90) 62|/0)3)62)60)_|
19 |55 1 1 1 1 71910_(5 10 1_(56/193
7|4\\_|717/176\\_2|9|00_)_|7(06\\0)0_)_|4
8 44950_/`.replace(/\d/g,n=>`___,| |,_  ,  _,   |_|, (,/ ,|_,          ,  `.split`,`[n]))

Simple encoding of the ten most (as far as I can tell) common substrings. They are not in order because of overlaps; my encoder (below) needs to see e.g. '_  ' and '  _' before '  '.
(s,a,t=s)=>a.map((t,i)=>s=s.split(t).join(i))&&[s,(b=>{b=new Map;for(i=0;i<s.length;i++)for(j=0;j0&&!/\d/.test(x[0]))x].sort(([a,b],[c,d])=>b-d)})(),t.length-(s+' '+a).length]

This takes a string and an array of substrings to encode and returns a) the encoded string b) the list of potential next savings c) the number of bytes saved so far.

Racket, 367 364 bytes
(require file/gunzip net/base64)((λ(o)(gunzip-through-ports(open-input-bytes(base64-decode #"H4sIAOhN/lYAA31QwQ3EMAj7dwqezYuFInkRhj+MoWor9UBCmGBDMBhN8cMg+9dhR1hkovhhZwutO/FhSadQzqJQDdXkjsOYfa5Hkm4QEsp0ZeYkEdmeKK8i91GHazesgoyJEdfXzvR4O1ooOLY7oA8QunnfhDdCCSE2oogBV7QN7RhzI3bwYPWUUDXRj9fVpj439h/OlCKU1gEAAA=="))o)(displayln(get-output-string o)))(open-output-bytes))

Ungolfed
(require file/gunzip net/base64)
((λ (o)
   (gunzip-through-ports
    (open-input-bytes
     (base64-decode
      #"H4sIAOhN/lYAA31QwQ3EMAj7dwqezYuFInkRhj+MoWor9UBCmGBDMBhN8cMg+9dhR1hkovhhZwutO/FhSadQzqJQDdXkjsOYfa5Hkm4QEsp0ZeYkEdmeKK8i91GHazesgoyJEdfXzvR4O1ooOLY7oA8QunnfhDdCCSE2oogBV7QN7RhzI3bwYPWUUDXRj9fVpj439h/OlCKU1gEAAA=="))
    o)
   (displayln (get-output-string o)))
 (open-output-bytes))

Based off a similar challenge I answered.

Python 2, 159 bytes
This source contains non-printable characters, so it is presented as a hexdump that can be decoded with xxd -r.
00000000: efbb bf70 7269 6e74 2278 017d 8fb5 7540  ...print"x.}..u@
00000010: 3114 c5fa 3f85 4abb f240 012d a2dd 432f  1...?.J..@.-..C/
00000020: 4cba c732 1302 20ff e0c0 dfc8 1501 e33f  L..2.. ........?
00000030: 580e 9b77 e40b d115 2911 aa23 1c33 05a7  X..w....)..#.3..
00000040: cf54 6ae4 74c7 7310 baa3 8310 c86d 8c27  .Tj.t.s......m.'
00000050: 04ea 6656 9c79 9bfb a5fb 6cdd f6fe b5c5  ..fV.y....l.....
00000060: a2ef 3182 4875 56a4 123d 770f 2702 902b  ..1.HuV..=w.'..+
00000070: 03b2 5bcb 28cf 985b 8520 876d b974 a6dc  ..[.(..[. .m.t..
00000080: be28 20bb f842 f6ee a57a 1e01 c1a2 733e  .( ..B...z....s>
00000090: 222e 6465 636f 6465 2827 7a69 7027 29    ".decode('zip')

Python 2, 343 328 316 bytes
This solution uses no decompression functions or other imports.
o=""
for i in range(250):j=ord(")*I*yyQZyyI*(!+9!+yyA,Z-q*y9!+(!+2)!!B)B1B1*9*AJ9B1:!+*1B1B!+(+12-!+/)*1+1*).+1*).!!!+1+1:-)/)*1+/:-1*-/)*1-/):-*+(!+9!,),)!!!!!!!!+*!+1!+B,),)!+:)!+*,),/)/!+A*(+*+9+*+.*3*!3*/!3*/).21+1+Z-*3*,:/).:-B-*+9+*+(y9+*+9+*+9,B/(".replace("!","+)")[i])-40;o+="\n _|()\/"[j&7]*(j/8+1)
print o

Readable version:
DATA=(")*I*yyQZyyI*("
"!+9!+yyA,Z-q*y9!+("
"!+2)!!B)B1B1*9*AJ9B1:!+*1B1B!+("
"+12-!+/)*1+1*).+1*).!!!+1+1:-)/)*1+/:-1*-/)*1-/):-*+("
"!+9!,),)!!!!!!!!+*!+1!+B,),)!+:)!+*,),/)/!+A*("
"+*+9+*+.*3*!3*/!3*/).21+1+Z-*3*,:/).:-B-*+9+*+("
"y9+*+9+*+9,B/(").replace("!","+)")
SIZE=250
o=""
for i in range(SIZE):
 j=ord(DATA[i])-40
 o+="\n _|()\/"[j&7]*(j/8+1)
print o

Uses a version of run length encoding with 3 bits for a symbol from the set "\n _|()/".  The remainder of the byte is the length, but I have limited the length to 10 and manipulated it so that the results are printable characters that are valid in a python string without any escaping.
Replacing the string corresponding with "| " with a single character in the encoded data saves a few more bytes.
I removed the trailing spaces on lines 1 and 5, which may be bending the rules a bit, but seems practical.
This program generates the packed data:
message="""
 _     _                            _______                           _
| |   | |                          (_______)          _              | |
| |__ | | ____ ____  ____  _   _    _____   ____  ___| |_  ____  ____| |
|  __)| |/ _  |  _ \|  _ \| | | |  |  ___) / _  |/___)  _)/ _  )/ ___)_|
| |   | ( ( | | | | | | | | |_| |  | |____( ( | |___ | |_( (/ /| |    _
|_|   |_|\_||_| ||_/| ||_/ \__  |  |_______)_||_(___/ \___)____)_|   |_|
              |_|   |_|   (____/"""[1:]
size=len(message)
symbols="\n _|()\/"
i=0
encoded=""
while i<size:
    count=0
    while count<10 and i+count+1<size and message[i+count+1]==message[i]:
        count+=1
    n = symbols.find(message[i]) | count<<3
    encoded+=chr(n+40)
    i+=count+1
encoded_lines = encoded.replace("+)","!").split(chr(40))
for line in encoded_lines:
    print line+chr(40)
print len(encoded)

Hello, and welcome to PPCG! Great post!

@NoOneWasLiterallyEverHereEver not that it's their first post or anything, but sure :)

///, 282 279 bytes
Improvement: I noticed that there are too many // in the replacement commands, so I decided to compress them also (to m), which saved me 3 bytes.
/m/\/\///l/ _mk/|amj/b_mi/\\\m/h/|cmg/ddmf/ccme/bbmd/aamc/ |mb/__ma/  /ldlgggdejgggal
hafggga(ej)ga_gdah
hbf e eaea_alde_a eajh_aeaeh
kb)hilak_ \\k_ \\|fcakj) ila|ij)a_)ila)i j)_|
hac ( (ffffc_hahe( (fjf_( (i ihd_
|_kc_|\\_||_h|_ih|_i \\bak|ej)_||_(ji \\j)e)_kc_|
gda|_kc_k (ei

Repeatly compress the most frequent substring.
Thirteenth generation, 282 bytes
/l/ _//k/|a//j/b_//i/\\\///h/|c//g/dd//f/cc//e/bb//d/aa//c/ |//b/__//a/  /ldlgggdejgggal
hafggga(ej)ga_gdah
hbf e eaea_alde_a eajh_aeaeh
kb)hilak_ \\k_ \\|fcakj) ila|ij)a_)ila)i j)_|
hac ( (ffffc_hahe( (fjf_( (i ihd_
|_kc_|\\_||_h|_ih|_i \\bak|ej)_||_(ji \\j)e)_kc_|
gda|_kc_k (ei

Try it online!
First generation, 486 bytes
No compression. Escaped the / and the \.
 _     _                            _______                           _
| |   | |                          (_______)          _              | |
| |__ | | ____ ____  ____  _   _    _____   ____  ___| |_  ____  ____| |
|  __)| |\/ _  |  _ \\|  _ \\| | | |  |  ___) \/ _  |\/___)  _)\/ _  )\/ ___)_|
| |   | ( ( | | | | | | | | |_| |  | |____( ( | |___ | |_( (\/ \/| |    _
|_|   |_|\\_||_| ||_\/| ||_\/ \\__  |  |_______)_||_(___\/ \\___)____)_|   |_|
              |_|   |_|   (____\/

Try it online!
Second generation, 402 bytes
Compressed two spaces to a. The /a/  / means "replace all occurrences of a to two spaces".
/a/  / _aa _aaaaaaaaaaaaaa_______aaaaaaaaaaaaa _
| |a | |aaaaaaaaaaaaa(_______)aaaaa_aaaaaaa| |
| |__ | | ____ ____a____a_a _aa_____a ____a___| |_a____a____| |
|a__)| |\/ _a|a_ \\|a_ \\| | | |a|a___) \/ _a|\/___)a_)\/ _a)\/ ___)_|
| |a | ( ( | | | | | | | | |_| |a| |____( ( | |___ | |_( (\/ \/| |aa_
|_|a |_|\\_||_| ||_\/| ||_\/ \\__a|a|_______)_||_(___\/ \\___)____)_|a |_|
aaaaaaa|_|a |_|a (____\/

Try it online!
Third generation, 369 bytes
Compressed __ to b. The /b/__/ at the beginning means "replace all occurrences of b to __".
/b/__//a/  / _aa _aaaaaaaaaaaaaabbb_aaaaaaaaaaaaa _
| |a | |aaaaaaaaaaaaa(bbb_)aaaaa_aaaaaaa| |
| |b | | bb bbabba_a _aabb_a bbab_| |_abbabb| |
|ab)| |\/ _a|a_ \\|a_ \\| | | |a|ab_) \/ _a|\/b_)a_)\/ _a)\/ b_)_|
| |a | ( ( | | | | | | | | |_| |a| |bb( ( | |b_ | |_( (\/ \/| |aa_
|_|a |_|\\_||_| ||_\/| ||_\/ \\ba|a|bbb_)_||_(b_\/ \\b_)bb)_|a |_|
aaaaaaa|_|a |_|a (bb\/

Try it online!
Fourth generation, 339 bytes
Compressed  | to c. The /c/ |/ at the beginning means "replace all occurrences of c to  |".
/c/ |//b/__//a/  / _aa _aaaaaaaaaaaaaabbb_aaaaaaaaaaaaa _
|caccaaaaaaaaaaaaa(bbb_)aaaaa_aaaaaaa|c
|cbcc bb bbabba_a _aabb_a bbab_|c_abbabb|c
|ab)|c\/ _a|a_ \\|a_ \\|ccca|ab_) \/ _a|\/b_)a_)\/ _a)\/ b_)_|
|cac ( (ccccccccc_|ca|cbb( (ccb_cc_( (\/ \/|caa_
|_|ac_|\\_||_|c|_\/|c|_\/ \\ba|a|bbb_)_||_(b_\/ \\b_)bb)_|ac_|
aaaaaaa|_|ac_|a (bb\/

Try it online!
The rest of the compression rules
So, the list of compression rules:

Compress two spaces to a.
Compress __ to b.
Compress  | to c.
Compress aa to d.
Compress bb to e.
Compress cc to f.
Compress dd to g.
Compress |c to h.
Compress \/ to i. Both the \ and the / in the rules are further escaped.
Compress b_ to j.
Compress |a to k.
Compress  _ to l.
Compress // to m.

As you can see, there are overlapping compression rules. For example, g encodes dd which encodes aaaa which encodes 8 spaces.

If you want to sound drunk but don't have any alcohol in reach just try pronouncing one of these. proven to work on parents

Your Mom (non-competing), 331 bytes
Decode the string and decompress it using the Jelly compressor
'IF8KfCgpL1z/AQAAAQAAAAAAAAAAAAAAAAAAEREREAAAAAAAAAAAAAAAAAAQIwMAAwMAAAAAAAAAAAAAAAAAQREREVAAAAAAAQAAAAAAAAAwMjAxEDAwEREBERABERABAAEAABEREAAREQAREwMQAREQARETAyMAEVMDYBADABBzABBzAwMDADABEVBgEANhEVABVgEAVgERUTIwMAAwQEAwMDAwMDAwMDEwMAMDERFAQDAxEQMDFARgYwMAABAjEwADE3EzEwMxYwMxYHEQAwAxERERUTMUERYHERUREVEwADEyAAAAAAAAADEwADEwAEERFg=='`

How did you compete in my mom?!?! Registration closed months ago...

CJam, 229
"3WPPEFXvN'vlFBse/cTD>.x:Na,Y&NJH^tZ%xL(NkYzo0Rq%BeV&Zl1T^2y69,W/QC4pL`nv<Jo$'Cq.'m2-3H#9teHi&<uyO>f V)D\E y'*]oGq*ODjQLyoS*GyM7;\Z.n6B;J@OyEaE!4'E5p5MOl^#[,ZtA;`jy,gTP^\;;i<A6^:k1%"' fm91b31b"}*+{~'NHIF\JLM
OGQK)(P/RST|_- \""f=~

No funky characters and no built-in compression :)
Try it online

Ruby, 271 262 248 bytes
require'zlib'
require'base64'
puts Zlib.inflate Base64.decode64'eJx1UMENxDAI+zMFz+bFQpG8CMMX46DeVWpQrJjYhGDp6e7Cj3VBaz0p/CvKbrWBLkStYHAcEH8uafqhUKE6rjoFTWS+BxWdZD9ShHrDakosju6oe7sq8h04hZLPHgX0AdLwODOBG8VOy0a2MRFC31CPOTOiggPrq6LKyW6vqU1+Zhx2A7NMZ9I'

Try it here

Python 3, 263 bytes
Initial pass using builtins.
from base64 import*
from zlib import*
print(decompress(a85decode(b"Gas1Y_%\"=:#lAfQT$<1I,'acT5E):N/+l.oQs`98(esP<+T'c!7p'"
b";rpgIeCXZQ&]8Z,D1U/2<LjGq-FIBH)'D@dH'FCjS[&_Wa(Y9N^<LMJiMJrGNuf@S=?GWT(W34:oA%hQ<"
b"thh3pT#pD4$L]LSa%IG!R,BiQaoor91d>uo0VEQs4+2O[m4o")).decode())

some extra quotes and linebreaks added to avoid horizontal scroll for display purposes only (not counted in score)

Don't worry about horizontal scroll. Just copy-paste the text as-is, because that's what we're interested in.

I know, I just prefer to avoid it. May as well also not do hex dumps all pretty.

You could try to store the zlib data in a string. You slould escape some characters, but it's probably a lot shorter. See this answer as reference.

@agtoever the repr() of the raw string was much longer than ascii85

@NickT Please remove the additional quotes and whitespace. Your code should be such that we can copy/paste it into a byte-counter and get the same result. Thanks. If you want a nice, displayable version, post an un-golfed version.

from base64 import*
from zlib import*
print(decompress(a85decode(b"Gas1Y_%\"=:#lAfQT$<1I,'acT5E):N/+l.oQs\98(esP<+T'c!7p';rpgIeCXZQ&]8Z,D1U/2<LjGq-FIBH)'D@dH'FCjS[&_Wa(Y9N^<LMJiMJrGNuf@S=?GWT(W34:oA%hQ<thh3pT#pD4$L]LSa%IG!R,BiQaoor91d>uo0VEQs4+2O[m4o")).decode())` Truly golfed

I count 271 bytes. Please update your count.

Python 3, 377 bytes
from re import*;i=0
r=r'2_.7_./ .|2.| .4_.\\. _._d|.( (.3_). _ .2|_. |2 ._| |.a| |./ _2 .|3 |_. 4_2 . | |.\n'
e='an5n28 t27jf3b26 (t)10n14bfub pcp2n3n4 5_3c3g_2c4gar u)q|erjorjo|bhr k e|/k2n)e)sk_|f3 qlbbbb |g2bplb3_b_ls/q|4ja|mo_iqi/qisou2h|t)_i(3_sokp)ma14 |m3 (p/'
for j in r.split('.'):e=sub(chr(117-i),j,e);i+=1
print(sub('(\d+)(.)',lambda x:int(x.group(1))*x.group(2),e))

similar to the javascript answer, used RLE plus a bunch of replacements for common substrings.
Think I went a bit over the top with the replacing stuff, probably didn't help that much but oh well.

JavaScript (ES6), 354 bytes
Another attempt. Not as efficient as run length, unfortunately.
i=0,console.log(`1c1bt96zfx1!1n4ikabr1w5!1n4iut4kyue!krgqthnkpkem8!43tb4j2urme!8hwrsagny80!69dfowb7hvk!2xj89rpvcb2!23l14ken5i1!1xzn6ns7j78!1tzyivgb4h2!1yy885vts00!12du7km7f51!1lvpcyzgbfq!17nicizf8og0!1246xqebgb9!1n4j181hywz!`.replace(/\w+!/g,v=>parseInt(v,36).toString(4).replace(/./g,w=>"_ |"[w]||`
()

)/\\\\)//))/)/)
((((((//
\\//\\)(/\\))
(/`[i++])))

Stores a bunch of base-36 numbers in the first string, delimited by a ! separator. Then replaces the numbers (along with the !) with the numbers' base-4 representations. Replaces all the 0's, 1's, and 2's in the base-4 number with _,  , and | respectively, and all the 3's are replaced with the elements in the second string sequentially.

Lua, 353 bytes
Program:
a=(" _ 5_ 28_7 27_\n|~ 2~2 26(_7) 10_ 13~2\n|~_2~2 _4 _4 2_4 2_ 3_ 4_5 3_4 2_3|~_ 2_4 2_4|~\n| 2_2)|~/ _ ~ 2_ \\| 2_ \\|~3 ~ 2_3) / _ ~/_3) 2_)/ _ 2)/ _3)_|\n|~ 2~ ( (~9_|~ ~2_4( (~2_3~2_( (/ /|~ 4_\n|_| 2~_|\\_|2_|~|_/|~|_/ \\_2 ~ ~_7)_|2_(_3/ \\_3)_4)_| 2~_|\n 13~_| 2~_| 3(_4/"):gsub("(.)(%d+)",function(a,b)return a:rep(b)end):gsub("~"," |")print(a)

Thanks to @jrich for compression.

Vim, 374 365 326 319 313 311 keystrokes
9 keystrokes thanks to @Dr Green Eggs and Ham DJ .
:im @ ___<CR>
:im % _|<CR>
a _## _<esc>28a <esc>yl7a_<esc>27pa_ <CR>
|!#!!<esc>26pa(<esc>7a_<esc>a)<esc>10pa_<esc>14pa|!<CR>
|!__!!<esc>3a @_<esc>bi <esc>A#_# _##@__# @_#@|!_#@_#@%!<CR>
|#__)|!/ _ !#_ \|#_ \<esc>4a| <esc>a!#@) / _ !/@)#_)/ _#)/ @)%<CR>
|!#! ( (<esc>9a!<esc>a%! !!@_( (!!@!!_( (/ /|!##_ <CR>
|%#!%\%|_<esc>2a|!|_/<esc>a \__ ! !<esc>7a_<esc>a)%|_(@/ \@)@_)%#!%<CR>
<esc>14pa|%#!%# (@_/<esc>
:%s/!/ |/g<CR>
:%s/#/  /g<CR>

Probably can be golfed further by using :nn?

Here's a couple quick tips after one glance over. 1. You do <number>a <esc> a lot. If you do yl on a space, you could replace this with <number>p. That should save around 8. 2. You could replace ea with A. You could probably take even more if you change your approach, but those are the quick tips I see.

@DrGreenEggsandHamDJ Is there any way that I could map a single keystroke to typing _ and | etc?

I'm on my phone, so I can't test this, but I think this is incorrect. :s only replaces on one line. You want :% s. You could also save some keystrokes by doing :im (imap) instead of search and replace. (Although you might need to use ctrl-v or ctrl-q to map to a space)

@DrGreenEggsandHamDJ Excellent, but using :im can only golf a few more bytes I suppose.

HTML, 482 481 475 bytes

 _     _                            _______                           _
| |   | |                          (_______)          _              | |
| |__ | | ____ ____  ____  _   _    _____   ____  ___| |_  ____  ____| |
|  __)| |/ _  |  _ \|  _ \| | | |  |  ___) / _  |/___)  _)/ _  )/ ___)_|
| |   | ( ( | | | | | | | | |_| |  | |____( ( | |___ | |_( (/ /| |    _
|_|   |_|\_||_| ||_/| ||_/ \__  |  |_______)_||_(___/ \___)____)_|   |_|
              |_|   |_|   (____/

Note: One does not simply view this thing properly on a phone.

Since you are doing all this anyways, you don't need the closing pre tag

And why do you have trailing spaces on 5th line? :P

Javascript (ES6) 464 352 bytes
00000000  63 6f 6e 73 6f 6c 65 2e  6c 6f 67 28 60 08 09 28  |console.log(`..(|
00000010  09 c3 a0 39 c3 98 09 08  0f 0c 08 0c 18 0c 08 0c  |...9............|
00000020  c3 90 0a 39 0e 50 09 70  0c 08 0c 0f 0c 08 0c 11  |...9.P.p........|
00000030  08 0c 08 0c 08 21 08 21  10 21 10 09 18 09 20 29  |.....!.!.!.... )|
00000040  18 21 10 19 0c 08 0c 09  10 21 10 21 0c 08 0c 0f  |.!.......!.!....|
00000050  0c 10 11 0e 0c 08 0c 0a  08 09 10 0c 10 09 08 0c  |................|
00000060  10 09 08 0c 08 0c 08 0c  08 0c 10 0c 10 19 0e 08  |................|
00000070  0a 08 09 10 0c 0a 19 0e  10 09 0e 0a 08 09 10 0e  |................|
00000080  0a 08 19 0e 09 0c 0f 0c  08 0c 18 0c 08 0a 08 0a  |................|
00000090  08 0c 08 0c 08 0c 08 0c  08 0c 08 0c 08 0c 08 0c  |................|
000000a0  08 0c 09 0c 08 0c 10 0c  08 0c 21 0a 08 0a 08 0c  |..........!.....|
000000b0  08 0c 19 08 0c 08 0c 09  0a 08 0a 08 0a 0c 08 0c  |................|
000000c0  20 09 08 0f 0c 09 0c 18  0c 09 0c 09 14 09 0c 08  | ...............|
000000d0  14 09 0a 0c 08 14 09 0a  08 11 10 0c 10 0c 39 0e  |..............9.|
000000e0  09 14 09 0a 19 0a 08 19  0e 21 0e 09 0c 18 0c 09  |.........!......|
000000f0  0c 0f 70 0c 09 0c 18 0c  09 0c 18 0a 21 60 2e 73  |..p.........!`.s|
00000100  70 6c 69 74 28 22 22 29  2e 6d 61 70 28 61 3d 3e  |plit("").map(a=>|
00000110  61 2e 63 68 61 72 43 6f  64 65 41 74 28 29 29 2e  |a.charCodeAt()).|
00000120  6d 61 70 28 61 3d 3e 41  72 72 61 79 28 28 61 3e  |map(a=>Array((a>|
00000130  3e 33 29 2b 31 29 2e 6a  6f 69 6e 28 22 20 5f 2f  |>3)+1).join(" _/|
00000140  5c 5c 7c 28 29 5c 6e 22  2e 73 70 6c 69 74 28 22  |\\|()\n".split("|
00000150  22 29 5b 61 26 37 5d 29  29 2e 6a 6f 69 6e 28 22  |")[a&7])).join("|
00000160  22 29 29                                          |"))|

Try it here!

C (gcc), 280 279 bytes
f(i){for(char*A=" _|/\\()\n",*s="H@@H.@#IA-@AWP@PP-@M#IF$@H'@BzBJABBIIHIAHIAH@H@@IIA@II@IQPAHIAHIQPW@IVPCAP@AT@AT#P@BHIFCAPKIFH^H@^HINzBB@BEE(BJBBPPIIEEBJIPPihCSP@@AWQ@PQLRQPJSPJCLAP@J#INRiIY`IqIINB@Jz'@JB@JB@MIY";i=*s>63?:*s++;s++)for(;i--&31;)printf("%c%c",A[*s&7],A[*s/8&7]);}

Try it online!
Rundown
We define an alphabet of 8 symbols, " _|/\\()\n", and compress the data by packing two symbols per byte according to its index in the alphabet, with the first symbol in bits 0..2, and the second in 3..5. Bit 6 is set to bring the resulting byte into printable ASCII territory. A simple RLE is then run on the compressed string. If a symbol in the string occurs more than twice in a row, it is stored as a character pair, with the first containing the run-length plus 32 (bit 5 set) and the second the symbol itself.
f(i){                                               i is run-length; not actually passed to f()
    for(                                            Loop over compressed string.
        char*A=" _|/\\()\n",                        Alphabet
        *s="...";                                   Compressed string.
        i=*s>63?:*s++;                             If char is outside symbol range, use as run-length and skip to next. Stop on EOS.
        s++)                                        Advance to next char.
            for(;i--&31;)                           Repeat symbol pair per run-length.
                printf("%c%c",A[*s&7],A[*s/8&7]);   Extract symbols from character and print.
}

Try it online!

@ceilingcat Hm. Can't be recalled without funky output. Still, tweaked it a bit and got 279 too.

05AB1E, 171 bytes
"_ |0/)(
\"•1æÆ&¢ÙDÿœƒ˜¶f
¹∍[saÎΛÞÀθ¶\‚e–8(¬šôon&{wαλµ.cRŽ1ºWèíÄʒΣ ι.ì¨Gt‰?WиΛÆ—©UãšW#тÊ÷´¥b™¢,V§¯l€éàøjòÐø¬ëäÇ kĀT¬Àн4p«ªÒdαñáyÛÆ¦‚@ø‘Ñ‚иu₅₂Qp>øî÷^‡иÓ7¯ÓÇŠ@ÄéS•9вèJ0…   :

Try it online.
Explanation:
"_ |0/)(
\"            "# Push string "_ |0/)(\n\"
  •1æÆ&¢ÙDÿœƒ˜¶f
  ¹∍[saÎΛÞÀθ¶\‚e–8(¬šôon&{wαλµ.cRŽ1ºWèíÄʒΣ ι.ì¨Gt‰?WиΛÆ—©UãšW#тÊ÷´¥b™¢,V§¯l€éàøjòÐø¬ëäÇ kĀT¬Àн4p«ªÒdαñáyÛÆ¦‚@ø‘Ñ‚иu₅₂Qp>øî÷^‡иÓ7¯ÓÇŠ@ÄéS•
               # Push compressed integer 1097503083536947704653792841425892054204805659502021445044262296065039856679486956980779201344195600186307613120325421519873972685660197036332437042797892085831181080642513349371962439499848029872306826792254102689695782393365417312419084231420872539225014767457254170199022042856591776594745757160095950475758150232076499909206475280246564765470414367938
   9в          # Converted to Base-8 as list: [1,0,3,1,1,0,3,3,3,3,3,3,3,3,3,1,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,3,0,7,2,1,2,3,2,1,2,3,3,3,3,3,3,3,3,1,1,6,0,0,0,0,0,0,0,5,3,3,3,1,0,3,3,3,3,1,1,2,1,2,7,2,1,2,0,0,1,2,1,2,1,0,0,0,0,1,0,0,0,0,1,1,0,0,0,0,1,1,0,3,0,3,1,0,0,0,0,0,3,0,0,0,0,1,1,0,0,0,2,1,2,0,1,1,0,0,0,0,1,1,0,0,0,0,2,1,2,7,2,1,1,0,0,5,2,1,2,4,1,0,1,1,2,1,1,0,1,8,2,1,1,0,1,8,2,1,2,1,2,1,2,1,1,2,1,1,0,0,0,5,1,4,1,0,1,1,2,4,0,0,0,5,1,1,0,5,4,1,0,1,1,5,4,1,0,0,0,5,0,2,7,2,1,2,3,2,1,6,1,6,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,0,2,1,2,1,1,2,1,2,0,0,0,0,6,1,6,1,2,1,2,0,0,0,1,2,1,2,0,6,1,6,4,1,4,2,1,2,3,1,0,7,2,0,2,3,2,0,2,8,0,2,2,0,2,1,2,2,0,4,2,1,2,2,0,4,1,8,0,0,1,1,2,1,1,2,0,0,0,0,0,0,0,5,0,2,2,0,6,0,0,0,4,1,8,0,0,0,5,0,0,0,0,5,0,2,3,2,0,2,7,3,3,3,3,1,1,2,0,2,3,2,0,2,3,6,0,0,0,0,4]
     è         # Index each into the string
      J        # Join all characters together to a single string
       0…   :  # Replace all "0" with "   " (3 spaces)
               # (and output the string implicitly as result)

See this 05AB1E tip of mine (section How to compress large integers? and How to compress integer lists?) to understand how the compressed integer and Base-8 list work.

I'ma beat you ;).

Nevermind, no I'm not +1.

@MagicOctopusUrn :D

Javascript ES6, 314 bytes
Contains unprintable bytes. Uses some black JS magic to run.
If console.log() is needed for this answer to be valid, the byte count will be 327.
[...`Ãm°Ûm¶Ûm¶Ûm¶Û\`��m¶Ûm¶Ûm¶Ûm�ç�±Çm¶Ûm¶Ûm¶Ûh���¶Ûm°Ûm¶Ûm�<â�8à�À�°�l6Ãm��m��\`�Äl����Ç��§��Ça�ØfqÇ��À�����»
°Ú¬� ó�Øé¦8ã�8ã� ã±Ä�&�â�Ç�4Y�vØnAÛ�X$�HG��\`lv �� ���0��
�Ø�öÛm¶Ûb�Ø�¶���`].map(a=>'0'.repeat(8-(z=a.charCodeAt().toString(2)).length)+z).join``.replace(/.{1,3}/g,a=>`_|/\\()
`[parseInt(a,2)]).slice(0,-2)

This was a huge pain to get right, and I couldn't manage to get rid of the .slice(0,-2) :(
Will edit in an explanation tomorrow when I'm less tired.
Replaced every single byte with the corresponding hex value in order for the code snippet to be able to run

f=_=>
[...`\xc3\x6d\xb0\xdb\x6d\xb6\xdb\x6d\xb6\xdb\x6d\xb6\xdb\x60\x00\x00\x6d\xb6\xdb\x6d\xb6\xdb\x6d\xb6\xdb\x6d\x86\xe7\x1d\xb1\xc7\x6d\xb6\xdb\x6d\xb6\xdb\x6d\xb6\xdb\x68\x00\x00\x0b\xb6\xdb\x6d\xb0\xdb\x6d\xb6\xdb\x6d\x8e\x3c\xe2\x06\x38\xe0\x00\xc0\x01\xb0\x00\x6c\x36\xc3\x6d\x80\x00\x6d\x80\x03\x60\x01\xc4\x6c\x00\x1b\x00\x01\xc7\x9d\x80\xa7\x15\x86\xc7\x61\x99\xd8\x66\x71\xc7\x1d\x8e\xc0\x0b\x96\x1b\x14\x00\xbb\x0a\xb0\xda\xac\x00\xa0\xf3\x8e\xd8\xe9\xa6\x38\xe3\x8e\x38\xe3\x8e\x20\xe3\xb1\xc4\x00\x26\x98\xe2\x00\xc7\x11\x34\x59\x1c\x76\xd8\x6e\x41\xdb\x10\x58\x24\x1c\x48\x47\x12\x16\x60\x6c\x76\x20\x00\x00\xa0\x91\x00\x0b\x30\x05\x00\x0a\x0e\xd8\x83\xf6\xdb\x6d\xb6\xdb\x62\x0e\xd8\x83\xb6\x80\x00\x80`].map(a=>'0'.repeat(8-(z=a.charCodeAt().toString(2)).length)+z).join``.replace(/.{1,3}/g,a=>`_|/\\()
`[parseInt(a,2)]).slice(0,-2)

a.innerHTML=f()

How does this work?

JavaScript, 294 292 bytes
_='_&3,,& *.,,&_ 7+&+,,-(*.)&&& _,-+7+__1 . .-.3&_& ._&.-*+_-.-.+7|3_)+2_43 b|3 \\+14-*) 2_4/*)3)2_-)2*)_|7+&| 51111 6+-+.51*1_52/+& _ 7|0\\_|6+6/+62\\__44*.)_|6(*2\\*).)07,40&(./,&&&&0_|&6|&- .*_*___1 ++| |3-_4-|- 2/ 5( (6|_7\n';for(Y in $='7652-43+1*.&0,')with(_.split($[Y]))_=join(pop());_

This... is literally just encoding of the art... with this...
If console.log() is required, then byte count is 307305 bytes.
294->292, -2B for encoding \n to 7.

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


text:
Partition a list!
In this challenge, you need to partition a list, where partitions have a max size, a min size, and a preferred size.  I'll be using the notation (min,pref,max)  to indicate the sizes in this challenge.
For those unfamiliar with partitioning, the following list has been partitioned into parts of 3:
[0..9] -> [[0,1,2],[3,4,5],[6,7,8]]
When the list is not evenly divisible, you need the partitions to be as close to the preferred size as possible: [0..10], (2,4,5) -> [[0,1,2,3],[4,5,6],[7,8,9]].  This partitioning is preferable to [[0,1,2,3],[4,5,6,7],[8,9]], even though the latter has more of the preferred length.  Formally, we need to minimize the sum of (partitionLength-preferredSize)^2 for each partition.
The order of the partition lengths does not matter: For [0..5], (2,3,3), either [[0,1,2],[3,4]] or [[0,1],[2,3,4]] works.  If no partition is possible, return an empty array: [0..7], (4,4,5) -> [].
You can assume that 1<=min<=pref<=max, and that the array passed to you is a non-empty array of integers.  The array will always be the first argument.  You can accept min, max, and pref in any order and as a tuple or as separate arguments.
Your program must run under a couple of seconds.  Basically, iterating through every possible partition size within the bounds is not allowed.
Test cases:
[1], (1,3,4)         -> [[1]]
[100], (1,2,3)       -> [[100]]
[1,2], (1,1,2)       -> [[1],[2]]
[1,2], (1,2,2)       -> [[1,2]]
[1,2], (1,3,3)       -> [[1,2]]
[1,2,3], (1,2,3)     -> [[1,2],[3]] or [[1,2,3]]
[1,2,3,4], (1,3,4)   -> [[1,2,3,4]]
[1,2,3,4,5], (3,3,4) -> []
[1,2,3,4,5], (2,2,2) -> []
[1,2,3,4,5], (3,3,5) -> [[1,2,3,4,5]]
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49], (2,6,6) -> [[1,2,3,4,5,6],[7,8,9,10,11,12],[13,14,15,16,17,18],[19,20,21,22,23,24],[25,26,27,28,29],[30,31,32,33,34],[35,36,37,38,39],[40,41,42,43,44],[45,46,47,48,49]]

This is a code-golf, so aim for as few bytes as possible in your favorite language!

The notation you're using of [a..b] includes a and excludes b, correct?

A inclusive, B exclusive.

Note that your interpretation of a  is not the same as a partition from set theory...

But it is effectively equivalent to integer partitioning.

What if there is no solution?

"If no partition is possible, return an empty array"

Haskell, 152
_%0=[]
s%k|(a,b)<-splitAt(div(z s)k)s=a:b%(k-1)
z=length
f s n p x=snd$minimum$(z s*p^2,[]):[(sum[(z x-p)^2|x<-s%k],s%k)|k<-[-div(-z s)x..div(z s)n]]

In any partition, if there are two lists which have lengths that differ by two or more, it will always be beneficial to shrink the bigger list and enlarge the smaller list. therefore, we only need to consider partitions with only two list sizes, which simplifies the computation.
the program then runs on all the possible amounts of lists in the partition. given the amount of lists in the partition, the score is uniquely determined. the program computes a fitting partition, and its score.
then it finds the overall minimum, and returns it.
Usage: input like f [1,2,3,4,5] 1 3 4 (f is the function that solves the challenge)
Although it is possible to computing the best option completely numerically and only then partitioning the list accordingly, it took too many bytes. however, my last version of this approach is:
_%0=[]
s%k|(a,b)<-splitAt(div(length s)k)s=a:b%(k-1)
f s n p x|l<-length s=(s%)$snd$minimum$(l*p^2,0):[(k*j^2+mod l k*(1-2*j),k)|k<-[1..div l n],k*x>=l,j<-[p-div l k]]

CJam, 70
q~:S;_,[0L]a{_S2=e<),S0=>f{[__S1=-_*\]@@-j.+}[esL]a+:e<}j1={/(\e_}/;]p

Try it online
The code finds an optimal sequence of partition sizes based on the list size, using dynamic programming (via memoized recursion), then goes ahead and partitions the list.


text:
Count rectangle intersections
The Challenge
Given an arbitrary amount of rectangles, output the total count of intersections of those when drawn in a 2D plane.
An intersection here is defined as a point P which is crossed by two lines which are orthogonal to each other and are both not ending in P.
Example
Each rectangle here is denoted by a 2-tuple with the coordinates of the upper left corner first and the coordinates of the bottom right corner second.

[(-8,6),(-4,-2)]
[(-4,9),(4,3)]
[(2,10),(14,4)]
[(1,7),(10,-6)]
[(7,4),(10,2)]
[(5,2),(9,-4)]
[(-6,-4),(-2,-6)]

Those rectangles create 6 intersections, which has to be your output.

As you can see in the image above, touching rectangles will not create intersections here and are not counted.
You can encode the rectagles in any format you want. Make it clear which format you use.
If multiple rectangles intersect at the same point, it only counts as one intersection.
The coordinates will always be integers.
There won't be any duplicate rectangles in the input.
You will always get at least one rectangle as input.
You may not use any builtins which solve this problem directly. Additionally you may not use builtins that solve equations. All other builtins are allowed.
The output has to be a single integer indicating the intersection count.

Rules

Function or full program allowed.
Default rules for input/output.
Standard loopholes apply.
This is code-golf, so lowest byte-count wins. Tiebreaker is earlier submission.

Test cases
Same format as in the example above. The rectangles are wrapped in a list.

[[(-8,6),(-4,-2)],[(-4,9),(4,3)],[(2,10),(14,4)],[(1,7),(10,-6)],[(7,4),(10,2)],[(5,2),(9,-4)],[(-6,-4),(-2,-6)]] -> 6
[[(-2,2),(6,-4)]] -> 0
[[(-12,10),(-8,6)],[(-14,6),(-10,2)],[(-10,6),(-6,2)]] -> 0
[[(-4,10),(6,2)],[(-2,8),(4,3)],[(1,6),(8,4)],[(2,11),(5,5)]] -> 10
[[(8,2),(12,-2)],[(10,0),(14,-4)]] -> 2
[[(0,2),(2,0)],[(0,1),(3,0)]] -> 1
[[(-10,-2),(-6,-6)],[(-6,-2),(-2,-6)],[(-8,-4),(-4,-8)]] -> 3

Happy Coding!

You need to define what it is that you want answers to count, as many points in the intersection of two or more rectangles are apparently ignored, according to the diagram.

So, [[(0,0),(1,2)],[(0,0),(2,1)]] would have 1 intersection?

@Neil Exactly. Gonna add this test case, thanks!

@feersum I think the diagram makes it pretty clear what to count and what not. But a formal definition wouldn't hurt I suppose, gonna add one.

If there are N pairs of rectangles that intersect at (x, y), is the point (x, y) counted once or N times?

@feersum Once. Clarified it in the challenge.

If multiple rectangles intersect at the same point, it only counts as one intersection. That makes the problem much harder! :-)

JavaScript (ES6), 186 bytes
a=>a.map(([a,b,c,d])=>h.push([b,a,c],[d,a,c])&v.push([a,b,d],[c,b,d]),h=[],v=[])|h.map(([d,a,e])=>v.map(([c,f,b])=>a<c&c<e&b<d&d<f&t.every(([a,b])=>a-c|b-d)&&t.push([c,d])),t=[])|t.length

Splits each rectangle into its component lines, then intersects the horizontal and vertical lines, building up a list of intersections to avoid duplicates.

Which input format do you use? When I call this with the tastcases, I always get zero.

@DenkerAffe Sorry, I should have said, I expect an array of arrays of 4 elements e.g. [[-4,10,6,2],[-2,8,4,3],[1,6,8,4],[2,11,5,5]]. Since JavaScript doesn't have tuples, if you'd tried to use your examples literally you'd have triggered the comma operator instead, invalidating the input.

Alright, thanks. However, this gives 4 instead of 3 for the last testcase, since intersections of multiple rectangles only count as one intersection. I clarified this after you posted your answer I think, so this one goes on me. Hope its not too hard to fix this, sorry for the inconvenience.

@DenkerAffe I've updated it to work with your new spec.

Mathematica 138 bytes
Not finished!
This works for all cases except [[(0,0),(1,2)],[(0,0),(2,1)]]

Length@Union[Join@@(Cases[RegionIntersection@@# &/@Subsets[Line[{{#,#2},{#3,#2},{#3,#4},{#,#4},{#,#2}}]&@@@Flatten/@#,{2}],Point@a__:> a])]

Example
Length@Union[
Join @@ (Cases[RegionIntersection @@ # & /@ Subsets[
Line[{{#, #2}, {#3, #2}, {#3, #4}, {#, #4}, {#, #2}}] & @@@ Flatten /@ #, {2}],
Point@a__ :> a])] &@{{{-8, 6}, {-4, -2}}, {{-4, 9}, {4, 3}}, {{2, 10}, {14, 4}},
{{1, 7}, {10, -6}}, {{7, 4}, {10, 2}}, {{5, 2}, {9, -4}}, {{-6, -4}, {-2, -6}}}

6


text:
Crosses, no Noughts
Everyone realizes that Tic Tac Toe is a solved game. However, the Misère version of only-Xs provides an interesting alternative.
In this version of the game, both players play Xs onto the board and try to avoid making three in a row. If you'd like to see more about this, Numberphile has a nice video about this concept.
Given a board of Misère Crosses, play an optimal move.
A board is three lines of three characters each, which are X or . Thus:
X X
X
 XX

is a valid board. You may take this in any convenient format, so long as your input and output use the same format. Formats include (but are not limited to): A multi-line string (with optional trailing newline); A 2D array of characters which are X or ; a 1D flattened array of boolean values representing if each position has been played.
An optimal move is one that guarantees you will win by continuing to play optimally or prolongs your loss for as long as possible and is defined by the following rules:

Avoid making three in a row.
If you go first, play in the middle.
If the only occupied space is the middle, play in any of the remaining spaces.
If the middle square is not occupied and an outer square is, play opposite your opponent's last play.
If the middle square is occupied and an outer square is, play a "knights move" (opposite, one over) away from a previous move that does not cause you to lose.
If no remaining squares are left where you won't lose, play in any of the remaining squares.

[NOTE: this has been proved to be non-optimal in one case but you should use this algorithm anyway.]
You may assume that all of your previous moves were optimal. Thus, the first example board is not a valid input. Your opponent's moves may or may not be optimal.
If the game has ended (i.e. a three in a row has been made), behavior is undefined.
As this is code-golf, the shortest answer in bytes wins!
One possible path, using only optimal moves, is this:
[   ]  [   ]  [X  ]  [X  ]  [X  ]  [X  ]  [XX ]
[   ]->[ X ]->[ X ]->[ XX]->[ XX]->[ XX]->[ XX]
[   ]  [   ]  [   ]  [   ]  [ X ]  [XX ]  [XX ]

Here are possible inputs originating from the opponent using non-optimal moves: (Note that only the left-side boards on this list are valid inputs.)
[X  ]  [X  ]
[   ]->[   ]
[   ]  [  X]

[XX ]  [XX ]
[   ]->[   ]
[  X]  [ XX]

[XX ]  [XX ]
[X  ]->[X X]
[ XX]  [ XX]

Related

What are the input and output formats? I'm assuming a board taken as an array or string? However this does not provide info on the last move, hence my next question.

The strategy "play opposite your opponent's last play" assumes either knowledge of your opponent's move history, or that you have previously followed this strategy, i.e have not inherited a board such as .XX\nX..\nX.. for example. Do we have to consider inheriting boards such as this?

@LevelRiverSt As written, "You may assume that all of your previous moves were optimal," so that board would be invalid input. You can take input in whatever format you like, but a multi line string such as your example there would be the "default": I just don't want to restrict anyone to having to parse the String when the move logic is the point of the challenge.

Ruby, Rev B 121 bytes
Submission is the anonymous function, minus the f=. Shown in test program to illustrate use.
f=->n{["~mK)\7","}uYwQO"][l=n%2].bytes{|t|9.times{|i|(m=n|1<<i)==n||8.times{|j|m/2*257>>j&255==126-t&&t+j%2!=119&&l=m}}}
l}

puts g=f[gets.to_i]
puts
[7,6,5,
 8,0,4,
 1,2,3].each{|i|print g>>i&1; puts if i/3==1}

2 bytes saved by making the centre square the least significant bit instead of most significant bit (remove by /2 instead of %256.) Remaining savings by a reorganization of the table of acceptable moves. Organizing as centre square free/occupied instead of by total number of X's allows for a simpler test. Also, now there are only 2 strings in the array so the %w{string1 string2} syntax is abandoned in favour of the ["string1","string2"] syntax. This enables a nonprintable character \7 to be included, which in turn enables a simpler encoding to be used: 126-t instead of (36-t)%120.
Ruby, Rev A 143 bytes
->n{l=r=("%b"%n).sum%8
%w{$ %5 - I+Wy Q S#}[r].bytes{|t|9.times{|i|(m=n|1<<i)==n||8.times{|j|m%256*257>>j&255==(t-36)%120&&t+j%2!=43&&l=m}}}
l}

This is  an anonymous function. The input / output format was left open, so I've gone for a 9-bit binary number. the 512's bit represents the centre, with the remaining bits spiralling round it (the 1's bit is considered to be a corner.)
There are far more possible inputs than acceptable outputs, so the algorithm is to try all moves, and find one that fits an acceptable output pattern. The acceptable output patterns for each number of X's are hardcoded.
The information about the centre square is stripped off and the remaining 8 bits are multiplied by 257 to duplicate them. This pattern is then rotated past the acceptable patterns by rightshifting.
The loop is not exited when a pattern is found, so the returned pattern will be the LAST acceptable pattern found. For this reason, preferable patterns (where there is a preference) come later in the list.
Given the 'Knights move' strategy it is of little importance whether a pattern is rotated by 45 degrees or not. The ungolfed version follows the knights move strategy and therefore does not need to differentiate between corner squares and edge squares: three in a row is to be avoided anyway.
However, I found that this is not always the best strategy, as there is the following trick. If your opponent goes first and takes the centre he should win. But on his second move he makes the error of allowing you to make a 2x2 square you should take it, as this allows you to force him to make three in a row. This is implemented in the golfed version. A little extra code is needed in this one instance to distinguish between three X's in a corner (force opponent to lose) and 3 X's along one edge (immediate suicide.)
Ungolfed in test program
The ungolfed version follows the logic expressed in the question.
In the golfed version the table is slightly modified to [[0],[1,17],[9],[37,7,51,85],[45],[47,119]] to implement the slightly different behaviour for the case r=3. It is then compressed to printable ASCII (requiring decoding (t-36)%120). An additional bit of logic is required to differentiate between three X's in a corner and three X's along an edge in the case of the table entry 7: &&t+j%2!=43
f=->n{l=r=("%b"%n).sum%8                                      #convert input to text, take character checksum to count 1's(ASCII 49.)
                                                              #0 is ASCII 48, so %8 removes unwanted checksum bloat of 48 per char.
                                                              #l must be initialised here for scoping reasons.
  [[0],[1,17],[9],[11,13,37,51,85],[45],[47,119]][r].each{|t| #according to r, find the list of acceptable perimeter bitmaps, and search for a solution.
    9.times{|i|(m=n|1<<i)==n||                                #OR 1<<i with input. if result == n, existing X overwritten, no good.
                                                              #ELSE new X is in vacant square, good. So..
      8.times{|j|m%256*257>>j&255==t&&l=m}}                   #%256 to strip off middle square. *257 to duplicate bitmap.
                                                              #rightshift, see if pattern matches t. If so, write to l
  }
l}                                                            #return l (the last acceptable solution found) as the answer.

#call function and pretty print output (not part of submission)
puts g=f[gets.to_i]
puts
[6,7,0,
 5,8,1,
4,3,2].each{|i|print g>>i&1; puts if i<3}

Output of test program
This what happens when the computer plays itself.

C:\Users\steve>ruby tictac.rb
0
256

000
010
000

C:\Users\steve>ruby tictac.rb
256
384

010
010
000

C:\Users\steve>ruby tictac.rb
384
400

010
010
100

C:\Users\steve>ruby tictac.rb
400
404

010
010
101

C:\Users\steve>ruby tictac.rb
404
436

010
110
101

C:\Users\steve>ruby tictac.rb
436
444

010
110
111

GAME ANALYSIS PLAYING FIRST
This is actually very simple and linear.
When playing first, the middle square will always be the first square occupied.
r=0
...  binary representation 0
.X.
...

r=2
X..  binary representation 1001=9
.XX
...

r=4
X.. binary representation 101101=45
.XX
XX.

There is only one way (up to symmetry) to have five X's including the middle square on the board without the game being over.
There is an X in the middle square, one on each diagonal (at 90 degrees to each other) and one on each horizontal/vertical centreline (at 90 degrees to each other.)
As an entire edge cannot be occupied the above is the only arrangement possible. Other player must lose on next move.
GAME ANALYSIS PLAYING SECOND
Play is quite different depending if the other player chooses the middle square.
r=1
middle square occupied
.X. X..  binary representation 1
.X. .X.
... ...

middle square free
X.. .X. binary representation 10001=17
... ...
..X .X.

r=3
Middle square occupied, if other player plays adjacent to your last X
Playing a knight's move away as below is supported in the ungolfed version
XX. .XX binary representation 1011=11
.X. XX. or mirror image 1101=13
X.. ...

However the above is NOT the best move and is not supported in the golfed version.
The best move is as follows, forcing a win on the next turn:
XX. binary representation 111=7.           XXX
XX. Only to be used where j is odd.        .X.
... Even j would look like image to right. ...

Middle square occupied, if other player plays at 90 or 135 degrees to your last X (play knight's move away.)
X.X .X. binary representation 100101=37
.X. .XX
.X. X..

Middle square free
X.X .X. XX. binary representations:
... X.X ...    1010101=85 (first two)
X.X .X. .XX and 110011=51 (last one)

r=5
middle square occupied. For the reasons stated above in r=4, there are four possible moves, all of which lose. only one is supported: 101111=47.
middle square free. There is only one possible board up to symmetry, as follows. Other player must lose on next move, so there is no need to support r>5.
XX. binary representation 1110111=119
X.X
.XX

This is a marvelous answer! I thought I had checked all cases for the optimal moe, but I guess I missed one. The spec'll stay the same for simplicity, though. (Really this is amazing thank you for doing this and this is so well explained! I left the I/O lose so people could do something amazing like this.)

Thanks, it was an interesting challenge. I've managed to golf quite a bit more out of it now.