title: Implement Amb and Require

text:
# Question
Title: Implement Amb and Require
# The Challenge

Implement **amb** and its sister statement **require** in whatever language you wish. See http://community.schemewiki.org/?amb for an example implementation in Scheme. You can rename them to **a** and **r**.

**amb** statements select a value passed to it arbitrarily, and **require** statements written *after* **amb** contain conditionals that limit the possibilities that **amb** will return, as the conditionals must evaluate to true. statements The pseudocode

```
fun rand() {
    return amb(1, 2, 3, 4)
}

```

will return whatever the computer feels like as long as it is 1, 2, 3 or 4. However the pseudocode

```
fun arbitary2 {
    x = amb(1, 2, 3, 4)
    y = square(x)
    require(even(y))
    return x
}

```

can only ever *eventually* return 2 or 4, but a user may not know which one will return. Depending on implementation, 2 may always be returned, or 4, or 2 is returned 3% of the time and so on. **require** can be called *any* time after **amb** is called as long as both statements are in the same program, even outside of the scope of **amb**, so

```
fun foo() {
    amb(1,2,3,4)
}
x = foo()
y = foo()
require(x > y)

```

is valid and x will never be less than y when the program successfully terminates. The degree to which this is possible varies language by language, so try your best to implement this. The following code should not successfully terminate:

```
amb(1, 2, 3, read("notes.txt"))
require(false)
print("this will never be printed")

```

The actual names and exact syntax of **amb** and **require** don't matter. For example, if your implementation is in assembly, then having **amb** read from predefined registers is legitimate as long as the essence of **amb** is preserved, and **require** can checked whether a certain register contains a certain value.

Try your best and have fun!

# Scoring

This has been changed from popcon to code-golf, so make your implementations short! Least number of characters wins. Don't cheat and rename existing implementations. Any submission which does something to the effect of:

```
#define r rename
#define a amb

```

will be disqualified.

# Answer
> 1 votes
# Mathematica, 143 bytes

```
a={{}};b=e@Length@Last[a=Join@@Outer[Append,a,#,1]]&;c@z_:=a=Select[a,#~f~z&];d@z_:=RandomChoice[#~f~z&/@a];f=#2/.Thread[e/@Range@Length@#->#]&

```

This code defines three functions. `b` (`amb`) and `c` (`require`) do what you expect, with `amb` taking a `List` of values and `require` taking an expression. `d` converts an `amb` expression to a human-readable value. As an upside, `amb` expressions act exactly like their values, with the final result being lazily evaluated during the `d` call. Gets slow when more than 3 `amb` expressions are entered. Could probably be golfed further.

# Answer
> 5 votes
## Scala, 406/377 Bytes

I offer two golfed versions of my implementation, one that chooses the value randomly and one that (somehow) abuses the task description and always returns the first legal value. It's up to you, with one to consider (the latter one is shorter, obviously):

```
trait A[X]{def g=scala.util.Random.shuffle(l).head;def l:Seq[X];def -(d:X)};class M{def a[X](e:Seq[X])=new A[X]{var s=e;def l=s;def -(d:X)=s=s.filter(_!=d)};def r(v:A[Boolean])=v-false;def p[X,Y](a:A[X],b:A[Y])=new A[(X,Y)]{var x=List[Any]();def l=(for(e<-a.l;f<-b.l)yield(e,f)).diff(x);def -(d:(X,Y))=x::=d};def o[X,Y](v:A[X],f:X=>Y)=new A[Y]{def l=v.l.map(f);def -(d:Y)=v.l.filter(f(_)==d).foreach(v.-)}}
trait A[X]{def g=l(0);def l:Seq[X];def -(d:X)};class M{def a[X](e:Seq[X])=new A[X]{var s=e;def l=s;def -(d:X)=s=s.filter(_!=d)};def r(v:A[Boolean])=v-false;def p[X,Y](a:A[X],b:A[Y])=new A[(X,Y)]{var x=List[Any]();def l=(for(e<-a.l;f<-b.l)yield(e,f)).diff(x);def -(d:(X,Y))=x::=d};def o[X,Y](v:A[X],f:X=>Y)=new A[Y]{def l=v.l.map(f);def -(d:Y)=v.l.filter(f(_)==d).foreach(v.-)}}

```

This versions are more or less just golfed versions of my initial submission (some implementations have changed slightly, but the interfaces were quite stable). Therefore I will not explain it any further but refer to my initial post. Just have in mind that everything that was "for convenience" now disappeared. And a lot of renaming happened. The only difference is that pairs are now a bit like new amb-values: If you define conditions on top of pairs this will never effect the underlying values (nevertheless, manipulating the underlying values will still affect the pairs).

To give you a hint on how to use this versions, here is a short testing code I used while golfing:

```
  val m = new M
  val a1 = m.a(List(1, 2, 3, 4, 5))
  val a2 = m.a(List(4, 5, 6))
  val a12 = m.p(a1, a2)
  m.r(m.o(a12, (p:(Int, Int)) => p._1 > p._2))
  m.r(m.o(a1, (e: Int) => e%2==1))

  println(a1.l)
  println(a2.l)
  println(a12.l)
  println(a12.g)

```

As you can see, the offered functions are now instance-methods, hence, you need an instance of M to interact with my library (this saved me one glorious byte).

Note that my ungolfed version (which I will not update any more) now includes natural syntax for the most common Int- and Boolean-operations.

---

*(my initial submission)*

Right before posting this answer the Mathematica answer was stated and it looks as if my solution is based on similar assumptions. Nevertheless, I will offer my solution, too, because I didn't copied the former answer as it wasn't there when I started.

I didn't tried to recreate a natural syntax (like: `(amb(1, 2, 3) + 3) * 5`, etc), but this would be possible if you like to implement the necessary implicit conversions. I chose the functional way as you will see later.

Let's start with the two keywords:

```
import ambiguous.AmbOps.op

object Amb {
  def amb[A](args: A*): AmbType[A] =
        new BasicAmb[A](args.toList)
  def require(amb: AmbType[Boolean]): Unit =
        amb.del(false)
  def require[A](amb: AmbType[A], predicate: A => Boolean): Unit =
        require(op(amb, predicate))
  def require[A, B](amb: AmbType[(A, B)], predicate: (A, B) => Boolean): Unit =
        require(op(amb, predicate))
}

```

The amb-method is quite straight forward, you provide some values and get some container, that may return a value back (more on that later). I offer three require methods but they are all based on the first one, so the others are just for convenience. Let me explain the first one (the others will become clear as you read on): If you have some boolean amb-Container and call require, all false values are eliminated.

But how is an amb-value of arbitrary type converted into a boolean value? By offering a conversion-policy:

```
object AmbOps {
  def op[A, B](amb: AmbType[A], op: A => B): AmbType[B] =
        new OpAmb[B, A](amb, op)
  def op[A, B, C](amb: AmbType[(A, B)], op: (A, B) => C): AmbType[C] =
        new OpAmb[C, (A, B)](amb, p => op(p._1, p._2))
  def pair[A, B](ambA: AmbType[A], ambB: AmbType[B]): AmbType[(A, B)] =
        new AmbPair[A, B](ambA, ambB)
}

```

Assume we have some numerical amb-value and want to square each element, then just call op with a corresponding function: `op(amb(1, 2, 4), (e: Int) => e * e) // returns a value equivalent to amb(1, 4, 16)` Following the same scheme you can convert the elements to boolean values for example with `op(amb(1, 2, 4), (e: Int) => e%2 == 0)`

If you have several amb-values and you want to define conditions between them, it isn't that easy to do with my approach when only using amb, require and op. Therefore I defined the method pair. With pair you can create tuples/pairs out of two amb-values (or any number if you again pair pairs with other values or pairs). If you then define conditions on top of this tuples, the illegal pairs will be eliminated. But the original values aren't always manipulated. Only if this process leads to the situation that one element from one of the initial amb-values is no longer legal in any tuple, than this value is completely eliminated from the initial amb-value. If now some other amb-value (or pair) is based on this manipulated amb-value, the dependent value will also miss the deleted element.

That means that if you need a pair of values fulfilling a condition, you have to get an element from the pair-value and you cannot always rely on the original values, but I think this is a acceptable limitation.

Just for convenience there is an additional op-method for tuples.

Now we have to dig deeper into the technical details of the amb-containers:

```
import scala.util.Random

trait AmbType[A] {
  def get: A = {
    if (list.isEmpty)
      throw new IllegalStateException("no value left")
    else list(Random.nextInt(list.length))}
  private[ambiguous] def list: List[A]
  private[ambiguous] def del(a: A): Unit
}

class BasicAmb[A](private var args: List[A]) extends AmbType[A] {
  override private[ambiguous] def list: List[A] = args
  override private[ambiguous] def del(a: A): Unit = { args = args.filterNot(_ == a)}
}

class OpAmb[A, B](amb: AmbType[B], op: B => A) extends AmbType[A] {
  override private[ambiguous] def list: List[A] = amb.list.map(op)
  override private[ambiguous] def del(a: A): Unit = amb.list.filter(op(_) == a).foreach(amb.del)
}

class AmbPair[A, B](ambA: AmbType[A], ambB: AmbType[B]) extends AmbType[(A, B)] {
  private var deleted: List[(A, B)] = List()
  override private[ambiguous] def list: List[(A, B)] =
    ambA.list.flatMap(a => ambB.list.map(b => (a, b))).diff(deleted)
  override private[ambiguous] def del(a: (A, B)): Unit = {
    deleted ::= a
    ambA.list.filter(a => !list.exists(_._1 == a)).foreach(a => {ambA.del(a); deleted = deleted.filterNot(_._1 == a)})
    ambB.list.filter(b => !list.exists(_._2 == b)).foreach(b => {ambB.del(b); deleted = deleted.filterNot(_._2 == b)})
  }
}

```

I don't want to say too much about the classes but one thing is worth mentioning: If you create pairs of two amb-values and define some conditions on top of them and afterwards define some further conditions on top of one of the original values, the pair-class misses to check if an element of the not-changed original value may be deleted as it doesn't appear as part of one pair any more. So some further observer-pattern would be great.

Now let's take a look on how to use this:

```
// create amb-values by invoking amb
val a = amb(1, 2, 3, 4)

// do some maths on a value
val b = op(a, (e: Int) => e + 2)

// define some conditions
require(b, (e: Int) => e%3 == 0)
// or first apply the condition to the value and afterwards pass the value to require
val filtered = op(b, (e: Int) => e%3 == 0)
require(filtered)

// pair values
val paired = pair(a, amb("hello", "welcome"))
// note that the amb-value a now only contains the elements 1 and 4 as the former requirement eliminated the other two

// state a condition on pairs
require(paired, (a: Int, b: String) => b.length % a == 0)
// now the amb-value a only contains the element 1 as there was no string with length divisible by 4

// query a value from our pairs (by calling get)
val selected = paired.get
// at this point only two pairs are left, so selected will always be either (1, "hello") or (1, "welcome")
val number = selected._1
val greetings = selected._2

```

---
Tags: code-golf
---


title: Toilet Paper Mysteries

text:
# Question
Title: Toilet Paper Mysteries
Today you need to solve a very practical problem: How many loops do you need to have a certain number of sheets on your toilet paper roll? Let's look at some facts:

* The diameter of a bare toilet paper cylinder is 3.8cm
* The length of one sheet of toilet paper is 10cm.
* The thickness of one sheet of toilet paper is 1mm.

Before you wrap around the cylinder the first time, it has a circumference in cm of 3.8\*pi. Every time you wrap a sheet around the cylinder its radius increases by .1, therefore its circumference increases by .2\*PI. Use this information to find out how many loops it takes to fit *n* sheets of toilet paper. (Note: Use an approximation of Pi that is at least as accurate as 3.14159).

**Test Cases**:

**n=1**:

* 10/(3.8\*pi) = **.838 loops**

**n=2**:

* (How many full loops can we make?) 1 full loop = 3.8\*pi = 11.938.
* (How much do we have left after the 1st loop?) 20 - 11.938 = 8.062
* (How much of a 2nd loop does the remaining piece make?) 8.062/(4\*pi) = .642 loops
* Answer: **1.642 loops**

**n=3**:

* 1st full loop = 3.8\*pi = 11.938, 2nd full loop = 4\*pi = 12.566
* 30 - 11.938 - 12.566 = 5.496
* 5.496/(4.2\*pi) = .417
* Answer: **2.417 loops**

**n=100** =\> 40.874

# Answer
# Pyth, ~~27~~ 23 bytes

