title: Sequentia Filii Bonacci

text:
# Question
Title: Sequentia Filii Bonacci
Leonardo of Pisa (ca. 1175 - ca. 1245) is better known as **Fibonacci**. But this is actually a short for the Latin "filius Bonacci" (the son of Bonacci) which was made up during the 18th century (according to Wikipedia).

In this challenge, you'll be given an ordinal number (in the literal sense) between ***1****st* and ***20****th* and you have to return the corresponding term in the Fibonacci sequence.

The twist is that the ordinal number will be given in Latin.

**Example**: "duodecimus" → \\$89\\$.

## Full I/O table

```
 input              | meaning | output
--------------------+---------+--------
 "primus"           |   1st   |    0
 "secundus"         |   2nd   |    1
 "tertius"          |   3rd   |    1
 "quartus"          |   4th   |    2
 "quintus"          |   5th   |    3
 "sextus"           |   6th   |    5
 "septimus"         |   7th   |    8
 "octavus"          |   8th   |   13
 "nonus"            |   9th   |   21
 "decimus"          |  10th   |   34
 "undecimus"        |  11th   |   55
 "duodecimus"       |  12th   |   89
 "tertius decimus"  |  13th   |  144
 "quartus decimus"  |  14th   |  233
 "quintus decimus"  |  15th   |  377
 "sextus decimus"   |  16th   |  610
 "septimus decimus" |  17th   |  987
 "duodevicesimus"   |  18th   | 1597
 "undevicesimus"    |  19th   | 2584
 "vicesimus"        |  20th   | 4181

```

## Rules

* The input is guaranteed to be *exactly* one of the strings described above.
* If that helps, you may take it in full uppercase instead. But it must be consistent for all entries. Mixed cases are not allowed.
* Depending on your algorithm and language, hardcoding or computing the terms of the sequence may either win or lose bytes. Both approaches are explicitly allowed.
* This is !

# Answer
# , ~~91~~ 86 bytes

Look up the index of the sum of bytes in a brute-forced UTF8 lookup table and use the magic Fibonacci generating function to give the answer.

```
function(x)round(1.618^match(sum(!x)%%93,!'%(-1!5+3JOSCW6')*.2765)
"!"=utf8ToInt

```

Try it online!

Edit: -2 bytes by improved numeric rounding

Edit: -3 bytes with a change to the lookup (thanks for the hint, @Giuseppe!)
> 8 votes

# Answer
# Clean, 87 bytes

*All escapes except `\n` are treated as one byte, since the compiler's fine with the actual raw values. (TIO and SE have issues with it not being valid UTF-8 though, and so it's escaped here)*

FryAmTheEggman made a nice demonstration / workaround: here

```
import StdEnv
$s=hd[i\\i<-k 1 0&c<-:"\340\152\060\065\071\354\172\045\223\n\255\362\132\137\143\026\244\051\344\270"|c==sum s]
k b a=[a:k(a+b)b]

```

Try it online!

Defines the function `$ :: [Char] -> Int`, which uses the uniqueness in the summation of the uppercase character values to determine which term in the sequence (generated by the helper function `k`) to return.
> 4 votes

# Answer
## Ruby, ~~104~~ 93 bytes

```
->x{[8,4181,3,144,21,13,0,1,233,5,987,0,377,55,0,89,1,1597,34,610,0,2,2584][x.sum%192%76%23]}

```

Try it online!

Simply takes the sum of the bytes, modulo 192 modulo 76 modulo 23, and indexes into a lookup table. (Magic numbers found by brute force.)
> 4 votes

# Answer
# 6502 machine code (C64), 82 bytes

```
00 C0 20 9E AD 20 A3 B6 A8 88 A9 05 4A 90 02 49 B1 71 22 88 10 F6 29 1F C9 07
B0 02 69 0D A8 BE 32 C0 B9 1E C0 4C CD BD 00 00 00 00 03 00 0A 00 06 10 01 00
FF 00 02 00 00 00 00 00 08 00 15 0D DB 02 18 90 3D 55 79 05 FF E9 62 22 01 59
01 37 FF 03

```

This uses hashing (of course), but optimized for short implementation on the 6502, taking advantage of the carry flag set by shifting and used in addition. Magic numbers for hashing were found by brute forcing with a little C program; the `FF` bytes are unfortunate holes in the hash table ;)

Byte count: 2 bytes load address, 38 bytes code, 42 bytes hashtable for values.

### Online demo

Usage: `SYS49152"[ordinal]"`, for example `SYS49152"DUODECIMUS"`. (note the letters appear upper case in the default C64 configuration).

**Important**: Before the first start, issue a `NEW` command. This is needed because the C64 BASIC `LOAD` command fiddles with some BASIC vectors, even when loading a machine program to some absolute address (like here `$C000`/`49152`).

**Commented disassembly**:

```
         00 C0                          ; load address
.C:c000  20 9E AD    JSR $AD9E          ; evaluate expression
.C:c003  20 A3 B6    JSR $B6A3          ; evaluate as string
.C:c006  A8          TAY                ; length to y register
.C:c007  88          DEY                ; decrement (start at last char)
.C:c008  A9 05       LDA #$05           ; start value for hash
.C:c00a   .hashloop:
.C:c00a  4A          LSR A              ; shift right
.C:c00b  90 02       BCC .skip          ; shifted bit zero? -> skip xor
.C:c00d  49 B1       EOR #$B1           ; xor "magic" value
.C:c00f   .skip:
.C:c00f  71 22       ADC ($22),Y        ; add current character (plus carry)
.C:c011  88          DEY                ; previous character
.C:c012  10 F6       BPL .hashloop      ; pos >= 0? -> repeat
.C:c014  29 1F       AND #$1F           ; mask lowest 5 bits
.C:c016  C9 07       CMP #$07           ; larger than 7 ?
.C:c018  B0 02       BCS .output        ; -> to output
.C:c01a  69 0D       ADC #$0D           ; add 13
.C:c01c   .output:
.C:c01c  A8          TAY                ; hash to y register
.C:c01d  BE 32 C0    LDX .lb-8,Y        ; load low byte from hashtable
.C:c020  B9 1E C0    LDA .hb-8,Y        ; load high byte from hashtable
.C:c023  4C CD BD    JMP $BDCD          ; to output of 16bit number
.C:c026   .hb:
.C:c026  00 00 00 00 .BYTE $00,$00,$00,$00
.C:c02a  03 00 0A 00 .BYTE $03,$00,$0A,$00
.C:c02e  06 10 01 00 .BYTE $06,$10,$01,$00
.C:c032  FF 00 02 00 .BYTE $FF,$00,$02,$00
.C:c036  00 00 00 00 .BYTE $00,$00,$00,$00
.C:c03a   .lb:
.C:c03a  08 00 15 0D .BYTE $08,$00,$15,$0D  ; second byte used in .hb as well
.C:c03e  DB 02 18 90 .BYTE $DB,$02,$18,$90
.C:c042  3D 55 79 05 .BYTE $3D,$55,$79,$05
.C:c046  FF E9 62 22 .BYTE $FF,$E9,$62,$22
.C:c04a  01 59 01 37 .BYTE $01,$59,$01,$37
.C:c04e  FF 03       .BYTE $FF,$03

```

---

### C64 BASIC V2 test suite

(containing the machine program in `DATA` lines)

### Online demo

```
0fOa=49152to49231:rEb:pOa,b:nE
1?"primus",:sY49152"primus":?
2?"secundus",:sY49152"secundus":?
3?"tertius",:sY49152"tertius":?
4?"quartus",:sY49152"quartus":?
5?"quintus",:sY49152"quintus":?
6?"sextus",:sY49152"sextus":?
7?"septimus",:sY49152"septimus":?
8?"octavus",:sY49152"octavus":?
9?"nonus",:sY49152"nonus":?
10?"decimus",:sY49152"decimus":?
11?"undecimus",:sY49152"undecimus":?
12?"duodecimus",:sY49152"duodecimus":?
13?"tertius decimus",:sY49152"tertius decimus":?
14?"quartus decimus",:sY49152"quartus decimus":?
15?"quintus decimus",:sY49152"quintus decimus":?
16?"sextus decimus",:sY49152"sextus decimus":?
17?"septimus decimus",:sY49152"septimus decimus":?
18?"duodevicesimus",:sY49152"duodevicesimus":?
19?"undevicesimus",:sY49152"undevicesimus":?
20?"vicesimus",:sY49152"vicesimus":?
21dA32,158,173,32,163,182,168,136,169,5,74,144,2,73,177,113,34,136,16,246,41,31
22dA201,7,176,2,105,13,168,190,50,192,185,30,192,76,205,189,0,0,0,0,3,0,10,0,6
23dA16,1,0,255,0,2,0,0,0,0,0,8,0,21,13,219,2,24,144,61,85,121,5,255,233,98,34,1
24dA89,1,55,255,3

```
> 4 votes

# Answer
# C (gcc), ~~135~~ 129 bytes

6 bytes down by suggestion of ceilingcat and Logern

```
f;i;b;o;n(char*a){for(f=i=b=o=0;*a;o+=21*b+++*a++-70);for(b=1,o="TACIHAAJQFSAAARCAMGKDANPEAOAAL"[o%30];--o>65;f=b,b=i)i=f+b;a=i;}

```

Try it online!

Explanation:

```
f; i; b; o; // Variables

n (char *a)
{
     // Calculate a silly hash of incoming string
     for (f = i = b = o = 0; *a; o += 21 * b++ + *a++ - 70);

     // Use the hash to index into the array of number values
     // and calculate the corresponding Fibonacci sequence element
     for
     (
         b = 1,
         o = "TACIHAAJQFSAAARCAMGKDANPEAOAAL"[o % 30];

         --o > 65;
         f = b, b = i
     )
         i = f + b;

     // implicit return
     a = i;
}

```
> 3 votes

# Answer
# Perl 6, 62 bytes

```
{(0,1,*+*...*)[index '%(-1!5+3JOSCW6',chr .ords.sum%93]}

```

Try it online!

Uses a lookup table in a string, as well as a short fibonacci sequence generator.
> 3 votes

# Answer
# Pyth, 54 bytes

```
L?>b1+ytbyttbbyxc."axnÛ±r†XVW‹(„WîµÏ£"2+hQ@Q618

```

Test suite

**Notice:** as the code makes use of some unprintable characters, it may not display correctly on Stack Exchange. The link provided leads to a working and copy-pastable source.

Long story short, `Q[0]+Q[618%len(Q)]` gives unique results for all accepted inputs `Q`.
> 2 votes

# Answer
# Python 2, 292 bytes

```
f=lambda x:x>1and f(x-1)+f(x-2)or x
def g(t):
	for i,c in zip("pr secun ter qua qui sex sep oc no ec".split(),range(1,11))+zip("un duo es ev".split(),(1,2,20,"-")):t=t.replace(i,str(c))
	return f(abs(eval("+".join("".join((" ",c)[c in"0123456789-"]for c in t).split()).replace("+-+","-")))-1)

```

