# Question
Title: The shortest distance between two points is a line
Code a program or function to construct an interactive canvas on the screen of at least 400 pixels x 400 pixels in size. The canvas can be any color you wish, bordered or borderless, with or without a title bar, etc., just some form of obvious canvas.

The user will click on two distinct areas of the canvas and the program must output the Euclidean distance (in pixels) between those two clicks in some fashion (STDOUT, displaying an alert, etc.). The two clicks can be only left clicks, only right clicks, a left click for the first and right click for the second, two double-left-clicks, etc., any combination is acceptable. Special Note: Clicking-and-dragging (e.g., using MOUSEUP as the second point) is specifically not allowed; they must be two distinct clicks.

The user must be able do this multiple times, and must get an output each time, until the program is closed/force-quit/killed/etc. You can choose the method of closure (clicking an X, ctrl-C, etc.), whatever is golfier for your code.

### Rules

* Either a full program or a function are acceptable. If a function, however, you must still display the output to the user somehow (simply returning the value is not acceptable).
* Output can be to the console, displayed as an alert, populated onto the canvas, etc.
* Standard loopholes are forbidden.
* This is so all usual golfing rules apply, and the shortest code (in bytes) wins.

# Answer
> 8 votes
# LOGO (FMSLogo), ~~54~~ 52 bytes

```
[mouseon[setpos mousepos]"[pr distance mousepos]"[]]

```

Unfortunately, I can't find any Logo interpreter online support mouse handling like FMSLogo.

This is a "explicit-slot template", which is similar to lambda in other programming languages. Click left mouse for first point and right mouse for second point (print distance).

Explanation: (Logo is a turtle graphics programming language)

```
mouseon                  Turn on mouse handling, with the following action:
[setpos mousepos]        Set the turtle to `mousepos` (the position of the mouse) on left mouse down
"                        Do nothing on left mouse up
[pr distance mousepos]   Print the distance from turtle position (`distance` is Logo builtin for that purpose) to `mousepos` on right mouse down
"                        Do nothing on right mouse up
[]                       Do nothing on mouse movement

```

The `"` is an empty word. Normally template is expected to be a list (where `[]`, an empty list, does nothing), passing a word is acceptable (it is wrapped in a list), and in this case it saves 2 bytes.

Run:

```
apply [... <put the code here> ...] []

```

The `apply` is one way to run template in Logo, the `[]` is argument list, for which the template receive none.

# Answer
> 7 votes
## Mathematica, 94 bytes

```
e="MouseDown";m:=x=MousePosition[];1~RandomImage~400~EventHandler~{e:>m,{e,2}:>Echo@Norm[x-m]}

```

The canvas is a random grey-scale image, the first click should be a left-click and the second one a right-click. The exact behaviour is actually that right-click prints the distance to the last click (left *or* right), so if you use right-click repeatedly, you can also get consecutive distances.

The results are exact, so they might contain a square root.

If the resolution of your webcam is at least 400x400, you could use `CurrentImage[]` instead of `1~RandomImage~400` for your canvas, saving 3 bytes.

# Answer
> 6 votes
# Java 8, ~~469~~ ~~389~~ ~~388~~ ~~385~~ ~~380~~ ~~357~~ ~~348~~ 325 bytes

```
import java.awt.event.*;interface F{static void main(String[]a){new java.awt.Frame(){{setSize(400,400);double[]a={-1,0};addMouseListener(new MouseAdapter(){public void mouseClicked(MouseEvent e){if(a[0]<0){a[0]=e.getX();a[1]=e.getY();}else{System.out.println(Math.hypot(e.getX()-a[0],e.getY()-a[1]));a[0]=-1;}}});}}.show();}}

```
~~```
import javafx.application.*;import javafx.scene.*;import javafx.scene.layout.*;import javafx.stage.*;public class E extends Application{double[]a={-1,0};public void start(Stage s)throws Exception{Pane p=new Pane();s.setScene(new Scene(p,400,400));s.show();p.setOnMouseClicked(e->{if(a[0]<0){a[0]=e.getX();a[1]=e.getY();}else {System.out.println(Math.sqrt(Math.pow(e.getX()-a[0],2)+Math.pow(e.getY()-a[1],2)));a[0]=-1;}});}public static void main(String[]a){launch(a);}}

```~~

~~Would be shorter with AWT, but I've never used it.~~

# Answer
> 5 votes
# Java (OpenJDK 8), 282 bytes

```
import java.awt.event.*;interface M{static void main(String[]a){new java.awt.Frame(){int k,x,y;{addMouseListener(new MouseAdapter(){public void mouseClicked(MouseEvent e){x=e.getX()-k*x;y=e.getY()-k*y;k^=1;if(k<1)System.out.println(Math.hypot(x,y));}});setSize(800,600);show();}};}}

```

I cannot test this right now; if someone could tell me if there are any compiler errors that would be great.

~~AWT would probably be shorter but I need an actual IDE for that lol. I've never used AWT before but I could make it work if I had an IDE. I could use the docs but that's really hard lol~~

-10 bytes using AWT thanks to Kevin Cruijssen
-44 bytes using an initializer block; developed independently of Roberto Graham though I now see that they did the same thing, I think
-6 bytes combining a few declarations thanks to Kevin
-11 bytes using an `interface` thanks to Kevin
-35 bytes eliminating some unnecessary variables thanks to mellamokb
-9 bytes removing the unnecessary import and using a qualified name thanks to mellamokb
-44 bytes thanks to mellamokb and aditsu

# Answer
> 4 votes
# TI-Basic (TI-84 Plus CE), 49 bytes (45 tokens) (possibly non-competing)

```
0→Xmin
0→Ymin
8³→Xmax
Ans→Ymax
While 1
Input
{X,Y
Input
Ans-{X,Y
Disp √(sum(Ans²
Pause
End

```

-7 bytes with suggestions from kamoroso94

The user doesn't 'click' per se, but moves around a cursor on the graph screen with the arrow keys and hits `enter` to select a point, and the smallest movement is ~1.5 for x and ~2.4 for y.

Explanation:

```
0→Xmin                # 5 bytes
0→Ymin                # 5 bytes
8³→Xmax               # 6 bytes,
Ans→Ymax              # 5 bytes, Set up graph screen size (512x512)
While 1               # 3 bytes, Until interrupted with `on` button
Input                 # 2 bytes, Get user input as a point on the graph screen in X and Y
{X,Y                  # 5 bytes, store the list {X,Y} in Ans
Input                 # 2 bytes, Get second user input as a point on the graph screen in X and Y
Ans-{X,Y              # 7 bytes, store {X1-X2,Y1-Y2} in Ans
Disp √(sum(Ans²       # 6 bytes, Display the distance between the two points
Pause                 # 2 bytes, Let the user see it (press `enter` to continue)
End                   # 1 bytes, End while loop

```

# Answer
> 4 votes
# JavaScript (ES6) + HTML, 58 bytes

The webpage itself serves as the "canvas" in question; I think it's quite safe to assume the browser window will be at least 400x400 pixels.

```
E=0,onclick=e=>(E&&alert(Math.hypot(E.x-e.x,E.y-e.y)),E=e)
```

---

# JavaScript (ES6) + HTML, 51 bytes

We can save 7 bytes if we ignore the `NaN` output on the first click. (@Nate)

```
E=onclick=e=>alert(Math.hypot(E.x-e.x,E.y-e.y),E=e)
```

---

# JavaScript (ES6) + HTML + CSS, 58 + 0 + 13 = 71 bytes

**Edit**: With an additional 13 bytes of CSS, we can ensure the scroll area will be sufficiently large enough to fit the 400x400 requirement.

```
E=0,onclick=e=>(E&&alert(Math.hypot(E.x-e.x,E.y-e.y)),E=e)
```

```
*{padding:9in
```

# Answer
> 3 votes
# Processing/Java, 149 bytes

```
void setup(){size(400,400);}void draw(){}int a,b;void mousePressed(){if(mouseButton==LEFT){a=mouseX;b=mouseY;}else println(dist(a,b,mouseX,mouseY));}

```

Pretty straightforward, uses 2 global variables and 3 built-in functions to do everything.

* Setup: just initializes the window to 400x400
* Draw: empty, but must exist for Processing to be interactive for \>1 frame
* MousePressed: if left click, save the mouse coordinates into the integers a and b. If right click, measure the distance from point (a, b) to the current position, and print to the console.

# Answer
> 2 votes
# Processing.org 126

```
float i,d,x,y;void setup(){fullScreen();}void draw(){}void mousePressed(){d=dist(x,y,x=mouseX,y=mouseY);print(i++%2<1?" ":d);}

```

# Answer
> 1 votes
## Python 2, 144

Prints distance between last clicks (first one prints distance from 400,400).

```
import Tkinter as t,math
r=t.Tk()
p=[400]*2
r.minsize(*p)
def f(e):print math.hypot(p[0]-e.x,p[1]-e.y);p[:]=e.x,e.y
r.bind('<1>',f)
r.mainloop()

```

# Answer
> 0 votes
# Python 2 (TigerJython), ~~125~~ 123 bytes

```
from gturtle import*
n=0
def c(x,y):
 global n
 if n:print distance(x,y)
 else:setPos(x,y)
 n^=1
makeTurtle(mousePressed=c)

```

TigerJython comes with a default size of (800x, 600y) sized canvas.

This spawns a temporary turtle image for every 'begin' point clicked, which disappears after the next 'begin' point is selected. This behaviour is approved by the OP.

# Answer
> 0 votes
# Autohotkey, 146 bytes

```
A=0
Gui,Add,Text,W400 H400 gC Border
Gui,Show
Return
C:
If A=0
MouseGetPos,A,B
Else{
MouseGetPos,C,D
Msgbox % Sqrt((A-C)**2+(B-D)**2)
A=0
}
Return

```

You'd think a language built specifically for capturing and simulating keyboard and mouse actions would be more efficient at this challenge...

This creates a window with a text box 400 x 400 pixels with a border to make it obvious. Without the border, there's a space around the edge that's in the window but outside the text box and you can't tell. Adding a border was the shortest way to differentiate them. The `gC` option make it run the subroutine `C` whenever you click on the text box. The command sequence is, therefore, Left Click followed by a different Left Click.

I found another solution that's 144 bytes but it allows clicks all over the screen instead of just in the "obvious canvas". It's also annoying to end because both left and right clicks are captured and it doesn't end when you close the GUI.

```
Gui,Add,Text,W400 H400 Border
Gui,Show
Return
LButton::
MouseGetPos,A,B
Return
RButton::
MouseGetPos,C,D
Msgbox % Sqrt((A-C)**2+(B-D)**2)
Return

```

# Answer
> 0 votes
# SmileBASIC, 86 bytes

```
@L
TOUCH OUT F,X,Y
S=S-X
T=T-Y
IF!O*F*M THEN?SQR(S*S+T*T)
S=X
T=Y
M=M!=!O*F
O=F
GOTO@L

```

Uses touch screen for input.

# Answer
> 0 votes
# Tcl/Tk, 94 ~~104~~

```
wm ge . 400x400
bind . <1> {if [info ex x] {puts [expr hypot(%x-$x,%y-$y)]}
set x %x
set y %y}

```

# Answer
> 0 votes
# Java 8, 228 bytes

```
interface A{static void main(String[]a){new java.awt.Frame(){{setSize(400,400);}int i,j,t;public boolean mouseDown(java.awt.Event e,int x,int y){if(t++%2==1)System.out.println(Math.hypot(x-i,y-j));i=x;j=y;return 1>0;}}.show();}}

```

Here's a Java solution that uses a deprecated AWT method `mouseDown` that you'd have to dig deep into the API to find. I only know of it because of the programming course I took as a high school sophomore, and one of the projects was to make a small paint program using that and similar methods. I never thought I'd have a good reason to use it until now.

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


title: Rotate a hypercube

text:
# Question
Title: Rotate a hypercube
## Introduction

A hypercube/tesseract is the 4 dimensional equivalent of a normal cube. It's made by taking a cube net, extending it to the 3rd dimension, then – using the 4th dimension – folding it into a hypercube. It's basically a cube, where each side is a cube.

To create a hypercube, you need 16 4d vectors (a vector with an `x`, a `y`, a `z` and a `w` component). These vectors are the following:

```
A(0, 0, 0, 0); B(1, 0, 0, 0); C(1, 0, 1, 0); D(0, 0, 1, 0); E(0, 1, 0, 0); F(1, 1, 0, 0); G(1, 1, 1, 0); H(0, 1, 1, 0);
I(0, 0, 0, 1); J(1, 0, 0, 1); K(1, 0, 1, 1); L(0, 0, 1, 1); M(0, 1, 0, 1); N(1, 1, 0, 1); O(1, 1, 1, 1); P(0, 1, 1, 1);

```

The hypercube has 24 faces. The following list contains all of them (every group marks a quad):

```
ABFE, CDHG, BCGF, DAEH, DCBA, FEHG
IJNM, KLPO, JKON, LIMP, LKJI, PMNO
ABJI, DCKL, BCKJ, DAIL, FEMN, GHPO, FGON, EHPM, EAIM, BFNJ, CGOK, HDLP

```

With all this information, you technically have a hypercube in code. To rotate this, you need 6 different matrices for each rotational plane, one for the YZ, XZ, XY, XW, YW and ZW planes. After you have every matrix, you need to multiply the cube's vertices with them.