```
+fg0=-QJc*.n0+18T50)cQJ

```

Try it online. Test suite.

### Explanation

```
                            Q = input number (implicit)
 f                 )        increment T from 1, for each T:
             +18T             add 18 to T, get radius
         *.n0                 multiply by pi to, get half the circumference
        c        50           divide by 50, get circumference in sheets
       J                      save it to J
    =-Q                       decrement Q by it
  g0                          use this T if Q is now <= 0
+                           add
                     Q        Q (now <= 0)
                    c J       divided by J (the last circumference)
                            and print (implicit)

```
> 13 votes

# Answer
# Haskell, ~~59~~ ~~46~~ 44 bytes

A scale factor of 5/pi is applied, so that a paper cylinder has a circumference of 19,20,21... cm and a sheet is 50/pi cm.

Saved 2 bytes thanks to xnor, by using an unnamed function.

```
x!s|s>x=1+(x+1)!(s-x)|1>0=s/x
(19!).(50/pi*)

```
> 10 votes

# Answer
# Jelly, ~~29~~ ~~27~~ 26 bytes

```
R+18×3.6°µ0;+\³_÷µḞi0©ị+®’

```

Try it online!
> 8 votes

# Answer
# Haskell, 97 bytes

```
p&((m,x):(n,y):z)|y<p=p&((n,y):z)|1>0=m+(p-x)/(y-x)
t=(&zip[0..](scanl(+)0$map(*pi)[0.38,0.4..]))

```

Might be able to golf it further by moving the filtering from the `&` operator into a `takeWhile` statement, but given that it's not a golfing language this seems relatively competitive.

## Explanation

The stream of lengths of toilet paper that comprise full loops are first calculated as `scanl (+) 0 (map (* pi) [0.38, 0.4 ..]]`. We zip these with the number of full revolutions, which will also pick up the type `Double` implicitly. We pass this to `&` with the current number that we want to calculate, call it `p`.

`&` processes the list of `(Double, Double)` pairs on its right by (a) skipping forward until `snd . head . tail` is greater than `p`, at which point `snd . head` is less than `p`.

To get the proportion of this row that is filled, it then computes `(p - x)/(y - x),` and adds it to the overall amount of loops that have been made so far.
> 5 votes

# Answer
# C++, 72 bytes

```
float f(float k,int d=19){auto c=d/15.9155;return k<c?k/c:1+f(k-c,d+1);}

```

I used C++ here because it supports default function arguments, needed here to initialize the radius.

Recursion seems to produce shorter code than using a `for`-loop. Also, `auto` instead of `float` \- 1 byte less!
> 5 votes

# Answer
# Lua, 82 bytes

```
n=... l,c,p=10*n,11.938042,0 while l>c do l,c,p=l-c,c+.628318,p+1 end print(p+l/c)

```

Not bad for a general-purpose language, but not very competitive against dedicated golfing languages of course. The constants are premultiplied with pi, to the stated precision.
> 3 votes

# Answer
# C, 87 bytes

```
float d(k){float f=31.831*k,n=round(sqrt(f+342.25)-19);return n+(f-n*(37+n))/(38+2*n);}

```

Uses an explicit formula for the number of whole loops:

```
floor(sqrt(100 * k / pi + (37/2)^2) - 37/2)

```

I replaced `100 / pi` by `31.831`, and replaced `floor` with `round`, turning the annoying number `-18.5` to a clean `-19`.

The length of these loops is

```
pi * n * (3.7 + 0.1 * n)

```

After subtracting this length from the whole length, the code divides the remainder by the proper circumference.

---

Just to make it clear - this solution has complexity `O(1)`, unlike many (all?) other solutions. So it's a bit longer than a loop or recursion.
> 3 votes

# Answer
# JavaScript, 77 bytes

```
function w(s,d,c){d=d||3.8;c=d*3.14159;return c>s*10?s*10/c:1+w(s-c/10,d+.2)}

```

```
function w(s,d,c){d=d||3.8;c=d*3.14159;return c>s*10?s*10/c:1+w(s-c/10,d+.2)}

function wraps(sheets, diameter, circumference) {
    // Default the value of diameter
    diameter = diameter || 3.8;
    circumference = diameter * 3.14159;
    if (circumference > sheets * 10)
        return sheets * 10 / circumference;
    return 1 + wraps(sheets - circumference / 10, diameter + .2);
}

document.getElementById('text').innerHTML = "0 => " + w(0)
+ "\n1 => " + w(1)
+ "\n2 => " + w(2)
+ "\n3 => " + w(3)
+ "\n100 => " + w(100)

+ "\n\n0 => " + wraps(0)
+ "\n1 => " + wraps(1)
+ "\n2 => " + wraps(2)
+ "\n3 => " + wraps(3)
+ "\n100 => " + wraps(100);
```

```
<pre id="text"></pre>
```
> 3 votes

# Answer
## C#, 113 bytes

```
double s(int n){double c=0,s=0,t=3.8*3.14159;while(n*10>s+t){s+=t;c++;t=(3.8+c*.2)*3.14159;}return c+(n*10-s)/t;}

```

Ungolfed:

```
double MysteryToiletPaper(int sheetNumber)
    {
        double fullLoops = 0, sum = 0, nextLoop = 3.8 * 3.14159;

        while (sheetNumber * 10 > sum + nextLoop)
        {
            sum += nextLoop;
            fullLoops++;
            nextLoop = (3.8 + fullLoops * .2) * 3.14159;
        }

        return fullLoops + ((sheetNumber * 10 - sum) / nextLoop);
    }

```

Results:

> for 1 sheet
>
> > 0,837658302760201
>
> for 2 sheets
>
> > 1,64155077524438
>
> for 3 sheets
>
> > 2,41650110749198
>
> for 100 sheets
>
> > 40,8737419532946
> 2 votes

# Answer
## PHP, 101 bytes

```
<?$p=pi();$r=3.8;$l=$argv[1]*10;$t=0;while($r*$p<$l){$t+=($l-=$r*$p)>0?1:0;$r+=.2;}echo$t+$l/($r*$p);

```

## Ungolfed

```
<?
$pi = pi();
$radius = 3.8;
$length_left = $argv[1]*10;
$total_rounds = 0;
while ($radius * $pi < $length_left) {
    $total_rounds += ($length_left -= $radius * $pi) > 0 ? 1 : 0;
    $radius += .2;
}
echo $total_rounds + $length_left/( $radius * $pi );

```

I feel like this could be done a little shorter, but I ran out of ideas.
> 2 votes

# Answer
# Python 3, ~~114~~ ~~109~~ 99 bytes

This function tracks the circumference of each layer until the sum of the circumferences is greater than the length of the number of sheets. Once this happens the answer is:

* One less than the number of calculated layers **+** length of leftover sheets **/** circumference of most recent layer

---

```
def f(n):
    l,s=0,[]
    while sum(s)<n:s+=[.062832*(l+19)];l+=1
    return len(s)-1+(n-sum(s[:-1]))/s[-1]

```

**Update**

* **-10** \[16-05-09\] Optimized my math-ing
* **-5** \[16-05-04\] Minimized number of lines
> 2 votes

# Answer
# JavaScript, 44 bytes

```
w=(i,d=19,c=d/15.9155)=>i<c?i/c:1+w(i-c,d+1)

```

I used anatolyg's idea and translated the code into JavaScript.
> 1 votes

# Answer
# \>\<\>, 46 44 bytes

```
a*0"Gq",:&a9+*\
?\:{$-{1+{&:&+>:{:})
;>{$,+n

```

Expects the number of sheets to be present on the stack at program start.

This uses an approximation of pi of `355/113 = 3.14159292...`, storing `pi/5` in the register. The current iteration's circumference lives on the stack, and `pi/5` is added on each iteration.

**Edit:** Refactored to store the circumference directly - previous version stored `pi/10` and started the diameter as `38`, which was 2 bytes longer.
> 1 votes

# Answer
# PHP, 79 bytes

```
function p($s,$d=3.8){$c=$d*pi();return $c>$s*10?$s*10/$c:1+p($s-$c/10,$d+.2);}

```

Run code in Sandbox

I have pretty much only translated Ross Bradbury's answer for JavaScript into a PHP function, which is also recursive.
> 0 votes

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


title: KOTH: Every coin has two sides

text:
# Question
Title: KOTH: Every coin has two sides
**Final results available**

# Introduction

After my previous KOTH with heavy themes (fantasy war, worldwide pandemic...), I'm back with a new lighthearted game. This time, you are facing off in a "board game-like" situation. A pile of upside down coins is placed at the center of a really big table, and you are determined to get your share of the loot!

# Glossary

> *Coins*: Tokens that can either be flipped or unflipped.
> *Unflipped*: Coins placed on the table with their value pointing down. This is the default state of the coins.
> *Flipped*: Coins placed on the table with their value pointing up.
> *Local*: Refers to your pile of coins.
> *Global*: Refers to the pile of coins at the center.

# Principle

**At the start** of the game, each player starts with **0 points** and **0 coins** (flipped or unflipped). The game is turn-based. During their turn, players can take up to 3 actions interacting either with the pile of coins at the center of the table, their own pile of coins or with other players.

Play order is defined randomly at the start of the game. The order of the players in the argument list represents the turn order, and it goes from left to right in that list. "Next" and "Previous" refer respectively to "on the right in that list" and "on the left in that list" with a loop if you're the last of either side.

The game lasts for **50 rounds** or until there are **0 coins at the center** at the end of a player turn (meaning that you will finish your 3 actions even if the pile is empty after your first action, and you can put back coins to let the game continue). The starting number of global coins is defined randomly with this formula:

```
(2 ^ nb_players) + (nb_players * 10) - random(1 + (nb_players ^ 2))`

```

Each action will get you points (or make you lose some) and **at the end** of the game, **each coin** you have will be added to your points (**-1 for unflipped, +2 for flipped**). The player with the highest score wins.

The controller provides you with input via command arguments, and your program has to output via stdout.

# Syntax

**Input**

Each time your program is called, it will receive arguments in this format:

`Round;YourPlayerId;Coins;PlayerId_Points_Flipped_Unflipped;PlayerId_Points_Flipped_Unflipped;...`

Rounds are 1-indexed.

**Example input**

`6;2;52;1_20_3_12;0_-2_0_1;2_12_1_0`

Here, you see it is the 6th round and you are player 2. There are 52 coins in the central pile. You have 12 points, 1 flipped coin and 0 unflipped coin. Points can be negative.

**Output**

You have to output three characters (no space, no separator), which each correspond to one action you'll take this turn. The order of the characters determine the order of the actions. You can output the same actions multiple times. In case there is not enough coins to complete your action, it will use the maximum of available coins and count points only for the coins used.

`N`: Do Nothing
`1`: Take 1 coin from the central pile *\[Effects: +1 local unflipped / -1 point / -1 global unflipped\]*
`2`: Take 2 coins from the central pile *\[Effects: +2 local unflipped / -2 points / -2 global unflipped\]*
`3`: Take 3 coins from the central pile *\[Effects: +3 local unflipped / -3 points / -3 global unflipped\]*
`A`: Put back 1 coin from your pile *\[Effects: -1 local unflipped / +1 point / +1 global unflipped\]*
`B`: Put back 2 coins from your pile *\[Effects: -2 local unflipped / +2 points / +2 global unflipped\]*
`C`: Put back 3 coins from your pile *\[Effects: -3 local unflipped / +3 points / +3 global unflipped\]*
`X`: Remove 1 coin from your pile *\[Effects: -1 local unflipped / 0 point\]*
`Y`: Remove 2 coins from your pile *\[Effects: -2 local unflipped / 0 point\]*
`Z`: Remove 3 coins from your pile *\[Effects: -3 local unflipped / 0 point\]*
`R`: Rotate coins to previous player *\[Effects: -1 point per unflipped received, +2 points per flipped received / applies to all players\]*
`T`: Rotate coins to next player *\[Effects: -1 point per unflipped received, +2 points per flipped received / applies to all players\]*
`F`: Flip 1 coin *\[Effects: -1 local unflipped / +1 local flipped / +2 point\]*
`U`: Unflip 1 coin *\[Effects: +1 local unflipped / -1 local flipped / -2 point\]*

**Example output**

`2FF` : Takes two coins and flips two coin, scoring `-2 + 2 + 2 = 2 points`

If your output is incorrect, controller will assume `NNN`.

# Controller

You can find the controller on GitHub. It also contains two samplebots, written in Java. To make it run, check out the project and open it in your Java IDE. The entry point in the `main` method of the class `Game`. Java 8 required.

To add bots, first you need either the compiled version for Java (.class files) or the sources for interpreted languages. Place them in the root folder of the project. Then, create a new Java class in the `players` package (you can take example on the already existing bots). This class must implement `Player` to override the method `String getCmd()`. The String returned is the shell command to run your bots. You can for example make a Ruby bot work with this command : `return "C:\Ruby\bin\ruby.exe MyBot.rb";`. Finally, add the bot in the players array at the top of the `Game` class.

# Rules

* Bots should not be written to beat or support specific other bots.
* Writing to files is allowed. Please write to"yoursubmissionname.txt", the folder will be emptied before a game starts. Other external resources are disallowed.
* Your submission has 1 second to respond.
* Provide commands to compile and run your submissions.

# Supported Languages

I'll try and support every language, but it needs to be available online for free. Please provide instructions for installation if you're not using a "mainstream" language.

As of right now, I can run : Java 6-7-8, PHP, Ruby, Perl, Python 2-3, Lua, R, node.js, Haskell, Kotlin, C++ 11.

# Final results

These are the results of 100 games (points are added up) :

```
1. BirdInTheHand: 1017790
2. Balance: 851428
3. SecondBest: 802316
4. Crook: 739080
5. Jim: 723440
6. Flipper: 613290
7. Wheeler: 585516
8. Oracle: 574916
9. SimpleBot: 543665
10. TraderBot: 538160
11. EgoisticalBot: 529567
12. RememberMe: 497513
13. PassiveBot: 494441
14. TheJanitor: 474069
15. GreedyRotation: 447057
16. Devil: 79212
17. Saboteur: 62240

```

Individual results of the games are available here : http://pasted.co/63f1e924 (with starting coins and number of rounds per game).

A bounty of 50 reputations is awarded to the winner : **Bird In The Hand** by Martin Büttner.

Thank you all for your participation, see you next KOTH~

# Answer
> 12 votes
## Bird in the Hand, Ruby

```
def deep_copy(o)
  Marshal.load(Marshal.dump(o))
end

ID = 0
PTS = 1
FLP = 2
UFL = 3

round, id, global, *players = ARGV[0].split(';')
round = round.to_i
id = id.to_i
global = global.to_i

players.map!{ |s| s.split('_').map(&:to_i) }

nplayers = players.size

my_pos = players.find_index { |i, p, f, u| i == id }

state = {
    round: round,
    id: id,
    global: global,
    players: players,
    my_pos: my_pos,
    me: players[my_pos],
    prev_p: players[my_pos-1],
    next_p: players[(my_pos+1)%nplayers],
    ends_game: round == 50 && my_pos == nplayers-1,
    score: 0
}

moves = {
    'N' => ->s{deep_copy(s)},
    '1' => ->s{t = deep_copy(s); coins = [1, t[:global]].min; t[:global] -= coins; t[:me][UFL] += coins; t[:score] -= coins; t},
    '2' => ->s{t = deep_copy(s); coins = [2, t[:global]].min; t[:global] -= coins; t[:me][UFL] += coins; t[:score] -= coins; t},
    '3' => ->s{t = deep_copy(s); coins = [3, t[:global]].min; t[:global] -= coins; t[:me][UFL] += coins; t[:score] -= coins; t},
    'A' => ->s{t = deep_copy(s); coins = [1, t[:me][UFL]].min; t[:global] += coins; t[:me][UFL] -= coins; t[:score] += coins; t},
    'B' => ->s{t = deep_copy(s); coins = [2, t[:me][UFL]].min; t[:global] += coins; t[:me][UFL] -= coins; t[:score] += coins; t},
    'C' => ->s{t = deep_copy(s); coins = [3, t[:me][UFL]].min; t[:global] += coins; t[:me][UFL] -= coins; t[:score] += coins; t},
    'X' => ->s{t = deep_copy(s); coins = [1, t[:me][UFL]].min; t[:me][UFL] -= coins; t},
    'Y' => ->s{t = deep_copy(s); coins = [2, t[:me][UFL]].min; t[:me][UFL] -= coins; t},
    'Z' => ->s{t = deep_copy(s); coins = [3, t[:me][UFL]].min; t[:me][UFL] -= coins; t},
    'F' => ->s{t = deep_copy(s); coins = [1, t[:me][UFL]].min; t[:me][UFL] -= coins; t[:me][FLP] += coins; t[:score] += 2*coins; t},
    'U' => ->s{t = deep_copy(s); coins = [1, t[:me][FLP]].min; t[:me][FLP] -= coins; t[:me][UFL] += coins; t[:score] -= 2*coins; t},
    'R' => ->s{
        t = deep_copy(s)
        (-1...t[:players].size-1).each do |i|
            t[:players][i][FLP] = s[:players][i+1][FLP]
            t[:players][i][UFL] = s[:players][i+1][UFL]
        end
        t[:score] += 2*t[:me][FLP] - t[:me][UFL];
        t
    },
    'T' => ->s{
        t = deep_copy(s)
        (0...t[:players].size).each do |i|
            t[:players][i][FLP] = s[:players][i-1][FLP]
            t[:players][i][UFL] = s[:players][i-1][UFL]
        end
        t[:score] += 2*t[:me][FLP] - t[:me][UFL];
        t
    }
}

results = {}

'N123ABCXYZFURT'.each_char { |c1|
    s1 = moves[c1][state]
    'N123ABCXYZFURT'.each_char { |c2|
        s2 = moves[c2][s1]
        'N123ABCXYZFURT'.each_char { |c3|
            s3 = moves[c3][s2]
            s3[:ends_game] ||= s3[:global] == 0
            results[c1+c2+c3] = s3
        }
    }
}

endingMoves = results.keys.select{|k| results[k][:ends_game]}

endingMoves.each{|k| results[k][:score] += 2*results[k][:me][FLP] - results[k][:me][UFL]}

$> << results.keys.shuffle.max_by {|k| results[k][:score]}

```

If neither of us has a bug in their programs, the main algorithm of this is likely very similar to Mathias's Oracle. Based on the assumption that prior to the final round we can't know which coins we'll end up with, we evaluate the current set of moves purely based on the points received immediately, ignoring completely what sort of coins we'll end up with. Since there are only **143 = 2744** possible move sets we can easily simulate all of them to figure out how many points they'll bring.

However, if a move set ends the game (either because it reduces the global pot to zero, or because this is round 50 and we're the last one to move), then it also takes into account the coins owned at the end of the move set to determine the move set's value. I first considered terminating the game whenever possible, but this would result in the horrible move `333` when there are only 9 coins left in the pot.

If there are multiple move sets giving the same result, we choose a random one. (I might change this to bias it in favour of game-terminating move sets.)

# Answer
> 16 votes
# Oracle, Python 3

Update: changed the order of the various tries to favor low pile of coins over rotations.

```
import sys
import itertools
from copy import deepcopy

MOVES_REQUIRED = 3

FLIPPED = 0
UNFLIPPED = 1

def filter_neighbors(neighbors, me, size):
    limit = size - MOVES_REQUIRED
    for data in neighbors:
        i, _, flipped, unflipped = map(int, data.split('_'))
        if MOVES_REQUIRED < (me - i) % size < limit:
            continue  # Skip neighbors that are too far away
        yield i, [flipped, unflipped]

class Player:
    def __init__(self, raw_data):
        _, me, coins, *data = raw_data.split(';')

        self.num_players = len(data)
        self._me = int(me)
        self._coins = int(coins)
        self._state = dict(filter_neighbors(data, self._me, self.num_players))

    def reset(self):
        self.me = self._me
        self.coins = self._coins
        self.state = deepcopy(self._state)
        self.my_state = self.state[self.me]

    def invalid_move(self, move):
        if move in 'NRT':
            return False

        if move in '123'[:self.coins]:
            return False

        flipped, unflipped = self.my_state
        if flipped and move == 'U':
            return False
        if unflipped and move == 'F':
            return False

        if move in 'AXBYCZ'[:2 * unflipped]:
            return False

        return True

    def N(self):
        return 0

    def one(self):
        self.coins -= 1
        self.my_state[UNFLIPPED] += 1
        return -1

    def two(self):
        self.coins -= 2
        self.my_state[UNFLIPPED] += 2
        return -2

    def three(self):
        self.coins -= 3
        self.my_state[UNFLIPPED] += 3
        return -3

    def A(self):
        self.coins += 1
        self.my_state[UNFLIPPED] -= 1
        return 1

    def B(self):
        self.coins += 2
        self.my_state[UNFLIPPED] -= 2
        return 2

    def C(self):
        self.coins += 3
        self.my_state[UNFLIPPED] -= 3
        return 3

    def X(self):
        self.my_state[UNFLIPPED] -= 1
        return 0

    def Y(self):
        self.my_state[UNFLIPPED] -= 2
        return 0

    def Z(self):
        self.my_state[UNFLIPPED] -= 3
        return 0

    def R(self):
        self.me = (self.me + 1) % self.num_players
        flipped, unflipped = self.my_state = self.state[self.me]
        return 2 * flipped - unflipped

    def T(self):
        self.me = (self.me - 1) % self.num_players
        flipped, unflipped = self.my_state = self.state[self.me]
        return 2 * flipped - unflipped

    def F(self):
        self.my_state[FLIPPED] += 1
        self.my_state[UNFLIPPED] -= 1
        return 2

    def U(self):
        self.my_state[FLIPPED] -= 1
        self.my_state[UNFLIPPED] += 1
        return -2

setattr(Player, '1', Player.one)
setattr(Player, '2', Player.two)
setattr(Player, '3', Player.three)

def scenarii(player):
    for tries in itertools.product('FUABCXYZ123NRT', repeat=MOVES_REQUIRED):
        player.reset()
        points = 0
        for try_ in tries:
            if player.invalid_move(try_):
                break
            points += getattr(player, try_)()
        else:
            yield points, ''.join(tries)

if __name__ == '__main__':
    player = Player(sys.argv[1])
    print(max(scenarii(player))[1])

```

Tries every single possible output and keep the one that yield the maximum amount of points for this turn.

# Answer
> 7 votes
## Greedy Rotation, Ruby

```
round, id, global, *players = ARGV[0].split(';')
round = round.to_i
id = id.to_i
global = global.to_i

players.map!{ |s| s.split('_').map(&:to_i) }

nplayers = players.size

my_pos = players.find_index { |i, p, f, u| i == id }

prev_p = players[my_pos-1]
next_p = players[(my_pos+1)%nplayers]

prev_score = 2*prev_p[2] - prev_p[3]
next_score = 2*next_p[2] - next_p[3]

take_from = prev_p

$><< '3'
if prev_score > next_score || prev_score == next_score && prev_p[3] > next_p[3]
    $><< 'T'
else
    $><< 'R'
    take_from = next_p
end

if take_from[3] >= 3
    $><< 'C'
elsif take_from[3] >= 1
    $><< 'F'
else
    $><< 'N'
end

```

This is quite similar to ArtOfCode's approach, except that this checks from which neighbour we can get more points, and it chooses `C` instead of `F` if we end up with 3 or more coins after the rotation.

After writing this up, I'm pretty sure that a better approach would be just to greedily pick the best out of all moves every time, preceding rotation by taking if possible (instead of sticking to a fixed "get unflipped, rotate, get rid of unflipped" pattern).

This also doesn't take into account the implicit points represented by the coins actually owned (based on the assumption that the game is going to last enough rounds that I likely won't end up keeping my coins anyway).

# Answer
> 6 votes
## Flipper, Python 2

Flipper gathers coins and tries to turn unflipped to flipped. Flipper is not a smart player but tries to be a positive force in the game.

```
import sys, random

# process input data (not used here):
args = sys.argv[1].split(';')
rounds, myid, coins = map(int, args[:3])
players = [map(int, data.split('_')) for data in args[3:]]

# implement strategy using multiples of 'N123ABCXYZRTFU':
options = '12333FFFFFFFFFFF'
print ''.join(random.choice(options) for i in range(3))

```

Flipper just needs the `python flipper.py <arg>` to run.

# Answer
> 5 votes
## SimpleBot, Python 3

SimpleBot is, well, simple. He's worked out one strategy and he's going to stick with it.

To run:

```
python3 main.py

```

where the contents of the `main.py` file is:

```
def main():
    print("3RF")

if __name__ == "__main__":
    main()

```

# Answer
> 5 votes
## Balance, Lua

Balance will try to keep the balance in its token, minimizing the loss in case someone uses the `R` and `T` actions against him. He thinks this style of life is the true one and should be enforced to anyone that doesn't keep a good balance of flipped/unflipped coins, so everyone close to him will be punished as soon as it could make them lose points.

He needs the following command to run:

```
lua balance.lua

```

Where the file balance.lua contains the following piece of code:

```
local datas={}
local arg=arg[1]..";"

-- parse the arguments
-- add some meta datas for debuging purpose/usefulness
arg:gsub("(.-);",function(c)
  if not datas.round
  then
    datas.round=c+0
  elseif not datas.myID
  then
    datas.myID=c+0
  elseif not datas.coins
  then
    datas.coins=c+0
  else
    datas[#datas+1]={}
    datas[#datas].repr=c
    c=c.."_"
    tmp={}
    c:gsub("(.-)_",function(d) tmp[#tmp+1]=d end)
    datas[#datas].id=tmp[1]+0
    datas[#datas].points=tmp[2]+0
    datas[#datas].flip=tmp[3]+0
    datas[#datas].unflip=tmp[4]+0
    if datas[#datas].id==datas.myID
    then
      datas.myOrder=#datas
      datas.myDatas=datas[#datas]
    end
  end
end)

local actions=""
-- construct actions
for i=1,3
do
  -- if we aren't in balance and can grab more coins
  -- we do it
  if #actions==0 and datas.myDatas.unflip<=datas.myDatas.flip/2 and datas.coins>=3
  then
    actions=actions.."3"
    datas.myDatas.unflip=datas.myDatas.unflip+3
    datas.coins=datas.coins-3
  -- if we couldn't grab coins, but aren't in balance, we flip some coins
  elseif datas.myDatas.unflip>datas.myDatas.flip/2
  then
    actions=actions.."F"
    datas.myDatas.unflip=datas.myDatas.unflip-1
    datas.myDatas.flip=datas.myDatas.flip+1

  -- if we didn't have anything to do on our pile, let's punish
  -- the fools who doesn't follow the great Balance principle
  else
    previous=datas.myOrder<2 and #datas or datas.myOrder-1
    following=datas.myOrder>=#datas and 1 or datas.myOrder+1

    lossPrev=-datas[previous].flip + 2*datas[previous].unflip
    lossFoll=-datas[following].flip+ 2*datas[following].unflip
    if lossFoll>0 and lossPrev>0
    then
      actions =actions.."N"
    elseif lossFoll>=lossPrev
    then
      actions=actions.."T"
      datas[following].unflip,datas[following].flip=datas[following].flip,datas[following].unflip
    else
      actions=actions.."R"
      datas[previous].unflip,datas[previous].flip=datas[previous].flip,datas[previous].unflip
    end
  end
end
print(actions)

```

# Answer
> 4 votes
# The Janitor, Python 3

He tries to clean the mess the other players make with all these coins and put them back into pool.

```
import sys;
def Parse(S):
    T = S.split(';');
    me = eval(T[1]);
    N = len(T)-3;
    A = list(map(lambda x: list(map(lambda y:int(y),T[3+((2*N+x+me)%N)].split('_'))),range(-3,4)));
    Dic = {}
    for a in A:
        Dic[a[0]] = a[1:];
    Dic[-1] = [me];
    return Dic;
def Recursive(Dic,me,D):
    if D==3: return '';
    V = Dic[me];
    N = max(Dic.keys());
    Next = (me+1)%N;
    Prev = (N+1+me)%N;
    for i in range(3,0,-1):
        if V[2]>=i:
            Dic[me][2] = Dic[me][2]-i;
            return chr((i-1)+ord('A'))+Recursive(Dic,me,D+1);
    if V[1]>0:
        Dic[me][1] = Dic[me][1]-1;
        Dic[me][2] = Dic[me][2]+1;
        return 'U'+Recursive(Dic,me,D+1);
    if Dic[Next][2]>Dic[Prev][2]:
        return 'T'+Recursive(Dic,Next,D+1);
    return 'R'+Recursive(Dic,Prev,D+1);
Dic = Parse(sys.argv[1]);
me = Dic[-1][0];
print(Recursive(Dic,me,0));

```

He tries to give back all his unflipped coins, if he has some stuck flipped coins he will unflip them and if he gets rid of all his coins he will get somebody's else.

# Answer
> 3 votes
# Crook, R

```
args <- strsplit(commandArgs(TRUE),";")[[1]]
state <- as.data.frame(do.call(rbind,strsplit(args[-(1:3)],"_")), stringsAsFactors=FALSE)
colnames(state) <- c("id","pts","flipped","unflipped")
state$flipped <- as.integer(state$flipped)
state$unflipped <- as.integer(state$unflipped)
nb <- nrow(state)
score <- function(place) 2*state$flipped[place]-state$unflipped[place]
my_place <- which(state$id==args[2])
next_1 <- ifelse(my_place!=nb,my_place+1,1)
next_2 <- ifelse(next_1!=nb,next_1+1,1)
next_3 <- ifelse(next_2!=nb,next_2+1,1)
previous_1 <- ifelse(my_place!=1,my_place-1,nb)
previous_2 <- ifelse(previous_1!=1,previous_1-1,nb)
previous_3 <- ifelse(previous_2!=1,previous_2-1,nb)
n <- 3
out <- c()
while(n){
    M <- N <- score(my_place)
    R <- switch(n,"1"=score(next_1),
                "2"=cumsum(c(score(next_1),score(next_2))),
                "3"=cumsum(c(score(next_1),score(next_2),score(next_3))))
    P <- switch(n,"1"=score(previous_1),
                "2"=cumsum(c(score(previous_1),score(previous_2))),
                "3"=cumsum(c(score(previous_1),score(previous_2),score(previous_3))))
    M <- c(M,M+R[-n])
    N <- c(N,N+P[-n])
    if(any(R>M & R>0)){
        action <- c("R","RR","RRR")[which.max(R-M)]
        out <- c(out, action)
        state[,3:4] <- state[c((nchar(action)+1):nb,seq_len(nchar(action))),3:4]
        n <- n-nchar(action)
    }else if(any(P>N & P>0)){
        action <- c("T","TT","TTT")[which.max(P-N)]
        out <- c(out, action)
        state[,3:4] <- state[c((nb+1-seq_len(nchar(action))),1:(nb-seq_len(nchar(action)))),3:4]
        n <- n-nchar(action)
    }else if(n>1 & all(R[1]+M[1]>c(0,P[1]+M[1],R[1]+R[2]))){
        out <- c(out,"RT")
        n <- n-2
    }else if(n>1 & all(P[1]+M[1]>c(0,R[1]+M[1],P[1]+P[2]))){
        out <- c(out,"TR")
        n <- n-2
    }else{
        out <- c(out, switch(n,"1"="A","2"="1F","3"="2FF"))
        n <- 0
        }
    }
cat(paste(out,collapse=""))

```

To run: `Rscript Crook.R`

Basically it exchanges its coins with its neighbours only if the exchange is uneven in its favour. If no beneficial exchange is possible, then it exchanges coins with the global pile in a way that keeps its ratio intact but generate some points.

**Edit:** I added a little bit of depth to this bot by making it check the next and previous 2 and 3 player stacks instead of just the next one and check if, overall, it is beneficial to rotate that many times.

**2nd Edit**: Following @MartinBüttner's idea, the bot now performs a "RT", or "TR", if it would be beneficial for him more than for its neighbours (if I didn't mess up in implementing it :) ).

# Answer
> 3 votes
# Jim, Ruby

based on Martin Büttner's *Greedy Rotation*.

```
PlayerId = 0
Points = 1
Flipped = 2
Unflipped = 3

round, id, global, *players = ARGV[0].split(';')
round = round.to_i
id = id.to_i
global = global.to_i

if(round == 1)
    print '3FF'
    exit
end

players.map!{ |s| s.split('_').map(&:to_i) }

nplayers = players.size

my_pos = players.find_index { |a| a[PlayerId] == id }

coin_vals = players.map{|a| a[Flipped]*2 - a[Unflipped]}

move = [-1,1].max_by{|s|
    swap_gain = coin_vals.rotate(s)
    scores = (0...nplayers).map{|i|
        swap_gain[i]+players[i][Points]
    }
    scores.delete_at(my_pos)-scores.max
}
if move == 1
    print 'R'
else
    print 'T'
end

print ['1F', 'FF'][rand 2]

```

will rotate one way or the other, depending on what will give him the most points compared to the best other player. Then, he flips for quick cash.

# Answer
> 2 votes
# Saboteur, Python 2

```
import random
moves = '3R'
print '33' + ''.join(random.choice(moves))

```

The randomness means it probably won't sabotage very well, but later I think I'll have it wait til the 'end' (how many turns/coins are left) and THEN rotate, after looking at the nearby reachable players to steal from... actually only doing one rotation seems really poor, considering other people are also likely to use rotations. I don't think this'll work very well...

# Answer
> 2 votes
## TraderBot

This bot tries to rotate whenever it is the one that takes the most points in that action. If it cannot rotate then tries to get rid of the unfliped coins or take a few more to change them in the following actions.

```
import java.util.ArrayList;

```

import java.util.List;

public class TraderBot {

```
class Player{
    private int id;
    private int points;
    private int flip;
    private int unflip;

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public int getPoints() {
        return points;
    }
    public void setPoints(int points) {
        this.points = points;
    }
    public int getFlip() {
        return flip;
    }
    public void setFlip(int flip) {
        this.flip = flip;
    }
    public int getUnflip() {
        return unflip;
    }
    public void setUnflip(int unflip) {
        this.unflip = unflip;
    }

}

int round;
int coins;
int otherMaxPoints = 0;
Player myself = new Player();
List<Player> players = new ArrayList<>();

public static void main (String[] s){
    new TraderBot().play(s);
}

private void play(String[] s){
    parse(s[0]);
    System.out.println(action() + action() + action());
}

private int simRotateNext(){
    int flip, unflip;
    int maxP = Integer.MIN_VALUE;
    int myP = 0;
    for (int i = 0; i < players.size(); i++){
        flip = players.get(i).getFlip();
        unflip = players.get(i).getUnflip();
        int next = i + 1 <= players.size() - 1 ? i + 1 : 0;
        int p = 2 * flip - unflip;
        if (p > maxP && players.get(next).getId() != myself.getId()){
            maxP = p;
        } else if (players.get(next).getId() == myself.getId()){
            myP = p;
        }

    }
    return  myP - maxP;
}

private int simRotatePrev(){
    int flip, unflip;
    int maxP = Integer.MIN_VALUE;
    int myP = 0;
    for (int i = players.size() -1; i > 0; i--){
        flip = players.get(i).getFlip();
        unflip = players.get(i).getUnflip();
        int prev = i - 1 >= 0 ? i - 1 : players.size() - 1;
        int p = 2 * flip - unflip;
        if (p > maxP && players.get(prev).getId() != myself.getId()){
            maxP = p;
        } else if (players.get(prev).getId() == myself.getId()){
            myP = p;
        }
    }
    return  myP - maxP;
}

private int rotateNext(){
    int flip, unflip, nflip, nunflip;
    flip = players.get(0).getFlip();
    unflip = players.get(0).getUnflip();
    for (int i = 0; i < players.size(); i++){
        int next = i + 1 <= players.size() - 1 ? i + 1 : 0;
        nflip = players.get(next).getFlip();
        nunflip = players.get(next).getUnflip();
        players.get(next).setFlip(flip);
        players.get(next).setUnflip(unflip);
        players.get(next).setPoints(players.get(next).getPoints() + 2 * flip - unflip);
        flip = nflip;
        unflip = nunflip;
    }
    return myself.getPoints();
}

private int rotatePrev(){
    int flip, unflip,  nflip, nunflip;
    flip = players.get(players.size() -1).getFlip();
    unflip = players.get(players.size() -1).getUnflip();
    for (int i = players.size() -1; i > 0; i--){
        int prev = i - 1 >= 0 ? i - 1 : players.size() - 1;
        nflip = players.get(prev).getFlip();
        nunflip = players.get(prev).getUnflip();
        players.get(prev).setFlip(flip);
        players.get(prev).setUnflip(unflip);
        players.get(prev).setPoints(players.get(prev).getPoints() + 2 * flip - unflip);
        flip = nflip;
        unflip = nunflip;
    }
    return myself.getPoints();
}

private String action() {
    int next = simRotateNext();
    int prev = simRotatePrev();

    if (next > 0 || prev > 0){
        if (next > prev){
            rotateNext();
            return "T";
        } else {
            rotatePrev();
            return "R";
        }
    }

    if (myself.getUnflip() > 3){
        myself.unflip -= 3;
        myself.points += 3;
        return "C";
    }

    if (myself.getUnflip() > 0){
        myself.unflip -= 1;
        myself.points += 2;
        return "F";
    }

    if (myself.getPoints() > otherMaxPoints){
        return "N";
    } else {
        myself.unflip += 3;
        myself.points -= 3;
        return "3";
    }

}

private void parse(String s){
    String[] ps = s.split(";");
    round = Integer.parseInt(ps[0]);
    myself.setId(Integer.parseInt(ps[1]));
    coins = round = Integer.parseInt(ps[2]);
    for (int i = 3; i < ps.length; i++){
        String[] sp2 = ps[i].split("_");
        if (Integer.parseInt(sp2[0]) == myself.getId()){
            myself.setPoints(Integer.parseInt(sp2[1]));
            myself.setFlip(Integer.parseInt(sp2[2]));
            myself.setUnflip(Integer.parseInt(sp2[3]));
            players.add(myself);
        } else {
            Player p = new Player();
            p.setId(Integer.parseInt(sp2[0]));
            p.setPoints(Integer.parseInt(sp2[1]));
            p.setFlip(Integer.parseInt(sp2[2]));
            p.setUnflip(Integer.parseInt(sp2[3]));
            players.add(p);
            if (p.getPoints() > otherMaxPoints){
                otherMaxPoints = p.getPoints();
            }
        }
    }
}
}

```

To run: Just add it to the same folder as the default bots and then create the following class

```
package players;

import controller.Player;

public class TraderBot extends Player {

    @Override
    public String getCmd() {
        return "java TraderBot";
    }
}

```

Then add that class to the `Player[] players` array.

# Answer
> 2 votes
## Wheeler

Wheeler calculated the best possible move for it when rotating the coins.

```
import java.util.ArrayList;
import java.util.List;

public class Wheeler {

String[] actions = {"TTT", "TTR", "TRR", "TRT", "RRR", "RRT", "RTR", "RTT"};
String paramString;

class Player{
    private int id;
    private int points;
    private int flip;
    private int unflip;

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public int getPoints() {
        return points;
    }
    public void setPoints(int points) {
        this.points = points;
    }
    public int getFlip() {
        return flip;
    }
    public void setFlip(int flip) {
        this.flip = flip;
    }
    public int getUnflip() {
        return unflip;
    }
    public void setUnflip(int unflip) {
        this.unflip = unflip;
    }
    @Override
    public String toString() {
        return "Player [id=" + id + ", points=" + points + ", flip=" + flip + ", unflip=" + unflip + "]";
    }

}

int round;
int coins;
int otherMaxPoints = 0;
Player myself = new Player();
List<Player> players = new ArrayList<>();

public static void main (String[] s){
    new Wheeler().play(s);
}

private void play(String[] s){
    paramString = s[0];
    reset();
    System.out.println(action());
}

private int rotateNext(){
    int flip, unflip, nflip, nunflip;
    flip = players.get(0).getFlip();
    unflip = players.get(0).getUnflip();
    for (int i = 0; i < players.size(); i++){
        int next = i + 1 <= players.size() - 1 ? i + 1 : 0;
        nflip = players.get(next).getFlip();
        nunflip = players.get(next).getUnflip();
        players.get(next).setFlip(flip);
        players.get(next).setUnflip(unflip);
        players.get(next).setPoints(players.get(next).getPoints() + 2 * flip - unflip);
        flip = nflip;
        unflip = nunflip;
    }
    return myself.getPoints();
}

private int rotatePrev(){
    int flip, unflip,  nflip, nunflip;
    flip = players.get(players.size() -1).getFlip();
    unflip = players.get(players.size() -1).getUnflip();
    for (int i = players.size() -1; i > 0; i--){
        int prev = i - 1 >= 0 ? i - 1 : players.size() - 1;
        nflip = players.get(prev).getFlip();
        nunflip = players.get(prev).getUnflip();
        players.get(prev).setFlip(flip);
        players.get(prev).setUnflip(unflip);
        players.get(prev).setPoints(players.get(prev).getPoints() + 2 * flip - unflip);
        flip = nflip;
        unflip = nunflip;
    }
    return myself.getPoints();
}

private String action() {
    int maxPoints = myself.getPoints();
    String action = "1F2";
    for (String s : actions){
        int cPoints = 0;
        for (char c : s.toCharArray()){
            if (c == 'T'){
                cPoints += rotateNext();
            } else {
                cPoints += rotatePrev();
            }
        }
        if (cPoints > maxPoints){
            action = s;
        }
        reset();
    }
    return action;
}

private void reset(){
    players = new ArrayList<>();
    String[] ps = paramString.split(";");
    round = Integer.parseInt(ps[0]);
    myself.setId(Integer.parseInt(ps[1]));
    coins = round = Integer.parseInt(ps[2]);
    for (int i = 3; i < ps.length; i++){
        String[] sp2 = ps[i].split("_");
        if (Integer.parseInt(sp2[0]) == myself.getId()){
            myself.setPoints(Integer.parseInt(sp2[1]));
            myself.setFlip(Integer.parseInt(sp2[2]));
            myself.setUnflip(Integer.parseInt(sp2[3]));
            players.add(myself);
        } else {
            Player p = new Player();
            p.setId(Integer.parseInt(sp2[0]));
            p.setPoints(Integer.parseInt(sp2[1]));
            p.setFlip(Integer.parseInt(sp2[2]));
            p.setUnflip(Integer.parseInt(sp2[3]));
            players.add(p);
            if (p.getPoints() > otherMaxPoints){
                otherMaxPoints = p.getPoints();
            }
        }
    }
}

}

```

# Answer
> 2 votes
## SecondBest, Python 3

This program will go through all possible 3 move combinations and choose the second-best one.

Because if you have the perfect move, it's probably a trap.

Edit: removed commented-out input

```
import sys
from copy import deepcopy
from random import randint
In=str(sys.argv[1])
def V(n,f=10,t=14):
 n=str(n);z=0;s='';d='0123456789';d1='N123ABCXYZRTFU'
 for i in n:z=z*f+d.index(i)
 while z:z,m=divmod(z,t);s=d1[m]+s
 while len(s)<3:s='N'+s
 return s
In=In.split(';')
number=In[0:3]
players=In[3:]
for x in range(0,len(players)):players[x]=players[x].split('_')
for x in players:
 if number[1] in x[0]:self=x
for x in range(0,len(players)):
 for y in range(0,len(players[x])):
  players[x][y]=int(players[x][y])
for x in range(0,len(number)):number[x]=int(number[x])
Pos=list(map(V,range(0,14**3)))
B=[]
C=[]
P1=deepcopy(players)
N1=deepcopy(number)
for x in range(len(Pos)):
    P=True
    y=Pos[x]
    if '1A'in y or '2B'in y or '3C'in y or 'FU'in y or 'A1'in y or 'B2'in y or 'C3'in y or 'UF'in y:
            P=False#stupid check
    if P:#legality check
        z=0
        players=deepcopy(P1)
        number=deepcopy(N1)
        for x in players:
            if str(number[1]) in str(x[0]):self=x
        for w in range(0,3):
            if y[w] in '3':
                if int(number[2])<3:P=False;break
                else:z-=3;self[3]+=3;number[2]-=3
            if y[w] in '2':
                if int(number[2])<2:P=False;break
                else:z-=2;self[3]+=2;number[2]-=2
            if y[w] in '1':
                if int(number[2])<1:P=False;break
                else:z-=1;self[3]+=1;number[2]-=1
            if y[w] in 'A':
                if int(self[3])<1:P=False;break
                else:z+=1;self[3]-=3;number[2]+=3
            if y[w] in 'B':
                if int(self[3])<2:P=False;break
                else:z+=2;self[3]-=2;number[2]+=2
            if y[w] in 'C':
                if int(self[3])<3:P=False;break
                else:z+=3;self[3]-=1;number[2]+=1
            if y[w] in 'X':
                if int(self[3])<1:P=False;break
                else:self[3]-=1
            if y[w] in 'Y':
                if int(self[3])<2:P=False;break
                else:self[3]-=2
            if y[w] in 'Z':
                if int(self[3])<3:P=False;break
                else:self[3]-=3
            if y[w] in 'F':
                if int(self[3])<1:P=False;break
                else:z+=2;self[3]-=1;self[2]+=1
            if y[w] in 'U':
                if int(self[3])<1:P=False;break
                else:z-=2;self[3]+=1;self[2]-=1
            if y[w] in 'R':
                self[2:4]=players[(players.index(self)+1)%len(players)][2:4]
                z+=int(self[3])*-1
                z+=int(self[2])*2
            if y[w] in 'T':
                self[2:4]=players[(players.index(self)-1)%len(players)][2:4]
                z+=int(self[3])*-1
                z+=int(self[2])*2
    if P:
        C.append(z);B.append((z,y))
c=list(set(C))
c.sort()
c=c[::-1][1];D=[]
for x in B:
    if c in x:D.append(x)
print(D[randint(0,len(D)-1)][1])

```

Edit: The code was printing a random legal move. It should now be returning the second best result.

# Answer
> 1 votes
# Devil's Bot

Although its output is only half the devil's number, the results should be quite disastrous. Taking 9 coins each turn, it eventually exhausts the pile of coins. Since this bot never flips any of the coins it takes, it is extremely bad for anyone else sitting next to it when there is a rotation (-9 points for each turn taken by this bot).

```
print("333")

```

Command: `python3 devil.py`

I hope to make some real bots later on.

# Answer
> 1 votes
## Remember Me, Python 3

This program contains a significant amount of inbuilt data from a test against the fixed SecondBest bot.

It *should* learn about what moves are the best to use, but it does not use other players' input.

Edit: removed unnecessary point calculation

Edit: uncommented player input

```
import sys
file=sys.argv[0].split('\\')[::-1][0]
from copy import deepcopy
from random import randint
In=str(sys.argv[1])
def V(n,f=10,t=14):
 n=str(n);z=0;s='';d='0123456789';d1='N123ABCXYZRTFU'
 for i in n:z=z*f+d.index(i)
 while z:z,m=divmod(z,t);s=d1[m]+s
 while len(s)<3:s='N'+s
 return s
In=In.split(';')
number=In[0:3]
players=In[3:]
for x in range(0,len(players)):players[x]=players[x].split('_')
for x in players:
 if number[1] in x[0]:self=x
for x in range(0,len(players)):
 for y in range(0,len(players[x])):
  players[x][y]=int(players[x][y])
for x in range(0,len(number)):number[x]=int(number[x])
Pos=list(map(V,range(0,14**3)))
B=[]
P1=deepcopy(players)
N1=deepcopy(number)
for x in range(len(Pos)):
    P=True
    y=Pos[x]
    if '1A'in y or '2B'in y or '3C'in y or 'FU'in y or 'A1'in y or 'B2'in y or 'C3'in y or 'UF'in y:
            P=False
    if P:
        players=deepcopy(P1)
        number=deepcopy(N1)
        for x in players:
            if str(number[1]) in str(x[0]):self=x
        for w in range(0,3):
            if y[w] in '3':
                if int(number[2])<3:P=False;break
                else:self[3]+=3;number[2]-=3
            if y[w] in '2':
                if int(number[2])<2:P=False;break
                else:self[3]+=2;number[2]-=2
            if y[w] in '1':
                if int(number[2])<1:P=False;break
                else:self[3]+=1;number[2]-=1
            if y[w] in 'A':
                if int(self[3])<1:P=False;break
                else:self[3]-=3;number[2]+=3
            if y[w] in 'B':
                if int(self[3])<2:P=False;break
                else:self[3]-=2;number[2]+=2
            if y[w] in 'C':
                if int(self[3])<3:P=False;break
                else:self[3]-=1;number[2]+=1
            if y[w] in 'X':
                if int(self[3])<1:P=False;break
                else:self[3]-=1
            if y[w] in 'Y':
                if int(self[3])<2:P=False;break
                else:self[3]-=2
            if y[w] in 'Z':
                if int(self[3])<3:P=False;break
                else:self[3]-=3
            if y[w] in 'F':
                if int(self[3])<1:P=False;break
                else:self[3]-=1;self[2]+=1
            if y[w] in 'U':
                if int(self[3])<1:P=False;break
                else:self[3]+=1;self[2]-=1
            if y[w] in 'R':
                self[2:4]=players[(players.index(self)+1)%len(players)][2:4]
            if y[w] in 'T':
                self[2:4]=players[(players.index(self)-1)%len(players)][2:4]
    if P:
        B.append(y)
Pos=list(B)
B=[]
#
C=[['NNN',0],['NN1',-1],['NN2',-2],['NN3',-3],['NNR',-6],['NNT',-1],['N1N',-1],['N11',-2],['N12',-3],['N13',-4],['N1X',-1],['N1R',-7],['N1T',-2],['N1F',1],['N1U',-3],['N2N',-2],['N21',-3],['N22',-4],['N23',-5],['N2A',-1],['N2X',-2],['N2Y',-2],['N2R',-8],['N2T',-3],['N2F',0],['N2U',-4],['N3N',-3],['N31',-4],['N32',-5],['N33',-6],['N3A',-2],['N3B',-1],['N3X',-3],['N3Y',-3],['N3Z',-3],['N3R',-9],['N3T',-4],['N3F',-1],['N3U',-5],['NRN',-6],['NR1',-7],['NR2',-8],['NR3',-9],['NRA',-5],['NRB',-4],['NRC',-3],['NRX',-6],['NRY',-6],['NRZ',-6],['NRR',-12],['NRT',-7],['NRF',-4],['NRU',-8],['NTN',-1],['NT1',-2],['NT2',-3],['NT3',-4],['NTA',0],['NTX',-1],['NTR',-7],['NTT',-2],['NTF',1],['NTU',-3],['1NN',-1],['1N1',-2],['1N2',-3],['1N3',-4],['1NA',0],['1NX',-1],['1NR',-7],['1NT',-2],['1NF',1],['1NU',-3],['11N',-2],['111',-3],['112',-4],['113',-5],['11B',0],['11X',-2],['11Y',-2],['11R',-8],['11T',-3],['11F',0],['11U',-4],['12N',-3],['121',-4],['122',-5],['123',-6],['12A',-2],['12C',0],['12X',-3],['12Y',-3],['12Z',-3],['12R',-9],['12T',-4],['12F',-1],['12U',-5],['13N',-4],['131',-5],['132',-6],['133',-7],['13A',-3],['13B',-2],['13X',-4],['13Y',-4],['13Z',-4],['13R',-10],['13T',-5],['13F',-2],['13U',-6],['1XN',-1],['1X1',-2],['1X2',-3],['1X3',-4],['1XR',-7],['1XT',-2],['1RN',-7],['1R1',-8],['1R2',-9],['1R3',-10],['1RA',-6],['1RB',-5],['1RC',-4],['1RX',-7],['1RY',-7],['1RZ',-7],['1RR',-13],['1RT',-8],['1RF',-5],['1RU',-9],['1TN',-2],['1T1',-3],['1T2',-4],['1T3',-5],['1TA',-1],['1TX',-2],['1TR',-8],['1TT',-3],['1TF',0],['1TU',-4],['1FN',1],['1F1',0],['1F2',-1],['1F3',-2],['1FR',-5],['1FT',0],['1UN',-3],['1U1',-4],['1U2',-5],['1U3',-6],['1UA',-2],['1UB',-1],['1UX',-3],['1UY',-3],['1UR',-9],['1UT',-4],['1UU',-5],['2NN',-2],['2N1',-3],['2N2',-4],['2N3',-5],['2NA',-1],['2NB',0],['2NX',-2],['2NY',-2],['2NR',-8],['2NT',-3],['2NF',0],['2NU',-4],['21N',-3],['211',-4],['212',-5],['213',-6],['21B',-1],['21C',0],['21X',-3],['21Y',-3],['21Z',-3],['21R',-9],['21T',-4],['21F',-1],['21U',-5],['22N',-4],['221',-5],['222',-6],['223',-7],['22A',-3],['22C',-1],['22X',-4],['22Y',-4],['22Z',-4],['22R',-10],['22T',-5],['22F',-2],['22U',-6],['23N',-5],['231',-6],['232',-7],['233',-8],['23A',-4],['23B',-3],['23X',-5],['23Y',-5],['23Z',-5],['23R',-11],['23T',-6],['23F',-3],['23U',-7],['2AN',-1],['2A2',-3],['2A3',-4],['2AR',-7],['2AT',-2],['2XN',-2],['2X1',-3],['2X2',-4],['2X3',-5],['2XA',-1],['2XX',-2],['2XR',-8],['2XT',-3],['2XF',0],['2XU',-4],['2YN',-2],['2Y1',-3],['2Y2',-4],['2Y3',-5],['2YR',-8],['2YT',-3],['2RN',-8],['2R1',-9],['2R2',-10],['2R3',-11],['2RA',-7],['2RB',-6],['2RC',-5],['2RX',-8],['2RY',-8],['2RZ',-8],['2RR',-14],['2RT',-9],['2RF',-6],['2RU',-10],['2TN',-3],['2T1',-4],['2T2',-5],['2T3',-6],['2TA',-2],['2TX',-3],['2TR',-9],['2TT',-4],['2TF',-1],['2TU',-5],['2FN',0],['2F1',-1],['2F2',-2],['2F3',-3],['2FA',1],['2FX',0],['2FR',-6],['2FT',-1],['2FF',2],['2UN',-4],['2U1',-5],['2U2',-6],['2U3',-7],['2UA',-3],['2UB',-2],['2UC',-1],['2UX',-4],['2UY',-4],['2UZ',-4],['2UR',-10],['2UT',-5],['2UU',-6],['3NN',-3],['3N1',-4],['3N2',-5],['3N3',-6],['3NA',-2],['3NB',-1],['3NC',0],['3NX',-3],['3NY',-3],['3NZ',-3],['3NR',-9],['3NT',-4],['3NF',-1],['3NU',-5],['31N',-4],['311',-5],['312',-6],['313',-7],['31B',-2],['31C',-1],['31X',-4],['31Y',-4],['31Z',-4],['31R',-10],['31T',-5],['31F',-2],['31U',-6],['32N',-5],['321',-6],['322',-7],['323',-8],['32A',-4],['32C',-2],['32X',-5],['32Y',-5],['32Z',-5],['32R',-11],['32T',-6],['32F',-3],['32U',-7],['33N',-6],['331',-7],['332',-8],['333',-9],['33A',-5],['33B',-4],['33X',-6],['33Y',-6],['33Z',-6],['33R',-12],['33T',-7],['33F',-4],['33U',-8],['3AN',-2],['3A2',-4],['3A3',-5],['3AR',-8],['3AT',-3],['3BN',-1],['3B1',-2],['3B3',-4],['3BA',0],['3BX',-1],['3BR',-7],['3BT',-2],['3BF',1],['3BU',-3],['3XN',-3],['3X1',-4],['3X2',-5],['3X3',-6],['3XA',-2],['3XB',-1],['3XX',-3],['3XY',-3],['3XR',-9],['3XT',-4],['3XF',-1],['3XU',-5],['3YN',-3],['3Y1',-4],['3Y2',-5],['3Y3',-6],['3YA',-2],['3YX',-3],['3YR',-9],['3YT',-4],['3YF',-1],['3YU',-5],['3ZN',-3],['3Z1',-4],['3Z2',-5],['3Z3',-6],['3ZR',-9],['3ZT',-4],['3RN',-9],['3R1',-10],['3R2',-11],['3R3',-12],['3RA',-8],['3RB',-7],['3RC',-6],['3RX',-9],['3RY',-9],['3RZ',-9],['3RR',-15],['3RT',-10],['3RF',-7],['3RU',-11],['3TN',-4],['3T1',-5],['3T2',-6],['3T3',-7],['3TA',-3],['3TX',-4],['3TR',-10],['3TT',-5],['3TF',-2],['3TU',-6],['3FN',-1],['3F1',-2],['3F2',-3],['3F3',-4],['3FA',0],['3FB',1],['3FX',-1],['3FY',-1],['3FR',-7],['3FT',-2],['3FF',1],['3UN',-5],['3U1',-6],['3U2',-7],['3U3',-8],['3UA',-4],['3UB',-3],['3UC',-2],['3UX',-5],['3UY',-5],['3UZ',-5],['3UR',-11],['3UT',-6],['3UU',-7],['RNN',-6],['RN1',-7],['RN2',-8],['RN3',-9],['RNA',-5],['RNB',-4],['RNC',-3],['RNX',-6],['RNY',-6],['RNZ',-6],['RNR',-12],['RNT',-7],['RNF',-4],['RNU',-8],['R1N',-7],['R11',-8],['R12',-9],['R13',-10],['R1B',-5],['R1C',-4],['R1X',-7],['R1Y',-7],['R1Z',-7],['R1R',-13],['R1T',-8],['R1F',-5],['R1U',-9],['R2N',-8],['R21',-9],['R22',-10],['R23',-11],['R2A',-7],['R2C',-5],['R2X',-8],['R2Y',-8],['R2Z',-8],['R2R',-14],['R2T',-9],['R2F',-6],['R2U',-10],['R3N',-9],['R31',-10],['R32',-11],['R33',-12],['R3A',-8],['R3B',-7],['R3X',-9],['R3Y',-9],['R3Z',-9],['R3R',-15],['R3T',-10],['R3F',-7],['R3U',-11],['RAN',-5],['RA2',-7],['RA3',-8],['RAA',-4],['RAB',-3],['RAC',-2],['RAX',-5],['RAY',-5],['RAZ',-5],['RAR',-11],['RAT',-6],['RAF',-3],['RAU',-7],['RBN',-4],['RB1',-5],['RB3',-7],['RBA',-3],['RBB',-2],['RBC',-1],['RBX',-4],['RBY',-4],['RBZ',-4],['RBR',-10],['RBT',-5],['RBF',-2],['RBU',-6],['RCN',-3],['RC1',-4],['RC2',-5],['RCA',-2],['RCB',-1],['RCC',0],['RCX',-3],['RCY',-3],['RCZ',-3],['RCR',-9],['RCT',-4],['RCF',-1],['RCU',-5],['RXN',-6],['RX1',-7],['RX2',-8],['RX3',-9],['RXA',-5],['RXB',-4],['RXC',-3],['RXX',-6],['RXY',-6],['RXZ',-6],['RXR',-12],['RXT',-7],['RXF',-4],['RXU',-8],['RYN',-6],['RY1',-7],['RY2',-8],['RY3',-9],['RYA',-5],['RYB',-4],['RYC',-3],['RYX',-6],['RYY',-6],['RYZ',-6],['RYR',-12],['RYT',-7],['RYF',-4],['RYU',-8],['RZN',-6],['RZ1',-7],['RZ2',-8],['RZ3',-9],['RZA',-5],['RZB',-4],['RZC',-3],['RZX',-6],['RZY',-6],['RZZ',-6],['RZR',-12],['RZT',-7],['RZF',-4],['RZU',-8],['RRN',-12],['RR1',-13],['RR2',-14],['RR3',-15],['RRA',-11],['RRB',-10],['RRC',-9],['RRX',-12],['RRY',-12],['RRZ',-12],['RRR',-18],['RRT',-13],['RRF',-10],['RRU',-14],['RTN',-7],['RT1',-8],['RT2',-9],['RT3',-10],['RTA',-6],['RTX',-7],['RTR',-13],['RTT',-8],['RTF',-5],['RTU',-9],['RFN',-4],['RF1',-5],['RF2',-6],['RF3',-7],['RFA',-3],['RFB',-2],['RFC',-1],['RFX',-4],['RFY',-4],['RFZ',-4],['RFR',-10],['RFT',-5],['RFF',-2],['RUN',-8],['RU1',-9],['RU2',-10],['RU3',-11],['RUA',-7],['RUB',-6],['RUC',-5],['RUX',-8],['RUY',-8],['RUZ',-8],['RUR',-14],['RUT',-9],['RUU',-10],['TNN',-1],['TN1',-2],['TN2',-3],['TN3',-4],['TNA',0],['TNX',-1],['TNR',-7],['TNT',-2],['TNF',1],['TNU',-3],['T1N',-2],['T11',-3],['T12',-4],['T13',-5],['T1B',0],['T1X',-2],['T1Y',-2],['T1R',-8],['T1T',-3],['T1F',0],['T1U',-4],['T2N',-3],['T21',-4],['T22',-5],['T23',-6],['T2A',-2],['T2C',0],['T2X',-3],['T2Y',-3],['T2Z',-3],['T2R',-9],['T2T',-4],['T2F',-1],['T2U',-5],['T3N',-4],['T31',-5],['T32',-6],['T33',-7],['T3A',-3],['T3B',-2],['T3X',-4],['T3Y',-4],['T3Z',-4],['T3R',-10],['T3T',-5],['T3F',-2],['T3U',-6],['TAN',0],['TA2',-2],['TA3',-3],['TAR',-6],['TAT',-1],['TXN',-1],['TX1',-2],['TX2',-3],['TX3',-4],['TXR',-7],['TXT',-2],['TRN',-7],['TR1',-8],['TR2',-9],['TR3',-10],['TRA',-6],['TRB',-5],['TRC',-4],['TRX',-7],['TRY',-7],['TRZ',-7],['TRR',-13],['TRT',-8],['TRF',-5],['TRU',-9],['TTN',-2],['TT1',-3],['TT2',-4],['TT3',-5],['TTA',-1],['TTX',-2],['TTR',-8],['TTT',-3],['TTF',0],['TTU',-4],['TFN',1],['TF1',0],['TF2',-1],['TF3',-2],['TFR',-5],['TFT',0],['TUN',-3],['TU1',-4],['TU2',-5],['TU3',-6],['TUA',-2],['TUB',-1],['TUX',-3],['TUY',-3],['TUR',-9],['TUT',-4],['TUU',-5]]
#
points=0
#
dpoints=self[1]-points
z=0
for x in range(len(Pos)):
    y=Pos[x]
    z=0
    for x in C:
     if x[0]==y:z=x[1]
    B.append((z,y))
B.sort()
B=B[::-1]
G=open(file,'r')
H=G.read().split('#')[::-1]
G.close()
G=open(file,'w')
H[3]=H[3].replace(H[3][8:-1],str(self[1]))
J=eval(H[4][3:-1])
A=[B[0][1],dpoints]
P=1
for x in range(0,len(J)):
 if J[x][0]==A[0]:J[x][1]+=A[1];P=0
if P:J.append(A)
H[4]='\nC='+str(J)+'\n'
s=''
for x in H[::-1]:s+=x;s+='#'
G.write(s[:-1])
G.close()
print(B[0][1])

```

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


title: Shortest paths in a divisor graph

text:
# Question
Title: Shortest paths in a divisor graph
## Introduction

In this challenge, we will be dealing with a certain infinite undirected graph, which I call the *high divisor graph*. Its nodes are the integers starting from 2. There is an edge between two nodes **a \< b** if **a** divides **b** and **a2 ≥ b**. The subgraph formed by the range from 2 to 18 looks like this:

```
16-8 12 18
  \|/ |/|
   4  6 9 10 15 14
   |  |/   |/   |
   2  3    5    7  11 13 17

```

It can be shown that the infinite high divisor graph is connected, so we can ask about the shortest path between two nodes.

## Input and output

Your inputs are two integers **a** and **b**. You can assume that **2 ≤ a ≤ b \< 1000**. Your output is the length of the shortest path between **a** and **b** in the infinite high divisor graph. This means the number of edges in the path.

You may find the following fact useful: there always exists an optimal path from **a** to **b** that's first increasing and then decreasing, and only visits nodes that are strictly less than **2b2**. In particular, since **b \< 1000** you only need to consider nodes less than 2 000 000.

## Examples

Consider the inputs `3` and `32`. One possible path between the nodes 3 and 32 is

```
3 -- 6 -- 12 -- 96 -- 32

```

This path has four edges, and it turns out there are no shorter paths, so the correct output is `4`.

As another example, an optimal path for `2` and `25` is

```
2 -- 4 -- 8 -- 40 -- 200 -- 25

```

so the correct output is `5`. In this case, no optimal path contains the node `50 = lcm(2, 25)`.

## Rules and scoring

You can write a full program or a function. The lowest byte count wins, and standard loopholes are disallowed. There are no time or memory limits, so brute forcing is allowed.

## Test cases

```
2 2 -> 0
2 3 -> 4
2 4 -> 1
2 5 -> 5
3 5 -> 4
6 8 -> 2
8 16 -> 1
12 16 -> 2
16 16 -> 0
2 25 -> 5
3 32 -> 4
2 256 -> 3
60 77 -> 3
56 155 -> 3
339 540 -> 2
6 966 -> 4
7 966 -> 2
11 966 -> 4
2 997 -> 7
991 997 -> 4

```

# Answer
> 4 votes
# Matlab, ~~218~~ ~~190~~ 175 bytes

```
function f(a,b);q=a;l(b)=0;l(a)=1;while~l(b);x=q(1);q=q(2:end);l(end+1:x^2)=0;g=x+1:x^2;s=2:x-1;u=[g(~mod(g,x)),s(~mod(x,s)&s.^2>=x)];u=u(~l(u));q=[q,u];l(u)=l(x)+1;end;l(b)-1

```

Thanks @beaker for the shortcut in in the list lengthening step!

This is a relatively straightforward dijkstra implementation:

```
q=a;                  %queue
l(b)=0;       %list of path lengths
l(a)=1;
while~l(b);         %if there is no predecessor to b
    x=q(1);         %get first queue element
    q=q(2:end);
    %add edges
    l(end+1:x^2)=0;% lengthen predecessor list if too short
    g=x+1:x^2;      % g=greater neighbours
    s=2:x-1;        % s=smaller neighbours %keep only valid/unvisited neighbours
    u=[g(~mod(g,x)),s(~mod(x,s)&s.^2>=x)]; %-1byte
    u=u(~l(u));
    q=[q,u];      %add only hte valid nodes edges to queue
    l(u)=l(x)+1;       %mark x as predecessor
end;
l(b)-1 %output length to the end of the path

```

 no convolution today

# Answer
> 1 votes
## JavaScript (ES6), 186 bytes

```
(m,n)=>(g=i=>{for(q=[i],r=[],r[i]=j=0;i=q[j++];)for(k=i+i;k<=i*i&(k<m*m*2|k<n*n*2);k+=i)r[k]-r[i]<2?0:r[q.push(k),k]=r[i]+1},g(m),s=r,g(n),Math.min(...r.map((i,j)=>i+s[j]).filter(i=>i)))

```

Uses a helper function `g` to calculate all the ascending paths from `m` and `n` in turn up to the provided limit, then sums the paths together and returns the lowest value.

# Answer
> 1 votes
# Mathematica 98 bytes

I am assuming that the built-in function, `FindShortestPath` does not violate the constraint about standard loopholes. If it does, just let me know and I'll delete this submission.

Brute force, hence slow with large values of `b`. I'm still thinking of ways to speed it up.

```
h@{a_,b_}:=Length@FindShortestPath[Graph[Apply[Join,Thread[#<->Range[2,#] #]&/@Range[b^2]]],a,b]-1

```

This sets up a graph with appropriate edges between the nodes from `a` to `b^2`. `FindShortestPath`finds the shortest path in the graph. `Length`counts the nodes; `Length -1` is the number of edges.

`Thread[# <-> Range[2, #] #] &` produces the edges of the full graph. For example, `Thread[# <-> Range[2, #] #]&[5]` would produce the edges `{5 <-> 2*5, 5 <-> 3*5, 5 <-> 4*5, 5 <-> 5*5}`, that is, `{5 <-> 10, 5 <-> 15, 5 <-> 20, 5 <-> 25}`.

# Answer
> 1 votes
## Matlab ~~(195)(185)(181)(179)~~(173)

> **Note:** Me the user Agawa001 personally I attest that I won over the user @flawr making use of his assistance

```
 function t(a,b,p),for r=0:1,d=(b*~r+r*a)/gcd(a,b);while(d>1)p=p+1;e=find(~rem(d,1:d));f=max(e(a^(1-r/2)>=e));a=a*min([find(1:a*a>=b) a])^~(f-1);d=d/f;a=a*f^(1-2*r);end,end,p

```
* This function is different drom others, it does follow a bunch of pure mathematical calculations and factorisations but has nothing to do with paths or graphs.
* Example of function call:

```
 t(2,3,0)

 p =

 4

```

All test cases are satisfied
* ***Explanation:***

Before beginning with explanations lets prove some lemmas "not green ones":

***Lemma(1):** An optimal path between any two numbers `(a,b)` exists in a way the nodes are firstly increasing then decreasing.*

Why ? This is simply proven because the maximal integer amount that divides any number `a` is respectively big as the number `a` itself, so as a clever approach we must choose to multiply `a` as much as possible to make it sufficiently bigger, then dividing by bigger values. If ever we do the way round, the number `a` shrinks, so we need needlessly more iterations to multiply it gradually that we are dispensed with.

***Lemma(2):** From a number `a` to `b`, if `gcd(a,b)=1` `a` is multiplied by `b`, if `b` is bigger than `a` it will be multiplied by a known number `c`, if `gcd>1` `a` must be multiplied gradually by the biggest divisor of `b/gcd` named `d` that verifies the condition `a >= d` also when all `d`'s namely the minimum are bigger than `a`, `a` receives `a*c` again.*

This assumption is simple to prove any starting node `a` must be multiplied until it reaches the smallest multiple of `a` and `b` so either we multiply by proportions of `b*gcd` beginning by the maximum which verifies the main condition, that guarantees always the shortest path to smp before division process begins, or when `d` isnt available a number `c` is multiplied by `a` to make a valid condition `a>=d` for this first stage.

***Lemma(3):** From a graph-ultimum multiple of `a` to `b`, the gcd of this number and `b` is `b` itself*

Well this is just a consequence of the previous manipulations, and the last remaining steps are also done gradually dividing by the biggest divisor which doesnt exceed its square root.

**Dilemma:** What is the optimum number `c` to be iteratively multiplied by `a` that would lead straight along to the opening condition for stage 1 then the ultimum?

Good question, for any simple situation there is a simple parry, so assuming an example of two ends `(a,b)=(4,26)` factorized like this:

```
  2 | 2
  2 | 13

```

Apart from the `gcd=2` the smallest integer wich must be multiplied by `2` to reach `13` is `7`, but it is obviously ruled out, cuz it is bigger than 2, so a is squared.

```
  2 | 2
  5 | 13

```

Appearenlty in the second example `(a,b)=(10,26)` above `c` is measured as the lowest integer from `1` to `5` which exceeds `13/5` hence it satisfies the condition of graph-scaling, which is `3`, so the next step here is multiplying by `3`

```
  2 | 2
  5 | 13
  3 |

```

Why ? this is because , once we have to multiply by `2*13/gcd=13` to match the second side of the table, the junk amount we added before is optimally smallest, and moving along the graph is minimized, if ever we multiplied by bigger value like `10` the chance of dividing by the least times reduces, and it would have been increased by 1 another dividing step to reach our goal `2*13`. which are enumerated to: `13*2*5*10/2*5` then `13*2*5/5`. Whilst, obviously here the number to be divided by is `5*3<13*2`

and one more thing ........ HAIL MATHS...

---

These are my comparative results with @flawr 's ones just pay attention that i made an upper bound for time execution consering flawr's algorithm, it takes too much time!

You may insert the starting and ending scanning ranges as variables a and b in the header of online compilable code.

---
Tags: code-golf, number-theory, path-finding
---


title: Is the electric garage door open?

text:
# Question
Title: Is the electric garage door open?
My electric garage door works like this:

* There is just one push button to control the door
* If the door is fully closed and I hit the button, the door starts to open. It takes 10 seconds to open fully
* If the door is fully open and I hit the button, the door starts to close. It takes 10 seconds to close fully
* If the door is part way through opening or closing and I hit the button, then the door stops and is left partially open.
* Whenever the door stops moving, either from automatic completion of an open or close action, or from manual interruption by pushing the button partway through an action, then the mechanism will reverse and remember its direction for the next action.
* If the button is pushed when the door is stopped but partially open, then the amount of time for it to complete its action will be a fraction of 10 seconds in proportion to the amount it needs to move to complete the action.

Assume the door is fully closed at the start.

An input list of integers will be given. These integers are the number of seconds I wait between successive pushes of the control button.

Output two things:

* a percentage indicating the state of the door once all button pushes are completed and the door has reached a steady state. Output of `%` symbol is optional.
* an unambiguous indication of what direction the door will travel on the next button push. This may be `up`/`down`, `U`/`D`, `+`/`-`, `1`/`0` or whatever you choose.

You may assume the door takes infinitesimally less than 10 seconds to complete an open or close action.

### Example inputs:

```
<empty list>  # button was pushed just once
20            # button was pushed twice with 20 seconds between
10
5
20 20
10 10
5 5
1 2 3
8 9 10 11
11 10 9 8 7

```

### Expected outputs corresponding to above inputs

```
100% D
0% U
0% U
50% D
100% D
100% D
0% U
100% D
0% U
20% U

```

### Worked example of the last test

* Door starts off closed. Button is pushed
* Wait 11 seconds. Door ends up fully opened. Button is pushed.
* Wait 10 seconds. Door ends up fully closed. Button is pushed.
* Wait 9 seconds. Button is pushed. Door stops at 90% open.
* Wait 8 seconds. Button is pushed. Door starts to close.
* Wait 7 seconds. Button is pushed. Door stops at 20% open. Next direction will be up.

# Answer
> 6 votes
# Lua, ~~258~~ ~~248~~ 242 bytes

```
u,s,p=1>0,0>1,0;io.read():gsub("%d+",function(a)if(not s)then p=u and p+a or p-a;if(p>=10 or p<=0)then s,p=1>0,p>0 and 10 or 0;end;u,s=not u,not s else s=0>1;end end)if(not s)then p=u and 10 or 0;u=not u;end;print(10*p.."% "..(u and"U"or"D"))

```

### Ungolfed

```
u,s,p=true,false,0;                          -- Up direction, Stopped, Position
io.read():gsub("%d+",function(t)             -- For each number in input
    if(not s)then                            -- If door wasn't stopped
        p=u and p+t or p-t;                  -- Position = Moving up ? +t : -t
        if(p>=10 or p<=0)then                -- If door fully opened or closed
            s,p=true,p>0 and 10 or 0;        -- Then door stopped at 0 or 10
        end
        u,s=not u,not s;                     -- Toggle direction and toggle stopped
    else
        s=false;                             -- If stopped, nothing happened, un-stop.
    end
end)
-------------------- Done pressing the button --------------------
if(not s)then                                -- If left off moving
    p=u and 10 or 0;                         -- Finish movement
    u=not u;                                 -- Toggle direction
end
print(10*p.."% "..(u and"U"or"D"))           -- Output answer

```

~~I don't see how your test cases can be right...~~

~~```
20 20 -- Initial push, after 20, garage is at 100, push to start it down, after 20, garage is at 0, push to start it up, garage finishes up.
10 10 -- Same as above
1 2 3 -- 0 U Moving, wait 1, 1 D Stopped, wait 2, 0 U stopped, wait 3, 100 D stopped

```~~

OP Fixed

# Answer
> 3 votes
## JavaScript (ES6), ~~109~~ 106 bytes

```
a=>a.map(e=>(s^=1)?(r-=e*(d=-d))>9?(s=0,r=10):r<1?(r=s=0):r:r,r=s=0,d=1)&&(s?r:5*++d)*10+(d-s?"% D":"% U")

```

# Answer
> 3 votes
# Pyth, ~~50~~ ~~45~~ 39 bytes

6 bytes thanks to Sp3000.

```
J1,*Tu@S[0T+?|!%GTZ+=Z0*H~_J~Z1G)1+QT0J

```

Test suite.

# Answer
> 3 votes
# Ruby, 152 bytes

```
->v{u,s,a=!!1,!0,0;v.map{|w|!s ?(a=u ? a+w : a-w;a>=10 ?(s,a=!!1,10):a<=0 ?(s,a=!!1,0):0;u,s=!u,!s):s=!0};!s ?(a=(u=!u)?0:10):0;p"#{10*a}% #{u ??U:?D}"}

```

**Test cases:**

```
f=->v{u,s,a=!!1,!0,0;v.map{|w|!s ?(a=u ? a+w : a-w;a>=10 ?(s,a=!!1,10):a<=0 ?(s,a=!!1,0):0;u,s=!u,!s):s=!0};!s ?(a=(u=!u)?0:10):0;p"#{10*a}% #{u ??U:?D}"}

f[[]]            # => "100% D"
f[[20]]          # => "0% U"
f[[10]]          # => "0% U"
f[[5]]           # => "50% D"
f[[20,20]]       # => "100% D"
f[[10,10]]       # => "100% D"
f[[5,5]]         # => "0% U"
f[[1,2,3]]       # => "100% D"
f[[8,9,10,11]]   # => "0% U"
f[[11,10,9,8,7]] # => "20% U"

```

# Answer
> 2 votes
# Python 3.5, ~~193~~ ~~187~~ ~~185~~ ~~181~~ ~~175~~ ~~173~~ 172 bytes:

```
def G(*p):
 O=100;y=0;l=10;z,v='UG'
 for g in[*p,O]:
  if v=='G':Q=O*g//10;y=min(max(0,[Q,y-Q][z=='D']),O);l=min(10,g);z='UD'[z=='U']
  v='GS'[(O>y>0)*(v!='S')]
 print(y,z)

```

Takes input in the form of comma separated numbers, for instance `1,2,3,4,5` or even `1.2,3.4,7.8,9.2`. Outputs whether the door in the next step is going up or down with `U` or `D`, respectively. Will golf more over time.

Try It Online! (Ideone) (Here the input is taken in the form of a list consisting of comma separated numbers, e.g. `[1,2,3,4,5]`.)

# Answer
> 1 votes
# PHP, ~~128~~ 120 bytes

```
$d=$argv[]=10;
foreach($argv as$a)
  if($r){$p=min(max($p+$a*$d,0),100);$r=$p<1||99<$p;$d=-$d;}else$r=1;
echo"$p% ".DU[$d>0];

```

The code is wrapped here to fit in the code box. Put everything on a single line, put the PHP open marker in front of it and save it into a file. Or run it from the command line using `php -d error_reporting=0 -r '...the code...' [arguments]`.

The ungolfed source code, the test suite and examples of usage can be found on github.

---
Tags: code-golf
---


# Question
Title: Find how many pair elements sums up to N
Based on a recent question in StackOverflow

Write a program/function that takes in one ARRAY/list and returns the number of pair-values which sums up to a given TOTAL.

### Explaining

```
TOTAL=4, ARRAY=[1,3,7,1,-3] => RESULT=2

```

The result was 2 because `1 + 3` and `7 + -3` are valid pairs which sums up to `TOTAL=4`.

* When one pair is formed, you should not count any of its values again
* Also, you are not allowed to add any value that is not present in the ARRAY.

This is , shortest in bytes wins

All values will be between your language's int min-max.

### Another cases

```
9, [1,2,3,5,4,6,7,-10] => 3          // [2,7]  [3,6]  [5,4]
0, [] => 0                           //
0, [1,-2,0,-1,2] => 2                // [1,-1]  [-2,2]
5, [5,5,5,0,-1,1,-5] => 1            // [5,0]
3, [7,-7,8,3,9,1,-1,5] => 0          //
2, [1,1] => 1                        // [1,1]
2, [1,1,1,1,1] => 2                  // [1,1]  [1,1]
4, [1,3,3,3] => 1                    // [1,3]

```

# Answer
> 4 votes
# Pyth, 9 bytes

```
/sM{.cSE2

```

Test suite

Takes the number and array newline separated.

**Explanation:**

```
/sM{.cSE2
/sM{.cSE2Q    Implicit variable introduction.
              Implicit: Q = eval(input())
       E      Take the array as input.
      S       Sort the input.
    .c  2     Form all ordered pairs.
   {          Deduplicate.
 sM           Map each to its sum.
/        Q    Count the number of occurrences of Q in the resulting list.

```

# Answer
> 4 votes
# R, 48 bytes

```
function(x,y)sum(colSums(combn(unique(x),2))==y)

```

# Answer
> 1 votes
# Pyth - 13 bytes

```
l{SMfqQsT.PE2

```

Test Suite.

# Answer
> 1 votes
## Matlab(38)

```
 @(a,b)nnz(sum(nchoosek([b,.5],2)')==a)

```
* the 0.5 part is a dodge for second test case

---

cropped by 2 bytes following Alex' comment.

# Answer
> 1 votes
# Julia, 48 bytes

```
x->n->count(p->sum(p)==n,combinations(∪(x),2))

```

This is an anonymous function that accepts an array and an integer and returns an integer. To call it, assign it to a variable and call like `f(x)(n)`.

We get all combinations of size 2 from the unique values in the input array and for each pair test whether the sum is equal to the input integer. We count all such cases and return the result.

Try it online! (includes all test cases)

# Answer
> 1 votes
# JavaScript (ES6), ~~112~~ ~~67~~ ~~59~~ 52 bytes

```
(a,b)=>{c=0;for(i of a)a.map(j=>c+=i+j==b);return c}

```

Because of amazing `for-of` loops of ES6, I was able to shave off **42** bytes from my previous solution!

**Update** : Thanks to @user6188402 for helping me shave off 3 bytes!

**Update** : Thanks to @Bálint for helping me shave off 15 bytes!

Try it Online!

**Note** : *This fails for repeating numbers.*

---
Tags: code-golf, math, arithmetic, array
---


title: Rotation-safe Latin squares

text:
# Question
Title: Rotation-safe Latin squares
**A Latin square is a square that has no repeated symbols in either the X or Y columns**. For example:

```
ABCD
DABC
CDAB
BCDA

```

is one such square. Notice how every column and row contains a permutation of the same 4 letters.

However, our Latin square has a problem: **If I were to rotate the second row (`DABC`) 1 to the left, I'd end up with `ABCD`, which is identical to the permutation above it.** If it is *impossible* to rotate any 1 column/row and obtain another column/row, then we consider the square to be **rotation safe**.

For example:

```
ABCD
BDAC
CADB
DCBA

```

is rotation safe. The grid has the following properties:

1. **Point \[0,N\] uses the Nth symbol**
2. **Point \[0,N\] and \[N,0\] are always the same symbol**. (I'd like to also say that \[x,y\] and \[y,x\] are also always the same letter, but I can't prove it)

**Your task is to print out 1 rotation-safe Latin square, when passed N.** I don't care if you output letters, numbers, a list, or a 2D array. **If you use numbers, the top column and row must be `0,1,2,3,...` (in that order). If you use letters, then it must be `A,B,C,D,....`**

For example, if your input was 4, you should either print:

```
0,1,2,3            0,1,2,3
1,3,0,2     or     1,0,3,2
2,0,3,1            2,3,1,0
3,2,1,0            3,2,0,1

```

There are no rotation-safe Latin squares of size less than 4. I don't care what your program does if N is less than 4. For the curious, the number of rotation-safe squares is (starting at 4): `2,5,5906,(too long to calculate)`

This is a , so try to make answers as short as possible in your favorite language!

# Answer
# Pyth - 29 bytes

Brute force.

```
hf&!@JsCBTsm.>RdJStQ.A{IMJ^.p

```

Does not finish online even for `n=4`, but you can try it out locally, or run this modified version online for one more byte.
> 3 votes

# Answer
# Sqlserver 2012 - 918 bytes

On my box this runs for @k = 5, although it takes 16 seconds.

This is code building code(watch out Skynet, you have competition)

Is there a price for the longest script?

```
DECLARE @k int = 4;

DECLARE @t VARCHAR(max)='WITH C as(SELECT
top '+left(@k,1)+'row_number()over(order by 1/0)n
FROM sys.messages),D(nÆ)as(SELECT
concat(~),~
FROM Ø
WHERE |)SELECT top 1~ FROM Å
WHERE 1=1',@
varchar(999)=''SELECT @+=','+CHAR(x+65)FROM(values(0),(1),(2),(3),(4),(5))x(x)WHERE x<@k
SELECT
@t=REPLACE(REPLACE(REPLACE(REPLACE(@t,'Æ',@),'Ø',STUFF(REPLACE(@,',',',C '),1,1,'')),'Å',STUFF(REPLACE(@,',',',D
'),1,1,'')),'~',STUFF(REPLACE(@,',','.n,'),1,3,'')+'.n'),@='';WITH C as(SELECT top(@k)x
FROM(values(0),(1),(2),(3),(4),(5))x(x))SELECT @+=' AND
'+char(65+C.x)+'.n<>'+char(65+D.x)+'.n'FROM c,c d WHERE C.x<D.x
SELECT @t=REPLACE(@t,'|',STUFF(@,1,4,''));WITH A
as(SELECT top(@k)x
FROM(values(65),(66),(67),(68),(69),(70))x(x))SELECT @t+='AND
'+char(A.x)+'.'+char(C.x)+'<>'+CHAR(B.x)+'.'+char(C.x)+' AND
'+char(A.x)+'.n+'+char(A.x)+'.n'+'
not like''%''+'+char(B.x)+'.n+''%'''FROM A,A B,A C
WHERE A.x<>B.x and C.x<>B.x
EXEC(@t)

```

Try online!
> 2 votes

---
Tags: code-golf, grid, permutations
---