Try it online!

Fibonacci generator shamelessly stolen from this answer.

Breaks each word down into its meaningful component parts and discards the rest (in "duodevicesimus", for example, we only care about "duo ev es "-\> "2 - 20 " - \> abs("2-20") -\> 18).

Passes the calculated value (minus 1 to 0-offset) to the Fibonacci generator function.

## Ungolfed Explanation:

```
# Fibonacci function
f=lambda x:x>1and f(x-1)+f(x-2)or x

def g(t):
    # generates a list of key, value pairs like [("pr", 1, ..., ("ec", 10)] +
    values = zip("pr secun ter qua qui sex sep oc no ec".split(), range(1,11))

    # adds values to existing list
    values += zip("un duo es ev".split(),(1,2,20,"-"))

    # replace the matching values in the string with the appropriate number/sign.
    # ORDER MATTERS - if "un" is searched for before "secun", this generates incorrect values.
    for i,c in values:
        t = t.replace(i,str(c))

    # replace each non-digit, non-minus character in string with "c"
    t = [(" ",c)[c in"0123456789-"]for c in t]

    # convert space-replaced array back to a string
    # then split it on spaces, creating an array of values
    t = "".join(t).split()

    # turn the array back into a string, with each individual item separated by "+"
    # this will cause "-" to become "+-+" (since "-" is ALWAYS between two numbers), so prelace that sequence with "-"
    t = "+".join(t).replace("+-+","-")

    # evaluate the string as an expression, and take the absolute value for when - occurs
    t = abs(eval(t))

    # pass the value, minus 1 for 0-offset, to the Fibonacci function.
    return f(t-1)

```
> 1 votes

# Answer
# Python 2, ~~97~~ 79 bytes

```
lambda s:int(1.618**('RV3NJ^[KDP=Z62AWeG<C'.find(chr(hash(s)%69+48)))*.4474+.5)

```

Try it online!

First, we want to convert from latin to a number `n`; this is accomplished by ~~replicating the input string enough times to ensure that there are at least 11 characters total; and then the `3`rd and `10`th characters (zero indexed) form a unique pair~~ taking the hash mod 69 and turning that into a printable char.

Now we have `n`. To find the `n`th Fibonacci number, we can use the rounding method, using only as many digits of precision as we need up to Fib(20).
> 1 votes

# Answer
# JavaScript (Node.js), ~~100~~ ~~97~~ ~~95~~ ~~92~~ 91 bytes

```
x=>1.618**(p=parseInt)("1 jgf7  ei 490dbch62385a"[p(x.length+x,32)%12789%24],36)*.4474+.5|0

```

Try it online!

**Warning: WORKS BECAUSE OF FLOATING POINT INACCURACY**

JavaScript has neither a built-in hash function, nor a short enough character-to-ASCII function (`String.charCodeAt` is the shortest already), so I need to define a simple hash function by myself.

Used the same rounding method as Chas Brown did after calculating the hash.

**After a whole day of brute-forcing a better is found:**

`b32_to_dec(x.length + x) % 12789 % 24` (\*floating point inaccuracy)

~~`b32_to_dec(x.length + x) % 353 % 27` (\*floating point inaccuracy)~~

~~`b36_to_dec(x.length + x[2]) % 158 % 29 - 4`~~

~~`b36_to_dec(x[2] + x.length) % 741 % 30`~~

~~`b36_to_dec(x[0] + x[2] + x.length) % 4190 % 27`~~

**`parseInt(x.length + x, 32)` result**

```
primus 7310236636
secundus 9773632960476
tertius 272155724764
quartus 269453490140
quintus 269461747676
sextus 7054
septimus 9774067964892
octavus 266721394652
nonus 192700380
decimus 254959770588
undecimus 350449413217244
duodecimus 36520018280274912 **NOT PRECISE**
tertius decimus 1302947875804
quartus decimus 1300245641180
quintus decimus 1300253898716
sextus decimus 37774
septimus decimus 42759416798172
duodevicesimus 43016381192006637977600 **NOT PRECISE**
undevicesimus 1326703556626028691456 **NOT PRECISE**
vicesimus 351376069188572

```

## Version without exploitation of floating point inaccuracy: 95 bytes

```
x=>1.618**(p=parseInt)("52d7i 6  he 8309jafc 41bg"[p(x.length+x[2],36)%158%29-4],36)*.4474+.5|0

```

Try it online!

`b36_to_dec(x.length + x[2]) % 158 % 29 - 4`

**Hash Table**

```
 Latin word           | Length | 3rd | Hash | Decimal | %158 | %29-4
----------------------+--------+-----+------+---------+------+-------
 primus               |      6 | i   | 6i   |     234 |   76 |    14
 secundus             |      8 | c   | 8c   |     300 |  142 |    22
 tertius              |      7 | r   | 7r   |     279 |  121 |     1
 quartus              |      7 | a   | 7a   |     262 |  104 |    13
 quintus              |      7 | i   | 7i   |     270 |  112 |    21
 sextus               |      6 | x   | 6x   |     249 |   91 |     0
 septimus             |      8 | p   | 8p   |     313 |  155 |     6
 octavus              |      7 | t   | 7t   |     281 |  123 |     3
 nonus                |      5 | n   | 5n   |     203 |   45 |    12
 decimus              |      7 | c   | 7c   |     264 |  106 |    15
 undecimus            |      9 | d   | 9d   |     337 |   21 |    17
 duodecimus           |     10 | o   | 10o  |    1320 |   56 |    23
 tertius decimus      |     15 | r   | 15r  |    1503 |   81 |    19
 quartus decimus      |     15 | a   | 15a  |    1486 |   64 |     2
 quintus decimus      |     15 | i   | 15i  |    1494 |   72 |    10
 sextus decimus       |     14 | x   | 14x  |    1473 |   51 |    18
 septimus decimus     |     16 | p   | 16p  |    1537 |  115 |    24
 duodevicesimus       |     14 | o   | 14o  |    1464 |   42 |     9
 undevicesimus        |     13 | d   | 13d  |    1417 |  153 |     4
 vicesimus            |      9 | c   | 9c   |     336 |   20 |    16

```
> 1 votes

---
Tags: code-golf, fibonacci
---


title: True color code

text:
# Question
Title: True color code
True color (24-bit) at Wikipedia is described in pertinent part as

> 24 bits almost always uses 8 bits of each of R, G, B. As of 2018 24-bit color depth is used by virtually every computer and phone display and the vast majority of image storage formats. Almost all cases where there are 32 bits per pixel mean that 24 are used for the color, and the remaining 8 are the alpha channel or unused.
>
> 224 gives 16,777,216 color variations. The human eye can discriminate up to ten million colors\[10\] and since the gamut of a display is smaller than the range of human vision, this means this should cover that range with more detail than can be perceived. ...
>
> ...
>
> Macintosh systems refer to 24-bit color as "millions of colors". The term "True color" is sometime used to mean what this article is calling "Direct color".\[13\] It is also often used to refer to all color depths greater or equal to 24.
>
> All 16,777,216 colors

## Task

Write a program which generates and returns all 16,777,216 color variations within an array as strings in the CSS `rgb()` function

> 5.1. The RGB functions: `rgb()` and `rgba()`
>
> The `rgb()` function defines an RGB color by specifying the red, green, and blue channels directly. Its syntax is:
>
> ```
> rgb() = rgb( <percentage>{3} [ / <alpha-value> ]? ) |
>         rgb( <number>{3} [ / <alpha-value> ]? )
> <alpha-value> = <number> | <percentage>
>
> ```
>
> The first three arguments specify the red, green, and blue channels of the color, respectively. `0%` represents the minimum value for that color channel in the sRGB gamut, and `100%` represents the maximum value. A `<number>` is equivalent to a `<percentage>`, but with a different range: `0` again represents the minimum value for the color channel, but `255` represents the maximum. These values come from the fact that many graphics engines store the color channels internally as a single byte, which can hold integers between 0 and 255. Implementations should honor the precision of the channel as authored or calculated wherever possible. If this is not possible, the channel should be rounded to the closest value at the highest precision used, rounding up if two values are equally close.
>
> The final argument, the `<alpha-value>`, specifies the alpha of the color. If given as a `<number>`, the useful range of the value is `0` (representing a fully transparent color) to `1` (representing a fully opaque color). If given as a , `0%` represents a fully transparent color, while `100%` represents a fully opaque color. If omitted, it defaults to `100%`.
>
> Values outside these ranges are not invalid, but are clamped to the ranges defined here at computed-value time.
>
> For legacy reasons, `rgb()` also supports an alternate syntax that separates all of its arguments with commas:
>
> ```
> rgb() = rgb( <percentage>#{3} , <alpha-value>? ) |
>         rgb( <number>#{3} , <alpha-value>? )
>
> ```
>
> Also for legacy reasons, an `rgba()` function also exists, with an identical grammar and behavior to `rgb()`.

or RGB hexadecimal notation `#RRGGBB` format

> 5.2. The RGB hexadecimal notations: `#RRGGBB`
>
> The CSS ***hex color*** notation allows a color to be specified by giving the channels as hexadecimal numbers, which is similar to how colors are often written directly in computer code. It’s also shorter than writing the same color out in `rgb()` notation.
>
> The syntax of a `<hex-color>` is a `<hash-token>` token whose value consists of 3, 4, 6, or 8 hexadecimal digits. In other words, a hex color is written as a hash character, "#", followed by some number of digits 0-9 or letters a-f (the case of the letters doesn’t matter - `#00ff00` is identical to `#00FF00`).
>
> The number of hex digits given determines how to decode the hex notation into an RGB color:
>
> **6 digits**
>
> The first pair of digits, interpreted as a hexadecimal number, specifies the red channel of the color, where `00` represents the minimum value and `ff` (255 in decimal) represents the maximum. The next pair of digits, interpreted in the same way, specifies the green channel, and the last pair specifies the blue. The alpha channel of the color is fully opaque.
>
> > EXAMPLE 2
> > In other words, `#00ff00` represents the same color as `rgb(0 255 0)` (a lime green).

See Editor's Draft of CSS Color Module Level 4

## **Examples**

**CSS `rgb()` function** (space character can be substituted for comma character, e.g., `rgb(0 255 0)`)

```
// `rgb()` `<percentage>` as strings in resulting array
['rgb(0%,0%,0%)', ...,'rgb(0%,255%,0)', ...'rgb(255,255,255)']

// `rgb()` `<number>` as strings in resulting array
['rgb(0,0,0)', ...,'rgb(0,255,0)', ...'rgb(255,255,255)']

```

**CSS RGB hexadecimal notation `RRGGBB`**

```
// RGB hexadecimal notation as strings in resulting array
['#000000', ...,'#00ff00', ...'#ffffff']

```

## Winning criteria

Least bytes used to write the program.

# Answer
# , 25 bytes

```
sprintf("#%06X",1:2^24-1)

```