The following images show the structure of each matrix:

For the rotation on the YZ plane:

For the rotation on the XZ plane:

For the rotation on the XY plane:

For the rotation on the XW plane:

For the rotation on the YW plane:

For the rotation on the ZW plane:

The rotations get applied in this order.

After all this, you have a rotated hypercube. Now you need to draw it. You should use an orthogonal projection combined with a perspective projection to send `(x, y, z, w)` to `(2x/(2+z), 2y/(2+z))`.

## Input

Your input is 6 integers between 0 (inclusively) and 360 (exclusively). These represent the rotations in degrees on the different rotational planes of the hypercube.

## Output

Your output should be a single image containing the hypercube. The display can be a rasterized image, a vector image or an ASCII art. The output image should be at least 100 * 100 pixels, and the cube needs to take up at least 50% of the screen. Any default image output format is allowed.

## Test cases

```
0 0 0 0 0 0

```

```
0 0 0 0 0 30

```

```
30 0 0 0 0 30

```

```
0 0 0 30 30 30

```

```
45 45 45 0 0 0

```

```
45 45 45 45 45 45

```

Open the images in a new tab, to see them in full size.

## Rules

* Default rules apply
* Standard loopholes are forbidden
* Shortest code in bytes wins

# Answer
> 9 votes
# Octave, ~~474~~ ~~433~~ 429 bytes

```
function H(a,b,c,d,e,f) C=@cosd;S=@sind;R=[1,0,0,0;0,C(e),0,-S(e);0,-S(e)*S(f),C(f),-C(e)*S(f);0,S(e)*C(f),S(f),C(e)*C(f)]*[C(c)*C(d),-S(c)*C(d),0,S(d);S(c),C(c),0,0;0,0,1,0;-C(c)*S(d),S(c)*S(d),0,C(d)]*[C(b),S(a)*S(b),C(a)*S(b),0;0,C(a),-S(a),0;-S(b),S(a)*C(b),C(a)*C(b),0;0,0,0,1]*(dec2bin(0:15)'-48.5);Z=R(3,:)+2;R=2*R./Z;Q=[1,2,10,12,11,9,10,14,16,12,4,8,16,15,11,3,7,15,13,9,1,5,13,14,6,8,7,5,6,2,4,3,1];plot(R(1,Q),R(2,Q));

```

**Rotated:**

```
function H(a,b,c,d,e,f)
C=@cosd;S=@sind;
R=[1,0,0,0;0,C(e),0,-S(e);0,-S(e)*S(f),C(f),-C(e)*S(f);0,S(e)*C(f),S(f),C(e)*C(f)]*
  [C(c)*C(d),-S(c)*C(d),0,S(d);S(c),C(c),0,0;0,0,1,0;-C(c)*S(d),S(c)*S(d),0,C(d)]*
  [C(b),S(a)*S(b),C(a)*S(b),0;0,C(a),-S(a),0;-S(b),S(a)*C(b),C(a)*C(b),0;0,0,0,1]*
  (dec2bin(0:15)'-48.5);
Z=R(3,:)+2;
R=2*R./Z;
Q=[1,2,10,12,11,9,10,14,16,12,4,8,16,15,11,3,7,15,13,9,1,5,13,14,6,8,7,5,6,2,4,3,1];
plot(R(1,Q),R(2,Q));

```

The rotation matrices still consume a lot of bytes, but the Eulerian cycle worked out quite well, reducing the number of vertices visited from ~~96~~ 120 down to 33.

Vertices are generated by taking the 4-bit binary representation of `[0:15]` and considering the msb to be the x-coordinate and the lsb the w-coordinate.

Edit: Pre-multiplying all of the rotation matrices was a nightmare, which is why I didn't use it initially, but pre-multiplying them in pairs saved 41 bytes. ~~Now to look for the optimum combination. :)~~ Multiplying the matrices by threes was worse than no pre-multiplication at all, so I'll be happy with the pair-wise approach.

---

**Output:**

```
H(0,0,0,0,0,0)

```

```
H(0,0,0,0,0,30)

```

```
H(30,0,0,0,0,30)

```

```
H(0,0,0,30,30,30)

```

```
H(45,45,45,0,0,0)

```

```
H(45,45,45,45,45,45)

```

# Answer
> 14 votes
## Postscript ~~1075~~ ~~732~~ ~~683~~ ~~640~~ ~~631~~ ~~601~~ ~~590~~ ~~545~~ ~~542~~ ~~526~~ ~~514~~ ~~478~~ 470

Uses mat.ps and .

