title: Code Golf Simulated Golf

text:
# Question
Title: Code Golf Simulated Golf
Given a list of hole yardages, green sizes, a slice angle and a max distance, compute a golf score.

## Assumptions

* Earth is flat
* All greens are circular
* Slice angle will be between -45 and 45 degrees and will be given in degrees
* All distances in the same metric (yards or meters, doesn't matter)
* No out of bounds, obstructions or doglegs
* Max score on any hole is 8
* All shots travel the lesser of max distance or distance to the hole, in a direction defined by the angle to the hole plus the slice angle.
* Distance is measured as the straight line or Euclidean distance between the start and end point.
* Max distance and slice angle are the same for all shots on all holes
* The golfer always two-putts once on the green (or exactly on the edge of the green).

## Example

Let's look at the hacker from the test case #5 below for hole #2. The hacker can hit the ball 320 yards, but always slices 30 degrees. If we assume without loss of generality that the tee box is at {0,0} and the green is at {497,0}, then he will hit shots to the following points, arriving on the green with the 7th shot:

`{{0.,0.},{277.128,-160.},{547.543,-131.372},{569.457,7.67088},{502.872,37.2564},{479.159,7.92741},{490.646,-7.85868},{500.078,-4.22987}}`

At this point, his score would be 9 due to the two putts required, so the final score for him gets capped at 8, per the assumptions.

Graphically, it will look like this:

## Test Cases

All the test cases have standard 18-hole courses

```
Case#1
{MaxDistance->280,SliceAngle->10,HoleDistances->{181,368,161,416,158,526,377,427,509,148,405,443,510,494,396,388,483,172},GreenDiameters->{26,18,17,23,27,23,21,23,25,21,19,24,21,23,25,24,22,22}}
Scores:
{4,5,4,5,4,5,5,5,5,4,5,5,5,5,5,5,5,4}
Output: 85

Case#2 (same course as Test Case #1, shorter more accurate golfer)
{MaxDistance->180,SliceAngle->5,HoleDistances->{181,368,161,416,158,526,377,427,509,148,405,443,510,494,396,388,483,172},GreenDiameters->{26,18,17,23,27,23,21,23,25,21,19,24,21,23,25,24,22,22}}
Scores:
{4,5,4,5,4,6,5,5,6,4,5,5,6,6,5,5,5,4}
Output: 89

Case#3 (Same golfer as test case #1, shorter course)
{MaxDistance->280,SliceAngle->10,HoleDistances->{147,497,110,528,409,118,196,154,134,514,374,491,131,138,523,478,481,494},GreenDiameters->{32,16,36,25,32,20,30,30,33,29,25,26,26,25,33,28,21,28}}
Scores:
{4,5,4,5,5,4,4,4,4,5,5,5,4,4,5,5,5,5}
Output: 82

Case#4 (Same course as test case #3)
{MaxDistance->180,SliceAngle->5,HoleDistances->{147,497,110,528,409,118,196,154,134,514,374,491,131,138,523,478,481,494},GreenDiameters->{32,16,36,25,32,20,30,30,33,29,25,26,26,25,33,28,21,28}}
Scores:
{3,6,3,6,5,4,4,3,3,5,5,5,3,3,5,5,6,5}
Output: 79

Case#5 (Hacker)
{MaxDistance->320,SliceAngle->30,HoleDistances->{147,497,110,528,409,118,196,154,134,514,374,491,131,138,523,478,481,494},GreenDiameters->{32,16,36,25,32,20,30,30,33,29,25,26,26,25,33,28,21,28}}
Scores:
{6,8,5,8,7,6,6,6,6,8,8,8,6,6,8,8,8,8}
Output: 126

```

## Rules

* Any format can be used for the input. Output is simply the number of simulated strokes, so should be an integer.
* This is so the shortest answer in bytes wins. Standard loopholes apply.

# Answer
## JavaScript (ES7), ~~128~~ 126 bytes

```
(m,a,D,S,t=0)=>S.map((s,i)=>t+=(r=(f=d=>d>s/2?1+f((l=d<m?d:m,l*l+d*d-2*d*l*Math.cos(a*Math.PI/180))**.5,s):2)(D[i]))<8?r:8)&&t

```

Try it online!

### Explanation

Because only the distance from the ball to the hole matters and not the coordinates of the ball, we can write an algorithm that calculates how close the ball gets to the hole with each shot, then run that repeatedly until the ball reaches the green. But how do we do this?

Re-using OP's helpful diagram explaining ball movement, with MS Paint modifications:

We have access to these numbers:

* **d**, the current distance from ball to hole;
* **θ**, the slice angle; and
* **l**, the length of the shot (minimum of **d** and the max shot length).

And the goal is to find **x**, the distance from ball to hole after the shot is taken.

First we note that **a** and **b** are simply **l cos θ** and **l sin θ**, respectively. We can see that by the Pythagorean theorem, **x** can be represented as **sqrt(b2 \+ (d-a)2)**. Expanding this out, we get

```
x = sqrt(b^2 + (d - a)^2)
  = sqrt((l*sin(θ))^2 + (d - l*cos(θ))^2)
  = sqrt((l^2 * sin^2(θ)) + (d^2 - 2*d*l*cos(θ) + l^2 * cos^2(θ))
  = sqrt(l^2 * sin^2(θ) + l^2 * cos^2(θ) + d^2 - 2dl*cos(θ))
  = sqrt(l^2 * (sin^2(θ) + cos^2(θ)) + d^2 - 2dl*cos(θ))
  = sqrt(l^2 * 1 + d^2 - 2dl*cos(θ))
  = sqrt(l^2 + d^2 - 2dl*cos(θ))

```

And so, the new distance from ball to hole will be **sqrt(l2 \+ d2 \- 2dl cos θ)**. Then we count the iterations it takes to get this distance within the radius of the green, add 2, and cap at 8 to get the final score for that hole.

(Thanks to @LegionMammal978 for pointing out that all of the calculations I made are a direct result of the law of cosines...)

---

Interestingly enough, when the ball is closer to the hole than its max shot, **l = d** and we can simplify the formula quite a bit further:

```
x = sqrt(l^2 + d^2 - 2dl*cos(θ))
  = sqrt(d^2 + d^2 - 2d^2*cos(θ))
  = sqrt(2d^2 - 2d^2*cos(θ))
  = sqrt(d^2(2 - 2cos(θ)))
  = d * sqrt(2 - 2cos(θ))

```

To find the # of remaining iterations, we could then simply find **d / r** (where **r** = the radius of the green) and divide that by **sqrt(2 - 2cos(θ))**, then take the ceiling of the result and add 2. Unfortunately, this doesn't seem to be as short as just finding the smaller of **d** and the max shot length.
> 10 votes

# Answer
# Perl 5, ~~144~~ 138 + 12 (`-MMath::Trig`) = 150 bytes

*shaved a few bytes using @ETHproductions' simplification of the formula*

```
sub p{$_=pi/180*pop;$m=pop;for$b(@_[0..17]){$s=!++$c;1while++$s<6&&$_[17+$c]/2<($b=sqrt$b*$b+($h=$m<$b?$m:$b)**2-2*$h*$b*cos);$t+=$s+2}$t}

```

Try it online!

Changed up the input format a bit:

```
Hole 1 distance
Hole 2 distance
...
Hole 18 distance
Hole 1 green diameter
...
Hole 18 green diameter
Maximum distance
Slice angle

```
> 3 votes

# Answer
# Julia 0.6, 106 bytes

```
S(m,t,D,G)=(s(m,d,g,v=2)=d<=g/2?v<8?v:8:(l=d<m?d:m;s(l,(d^2+l^2-2d*l*cosd(t))^.5,g,v+1));sum(s.([m],D,G)))

```

Try it online!

Based on ETHproductions' answer.

**Explanation**

* `s(m,d,g,v=2)=...` Define function `s` that calculates the score for one hole recursively.
* `sum(s.([m],D,G))` Apply `s` for each hole and sum the result. `.` is element-wise function application with singleton expansion. E.g.: `min.([1],[2,3]) = [min(1,2), min(1,3)]`

```
d<=g/2?v<8?v:8:(l=d<m?d:m;s(...)) #
d<=g/2?       :                   # is the ball on the green?
       v<8?v:8                    # yes -> return min(v,8)
               (l=d<m?d:m;s(...)) # no  ->
                                  # calculate new distance using ETHproductions' formula
                                  # increment current score
                                  # call s recursively

```
> 2 votes

---
Tags: code-golf, geometry
---


title: Golfing ASCII-art

text:
# Question
Title: Golfing ASCII-art
Let's try to golf this piece of ascii-art representing a golfing man:

```

      '\                   .  .                        |>18>>
        \              .         ' .                   |
       O>>         .                 'o                |
        \       .                                      |
        /\    .                                        |
       / /  .'                                         |
 jgs^^^^^^^`^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

```

Source: JGS - http://www.retrojunkie.com/asciiart/sports/golf.htm

**Rules:**

* No input allowed
* No external resources allowed
* The output must be exactly this text, displayed in a monospace font (OS console, JS console, HTML \<pre\> tag, ...), including the leading and trailing line-break.
* Surrounding quotes or double-quotes are allowed (the JS console adds double quotes when you output a string, this is okay)

The best answer will be the one using the less **characters** in any language.

Have fun!

# Answer
# CJam, 62 characters

```
"Ⴀ지尦렒>Ä΀ྀ㸀⡅쇋蒧ʸ鿀ʃ케袧Ƽ蟀ʄ導뤷쀂萯Ű⋥ἀ਎밊耧台 ⢙⿶ꝍ㕟劢햟騤꩏脽啎"2G#b128b:c~

```

Try it online.

### Test run

```
$ base64 -d > golf.cjam <<< IgHhgqDsp4DlsKbroJLujJ8+w4TOgOC+gOO4gOKhheyHi+iSp8q46b+AyoPsvIDvoIPuhKvooqfGvOifgMqE5bCO66S37ICC6JCvxbDii6XhvIDgqI7rsIrvgYvogKflj7DCoOKimeK/tuqdjeOVn+WKou2Wn+mopO+em+qpj+iEve6arOWVjiIyRyNiMTI4Yjpjfg==
$ wc -m golf.cjam
62 golf.cjam
$ cjam golf.cjam

      '\                   .  .                        |>18>>
        \              .         ' .                   |
       O>>         .                 'o                |
        \       .                                      |
        /\    .                                        |
       / /  .'                                         |
 jgs^^^^^^^`^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
$

```

### How it works

`2G#b` converts the preceding string into an integer by considering it a base-65536 number.

`128b:c` converts that integer back to a string (**110 bytes**) by considering it a base-128 number, which `~` then executes:

```
"
^F'^@\^S.^B.^X|^@>^@1^@8^@>^@>^@
^H\^N.^I'^A.^S|^@
^GO^@>^@>^I.^Q'^@o^P|^@
^H\^G.&|^@
^H/^@\^D.(|^@
^G/^A/^B.^@')|^@
^A"2/{)iS*}%"jgs"'^7*'`'^51*N

```

*(caret notation)*

```
2/{)iS*}%

```

splits the string into pairs of two characters and does the following for each pair: Pop the second character of the string, convert it into an integer and repeat the string `" "` that many times.

For example, `".("` becomes `". "`, because the ASCII character code of `(` is 40.

Finally,

```
"jgs"'^7*'`'^51*N

```

pushes the string `"jgs"`, the character `^` repeated 7 times, the character ```, the character `^` repeated 51 times and a linefeed.
> 14 votes

# Answer
## Ruby, 107

I thought I'd actually try to "generate" the image in code (instead of using some existing compression function):

```
S=?\s*351+?^*60
"⠀鰇렜렟쐺⠾롖鱠롢⡷뢋鲝⢰룁⣩볲룸⤢봪봬뤯鴰⥛".chars{|q|S[511&r=q.ord]=(r>>10).chr}
puts S

```

There are some non-printable characters in that array literal.

Here is the hex view of the file, to show the non-printable characters, too:

```
0000000: 533d 3f5c 732a 3335 312b 3f5e 2a36 300a  S=?\s*351+?^*60.
0000010: 22e2 a080 e9b0 87f0 9780 88eb a09c eba0  "...............
0000020: 9ff0 9f80 b8ef a0b9 ec90 baee 80bb efa0  ................
0000030: bcef a0bd e2a0 bef0 9781 87eb a196 e9b1  ................
0000040: a0eb a1a2 f09f 81b6 e2a1 b7f0 93b1 bfef  ................
0000050: a280 efa2 81eb a28b e9b2 9df0 9bb2 9ef0  ................
0000060: 9f82 afe2 a2b0 f097 82b9 eba3 81f0 9f83  ................
0000070: a8e2 a3a9 ebb3 b2f0 9783 b3eb a3b8 f09f  ................
0000080: 84a1 e2a4 a2eb b4aa ebb4 aceb a4af e9b4  ................
0000090: b0f0 9f85 9ae2 a59b f09a a59d f099 b59e  ................
00000a0: f09c b59f f098 85a7 222e 6368 6172 737b  ........".chars{
00000b0: 7c71 7c53 5b35 3131 2672 3d71 2e6f 7264  |q|S[511&r=q.ord
00000c0: 5d3d 2872 3e3e 3130 292e 6368 727d 0a70  ]=(r>>10).chr}.p
00000d0: 7574 7320 53                             uts S