Try it online!
> 8 votes

# Answer
# Python 2, ~~77~~ ~~40~~ ~~39~~ 37 bytes

```
print['#%06X'%c for c in range(8**8)]

```

Try it online!

-1 byte thanks to Digital Trauma

-2 bytes thanks to dylnan
> 7 votes

# Answer
# JavaScript (ES7), ~~65~~ ~~62~~ 61 bytes

*Saved ~~3~~ 4 bytes thanks to @tsh*

Returns an array of `#RRGGBB` strings.

```
_=>[...Array(n=8**8)].map(_=>'#'+(n++).toString(16).slice(1))

```

Try it online! (truncated output)
> 6 votes

# Answer
# PowerShell, ~~28~~ 26 bytes

```
1..16mb|%{"#{0:x6}"-f--$_}

```

Try it online!

Loops from `1` to `16mb` (16777216). Each iteration, we use the `-f`ormat operator acting on the current number pre-decremented `--$_` against the string `"#{0:x6}"`. Here, we're specifying he`x` values, padded to `6` digits, with a hash `#` in front. On TIO, limited to 60 seconds / 128KiB of output. Change the `1` to `(16mb-5)` to see how it ends.
> 6 votes

# Answer
# Common Lisp, 42 bytes

```
(dotimes(i 16777216)(format t"#~6,'0x "i))

```

Try it online!
> 5 votes

# Answer
# Japt, 14 bytes

Outputs as `#rrggbb`.

```
G²³ÇsG ùT6 i'#

```

Try it (Limited to the first 4096 elements)

---

## Explanation

```
G                  :16
 ²                 :Squared
  ³                :Cubed
   Ç               :Map the range [0,result)
    sG             :  Convert to base-16 string
       ù           :  Left pad
        T          :   With 0
         6         :   To length 6
           i'#     :  Prepend "#"

```
> 4 votes

# Answer
## Haskell, 41 bytes

```
l="ABCDEF"
mapM id$"#":(['0'..'9']++l<$l)

```

Try it online!
> 4 votes

# Answer
# 05AB1E, ~~15~~ ~~14~~ 10 bytes

```
15Ýh6ãJ'#ì

```

Try it online.

**Explanation:**

```
15Ý           # Create a list in the range [0, 15]
   h          # Convert each to a hexadecimal value
    6ã        # Create each possible sextuple combination of the list
      J       # Join them together to a single string
       '#ì    # And prepend a "#" before each of them

```
> 3 votes

# Answer
## Batch, 87 bytes

```
@set s= in (0,1,255)do @
@for /l %%r%s%for /l %%g%s%for /l %%b%s%echo rgb(%%r,%%g,%%b)

```

Outputs in CSS format. The variable substitution happens before the `for` statement is parsed so the the actual code is as follows:

```
@for /l %%r in (0,1,255)do @for /l %%g in (0,1,255)do @for /l %%b in (0,1,255)do @echo rgb(%%r,%%g,%%b)

```
> 3 votes

# Answer
# C# (Visual C# Interactive Compiler), 47 bytes

```
Enumerable.Range(0,1<<24).Select(q=>$"#{q:X6}")

```

Try it online!
> 3 votes

# Answer
# MATL, ~~17~~ 15 bytes

```
10W:q'#%06X,'YD

```

Try it online!

The TIO version displays the first 2^10 only as not to time out. I included the final iteration in the footer to show that it indeed terminates at `#FFFFFF`. Saved one byte by changing to `fprintf` instead of manually assembling the string. Outputs a comma-separated list.

Explanation

```
24W:q            % Range from 0 to 2^24-1
     '#%06X,'    % fprintf format spec (# followed by hexadecimal, zero-padded, fixed-width, followed by newline)
             YD  % Call fprintf. Internally loops over range.

```
> 2 votes

# Answer
# C# (.NET Core), 75 bytes

```
()=>{int i=1<<24;var a=new string[i];for(;i-->0;)a[i]=$"#{i:X6}";return a;}

```

Try it online!

Port of JAVA 10 version with C# interpolated string format
> 2 votes

# Answer
# K (oK), 19 bytes

**Solution:**

```
$(3#256)\'!16777216

```

Try it online! (limited to first 500 numbers)

**Explanation:**

Dump out rgb strings. Convert each number between 0 and 16777216 to base 256, then convert to strings...

```
$(3#256)\'!16777216 / the solution
          !16777216 / range 0..16777215
 (     )\'          / split each both
  3#256             / 256 256 256
$                   / string

```
> 2 votes

# Answer
# APL (Dyalog Unicode), ~~47~~ ~~43~~ 20 bytes

```
'#',(⎕D,⎕A)[↑,⍳6⍴16]

```

Try it online!

Given enough time/memory, this anonymous function will output all \\$2^{24}-1\\$ color codes. To see this, you can swap the `6⍴` for a `4⍴` in the code, and you'll see it output every code with up to 4 digits.

Thanks to @Dzaima and @ngn for the 23 bytes.

Uses `⎕IO←0`.

### How:

```
'#',(⎕D,⎕A)[↑,⍳6⍴16] ⍝ Main function
               ⍳6⍴16  ⍝ Generate every possible 6 digit hex number in a matrix format
              ,       ⍝ Ravel the matrix (from a 16x16x16x16x16x16 matrix to a 16^6x2 list)
             ↑        ⍝ Mix; (turns the list into a 16^6x2 matrix)
    (⎕D,⎕A)[       ] ⍝ Use that matrix to index the vector of the digits 0-9 concatenated with the alphabet.
'#',                  ⍝ Then prepend a '#' to each.

```
> 2 votes

# Answer
# Ruby, 31 bytes

```
$><<("#%06x\n"*d=2**24)%[*0..d]

```

Try it online!
> 1 votes

# Answer
## Batch, 69 + 4 = 73

### g.cmd, 69

```
for /L %%A in (0,1,16777215)do cmd/kexit %%A&set #%%A=#!=exitcode:~2!

```

Saves the hexadecimal value with form `#RRGGBB` into an 'Array'.

`g.cmd` is to be called using `cmd /V/Q/K g.cmd`. This is where the + 4 comes from, `/V/Q`, counting as 4 additional characters compared to just `cmd /K g.cmd`. This sets up an environment that has the 'Array' in memory. It also takes forever to run, so use very low values to try or break execution using `Ctrl+C`

---

## Breakdown

### Invokation

* `/V` enables delayed expansion, but is shorter than `setlocal EnableDelayedExpansion`, which is why we need the `cmd` call in the first place
* `/Q` omits the output and is equivalent to `@echo off`
* `/K` lets you execute an expression (In this case `g.cmd`) and does not exit afterwards, so you can check the 'Array' by using `set #`

### g.cmd

```
for /L %%A IN (0,1,16777215) DO (
    cmd /k exit %%A
    set #%%A=#!=exitcode:~2!
)

```

This bit uses a trick documented here to convert a normal number to a hexadecimal, then saves that value into an 'Array'.

---

I've been calling that storing structure an 'Array' but that is not actually right as true Arrays do not exist in Batch. BUT you can name variables so that they have arraylike names, like so:

```
set elem[1]=First element
set elem[2]=Second one

```

or, like in this case:

```
set #1=First element
set #2=Second one

```

You can still access them via `!#%position%!`
> 1 votes

# Answer
# , 25 bytes

```
8É00lrx16777215ñÄ<C-a>ñ0<C-v>Gls#

```

Try it online! (replaced `16777215` by `31`)

### Explanation

```
8É0                                " insert 8 zeroes
   0l                              " move cursor to the second character
     rx                            " replace by x
       16777215ñ      ñ            " 16777215 times do ..
                Ä                  " .. duplicate line
                 <C-a>             " .. increment (leading 0x makes sure it uses hexadecimals)
                       0<C-v>      " move cursor to beginning of line and start selection
                             Gl    " select the column with 0x
                               s#  " replace by #

```
> 1 votes

# Answer
# Java 10, ~~87~~ 84 bytes

```
v->{int i=1<<24;var r=new String[i];for(;i-->0;)r[i]="".format("#%06X",i);return r;}

```

-3 bytes thanks to *@archangel.mjj*.

Try it online (limited to the first `4,096` items).

**Explanation:**

```
v->{                       // Method with empty unused parameter & String-array return-type
  int i=1<<24;             //  Integer `i`, starting at 16,777,216
  var r=new String[i];     //  Result String-array of that size
  for(;i-->0;)             //  Loop `i` in the range (16777216, 0]
    r[i]=                  //   Set the `i`'th item in the array to:
      "".format("#%06X",i);//   `i` converted to a hexadecimal value (of size 6)
  return r;}               //  Return the result-array

```
> 0 votes

# Answer
# Groovy, 53 bytes

```
c={a=[];(1<<24).times{a.add "".format("#%06x",it)};a}

```