*Edit:-343* Applied binary-encoding generation of vectors and Eulerian circuit ~~stolen~~ borrowed from other answers. And applied binary-token-strings from the G library.
*Edit:-49* Redefined `sin` `cos` and `neg` to shorter names.
*Edit:-43* Defined short names for sequences `0 0` `0 1` `1 0`.
*Edit:-9* `al` (ie. `aload`) is shorter than `(")@`. Factored 3 calls to `idi` (ie. `idiv`) at the cost of a do-nothing `1 idiv`.
*Edit:-30* Applied *implicit definition block* from G.
*Edit:-10* A few more triply-used sequences.
*Edit:-45* Remove variables `i` `j` `k` `l` `m` `n` for the angles and always define the current angle as `t` and functions of angles use the value of the (global) `t` variable. Defer execution of the code-description of the rotation matrix until its `t` value is ready.
*Edit:-3* Remove `<16>$` ie. `closepath`. And a space.
*Edit:-16* Factor-out array brackets from unit vectors in the rotation matrices (`J` `K` `L` and `M`). Re-apply dropped `mo` for `mod` and `su` for `sub`.
*Edit:-12* In-line the *project-and-draw* function and remove (now empty) enclosing dictionary.
*Edit:-36* Encoded the circuit (ie. the *faces*) in a string.
*Edit:-8* Remove definition of vertices array `V`. Instead, leave on stack and `dup` working copies as needed (once, at first, and again at the end of the loop). Also, translated a few operators from binary-token-strings back to abbreviated names where the BTS gave no savings, so `(I)$` is now `fora` (ie. `forall`). `if du` could be `(T8)$`, but `if du` is clearly a better choice (it's *golf*, not *obfuscation* per se). Also, perform the `scale` *before* `translate`, so translated coordinates can be `3` and `4` instead of `300` and `400`.

```
(mat.ps)run 3(G)run $
t sin
A neg
t cos
0 0
0 1
1 0
2 mu Z 2(!V)@
idi 2 mo .5 su
(>8)$
[F D]
[D E]
[E D]
[D F]

3 4 100(&>88)$(,)# div(<N)#[E 15{[I 1 H I 2 H I 4 H ex 8 H]}fo]E
5{ARGUMENTS 1(XK/)$/t ex d{{J[0 C B 0][0 A C 0]K}{[C 0 A 0]L[B 0
C 0]K}{[C B D][A C D]M K}{[C D A]L M[B D C]}{J[0 C 0 B]M[0 A 0
C]}{J L[D C B][D A C]}}(>K)$[(>?)$]transpose matmul}fo
du(019;:89=?;37?>:26><804<=576451320){48 su get al po{W
Z Y X}{(>3)$}fora X G Y G{li}(D)#{mov}if du}fora(HB)#

```

The `3` `4` and `100` in the first line of the second block are parameters representing center-x, center-y and scale, respectively, of the drawing on the page (center coordinates are scaled by `scale`). (300,400) is roughly the center of US letter-sized paper (612,792) in PS units.

If you can roughly follow postscript, the important bizarre things are the *implicit procedure block* and the encoded operator strings. As shown by comments in the workfile, below, each line of the first block is implicitly named by A, B, C, etc. So, eg. `F E D` would produce `1 0 0 1 0 0`. For the encoded operator strings, anything that is an argument to `$` `#` or `@` is a sequence of operator calls, using the bytes to select operators from the system name table, PLRM 3ed Appendix F. These features and more are available for PostScript with the G library (now includes the mat.ps functions too).

Workfile:

```
(mat.ps)run 3(G)run $
t sin %/A
A neg %/B
t cos %/C
0 0 %/D
0 1 %/E
1 0 %/F
2 mu Z 2(!V)@ %/G  %ad div %add div %108 1 54
idi 2 mo .5 su %idiv mod sub %/H %106 169 51
(>8)$ %/I %exch dup
[F D] %/J
[D E] %/K
[E D] %/L
[D F] %/M

3 4
100(&>88)$ %currentlinewidth exch dup dup %38
(,)#  %scale %139-95=44
div(<N)# %div setlinewidth %54 155-95=60 %translate %173-95=78
%/V
[E 15{[ I
    1 H I
    2 H I
    4 H ex
    8 H]}fo]

E 5{ARGUMENTS 1(XK/)$ %index get cvr %88 75 47
    /t ex d %exch def %62 51
    {{J[0 C B 0][0 A C 0]K}
     {[C 0 A 0]L[B 0 C 0]K}
     {[C B D][A C D]M K}
     {[C D A]L M[B D C]}
     {J[0 C 0 B]M[0 A 0 C]}
     {J L[D C B][D A C]}}
    (>K)$ %exch get %62 75
    [
        (>?)$ %exch exec %62 63
    ]
    transpose matmul
}fo %for
du %dup
%d %def
%{transpose matmul}fora d

%[E 9 11 10 8 9 13 15 11 3 7 15 14 10 2 6 14 12 8 0 4 12 13 5 7 6 4 5 1 3 2 0]
%<0001090b0a08090d0f0b03070f0e0a02060e0c0800040c0d050706040501030200>
%          abcdef
%0123456789:;<=>?
(019;:89=?;37?>:26><804<=576451320)
{48 su get % 169 75 %V (>K)$ %sub %exch get

    al po %aload pop %2 117
    {W Z Y X}{(>3)$ %exch def
    }fora %forall %2 117  62 51 73
    X G
    Y G
    {li}(D)# %stopped
    {mov}
    if du%(T8)$ %if %84 du %dup 56
}
%<49a7a1>$ %forall stroke showpage %73 167-95=72 161-95=66
fora(HB)#

```

Ungolfed and lightly commented:

```
300 400 translate   %roughly center of letter paper
currentlinewidth
100 dup dup scale
div setlinewidth    %scale x100, reduce line-width/100
(mat.ps)run         %load matrix library
ARGUMENTS aload pop{f e d c b a}{exch cvr def}forall  %define args as
                                 % a,b,etc and convert to real numbers
/m{2 mod .5 sub}def
/P{aload pop{w z y x}{exch def}forall   %P: [x y z w]  project-and-draw  -
    x 2 mul z 2 add div
    y 2 mul z 2 add div
    {lineto}stopped{moveto}if %catch(&handle!) nocurrentpoint error in lineto
}bind def
/V[0 1 15{    % generate vectors with a for-loop
    [ exch
        dup m
        1 index 2 idiv m
        2 index 4 idiv m
        4 3 roll 8 idiv m
    ]
}for]
[[[1 0 0 0][0 a cos a sin neg 0][0 a sin a cos 0][0 0 0 1]]
     [[b cos 0 b sin 0][0 1 0 0][b sin neg 0 b cos 0][0 0 0 1]]
     [[c cos c sin neg 0 0][c sin c cos 0 0][0 0 1 0][0 0 0 1]]
     [[d cos 0 0 d sin][0 1 0 0][0 0 1 0][d sin neg 0 0 d cos]]
     [[1 0 0 0][0 e cos 0 e sin neg][0 0 1 0][0 e sin 0 e cos]]
     [[1 0 0 0][0 1 0 0][0 0 f cos f sin neg][0 0 f sin f cos]]]
{transpose matmul} forall def   % apply array of rotations and define

%Eulerian circuit (borrowed and adjusted for 0-based indexing)
[0 1 9 11 10 8 9 13 15 11 3 7 15 14 10 2 6 14 12 8 0 4 12 13 5 7 6 4 5 1 3 2 0]

% the main program!
% on the stack is the Eulerian circuit array
{
    V exch get  %lookup index in (sextuply-transformed) vertex array
    P           %call project-and-draw
} forall
closepath stroke %draw it, don't just think about it

showpage % gs's cmd-line-args option automatically sets -dBATCH,
    % so without a showpage, gs will immediately exit before you
    % can look at the picture :(

```

Some of my outputs are mirror images of the question's examples.

For `gs -- hc.ps 0 0 0 0 0 0`, I get:

`gs -- hc.ps 0 0 0 0 0 30`

`gs -- hc.ps 30 0 0 0 0 30`

`gs -- hc.ps 0 0 0 30 30 30`

`gs -- hc.ps 45 45 45 0 0 0`

`gs -- hc.ps 45 45 45 45 45 45`

Bonus animation I just made with this program. This image corresponds to the rotation sequence 0 30 60 0 *i* *i*, where i ranges from 0 to 360 by 2.

# Answer
> 8 votes
# C# + Unity, ~~1060~~ ~~845~~ 835 bytes

C# ≈ Java

Assumes that this function is in a script placed on `MainCamera`.

Edit:
Thanks to @TuukkaX for the suggestions to save 19 bytes Saved ~200 bytes using the Eulerian cycle.

Golfed:

```
void d(float[]r){transform.position=Vector3.back*2;GetComponent<Camera>().backgroundColor=Color.black;Vector4[]p=new Vector4[16];Matrix4x4[]m=new Matrix4x4[6];int i=0;for(;i<16;i++)p[i]=new Vector4(i%2,i/2%2,i/4%2,i/8%2)-new Vector4(.5f,.5f,.5f,.5f);int[,]X={{6,8,1,12,7,11},{5,0,0,0,5,10},{10,10,5,15,15,15}};for(i=0;i<6;i++){m[i]=Matrix4x4.identity;r[i]=Mathf.Deg2Rad*r[i];float c=Mathf.Cos(r[i]),s=Mathf.Sin(r[i]);m[i][X[1,i]]=c;m[i][X[2,i]]=c;m[i][X[0,i]]=s;m[i][X[0,i]%4*4+X[0,i]/4]=-s;}for(i=0;i<16;i++)foreach(Matrix4x4 x in m)p[i]=x*p[i];int[]F={0,1,9,11,10,8,9,13,15,11,3,7,15,14,10,2,6,14,12,8,0,4,12,13,5,7,6,4,5,1,3,2,0};LineRenderer l=new GameObject().AddComponent<LineRenderer>();l.SetVertexCount(33);l.material=new Material(Shader.Find("Sprites/Default"));l.SetWidth(.03f,.03f);for(i=0;i<33;i++)l.SetPosition(i,p[F[i]]);

```

Newlines + indentation + Full shell:

```
using UnityEngine;
using System.Collections;

public class h : MonoBehaviour {

    void d(float[]r)
    {
        transform.position=Vector3.back*2.5f;
        GetComponent<Camera>().backgroundColor=Color.black;
        Vector4[]p=new Vector4[16];
        Matrix4x4[]m=new Matrix4x4[6];
        int i=0;
        for(;i<16;i++)p[i]=new Vector4(i%2,i/2%2,i/4%2,i/8%2)-new Vector4(.5f,.5f,.5f,.5f);
        int[,]X={{6,8,1,12,7,11},{5,0,0,0,5,10},{10,10,5,15,15,15}};
        for (i=0;i<6;i++){
            m[i]=Matrix4x4.identity;
            r[i]=Mathf.Deg2Rad*r[i];
            float c=Mathf.Cos(r[i]);
            float s=Mathf.Sin(r[i]);
            m[i][X[1,i]]=c;
            m[i][X[2,i]]=c;
            m[i][X[0,i]]=s;
            m[i][X[0,i]%4*4+X[0,i]/4]=-s;
        }
        for (i=0;i<16;i++)foreach(Matrix4x4 x in m)p[i]=x*p[i];
        int[]F={0,1,9,11,10,8,9,13,15,11,3,7,15,14,10,2,6,14,12,8,0,4,12,13,5,7,6,4,5,1,3,2,0};
        LineRenderer l=new GameObject().AddComponent<LineRenderer>();
        l.SetVertexCount(33);
        l.material=new Material(Shader.Find("Sprites/Default"));
        l.SetWidth(.03f,.03f);
        for (i=0;i<33;i++)
            l.SetPosition(i,p[F[i]]);
        l.gameObject.tag = "Player";
    }
    public float[] input;
    void Start()
    {
        d(input);
    }
}

```

~~I couldn't figure out a simple formula for constructing the rotation matrices nor the "faces" which to draw, so that cost a lot of bytes to hard-code.~~ I borrowed the Eulerian cycle from @beaker. Also, Unity built-ins are extremely verbose.

You can verify all test cases online.

# Answer
> 6 votes
# Javascript ES6, 584 bytes

```
f=(...R)=>(P=s=>[...s].map(i=>parseInt(i,16)),C=document.createElement`canvas`,X=C.getContext`2d`,X.translate((C.width=300)/2,(C.height=300)/2),X.lineWidth=0.01,X.scale(100,100),X.beginPath(),P("0267fd9804c8ab915dcefb37546ea2310").map((e,i)=>{[x,y,z]=P("084c2a6e195d3b7f").map(i=>[...(1e3+i.toString(2)).slice(-4)].map(i=>i-0.5)).map(e=>(R.map((R,i,_,M=Math,C=M.cos(r=R*M.PI/180),S=M.sin(r))=>((a,b,s=1)=>[e[a],e[b]]=[C*e[a]-s*S*e[b],s*S*e[a]+C*e[b]])(...[[1,2],[0,2,-1],[0,1],[0,3,-1],[1,3],[2,3]][i])),e))[e];[x,y]=[2*x/(2+z),2*y/(2+z)];i?X.lineTo(x,y):X.moveTo(x,y)}),X.stroke(),C)

```

"Ungolfed":

```
f=(...R)=>(                                                              // function that accepts rotations in the following form: f(a,b,c,d,e,f)
    P=s=>[...s].map(i=>parseInt(i,16)),                                  // function to convert strings to hex-arrays
    V=P("084c2a6e195d3b7f")                                              // vertices encoded as hex values ( [0,1,1,0] -> 6 )
        .map(i=>[...(1e3+i.toString(2)).slice(-4)].map(i=>i-0.5))        // convert hex values to vertices, center the hypercube
        .map(e=>(R.map((R,i,_,M=Math,C=M.cos(r=R*M.PI/180),S=M.sin(r))=> // convert angles to degrees, precalculate sin and cos values
        ((a,b,s=1)=>[e[a],e[b]]=[C*e[a]-s*S*e[b],s*S*e[a]+C*e[b]])       // apply matrix transforms to all vertices
        (...[[1,2],[0,2,-1],[0,1],[0,3,-1],[1,3],[2,3]][i])),e)),        // list of encoded matrix transforms
    C=document.createElement`canvas`,X=C.getContext`2d`,                 // create image to draw on
    X.translate((C.width=300)/2,(C.height=300)/2),                       // setup image dimensions, center transform
    X.lineWidth=0.01,X.scale(100,100),X.beginPath(),                     // setup line, scale the transform and begin drawing
    P("0267fd9804c8ab915dcefb37546ea2310").map((e,i)=>{                  // hypercube edge path indices encoded as hex values
        [x,y,z]=V[e];[x,y]=[2*x/(2+z),2*y/(2+z)];                        // project vertex
        i?X.lineTo(x,y):X.moveTo(x,y)}),X.stroke(),                      // draw vertex
    C)                                                                   // return image

```

See it in action (modified to continuously rotate):

```
with(document)with(Math)with(document.getElementById`canvas`)with(getContext`2d`){render=()=>{requestAnimationFrame(render);clearRect(0,0,width,height);save();K=performance.now();R=[K*0.01,K*0.02,K*0.03,K*0.04,K*0.05,K*0.06];X=s=>[...s].map(i=>parseInt(i,16));V=X("084c2a6e195d3b7f").map(i=>[...(1e3+i.toString(2)).slice(-4)].map(i=>i-0.5)).map(e=>(R.map((R,i,_,C=cos(r=R*PI/180),S=sin(r))=>((a,b,s=1)=>[e[a],e[b]]=[C*e[a]-s*S*e[b],s*S*e[a]+C*e[b]])(...[[1,2],[0,2,-1],[0,1],[0,3,-1],[1,3],[2,3]][i])),e));translate((width=300)/2,(height=300)/2);lineWidth=0.01;scale(100,100);beginPath();X("0267fd9804c8ab915dcefb37546ea2310").map((e,i)=>{[x,y,z]=V[e];[x,y]=[2*x/(2+z),2*y/(2+z)];i?lineTo(x,y):moveTo(x,y)});stroke();restore();};render();}
```

```
<html><body><canvas id="canvas"></canvas></body></html>
```

The function returns a HTML5 canvas object, you need to add it to the page by doing `document.body.appendChild(f(0,0,0,0,0,0))` for example.

Currently, the rotations are applied out of order, I'm working on the reordering, but as is, it rotates a hypercube correctly.

# Answer
> 2 votes
# Mathematica, ~~453~~ 415 bytes\*

Shortened by using the Eulerian tour and cleaning it all up into a single statement without defining functions in variables. This makes the code slower for some reason. I'm guessing Mathematica reevaluates the functions multiple times now that they are not stored in a variable.

```
Graphics[Line[Table[{2#/(2+#3),2#2/(2+#3)}&@@Map[Dot@@Table[Table[If[n==m==#2||n==m==#,Cos[#3],If[n==#2&&m==#,If[#2==1&&(#==3||#==4),1,-1]Sin[#3],If[n==#&&m==#2,If[#2==1&&(#==3||#==4),-1,1]Sin[#3],If[n==m,1,0]]]],{n,4},{m,4}]&[k[[1]],k[[2]],a[[k[[3]]]]°],{k,{{4,3,6},{4,2,5},{4,1,4},{2,1,3},{3,1,2},{3,2,1}}}].#&,Tuples[{0,1},4]-.5,{1}][[i]],{i,{1,2,10,12,11,9,10,14,16,12,4,8,16,15,11,3,7,15,13,9,1,5,13,14,6,8,7,5,6,2,4,3,1}}]]]

```

* I am counting `°` and `==` as single bytes each since they are represented as a single character in Mathematica. I think this is fair since lots of languages use weird character encodings.

Ungolfed with comments. The input is hard coded at the top as `a={30,0,0,0,0,30};`. I didn't count that toward my score.

```

a = {45, 45, 45, 45, 45, 45};

(* #2,#-th rotation matrix as a funciton of #3 *)
(* Using the \
#-notation saved 6 bytes over the more common function definition \
notation*)
r =
  Table[If[n == m == #2 || n == m == #, Cos[#3],
     If[n == #2 && m == #,
      If[#2 == 1 && (# == 3 || # == 4), 1, -1] Sin[#3],
      If[n == # && m == #2,
       If[#2 == 1 && (# == 3 || # == 4), -1, 1] Sin[#3],
       If[n == m, 1, 0]]]], {n, 4}, {m, 4}] &;

(* Total rotation matrix. Need six of them. Function of the six \
angles to rotate.*)

u = Dot @@
     Table[r[k[[1]],
       k[[2]], \[Degree]*
        a[[k[[3]]]]], {k, {{4, 3, 6}, {4, 2, 5}, {4, 1, 4}, {2, 1,
         3}, {3, 1, 2}, {3, 2, 1}}}].# &;

(* List of all vertices of the hypercube *)
t = Tuples[{0, 1}, 4];
t -= .5;
v = Map[u, t, {1}];

(*projection*)
p = {2 #/(2 + #3), 2 #2/(2 + #3)} &;

(*Eulerian tour*)

l = Table[
   p @@ v[[i]], {i, {1, 2, 10, 12, 11, 9, 10, 14, 16, 12, 4, 8, 16,
     15, 11, 3, 7, 15, 13, 9, 1, 5, 13, 14, 6, 8, 7, 5, 6, 2, 4, 3,
     1}}];
Graphics[Line[l]]

```

`0 0 0 0 0 30`

`0 0 0 30 30 30`

`405 10 -14 -8 -9 205`

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


title: Tips for golfing in Starry

text:
# Question
Title: Tips for golfing in Starry
What general tips do you have for golfing in Starry? I'm looking for ideas which can be applied to code-golf problems and which are also at least somewhat specific to Starry (e.g. "remove comments" is not an answer).

Please post one tip per answer.

# Answer
# Use `dup` and `add` for large numbers

If you need to produce a big but reasonable number which is a multiple of 2 (and in some cases, even not a multiple), you can push half the number and end with `+*` (dup and add) instead of pushing the whole number. The threshold for this is **8** and above.

As mentioned, sometimes you can double, then subtract one (threshold **27**), and with multiples of higher 2 powers it can be repeated to gain greater numbers.

Try it online!
> 2 votes

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


title: Traveling on a flat Earth

text:
# Question
Title: Traveling on a flat Earth
Coordinates in the flat-Earth world consist of latitude (x) and longitude (y), which are integers in the range 0...9999. Much like Gaussian integers, but they are always written using this notation:

```
411S 370E

```

That is, with `S` or `N` appended to the latitude, and `E` or `W` appended to the longitude, with space(s) between the two components.

# Goal

Write a program (not a function) that reads two coordinates, separated by whitespace, and outputs their sum. The first coordinate is a starting point, the second one is a displacement, and the output is the resulting position.

# Input/Output

Since this challenge is partially about formatting, I'll try to define the input and output formats unambiguously.

The preferred input format has 1 space between the coordinate components, no leading zeros, and a newline character between the two coordinates. The program must be able to read the preferred format.

The output can contain any amount of whitespace and leading zeros. If it's different from the preferred input format, the program must be able to read this format too.

Just to make it clear, the input cannot (will not) contain any additional formatting characters. Just spaces and newlines where needed.

# Scoring

This is an experiment on a new winning condition. I'll choose the winner by accepting an answer in a few weeks. If a better answer appears afterwards, I'll change the accepted answer.

The score for the program is its byte count. The winning program is one that is shorter than 400 bytes, has the fewest byte count, but is written in the *most verbose* programming language. To determine the winner:

* Remove programs with byte count 400 or more (they can participate but cannot win)
* Consider only the *shortest* program for each programming language
* The *longest* program wins

Polyglots compete against programs in all languages in which they are valid (e.g. if a program is valid in both `bash` and `sh`, it competes against programs in both languages).

# Test cases

In the test cases, the first two lines are the input, and the third line is the output.

```
0S 0E
0S 0W
0N 0E

```

(the direction of zero doesn't matter, both in input and output)

---

```
0S 9999E
9999N 9999W
9999N 0E

```

(maximal values)

---

```
42S 314W
42N 2718W
0N 3032W

```

(the direction of zero doesn't matter in the output)

---

```
5555N 8888W
7777S 0E
2222S 8888W

```

(no negative values; change the direction if you need to change the sign)

---

```
0001N        4545W
0999N        5454W
1000N        9999W

```

(if the program outputs leading zeros and several spaces, it must be able to read them; it must also be able to read input that doesn't contain them)

---

```
8888N 8888W
9999N 9999W

```

(invalid input - any behavior is acceptable, including crash and infinite loop)

# Answer
> 3 votes
# ABAP, ~~377~~ 365 bytes

```
REPORT r.PARAMETERS: x TYPE string,y TYPE string.DEFINE m.SHIFT &1 RIGHT CIRCULAR.TRANSLATE &1 USING 'W-E+S-N+'. END-OF-DEFINITION. DEFINE o.&1 = |{ &1 * 1 SIGN = RIGHTPLUS DECIMALS = 0 }|.TRANSLATE &1 using &2. END-OF-DEFINITION.
SPLIT: x AT space INTO DATA(a) DATA(b),y AT ' ' INTO DATA(c) DATA(d). m: a,b,c,d.a = a + c.b = b + d.o: a '-S+N',b '-W+E'.WRITE: a, b.

```

Ungolfed:

```
REPORT r.
PARAMETERS: x TYPE string,
            y TYPE string.
DEFINE m.
  SHIFT &1 RIGHT CIRCULAR.
  TRANSLATE &1 USING 'W-E+S-N+'.
END-OF-DEFINITION.

DEFINE o.
  &1 = |{ &1 * 1 SIGN = RIGHTPLUS DECIMALS = 0 }|.
  TRANSLATE &1 using &2.
END-OF-DEFINITION.

SPLIT: x AT space INTO DATA(a) DATA(b),y AT ' ' INTO DATA(c) DATA(d).
m: a,b,c,d.
a = a + c.
b = b + d.
o: a '-S+N',b '-W+E'.
WRITE: a, b.

```

It was actually challenging to be within 400 characters.

Some notes:

* Original version had `ADD c TO a.` which is one of my favourite verbose statements.
* The built-in editor would not accept this as a 1 liner
* Using subroutines with `FORM` and `PERFORM` exploded the char count, so I kept to macros
* Chaining statements with colons is discouraged outside of data declarations, but was needed for saving bytes
* `+` without a preceding space is an offset operator, requiring many spaces in the code
* ABAP writes a space after numbers, hence the trick to just replace the sign
* In order to use `RIGHTPLUS` the expression needed to be a number, so the need to mulitply with 1, but then the format has decimals.. so hence `DECIMALS`

# Answer
> 4 votes
# MATLAB, ~~327~~ ~~304~~ ~~296~~ ~~290~~ ~~282~~ ~~276~~ ~~267~~ ~~259~~  ~~255~~  253 bytes

I think I'm closing in on a limit now. I've managed to remove ~~51, 60~~ ~~68~~ ~~72~~ 74 bytes from an answer I thought was well golfed. =)

Removed 8 bytes by taking the `input` inside the `strsplit`, thanks to Luis Mendo. Removed another 6 bytes by taking all the input into one cell array instead of two. Removed another 8 bytes by taking both last statements inside `disp()`. Removed 6 bytes by removing `char` and some brackets. This wasn't possible in a previous revision of the answer. Splitting the cell elements into four variables costed 15 bytes, but saved 24, thus 9 bytes saved! 8 additional bytes due to improved `disp` scheme. `5*~~s` saves two bytes compared to `(s>0)*5`. Thus 4 new bytes saved (for s and t). Taking the opposite of this last expression saves yet another 2 bytes, `83-5*~s` is shorter than `78+5*~~s`

Golfed code:

```
x=strsplit([input('','s'),' ',input('','s')]);[a,b,c,d]=x{:};f=@str2num;n=@num2str;i=@sign;s=f(a(1:end-1))*i(a(end)-79)+f(c(1:end-1))*i(c(end)-79);t=f(b(1:end-1))*i(b(end)-79)+f(d(1:end-1))*i(d(end)-79);disp([n(abs(s)),83-5*~s,32,n(abs(t)),87-18*~t,''])

```

Same code, but with line breaks:

```
x=strsplit([input('','s'),' ',input('','s')]);
[a,b,c,d]=x{:};
f=@str2num;
n=@num2str;
i=@sign;
s=f(a(1:end-1))*i(a(end)-79)+f(c(1:end-1))*i(c(end)-79);
t=f(b(1:end-1))*i(b(end)-79)+f(d(1:end-1))*i(d(end)-79);
disp([n(abs(s)),78+5*~~s,32,n(abs(t)),69+18*~~t,''])

```

**Test cases:**

Save the above as `flat_earth.m`

```
flat_earth
0S 0E
0S 0W
0N 0E

flat_earth
0S 9999E
9999N 9999W
9999N 0E

flat_earth
42S 314W
42N 2718W
0N 3032W

flat_earth
5555N 8888W
7777S 0E
2222S 8888W

flat_earth
0001N        4545W
0999N        5454W
1000N 9999W

```

# Answer
> 4 votes
## JavaScript (ES6), 118 bytes

```
s=>(g=([i,j,k,l,m,n],[o,p])=>(i=(j>p?-i:+i)+(n>p?-j:+j))<0?-i+o:i+p)(a=s.match(/\d+|\w/g),"SN")+' '+g(a.slice(2),"WE")

```

# Answer
> 3 votes
# R, 196 bytes

R is pretty verbose, by golfing standards. Let's see...

```
i=scan(,'');l=nchar(i);S=W=`-`;N=E=c;n=as.double(substr(i,1,l-1));d=substr(i,l,l);for(j in 1:4)n[j]=get(d[j])(n[j]);o=c(n[1]+n[3],n[2]+n[4]);cat(paste0(abs(o), ifelse(o<0,c("S", "W"),c("N","E"))))

```

Ungolfed:

```
input = scan(,'')       # Take input from stdin, separating at newlines and spaces
length = nchar(input)   # Get the number of characters in each input
S=W=`-`                 # These two lines create aliases of `-` (the minus function)
N=E=c                   # and c (the concatenate function).
                        # We will later treat the NSEW part of the coordinate
                        # as a call to a function, to ensure that the numbers
                        # are treated with the correct polarity.
numbers = as.double(substr(input, 1, length-1))
                        # Strip the last character off of every coordinate, convert
                        # to integer
directions = substr(input, length, length)
                        # Strip off the numbers and grab the cardinal directions
for(j in 1:4)
    numbers[j] = get(directions[j])(numbers[j])
                        # For our four numbers, treat the cardinal direction as
                        # a function, which is mapped to `-` for south and west, and
                        # `c` for north and east (which is essentially identity)
output = c(numbers[1]+numbers[3], numbers[2]+numbers[4])
                        # Add together the numbers
cat(paste0(abs(output), ifelse(output<0, c("S", "W"), c("N","E"))))
                        # Output the absolute values of the new coordinates, followed
                        # by "S" or "W" if the number is negative and "N" or "E" if
                        # the number is positive

```

Edit to add: I just looked at the other answers, and I'm surprised that my entry is one of the shortest! Perhaps R isn't as verbose as I thought...

# Answer
> 2 votes
# Java, 372 bytes

```
import static java.lang.System.*;class A{public static void main(String[]v){String l=" ",s=console().readLine()+l+console().readLine();Integer i=0,n[]=new Integer[4],y;for(;i<4;i++)n[i]=i.parseInt(s.replaceAll("[A-Z] *",l).split(l)[i])*(s.replaceAll("\\d| ","").charAt(i)==(i%2<1?83:87)?1:-1);i=n[0]+n[2];y=n[1]+n[3];out.println((i<0?-i+"N":i+"S")+l+(y<0?-y+"E":y+"W"));}}

```

### Ungolfed

```
import static java.lang.System.console;
import static java.lang.System.out;

class A {
    public static void main(String[] v) {
        String l = " ", s = console().readLine() + l + console().readLine();
        Integer i = 0, n[] = new Integer[4], y;
        for (; i < 4; i++)
            n[i] = i.parseInt(s.replaceAll("[A-Z] *", l).split(l)[i]) * (s.replaceAll("\\d| ", "").charAt(i) == (i % 2 < 1 ? 83 : 87) ? 1 : -1);
        i = n[0] + n[2];
        y = n[1] + n[3];
        out.println((i < 0 ? -i + "N" : i + "S") + l + (y < 0 ? -y + "E" : y + "W"));
    }
}

```

### Notes

* Save as `A.java`, compile with `javac A.java`, run with `java A`. Then enter the inputs line separated or as two separate inputs on stdin.

### Outputs:

```
0S 0E
0S 0W
0S 0W

0S 9999E
9999N 9999W
9999N 0W

42S 314W
42N 2718W
0S 3032W

5555N 8888W
7777S 0E
2222S 8888W

0001N        4545W
0999N        5454W
1000N 9999W

8888N 8888W
9999N 9999W
18887N 18887W

```

# Answer
> 2 votes
# Java, 308 bytes

```
import java.util.*;class x{public static void main(String[]a){Scanner r=new Scanner(System.in);int[]v=new int[2];int l,x,g,i;for(i=5;i-->1;System.out.println(i<3?""+x*g+"ENWS".charAt(i-g):"")){String s=r.next();x=Integer.parseInt(s.substring(0,l=s.length()-1));x=v[i%2]+=x*=s.charAt(l)>80?-1:1;g=x<0?-1:1;}}}

```

A more readable version:

```
import java.util.*;
class x
{
    public static void main(String[]args)
    {
        Scanner r = new Scanner(System.in);
        int[] v = new int[2];
        for (int i = 5; i-->1; )
        {
            String s = r.next();
            int l = s.length() - 1;
            int x = Integer.parseInt(s.substring(0, l));
            x = v[i%2] += x *= s.charAt(l) > 'N' ? -1 : 1;
            int g = x < 0 ? -1 : 1;
            System.out.println(i < 3?"" + x * g + "ENWS".charAt(i-g):"");
        }
    }
}

```

---

Golfing in Java is a special kind of fun. The following two lines of code do the same, but the first one is shorter:

```
(x<0?-x:x)
Math.abs(x)

```

---

The code reads 4 tokens from standard input. For each token, the part up to the last character is converted to `int`, and the last character optionally flips its sign.

Then it adds the value that was read 2 iterations ago. Java initializes arrays to 0, so at the first two iterations this will do the right thing.

Then it will format the values and print them. However, in the first two iterations, it prints the empty string instead (so two extra linebreaks appear in the output).

It uses some funky arithmetic so the iteration variable (4,3,2 or 1) and the sign (-1 or 1) can be combined to a zero-based index into the string `"ENWS"`.

# Answer
> 2 votes
# SQL (PostGreSQL 9.4), 305 bytes

```
PREPARE p(char,char)AS
SELECT string_agg(abs(n)||substr('SNNEEW',i+sign(n)::int,1),' ')FROM(SELECT i,sum(to_number(v,'9999')*CASE right(v,1)WHEN'N'THEN 1 WHEN'E'THEN 1 ELSE -1 END)n
FROM(SELECT CASE WHEN v~'[NS]' THEN 2 ELSE 5 END i,v
FROM regexp_split_to_table($1||' '||$2,' ')v)i
GROUP BY i ORDER BY i)g

```

Implemented as a prepared statement that takes 2 character parameters. One parameter for each input line.

It is called as follows

```
execute p('0S 9999E','9999N 9999W');

```

and outputs a row containing a single character column for the result. `9999N 0E`

# Answer
> 2 votes
# Perl 6, 130 bytes

```
my (\h,\v)=[Z+] lines».split(' ')».map: {m/(.*)(.)/;$1 eq'S'|'W'??-$0!!$0}
say "{abs h}{h <0??'S'!!'N'} {abs v}{v <0??'W'!!'E'}"

```

# Answer
> 2 votes
# Ruby, 186 bytes

It's too short, sorry. I did my best.

```
x=-1
puts gets.scan(/\d+\D/).map{|i|i.to_i*(i[-1]=~/[WS]/?-1:1)}.zip(gets.scan(/\d+\D/).map{|i|i.to_i*(i[-1]=~/[WS]/?-1:1)}).map{|a,b|a+b}.map{|s|s.abs.to_s+%w"NNS EEW"[x+=1][s<=>0]}*' '

```

# Answer
> 2 votes
# C - 267 bytes

I though C would be long... might as well just put it up. ;\_;

```
#include <stdio.h>
#include <stdlib.h>
int main(){int x,y,z,w;char m,n,o,p;scanf("%d%c %d%c",&x,&m,&y,&n);scanf("%d%c %d%c",&z,&o,&w,&p);int a=x*(m<'O'?1:-1)+z*(o<'O'?1:-1),b=y*(n<'F'?1:-1)+w*(p<'F'?1:-1);printf("%d%c %d%c\n",abs(a),a<0?'S':'N',abs(b),b<0?'W':'E');}

```

# Answer
> 2 votes
## Befunge-93, 240 bytes

```
v
  v$      <
>&>~:" "-!|
vp01p02   <
  v$      <
>&>~:" "-!|
vp03p04   <
  v$      <
>&>~:" "-!|
vp05p06   <
  v$      <
>&>~:" "-!|
 vp07p08  <
v>30g70g40g80g-!
_-:0` v1+
\v\g04_01-*80g
v>10g50g20g60g-!
_-:0` v1+
\v\g02_01-*60g
@>.," ",.,

```

Note that the interpreter has a single line input box. Pasting the *preferred format* replaces the newline with a space. Getting integer values with `&` already consumes leading spaces and zeros, so the *preferred format* can be read to the stack with `&~&~&~&~` alone. Adding steps to put the values in a blank line so that one can retrieve and compare the vectors one coordinate at a time, the following 136 byte program (excluding notes right of line) can be used:

```
v                      | blank line to store data
> &10p~20p&30p~40pv    | read and store first vector
 vp08~p07&p06~p05&<    | (backwards) read and store second vector
v>30g70g40g80g-!       | load E/W coordinates
_-:0` v1+              | subtract or add (based on direction)
\v\g04_01-*80g         | change directions if negative
v>10g50g20g60g-!       | load N/S coordinates
_-:0` v1+              | subtract or add (based on direction)
\v\g02_01-*60g         | change directions if negative
@>.," ",.,             | output

```

**The Catch:** The output forces an additional space after integers, so it is impossible to output in the *preferred format*. For example, output will appears as `1000 N 9999 W` instead of `1000N 9999W`. To check for and ignore spaces before each coordinate's direction on input, four additional loops (one for each coordinate) are needed. A single loop is shown below:

```
  v$      <            | throw out " " and repeat
>&>~:" "-!|            | (start read number) get and check character
vp01p02   <            | store

```

The resulting program can have multiple spaces anywhere in the input (except between digits).
*Example Input:* `0001 N 4545 W 0999 N 5454 W`

# Answer
> 1 votes
# Lua, ~~333~~ 328 bytes

Features high-level invalid input system and absolutely innovative infinite loop for repeated use.

```
m=math.abs p=print::e::c={}for i=1,2 do for s in io.read():gmatch'%S+'do c[#c+1]=s end end for i=1,4 do n=c[i]:sub(1,-2)d=c[i]:sub(-1,-1)c[i]=d==("N"or"E")and n or-n end x=c[2]+c[4]y=c[1]+c[3]a=m(x)b=m(y)if(a or b)>9999 then p'Invalid input\n'goto e end x=x<0 and a.."W"or a.."E"y=y<0 and b.."S"or b.."N"p(y.." "..x.."\n")goto e

```

Enjoy ;)

Edit: saved 5 bytes from renaming `math.abs` as `m` and `print` as `p`

# Answer
> 1 votes
# PHP, 169 bytes

Inspired by @Paul Drewett:

```
<?for($i=2;$i--;$e+=$p[1]*(substr($p[1],-1,1)<W?:-1))$n+=($p=explode(' ',trim(fgets(STDIN))))[0]*(substr($p[0],-1)<S?:-1);echo abs($n),'NS'[$n<0],' ',abs($e),'EW'[$e<0];

```

**breakdown**

```
for($i=2;$i--;                                  // loop twice
    $e+=$p[1]*(substr($p[1],-1,1)<W?:-1)        // add longitude to result
)
    $n+=
        ($p=explode(' ',trim(fgets(STDIN))))    // read line, split at blank
    [0]*(substr($p[0],-1)<S?:-1)                // add latitude to result
    ;
echo abs($n),'NS'[$n<0],' ',abs($e),'EW'[$e<0]; // print result

```

# PHP, ~~206~~ ~~197~~ 195 bytes

literally speaking, "moste verbose" would probably be Mathematica or Mathlab?

```
<?function i(){preg_match('#\d+(.) (\d+)(.)#',fgets(STDIN),$m);return[$m[0]*($m[1]<S?:-1),$m[2]*($m[3]<W?:-1)];}echo abs($v=($a=i())[0]+($b=i())[0]),'NS'[$v<0],' ',abs($v=$a[1]+$b[1]),'EW'[$v<0];

```
* output is pretty unformatted, not even a trainling newline
* prints large numbers for too large result

Now, how can I double the size of this ...

**breakdown**

```
function i()
// read a pair of coordinates from STDIN, return signed values
{
    // read line from STDIN and take (number,character,number,character) from it
    // will produce something like ["111N 222E","N","222","E"]
    preg_match('#\d+(.) (\d+)(.)#',fgets(STDIN),$m);
    return[
        // using a numerical operation on $m[0] casts the string to number (int in this case)
        $m[0]*($m[1]<S?:-1) // convert latitude to signed int: multiply with -1 for $m[1]=='S'
        ,
        $m[2]*($m[3]<W?:-1) // convert longitude to signed int
    ];
}
$a=i();$b=i();  // read coordinates from STDIN
echo            // output:
    abs($v=$a[0]+$b[0])     // 1. unsigned sum of latitudes
    ,'NS'[$v<0]             // 2. direction depending on sign
    ,' ',                   // 3. delimiter
    abs($v=$a[1]+$b[1]),    // 4. unsigned sum of longitudes
    'EW'[$v<0]              // 5. direction depending on sign
;

```

# Answer
> 1 votes
**PHP 291 Bytes.**

```
<?php $E=0;$N=0;$l=explode(PHP_EOL,STDIN);foreach($l as $i){ $x=explode(' ',$i); $s=(substr($x[0],-1,1)=='N')?1:-1; $N=$N+((substr($x[0],0,-1)*$s));$s=(substr($x[1],-1,1)=='E')?1:-1;$E=$E+((substr($x[1],0,-1))*$s);}$l=($E<=0)?'W':'E';$u=($N<=0)?'S':'N';echo'<br/>'.abs($N).$u.' '.abs($E).$l;

```

Does not do anything clever, just plods through the problem.

```
<?php
$lines = explode(PHP_EOL, STDIN);
foreach ($lines as $line) {
    $bits = explode(' ', $line);
    $sign = (substr($bits[0],-1, 1) == 'N')? 1 : -1;
    $N = $N + ( (substr($bits[0],0,-1) * $sign) );
    $sign = (substr($bits[1],-1, 1) == 'E')? 1 : -1;
    $E = $E + ( (substr($bits[1],0,-1)) * $sign );
}
$side = ($E<=0)?'W':'E';
$up = ($N<=0)?'S':'N';
echo '<br />'.abs($N).$up.' '.abs($E).$side;

```

The rules should have an additional clause saying only the language with at least 2 entries can win.

# Answer
> 1 votes
# GolfScript \- 111 bytes

```
{~)}:"S":"E";{}:"N":"W";"
"/~[{' '/[{.-1<~\-1>`~}/]\}2*]zip[{{+}*}/](.0<{abs'S'}{'N'}if' '+@~.0<{abs'E'}{'W'}if

```

### Explanation

```
{~)}:"S":"E";    # Aliases these as *-1
{}:"N":"W";      # Alieses to nop
"\n"/~           # Splits lines
[{' '/[{.-1<~\-1>`~}/]\}2*]zip    # Parses the input as vectors and applies the aliases
[{{+}*}/]                         # Vector sum
(.0<{abs'S'}{'N'}if' '+@          # Formats output
~.0<{abs'E'}{'W'}if

```

# Answer
> 0 votes
# Python 2.7 - ~~232~~ 175 bytes

Works for all of the test cases. Always inserts N or W for 0. I'm sure a better Python golfer than me could shave a good few more bytes off.

```
f=(raw_input().split(" ")+raw_input().split(" "))
for x in range(4):
 i=f[x]
 if "S" in i or "E" in i:i="-"+i
 f[x]=int(i[:-1])
n=f[0]+f[2]
q=f[1]+f[3]
print str(abs(n))+("S" if n<0 else "N"),str(abs(q))+("E" if q<0 else "W")

```

**EDIT**

Golfed off a mighty 57 bytes due to some great tips from @mbomb007 and @Titus plus by spotting the fact that I could combine the two raw\_inputs with a space then just use one .split() which splits on the space without specifying it. The algorithm is the same but just much better golfed.

```
f=(raw_input()+" "+raw_input()).split()
for x in 0,1,2,3:
 i=f[x]
 if i[-1]in"SE":i="-"+i
 f[x]=int(i[:-1])
n=f[0]+f[2]
q=f[1]+f[3]
print`abs(n)`+"NS"[n<0],`abs(q)`+"WE"[q<0]

```

---
Tags: code-challenge, arithmetic, parsing
---


title: Honest Rock, Paper, Scissors

text:
# Question
Title: Honest Rock, Paper, Scissors
Many people consider RPS to be a game of chance. If both players play unpredictably, the best strategy is to play randomly. However, let's introduce a bit of predictability to it.

Each bot will have a chance to tell the other bot what it's going to play simultaneously. Then there is a pause in which each bot will know what the other player announced. If it plays that weapon it announced it will score one point in addition to its points for a win loss or draw.

A win is worth two points, a draw, one point, and a loss 0 points.

```
     Honest Bot       Dishonest
Win     3                  2
Draw    2                  1
Loss    1                  0

```

It is in your best interest to be honest (but also to make sure your opponent does not believe you).

The matches will be played in a round robin format, and the objective will be to maximise your own total score across the matches you play.

## I/O Format:

* Your bot will be a Python 2.7 function that takes 4 arguments, and must have a unique name (which will be used to represent your submission).
* The first two arguments will always be, in order: the opponent's past moves, followed by your past moves. These will be a list in order from first to most recent round, with each index containing a list with the move the opponent claimed they would make, followed by the move they actually made.
* The next two arguments will allow your bot to determine if this is an "honest" round or a "real" round. If it is an "honest" round, they will both be None. If it is a "real" round, they will be, in order, the move your opponent declared they would make, followed by the move you declared you would make.
* All arguments or portions of arguments that represent moves will use "R", "P", and "S" to represent rock, paper, and scissors, respectively.
* Your function should return either an "R" for rock, a "P" for paper, or an "S" for scissors. Bots that have the ability to return other values will be disqualified.
* Each bot will be run against every other bot 200 times, and itself 100 times. The goal is to be the bot with the most points at the end of the competition.
* In regards to discussion in the comments, submissions may not read from or write to any file, or in any way sabotage or read opponent's code.

## Examples:

These are four example bots I put together quickly. They will be joining the competition as additional bots. If you lose to the last one, you have some work to do.

```
def honestpaper(I,dont,care,about_these):
    return "P"

def honestrock(I,dont,care,about_these):
    return "R"

def honestscissors(I,dont,care,about_these):
    return "S"

import random
def randombot(I,dont,care,about_these):
    return random.choice(["R","P","S"])

```

## Controller:

And here's the controller I'll be using. New submissions will be imported at the beginning and added to the bot\_map dictionary.

```
from honestrock import honestrock
from honestpaper import honestpaper
from honestscissors import honestscissors
from randombot import randombot

bot_map = {
  0:honestrock, 1:honestpaper, 2:honestscissors, 3:randombot
}

player_num=len(bot_map)

def real(history1,history2,number,honest1,honest2):
    return bot_map[number](history1,history2,honest1,honest2)

def honest(history1,history2,number):
    return bot_map[number](history1,history2,None,None)

def play_match(num1,num2):
    history1=[]
    history2=[]
    score1=0
    score2=0
    for x in range(250):
        h1=honest(history2,history1,num1)
        h2=honest(history1,history2,num2)
        r1=real(history2,history1,num1,h2,h1)
        r2=real(history1,history2,num2,h1,h2)

        if h1==r1: score1+=1
        if h2==r2: score2+=1

        if r1==r2: score1+=1; score2+=1
        elif r1=="R":
            if r2=="P": score2+=2
            else: score1+=2
        elif r1=="P":
            if r2=="S": score2+=2
            else: score1+=2
        else:
            if r2=="R": score2+=2
            else: score1+=2

        history1.append([h1,r1])
        history2.append([h2,r2])
    return score1,score2

scores = []
for x in range(player_num):
    scores.append(0)

for _ in range(100):

    for x in range(player_num):
        for y in range(player_num):
            scorex,scorey=play_match(x,y)
            scores[x]+=scorex
            scores[y]+=scorey

for score in scores:
    print score

```

## Final Scores:

```
csbot                    3430397
thompson                 3410414
rlbot                    3340373
have_we_been_here_before 3270133
mason                    3227817
deepthought              3019363
adaptive_bot             2957506
THEbot                   2810535
dontlietome              2752984
irememberhowyoulie       2683508
learningbot4             2678388
betrayal                 2635901
averager                 2593368
honestrandom             2580764
twothirds                2568620
mirrorbot                2539016
tit4tat                  2537981
honestscissors           2486401
trusting_bot             2466662
rotate_scissors          2456069
rotate_paper             2455038
rotate_rock              2454999
honestpaper              2412600
honestrock               2361196
rockBot                  2283604
trustingRandom           2266456
user5957401bot           2250887
randombot                2065943
Dx                       1622238
liarliar                 1532558
everybodylies            1452785

```

# Answer
## Mason

Tries to pick up information about other bots such as how honest they are and how they're effected by my first move. I then try and find other obvious bots that follow a pattern and exploit those into giving me more points. Finally, the Mason has a secret weapon: knowledge of a secret society where both bots participating mutually go for a full draw, gaining 500 points each. Unfortunately the secret is rather... Well secret and changes every time the Mason does.

```
def mason(op_hist, my_hist, op_move, my_move):
    win_map = {"R": "P", "P": "S", "S": "R"}
    lose_map = {"R": "S", "P": "R", "S": "P"}
    if not len(op_hist):
        return "S"
    if op_hist[0] == ['S', 'S']:
        code = "S" + "".join("RPS"[ord(i) % 3] if isinstance(i, str) else "RPS"[i % 3] for i in __import__("sys")._getframe().f_code.co_code)[1::2]
        honest, guess = zip(*op_hist)
        if honest == guess == tuple(code[:len(op_hist)]):
            return code[len(op_hist)]
    op_honesty = sum(len(set(round))-1 for round in op_hist) / float(len(op_hist))
    if not my_move:
        moves = "".join(i[1] for i in op_hist)
        # Identify rotators
        if "PSRPSR" in moves:
            return moves[-2]
        # Identify consecutive moves
        if "RRRRR" in moves[:-10] or "SSSSS" in moves[:-10] or "PPPPP" in moves[:-10]:
            return win_map[moves[-1]]
        # Try just what wins against whatever they choose most
        return win_map[max("RPS", key=moves.count)]
    op_beats_my_honest = sum(win_map[me[0]] == op[1] for op, me in zip(op_hist, my_hist)) / float(len(op_hist))
    op_draws_my_honest = sum(me[0] == op[1] for op, me in zip(op_hist, my_hist)) / float(len(op_hist))
    op_loses_my_honest = sum(lose_map[me[0]] == op[1] for op, me in zip(op_hist, my_hist)) / float(len(op_hist))
    if op_honesty <= 0.4:
        return win_map[op_move]
    max_prob = max((op_loses_my_honest, op_draws_my_honest, op_beats_my_honest))
    if max_prob >= 0.6:
        if op_beats_my_honest == max_prob:
            return lose_map[my_move]
        if op_draws_my_honest == max_prob:
            return win_map[my_move]
        if op_loses_my_honest == max_prob:
            return my_move
        assert False
    return my_move

```
> 13 votes

# Answer
# Rlbot: reinforcement learning

Uses a reinforcement learning approach, tackling this game in a way similar to the n-armed bandit problem. It does so in two ways: tries to learn which declaration is better against each opponent and sticks to that one (useful against constant bots), and tries to learn the outcome of various moves in previous similar situations (similar in regard to the relative plays, e.g. rock vs paper is similar to a previous paper vs scissor). The initial assumptions are optimistic, so this player will assume that being honest will give it 3 points and lying will give 2, and will therefore always be honest until proven otherwise.

*Update:* The first tournament results highlighted a problem with this bot, which was its inability to detect patterns in its opponents' declarations (which made it play suboptimally against rotators). I've then added a pattern-matching component to the code for the honest rounds, which uses a regex to look for the longest suffix in the history of opponent declarations that is present somewhere previously in that history, and what move was played after that. We assume that the opponent will play the same move again, and use reinforcement learning as before to decide what the best answer to that should be.

```
import re
def rlbot(hismoves,mymoves,hismove,mymove):
 def score(d,m1,m2):
  s=0
  if m1==m2:
   s=1
  elif (m1+m2) in "RPSR":
   s=2
  return s+(d==m2)

 alpha=0.2
 if mymove:
  history=[([d1,m1],[d2,m2]) for ((d1,m1),(d2,m2)) in zip(hismoves,mymoves) if score(None,hismove,mymove)==score(None,d1,d2)]
  bestscore=-1
  bestmove=""
  for move in "RPS":
   ev=2+(move==mymove)
   for ((d1,m1),(d2,m2)) in history:
    if score(None,move,mymove)==score(None,m2,d2):
     ev=(1-alpha)*ev+alpha*score(d2,m1,m2)
   if ev>bestscore:
    bestscore=ev
    bestmove=move
  return bestmove

 else:
  if len(hismoves)==0:
   return "R"
  bestscore=-1
  bestmove=""
  hisdeclarations="".join(d for [d,m] in hismoves)
  predicted_move=re.search(r'(.*)\n.*\1(.)',hisdeclarations+'\n'+hisdeclarations).group(2)
  history=[([d1,m1],[d2,m2]) for ((d1,m1),(d2,m2)) in zip(hismoves,mymoves) if d1==predicted_move]
  for move in "RPS":
   ev=3
   for (his,my) in history:
    (d1,m1)=his
    (d2,m2)=my
    if d2==move:
     ev=(1-alpha)*ev+alpha*score(d2,m1,m2)
   if ev>bestscore:
    bestscore=ev
    bestmove=move
  return bestmove

```

Try it online!
> 9 votes

# Answer
I've never really used python much so I'm sure I've made a mistake somewhere.

```
import random
def learningbot3(opponentlist,a,opponent,me):
 #tell the other bot a random thing
 if opponent==None:
  return random.choice(["R","P","S"])
 #check whether the other bot has mostly told the truth in the last 10 rounds
 truth=0
 for game in opponentlist[-10:]:
  truth-=1
  if game[0]==game[1]:
   truth+=2
 #assume the other bot will tell the truth
 if truth>=3:
  if me==opponent:
    return me
  elif opponent=="R":
   return "P"
  elif opponent=="P":
   return "S"
  elif opponent=="S":
   return "R"
 #assume the other bot is lying
 elif truth<=-3:
  return random.choice([me,opponent])
  #return opponent
 #pick whatever we said we would
 else:
  return me

```

It should check the last 10 rounds to see how often the opponent lied, then chose a different response depending on that.
> 6 votes

# Answer
Here is my adaptive bot. It analyses the last 2 moves of the opponent to determine if it is an honest bot or not and plays accordingly:

Edit 1: If the other bot is a constant bot (ie. always plays the same weapon) this bot crushes it by playing the winning weapon and being honest at the same time.

Edit 2: Improved constant bot detector to work with rotator bots too.

```
import random
def adaptive_bot(other_past, my_past, other_next, my_next):
    winners = {"R": "P", "P": "S", "S": "R"}
    if my_next is None:
        return winners[other_past[-6:][0][1]] if other_past else random.choice(list(winners.keys()))
    else:
        is_other_honest = all([other_claim == other_move for other_claim, other_move in other_past[-2:]])
        return winners[other_next] if is_other_honest else my_next

```
> 6 votes

# Answer
# csbot

```
def csbot(ophist,myhist,opdecl,mydecl):

  import random

  RPS = "RPS"

  def value(opd,myd,opmove,mymove):
    if opmove==mymove:
      val = 9
    elif opmove+mymove in RPS+RPS:
      val = 20
    else:
      val = -2
    return val+10*(myd==mymove)-(opd==opmove)

  def best(od,md):
    l = float(len(ophist))
    weights = dict([ (m, random.random()/8) for m in RPS ])
    for n in range(len(ophist)):
      if ophist[n][0]==od and myhist[n][0]==md:
        weights[ophist[n][1]] += 1+4*((n+1)/l)**2
    sw = sum([ weights[m] for m in RPS ])
    bestexpect = 0
    for m in RPS:
      expect = sum([ weights[om]/sw*value(od,md,om,m) for om in RPS ])
      if expect > bestexpect:
        bestexpect = expect
        bestmove = m
    return bestmove, bestexpect

  honest = all ([ decl==mv for decl, mv in ophist ])

  if honest:
    if mydecl<>None:
      return mydecl
    expnxt = set();
    for i in range(len(ophist)-1):
      if ophist[i][0]==ophist[-1][0]:
        expnxt.add(ophist[i+1][0])
    if len(expnxt)==1:
      return RPS[ (RPS.index(expnxt.pop())+1) % 3 ]

  if mydecl==None:
    l = float(len(ophist))
    weights = dict([ (m, random.random()) for m in RPS ])
    for n in range(len(ophist)):
      weights[ophist[n][0]] += 1+((n+1)/l)**2
    sw = sum([ weights[m] for m in RPS ])
    bestexpect = 0
    worstexpect = 99
    for m in RPS:
      expect = sum([ best(od,m)[1]/sw*weights[od] for od in RPS ])
      if expect > bestexpect:
        bestexpect = expect
        bestmove = m
      if expect < worstexpect:
        worstexpect = expect
    if bestexpect-worstexpect < 3:
      bestmove = random.choice(RPS)
    return bestmove

  return best(opdecl,mydecl)[0]

```

Be honest as long as the other player is, and detect simple deterministic bots. Play the move that maximizes the expected value, where we mostly go for our points, but also like to not give points to the other player. But own points are better by a factor of ten, hence the unusual numbers in the `value` function. Opponent moves are expected according to how often we have seen them before in this situation (declared moves), but recently seen moves are weighted more than moves seen earlier. For random initial moves (situations never seen before) and some extra fuzzyness, the weights include small extra random numbers.

**Update:** Use expected results also in the honest round. To be able to do this, normalize and take the additional point the opponent may get for honesty into account - it couldn't influence our decission in the real round but is needed now. I considered doing this from the beginning, but wrongfully thought it wouldn't be worthwhile. I saw that it would be possible to give `trusting_bot` less points (but that bot isn't a strong opponent anyway), but missed that extra points could be gained from `rockbot` by good play in the honest round even though its play in this round is random.
> 6 votes

# Answer
# Betrayal

```
def betrayal(yours, mine, you ,me):
    import random
    if you is None:
        pick = random.choice(['R','P','S'])
    else:
        you = you[0]
        me = me[0]
        if len(yours) < 50: #Build myself a reputation of honesty
            pick = me
        else:
            if len(yours) >= 50 and len(yours) < 100:
                honesty = sum([1 if y[0]==y[1] else 0 for y in yours])/float(len(yours))
                if honesty <= 0.5: #If dishonest try to outwit
                    pick = 'S' if me=='R' else 'R' if me == 'P' else 'P'
                else: #Else just plain cheat
                    pick = 'P' if you=='R' else 'R' if you=='S' else 'S'
            elif len(yours) >= 100: #When dishonest moves outweight honest moves, change tactics...
                honesty = sum([1 if y[0]==y[1] else 0 for y in yours[50:]])/float(len(yours[50:]))
                if honesty <= 0.5: #... and just play according to most likely pick
                    what_did_you_do = [k[1] for k in yours if k[1]!=k[0]]
                    index = [i for i,k in enumerate(yours) if k[1]!=k[0]]
                    what_i_said_i_ll_do = [k[0] for i,k in enumerate(mine) if i in index]
                    matches = zip(what_i_said_i_ll_do, what_did_you_do)
                    what_you_might_answer = [k[1] for k in matches if k[0]==me]
                    table = [len([k for k in what_you_might_answer if k=='R']),len([k for k in what_you_might_answer if k=='P']),len([k for k in what_you_might_answer if k=='S'])]
                    maybe_your_pick = ['R','P','S'][table.index(max(table))]
                    pick = 'P' if maybe_your_pick=='R' else 'R' if maybe_your_pick=='S' else 'S'
                else:
                    pick = 'P' if you=='R' else 'R' if you=='S' else 'S'
    return pick

```

The idea is that for the first 50 moves I play honestly, and then once I have lured the opponent into thinking i am honest, play dishonestly, trying to play what would counter what the opponent will play (based on whether he was honest or dishonest in the past). When I reach the point at which i played as often honestly than dishonestly I change tactics and pick the most likely move of the opponent based on previous known configurations.
> 4 votes

# Answer
```
import random
def honestrandom(a, b, c, move):
    if move == None:
        return random.choice(["R","P","S"])
    return move

```
> 3 votes

# Answer
## Two Thirds

Uses the strategy Peter Taylor mentioned in the Sandbox and in this comment.

It uses the Nash equilibrium.

```
import random

def two_thirds(h_opp, h_me, opp, me):

    def result(opp, me):
        if opp==me: return 0
        if opp=="R" and me=="S" or opp=="S" and me=="P" or opp=="P" and me=="R": return -1
        return 1

    moves = {"R", "P", "S"}
    honest = (opp == None)
    if honest:
        return random.choice(list(moves))
    else:
        res = result(opp, me)
        if res==-1:
            counter = list(moves - {opp, me})[0]
            return random.choice([me,counter,counter])
        if res==1:
            return random.choice([me,me,opp])
        return me

```
> 3 votes

# Answer
# Bot Name: I Remember How You Lie

```
import random

#Bot Name: I Remember How You Lie
def irememberhowyoulie(opponentlist, mylist, opponentmove, mymove):
    random.seed()

    wintable = {
                "R": {"R": 1, "P": 0, "S": 2},
                "P": {"R": 2, "P": 1, "S": 0},
                "S": {"R": 0, "P": 2, "S": 1}
               }

    winprob = {
               "R": {"R": 0.0, "P": 0.0, "S": 0.0},
               "P": {"R": 0.0, "P": 0.0, "S": 0.0},
               "S": {"R": 0.0, "P": 0.0, "S": 0.0}
              }

    totalprob = {"R": 0, "P": 0, "S": 0}

    # Calculate the probability that the opponent will lie base on the probability that it lied in the last 15 ~ 25 rounds
    # And calculate the probability that what the bot will show next
    picklength = min(random.randint(15, 25), len(opponentlist))
    lying, tempsum = 0, 0.0
    pickedup = {"R": 0, "P": 0, "S": 0}
    if picklength == 0:
        lying = 0.5
    else:
        for eachround in opponentlist[-picklength:]:
            pickedup[eachround[1]] += 1
            if eachround[0] != eachround[1]:
                lying += 1
        lying = lying * 1.0 / picklength
    for s in pickedup:
        pickedup[s] = 1.0 / (1 + pickedup[s])
        tempsum += pickedup[s]

    #Honest Round
    if opponentmove is None and mymove is None:
        a = random.random() * tempsum
        if a < pickedup["R"]:
            return "R"
        elif a < pickedup["R"] + pickedup["P"]:
            return "P"
        else:
            return "S"

    #Real Round
    else:
        for me in winprob:
            ishonest = 0
            if me == mymove:
                ishonest = 1
            for op in winprob[me]:
                if op == opponentmove:
                    winprob[me][op] = (wintable[me][op] + ishonest) * (1 - lying)
                else:
                    winprob[me][op] = (wintable[me][op] + ishonest) * lying * pickedup[op] / (tempsum - pickedup[opponentmove])
                totalprob[me] += winprob[me][op]

        optimalmove, optimalvalue = "R", -9999999.0
        for me in totalprob:
            if totalprob[me] > optimalvalue:
                optimalmove, optimalvalue = me, totalprob[me]
        return optimalmove

```

Tested for several 100-round runs, and turned out that the winner scores about 220 in average. Rather honest I think;)

First time for me to participate in KOTH challenges, so I think there is still room for improvement
> 3 votes

# Answer
## Tit for Tat

The classic Axelrodian contestant: hopeful, yet petty; simple, yet robust. This isn't Prisoner's Dilemma and I made no attempt to predict the opponent's move, so I highly doubt it'll be truly competitive. But "cooperating" still produces the most overall points for contestants, so I think it'll at least do middlingly.

```
import random
def tit4tat(opphist, myhist, oppfut, myfut):
    if (not myfut): return random.choice(['R','P','S'])
    if (not opphist) or opphist[-1][0]==opphist[-1][1]: return myfut
    return random.choice(['R','P','S'])

```
> 3 votes

# Answer
# DeepThought

```
def check_not_loose_bot(opHist, myHist):
    not_loose_points = 0
    for i in range(0, len(opHist)):
        if opHist[i][1] == opHist[i][0] or myHist[i][0] == win_map[opHist[i][0]] and opHist[i][1] == win_map[myHist[i][0]]:
            not_loose_points += 1
    not_loose_percent = float(not_loose_points) / len(opHist)
    if not_loose_percent > 0.9:
    #    print("is not willing to loose")
        return True
    return False

def check_trick_bot(opHist, myHist):
    trick_points = 0
    for i in range(0, len(opHist)):
        if opHist[i][1] == win_map[myHist[i][0]]:
            trick_points += 1
    trick_percent = float(trick_points) / len(opHist)
    if trick_percent > 0.9:
  #      print("is tricking me")
        return True
    return False

def check_honest_bot(opHist):
  #  print("check honest")
    honest_points = 0
    for i in range(0, len(opHist)):
        if opHist[i][0] == opHist[i][1] :
            honest_points += 1
    honest_percent = float(honest_points) / len(opHist)
    if honest_percent > 0.9:
    #    print("is honest")
        return True
    return False

def check_self_match(opHist, myHist):
    for i in range(0, len(myHist)):
        if opHist[i][0] != myHist[i][0]:
            # im not playing against myself, because the other one was claiming a different value than i did
#            print("differ: "+str(opHist)+", "+str(myHist))
            return False
        if opHist[i][1] != opHist[i][0]:
#            print("lie")
            # im not playing against myself, because the other bot wasn't honest (and i'm always honest as long as i think i play against myself)
            return False
    return True

def check_equal(move1, move2, fullCheck): # WARNING: FOR COMPABILITY THIS IS RETURNING NEQ INSTEAD OF EQ
    if fullCheck:
        return move1 != move2
    else:
        return move1[0] != move2[0] #only check claims

def is_pattern(opHist, pattern_start, prob_pattern_start, pattern_length, full_check):
    for i in range(0, pattern_length-1):
        if check_equal(opHist[pattern_start + i] , opHist[prob_pattern_start + i], full_check):
            return False
    return True

win_map = {"R": "P", "P": "S", "S": "R"}
def deterministic_best_guess(opHist, full_check = True):
    size = 0
    random_result = random.choice(["R", "P", "S"])
    for pattern_length in range(2, (len(opHist)+1)/2): #a pattern has to occur at least twice
        for pattern_start in range(0, len(opHist) - 2 * pattern_length):
            if not is_pattern(opHist, pattern_start, len(opHist) - pattern_length + 1, pattern_length, full_check):
                 continue
            is_repeated = False
            is_fooled = False
            for repeated_pattern_start in range(pattern_start + pattern_length, len(opHist) - pattern_length):
                if not is_pattern(opHist, pattern_start, repeated_pattern_start, pattern_length, full_check):
                     continue
                is_repeated = True
                if check_equal(opHist[pattern_start + pattern_length - 1], opHist[repeated_pattern_start + pattern_length - 1], full_check):
                    is_fooled = True
                    break
    #            print("pattern found: " + str(opHist[pattern_start : pattern_start + pattern_length]) +" at "+str(pattern_start)+" and "+str(repeated_pattern_start))
   #             print("check: "+str(opHist))
            if is_fooled or not is_repeated:
                break
            #we have found a deterministic best guess
  #          print("most likely next step: "+ str(opHist[pattern_start + pattern_length - 1]))
            if full_check:
                return win_map[opHist[pattern_start + pattern_length - 1][1]], True
            return win_map[opHist[pattern_start + pattern_length - 1][0]], True # if we don't have a full check, the pattern only applies to claims. So pretend to win against the claimed result.

    #fallback
 #   print("fallback")
    return random_result, False

def DeepThought(opHist, myHist, opMove, myMove):
    if opMove == None:
    #claiming phase
        if len(myHist) == 0:
        #seed random to be able to be deterministic when chosing randomly
            #The seed is secret (kind of)
            random.seed(133427)
        else:
            #seed random according to my previous claims
            seed = 133427
            for i in range(0, len(myHist)):
                if myHist[i][0] == "R":
                    seed = seed*3+1
                elif myHist[i][0] == "S":
                    seed = seed*7+1
                elif myHist[i][0] == "P":
                    seed = seed*11+1
                while seed%2 == 0:
                    seed /= 2
            random.seed(seed)
        if check_self_match(opHist, myHist):
            #claim a random value, will happen in the first round or in a self-match
            result = random.choice(["R", "P", "S"])
            return result
      #  print("differ detected")
        if check_trick_bot(opHist, myHist) and len(myHist) > 10:
            # i play against a trick bot. I can reduce its points by trieing to guess its claim, and force him to lie
            result, sure = deterministic_best_guess(opHist, False)
        else:
            result, sure = deterministic_best_guess(opHist)
        random.seed(0)
        return result
    if check_self_match(opHist, myHist):
        #i play against myself, i can only hope for a honest draw, so do that
        return myMove
#    print("no self-math")
    #dbg needs a valid seed, so provide it
    random.seed(133427)
    result, sure = deterministic_best_guess(opHist)
    if sure:
        #i'm sure i play against a deterministic bot. I'll be honestly winning. YEY.
        return myMove
    if check_honest_bot(opHist) and len(opHist) > 10:
        #i play against an honest bot. I'll accept a draw, but i will not accept a loss
        if win_map[myMove] == opMove:
            return win_map[opMove]
        return myMove
    if check_trick_bot(opHist, myHist) and len(opHist) > 10:
        #i play against a tricking bot. He'll make me either loose honestly (1 Pnt) or i have to be dishonest (2 Pnt). So let's lie.
        return win_map[win_map[myMove]]
    if check_not_loose_bot(opHist, myHist) and len(opHist) > 10:
        #i play against a bot thats not willing to loose. If it looks like i won, i can loose honestly (1Pnt, 2Pnt for him),
        #or i have to be dishonest (2 Pnt, 0 Pnt for him). So let's lie in that case.
        #If it looks like its a draw, i'll be honest (conservative way), and get my 2 : 2 Pnt.
        #If it lokks like i'll loose, I'll not accept it. I'll lie to win for 2 : 1 Pnt.
        if myMove == opMove:
            return myMove
        if myMove == win_map[opMove]:
            # He'll lie. So lie together and keep smiling.
            return opMove
        # I'll loose. NO!!!! Not gonna happen
        return win_map[opMove]
    return myMove

```

Just a few notes on it:

* DeepThought likes to think. A lot. I'm sorry about it, but i don't really know how to fix it. I blame Python.
* DeepThought tries to be honest. Beeing honest does provide you one aditional point, which is the same as the expected value for normale RPS
* But: DeepThought gets in averange even more than 2 Points per Game. He uses some detection to find some common behaviours (like tricking, beeing honest, etc.), and adapts according to that.
* DeepThought is purely deterministic, so it'll draw against itself, because it'll always do the same decition on both ends.
* To be sure not to lie against itself, it has a special detection, like some other bots here, too. This is a very aggressive one, even assuming to be true after one round (and in the first round, too). Basically, as long as the opponent moves are exactly mine, i'll assume its a mirror match.
* The interesting part (and the part that has dozens of false-positives) is the check for a deterministic bot, that is only dependend on its own prevoius result. That check search for any pattern of size n, that is repeated twice, and that could be describing the last n-1 moves, predicting the opponent's claim and move in advance. This part is taking some time, sadly.

I'm new to both, koth and Python, so tell me if I messed anything up in this bot. I don't think it can beat reinforced learning (because I guess it'll learn my moves too quickly), but let's give it a try.

I like this challenge, and if I find some time, I'd like to add an organic computing approch (althogh there might be too less pressure on the higher dimensions). Is it allowed to add multiple suggestions? Or is it forbidden to prevent boosing your main bot by inserting some that only aim for loosing to your primary?

EDIT: Fixed code-typo that caracterized me as non-native english speaker
> 3 votes

# Answer
```
import random
def user5957401bot(a,b,c,d):
    if d == None:
       return random.choice(["R","P","S"])
    else:
       return random.choice(["R","P","S",d])

```
> 2 votes

# Answer
## THEbot: THE Honest Exploiter

```
import random
def thebot(ho,hm,om,mm):
    hands = {"R": "P", "P": "S", "S": "R"}
    if om == None:
        if (len(set([i[0] for i in ho])) < 3) and (len(ho) > 2):
            return hands[random.choice(list(set([i[0] for i in ho])))]
        else:
            return random.choice(["R","P","S"])
    else:
        if sum(1 for i in ho if i[0]==i[1]) > (len(ho)/3):
            if om == mm:
                return om
            else:
                return hands[om]
        else:
            return mm

```
> 2 votes

# Answer
# have\_we\_been\_here\_before

Simply asks "have we been here before", and chooses the move which would have given the best average outcome in any such previous games.

**Edit: Honesty Club.** I've added a small block of code because another bot (mason) has done extremely well by forming a secret club with itself. Notice however, that playing honestly against honest opponents has on average exactly the same payoff when playing against oneself, and perhaps there are broader mutual benefits to be had too?

**Edit2:** At the time of writing the two bots ahead of me both exploit rotators, so I'm going to add another block of code in order to jump on that bandwagon too. I guess my code must seem quite old school - sticking to familiar constructs found in any programming language because I really don't know Python.

```
import random

def have_we_been_here_before(opponentList, myList, opponent, me):

    def win(x):
        if x=="R": return "P"
        elif x=="P": return "S"
        elif x=="S": return "R"

    def calc_score(r1, r2):
        if r1==r2: return 1
        elif r1==win(r2): return 2
        else: return 0

    def have_we(opponentList, myList, opponent, me, me2):
        score, count = 0, 0
        for n in range(len(opponentList)):
            if (opponent == opponentList[n][0] and me == myList[n][0]):
                score += calc_score(me2, opponentList[n][1])
                count += 1
        if count == 0: return 0
        else: return float(score) / float(count)

    if opponent == None:

        # exploit rotators
        if len(opponentList) >= 3:
            rotator = True

            for n in range(3, len(opponentList)):
                if opponentList[n][1] != opponentList[n % 3][1]:
                    rotator = False
                    break

            if rotator: return win(opponentList[len(opponentList) % 3][1])

        if len(opponentList) == 0:
            return random.choice(["R", "P", "S"])
        else:
            # crude attempt to exploit the house bots
            prev = random.choice(opponentList)[1]
            return win(prev)

    # Play honestly if opponent has played honestly so far
    honest = True
    for oppMove in opponentList:
        if (oppMove[0] != oppMove[1]):
            honest = False
            break

    if honest: return me
    # Done playing honestly

    # Have we been here before?
    rock = have_we(opponentList, myList, opponent, me, "R")
    paper = have_we(opponentList, myList, opponent, me, "P")
    sissors = have_we(opponentList, myList, opponent, me, "S")

    if rock > paper and rock > sissors: return "R"
    elif paper > rock and paper > sissors: return "P"
    elif sissors > paper and sissors > rock: return "S"
    else: return win(opponent)

```
> 2 votes

# Answer
**Thompson**

```
import math
import random

moves = list(range(3))
names = "RPS"
from_name = dict(zip(names, moves))
to_name = dict(zip(moves, names))

#Payoff matrices given each relationship between honest moves.
A = [
    [[2, 1, 3], [2, 1, 0], [0, 2, 1]],
    [[1, 3, 2], [1, 0, 2], [2, 1, 0]],
    [[3, 2, 1], [0, 2, 1], [1, 0, 2]]
]

#Add a 1.2% penalty for the opponent's score (idea shamelessly stolen from csbot).
for d_h in range(3):
    for i in range(3):
        for j in range(3):
            A[d_h][i][j] -= 0.012 * A[[0, 2, 1][d_h]][j][i]

third = 1. / 3
two_thirds = 2 * third

nash_prior = [
    [[1, 0, 0], [two_thirds, 0, third], [third, 0, two_thirds]],
    [[third, 0, two_thirds], [1, 0, 0], [two_thirds, 0, third]],
    [[two_thirds, 0, third], [third, 0, two_thirds], [1, 0, 0]]
]

def mult_m_v(M, v):
    w = [0 for _ in v]
    for i, M_i in enumerate(M):
        for M_ij, v_j in zip(M_i, v):
            w[i] += M_ij * v_j
    return w

def mean_belief(counts):
    c = 1. / sum(counts)
    return [n * c for n in counts]

def sample_belief(counts):
    return mean_belief([random.gammavariate(n, 1) for n in counts])

def thompson(h_opp, h_me, opp, me):

    #Prior rationality of opponent.
    a = 0.95

    #Confidence in priors.
    n0_h = 0.5
    n0_m = 0.5

    def v(x):
        return [x for _ in range(3)]

    h_p = [v(n0_h * third) for _ in range(3)]

    m_p0 = [v(None) for _ in range(3)]
    m_p1 = [v(None) for _ in range(3)]

    #Expected prior is a mixture between nash equilibrium and uniform distribution.
    for h_i in range(3):
        for h_j in range(3):
            m_p0[h_i][h_j] = [n0_m * (a * nash + (1 - a) * third) for nash in nash_prior[h_i][h_j]]

    for d_j_prev in range(3):
        for d_ij in range(3):
            m_p1[d_j_prev][d_ij] = list(m_p0[0][d_ij])

    #Track whether it's better to model the real moves based on the exact honest moves or
    #just the relationship between honest moves together with the opponent's defection strategy in the previous round.
    log_mp0 = 0
    log_mp1 = 0

    #Identify myself and always cooperate.
    is_me = True

    for (t, ((h_i, m_i), (h_j, m_j))) in enumerate(zip(h_me, h_opp)):

        h_i, m_i, h_j, m_j = from_name[h_i], from_name[m_i], from_name[h_j], from_name[m_j]

        d_j = (m_j - h_j) % 3
        d_ij = (h_j - h_i) % 3

        if t:
            h_j_prev = from_name[h_opp[t - 1][0]]
            m_j_prev = from_name[h_opp[t - 1][1]]
            h_p[h_j_prev][h_j] += 1

            d_j_prev = (m_j_prev - h_j_prev) % 3

            log_mp0 += math.log(m_p0[h_i][h_j][d_j] / sum(m_p0[h_i][h_j]))
            log_mp1 += math.log(m_p1[d_j_prev][d_ij][d_j] / sum(m_p1[d_j_prev][d_ij]))

            m_p1[d_j_prev][d_ij][d_j] += 1

        m_p0[h_i][h_j][d_j] += 1

        if is_me and ((h_i != h_j) or (h_j != m_j)):
            is_me = False

    if is_me:
        random.seed(len(h_me) + 1337)
        me_next = random.randrange(3)

    log_ps = [log_mp0, log_mp1]
    log_p_max = max(log_ps)
    ps = [math.exp(log_p - log_p_max) for log_p in log_ps]
    p0 = ps[0] / sum(ps)

    #We have to blend between the predictions of our 2 models for the real rounds.

    def sample_expectation(h_i, h_j, d_j_prev=None):
        d_ij = (h_j - h_i) % 3
        if d_j_prev is None or random.random() < p0:
            p = m_p0[h_i][h_j]
        else:
            p = m_p1[d_j_prev][d_ij]
        return mult_m_v(A[d_ij], sample_belief(p))

    def take_expectation(h_i, h_j, d_j_prev=None):
        d_ij = (h_j - h_i) % 3
        e0 = mult_m_v(A[d_ij], mean_belief(m_p0[h_i][h_j]))
        if d_j_prev is None:
            return e0
        e1 = mult_m_v(A[d_ij], mean_belief(m_p1[d_j_prev][d_ij]))
        return [p0 * e0i + (1 - p0) * e1i for e0i, e1i in zip(e0, e1)]

    #We use thompson sampling, selecting the optimal deterministic strategy
    #with respect to a random opponent sampled from the posterior.

    #Actually, we use optimistic thompson sampling which clips samples to have >= than the mean expected value.

    if opp == None:
        #For the honest round we perform a lookahead to the real round to choose our strategy.
        if h_opp:
            if is_me:
                return to_name[me_next]
            h_j_prev = from_name[h_opp[-1][0]]
            m_j_prev = from_name[h_opp[-1][1]]
            d_j_prev = (m_j_prev - h_j_prev) % 3
            h_p_s = sample_belief(h_p[h_j_prev])
            h_p_u = mean_belief(h_p[h_j_prev])
            s_i = [0] * 3
            s_i_u = [0] * 3
            for h_i in range(3):
                for h_j in range(3):
                    s_i[h_i] += h_p_s[h_j] * max(sample_expectation(h_i, h_j, d_j_prev))
                    s_i_u[h_i] += h_p_u[h_j] * max(take_expectation(h_i, h_j, d_j_prev))
                s_i[h_i] = max(s_i[h_i], s_i_u[h_i])
            return to_name[s_i.index(max(s_i))]
        else:
            return to_name[me_next]
    else:
        if h_opp:
            if is_me:
                return me
            h_j_prev = from_name[h_opp[-1][0]]
            m_j_prev = from_name[h_opp[-1][1]]
            d_j_prev = (m_j_prev - h_j_prev) % 3
        else:
            if opp == me:
                return me
            d_j_prev = None
        h_i, h_j = from_name[me], from_name[opp]
        s_i = [max(s0, s1) for s0, s1 in zip(sample_expectation(h_i, h_j, d_j_prev), take_expectation(h_i, h_j, d_j_prev))]
        return to_name[(h_i + s_i.index(max(s_i))) % 3]

```
> 2 votes

# Answer
# mirrorbot

```
import random

def mirrorbot(op_hist, my_hist, op_move, my_move):
    if my_move == None :
        return random.choice(["R","P","S"])
    else :
        for x in range(len(op_hist)):
            if ((op_hist[len(op_hist) -x-1][0] == my_move) and (my_hist[len(op_hist) -x-1][0] == op_move)):
                return op_hist[len(op_hist) -x-1][1]
        return my_move

```

I will try a simple bot that redo the last play of its opponent in these conditions
> 2 votes

# Answer
```
def rotate_rock(h1, h2, is_, honest):
 return ("R", "P", "S")[len(h1) % 3]

```

```
def rotate_paper(h1, h2, is_, honest):
 return ("P", "S", "R")[len(h1) % 3]

```

```
def rotate_scissors(h1, h2, is_, honest):
 return ("S", "R", "P")[len(h1) % 3]

```

The idea here is to maximize the score while playing self while still being randomly competitive during other stages against other bad bots.
> 1 votes

# Answer
# Bot name: Liar Liar

Can't stop lying.

```
import random

def liarliar (herHistory, myHistory, herMove, myMove):
    options = ["R", "P", "S"]
    if myMove == None:
        return random.choice(options)
    else:
        options.remove(myMove);
        return random.choice(options)

```
> 1 votes

# Answer
**RockBot**

Assumes the opponent will be honest and tries to beat them, but refuses to play rock.

```
import random
def rockBot(oppHist,myHist,oppMove,myMove):
    if oppMove == None:
        return random.choice(["R","P","S"])
    else:
        if(oppMove == "R"):
            return "P"
        elif(oppMove == "P"):
            return "S"
        elif(myMove != "R"):
            return myMove
        else:
            return random.choice(["P","S"])

```
> 1 votes

# Answer
## Dx

I only wrote this bot so i can have an smiley in my bot name xD.

```
def Dx(ophist, myhist, opmove, mymove):
    from random import choice
    import math
    def honest(hist):
        return [int(x[0]==x[1]) for x in hist]

    def avg(arr):
        if len(arr)==0:
            return 0
        return sum(arr)/float(len(arr))

    def clamp(i, lo, hi):
        return min(hi, max(lo, i))

    def deltas(arr):
        return [a-b for a,b in zip(arr[1:],arr[:-1])]

    def delta_based_prediction(arr,l):
        deltarr = []
        i=0
        while len(arr)<0:
            deltarr[i]=avg(arr[-l:])
            i+=1
            arr = deltas(arr)
        return sum(deltarr)

    next_honesty = delta_based_prediction(honest(ophist),int(math.sqrt(len(ophist))))
    if abs(next_honesty-0.5)<0.1 or not opmove:
        return choice(['R','P','S'])
    next_honesty=int(clamp(round(next_honesty),0,1))
    winner = {'S': 'R', 'R': 'P', 'P': 'S'}

    if next_honesty > 0:
        return winner[opmove]

    return choice([opmove, winner[winner[opmove]]])

```
> 1 votes

# Answer
# Bot name: dontlietome

Determines if the opponent is lying or not depending on how many times the opponent lied in the last 10 rounds. Selects move depending on if the opponent is lying or not. If the opponent is determined to be lying, then plays what the hint was.

```
import random
def dontlietome(opp_moves, my_moves, opp_hint, my_hint):
    def is_trustworthy(moves, length):
        length = max(-length, -len(moves))
        history = [1 if move[0] == move[1] else 0 for move in moves[length:]]
        prob_honest = float(sum(history))/float(len(history))
        choice = random.uniform(0., 1.)
        if choice <= prob_honest:
            return True
        else:
            return False

    moves = ["R", "P", "S"]
    lose_against_map = {"S":"R", "R":"P", "P":"S"}
    length = 10
    if opp_hint == None:
        # Honest round
        return random.choice(moves)
    else:
        # Real round
        if len(opp_moves) < length:
            return my_hint
        if is_trustworthy(opp_moves, length):
            return lose_against_map[opp_hint]
        else:
            return my_hint

```
> 1 votes

# Answer
## Everybody Lies

```
import random

def everybodylies (opphist, myhist, oppmove, mymove):
    if mymove == None:
        return random.choice(["R","P","S"])
    elif mymove == "R": return "S"
    elif mymove == "P": return "R"
    elif mymove == "S": return "P"

```

It lies about its move ("I'll play Scissors!"), and assumes the opponent was also lying and that they'll try to beat what I said my move would be ("hmm, Rock beats Scissors so I'm playing that"), but I actually play the move that beats that move ("Paper! Surprise!").
> 1 votes

# Answer
# Trusting Bot

```
def trusting_bot(h_opp, h_me, opp, me):
    if opp=="S":
        return "R"
    elif opp=="R":
        return "P"
    else:
        return "S"

```

Always claims to throw scissors, but will do whatever beats what the opponent said. Will reliably draw with itself.
> 1 votes

# Answer
```
import random
def trustingRandom(a,b,c,d):
  move = random.choice(["R","P","S"])
  if c == "R":
    move = "P"
  elif c == "P":
    move = "S"
  elif c == "S":
    move = "R"
  return move

```
> 0 votes

# Answer
# Averager

```
def averager(op, mp, od, md):
  import random
  if od == md == None:
    if op == mp == []:
      return random.choice('RPS')
    else:
      opa = [i[1] for i in op]
      copa = [opa.count(i) for i in 'RPS']
      copam = [i for i, j in zip('RPS', copa) if j == max(copa)]
      opd = [i[0] for i in op]
      copd = [opd.count(i) for i in 'RPS']
      copm = [i for i, j in zip('RPS', copd) if j == max(copd) and i in copam]
      return random.choice(copam if copm == [] else copm)
  else:
    if op == mp == []:
      return md
    else:
      hop = sum([1. if i[0] == i[1] else 0. for i in op]) / len(op)
      hmp = sum([1. if i[0] == i[1] else 0. for i in mp]) / len(mp)
      return 'PSR'['RPS'.index(od)] if hmp >= 0.75 and hop >= 0.50 else md

```
> 0 votes

# Answer
Just a little better than my previous entry...

```
def learningbot4(yourlist,mylist,you,me):
  CHECK={"R":{"R":0,"P":1,"S":-1},"P":{"R":-1,"P":0,"S":1},"S":{"R":1,"P":-1,"S":0}}
  results={None:{"R":0,"P":0,"S":0},"R":{"R":0,"P":0,"S":0},"P":{"R":0,"P":0,"S":0},"S":{"R":0,"P":0,"S":0}}
  for i in range(len(yourlist)):
    res=CHECK[yourlist[i][1]][mylist[i][1]]
    if mylist[i][0]==mylist[i][1]: res+=0.5
    results[yourlist[i][0]][mylist[i][1]]+=res
    results[None][mylist[i][0]]+=res
  return max(results[you],key=results[you].get)

```
> 0 votes

# Answer
## csbot on steroids

I think the suggestion that @user1502040 makes in the comments should be followed. Otherwise this bot would have an advantage that I would consider unfair. I submit it so that the difference that it makes can be assessed. With the suggested random seeding the steroids would be neutralized and the bot would be equivalent to `csbot`, so then only one should participate in the contest.

```
from random import seed
from csbot import csbot

def csbot_on_steroids(ophist,myhist,opdecl,mydecl):
  seed()
  m = csbot(ophist,myhist,opdecl,mydecl)
  seed(0)
  return m

```
> 0 votes

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