```

Thanks to Ventero for some major improvements! (He basically reduced the code by 50%.)
> 15 votes

# Answer
# bash + iconv + DosBox/x86 machine code (~~104~~ ~~97~~ ~~96~~ 95 characters)

```
echo ↾각슈삨੽₲ɻ庲錿ʴ⇍罋곹삄ૃ蘊尧⺓⺂粘ㄾ㸸ਾ岈⺎➉⸠粓蜊㹏褾鄮漧粐蠊蝜꘮੼⾈葜꠮੼⾇⼠⺂ꤧ੼樠獧惇૳|iconv -futf8 -tucs2>o.com;dosbox o*

```

I suggest to put this in a script in an empty directory, it's almost guaranteed that copy-pasting it in a terminal will break everything; even better, you can grab the script here ready-made.

Expected output:

## How it works

The bash part is just a launcher that uses `iconv` to "decompress" a `.com` file from the UTF-8 characters of the script and launches it with DosBox.

Notice that this poses some limitation on the content, as not all the input sequences can be interpreted as UCS-2 with `iconv` not complaining; for example, for some reason many operations involving the `bx` register broke havoc depending on the place where I used them, so I had to work around this problem several times.

Now, the Unicode thing is just to take advantage of the "character count" rules; the actual size (in bytes) of the script is way larger than the original `.COM` file.

The extracted `.com` file is

```
00000000  be 21 01 ac 88 c2 a8 c0  7d 0a b2 20 7b 02 b2 5e  |.!......}.. {..^|
00000010  83 e0 3f 93 b4 02 cd 21  4b 7f f9 ac 84 c0 75 e4  |..?....!K.....u.|
00000020  c3 0a 0a 86 27 5c 93 2e  82 2e 98 7c 3e 31 38 3e  |....'\.....|>18>|
00000030  3e 0a 88 5c 8e 2e 89 27  20 2e 93 7c 0a 87 4f 3e  |>..\...' ..|..O>|
00000040  3e 89 2e 91 27 6f 90 7c  0a 88 5c 87 2e a6 7c 0a  |>...'o.|..\...|.|
00000050  88 2f 5c 84 2e a8 7c 0a  87 2f 20 2f 82 2e 27 a9  |./\...|../ /..'.|
00000060  7c 0a 20 6a 67 73 c7 60  f3 0a 0a 00              ||. jgs.`....|
0000006c

```

and is 108 bytes long. The NASM source for it is:

```
    org 100h

start:
    ; si: pointer to current position in data
    mov si,data
    ; load the character in al
    lodsb
mainloop:
    ; bx: repetition count
    ; - zero at startup
    ; - -1 after each RLE run
    ; - one less than each iteration after each "literal" run
    ; the constant decrement is not really a problem, as print
    ; always does at least one print, and there aren't enough
    ; consecutive literal values to have wraparound

    ; if the high bit is not set, we have a "literal" byte;
    ; we prepare it in dl just in case
    mov dl,al
    ; then check if it's not set and branch straight to print
    ; notice that bx=0 is fine, as print prints always at least one character
    ; test the top two bits (we need the 6th bit below)
    test al,0xc0
    ; to see if the top bit was set, we interpret it as the sign bit,
    ; and branch if the number is positive or zero (top bit not set)
    jge print
rle:
    ; it wasn't a literal, but a caret/space with a repetition count
    ; space if 6th bit not set, caret otherwise
    mov dl,' '
    ; exploit the parity bit to see if the 6th bit was set
    jnp nocaret
    mov dl,'^'
nocaret:
    ; lower 6 bits: repetition count
    ; and away the top bits and move in bx
    ; we and ax and not al because we have to get rid of the 02h in ah
    and ax,3fh
    xchg ax,bx
print:
    ; print bx times
    mov ah,2
    int 21h
    dec bx
    jg print
    ; read next character
    lodsb
    test al,al
    ; rinse & repeat unless we got a zero
    jnz mainloop
end:
    ret
data:
    ; here be data
    incbin "compressed.dat"
    ; NUL terminator
    db 0

```

All this is just a decompresser for `compressed.dat` whose format is as follows:

* if the high bit is not set, print the character as-is;
* otherwise, the low 6 bits are the repetition count, and the second-highest bit specifies if it has to print a space (bit not set) or a caret (bit set).

`compressed.dat` in turn is generated using a Python script from the original text.

The whole thing can be found here.
> 13 votes

# Answer
## Python, 156

```
print'''
%6s'\%19s.  .%24s|>18>>
%8s\%14s.%9s' .%19s|
%7sO>>%9s.%17s'o%16s|
%8s\%7s.%38s|
%8s/\%4s.%40s|
%7s/ /  .'%41s|
 jgs'''%(('',)*19)+'^'*7+'`'+'^'*51

```

This uses string formatting with space padding for some basic compression.
> 10 votes

# Answer
# PHP, 147

This runs on the command line and outputs directly to the console:

```
php -r 'echo gzinflate(base64_decode("41IAA/UYBUygB0bYQY2doYWdHReMG4OhEwrUsRpRA9Pob2eHRRNccz5OjXAbcboQl0b9GBK0IWnUB0IFPXUFEjRmpRfHQUBCHOmAiwsA"));'

```
> 7 votes

# Answer
# Perl - 127 ~~129~~ ~~130~~ ~~132~~ ~~135~~ ~~137~~ ~~145~~

```
print q(
6'\19.2.24|>18>>
8\14.9'1.19|
7O>>9.17'o16|
8\7.38|
8/\4.40|
7/1/2.'41|
1jgs^^^^^^^`0
)=~s/\d++(?!>)/$"x$&||'^'x51/reg

```

Thanks to **Ventero** and **m.buettner** for their help in my RegEx optimization.
> 6 votes

# Answer
## GCC C - 203 bytes

I figured I'd have some fun with this one. This compiles on my version of MinGW and outputs the expected text.

Whitespace added for clarity.

```
char*v="\n ú'\\ í.  . è|>18>>\n ø\\ ò. ÷' . í|\n ùO>> ÷. ï'o ð|\n ø\\ ù. Ú|\n ø/\\ ü. Ø|\n ù/ /  .' ×|\n jgs^ù`^Í\n";
main(g,o,l){
    for(;*v;
        g=!g&*v<0&l?-*v++:g){
        v+=!(l=*v-35);
        putchar((g-=g>0)?o:(o=*v++));
    }
}

```

None of the online code pasting sites allow the use of single byte characters outside the ASCII range, so I had to escape them for an uploaded example. It's otherwise identical though. http://codepad.org/nQrxTBlX

You can always verify it with your own compiler, too.
> 4 votes

# Answer
# LOLCODE, 590 characters

Cuz LOLCODE iz perfik language 4 golfin: iz easy 2 compres an obfuscate an it isnt verbose at all.

```
HAI
HOW DUZ I D C T
I HAZ A O
I HAZ A N ITZ 0
IM IN YR LOOP UPPIN YR N TIL BOTH SAEM N AN T
O R SMOOSH O AN C MKAY
IM OUTTA YR LOOP
FOUND YR O
IF U SAY SO
VISIBLE ""
VISIBLE SMOOSH "  '\" AN D " " 19 AN ".  ." AN D " " 24 AN "|>18>>" MKAY
VISIBLE "    \              .         ' .                   |"
VISIBLE "   O>>         .                 'o                |"
VISIBLE SMOOSH "    \       ." AN D " " 38 AN "|" MKAY
VISIBLE SMOOSH "    /\    ." AN  D " " 40 AN "|" MKAY
VISIBLE SMOOSH "   / /  .'" AN D " " 41 AN "|" MKAY
VISIBLE SMOOSH "jgs^^^^^^^`" AN D "^" 51 MKAY
VISIBLE ""
KTHXBYE

```

Im pritee sure dis werkz, but I doan has an LOLCODE interpretr an http://repl.it's seems 2 not liek funcshuns.

(Tranzlashun generously providd by http://speaklolcat.com's robots cuz I doan speek lolcat)

---

Indented, spaced, and commented version of the code (LOLCODE comments start with BTW):

```
HAI BTW All LOLCODE programs start with HAI
    HOW DUZ I D C T BTW Function declarations follow the form "HOW DUZ I <func-name>[ <func-arg1>[ <func arg2>[ ...]]]". In this case, D is a function that repeats a YARN C (YARN is the equivalent of string in LOLCODE) NUMBR T (NUMBR = int) times.
        I HAZ A O BTW Variable declarations follow the form "I HAZ A <var-name>"

        I HAZ A N ITZ 0 BTW Variables can be intialised when declared by appending " ITZ <init-value>" to the declaration
        IM IN YR LOOP UPPIN YR N TIL BOTH SAEM N AN T BTW Loops follow the form "IM IN YR LOOP <action> TIL <condition>" where action and condition are "UPPIN YR N" and "BOTH SAEM N AN T", respectively, in this case
            O R SMOOSH O AN C MKAY BTW "R" assigns a new value to a variable. YARN (string) concatenation follows the form "SMOOSH <str-1> AN <str-2>[ AN <str-3>[...]] MKAY"
        IM OUTTA YR LOOP BTW "IM OUTTA YR LOOP" ends LOLCODE loops

        FOUND YR O BTW "FOUND YR <value>" returns a value
    IF U SAY SO BTW "IF U SAY SO" ends functions

    VISIBLE "" BTW "VISIBLE" prints its argument to stdout
    VISIBLE SMOOSH "  '\" AN D " " 19 AN ".  ." AN D " " 24 AN "|>18>>" MKAY BTW The function I wrote above only "pays off" in terms of characters added/saved when repeating 19 or more characters (the function call itself takes 8 characters, assuming a one-character first argument and a 2-digit second one; you need to factor in the added quotes (2 characters), spaces (4) and ANs (4) for 18 total extra characters; and possible SMOOSH/MKAY)
    VISIBLE "    \              .         ' .                   |"
    VISIBLE "   O>>         .                 'o                |"
    VISIBLE SMOOSH "    \       ." AN D " " 38 AN "|" MKAY
    VISIBLE SMOOSH "    /\    ." AN  D " " 40 AN "|" MKAY
    VISIBLE SMOOSH "   / /  .'" AN D " " 41 AN "|" MKAY
    VISIBLE SMOOSH "jgs^^^^^^^`" AN D "^" 51 MKAY
    VISIBLE ""
KTHXBYE BTW "KTHXSBYE" ends LOLCODE programs

```
> 4 votes

# Answer
# Python - ~~205~~ ~~203~~ 197

```
i="""
G^y`G^MsGgGj!G
G|!o'G.!H/!G/!M
G|!n.!J\G/!N
G|!l.!M\!N
G|!VoG'!W.!O>HO!M
G|!Y.!G'!O.!T\!N
G>H8G1G>G|!^.!H.!Y\G'!L
G""".replace('!','G ')
o=''
j=140
while j:j-=2;o+=ord(i[j+1])%70*i[j]
print o

```

The string `i` interleaves the characters in the ascii art with their multiplicites, represented as characters, all in in reverse order. In addition, I save a bit of space by using '!' instead of 'G ' in `i` and then just replacing it.
> 3 votes

# Answer
# Python (145)

```
'eJzjUgAB9RgFTKAHRthBjZ2hhZ0dF5SHphuhSx2rCTVQff52dlj0wPXm49IHtw+n83Do048hQRdCnz4QKuipE6sNqC8rvTgOAhLiSAdcAG/9Ri8='.decode('base64').decode('zip')

```

Not very original, I know.
> 3 votes

# Answer
# Javascript (*ES6*) 193 175 bytes

Edit: Modified RegPack v3 to maintain newlines, use a `for in` loop to save 3 bytes, and removed eval for implicit console output.

```
_="\nx'\\w{. z~|>18>>\n~\\~x.~ 'z{yx O>>~z 'owy~\\xzwxy~/\\{zw~yx / /  .'ww~ y jgs}`}}}}}}}^^\n~x  }^^^^^^^{   z .wy|\nx{{w~~";for(i of "wxyz{}~")with(_.split(i))_=join(pop())

```

# Using xem's unicode compression: 133 characters

```
eval(unescape(escape('').replace(/uD./g,'')))

```
> 2 votes

# Answer
## ES6, 155 chars

Just trying anorher approach:

Run this in Firefox's JS console.

Each unicode character has the following form: \uD8\[ascii charcode\]\uDC\[number of repeats\].

```
"".replace(/../g,a=>String.fromCharCode(a[c='charCodeAt']()&255).repeat(a[c](1)&255))

```

(Unicode string made with: http://jsfiddle.net/LeaS9/)
> 2 votes

# Answer
# PHP

Method 1, simpler (139 bytes):

Using a pre-deflated string.

```
<?=gzinflate(base64_decode('41IAA/UYBUygB0bYQY2doYWdHReMG4OhEwrUsRpRA9Pob2eHRRNccz5OjXAbcboQl0b9GBK0IWnUB0IFPXUFEjRmpRfHQUBCHOmACwA='));?>

```

Method 2, encoding runs of spaces into alphabet letters (192 bytes):

```
<?=preg_replace_callback('#[D-NP-Zu]#',function($e){return str_repeat('a'<$e[0]?'^':' ',ord($e[0])-66);},"
H'\U.D.Z|>18>>
J\P.K' .U|
IO>>K.S'oR|
J\I.WS|
J/\F.ZR|
I/ /D.'ZS|
 jgs^^^^^^^`u
")?>

```
> 2 votes

# Answer
## PowerShell, ~~192~~ ~~188~~ 119

```
 -join('̠§Üঠ®Ġ®ఠü¾±¸ľРÜܠ®Ҡ§ ®ঠüΠÏľҠ®ࢠ§ïࠠüРÜΠ®ጠüР¯ÜȠ®ᐠüΠ¯ ¯Ġ®§ᒠü êçóϞà᧞'[0..70]|%{"$([char]($_%128))"*(+$_-shr7)})

```

The part above contains a few non-characters. Hex dump:

```
00: 002D 006A 006F 0069 │ 006E 0028 0027 008A  -join('
10: 0320 00A7 00DC 09A0 │ 00AE 0120 00AE 0C20  ̠§Üঠ®Ġ®ఠ
20: 00FC 00BE 00B1 00B8 │ 013E 008A 0420 00DC  ü¾±¸ľРÜ
30: 0720 00AE 04A0 00A7 │ 00A0 00AE 09A0 00FC  ܠ®Ҡ§ ®ঠü
40: 008A 03A0 00CF 013E │ 04A0 00AE 08A0 00A7  ΠÏľҠ®ࢠ§
50: 00EF 0820 00FC 008A │ 0420 00DC 03A0 00AE  ïࠠüРÜΠ®
60: 1320 00FC 008A 0420 │ 00AF 00DC 0220 00AE  ጠüР¯ÜȠ®
70: 1420 00FC 008A 03A0 │ 00AF 00A0 00AF 0120  ᐠüΠ¯ ¯Ġ
80: 00AE 00A7 14A0 00FC │ 008A 00A0 00EA 00E7  ®§ᒠü êç
90: 00F3 03DE 00E0 19DE │ 0027 005B 0030 002E  óϞà᧞'[0.
A0: 002E 0037 0030 005D │ 007C 0025 007B 0022  .70]|%{"
B0: 0024 0028 005B 0063 │ 0068 0061 0072 005D  $([char]
C0: 0028 0024 005F 0025 │ 0031 0032 0038 0029  ($_%128)
D0: 0029 0022 002A 0028 │ 002B 0024 005F 002D  )"*(+$_-
E0: 0073 0068 0072 0037 │ 0029 007D 0029       shr7)})

```

Encoding scheme is RLE with the length encoded above the lower 7 bit, which are the character to display.
> 2 votes

# Answer
## JS (190b) / ES6 (146b) / ES6 packed (118chars)

Run this in the JS console:

JS:

```
"\n7'\\20.3.25|>18>>\n9\\15.10'2.20|\n8O>>10.9 9'o17|\n9\\8.39|\n9/\\5.41|\n8/2/3.'42|\n2jgs^^^^^^^`".replace(/\d+/g,function(a){return 18==a?a:Array(+a).join(' ')})+Array(51).join("^")+"\n"

```

ES6:

```
"\n6'\\19.2.24|>0>>\n8\\14.9'1.19|\n7O>>9.17'o16|\n8\\7.38|\n8/\\4.40|\n7/1/2.'41|\n1jgs58`101\n".replace(/\d+/g,a=>' ^'[a>51|0].repeat(a%51)||18)

```

ES6 packed: (http://xem.github.io/obfuscatweet/)

```
eval(unescape(escape('').replace(/uD./g,'')))

```

Thanks to @nderscore!
> 1 votes

# Answer
# Python - 236

```
s=' ';print('\n'+6*s+"'\\"+19*s+'.  .'+24*s+"|>18>>\n"+8*s+'\\'+14*s+'.'+9*s+"' ."+19*s+"|\n       O>>"+9*s+'.'+17*s+"'o"+16*s+'|\n'+8*s+"\\       ."+38*s+'|\n'+8*s+"/\\    ."+40*s+"|\n       / /  ."+42*s+"|\n jgs^^^^^^^`"+51*'^'+'\n')

```
> 1 votes

# Answer
## ES6, 163b / 127 chars

Yet another approach, thanks to @nderscore.

Execute it in Firefox's console

JS (163b):

```
"\n'\\..|>18>>\n\\. '.|\nO>>    .'o|\n\\.&|\n/\\.(|\n//.')|\njgs<`h\n".replace(/[^'`Og\n>\\,-8j-|]/g,a=>" ^"[a=a.charCodeAt(),a>53|0].repeat(a%53))

```

Packed (127c):

```
eval(unescape(escape('').replace(/uD./g,'')))

```
> 1 votes

# Answer
# Python, 70 UTF-16 chars

```
挣摯湩㩧呕ⵆ㘱䕂
print砧RԘꁌ䘇䇘鶍薡ᶝ谗ꚋꄝᵍᆫ〵ﺍ癶㑘㗁ࣔᆷ஧楱返䄡鈛絆吠叐嘧䠟噣煺М쐤ຑꀀ䜮'.decode(稧楬b')

```

Of course you're probably going to have to use the hex version:

```
23 63 6F 64 69 6E 67 3A 55 54 46 2D 31 36 42 45 0A 00 70 00 72 00 69 00 6E 00 74 00 27 78 9C E3 52 00 03 F5 18 05 4C A0 07 46 D8 41 8D 9D A1 85 9D 1D 17 8C 8B A6 1D A1 4D 1D AB 11 35 30 8D FE 76 76 58 34 C1 35 E7 E3 D4 08 B7 11 A7 0B 71 69 D4 8F 21 41 1B 92 46 7D 20 54 D0 53 27 56 1F 48 63 56 7A 71 1C 04 24 C4 91 0E 00 A0 2E 47 05 00 27 00 2E 00 64 00 65 00 63 00 6F 00 64 00 65 00 28 00 27 7A 6C 69 62 00 27 00 29 00

```

or the base64 version:

```
I2NvZGluZzpVVEYtMTZCRQoAcAByAGkAbgB0ACd4nONSAAP1GAVMoAdG2EGNnaGFnR0XjIumHaFNHasRNTCN/nZ2WDTBNefj1Ai3EacLcWnUjyFBG5JGfSBU0FMnVh9IY1Z6cRwEJMSRDgCgLkcFACcALgBkAGUAYwBvAGQAZQAoACd6bGliACcAKQA=

```

The first "line" of the program declares the UTF-16 encoding. The entire file is UTF16, but the Python interpreter always interprets the coding line in ASCII (it is `#coding:UTF-16BE`). After the newline, the UTF-16 text begins. It simply amounts to `print'<data>'.decode('zlib')` where the text is a deflated version of the target ASCII image. Some care was taken to ensure that the stream had no surrogates (which would ruin the decoding).
> 1 votes

# Answer
# C# - 354 332

```
using System;
using System.IO;
using System.IO.Compression;
class X
{
    static void Main(string[] args)
    {
        var x= Convert.FromBase64String("41IAA/UYBUygB0bYQY2doYWdHReMG4OhEwrUsRpRA9Pob2eHRRNccz5OjXAbcboQl0b9GBK0IWnUB0IFPXUFEjRmpRfHQUBCHOmAiwsA");
        Console.WriteLine(new StreamReader(new DeflateStream(new MemoryStream(x), CompressionMode.Decompress)).ReadToEnd());
    }
}

```

A bit golfed:

```
using System;using System.IO;using System.IO.Compression;class X{static void Main(){var x=Convert.FromBase64String("41IAA/UYBUygB0bYQY2doYWdHReMG4OhEwrUsRpRA9Pob2eHRRNccz5OjXAbcboQl0b9GBK0IWnUB0IFPXUFEjRmpRfHQUBCHOmAiwsA");Console.WriteLine(new StreamReader(new DeflateStream(new MemoryStream(x),(CompressionMode)0)).ReadToEnd());}}
```
> 1 votes

# Answer
**bzip2, 116**

After seeing the CJAM answer, I figured this one should qualify too.

```
$ wc -c golf.txt.bz2
116 golf.txt.bz2
$ bzip2 -dc golf.txt.bz2

  '\                   .  .                        |>18>>
    \              .         ' .                   |
   O>>         .                 'o                |
    \       .                                      |
    /\    .                                        |
   / /  .'                                         |
jgs^^^^^^^`^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

$

```

I doubt any further explanation is required. :)
> 1 votes

# Answer
# C (gcc), 190 bytes

```
r(n,c){while(n--)putchar(c);}f(c){for(char*s="F'\\S.B.X|>18>>\nH\\N.I' .S|\nGO>>I.Q'oP|\nH\\G.ZL|\nH/\\D.ZN|\nG/ /B.'ZN |\n jgs^^^^^^^`";c=*s++;)c>64&&c<91&&c^79?r(c-64,32):r(1,c);r(51,94);}

```

Try it online!
> 0 votes

# Answer
# Vim, 99 keystrokes

```
63i^<Esc>0R jgs<C-O>7l`<Esc>O<Esc>55I <Esc>A|<Esc>Y5PA>18>><Esc>7|R'\<Down>\<Down><Left><Left>O>><Down><Left><Left>\<Down>\<Down><Left><Left><Left>/<Up>/<Down>/<Right><Right>.'<Up>.<Right><Up>.<Right><Right><Up>.<Right><Right><Right><Up>.<Right><Right><Right><Up>.<Right><Right>.<Right><Right><Down>'<Right>.<Down><Right>'o

```

probably golfable

Explanation:

```
63i^<Esc>0R jgs<C-O>7l`<Esc>
Bottom line, 63 '^'s, replace the beginning with ' jgs', then move 7 caracters to the right and replace one character with '`'

O<Esc>55I <Esc>A|<Esc>
Above current line, add one line and insert 55 spaces, then a trailing '|'

Y5PA>18>><Esc>
Copy that line and paste it above five times. Cursor ends up in topmost line. Append '>18>>'

7|R'\<Down>\<Down><Left><Left>O>><Down><Left><Left>\<Down>\<Down><Left><Left><Left>/<Up>/<Down>/<Right><Right>.'<Up>.<Right><Up>.<Right><Right><Up>.<Right><Right><Right><Up>.<Right><Right><Right><Up>.<Right><Right>.<Right><Right><Down>'<Right>.<Down><Right>'o
Go to 7th column, enter Replace-mode, and replace spaces with golfer and golf ball trail. Arrow keys are used to move around, since it uses fewer keypresses to use the arrow keys instead of <C-o>+movement for up to three keypresses.

```
> 0 votes

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


title: Let's Play Mafia!

text:
# Question
Title: Let's Play Mafia!
Mafia (also known as Werewolf) is a party game that plays roughly like this:

* The game begins on day 0. After every day `n` comes a night `n`. After every night `n` comes a day `n+1`. i.e. `D0, N0, D1, N1, D2, N2`...
* At the dawn of day 0, a host secretly chooses players to fill certain roles:
    + Some number of players become the mafia. Every night, every mafioso chooses a player. At the dawn of the next day, the player chosen by the most mafiosos is killed. They are permanently removed from the game and their role is publicly revealed. Mafia-aligned.
    + Some number of players become cops. Every night, each cop chooses a player. At the dawn of the next day, the cop becomes aware of that players alignment. Village-aligned.
    + Some number of players become doctors. Every night, each doctor chooses a player. If this player is the same player that the mafia chose to kill, the mafia's actions for that night are canceled. Village-aligned.
    + All players who aren't chosen for another role are villagers. Villagers have no abilities that aren't shared by the whole town. Village-aligned.
* Every day except day 0, the entire town (that is, all living players) votes for a player. At the end of the day, that player is removed from the game and their role is revealed. (On day 0, everyone just chills until nightfall.)
* If, at any point, there are no remaining mafiosos, the game ends with all village-aligned players victorious (including the dead).
* If, at any point, the village-aligned players do not outnumber the mafia-aligned players, the game ends with all mafia-aligned players victorious (including the dead).

For this challenge, your goal is to write a bot to beat other bots at Mafia!

**How to make a working bot**

All you *have* to supply for me is a file called `run`. Inside the directory structure where this challenge will take place, your bot will live here:

```
start
controller/
tmp/
players/               # You are here!
    some_bot/          # Let's pretend you're some_bot.
        to_server
        from_server
        players
        run            # This is what you give me
    mafia-game-bot/
    skynet/

```

The `run` file, when executed, will make your bot do its thing. It's important to note that this file must not require any command line arguments or anything. It will be run exactly as `./run`. If you need to be executed in a different way, you'll have to work around it by doing something like this:

`real_bot.py`

```
#!/bin/python2

# code goes here

```

`run`

```
#!/bin/bash

./real_bot.py --flags --or --whatever

```

An important thing to note is that all input your bot receives will be found in the file `from_server` and the control program will look for your bot's output in `to_server`. I chose to do it this way so that any language that can do file I/O is able to participate. If your language makes it easier to work with stdin and stdout than file I/O, you may want to write a `run` file that looks like this:

```
#!/bin/bash

./real_bot.py < from_server > to_server

```

This will make it so that stdin comes from the `from_server` file and stdout goes directly to `to_server`.

Your bot will not stay running for the duration of the game. Instead, it will be run when it needs to make a decision. Likewise, it will not be informed when it's dead, it just won't be run anymore. Plan for this by saving anything you want to remember to a file and reading it later. You may create, write to or read from any file in your bot's folder, but **you may not write or read *anywhere* outside of that folder, including network access or anything**. If your bot knows *anything* that it wasn't told from inside the folder, or if it touches *anything* that isn't inside that folder, your bot is disqualified.

**How to make a *functional* bot**

*Day*

At the beginning of the game, the file `players` will be filled with a newline-delimited list of all players in the game. It will not be updated as players leave the game.

At the dawn of day 0, all players will find this message in their `from_server` file:

```
Rise and shine! Today is day 0.
No voting will occur today.
Be warned: Tonight the mafia will strike.

```

If you are the cop, the line `You are the cop` is appended to the end. The doctor sees `You are the doctor`. The mafia sees `You are a member of the mafia.\nYour allies are:` and a newline-delimited list of mafia members, excluding the player reading the message.

At the dawn of all other days, this message will appear:

```
Dawn of day `day_number`.
Last night, `victim` was killed. They were `victim_role`.
Investigations showed that `cop_target` is `target_alignment`-aligned.
These players are still alive: `remaining_players`

```

`dayNumber` is replaced with the number of the day. `victim` is replaced with the name of last night's victim, and `victim_role` is one of:

* `a villager`
* `a mafioso`
* `the cop`
* `the doctor`

`cop_target` is the name of the player the cop investigated last night, and `target_alignment` is either `village` or `mafia`. Finally, `remaining_players` is a list of players that are still alive in this format: `player1, player2, player3`

The second line is omitted if there was no kill last night, and the third line is shown only to the cop.

For example,

```
Dawn of day 42.
Last night, Xyzzy was killed. They were a villager.
Investigations showed that Randy is mafia-aligned.
These players are still alive: Randy, CopBot, JohnDoe, Steve

```

Once this message is out of the way, the day begins! Each bot can make 50 actions throughout the day, where an "action" is voting for a player or saying something out loud.

To vote for a player, write `vote player_name` to your `to_server` file and terminate. To vote to not kill anyone, write `vote no one`. When you vote, all players (including you) will see `your_bot votes to kill your_selection`. Votes are ignored on day 0.

A number of pre-defined messages can be sent to all players. The id of each possible message is listed here:

```
 0: No
 1: Yes
 2: I am the cop
 3: I am the doctor
 4: I am a normal villager
 5: I trust this player:
 6: I think this player is suspicious:
 7: I think this player is the cop:
 8: I think this player is the doctor:
 9: I think this player is a normal villager:
10: I think this player is mafia:
11: Do you think this player is mafia?
12: I tried to save this player:
13: I successfully saved this player:
14: I investigated this player and found that they were mafia-aligned:
15: I investigated this player and found that they were village-aligned:
16: Will you please use your power on this player tonight?

```

All of these messages except the first five are referring to a specific player. To say one of those messages, write `say message_id player_name`. For one of the first five messages, just write `say message_id`. You may add an optional third argument to both of these, specifying the name of a player you're talking to (all players can still read it, but they'll know who the intended recipient is).

When your bot says a message, all players read `your_bot says "message"`, where `message` is the message associated with the id you wrote. If the message includes a subject, one space character and the subject are inserted directly after the end of the message. If it includes a recipient, their name, one colon and one space character are inserted immediately before the message.

At the end of the day, all living players are run one last time to see the result of the vote. If a player was voted out, this is written:

```
The town has killed player_name!
They were a villager

```

... or `a mafioso`, or `the cop`, or `the doctor`.

If no player was voted out, this is written instead:

```
The town opted to lynch no one today.

```

When the controller sends these messages, it ignores any response from players. The day is over.

*Night*

At night, everyone but the villagers get to use their power.

**Mafia:**

You will read `It is night. Vote for a victim.`. When this happens, output the name of the player you'd like to kill.

**Cop:**

You will read `It is night. Who would you like to investigate?`. When this happens, output the name of the player you'd like to check.

**Doctor:**

You will read `It is night. Who would you like to save?`. When this happens, output the name of the player you'd like to protect.

After this, the next day begins as normal.

You may save yourself only once per game.

**General Information**

* The game will not run without 6 or more players.
* One third of the players, rounded down, will be mafia. One player will be a doctor, and one player will be a cop. All other players are villagers.
* Ties in the village vote or the mafia's overnight vote are settled randomly.
* Bot names must be alphanumeric + dashes and underscores.
* It is forbidden to use knowledge of opponent's code directly. In theory, I should be able to put your bot up against bots you've never seen before and have it perform comparably.
* Regrettably, if I can't get your program running using exclusively free (as in beer) software, I'll have to disqualify it.
* I reserve the right to disqualify any submission if I believe it to be malicious. This includes, but is not limited to using excessive abouts of time, memory or space to run. I've intentionally left the limit soft, but remember: I'm running this on my home computer, not a supercomputer, and I don't want getting results to take a year. I don't expect to have to use this, since my standards are pretty low. This is basically "if I think you're being a dick on purpose", and if you can convince me otherwise I'll reverse my decision.

**Scoring**

Each round, 100 games will be run (this may increase as more bots join to keep the sample size large enough, but in theory that won't affect anything). I will record how many times each bot wins as a villager compared to how many times it plays as a villager, and the same for mafia. A bot's `villager_ratio` is `number of games won as villager / number of games played as villager`, and `mafia_ratio` is the same but `s/villager/mafia/g`. A bot's score is `(villager_ratio - mean villager_ratio) + (mafia_ratio - mean mafia_ratio)`.

**Example bot**

Randy the Robot is not a good mafia player. Randy ignores pretty much everything, randomly choosing what to say, who to vote for, and who to target with night powers.

`run.sh`:

```
#!/bin/bash

./randy.py < from_server > to_server

```

`randy.py`:

```
#!/usr/bin/env python

import random

with open('players') as f:
    p = f.read().split() + ['no one']

day = True
try:
    line = raw_input()
    if line.endswith(('?', 'victim.')):
        day = False
    if not day:
        print random.choice(p)
    else:
        if random.random() > 0.5:
            if random.random() > 0.5:
                print 'vote {}'.format(random.choice(p))
            else:
                id = random.randint(0, 17)
                print 'say {}{}'.format(id, (' ' + random.choice(p)) if id > 4 else '')
except: pass

```

## Controller

@undergroundmonorail wrote a control program for this challenge, available here.

You have one month to code and turn in answers, I will give the winning bot (highest win rate tie breaker is votes) at least a 50 reputation bounty (depending on how much rep I can earn in a month)

---

Here is a wrapper script, made by @Blacksilver, to use with compiled languages:

```
#!/bin/bash

run="./a.out"
compile="gcc bot.c"

if [ -e $run ]; then
        $run
else
        $compile
        $run
fi

```

Put this in `run`.

---

This post was written by @undergroundmonorail (I made a few edits).

He gave it up here to anyone who wanted to finish and post it.

# Answer
> 3 votes
# Zulu

`run`

```
#!/usr/bin/env php
<?php
error_reporting(E_ERROR|E_WARNING|E_PARSE);

$self = basename(__DIR__);

$msgids = array(
    "No",
    "Yes",
    "I am the cop",
    "I am the doctor",
    "I am a normal villager",
    "I trust this player:",
    "I think this player is suspicious:",
    "I think this player is the cop:",
    "I think this player is the doctor:",
    "I think this player is a normal villager:",
    "I think this player is mafia:",
    "Do you think this player is mafia?",
    "I tried to save this player:",
    "I successfully saved this player:",
    "I investigated this player and found that they were mafia-aligned:",
    "I investigated this player and found that they were village-aligned:",
    "Will you please use your power on this player tonight?"
);
$msgids = array_flip($msgids);

if(!file_exists('./from_server')){
    die;
}
$in = file('from_server');
if(count($in) && strpos($in[0],'day 0.') !== false){
    $game = array(
        'day'               =>0,
        'players'           =>array(),
        'alive'             =>array(),
        'dead'              =>array(),
        'mafia'             =>array(),
        'village'           =>array(),
        'cop'               =>'',
        'doctor'            =>'',
        'votes'             =>array(),
        'messages'          =>array(),
        'currentvotes'      =>array(),
        'currentmessages'   =>array()
    );
    $playersfile = file('players');
    foreach($playersfile as $name){
        $game['players'][trim($name)] = 1;
        $game['alive'][trim($name)] = 1;
        $game['votes'][trim($name)] = array();
        $game['messages'] = array();
    }
    $allies = false;
    foreach($in as $line){
        if($allies){
            if(array_key_exists(trim($line),$game['players'])){
                $game['mafia'][trim($line)] = 1;
            }
        }
        else if(strpos($line,"You are the cop") !== false){
            $game['cop'] = $self;
            $game['village'][$self] = 1;
        }
        else if(strpos($line,"You are the doctor") !== false){
            $game['doctor'] = $self;
            $game['village'][$self] = 1;
        }
        else if(strpos($line,"member of the mafia") !== false){
            $game['mafia'][$self] = 1;
        }
        else if(strpos($line,"allies are:") !== false && $game['mafia'][$self]){
            $allies = true;
        }
    }
    if(!$game['mafia'][$self]){
        $game['village'][$self] = 1;
    }
    else{
        foreach($game['players'] as $name=>$g){
            if(!$game['mafia'][$name]){
                $game['village'][$name] = 1;
            }
        }
    }
    $out = json_encode($game);
    write('myinfo',$out);
}
else{
    $myinfo = file_get_contents('myinfo');
    $game = json_decode($myinfo,true);
    if(count($in) && strpos($in[0],"town has killed") !== false){
        $e = explode(" ",trim($in[0]));
        $dead = trim($e[4],'!');
        unset($game['alive'][$dead]);
        $game['dead'][$dead] = 1;
        $e = explode(" ",trim($in[1]));
        $allegiance = trim($e[3],".");
        $game[$allegiance][$dead] = 1;
    }
    else if(count($in) && strpos($in[0],"town opted to") !== false){
        //
    }
    else if(count($in) && strpos($in[0],"night") !== false){
        if(strpos($in[0],"victim") !== false){
            $voted = false;
            if($game['day'] > 0){
                $possible = array();
                foreach($game['alive'] as $name=>$g){
                    if(!$game['mafia'][$name]){
                        foreach($game['votes'][$name] as $for){
                            if($voted && $game['mafia'][$for]){
                                $possible[] = $name;
                            }
                        }
                    }
                }
                if(count($possible)){
                    shuffle($possible);
                    write('to_server',$possible[0]);
                    $voted = 1;
                }
            }
            if(!$voted){
                while($rand = array_rand($game['alive'])){
                    if(!$game['mafia'][$rand]){
                        write('to_server',$rand);
                        $voted = 1;
                        break;
                    }
                }
            }
        }
        else if(strpos($in[0],"investigate") !== false){
            $possible = array();
            foreach($game['alive'] as $name=>$g){
                if(!$game['village'][$name] && !$game['mafia'][$name] && $game['doctor'] != $name){
                    $possible[] = $name;
                }
            }
            if(count($possible)){
                shuffle($possible);
                write('to_server',$possible[0]);
            }
        }
        else if(strpos($in[0],"save") !== false){
            if($game['day'] == 0){
                write('to_server',$self);
            }
            else{
                if($game['cop'] != '' && $game['alive'][$game['cop']]){
                    write('to_server',$game['cop']);
                }
                else{
                    $voted = false;
                    foreach($game['alive'] as $name=>$g){
                        if($game['village'][$name] && $name != $self){
                            write('to_server',$name);
                            $voted = true;
                            break;
                        }
                    }
                    if(!$voted){
                        while($rand = array_rand($game['alive'])){
                            if($rand != $self){
                                write('to_server',$rand);
                                break;
                            }
                        }
                    }
                }
            }
        }
    }
    else if(count($in) && strpos($in[0],"Dawn of day") !== false){
        $e = explode(" ",trim($in[0]));
        $game['day'] = trim($e[3],".");
        foreach($in as $line){
            if(strpos($line,"was killed") !== false){
                $e = explode(" ",trim($line));
                $dead = $e[2];
                if(strpos($line,"the cop") !== false){
                    $game['cop'] = $dead;
                    $game['village'][$dead] = 1;
                }
                else if(strpos($line,"the doctor") !== false){
                    $game['doctor'] = $dead;
                    $game['village'][$dead] = 1;
                }
                else if(strpos($line,"a villager") !== false){
                    $game['village'][$dead] = 1;
                }
                else if(strpos($line,"a mafioso") !== false){
                    $game['mafia'][$dead] = 1;
                }
                unset($game['alive'][$dead]);
                $game['dead'][$dead] = 1;
            }
            else if(strpos($line,"Investigations showed") !== false){
                $e = explode(" ",trim($line));
                $name = $e[3];
                $align = trim($e[5]);
                $e = explode("-",$align);
                $game[$e[0]][$name] = 1;
            }
        }
        $game['currentvotes'] = array();
        $game['currentmessages'] = array();
        foreach($game['alive'] as $name=>$g){
            $game['currentvotes'][$name] = '';
        }
    }
    else{
        foreach($in as $line){
            if(strpos($line," has voted to lynch no one") !== false){
                $e = explode(" ",trim($line));
                $game['votes'][$e[0]][] = false;
                $game['currentvotes'][$e[0]] = false;
            }
            else if(strpos($line," has voted to ") !== false){
                $e = explode(" ",trim($line));
                $game['votes'][$e[0]][] = trim($e[5]," .");
                $game['currentvotes'][$e[0]] = trim($e[5]," .");
            }
            else if(strpos($line," says ") !== false){
                foreach($msgids as $msg=>$id){
                    $chk = preg_match('/([^\s]+) says "(([^\s]+)[:,] )?'.preg_quote($msg).'( ([^\s]+))?"/',$line,$matches);
                    if($chk){
                        //                                  said by     said to     said  said about
                        $game['messages'][]         = array($matches[1],$matches[3],$msg, $matches[5]);
                        $game['currentmessages'][]  = array($matches[1],$matches[3],$msg, $matches[5]);
                    }
                }
            }
        }
        $written = false;
        $convo = array();
        foreach($game['currentmessages'] as $msg){
            if($msg[1] == $self){
                $convo[$msg[0]] = $msg;
            }
            else if($msg[0] == $self && $msg[1] != ''){
                unset($convo[$msg[1]]);
            }
        }
        if(count($convo)){
            foreach($convo as $c){
                if($msgids[$c[2]] == 11){
                    if($game['mafia'][$msg[3]]){
                        write('to_server',"say 1 ".$msg[0]);
                        $written = true;
                        break;
                    }
                    else if($game['village'][$msg[3]]){
                        write('to_server',"say 0 ".$msg[0]);
                        $written = true;
                        break;
                    }
                    else{
                        write('to_server',"say 11 ".$msg[0]);
                        $written = true;
                        break;
                    }
                }
                else if($msgids[$c[2]] == 16){
                    write('to_server',"say 0 ".$msg[0]);
                    $written = true;
                }
                else{
                    write('to_server',"say 4 ".$msg[0]);
                    $written = true;
                }
            }
        }
        if(!$written){
            $currentvote = false;
            if(array_key_exists($self,$game['currentvotes'])){
                $currentvote = $game['currentvotes'][$self];
            }
            if($game['mafia'][$self]){
                $votes = @array_count_values($game['currentvotes']);
                if($votes && count($votes)){
                    arsort($votes);
                    foreach($votes as $name=>$number){
                        if($game['village'][$name]){
                            if($currentvote != $name){
                                write('to_server','vote '.$name);
                                $written = true;
                                break;
                            }
                        }
                    }
                }
            }
            else{
                if(count($game['mafia'])){
                    foreach($game['mafia'] as $name=>$g){
                        if($game['alive'][$name]){
                            $written = true;
                            if($currentvote != $name){
                                write('to_server','vote '.$name);
                            }
                            break;
                        }
                    }
                    if(!$written){
                        foreach($game['mafia'] as $name=>$g){
                            $non = $game['alive'];
                            unset($non[$self]);
                            if(array_key_exists($name,$game['votes'])){
                                foreach($game['votes'][$name] as $vote){
                                    if(array_key_exists($vote,$non)){
                                        unset($non[$vote]);
                                    }
                                }
                            }
                            if(count($non)){
                                $rand = array_rand($non);
                                write('to_server','vote '.$rand);
                                $written = true;
                                break;
                            }
                        }
                    }
                }
                if(!$written && $game['cop']){
                    $possible = array();
                    foreach($game['votes'][$game['cop']] as $name){
                        if($game['alive'][$name] && $name != $self){
                            $possible[] = $name;
                        }
                    }
                    if(count($possible)){
                        shuffle($possible);
                        write('to_server','vote '.$possible[0]);
                        $written = true;
                    }
                }
                if(!$written && count($game['dead'])){
                    foreach($game['dead'] as $name=>$g){
                        if($game['village'][$name]){
                            $v = array();
                            foreach($game['votes'] as $voted=>$arr){
                                if($game['alive'][$voted] && in_array($name,$arr)){
                                    $v[$voted] = 1;
                                }
                            }
                            unset($v[$self]);
                            if(count($v)){
                                $rand = array_rand($v);
                                write('to_server','vote '.$rand);
                                $written = true;
                                break;
                            }
                        }
                    }
                }
                if(!$written){
                    $votes = @array_count_values($game['currentvotes']);
                    if($votes && count($votes) && array_key_exists($self,$votes)){
                        arsort($votes);
                        foreach($votes as $name=>$number){
                            if(!$game['village'][$name]){
                                if($name != $self){
                                    write('to_server','vote '.$name);
                                    $written = true;
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    $myinfo = json_encode($game);
    write('myinfo',$myinfo);
}

function write($filename,$data){
    $fh = fopen($filename,"wb+");
    if($fh){
        $bytes = fwrite($fh,$data);
        fclose($fh);
    }
}

```

Not everything I hoped it would be. I may end up tweaking it occasionally.

## How it works v1.0

Keeps track of day number, who is alive, who is dead, who is mafia, who is village-aligned, roles, current day votes/messages, and overall votes/messages.

1. Night

a. Mafia - Vote for any villager who has voted against mafia (randomly) if possible, otherwise a random villager.

b. Cop - Investigate anyone who is of unknown alignment.

c. Doctor - Save self first turn, then save cop if known (I don't think it can ever know this as of now), save villager if known (probably doesn't know this either), otherwise save random person.
2. Day

a. If anyone has spoken a message directly to self, respond to them (limited responses possible).

b. Mafia - Vote for the villager who has the most votes.

c. Villager with any alive Mafia-aligned known - vote for mafioso.

d. Villager with only dead Mafia-aligned known - vote for a random bot who has never voted for the mafioso.

e. Villager with Cop known - vote for random bot the cop has voted for.

f. Villager with dead Village-aligned known - vote for a random bot who voted for the dead.

g. Villager with votes against self - vote for the highest currently voted non-village-aligned bot.

# Answer
> 6 votes
The example code didn't worked for me, I use Python 3, so I changed the `main.py` file to make it work.

So here is my fixed version for Python 3, I never programmed in Python before so maybe it is a horrible code but it is works :)

`run.sh`:

```
#!/bin/bash

./randy.py < from_server > to_server

```

`randy.py`:

```
#!/usr/bin/env python3

import random

with open('players') as f:
    p = f.read().split() + ['no one']

with open('from_server') as f:
    fs = f.read().split()

msg = ""
day = True
try:
    line = fs[0]
    if line.endswith(('?', 'victim.')):
        day = False
    if not day:
        msg = (random.choice(p))
    else:
        if random.random() > 0.5:
            if random.random() > 0.5:
                msg = ('vote {}'.format(random.choice(p)))
            else:
                id = random.randint(0, 17)
                msg = ('say {}{}'.format(id, (' ' + random.choice(p)) if id > 4 else ''))

    with open('to_server', 'w') as f:
        f.write(msg)
    print(msg)
except: pass

```

A few thing I learned while I made this work (and it was not clear for me in the description)

* `print` does not do anything with the game it is like a `console.log` in js
* `input()` blocks the program running it can be good for step by step debugging
* `from_server` and `to_server` is cleared every round.
* It is impossible to stop the script with `Ctrl+C` combination, which is annoying.

# Answer
> 5 votes
# The Logician

```
#!/usr/bin/env python3
import sys
import os
import re
import random
from types import SimpleNamespace
def chooseSet(set):
    return random.choice(list(set))
sys.stdin = open("from_server")
sys.stdout = open("to_server","w")
def saveData(data):
    with open("gameData.txt", "w") as datafile:
        datafile.write(repr(data.__dict__))
MY_NAME = os.path.basename(os.getcwd())
opener = input()
DATABASES = ("targets","herd","mafiosos","guilty","innocent","unlikely", "requests",
            "selfvotes","players","used_roles")
ALLOW_SELF = ("players", "mafiosos")
LIESPERROLE = {"cop": ("I am the cop",
                "I investigated this player and found that they were mafia-aligned",
                "I investigated this player and found that they were village-aligned"),
              "doctor": ("I am the doctor",
                   "I tried to save this player",
                   "I successfully saved this player"
                   )
        }
#1: At the beginning of the game, parse beginning of day 0
if opener == "Rise and shine! Today is day 0.":
    #Next two lines are completely predetermined and hold no data
    assert input() == "No voting will occur today."
    assert input() == "Be warned: Tonight the mafia will strike."
    data = SimpleNamespace(cop=False, doctor=False, queued=[],askers={})
    for datum in DATABASES:
        setattr(data, datum, set())
    try:
        nextline = input()
        if nextline == "You are a member of the mafia.":
            data.mafiosos.add(MY_NAME)
            assert input() == "Your allies are:"
            while True:
                data.mafiosos.add(input())
        elif nextline == "You are the doctor":
            data.doctor = True
            data.used_roles.add("doctor")
        elif nextline == "You are the cop":
            data.cop = True
            data.used_roles.add("cop")
    except EOFError:
        #villager, or ran out of mafiosos to add
        pass
    with open("players") as playersfile:
        data.players = set(playersfile.read().strip().splitlines())
    saveData(data)
    exit()
with open("gameData.txt") as datafile:
    data = SimpleNamespace(**eval(datafile.read().strip()))
#2: Beginning of day nonzero
if opener.startswith("Dawn of day"):
    data.requests.clear()
    data.selfvotes.clear()
    data.askers.clear()
    data.voted = False
    try:
        while True:
            nextline = input()
            victim = re.match("Last night, (.*) was killed. They were (?:a|the) (.*).", nextline)
            if victim:
                victim, role = victim.groups()
                #remove dead people from lists
                for datum in DATABASES:
                    getattr(data, datum).discard(victim)
                if role == "cop" or role == "doctor":
                    data.used_roles.add(role)
                continue
            investigated = re.match("Investigations showed that (.*) is (.*)-aligned.", nextline)
            if investigated:
                assert data.cop
                who = investigated.group(1)
                if investigated.group(2) == "mafia":
                    data.guilty.add(who)
                    data.unlikely.discard(who)
                else:
                    data.targets.discard(who)
                    data.herd.discard(who)
                    data.innocent.add(who)
                    data.unlikely.add(who)
                continue
    except EOFError:
        pass
#3: We're being told some messages / news
elif " says " in opener or " voted " in opener:
    message = opener
    acted = question = False
    try:
        while True:
            if " voted " in message:
                message = "<vote against>"
                speaker, subject = re.match("(.*) has voted to lynch (.*)", message).groups()
                target = None
            else:
                speaker, target, message, subject = \
                    re.match("(.*) says \"(?:(.*), )?([^:\?]+)(?:[:\?]\s*(.*))?\"",
                             message).groups()
            if speaker == MY_NAME:
                continue
            BAD_MESSAGES = ("<vote against>", "I think this player is mafia",
                            "I investigated this player and found that they were mafia-aligned",
                            "I think this player is suspicious")
            GOOD_MESSAGES = ("I think this player is the cop",
                             "I think this player is the doctor",
                             "I think this player is a normal villager",
                             "I trust this player",
                             "I investigated this player and found that they were village-aligned")
            OUTS = "I am the cop", "I am the doctor"
            LIES = ()
            for role in data.used_roles:
                LIES += LIESPERROLE[role]
            if message == "Yes" or message == "No":
                if question and not target:
                    target = chooseSet(data.askers)
                if target in data.askers:
                    BAD_MESSAGES += "Yes",
                    GOOD_MESSAGES += "No",
                    subject = data.askers[target]
            if message in LIES and speaker not in data.mafiosos and speaker not in data.innocent:
                # What you just said is false, and I know it!
                data.unlikely.discard(speaker)
                data.targets.add(speaker)
                if subject and subject not in (data.unlikely.union(data.mafiosos)):
                    data.targets.add(subject)
            elif message in BAD_MESSAGES:
                if speaker in data.guilty:
                    #mafiosos rarely turn on eachother
                    data.unlikely.add(subject)
                    data.targets.discard(subject)
                elif speaker in data.unlikely:
                    #believe the herd, especially people who we trust
                    data.herd.add(subject)
                elif subject in data.unlikely:
                    #how dare you speak against players likely to be village-aligned!
                    data.targets.add(speaker)
                elif subject == MY_NAME or subject in data.mafiosos:
                    #DON'T ATTACK ME (or my fellow mafiosos)
                    data.targets.add(speaker)
                else:
                    #believe the herd
                    data.herd.add(subject)
                if not acted and message == "<vote against>":
                    if subject == MY_NAME:
                        data.selfvotes.add(speaker)
                        if len(data.selfvotes) >= (len(data.players)-len(data.mafiosos))/3:
                            if data.cop:
                                print("say 2")
                                #give a data point to prove it
                                if random.random() > .5 and data.guilty:
                                    data.queued.append("say 14 %s" % chooseSet(data.guilty))
                                elif data.innocent:
                                    data.queued.append("say 15 %s" % chooseSet(data.innocent))
                            else:
                                print("say 4") #Don't out myself if I'm the doctor
                                # and just lie if I'm a mafioso
                            acted = True
                    else:
                        data.selfvotes.discard(speaker)
            elif message in OUTS and data.mafiosos and speaker not in data.unlikely:
                data.targets.add(speaker) #Kill the fools who boast!
            elif message in GOOD_MESSAGES:
                chance = random.random() < .1 - (speaker in data.targets) / 20
                if speaker in data.guilty: #Mafia liars
                    if subject not in data.unlikely:
                        data.targets.add(subject)
                elif subject == MY_NAME and chance:
                    if speaker in data.targets:data.targets.remove(speaker)
                    data.unlikely.add(speaker)
                elif speaker in data.unlikely or chance:
                    data.unlikely.add(subject)
            elif message == "Do you think this player is mafia":
                if subject == MY_NAME:
                    data.targets.append(speaker)
                if target == MY_NAME or not target:
                    if speaker in data.guilty:
                        data.queued.append("say 14 %s %s" % (subject, speaker))
                    elif speaker in data.innocent:
                        data.queued.append("say 15 %s %s" % (subject, speaker))
                    elif subject in data.targets or subject in data.herd:
                        data.queued.append("say 1 %s" % (speaker))
                    elif subject in data.unlikely:
                        data.queued.append("say 0 %s" % (speaker))
                    if data.cop:
                        data.requests.add(subject)
                data.askers[speaker] = subject
                question = True
            elif target == MY_NAME and message == "Will you please use your power on this player tonight":
                data.requests.add(subject)
            message = input()
    except EOFError:
        pass
    for datum in DATABASES:
        if datum in ALLOW_SELF: continue
        getattr(data, datum).discard(MY_NAME)
    chance = random.random()
    if data.queued:
        print(data.queued.pop())
    elif chance < .1:
        target = chooseSet(data.targets or data.players)
        if target != MY_NAME:
            print("say 10 %s" % target)
            data.askers[MY_NAME] = target
    elif chance < .3 and data.targets:
        print("say 6 %s" % chooseSet(data.guilty or data.targets))
    elif chance < .5 and data.unlikely:
        print("say 5 %s" % chooseSet(data.innocent or data.unlikely))
    elif chance < .6 and not data.voted:
        target = chooseSet(data.guilty or data.targets or data.herd or data.players)
        if target not in data.mafiosos and target != MY_NAME:
            print("vote %s" % target)
        data.voted = True
    elif chance < .8:
        #do nothing
        pass
    elif chance < .9:
        #Confuse everybody
        print("say 1")
        data.queued.append("say 0")
######################
#4: End of day
elif "has killed" in opener:
    victim = re.match("The town has killed (.*)!", opener)
    if not victim:
        exit()
    victim = victim.group(1)
    #remove dead people from lists
    for datum in DATABASES:
        getattr(data, datum).discard(victim)
    role = input()
    role = re.match("They were (?:a|the) (.*)", role).group(1)
    if role == "cop" or role == "doctor":
        data.used_roles.add(role)
    #Misc: purge people from lists if too large
    for list in data.unlikely, data.targets, data.herd:
        while len(list) > len(data.players)/3:
            list.pop()
    for player in data.innocent:
        data.unlikely.add(player)
elif opener == "The town opted to lynch no one today.":
    #Do nothing
    pass
#5: Night
elif "night" in opener:
    if not data.mafiosos and data.requests and random.random() > .5:
        print(chooseSet(data.requests))
    if data.doctor:
        print(chooseSet(data.unlikely or data.players))
    else:
        while True:
            try:
              target = (data.targets or data.herd).pop()
            except KeyError:
              target = chooseSet(data.players)
            if target in data.mafiosos or target == MY_NAME:
                continue
            print(target)
            break
else:
    raise ValueError("Unknown message")
saveData(data)

```

Fancy, long bunch of python code that I'm not going to explain (although it isn't golfed), other than that it keeps lists of "friends" and "enemies" that are originally populated based on chance and/or cop investigation. Warning: do not lie in the logician's presence.

# Answer
> 4 votes
# Survivalist (v 1.0)

**Synopsis**

Survivalist simply brutally survives the game by berating anyone that dares to accuse him, regardless of whether he is mafia or not.

**Logic**

If you survive to the end of the game, you win no matter what. Therefore, you survive at all costs.

**Backstory**

The troops marched through the dark, damp forest.

"Lieutenant, where are we marching?" The young recruit apparently hadn't hardened himself to atrocities, the commander thought. Oh well. He answered with a brusque "to destroy the enemy".

At the village, the enemy commander was drinking and laughing along with the other officers at the club when a scout rushed in with the news. "There's a column, several hundred yards long, marching through the Yulin forest for us! Rally the troops!"

The enemy commander, obviously inebriated, said unexpectedly, "I've had no reports from other scouts." The scout (later Survivalist) thought, *then I'll have to rally the troops myself*. After telling the story to the fellow scouts, they came back together, all saying that they had seen enemy troops. The commander still did not believe, saying, "I am *ordering* you to discontinue scouting. There are *no* enemy troops".

The scouts decided to get their weapons to save the community. They managed to get to their positions just as the enemy arrived in the village in force. "CHARGE!" yelled the commander of the ambush. "BURN THE HOUSES! **BURN THE HOUSES! KILL EVERYONE, INCLUDING THE WOMEN AND THE CHILDREN!**"

The scouts saved their entire army. They expected promotion, awards, and medals. Instead, they got a rigged court-martial for mutiny, conviction, 10 years in prison, dishonorable discharge from the military and exile.

---

There is an old elder at the city council of Salem, Massachusetts. Legend has it that he founded the town. When you meet him in his isolated cottage out in the forest, don't let the twinkle in his eye make you think he's peaceful. If you accuse him, he will ruin you in front of the town.

> The Veteran laughed in the darkness. Afraid of the dark, no way. Afraid of monsters under the bed? The man with his hand on trigger of a gun laughed nervously. He wasn't scared of anything, he had told himself. Sure, he was a past war time hero, but he was so used to ambushes and life threatening situations that it made the man simply neurotic. His trigger finger twitched at simple shadows; his heartbeat quickened with every little sound. Yes, he was this scared of death. How could he not, seeing so many people die in horrible ways? All he knew from being kidnapped and miraculously escaping his enemies was that there was no mercy.

Veteran

---

**Code (I'm a rookie in python, not sure if the code is good)**

```
#!/bin/python2

import random

with open('players') as f:
    p = f.read().split() + ['no one']

day = True
target = "survivalist"
role = "villager"
try:
    line = raw_input()
    if "You are the cop" in line:
        role = "cop"
    else if "You are the doctor" in line:
        role = "doctor"
    else if "You are a member of the mafia" in line:
        role = "mafia"

    if line.endswith(('?', 'victim.')):
        day = False
    if not day:
        if target == "survivalist":
            print random.choice(p)
        else if role == mafia || role == sheriff:
            print target
        else if role == doctor:
            print random.choice(p)
    else:
        if "survivalist" in line && ("I think this player is suspicious:" in line ||
        "I think this player is mafia:" in line ||
        "I investigated this player and found that they were mafia-aligned:")):
            print 'say 0'
            if role == "villager" || role == "mafia":
                print 'say 4'
            else if role == "cop":
                print 'say 2'
            else if role == "doctor"
                print 'say 3'
            target = line.split(" ")[0]
            print 'vote ' + target

        else if target != "survivalist":
            print 'say 6 ' + target
            print 'vote ' + target
    else:
        pass

except: pass

```

# Answer
> 3 votes
# Avatar

Avatar "randomly" picks one player at the start and relentlessly focuses them for the rest of the round.

This is not a reference to a similarly-named animated TV show.

> It's an EVE online refrence.

Download tar of all required files

## Changelog

* **v1** Birthday
* **v2** Doesn't log anything to `stdout`, only to `stderr`.
To suppress `stderr` too, add `2>/dev/null` to the end of the `run` file.

```
/*  Casting his sight on his realm, the Lord witnessed
    The cascade of evil, the torrents of war.
    Burning with wrath, He stepped
    down from the Heavens
    To judge the unworthy,
    To redeem the pure.

    -The Scriptures, Revelation Verses 2:12
*/

#include <stdlib.h>
#include <stdio.h>
#include "mafia.h"

int getRandomNumber(){
    return 4; // Chosen by a fair dice roll.
              // Garunteed to be random.
}

void day0(){
    char * target = get_player(getRandomNumber()-1)->name;
    fprintf(stderr, "Target: `%s'\n", target);
    FILE * f = fopen("target", "w");
    if(!f){exit(1);}
    fprintf(f, "%s", target);
    fclose(f);
}

int main(){
    get_players();
    int cycle = get_cycle(day0);
    FILE * out = fopen("to_server", "w");
    if(!out){exit(1);}
    FILE * targetF = fopen("target", "r");
    if(!targetF){exit(1);}

    char target[64];

    fscanf(targetF, "%s", target);

    fprintf(stderr, "Target: %s\n", target);

    if(cycle == 0){
        // night
        fprintf(out,"%s\n", target);
        fprintf(stderr, "> Voting to kill %s\n", target);
        exit(0);
    } else if (cycle > 0) {
        // day
        fprintf(out, "vote %s\n", target);
        fprintf(stderr, "> Voting to lynch %s\n", target);
        exit(0);
    } else if (cycle == -1) {
        fprintf(stderr, "> saying 6, 10 at %s\n", target);
        fprintf(out, "say 6 %s\n", target);
        fprintf(out, "say 10 %s\n", target);
    }
}

```

It requires `mafia.c` and `mafia.h`, libraries I wrote, in the same directory.

These are included in the download, along with a Makefile and a run script.

### TODO

* Stop voting against the target when they're killed or lynched.

While I'm here, I'll submit the non-bot, Steve:

# Answer
> 2 votes
# Leviathan

Leviathan iterates over all the players in the `players` file and targets them one by one.

Download

```
/*  Citizens of the State, rejoice!

    Today, a great milestone has been achieved by our glorious leaders.
    A stepping stone in the grand story of our empire has been traversed.
    Our individual fears may be quietened;
    the safety of our great nation has been secured.

    Today, unyielding, we have walked the way of the warrior.
    In our hands have our fates been molded.
    On the Leviathan's back will our civilization be carried home
    and the taint of the Enemy purged from our souls.

    Rejoice, citizens! Victory is at hand.

    -Caldari State Information Bureau Pamphlet, YC 12
*/

#include <stdio.h>
#include <stdlib.h>
#include "mafia.h"

void day0(){
    FILE * index = fopen("idx", "w");

    fprintf(index,"0");

    fclose(index);
}

int main(){
    get_players();
    int i, cycle = get_cycle(day0);

    FILE * out = fopen("to_server", "w");
    FILE * idx = fopen("idx", "r");

    fscanf(idx, "%d", &i);
    fclose(idx);

    char * target;
    target = get_player(i)->name;

    fprintf(stderr, "Idx: %d\n", i);
    fprintf(stderr, "Target: %s\n", target);

    if(cycle > 0){
        idx = fopen("idx", "w");
        i++;
        i = i%NPLAYERS;
        fprintf(idx, "%d", i);
        fprintf(out, "vote %s\n", target);
    } else if (cycle == -1) {
        printf("> saying 6, 10 at %s\n", target);
        fprintf(out, "say 6 %s\n", target);
        fprintf(out, "say 10 %s\n", target);
    }

    fclose(out);
}

```

As with Avatar, It requires `mafia.c` and `mafia.h` in the same directory.

These are included in the download, along with a Makefile and a run script.

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


title: Check all the keys of a keyboard

text:
# Question
Title: Check all the keys of a keyboard
Write the shortest program that waits for every key of a Standard 101 key US Keyboard* to be pressed and then exits writing OK!

Every time a key is pressed the program displays on a new line the remaining number of unpressed unique keys that need to be pressed until all key are pressed at least once. The program should be able to test a 101 keyboard and see if every key works. So pressing twice a key or enter is to be allowed as long as this is specified to the user.

Pressing same key twice or more should not disrupt the code nor change the displayed number of remaining unpressed keys.

All keys (`Left Shift`, `Right Shift`, `Right Control`, `Esc`, `Enter`, etc.) should be included.

The actual keyboard keys are important in this challenge so from the perspective of the program (`A` and `a`, are the same and so are `6` and `^`).

Combined keys will not be registered as a combined command and only the individual keys will be registered if `Ctrl` \+ `Alt` \+ `Del` is pressed that will count for all the individual keys in the combination being pressed. So no need to press also the capital letters if you pressed already the lowercase and vice-versa.

Numeric keys on the numeric keypad are different from the perspective of the program, so they are still needed to be pressed for the program to finish, if you have a laptop or any other keyboard that doesn't have the US Standard 101 keyboard layout you cannot fulfill the challenge unless you plugin a compatible keyboard.

*Keyboards having Fn key and laptop key will not be supported to keep this challenge doable

This is the list of keys for a US Standard 101 keyboard layout:

```
backspace
tab
enter
right shift
right ctrl
right alt
left shift
left ctrl
left alt
print screen
pause/break
caps lock
escape
page up
page down
end
home
left arrow
up arrow
right arrow
down arrow
insert
delete
0
1
2
3
4
5
6
7
8
9
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
numpad 0
numpad 1
numpad 2
numpad 3
numpad 4
numpad 5
numpad 6
numpad 7
numpad 8
numpad 9
multiply
add
subtract
decimal point
numpad enter
divide
f1
f2
f3
f4
f5
f6
f7
f8
f9
f10
f11
f12
num lock
scroll lock
semi-colon
equal sign
comma
dash
period
forward slash
grave accent
open bracket
back slash
close braket
single quote
space

```

# Answer
> 6 votes
# Javascript, 524 bytes

Hi, this is my first ever post here, so excuse me if I'm still ignorant on some stuff, I think I stayed within the rules though.

```
k=[8,9,"130","133","161","162","171","172","181","182",19,20,27,44,45,46,48,49,50,51,52,53,54,55,56,57,144,145,186,187,188,189,190,191,192,219,220,221,222];for(i=32;i<124;i+=1){i<41?k.push(i):i>64?i<91?k.push(i):i>95?i!=108?k.push(i):0:0:0}d=[13,16,17,18];m=document.addEventListener;c=console.log;m("keydown",e=>{e.preventDefault()});m("keyup",e=>{c(e.code);if(d.includes(e.which)){l=e.which+""+e.location;if(k.includes(l)){k.splice(k.indexOf(l),1)}}else if(k.includes(e.which)){k.splice(k.indexOf(e.which),1)}c(k.length)})

```

It seems buggy if I don't use Chrome, but you can try it out here. (be sure to open the console before you focus on the example window, as the default functionality of F12 is prevented)

## Overview

The program makes an array of all the 101 "keycodes". Some are written explicitly, some sequences are added with a for loop and some are stored as strings. I have a seperate array for the "double" keycodes, since left and right control for instance give the same keycode. They also give a location, however, so I combine the keycodes with the locations as strings in the array. From there it's just an eventlistener that prevents default keydown functionality (don't wanna refresh with F5 in this case) and a seperate eventlistener for keyup, because every single key can be detected on keydown, EXCEPT FOR PRINTSCREEN.

After every keyup event the remaining keys (aka the length of the array) gets logged, as well as the name of the keycode (so there is the distinction between left and right shift, etc). I wasn't sure if that was a requirement, if not you can subtract another 10 bytes from the score.

## Limitations

* It only seems to work well in Chrome

I hope this answer is appreciated and please let me know if I've done anything wrong.

# Answer
> 4 votes
# Java 8, 607 + 64 = 671 bytes

This is a lambda taking an unused parameter and throwing `InterruptedException`. It launches a window which, when in focus, intercepts presses of the 101 standard keys. Byte count includes lambda and required imports.

```
import java.awt.event.*;import javax.swing.*;import java.util.*;

```

```
v->{Set<Integer>s=new HashSet();long[]l={0x2bfff1ff081f0300l,0x8fffefff3ffffffel,3075<<16,4<<28|1};JFrame f=new JFrame();f.addKeyListener(new KeyAdapter(){public void keyReleased(KeyEvent e){int c=e.getKeyCode(),o=e.getKeyLocation(),n;c=(c==10|c>15&c<19)&o<3?-c:c==225?98:c==226?100:c==65386?101:c==227?102:c==224?104:o>3?c==33?105:c==34?99:c==35?97:c==36?103:c==127?110:c==155?96:c:(l[c/64]>>>c&1)<1?0:c;if(c!=0)s.add(c);System.out.println(n=101-s.size());if(n<1)synchronized(f){f.notify();}}});f.setFocusTraversalKeysEnabled(0<1);f.show();synchronized(f){f.wait();}System.out.print("OK!");System.exit(0);}

```

You can find a test class with an ungolfed version here.

## Overview

As keys are pressed, values uniquely identifying them (in most cases the key code) are stored in a set. The first few levels of the ternary assignment to `c` handle cases where the key code is ambiguous (e.g. the "Home" key, which could come from the main portion of the keyboard or the number pad) and cases where the same key can map to multiple key codes (e.g. number pad behavior with Num Lock on or off). The final branch handles the "normal" keys whose key code can simply be used in the set. The key code indexes into the bitmap `l` which indicates whether the key is one of the standard 101.

## Limitations

* > The program should be able to test a 101 keyboard and see if every key works.

If any key other than the standard 101 is pressed, a stack trace may be printed to standard error, or unexpected behavior may occur.
* The program uses the numeric values of key code constants directly, and Oracle's `KeyEvent` documentation indicates that these values may change over time.

## Acknowledgments

* -10 bytes thanks to Kevin Cruijssen

# Answer
> 4 votes
# JavaScript, ~~98~~ ~~90~~ 75 bytes

So ... I suspect I may be underthinking things here but this should work. Let me know if I *have* overlooked anything. Only tested in Chrome.

```
s=new Set()
f=onkeydown=e=>!(onkeyup=e=>f(e,alert(101-s.add(e.code).size)))

```

---

## Try it

`alert` overridden for your sanity and order reversed to save scrolling.

```
alert=x=>o.prepend(document.createTextNode(x+`\n`))
s=new Set()
f=onkeydown=e=>!(onkeyup=e=>f(e,alert(101-s.add(e.code).size)))
```

```
p{font-family:sans-serif;font-size:14px;}pre{margin:0 10px;}
```

```
<p>Focus here and start typing ...</p><pre id=o></pre>
```

---
Tags: code-golf, keyboard, interactive
---


title: Tips for golfing in uBasic

text:
# Question
Title: Tips for golfing in uBasic
UBASIC is a freeware interpreter written by Yuji Kida at Rikkyo University in Japan, specialized for mathematical computing. It is considered to be a "ready-to-run" language that and is capable of running on DOS and Windows.

What general tips do you have for golfing in uBasic? Any ideas that can be applied to code golf problems in general that are at least somewhat specific to uBasic. Please post one tip per answer.

> Some helpful links
>
> uBasic Wikipedia Page
>
> Try it Online

# Answer
# Use `?` in place of `Print`

Instead of using the `Print` command, `?` may be used, as is the case in many BASIC languages - this means that the most simplest uBASIC `Hello, World!` program is as follows

```
0?"Hello, World!"

```

Rather than

```
10 Print "Hello, World!"

```

Try it Online!
> 1 votes

# Answer
# Avoid Whitespace in `For` and Like statements

Whitespace between `For` and a variable name is not necessary in uBASIC meaning that a `For` loop may be condensed from

```
0 For t = 1 To 2
1 ?t
2 Next t

```

to

```
0Fort=1To2
1?t
1Nextt

```

Try it Online!
> 1 votes

# Answer
# Execute multiple commands on a single line with `:`

uBasic allows for the execution of many commands on a single line with the use of `:` over a new line and new line number.

This means that this (50 Bytes)

```
0Fori=0To10
1Forj=1To9Step3
2?i*10+j
3Nextj
4Nexti

```

May be condensed to this (46 Bytes)

```
0Fori=0To10:Forj=1To9Step3:?i*10+j:Nextj:Nexti

```

Try it Online!
> 1 votes

# Answer
# Use `;` to `Print` Without a Newline

Much like is the case in VBA and other BASIC languages, you may add a `;` to the end of a print statement to keep from printing a newline character and continue printing on that line.

Example:

```
0For i=1 To 10
1?i;
2Next i

```

Outputs

```
12345678910

```

Try it Online!

Similarly, `,` may be appended to the end of a print statement to prevent to pad the output right to a width of eight characters (note however, the output number or string must be of a length less than or equal to 6 characters)

Example

```
0?1,"|"

```

Outputs

```
1       |

```

Try it Online!
> 0 votes

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


title: Tips for golfing in VBScript

text:
# Question
Title: Tips for golfing in VBScript
What general tips do you have for golfing in VBScript? I'm looking for ideas that can be applied to code golf problems in general that are at least somewhat specific to VBScript. Please post one tip per answer.

Thanks to Marcog for the original idea. :)

# Answer
> 2 votes
Use an empty variable instead of ""

##

Uninitialized variables are set to a special value: empty. When empty is cast to a string it becomes "".

Contrived example (using z instead of ""):

```
s=InputBox(z)
For i=1To 5
    For j=1To i
        r=r&s
    Next
    MsgBox r
    r=z
Next

```

For numeric types Empty is 0, and for booleans it is false. This can cut down on initialization code.

```
a=inputbox("Enter Starting Value")
b=a
while done=0
    i=i+1
    b=b*2
    done=(b>10000 or i>10)
wend
msgbox "Your "&a&" rabbit(s) have turned into "&b&" rabbit(s) in "&i&" years."

```

# Answer
> 1 votes
## Shorter `IF` `Then`: save 10 bytes

If you terminate an IF/THEN clause with a carriage return, you don't need to use an END IF.

Example:

```
For x=1 to 1
  IF x=1 THEN MSGBOX "No Error"
Next

```

# Answer
> 1 votes
# Use IIf instead of If...Then

`IIf()` is essentially a ternary operator. You can potentially save quite a few bytes.

For example:

```
var = "World"

If foo Then
    MsgBox "Hello" & var
Else
    MsgBox "Goodbye" & var
End If

```

Vs.

```
MsgBox IIf(foo, "Hello", "Goodbye") & "World"

```

Note: VBA only. VBScript doesn't support this one.

# Answer
> 1 votes
# Use Line Separators

Newlines count as two bytes ("\n"), but a colon is only one.

```
For i = 0 To 10
    MsgBox "Hello"
Next

```

Vs.

```
For i = 0 To 10: MsgBox "Hello": Next

```

*Note: You can't use the line separator for `If` statements.*

# Answer
> 0 votes
# Condense `For` statements

In `For` statements (and in fact any statement comprised of a `"` or numeric literal followed by a reserved command) the space that separates any numeric and a following word may be removed

This means that

```
For i = 1 To 100 Step 2
...
Next

```

May be condensed down to

```
For i=1To 100Step 2
...
Next

```

and following this logic,

```
If t = "TEST" Then ...

```

may be condensed to

```
If t="Test"Then ...

```

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


title: Cyclic Weak Levenquine

text:
# Question
Title: Cyclic Weak Levenquine
~~This question asking us to make a "Cyclic Levenquine" has gone unanswered~~. So today we will ask a slightly simpler version. In this challenge we will define a **K**-Levenquine to be a program whose output is Levenshtein distance **K** from its source.

## Task

Your goal in this challenge is to write a program with some output different from its own source; running that output as a program should also do the same. Eventually, the sequence of repeatedly running the outputs of each successive program (in the same language) must eventually output the original program.

As with the last challenge there must be two distinct programs in this cycle such that they do not share any two bytes (i.e. their byte sets are disjoint).

As with most challenges, reading your own source code is forbidden.

## Scoring

Each program in your cycle will be a **K**-Levenquine for some **K**. The largest **K** of any of the programs in your cycle will be your score. Your goal should be to minimize this score, with **1** being the optimal score.

# Answer
> 3 votes
# \>\<\>, Score: 41

```
'd3*}>a!o-!<<8:5@lI55>@z:5ll55>>q:>|q::|,

```

and the disjoint program

```
"r00gr40g44++bb+0p64++?b6+0.22#eW4s )Z

```

Try it online!

A copy of my answer to the Mutually Exclusive Quine question. A mutually exclusive quine is made of two programs, A and B sharing no common characters, where A outputs B and B outputs A. This means it is a 2-cycle Levenquine and also qualifies for this question. This can act as a baseline for other more inventive answers (though I'm not very confidant this won't go the way of the original Levenquine question).

A more detailed explanation can be found here.

---
Tags: code-challenge, quine
---


title: Mod 2 Multinomial coefficients

text:
# Question
Title: Mod 2 Multinomial coefficients
quintopia has posted here a challenge to compute multinomial coefficients (some of the text here is copied from there). There is a fun algorithm to compute multinomial coefficients mod 2.

Given a list of numbers, *k1*, *k2*, ... ,*km*, output the residue of the multinomial coefficient:

reduced mod 2. The following algorithm does this efficiently: for each *ki*, compute the binary expansion of *ki*, that is, find *aij* such that each *aij* is either 1 or 0 and

If there is any j such that *arj = asj = 1* for r ≠ s, then the associated mod 2 multinomial coefficient is 0, otherwise the mod 2 multinomial coefficient is 1.

## Task

Write a program or function which takes *m* numbers, *k1*, *k2*, ... ,*km*, and outputs or returns the corresponding multinomial coefficient. Your program may optionally take *m* as an additional argument if need be.

* These numbers may be input in any format one likes, for instance grouped into lists or encoded in unary, or anything else, as long as the actual computation of the multinomial coefficient is performed by your code, and not the encoding process.
* Output can be any truthy value if the multinomial coefficient is odd and any falsey value if the multinomial coefficient is even.
* Built-ins designed to compute the multinomial coefficient are not allowed.
* Standard loopholes apply.

## Scoring

This is code golf: Shortest solution in bytes wins.

## Examples:

To find the multinomial coefficient of 7, 16, and 1000, we binary expand each of them:

Since no column has more than one 1, the multinomial coefficient is odd, and hence we should output something truthy.

To find the multinomial coefficient of 7, 16, and 76, we binary expand each of them:

Since both 76 and 7 have a 4 in their binary expansion, the multinomial coefficient is even and so we output a falsey value.

## Test cases:

```
Input: [2, 0, 1]
Output: Truthy

Input: [5,4,3,2,1]
Output: Falsey

Input: [1,2,4,8,16]
Output: Truthy

Input: [7,16,76]
Output: Falsey

Input: [7,16,1000]
Output: Truthy

Input: [545, 1044, 266, 2240]
Output: Truthy

Input: [1282, 2068, 137, 584]
Output: Falsey

Input: [274728976, 546308480, 67272744, 135004166, 16790592, 33636865]
Output: Truthy

Input: [134285315, 33849872, 553780288, 544928, 4202764, 345243648]
Output: Falsey

```

# Answer
# Jelly, 4 bytes

```
S=|/

```

Try it online!

Test whether the sum is equal to the bitwise-or-sum (i.e. `a+b+c == a|b|c`).
> 9 votes

# Answer
# Python ~~3~~ 2, ~~55~~ ~~43~~ 42 bytes

```
lambda l:sum(l)==eval(`l`.replace(*',|'))

```

-12 bytes from Mr. Xcoder

-1 byte from Rod

Try it online!

Explanation: Checks if the sum of the numbers is equal to the bitwise-or of the numbers.
> 7 votes

# Answer
# Python 2, 37 bytes

```
lambda l:sum(l)==reduce(int.__or__,l)

```

Try it online!

Another port of pizzapants184's algorithm...
> 4 votes

# Answer
# Clean, 38 bytes

```
import StdEnv
?l=sum l==foldr(bitor)0l

```

Try it online!

Yet another port.
> 3 votes

# Answer
# JavaScript (ES6), ~~37~~ ~~35~~ 34 bytes

*Saved 2 bytes thanks to @Mr.Xcoder*
*Saved 1 byte thanks to @ETHproductions*

Comparing the sum with the bitwise OR (like pizzapants184 and Leaky Nun did) is ~~1~~ ~~3~~ 4 bytes shorter than my initial approach:

```
a=>(q=c=>eval(a.join(c)))`|`==q`+`

```

### Test cases

```
let f =

a=>(q=c=>eval(a.join(c)))`|`==q`+`

console.log(f([2, 0, 1]))                                                       // Truthy
console.log(f([5,4,3,2,1]))                                                     // Falsey
console.log(f([1,2,4,8,16]))                                                    // Truthy
console.log(f([7,16,76]))                                                       // Falsey
console.log(f([7,16,1000]))                                                     // Truthy
console.log(f([545, 1044, 266, 2240]))                                          // Truthy
console.log(f([1282, 2068, 137, 584]))                                          // Falsey
console.log(f([274728976, 546308480, 67272744, 135004166, 16790592, 33636865])) // Truthy
console.log(f([134285315, 33849872, 553780288, 544928, 4202764, 345243648]))    // Falsey
```

---

# Alt. version, 38 bytes

```
a=>!a.some((x,i)=>a.some(y=>i--&&x&y))

```

### Test cases

```
let f =

a=>!a.some((x,i)=>a.some(y=>i--&&x&y))

console.log(f([2, 0, 1]))                                                       // Truthy
console.log(f([5,4,3,2,1]))                                                     // Falsey
console.log(f([1,2,4,8,16]))                                                    // Truthy
console.log(f([7,16,76]))                                                       // Falsey
console.log(f([7,16,1000]))                                                     // Truthy
console.log(f([545, 1044, 266, 2240]))                                          // Truthy
console.log(f([1282, 2068, 137, 584]))                                          // Falsey
console.log(f([274728976, 546308480, 67272744, 135004166, 16790592, 33636865])) // Truthy
console.log(f([134285315, 33849872, 553780288, 544928, 4202764, 345243648]))    // Falsey
```
> 2 votes

# Answer
# Japt, 6 bytes

Another port of pizzapants184's & Leaky Nun's solutions.

```
x ¶Ur|

```

Test it
> 2 votes

# Answer
# Java 8, 53 bytes

```
a->{int i=0,j=0;for(int x:a){i+=x;j|=x;}return i==j;}

```

Port of *@LeakyNun*'s Jelly answer.

**Explanation:**

Try it here.

```
a->{             // Method with integer-array parameter and boolean return-type
  int i=0,j=0;   //  Two integers, both starting at 0
  for(int x:a){  //  Loop over the array
    i+=x;        //   Add them to the first integer
    j|=x;}       //   And bitwise-OR it with the second integer
  return i==j;}  //  Return if both integers are the same after the loop

```
> 2 votes

# Answer
# Haskell, 38 bytes

`(==).sum<*>foldl1 xor` is an anonymous function returning a `Bool`. Use as `((==).sum<*>foldl1 xor) [2,0,1]`.

```
import Data.Bits
(==).sum<*>foldl1 xor

```

Try it online!

* Pretty much the same trick by pizzapants184 and Leaky Nun that everyone uses, except that with Haskell operator names it saves one byte to use (bitwise) `xor` instead of `(.|.)` (bitwise or).
* `(==).sum<*>foldl1 xor` is a point-free version of `\l->sum l==foldl1 xor l`.
> 2 votes

# Answer
# Pyth, 6 bytes

```
qsQ.|F

```

Test Suite.
> 1 votes

# Answer
# Husk, 5 bytes

```
§=ΣFv

```

Try it online!
> 1 votes

# Answer
# Perl 6, 15 bytes

```
{.sum==[+|] $_}

```

Test it

## Expanded:

```
{  # bare block lambda with implicit parameter ｢$_｣

    .sum  # the sum of ｢$_｣ (implicit method call)

  ==

    [+|]  # reduce using &infix:«+|» (numeric binary or)

      $_  # the input
}

```
> 1 votes

# Answer
# Red, 78 bytes

```
f: func[x][b: :to-binary t: 0 s: b 0 foreach n x[t: t + n s: s or b n]s = b t]

```

## How it works:

Ungolfed:

```
Red []
f: func [x][         -  a function taking a block as an argument
    b: :to-binary    -  an alias for the to-binary function
    t: 0             -  set the sum of the numbers to 0
    s: b 0           -  set the "or" total to binary 0
    foreach n x[     -  for each number in the block
        t: t + n     -  add it to the sum
        s: s or b n  -  bitwise or of its binary representation with the total
    ]
    s = b t          - are the sum (binary) and the "or" total equal?
]

```

Try it online!
> 1 votes

# Answer
# Wolfram Language (Mathematica), 15 bytes

```
Tr@#==BitOr@@#&

```

Try it online!
> 1 votes

# Answer
## Batch, 73 bytes

```
@set/as=o=0
@for %%i in (%*)do @set/as+=%%i,o^|=%%i
@if %s%==%o% echo 1

```

Outputs `1` for truthy, nothing for falsy. Another obvious port of pizzapants184/Leaky Nun's algorithm.
> 0 votes

# Answer
# , 10 bytes

```
+/=+./&.#:

```

Yet another port of pizzapants184's & Leaky Nun's solutions.

## How it works?

`+/.&.#:` \- convert the numbers to binary, apply bitwise or to the powers of two and convert back from binary to decimal

`+/` \- reduce the input by addition

`=` \- are the above equal?

Try it online!

## Straightforward alternative

# , 12 bytes

```
2>[:>./+/@#:

```

## How it works?

`+/@#:` \- convert each number to binary and find the sum of each power of 2

`>./` \- find the maximum

`2>` \- is it less than 2? -\> truthy

Try it online!
> 0 votes

# Answer
# Triangularity, 31 bytes

```
...)...
..IEu..
.)IE...
"|"JE=.

```

Try it online!

# Alternate solution, 31 bytes

```
...)...
..IED..
.us"|".
JE=....

```

Try it online!
> 0 votes

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