Function definition. c() returns an ArrayList (I assume that's fine, even through the question asks for an array).

Ungolfed, with implicit types:

```
ArrayList<String> c = {
    ArrayList<String> a = []
    (1 << 24).times {
        a.add("".format("#%06x", it)) // add the hex-formatted number to the list.
    }
    return a
}

```

Try it online!
> 0 votes

# Answer
# PHP, ~~68~~ 62 bytes

This is supposed to be placed inside a file, the array is returned in the end, to be usable.

```
<?foreach(range(0,1<<24)as$i)$a[]=sprintf('#%06x',$i);return$a;

```

To have access to the array, simply give the result of the include (e.g.: `$a = include 'xyz.php';`) to a variable.

---

Thanks to @manatwork for saving me 6 bytes and fix a goof.
> 0 votes

# Answer
# Lua, ~~47~~ 45 bytes

```
for i=1,8^8 do s='#%06X'print(s:format(i))end

```

Try it online!
> 0 votes

# Answer
# MATL, 11 bytes

```
'#'5Y26Z^Yc

```

Try it online! (with only three hex digits instead of six)

### Explanation

```
'#'   % Push this character
5Y2   % Push '01234567890ABCDEF'
6     % Push 6
Z^    % Cartesian power. Gives a (16^6)×6 char matrix
Yc    % String concatenation. '#' is implicitly replicated
      % Implicitly display

```
> 0 votes

# Answer
# Bash \+ jot, 22

```
jot -w\#%06X $[8**8] 0

```

Try it online!
> 0 votes

# Answer
# Perl 5, 31 bytes

```
printf"#%06X
",$_ for 0..8**8-1

```

Try it online!
> 0 votes

# Answer
# T-SQL, ~~122~~ 117 bytes

Returns a 16,777,216-row table of `#RRGGBB` strings. The line break is for readability only:

```
WITH t AS(SELECT 0n UNION ALL SELECT n+1FROM t WHERE n<16777215)
SELECT'#'+FORMAT(n,'X6')FROM t option(maxrecursion 0)

```

Uses a recursive CTE for a number table from 0 to 2^24-1, then uses the built-in `FORMAT` command (available in SQL 2012 or later) to turn it into a 6-digit hex string. Attach the `#` to the front, and we're done.

Edit 1: Removed `POWER()` function, the number was shorter :P
> 0 votes

# Answer
# Jelly, 12 bytes

```
⁴ṖṃØHœċ6ṭ€”#

```

Try it online!
> 0 votes

# Answer
# Pascal (FPC), ~~67~~ 65 bytes

*Saved 2 bytes thanks to @tsh*

```
var i:int32;begin for i:=1to 1<<24do writeln('#',hexStr(i,6))end.

```

Try it online!

Writes on standard output. It can be stored in an array using procedure, but it will be longer.
> 0 votes

# Answer
# Jelly, 8 bytes

```
ØHṗ6”#;Ɱ

```

Try it online! (note: uses `2` rather than `6` as `6` times out on TIO)

Function submission (because Jelly full programs will, by default, print lists of strings with no delimiters between them, making it hard to see the boundaries). The TIO link contains a wrapper to print a list of strings using newlines to separate them.

## Explanation

```
ØHṗ6”#;Ɱ
ØH         All hex digits (“0123456789ABCDEF”)
  ṗ6       Find all strings of 6 of them (order relevant, repeats allowed)
    ”#;    Prepend “#”
       Ɱ     to each of the resulting strings

```
> 0 votes

# Answer
# PHP, 43 bytes

```
<?php for(;$i<1<<24;printf("#%06X ",$i++));

```

Try it online!
> 0 votes

# Answer
# Perl 6, 26 bytes

```
{map *.fmt("#%06X"),^8**8}

```

Try it online!

Uses the same format as everyone else. Times out on TIO.

Or, in rgb format:

### 31 bytes

```
{map {"rgb($_)"},[X] ^256 xx 3}

```

Try it online!
> 0 votes

# Answer
# Scala, 40 bytes

```
(1 to 1<<24).map(x=>println(f"#$x%06x"))

```

Try it online!
> 0 votes

# Answer
# \>\<\>, 99 bytes

I added an extra space here to fix the layout, because of the `က` character, which is `4096` or `sqrt(2^24)` which is used in the main loop invariant.

```
!/ i&"ÿĀ"::*3ep4ep5ep\1+:&:5eg%n$o:4eg,:1%-5eg%n$o3eg,:1%-5eg%noo:*&:&(?;!
 >"က"a"),,(bgr"oooo&\

```

The idea is pretty simple: use the register as a counter `n` and output `rgb(n%255, (n/255)%255, (n/255^2)%255)`.

Pretty sure some bytes can be golfed off, but it's a start.

Try it online!
> 0 votes

# Answer
# Tcl, 53 bytes

```
time {puts #[format %06X [expr [incr i]-1]]} 16777216

```

Try it online!

Times out on TIO, but runs fine on my machine!
> 0 votes

---
Tags: code-golf, string, kolmogorov-complexity, color
---


title: Two dozen kissing number approximations

text:
# Question
Title: Two dozen kissing number approximations
Given a number from 1 to 24, output the kissing number to the best of current knowledge (some numbers will have more than one acceptable output). Knowledge of geometry is not essential as the outputs are all listed below.

From the Wikipedia page on the Kissing Number Problem:

> a kissing number is defined as the number of non-overlapping unit spheres that can be arranged such that they each touch another given unit sphere

That is, given one unit sphere, how many more unit spheres can touch it without any of them overlapping? The question will be asked in N dimensional space, where a sphere is understood to be an N-1 dimensional sphere.

For example:

* in 2 dimensional space, a unit circle can touch 6 other unit circles.
* in 3 dimensional space, a unit sphere can touch 12 other unit spheres.

The Wikipedia page lists values for 1 to 24 dimensional space. However, some of these are not yet known accurately, so only a lower and upper bound are given. The table is reproduced here so that it will remain fixed, regardless of any future narrowing of the ranges due to new proofs. Solutions are judged against this fixed table, even if the Wikipedia page is modified in future.

# Table of bounds

```
Dimension   Lower bound     Upper bound
1           2               2
2           6               6
3           12              12
4           24              24
5           40              44
6           72              78
7           126             134
8           240             240
9           306             364
10          500             554
11          582             870
12          840             1357
13          1154            2069
14          1606            3183
15          2564            4866
16          4320            7355
17          5346            11072
18          7398            16572
19          10668           24812
20          17400           36764
21          27720           54584
22          49896           82340
23          93150           124416
24          196560          196560

```

# Input

The dimension: An integer from 1 to 24 (inclusive).

Here "integer" indicates that the input will have no fractional part - it may be `2` or `3` but never `2.5`. A solution may still take input as a float, or a string, for example.

# Output

A number in the relevant range, from the lower limit to the upper limit for that input (inclusive).

The output must be deterministic (always the same for the same input).

The output must be integer. For example, for input `5` the possible valid outputs are `40`, `41`, `42`, `43`, `44`. Note this is a restriction on the value, not the type. It is acceptable to return a float, provided it has zero fractional part. For example, `41.5` would not be valid, but `41.0` would be valid.

# Scoring

This is . Your score is the number of bytes in your code. For each language, the winner is the solution with the lowest score.

# Answer
> 11 votes
# Julia 0.6, 52 bytes

```
n->ceil(n<8?3.7exp(.51n)-5.1:n<24?9exp(.41n):196560)

```

Try it online!

### How?

Machine learning! (Kinda. Maybe. *Not really.*)

First, from plotting the lower and upper limit data against N, and some manual trial and error, it seemed like an exponential function could fit well for N \>= 8. After some attempts at manually finding this function, I resorted to using a parameter tuning function to tune \\$ a * e^{b K} + c \\$ (where K = 8 to 24) to find a, b, and c such that the expression gave values that lie within the correct range for each K (with successively smaller range of possible values and correspondingly higher precisions for a, b, c in different runs of the function). There were a few such set of values, though none of them could fit the N=24 case exactly, so I went with one that had 0 `c` and hardcoded the value for N=24.

For lower N, from 1 to 7, I was hoping to find some simpler expression or polynomial, but couldn't find any that fit. So back to fitting \\$ a * e^{b K} + c \\$ , this time for K = 1 to 7 (though I didn't really think an exponential would be a right fit in this case, based on visual plot trends). Thankfully, there *were* parameters a, b, c that could give correct values throughout the range here (at least to within a `ceil` call).

# Answer
> 7 votes
# JavaScript (ES6), 60 bytes

```
f=(n,k=2)=>n<24?--n?f(n,k*24/(17+~'_8443223'[n])):~~k:196560

```

Try it online!

### How?

The last term \\$a\_{24}=196560\\$ is hard-coded.

All other terms are computed recursively, using:

$$\begin{cases}a\_1=2\\a\_{n+1}=a\_n\times\dfrac{24}{q\_n}\end{cases}$$

where \\$q\_n\\$ is defined as:

$$\begin{cases}q\_1=8\\q\_2=12\\q\_3=12\\q\_4=13\\q\_5=14\\q\_6=14\\q\_7=13\\q\_n=16,&\text{for }n\>7\end{cases}$$

leading to the following ratios:

$$3,2,2,\frac{24}{13},\frac{12}{7},\frac{12}{7},\frac{24}{13},\frac{3}{2},\frac{3}{2},\ldots,\frac{3}{2}$$

The final result is eventually floored and returned.

### Results summary

Approximated results are given with 2 decimal places.

```
  n |   a(n-1) | multiplier |      a(n) | output |          expected
----+----------+------------+-----------+--------+-------------------
  1 |      n/a |        n/a |         2 |      2 |                2
----+----------+------------+-----------+--------+-------------------
  2 |        2 |          3 |         6 |      6 |                6
  3 |        6 |          2 |        12 |     12 |               12
  4 |       12 |          2 |        24 |     24 |               24
  5 |       24 |      24/13 |     44.31 |     44 |        [40,..,44]
  6 |    44.31 |       12/7 |     75.96 |     75 |        [72,..,78]
  7 |    75.96 |       12/7 |    130.21 |    130 |      [126,..,134]
  8 |   130.21 |      24/13 |    240.39 |    240 |              240
  9 |   240.39 |        3/2 |    360.58 |    360 |      [306,..,364]
 10 |   360.58 |        3/2 |    540.87 |    540 |      [500,..,554]
 11 |   540.87 |        3/2 |    811.31 |    811 |      [582,..,870]
 12 |   811.31 |        3/2 |   1216.97 |   1216 |     [840,..,1357]
 13 |  1216.97 |        3/2 |   1825.45 |   1825 |    [1154,..,2069]
 14 |  1825.45 |        3/2 |   2738.17 |   2738 |    [1606,..,3183]
 15 |  2738.17 |        3/2 |   4107.26 |   4107 |    [2564,..,4866]
 16 |  4107.26 |        3/2 |   6160.89 |   6160 |    [4320,..,7355]
 17 |  6160.89 |        3/2 |   9241.34 |   9241 |   [5346,..,11072]
 18 |  9241.34 |        3/2 |  13862.00 |  13862 |   [7398,..,16572]
 19 | 13862.00 |        3/2 |  20793.01 |  20793 |  [10668,..,24812]
 20 | 20793.01 |        3/2 |  31189.51 |  31189 |  [17400,..,36764]
 21 | 31189.51 |        3/2 |  46784.26 |  46784 |  [27720,..,54584]
 22 | 46784.26 |        3/2 |  70176.40 |  70176 |  [49896,..,82340]
 23 | 70176.40 |        3/2 | 105264.59 | 105264 | [93150,..,124416]
----+----------+------------+-----------+--------+-------------------
 24 |           (hard-coded)            | 196560 |           196560

```

# Answer
> 7 votes
# x86, ~~62~~ ~~59~~ ~~53~~ 50 bytes

My solution uses a byte lookup table and shifting by 2 (no FP computations). Dimensions 9 through 23 provide enough leeway for the shifting. Input in `eax` and output in `ecx`.

-3 by swapping `eax` and `ecx` since `cmp $imm, %al` is shorter than `cmp $imm, %cl`.

-4 by *not* treating the N=24 case separately but applying the adjustment to all times 1024 cases.

-2 by not returning early (stupid)

-3 by using table as offset and `movzbl` instead of zeroing with `xor`

```
start:
        dec     %eax                # 1-indexed table

        movzbl  table(%eax), %ecx   # return byte directly
        cmp     $8, %al
        jl      exit

        sal     $6, %ecx            # * 64
        cmp     $19, %al
        jl      exit

        sal     $4, %ecx            # * 16
        sub     $48, %ecx

exit:
        ret

#.data
table:  .byte   2, 6, 12, 24, 40, 72, 126, 240              # * 1
        .byte   5, 8, 10, 14, 19, 26, 41, 68, 84, 116, 167  # * 64
        .byte   18, 28, 49, 92, 192                         # * 1024 - 48

```

Hexdump (table in `.text` instead of `.data`)

```
00000502  48 0f b6 88 1c 05 00 00  3c 08 7c 0d c1 e1 06 3c  |H.......<.|....<|
00000512  13 7c 06 c1 e1 04 83 e9  30 c3 02 06 0c 18 28 48  |.|......0.....(H|
00000522  7e f0 05 08 0a 0e 13 1a  29 44 54 74 a7 12 1c 31  |~.......)DTt...1|
00000532  5c c0                                             |\.|

```

# Answer
> 4 votes
# Jelly, ~~29~~ 26 bytes

```
“~D=ⱮziEc+y’Dḣ+⁵÷7PĊ«“£#;’

```

Try it online!

### How it works

```
“~D=ⱮziEc+y’Dḣ+⁵÷7PĊ«“£#;’  Main link. Argument: n

“~D=ⱮziEc+y’                Set the return value to 485523230101001100011122.
            D               Decimal; convert the return value to base 10.
             ḣ              Head; take the first n elements of the digit list.
              +⁵            Add 10 to each element.
                ÷7          Divide the sums by 7.
                  P         Take the product.
                   Ċ        Ceil; round up to the nearest integer.
                     “£#;’  Yield 196560.
                    «       Take the minimum.

```

# Answer
> 1 votes
# JavaScript (Node.js), ~~120~~ 99 bytes

Dropped 21 bytes. Big reduction thanks to tsh's suggestion to add a hole to the start of the array (saving two bytes going from `n-1` to `n`, and aiming for round numbers within the lower- and upper-bounds, thus shrinking them from fixed-point notation like `1154` to exponential notation like `2e3`.

Again, my original goal was to show how light the "dumb" way would be (eg not using any real math, like Arnauld's answer. It's impressive that there was still room to shrink it without any transformations or calculations.

```
n=>[,2,6,12,24,40,72,126,240,306,500,582,840,2e3,2e3,3e3,5e3,6e3,8e3,2e4,2e4,3e4,5e4,1e6,196560][n]

```

Try it online!

Twice the length of Arnauld's answer, 0 amount of the complexity.

# JavaScript (Node.js), ~~129~~ 128 bytes

(-1 byte thanks to suggestion to use bitshifting)

```
f=(n)=>[2,6,12,24,40,72,126,240].concat([5,8,10,14,19,26,41,68,84,116,167].map(x=>x<<6),[17,28,49,91].map(x=>x<<10),196560)[n-1]

```

Try it online!

To meet the demands of being interesting, I stole the logic from the x86 answer, and built the array from that. Making it 9 bytes longer. But slightly more interesting.

# Answer
> 1 votes
# Runic, 173 bytes

```
>i:8(?D5X1+1C,*212,+16,+1c2*,+1cX,+Sp3X7+a,*5X1+a,-1+kn$;
      R:c2*(?D4X1+1C,*212,+16,+1c2*,+Sp9*1+:4XY(?Dkn$;
             R`196560`r@;              ;$*C1nk,C1L

```

(Note that the lower right corner should be counted for bytes: they are implicitly filled with spaces.)

TIO's exe needs an update that this answer relies on (and I'm patching up some other holes before asking Dennis to rebuild). But plugging a value in (be sure to add whitespace on lines 2 and 3 if using more than one character for the value on the first line). Here's the easiest way to write the values needed:

```
0-9,a-f  ->  1-15
2Xn+     ->  20+n

```

Try it online!

Functionally this is a port of sundar's Julia answer (but Runic doesn't have a command for pushing `e` to the stack (or really, any decimal value), so an approximation was needed). The approximation for `e` for inputs less than 8 is more precise, as the loss of precision resulted in values lying outside the allowable range of outputs (e.g. `7` would produce 125). `Ceil()` was accomplished by converting to a character and then back to a number (this failed for exceptionally large values, so at 40k I had it divide by 100, do the conversion to and back, then multiply by 100 again).

There's probably some room to simplify the arrangement (e.g. running the entry point vertically, below, or finding a way to compress the approximations for `e`), but I'm happy with just being able to *do* the calculation.

```
/?D5X1+1C,*212,+16,+1c2*,+1cX,+Sp3X7+a,*5X1+a,-1+kn$;
  R:c2*(?D4X1+1C,*212,+16,+1c2*,+Sp9*1+:4XY(?Dkn$;
\(8:i<   R`196560`r@;              ;$*C1nk,C1L

```

161 bytes.

### Interpreter Update:

With the push fixing input reading, Runic now has several math functions and the ability to parse strings as doubles. That will vastly simplify this answer, but I will leave it as is to show off the effort I put into it (I added the single-argument Math functions and string parsing shortly after posting: I'd already had Sin/Cos/Tan on my to-do list, but hadn't considered Exp, Abs, Log, etc. and was running out of characters). TIO should update in the next 24-48 hours, depending on when Dennis sees it.

`212,+16,+1c2*,+1cX,+` would reduce to -\> `1'eA` with this interpreter update. `A` pops a character and a value and performs a Math operation on that value based on the character popped (`e` in this case is `Exp()` and `Exp(1)` returns *e*).

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


title: Smallest unique number KoTH

text:
# Question
Title: Smallest unique number KoTH
Create a bot to choose the smallest unique number.

(Based on a psychology experiment I heard about many years ago but haven't been able to track down again.)

### Rules

* Each game will consist of 10 randomly selected bots playing 1000 rounds.
* Each round, all bots select an integer from 1 to 10 (inclusive). Any bots that choose the same value will be be excluded, and the remaining bot with the smallest value will receive a point.
* In the event that no bot picks a unique value, no points will be awarded.
* At the end of 1000 rounds, the bot with the most points (or all bots tied with the most points) wins the game.
* The tournament will last 200 * (number of players) games.
* The bot with the highest win percentage wins the tournament.

### Specifications

Bots must be Python 3 classes and must implement two methods: `select` and `update`.
Bots will be constructed with an index.
`select` is passed no arguments and returns the bot's choice for the current round.
`update` is passed a list of the choices made by each bot in the previous round.

### Example

```
class Lowball(object):
    def __init__(self, index):
        # Initial setup happens here.
        self.index = index
    def select(self):
        # Decision-making happens here.
        return 1
    def update(self, choices):
        # Learning about opponents happens here.
        # Note that choices[self.index] will be this bot's choice.
        pass

```

### Controller

```
import numpy as np

from bots import allBotConstructors
allIndices = range(len(allBotConstructors))
games = {i: 0 for i in allIndices}
wins = {i: 0 for i in allIndices}

for _ in range(200 * len(allBotConstructors)):
    # Choose players.
    playerIndices = np.random.choice(allIndices, 10, replace=False)
    players = [allBotConstructors[j](i) for i, j in enumerate(playerIndices)]

    scores = [0] * 10
    for _ in range(1000):
        # Let everyone choose a value.
        choices = [bot.select() for bot in players]
        for bot in players:
            bot.update(choices[:])

        # Find who picked the best.
        unique = [x for x in choices if choices.count(x) == 1]
        if unique:
            scores[choices.index(min(unique))] += 1

    # Update stats.
    for i in playerIndices:
        games[i] += 1
    bestScore = max(scores)
    for i, s in enumerate(scores):
        if s == bestScore:
            wins[playerIndices[i]] += 1

winRates = {i: wins[i] / games[i] for i in allIndices}
for i in sorted(winRates, key=lambda i: winRates[i], reverse=True):
    print('{:>40}: {:.4f} ({}/{})'.format(allBotConstructors[i], winRates[i], wins[i], games[i]))

```

### Additional information

* No bot will play in a game against itself.
* In the unlikely event that a bot is included in less than 100 games, the tournament will be rerun.
* Bots may store state between rounds, but not between games.
* Accessing the controller or other bots is not allowed.
* The number of games and number of rounds per game are subject to increase if the results are too variable.
* Any bots that raise errors or give invalid responses (non-ints, values outside \[1, 10\], etc.) will be disqualified, and the tournament will be rerun without them.
* There is no time limit for rounds, but I may implement one if bots take too long to think.
* There is no limit on the number of submissions per user.
* ~~The deadline for submissions is 23:59:59 UTC on Friday, September 28.~~ The tournament is now closed for submissions.

### Results

```
                BayesBot: 0.3998 (796/1991)
      WhoopDiScoopDiPoop: 0.3913 (752/1922)
           PoopDiScoopty: 0.3216 (649/2018)
                   Water: 0.3213 (660/2054)
                 Lowball: 0.2743 (564/2056)
                Saboteur: 0.2730 (553/2026)
                OneUpper: 0.2640 (532/2015)
         StupidGreedyOne: 0.2610 (516/1977)
          SecondSaboteur: 0.2492 (492/1974)
                    T42T: 0.2407 (488/2027)
                     T4T: 0.2368 (476/2010)
          OpportunityBot: 0.2322 (454/1955)
              TheGeneral: 0.1932 (374/1936)
             FindRepeats: 0.1433 (280/1954)
                  MinWin: 0.1398 (283/2025)
             LazyStalker: 0.1130 (226/2000)
               FollowBot: 0.1112 (229/2060)
                Assassin: 0.1096 (219/1999)
           MostlyAverage: 0.0958 (194/2024)
             UnchosenBot: 0.0890 (174/1955)
                 Raccoon: 0.0868 (175/2015)
               Equalizer: 0.0831 (166/1997)
       AvoidConstantBots: 0.0798 (158/1980)
WeightedPreviousUnchosen: 0.0599 (122/2038)
               BitterBot: 0.0581 (116/1996)
               Profiteur: 0.0564 (114/2023)
              HistoryBot: 0.0425 (84/1978)
            ThreeFourSix: 0.0328 (65/1984)
                 Stalker: 0.0306 (61/1994)
             Psychadelic: 0.0278 (54/1943)
              Unpopulist: 0.0186 (37/1994)
             PoissonsBot: 0.0177 (35/1978)
         RaccoonTriangle: 0.0168 (33/1964)
              LowHalfRNG: 0.0134 (27/2022)
              VictoryPM1: 0.0109 (22/2016)
            TimeWeighted: 0.0079 (16/2021)
             TotallyLost: 0.0077 (15/1945)
            OneTrackMind: 0.0065 (13/1985)
              LuckySeven: 0.0053 (11/2063)
          FinalCountdown: 0.0045 (9/2000)
                Triangle: 0.0039 (8/2052)
           LeastFrequent: 0.0019 (4/2067)
                Fountain: 0.0015 (3/1951)
             PlayerCycle: 0.0015 (3/1995)
                  Cycler: 0.0010 (2/1986)
               SecureRNG: 0.0010 (2/2032)
             SneakyNiner: 0.0005 (1/2030)
            I_Like_Nines: 0.0000 (0/1973)

```

# Answer
> 12 votes
# BayesBot

Tries to make the optimal choice using a simple statistical model.

```
import random

def dirichlet(counts):
    counts = [random.gammavariate(n, 1) for n in counts]
    k = 1. / sum(counts)
    return [n * k for n in counts]

class BayesBot(object):
    def __init__(self, index):
        self.index = index
        self.counts = [[0.2 * (10 - i) for i in range(10)] for _ in range(10)]
    def select(self):
        player_distributions = []
        for i, counts in enumerate(self.counts):
            if i == self.index:
                continue
            player_distributions.append(dirichlet(counts))
        cumulative_unique = 0.
        scores = [0.] * 10
        for i in range(10):
            p_unpicked = 1.
            for d in player_distributions:
                p_unpicked *= (1. - d[i])
            p_unique = p_unpicked * sum(d[i] / (1. - d[i]) for d in player_distributions)
            scores[i] = p_unpicked * (1. - cumulative_unique)
            cumulative_unique += p_unique * (1. - cumulative_unique)
        return scores.index(max(scores)) + 1
    def update(self, choices):
        for i, n in enumerate(choices):
            self.counts[i][n - 1] += 1

```

# Answer
> 12 votes
# Avoid Constant Bots

Keep track of which bots have always returned the same value, and skip those values. Of the remaining values, select them randomly, but biased significantly towards lower values.

```
import numpy as np

class AvoidConstantBots(object):
    all_values = range(1, 11)
    def __init__(self, index):
        self.index = index
        self.constant_choices = None

    def select(self):
        available = set(self.all_values)
        if self.constant_choices is not None:
            available -= set(self.constant_choices)
        if len(available) == 0:
            available = set(self.all_values)
        values = np.array(sorted(available))
        weights = 1. / (np.arange(1, len(values) + 1)) ** 1.5
        weights /= sum(weights)
        return np.random.choice(sorted(available), p=weights)

    def update(self, choices):
        if self.constant_choices is None:
            self.constant_choices = choices[:]
            self.constant_choices[self.index] = None
        else:
            for i, choice in enumerate(choices):
                if self.constant_choices[i] != choice:
                    self.constant_choices[i] = None

```

# Answer
> 11 votes
# WaitWhatBot

Not the most competitive bot and definitely not GTO, but will stifle the score of any "always 1" or "nearly always 1" opponent in the same game as in such a scenario WaitWhatBot becomes such a bot too.

Uses evolving probabilities with weighted weights both in time (more recent -\> greater weight) and choice value (lower point -\> greater weight).

Uses somewhat obfuscated code for a bit of a giggle.

```
from random import choices as weightWeight
class WaitWhatBot(object):
    def __init__(wait,what):
        weight,weightWhat=5,2
        wait.what,wait.weight=what,(weight**(weight/weight/weightWhat)+weightWhat/weightWhat)/weightWhat
        wait.whatWeight,wait.weightWeight=[wait.what==wait.weight]*int(wait.weight**weight),wait.weight
        wait.whatWhat=wait.whatWeight.pop()#wait, when we pop weight off whatWeight what weight will pop?
        wait.waitWait=tuple(zip(*enumerate(wait.whatWeight,wait.weightWeight!=wait.whatWeight)))[weightWeight==wait.weight]
    def select(what):return int(what.weight**what.whatWhat if all(not waitWait for waitWait in what.whatWeight)else weightWeight(what.waitWait,what.whatWeight)[what.weight==what.what])
    def update(waitWhat,whatWait):
        what,wait,weightWhat=set(wait for wait in whatWait[:waitWhat.what]+whatWait[waitWhat.what+1:]if wait in waitWhat.waitWait),-~waitWhat.whatWhat,waitWhat.weightWeight
        while wait not in what:
            waitWhat.whatWeight[wait+~waitWhat.whatWhat]+=weightWhat
            weightWhat/=waitWhat.weight
            wait-=~waitWhat.whatWhat
        if not wait!=(what!=weightWhat):waitWhat.whatWeight[waitWhat.whatWhat]+=weightWhat
        waitWhat.weightWeight*=waitWhat.weight

```

# Answer
> 5 votes
# Flow Like Water

Avoids basic constant bot detection algorithms by doubling up on each number, slowly advancing toward lower values if they're unoccupied.

```
class Water(object):
    def __init__(self, index):
        self.index = index
        self.round = 0
        self.play = 4
        self.choices = [0]*10

    def select(self):
        if self.round > 0 and self.round%2 == 0:
            if not max([1, self.play - 1]) in self.choices:
                self.play -= 1
        return self.play

    def update(self, choices):
        self.round += 1
        self.choices = choices

```

# Answer
> 5 votes
# Stalker

At the start of the game, this bot randomly chooses a specific index as its target. It then stalks that target the entire game, copying the number that it chose in the previous round.

```
import random

class Stalker(object):
  def __init__(self, index):
    # choose a random target to stalk that isn't ourself
    self.targetIndex = random.choice([x for x in range(10) if x != index])
    # get a random number to start with since we haven't seen our target's value yet
    self.targetValue = random.randint(1, 10)
  def select(self):
    return self.targetValue
  def update(self, choices):
    # look at what our target chose last time and do that
    self.targetValue = choices[self.targetIndex]

```

# Answer
> 5 votes
# Whoop-di-scoop-di-poop

```
class WhoopDiScoopDiPoop(object):
    def __init__(self, index):
        self.index = index
        self.guess = 1
        self.tenure = 0
        self.perseverance = 4

    def select(self):
        return self.guess

    def update(self, choices):
        others = {c for i, c in enumerate(choices) if i != self.index}
        for i in range(1, self.guess):
            if i not in others:
                self.guess = i
                self.tenure = 0
                self.perseverance += 1
                return
        if self.guess not in others:
            self.tenure = 0
            return
        self.tenure += 1
        if self.tenure > self.perseverance:
            if self.guess == 10:
                return
            self.guess += 1
            self.tenure = 0

```

# Poop-di-scoopty

```
class PoopDiScoopty(object):
    def __init__(self, index):
        self.index = index
        self.guess = 1
        self.tenure = 0
        self.perseverance = 4

    def select(self):
        return self.guess

    def update(self, choices):
        others = [c for i, c in enumerate(choices) if i != self.index]
        for i in range(1, self.guess):
            if i not in others:
                self.guess = i
                self.tenure = 0
                self.perseverance += 1
                return
        if self.guess not in others:
            self.tenure = 0
            return
        self.tenure += others.count(self.guess) # this is the change
        if self.tenure > self.perseverance:
            if self.guess == 10:
                return
            self.guess += 1
            self.tenure = 0

```

I've never seen or touched Python, is this unpythonic?

# Answer
> 5 votes
# Opportunitybot

This bot keeps track of the lowest number not chosen by any other bots each round (the lowest available number, or opportunity), and plays the number that has been that number most frequently.

```
class OpportunityBot(object):
    def __init__(self, index):
        self.index = index
        self.winOccasions = [0,0,0,0,0,0,0,0,0,0]

    def select(self):
        return self.winOccasions.index(max(self.winOccasions))+1

    def update(self, choices):
        choices.pop(self.index)
        succeeded = [choices.count(i)==0 for i in range(1,11)]
        self.winOccasions[succeeded.index(True)] += 1

```

# Answer
> 4 votes
# The top 50% RNG bot

```
import random

class LowHalfRNG(object):
    def __init__(self, index):
        pass
    def select(self):
        return random.randint(1, 5)
    def update(self, choices):
        pass

```

I was about to post a random bot, but hidefromkgb posted before me (by posting they're making themselves an easy target for the KGB, not a good way to hide). This is my first KOTH answer, just hoping to beat the rng bot.

# Answer
> 4 votes
# Stupid Greedy One

```
class StupidGreedyOne(object):
    def __init__(self, index):
        pass
    def select(self):
        return 1
    def update(self, choices):
        pass

```

This bot assumes that other bots don't want to tie.

I realize this is the same as the provided example but I had the thought before I'd read that far. If this is incongruous with how KoTH challenges are run, let me know.

# Answer
> 4 votes
# HistoryBot

```
import random

class HistoryBot(object):
    def __init__(self, index):
        self.pastWins = []
    def select(self):
        if not self.pastWins:
            return 1
        return random.choice(self.pastWins)
    def update(self, choices):
        unique = [x for x in choices if choices.count(x) == 1]
        if unique:
            self.pastWins.append(min(unique))

```

Implementation of user2390246's comment:

> What about this then? Start with 1. After the first round, keep track of the winning values and pick randomly from them with probability equal to the number of occurrences. E.g. if the winning values in the first three rounds are \[2, 3, 2\] then in round four, pick \[2\] with p = 2/3 and \[3\] with p = 1/3.

# Answer
> 4 votes
## OneUpper

```
class OneUpper(object):
    def __init__(self, index):
        self.index = index
    def select(self):
        return 2
    def update(self, choices):
        pass

```

Everyone else's bots are either aiming for 1 or random, so why not just aim for 2?

# Answer
> 4 votes
# The Final Countdown

```
class FinalCountdown(object):
    def __init__(self, index):
        self.round = -1
    def select(self):
        self.round += 1
        return (10 - self.round // 100)
    def update(self, choices):
        pass

```

Try it online!

Returns 10 for the first 100 rounds, 9 for the next 100 and so on.

# Answer
> 4 votes
# PatterMatcher

Looks for repeating sections in the submissions of the bots, tries to predict and avoid there numbers.

```
class PatternMatcher(object):
    def __init__(self, index):
        self.bots=[[]]*9
        self.index=index
    def select(self):
        minVisible=3    #increase these if this bot is to slow
        minOccurences=2
        predictions=set()
        for bot in self.bots:
            #match patters of the form A+(B+C)*minOccurences+B and use C[0] as a prediction
            for lenB in range(minVisible,len(bot)//(minVisible+1)+1):
                subBot=bot[:-lenB]
                patterns=[]
                for lenBC in range(lenB,len(subBot)//minOccurences+1):
                    BC=subBot[-lenBC:]
                    for i in range(1,minOccurences):
                        if BC!=subBot[-lenBC*i-lenBC:-lenBC*i]:
                            break
                    else:
                        patterns.append(BC)
                predictions|={pattern[lenB%len(pattern)] for pattern in patterns}
        other=set(range(1,11))-predictions
        if other: return min(other)
        else: return 1

    def update(self, choices):
        j = 0
        for i,choice in enumerate(choices):
            if i == self.index:
                continue
            self.bots[j].append(choice)
            j += 1

```

# Triangle

The chance of picking n is `(10-n)/45`

```
import random
class Triangle(object):
    def __init__(self, index):pass
    def select(self):return random.choice([x for x in range(1, 11) for _ in range(10 - x)])
    def update(self, choices):pass

```

# TimeWeighted

The probability a bot chooses a number is proportional to `(10-n)*Δt`. The first round this is identical to triangle.

```
import random
class TimeWeighted(object):
    def __init__(self, index):
        self.last=[0]*10
        self.round=1
    def select(self):
        weights=[(self.round-self.last[i])*(10-i) for i in range(10)]
        return 1+random.choice([x for x in range(10) for _ in range(weights[x])])

    def update(self, choices):
        for c in choices:
            self.last[c-1]=self.round
        self.round+=1

```

# LeastFrequent

Submits the least frequently occurring number, if they are equal, take the lowest one.

```
class LeastFrequent(object):
    def __init__(self, index):self.frequenties=[0]*10
    def select(self):return 1+self.frequenties.index(min(self.frequenties))
    def update(self, choices):
        for c in choices:
            self.frequenties[c-1]+=1

```

# LongestTime

Same as with frequenties but with the longest time between submissions.

```
class LongestTime(object):
    def __init__(self, index):
        self.frequencies=[0]*10
        self.round=1
    def select(self):return 1+self.frequencies.index(min(self.frequencies))
    def update(self, choices):
        for c in choices:
            self.frequencies[c-1]=self.round
        self.round+=1

```

# Saboteur

Submits the lowest number which was submitted last time.

```
class Saboteur(object):
    def __init__(self, index):self.last=[1]
    def select(self):return min(self.last)
    def update(self, choices):self.last=choices

```

# SecondSaboteur

Submits the second lowest number which was submitted last time

```
class SecondSaboteur(object):
    def __init__(self, index):self.last=[1,2]
    def select(self):return min({i for i in self.last if i!=min(self.last)})
    def update(self, choices):self.last=choices

```

# Profiteur

Submits the lowest number not submitted last time

```
class Profiteur(object):
    def __init__(self, index):self.last=set()
    def select(self):return min(set(range(1, 11))-self.last, default=1)
    def update(self, choices):self.last=set(choices)

```

Sorry I got a bit carried away, getting idea for new bots while implementing the previous once. I wasn't sure which one would be the best and I'm curious about the performance of each of them. You can find them all here: https://repl.it/@Fejfo/Lowest-Unique-Number

# Answer
> 3 votes
# Totally Lost

```
class TotallyLost(object):
    def __init__(self, index):
        self.index = index
        self.round = 0
        self.numbers = [4,8,1,5,1,6,2,3,4,2]
    def select(self):
        return self.numbers[self.round % len(self.numbers)]
    def update(self, choices):
        self.round = self.round + 1

```

# Answer
> 3 votes
# The Cycler

This bot simply cycles through each of the numbers on its turns. Just for fun, it initializes the counter with its index.

```
class Cycler(object):
  def __init__(self, index):
    self.counter = index # Start the count at our index
  def select(self):
    return self.counter + 1 # Add 1 since we need a number between 1-10
  def update(self, choices):
    self.counter = (self.counter + 1) % 10

```

# Answer
> 3 votes
## OneTrackMind

This bot randomly picks a number and sticks with it for 50 rounds, then picks another and repeats.

```
import random

class OneTrackMind(object):
    def __init__(self, index):
        self.round = 0;
        self.target = random.randint(1,10)
    def select(self):
        return self.target
    def update(self, choices):
        self.round += 1;
        if self.round % 50 == 0:
            self.target = random.randint(1,10)

```

# Answer
> 3 votes
# Lucky Seven

```
class LuckySeven(object):
    def __init__(self, index):
        pass
    def select(self):
        return 7
    def update(self, choices):
        pass

```

I'm feeling lucky today! I'm throwing out everything on 7!

# Answer
> 3 votes
My idea is that the strategy is more dependent on the number of bots than on actual evaluation of strategies.

With a significant number of bots, the options are:

* "Greedy" robots aiming to the lower 1-3 numbers 10 bots being "clever" and aiming to get the lower 1-3 numbers, the best is to just let those bots interfere between them.
* "Smart" robots who, once they realize 4 is always picked up, will go elsewhere.
* "Random" and "constant" robots. Not much to do here.

So, I bet on #4.

```
class LazyStalker(object):
    def __init__(self, index):
        pass
    def select(self):
        return 4
    def update(self, choices):
        pass

```

# Answer
> 2 votes
# The essential RNG bot

```
import secrets

class SecureRNG(object):
    def __init__(self, index):
        pass
    def select(self):
        return secrets.randbelow(10) + 1
    def update(self, choices):
        pass

```

# Answer
> 2 votes
# Fountain

A simple bot, picks the lowest number first and if any other bot chooses it too, it will increment the counter - the floor gets filled and the water flows down. When it reaches 11, it restarts to 1 - the water gets pumped back to the top.

```
class Fountain:

    def __init__(self, index, target=10):

        # Set data
        self.index = index
        self.pick  = 1
        self.target = target+1

    def select(self):

        # Select the number
        return self.pick

    def update(self, choices: list):

        # Remove self from the list
        choices.pop(self.index)  # I hope `choices[:]` is passed, not `choices`.

        # While the selected number is occupied
        while self.pick in choices:

            # Pick next number
            self.pick += 1

            # If target was reached
            if self.pick == self.target:

                # Reset to 1
                self.pick = 1

```

# Answer
> 2 votes
# Assassin

Stays in the shadows, then aims for the current lowest guess. Run.

```
class Assassin(object):
    def __init__(self, index):
        self.index = index
        self.round = 0
        self.choices = [0]*10

    def select(self):
        if self.round == 0:
            return 10
        else:
            return min(self.choices)

    def update(self, choices):
        self.round += 1
        self.choices = choices
        self.choices[self.index] = 10

```

# Answer
> 2 votes
# FollowBot

Copy the winner from the last round, or at least the best minimally-tied selection if there was no winner.

```
import collections

class FollowBot(object):
    def __init__(self, index):
        self.lastround = []

    def select(self):
        counter = collections.Counter(self.lastround)
        counts = [(count,value) for (value,count) in counter.items()]
        counts.sort()
        if len(counts) >= 1:
            return counts[0][1]
        else:
            return 1

    def update(self, choices):
        self.lastround = choices

```

# Answer
> 2 votes
# PoissonsBot

Select numbers from a Poisson distribution which is biased to lower values. Adjust the mean parameter of the distribution up if we are in a tie and down if there are guesses below us. Step size gets progessively smaller as the game proceeds.

```
from numpy.random import poisson
import math

class PoissonsBot(object):
    def __init__(self, index):
        self.index = index
        self.mean = 2
        self.roundsleft = 1000

    def select(self):
        self.roundsleft = max(self.roundsleft-1, 2)
        return max(min(poisson(self.mean),10),1)

    def update(self, choices):
        myval = choices[self.index]
        nequal = len([c for c in choices if c==myval])
        nless = len([c for c in choices if c<myval])
        step = math.log10(self.roundsleft)
        if nequal > 1:
            self.mean += nequal/step
        self.mean -= nless/step
        self.mean = max(self.mean, 0.3)

```

# Answer
> 2 votes
## Psychadelic

The only way to win a nuclear war is to make yourself insane. So I'm going to make every predictive bot in the tournament insane.

```
class Psychadelic(object):
    def __init__(self, index):
        self.index = index
    def select(self):
        return random.randint(1, self.index + 1)
    def update(self, choices):
        pass

```

# Answer
> 2 votes
# UnchosenBot

```
class UnchosenBot(object):
    def __init__(self, index):
        self.index = index
        self.answer = 0
    def select(self):
        if self.answer == 0:
            return 1
        return self.answer
    def update(self, choices):
        self.answer = 0
        del choices[self.index]
        for x in range(1, 11):
            if x not in choices:
                self.answer = x
                return

```

Takes the last round's choices, and chooses the lowest unchosen number (ignoring UnchosenBot's choice, of course).

# Answer
> 2 votes
# MinWin

Keeps a running count of the winning values and the minimum unselected values (where the minimum unselected value is only considered if it is less than the winning value). It randomly selects among these winning and minimum values.

```
import random

class MinWin:

    def __init__(self, index):
        self.index = index
        self.mins = list(range(1, 11))
        self.wins = list(range(1, 11))

    def select(self):
        return min(random.choice(self.mins), random.choice(self.wins))

    def update(self, choices):
        counts = [0] * 10
        for x in choices:
            counts[x - 1] += 1

        if 0 in counts and (1 not in counts or counts.index(0) < counts.index(1)):
            self.mins.append(counts.index(0) + 1)
        if 1 in counts:
            self.wins.append(counts.index(1) + 1)

```

# Answer
> 2 votes
# PlayerCycle

Cycles through the players. Current player (could be self)'s choice is now this bot's choice. Starts out printing 8, because why not. Sorry I can't python, this is probably bad code.

```
import itertools
class PlayerCycle(object):
    def __init__(self, index):
        self.a = itertools.cycle(range(10))
        self.b = 8
    def select(self):
        return self.b
    def update(self, choices):
        self.b = choices[next(self.a)]

```

Edit: Thanks to Triggernometry for improving my code with itertools

# Answer
> 2 votes
# **Raccoon**

Choose the lowest number not chosen in the previous round, except our own previous choice, which could be chosen again this time. In the first round, choose 1. (Given 9 opponents and 10 choices, there is guaranteed to be one available value.)

I came up with this independently, but now see at least 2 previous bots that are essentially the same.

```
class Raccoon(object):
    def __init__(self, index):
        self.index = index
        self.last_round = None
        self.domain = None
    def select(self):
        # Return the lowest number not chosen last time.
        if self.domain is None:
            return 1
        else:
            # This finds the smallest element of domain, not present in last_round
            return min(self.domain-self.last_round)
    def update(self, choices):
        last_round = choices[:]
        last_round[self.index] = 0 # don't include our own choice
        self.last_round = set(last_round)
        if self.domain is None:
            self.domain = set(range(1,len(choices)+1))

```

# **Raccoon Triangle**

Combines Raccoon and Triangle: from the unchosen values, choose one based on reverse triangle probability.

```
import random
class RaccoonTriangle(object):
    def __init__(self, index):
        self.index = index
        self.unchosen = set([1,])
        self.domain = None
    def select(self):
        # Return the lowest number not chosen last time.
        if self.domain is None:
            return random.randint(1,self.index+1)
        else:
            # Reverse triangle weights for unchosen values
            weighted_choices = [u for i,u in enumerate(sorted(self.unchosen),0) for _ in range(len(self.unchosen)-i)]
            return random.choice(weighted_choices)
    def update(self, choices):
        last_round = choices[:] # make a copy
        last_round[self.index] = 0 # don't include our own choice
        if self.domain is None:
            self.domain = set(range(1,len(choices)+1))
        self.unchosen = self.domain - set(last_round)

```

# Answer
> 1 votes
# The General

The General always fights the last war*(s)*.

```
import numpy
import random

class TheGeneral:
    def __init__(self, index):
        self.round = 0
        self.index = index
        self.would_have_won = [0] * 10

    def select(self):
        if self.round <= 100:
            return random.choice((list(numpy.nonzero(self.would_have_won)[0]) + [0, 1])[:2]) + 1

        return random.choice(numpy.argsort(self.would_have_won)[-2:]) + 1

    def update(self, choices):
        for i, s in enumerate(numpy.bincount([c - 1 for i, c in enumerate(choices)
            if i != self.index], minlength=10)):

            if s == 0:
                self.would_have_won[i] += 1
            elif s == 1:
                break

        self.round += 1

```

# Answer
> 1 votes
# No-Repeat Random

```
import secrets

class NoRepeats(object):
    def __init__(self, index):
        self.lastround = secrets.randbelow(10) + 1

    def select(self):
        i = secrets.randbelow(10) + 1
        while i == self.lastround:
             i = secrets.randbelow(10) + 1
        self.lastround = i
        return self.lastround

    def update(self, choices):
        pass

```

Bot picks randomly, but avoids picking the same number it did the previous round.

# Answer
> 1 votes
# Tit for two Tats

T4T, but uses the value from two rounds ago.

```
class T42T(object):
    def __init__(self, _):
        self.next = [10, 9]
    def select(self):
        return self.next.pop(0)
    def update(self, choices):
        choice = 10
        for c in choices:
            choice = min(c, choice)
        choice += 1
        if(choice > 10): choice = 10
        self.next.append(choice)

```

# Answer
> 1 votes
## MostlyAverage

```
import random
import math

class MostlyAverage(object):
    def __init__(self, index):
        self.total = 0
        self.count = 0
    def select(self):
        returner = []
        if self.count > 0:
            avg = math.floor(self.total / self.count)
            if avg > 1:
                returner.append(avg-1)
            if avg < 10:
                returner.append(avg+1)
            returner.append(avg)
            returner.append(avg)
        else:
            returner.append(1)
        return returner[random.randint(0, len(returner)-1)]
    def update(self, choices):
        for x in range(11):
            if choices.count(x) == 1:
                self.total += x
                self.count += 1
                break

```

Keeps track of the average winning number and returns a number close to it.

# Answer
> 1 votes
## I Like Nines

This bot is bored, and doesn't like mind games. So they choose a random number every turn. However, they only have a d16 and don't want to disrupt the game to go find a d10 - so they choose 9 anytime they roll greater than 10!

EDIT: Just to be contrary, if own index is 9, the bot will instead prefer 6 when they roll greater than 10.

```
import random

class I_Like_Nines(object):
    def __init__(self, index):
        self.index = index

    def select(self):
        r = 0
        # 4 bits are required to code 1-10 ([0-9] + 1, [0b0000 - 0b1001] + 1)
        for i in range(0, 4):
            # flip a coin. Puts a 1 in this bit place 50% of the time
            if random.random() >= .50:
                r += 2 ** i
        # if your random bit assigning has produced a number outside the range 1-10, prefer 9
        if not (0 < r < 11):
            # when you are Bot #9, prefer 6
            if self.index == 9:
                r = 6
            else:
                r = 9
        return r

    def update(self, choices):
        pass

```

# Answer
> 1 votes
# BitterBot

Chooses randomly for 100 rounds, then targets the bot with the most wins (besides itself) to that point and mimics it for the rest of the game.

```
import random

class BitterBot(object):
    def update_score(self, choices):
        for element in sorted(choices):
            if choices.count(element) == 1:
                self.scores[choices.index(element)] += 1
                return
        return

    def choose_target(self):
        other_bot_scores = list(self.scores)
        del(other_bot_scores[self.index])
        return self.scores.index(max(other_bot_scores))

    def __init__(self, index):
        self.scores = [0] * 10
        self.index = index
        self.round_num = 0
        self.target_index = 0
        self.target_choice = 0

    def select(self):
        if self.round_num <= 100:
            return random.choice(range(1,5))
        else:
            return self.target_choice

    def update(self, choices):
        self.round_num += 1
        if self.round_num < 100:
            self.update_score(choices)
        elif self.round_num == 100:
            self.target_index = self.choose_target()
        else:
            self.target_choice = choices[self.target_index]

```

# Answer
> 1 votes
## Equalizer

```
class Equalizer(object):
    def __init__(self,index):
        self.chosen = []
        self.wins = {}
        for x in range(10):
            self.chosen.append([])
            self.wins[x] = 0
        self.choice = 1
    def select(self):
        return self.choice
    def update(self,choices):
        winningnum = 0
        for x in range(11):
            if choices.count(x) == 1:
                winningnum = x
                break
        for x in range(10):
            self.chosen[x].append(choices[x])
            if choices[x] == winningnum:
                self.wins[x] += 1
        bests = [key for key in self.wins.keys() if self.wins[key] == max(self.wins.values())]
        if len(bests) > 0:
            target = bests[random.randint(0, len(bests)-1)]
            if len(self.chosen[target]) > 2:
                shortlist = self.chosen[target][-20:]
                match = self.chosen[target][-1]
                match2 = self.chosen[target][-2]
                lastmatch = 0
                foundit = 0
                for k,v in enumerate(shortlist):
                    if k < 19:
                        if lastmatch == 1:
                            if shortlist[k] == match:
                                lastmatch = 2
                            else:
                                lastmatch = 0
                        elif lastmatch == 2:
                            self.choice = v
                            foundit = 1
                            break
                        elif shortlist[k] == match2:
                            lastmatch = 1
                if foundit == 0:
                    lastmatch = 0
                    for k,v in enumerate(shortlist):
                        if k < 19:
                            if lastmatch == 1:
                                self.choice = v
                                foundit = 1
                                break
                            elif shortlist[k] == match:
                                lastmatch = 1

```

Tries to keep the scores in the lead as even as possible by attempting to match what the first place bot will play, looking for patterns in their recent selections. It works on some bot combinations better than others, but I have seen many games within one/two points or even tied at the end.

# Answer
> 0 votes
# ThreeFourSix

Start with 6, then randomly pick one of 3, 4, 6, excluding the one picked in the previous round.

Seeing other (random) bots picking 1 or 2 each round and picking values \< 5 or lower values more often, hopefully using 3, 4 and 6 is a good combination.

```
class ThreeFourSix(object):
    def __init__(self, index):
        self.index = index
        self.guess = 6
    def select(self):
        return self.guess
    def update(self, choices):
        threeFourSix = [3, 4, 6]
        threeFourSix.remove(choices[self.index])
        self.guess = threeFourSix[random.randint(0, 1)]

```

# Answer
> 0 votes
## Unpopulist

```
import random

class Unpopulist(object):
    def __init__(self, index):
        self.index = index
        self.choices = [0, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
    def select(self):
        pos = random.randrange(sum(self.choices))
        for i in range(1, 11):
            if pos < self.choices[i]:
                return i
            pos -= self.choices[i]
    def update(self, choices):
        choices[self.index] = 0;
        for i in range(1, 11):
            if choices.count(i) < 2:
                self.choices[i] += 11 - i

```

Prefers lower numbers as long as they don't get too many collisions.

# Answer
> 0 votes
# Tit for Tat

Plays 10, then the smallest value plus one last round.

```
class T4T(object):
    def __init__(self, _):
        self.next = 10
    def select(self):
        return self.next
    def update(self, choices):
        choice = 10
        for c in choices:
            choice = min(c, choice)
        choice += 1
        if(choice > 10): choice = 10
        self.next = choice

```

# Answer
> 0 votes
# Victory Plus Minus One

Randomly picks one above or below the last victory number.

```
import random

class VictoryPM1(object):
    def __init__(self, index):
        self.index = index
        self.victory = 0

    def select(self):
        if self.victory < 1 or self.victory > 10:
            return 1
        elif random.randint(0, 1):
            if self.victory < 2:
                return 2
            else:
                return self.victory - 1
        else:
            if self.victory > 9:
                return 9
            else:
                return self.victory + 1

    def update(self, choices):
        a = [0] * 11
        for b in choices:
            a[b] += 1
        for i in range(1, 10):
            if a[i] == 1:
                self.victory = i
                return

```

# Answer
> 0 votes
Nobody likes high numbers but somebody might decide to go for 10 as the least obvious pick. Avoid those tricksters and sneak in with a 9.

```
class SneakyNiner(object):
    def __init__(self, index):
        self.index = index
    def select(self):
        return 9
    def update(self, choices):
        pass

```

# Answer
> 0 votes
## FindRepeats

```
class FindRepeats(object):
    def __init__(self,index):
        self.wins = []
    def select(self):
        returner = 1
        length = len(self.wins)
        if length > 10 and self.wins[-1] == self.wins[-6] and self.wins[-2] == self.wins[-7] and self.wins[-3] == self.wins[-8] and self.wins[-4] == self.wins[-9] and self.wins[-5] == self.wins[-10]:
            returner = self.wins[-5]
        if length > 8 and self.wins[-1] == self.wins[-5] and self.wins[-2] == self.wins[-6] and self.wins[-3] == self.wins[-7] and self.wins[-4] == self.wins[-8]:
            returner = self.wins[-4]
        if length > 6 and self.wins[-1] == self.wins[-4] and self.wins[-2] == self.wins[-5] and self.wins[-3] == self.wins[-6]:
            returner = self.wins[-3]
        if length > 4 and self.wins[-1] == self.wins[-3] and self.wins[-2] == self.wins[-4]:
            returner = self.wins[-2]
        if length > 2 and self.wins[-1] == self.wins[-2]:
            returner = self.wins[-1]
        return returner
    def update(self,choices):
        for x in range(11):
            if choices.count(x) == 1:
                self.wins.append(x)
                break

```

Tries to find patterns in the most recent winning numbers and continue the pattern if it finds one.

# Answer
> 0 votes
# WeightedPreviousUnchosen

Selects from the previous round's unchosen numbers. In order, each has the chance to be chosen equal to 1.25 * (the frequency at which they remained unchosen in the next round).

```
class WeightedPreviousUnchosen(object):

    def get_unchosen(self, list):
        unique_choices = []
        duplicate_choices = []
        for choice in list:
            if choice not in duplicate_choices:
                if choice in unique_choices:
                    duplicate_choices.append(choice)
                    unique_choices.remove(choice)
                else:
                    unique_choices.append(choice)
        return unique_choices

    def __init__(self, index):
        self.previous_unchosen = []
        self.current_choices = []
        self.unchosen_history = []
        for n in range (0, 10):
            self.unchosen_history.append([0, 0])

    def select(self):
        current_unchosen = sorted(self.get_unchosen(self.current_choices))
        if len(self.previous_unchosen) > 0:
            rand = random.random()
            for n in range(0, len(current_unchosen) - 1):
                option = (self.unchosen_history)[n]
                if option[0] != 0:
                    if ( (option[1] / option[0])*1.25 > rand):
                        self.previous_unchosen = current_unchosen
                        return sorted(self.get_unchosen(self.current_choices))[n]

        self.previous_unchosen = current_unchosen
        return random.choice(range(2,5))

    def update(self, choices):
        self.current_choices = choices
        for n in range(1, 10):
            if n in self.previous_unchosen:
                self.unchosen_history[n-1][0] += 1
                if n not in choices:
                    self.unchosen_history[n-1][1] += 1

```

Based on the premise that bots could be missing would-be-winning numbers. Looks like this generally isn't the case, so it isn't performing too well!

---
Tags: king-of-the-hill
---