REM >penney
PRINT "*** Penney's Game ***"
REPEAT
  PRINT ' "Heads you pick first, tails I pick first."
  PRINT "And it is... ";
  WAIT 100
  ht% = RND(0 - TIME) AND 1
  IF ht% THEN
    PRINT "heads!"
    PROC_player_chooses(player$)
    computer$ = FN_optimal(player$)
    PRINT "I choose "; computer$; "."
  ELSE
    PRINT "tails!"
    computer$ = FN_random
    PRINT "I choose "; computer$; "."
    PROC_player_chooses(player$)
  ENDIF
  PRINT "Starting the game..." ' SPC 5;
  sequence$ = ""
  winner% = FALSE
  REPEAT
    WAIT 100
    roll% = RND AND 1
    IF roll% THEN
      sequence$ += "H"
      PRINT "H  ";
    ELSE
      PRINT "T  ";
      sequence$ += "T"
    ENDIF
    IF RIGHT$(sequence$, 3) = computer$ THEN
      PRINT ' "I won!"
      winner% = TRUE
    ELSE
      IF RIGHT$(sequence$, 3) = player$ THEN
        PRINT ' "Congratulations! You won."
        winner% = TRUE
      ENDIF
    ENDIF
  UNTIL winner%
  REPEAT
    valid% = FALSE
    INPUT "Another game? (Y/N) " another$
    IF INSTR("YN", another$) THEN valid% = TRUE
  UNTIL valid%
UNTIL another$ = "N"
PRINT "Thank you for playing!"
END
:
DEF PROC_player_chooses(RETURN sequence$)
LOCAL choice$, valid%, i%
REPEAT
  valid% = TRUE
  PRINT "Enter a sequence of three choices, each of them either H or T:"
  INPUT "> " sequence$
  IF LEN sequence$ <> 3 THEN valid% = FALSE
  IF valid% THEN
    FOR i% = 1 TO 3
      choice$ = MID$(sequence$, i%, 1)
      IF choice$ <> "H" AND choice$ <> "T" THEN valid% = FALSE
    NEXT
  ENDIF
UNTIL valid%
ENDPROC
:
DEF FN_random
LOCAL sequence$, choice%, i%
sequence$ = ""
FOR i% = 1 TO 3
  choice% = RND AND 1
  IF choice% THEN sequence$ += "H" ELSE sequence$ += "T"
NEXT
= sequence$
:
DEF FN_optimal(sequence$)
IF MID$(sequence$, 2, 1) = "H" THEN
  = "T" + LEFT$(sequence$, 2)
ELSE
  = "H" + LEFT$(sequence$, 2)
ENDIF


#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define SEQLEN 3

int getseq(char *s)
{
    int r = 0;
    int i = 1 << (SEQLEN - 1);

    while (*s && i) {
        switch (*s++) {
            case 'H':
            case 'h':
                r |= i;
                break;
            case 'T':
            case 't':
                /* 0 indicates tails, this is 0, so do nothing */
                break;
            default:
                return -1;
        }
        i >>= 1;
    }

    return r;
}

void printseq(int seq)
{
    int i;
    for (i = SEQLEN - 1; i >= 0; --i)
        printf("%c", seq & (1 << i) ? 'h' : 't');
}

int getuser(void)
{
    int user;
    char s[SEQLEN + 1];

    printf("Enter your sequence of %d (h/t): ", SEQLEN);
    while (1) {
        /* This needs to be manually changed if SEQLEN is changed */
        if (scanf("%3s", s) != 1) exit(1);
        if ((user = getseq(s)) != -1) return user;
        printf("Please enter only h/t characters: ");
    }
}

int getai(int user)
{
    int ai;

    printf("Computers sequence of %d is: ", SEQLEN);
    /* The ai's perfect choice will only be perfect for SEQLEN == 3 */
    if (user == -1)
        ai = rand() & (1 << SEQLEN) - 1;
    else
        ai = (user >> 1) | ((~user << 1) & (1 << SEQLEN - 1));

    printseq(ai);
    printf("\n");
    return ai;
}

int rungame(int user, int ai)
{
    /* Generate first SEQLEN flips. We only need to store the last SEQLEN
     * tosses at any one time. */
    int last3 = rand() & (1 << SEQLEN) - 1;

    printf("Tossed sequence: ");
    printseq(last3);
    while (1) {
        if (user == last3) {
            printf("\nUser wins!\n");
            return 1;
        }

        if (ai == last3) {
            printf("\nAi wins!\n");
            return 0;
        }

        last3 = ((last3 << 1) & (1 << SEQLEN) - 2) | (rand() & 1);
        printf("%c", last3 & 1 ? 'h' : 't');
    }
}

int main(void)
{
    srand(time(NULL));
    int playerwins = 0;
    int totalgames = 0;

    /* Just use ctrl-c for exit */
    while (1) {
        int user = -1;
        int ai   = -1;

        printf("\n");
        if (rand() & 1) {
            ai   = getai(user);
            user = getuser();
        }
        else {
            user = getuser();
            ai   = getai(user);
        }

        playerwins += rungame(user, ai);
        totalgames++;

        printf("You have won %d out of %d games\n", playerwins, totalgames);
        printf("=================================\n");
    }

    return 0;
}


using static System.Console;
using static System.Threading.Thread;
using System;

public static class PenneysGame
{
    const int pause = 500;
    const int N = 3;
    static Random rng = new Random();

    static int Toss() => rng.Next(2);

    static string AsString(this int sequence) {
        string s = "";
        for (int b = 0b100; b > 0; b >>= 1) {
            s += (sequence & b) > 0 ? 'T' : 'H';
        }
        return s;
    }

    static int UserInput() {
        while (true) {
            switch (ReadKey().Key) {
                case ConsoleKey.Escape: return -1;
                case ConsoleKey.H: return 0;
                case ConsoleKey.T: return 1;
            }
            Console.Write('\b');
        }
    }

    public static void Main2() {
        int yourScore = 0, myScore = 0;
        while (true) {
            WriteLine($"Your score: {yourScore}, My score: {myScore}");
            WriteLine("Determining who goes first...");
            Sleep(pause);
            bool youStart = Toss() == 1;
            WriteLine(youStart ? "You go first." : "I go first.");
            int yourSequence = 0, mySequence = 0;
            if (youStart) {
                WriteLine("Choose your sequence of (H)eads and (T)ails (or press Esc to exit)");
                int userChoice;
                for (int i = 0; i < N; i++) {
                    if ((userChoice = UserInput()) < 0) return;
                    yourSequence = (yourSequence << 1) + userChoice;
                }
                mySequence = ((~yourSequence << 1) & 0b100) | (yourSequence >> 1);
            } else {
                for (int i = 0; i < N; i++) {
                    mySequence = (mySequence << 1) + Toss();
                }

                WriteLine("I chose " + mySequence.AsString());
                do {
                    WriteLine("Choose your sequence of (H)eads and (T)ails (or press Esc to exit)");
                    int choice;
                    yourSequence = 0;
                    for (int i = 0; i < N; i++) {
                        if ((choice = UserInput()) < 0) return;
                        yourSequence = (yourSequence << 1) + choice;
                    }
                    if (yourSequence == mySequence) {
                        WriteLine();
                        WriteLine("You cannot choose the same sequence.");
                    }
                } while (yourSequence == mySequence);
            }

            WriteLine();
            WriteLine($"Your sequence: {yourSequence.AsString()}, My sequence: {mySequence.AsString()}");
            WriteLine("Tossing...");
            int sequence = 0;
            for (int i = 0; i < N; i++) {
                Sleep(pause);
                int toss = Toss();
                sequence = (sequence << 1) + toss;
                Write(toss > 0 ? 'T' : 'H');
            }
            while (true) {
                if (sequence == yourSequence) {
                    WriteLine();
                    WriteLine("You win!");
                    yourScore++;
                    break;
                } else if (sequence == mySequence) {
                    WriteLine();
                    WriteLine("I win!");
                    myScore++;
                    break;
                }
                Sleep(pause);
                int toss = Toss();
                sequence = ((sequence << 1) + toss) & 0b111;
                Write(toss > 0 ? 'T' : 'H');
            }
            WriteLine("Press a key.");
            ReadKey();
            Clear();
        }
    }

}


#include <time.h>
#include <iostream>
#include <string>

using namespace std;

class penney
{
public:
    penney()
    { pW = cW = 0;  }
    void gameLoop()
    {
	string a;
	while( true )
	{
	    playerChoice = computerChoice = "";
	    if( rand() % 2 )
	    { computer(); player(); }
	    else
	    { player(); computer(); }

	    play();

	    cout << "[Y] to play again "; cin >> a;
	    if( a[0] != 'Y' && a[0] != 'y' )
	    {
		cout << "Computer won " << cW << " times." << endl << "Player won " << pW << " times.";
		break;
	    }
	    cout << endl << endl;
        }
    }
private:
    void computer()
    {
        if( playerChoice.length() == 0 )
	{
	    for( int x = 0; x < 3; x++ )
		computerChoice.append( ( rand() % 2 ) ? "H" : "T", 1 );
	}
	else
	{
	    computerChoice.append( playerChoice[1] == 'T' ? "H" : "T", 1 );
	    computerChoice += playerChoice.substr( 0, 2 );
	}
	cout << "Computer's sequence of three is: " << computerChoice << endl;
    }
    void player()
    {
	cout << "Enter your sequence of three (H/T) "; cin >> playerChoice;
    }
    void play()
    {
	sequence = "";
	while( true )
	{
	    sequence.append( ( rand() % 2 ) ? "H" : "T", 1 );
	    if( sequence.find( playerChoice ) != sequence.npos )
	    {
		showWinner( 1 );
		break;
	    }
	    else if( sequence.find( computerChoice ) != sequence.npos )
	    {
		showWinner( 0 );
		break;
	    }
	}
    }
    void showWinner( int i )
    {
	string s;
	if( i ) { s = "Player wins!"; pW++; }
	else { s = "Computer wins!"; cW++; }
	cout << "Tossed sequence: " << sequence << endl << s << endl << endl;
    }
    string playerChoice, computerChoice, sequence;
    int pW, cW;
};
int main( int argc, char* argv[] )
{
    srand( static_cast<unsigned>( time( NULL ) ) );
    penney game; game.gameLoop();
    return 0;
}


(ns penney.core
  (:gen-class))

(def heads \H)
(def tails \T)

(defn flip-coin []
  (let [flip (rand-int 2)]
    (if (= flip 0) heads tails)))

(defn turn [coin]
  (if (= coin heads) tails heads))

(defn first-index [combo coll]
  (some #(if (= (second %) combo) (first %)) coll))

(defn find-winner [h c]
  (if (< h c)
    (do (println "YOU WIN!\n") :human)
    (do (println "COMPUTER WINS!\n") :computer)))

(defn flip-off [human comp]
  (let [flips (repeatedly flip-coin)
        idx-flips (map-indexed vector (partition 3 1 flips))
        h (first-index (seq human) idx-flips)
        c (first-index (seq comp) idx-flips)]
    (println (format "Tosses: %s" (apply str (take (+ 3 (min h c)) flips))))
    (find-winner h c)))

(defn valid? [combo]
  (if (empty? combo) true (and (= 3 (count combo)) (every? #(or (= heads %) (= tails %)) combo))))

(defn ask-move []
  (println "What sequence of 3 Heads/Tails do you choose?")
  (let [input (clojure.string/upper-case (read-line))]
    (if-not (valid? input) (recur) input)))

(defn optimize-against [combo]
  (let [mid (nth combo 1)
        comp (str (turn mid) (first combo) mid)]
    (println (format "Computer chooses %s: " comp)) comp))

(defn initial-move [game]
  (let [combo (apply str (repeatedly 3 flip-coin))]
    (println "--------------")
    (println (format "Current score | CPU: %s, You: %s" (:computer game) (:human game)))
    (if (= (:first-player game) tails)
      (do
        (println "Computer goes first and chooses: " combo)
        combo)
      (println "YOU get to go first."))))

(defn play-game [game]
    (let [c-move (initial-move game)
          h-move (ask-move)]
      (if-not (empty? h-move)
        (let [winner (flip-off h-move (if (nil? c-move) (optimize-against h-move) c-move))]
          (recur (assoc game winner (inc (winner game)) :first-player (flip-coin))))
        (println "Thanks for playing!"))))

(defn -main [& args]
  (println "Penney's Game.")
  (play-game {:first-player (flip-coin)
              :human 0, :computer 0}))


(setf *random-state* (make-random-state t))

(defparameter *heads* #\H)
(defparameter *tails* #\T)

(defun main ()
  (format t "Penney's Game~%~%")
  (format t "Flipping to see who goes first ...")

  (setq p2 nil)
  (if (string= (flip) *heads*)
      (progn (format t " I do.~%")
             (setq p2 (choose-random-sequence))
             (format t "I choose: ~A~%" p2))
      (format t "You do.~%"))

  (setq p1 nil)
  (loop while (null p1) doing
    (format t "Enter your three-flip sequence: ")
    (setq p1 (string (read)))
    (cond ((/= (length p1) 3)
           (format t "Sequence must consist of three flips.~%")
           (setq p1 nil))
          ((string= p1 p2)
           (format t "Sequence must be different from mine.~%")
           (setq p1 nil))
          ((notevery #'valid? (coerce p1 'list))
           (format t "Sequence must be contain only ~A's and ~A's.~%" *heads* *tails*)
           (setq p1 nil))))
  (format t "You picked: ~A~%" p1)

  (if (null p2)
    (progn
      (setq p2 (choose-optimal-sequence p1))
      (format t "I choose: ~A~%" p2)))

  (format t "Here we go. ~A, you win; ~A, I win.~%" p1 p2)
  (format t "Flips:")
  (let ((winner nil)
        (flips '()))
    (loop while (null winner) doing
      (setq flips (cons (flip) flips))
      (format t " ~A" (car flips))
      (if (>= (length flips) 3)
        (let ((trail (coerce (reverse (subseq flips 0 3)) 'string)))
          (cond ((string= trail p1) (setq winner "You"))
                ((string= trail p2) (setq winner "I"))))))
    (format t "~&~A win!" winner)))

(defparameter *sides* (list *heads* *tails*))
(defun flip () (nth (random 2 *random-state*) *sides*))

(defun valid? (flip) (not (null (member flip *sides*))))

(defun opposite (flip) (if (string= flip *heads*) *tails* *heads*))

(defun choose-random-sequence () (coerce (list (flip) (flip) (flip)) 'string))

(defun choose-optimal-sequence (against)
  (let* ((opposed (coerce against 'list))
         (middle  (cadr opposed))
         (my-list (list (opposite middle) (car opposed) middle)))
    (coerce my-list 'string)))

(main)


void main() {
    import std.stdio, std.random, std.algorithm, std.string,
           std.conv, std.range, core.thread;

    immutable first = uniform(0, 2) == 0;

    string you, me;
    if (first) {
        me = 3.iota.map!(_ => "HT"[uniform(0, $)]).text;
        writefln("I choose first and will win on first seeing %s in the list of tosses", me);
        while (you.length != 3 || you.any!(c => !c.among('H', 'T')) || you == me) {
            "What sequence of three Heads/Tails will you win with: ".write;
            you = readln.strip;
        }
    } else {
        while (you.length != 3 || you.any!(c => !c.among('H', 'T'))) {
            "After you: What sequence of three Heads/Tails will you win with: ".write;
            you = readln.strip;
        }
        me = (you[1] == 'T' ? 'H' : 'T') ~ you[0 .. 2];
        writefln("I win on first seeing %s in the list of tosses", me);
    }

    "Rolling:\n  ".write;
    string rolled;
    while (true) {
        rolled ~= "HT"[uniform(0, $)];
        rolled.back.write;
        if (rolled.endsWith(you))
            return "\n  You win!".writeln;
        if (rolled.endsWith(me))
            return "\n  I win!".writeln;
        Thread.sleep(1.seconds);
    }
}


defmodule Penney do
  @toss [:Heads, :Tails]

  def game(score \\ {0,0})
  def game({iwin, ywin}=score) do
    IO.puts "Penney game score  I : #{iwin}, You : #{ywin}"
    [i, you] = @toss
    coin = Enum.random(@toss)
    IO.puts "#{i} I start, #{you} you start ..... #{coin}"
    {myC, yC} = setup(coin)
    seq = for _ <- 1..3, do: Enum.random(@toss)
    IO.write Enum.join(seq, " ")
    {winner, score} = loop(seq, myC, yC, score)
    IO.puts "\n #{winner} win!\n"
    game(score)
  end

  defp setup(:Heads) do
    myC = Enum.shuffle(@toss) ++ [Enum.random(@toss)]
    joined = Enum.join(myC, " ")
    IO.puts "I chose  : #{joined}"
    {myC, yourChoice}
  end
  defp setup(:Tails) do
    yC = yourChoice
    myC = (@toss -- [Enum.at(yC,1)]) ++ Enum.take(yC,2)
    joined = Enum.join(myC, " ")
    IO.puts "I chose  : #{joined}"
    {myC, yC}
  end

  defp yourChoice do
    IO.write "Enter your choice (H/T) "
    choice = read([])
    IO.puts "You chose: #{Enum.join(choice, " ")}"
    choice
  end

  defp read([_,_,_]=choice), do: choice
  defp read(choice) do
    case IO.getn("") |> String.upcase do
      "H" -> read(choice ++ [:Heads])
      "T" -> read(choice ++ [:Tails])
      _   -> read(choice)
    end
  end

  defp loop(myC, myC, _, {iwin, ywin}), do: {"I", {iwin+1, ywin}}
  defp loop(yC,  _,  yC, {iwin, ywin}), do: {"You", {iwin, ywin+1}}
  defp loop(seq, myC, yC, score) do
    append = Enum.random(@toss)
    IO.write " #{append}"
    loop(tl(seq)++[append], myC, yC, score)
  end
end

Penney.game


USING: arrays ascii io kernel math prettyprint random sequences
strings ;
IN: rosetta-code.penneys-game

! Generate a random boolean.
: t|f ( -- t/f )
    1 random-bits 0 = ;

! Checks whether the sequence chosen by the human is valid.
: valid-input? ( seq -- ? )
    [ [ CHAR: H = ] [ CHAR: T = ] bi or ] filter length 3 = ;

! Prompt the human player for a sequence.
: input-seq ( -- seq )
    "Please input a 3-long sequence of H or T (heads or tails)."
    print "Example: HTH" print "> " write readln >upper >array ;

! Get the human player's input sequence with error checking.
: get-input ( -- seq )
    t [ drop input-seq dup valid-input? not ] loop ;

! Add a random coin flip to a vector.
: flip-coin ( vector -- vector' )
    t|f CHAR: H CHAR: T ? over push ;

! Generate a random 3-long sequence of coin flips.
: rand-seq ( -- seq )
    V{ } clone 3 [ flip-coin ] times ;

! Generate the optimal sequence response to a given sequence.
: optimal ( seq1 -- seq2 )
    [ second dup CHAR: H = [ CHAR: T ] [ CHAR: H ] if ]
    [ first ] [ second ] tri 3array nip dup
    "The computer chose " write >string write "." print ;

! Choose a random sequence for the computer and report what
! was chosen.
: computer-first ( -- seq )
    "The computer picks a sequence first and chooses " write
    rand-seq dup >string write "." print >array ;

! The human is prompted to choose any sequence with no
! restrictions.
: human-first ( -- seq )
    "You get to go first." print get-input ;

! Forbid the player from choosing the same sequence as the
! computer.
: human-second ( cseq -- cseq hseq )
    get-input [ 2dup = not ]
    [ drop
        "You may not choose the same sequence as the computer."
        print get-input
    ] until ;

! Display a message introducing the game.
: welcome ( -- )
    "Welcome to Penney's Game. The computer or the player" print
    "will be randomly selected to choose a sequence of"    print
    "three coin tosses. The sequence will be shown to the" print
    "opponent, and then he will choose a sequence."   print nl
    "Then, a coin will be flipped until the sequence" print
    "matches the last three coin flips, and a winner" print
    "announced." print nl ;

! Check for human victory.
: human-won? ( cseq hseq coin-flips -- ? )
    3 tail* >array = nip ;

! Check for computer victory.
: computer-won? ( cseq hseq coin-flips -- ? )
    3 tail* >array pick = 2nip ;

! Flip a coin until a victory is detected. Then, inform the
! player who won.
: flip-coins ( cseq hseq -- )
    "Flipping coins..." print
    rand-seq [ 3dup [ human-won? ] [ computer-won? ] 3bi or ]
    [ flip-coin ] until dup >string print human-won?
    [ "You won!" print ] [ "The computer won." print ] if ;

! Randomly choose a player to choose their sequence first.
! Then play a full round of Penney's Game.
: start-game ( -- )
    welcome t|f [ human-first dup optimal swap ]
    [ computer-first human-second ] if flip-coins ;

start-game


Sub Jugador_elige(secuencia As String)
    Dim As String eleccion
    Dim As Byte valido, i
    Do
        valido = True
        Print !"\nIngresa una secuencia de 3 opciones, cada una de ellas H o T:";
        Input " > ", secuencia
        If Len(secuencia) <> 3 Then valido = False
        If valido Then
            For i = 1 To 3
                eleccion = Mid(Ucase(secuencia), i, 1)
                If eleccion <> "H" And eleccion <> "T" Then valido = False
            Next
        End If
    Loop Until valido
End Sub

Function Aleatorio() As String
    Dim As Byte eleccion, i
    Dim As String tirada
    tirada = ""
    For i = 1 To 3
        eleccion = Rnd And 1
        If eleccion Then tirada += "H" Else tirada += "T"
    Next
    Return tirada
End Function

Function Optima(secuencia As String) As String
    If Mid(secuencia, 2, 1) = "H" Then
        Optima = "T" + Left(secuencia, 2)
    Else
        Optima = "H" + Left(secuencia, 2)
    End If
End Function

Randomize Timer
Dim As String jugador, computador, otro
Dim Shared As String secuencia
Dim As Boolean ganador, valido
Do
    Cls
    Color 11
    Print "*** Penney's Game ***" & Chr(10)
    Color 7
    Print "Cara eliges primero, cruz yo elijo primero."
    Print "Y es... ";
    Sleep 300
    Dim As Double ht: ht = Rnd(0 - Timer) And 1
    If ht Then
        Print "cara!"
        Jugador_elige(jugador)
        computador = Optima(jugador)
        Print !"\nYo elijo "; computador; !".\n"
    Else
        Print "cruz!"
        computador = Aleatorio
        Print !"\nYo elijo "; computador; !".\n"
        Jugador_elige(jugador)
    End If
    Print "Comenzando el juego ..."
    secuencia = ""
    ganador = False
    Do
        Sleep 200
        Dim As Integer lanzar = Rnd And 1
        If lanzar Then
            secuencia += "H"
            Print "H  ";
        Else
            Print "T  ";
            secuencia += "T"
        End If

        If Right(secuencia, 3) = computador Then
            Print !"\nGan‚!\n"
            ganador = True
        Else
            If Right(secuencia, 3) = jugador Then
                Print !"\nFelicidades! Ganaste.\n"
                ganador = True
            End If
        End If
    Loop Until ganador
    Do
        valido = False
        Input "¨Otra ronda? (S/N) ", otro
        If Instr("SYN", Ucase(otro)) Then valido = True
    Loop Until valido
Loop Until Ucase(otro) = "N"
Print !"\nGracias por jugar!"
Sleep
End


package main
import "fmt"
import "math/rand"
func main(){
var a1,a2,a3,y,match,j,k int
var inp string
y=1
for y==1{
fmt.Println("Enter your sequence:")
fmt.Scanln(&inp)
var Ai [3] int
var user [3] int
for j=0;j<3;j++{
if(inp[j]==104){
user[j]=1
}else{
user[j]=0
}
}
for k=0;k<3;k++{
Ai[k]=rand.Intn(2)
}
for user[0]==Ai[0]&&user[1]==Ai[1]&&user[2]==Ai[2]{
for k=0;k<3;k++{
Ai[k]=rand.Intn(2)
}
}
fmt.Println("You gave the sequence:")
printht(user)
fmt.Println()
fmt.Println("The computer generated sequence is:")
printht(Ai)
fmt.Println()
a1=rand.Intn(2)
a2=rand.Intn(2)
a3=rand.Intn(2)
fmt.Print("The generated sequence is:")
printh(a1)
printh(a2)
printh(a3)
match=0
for match==0{
if(matches(user,a1,a2,a3)==1){
fmt.Println()
fmt.Println("You have won!!!")
match=1
}else if(matches(Ai,a1,a2,a3)==1){
fmt.Println()
fmt.Println("You lost!! Computer wins")
match=1
}else{
a1=a2
a2=a3
a3=rand.Intn(2)
printh(a3)
}
}
fmt.Println("Do you want to continue(0/1):")
fmt.Scanln(&y)
}
}
func printht(a [3] int) int{
var i int
for i=0;i<3;i++{
if(a[i]==1){
fmt.Print("h")
}else{
fmt.Print("t")
}
}
return 1
}
func printh(a int) int{
if(a==1){
fmt.Print("h")
}else{
fmt.Print("t")
}
return 1
}
func matches(a [3] int,p int,q int,r int) int{
if(a[0]==p&&a[1]==q&&a[2]==r){
return 1
}else{
return 0
}
}


import qualified Data.List as L
import System.IO
import System.Random

data CoinToss = H | T deriving (Read, Show, Eq)

parseToss :: String -> [CoinToss]
parseToss [] = []
parseToss (s:sx)
  | s == 'h' || s == 'H' = H : parseToss sx
  | s == 't' || s == 'T' = T : parseToss sx
  | otherwise = parseToss sx

notToss :: CoinToss -> CoinToss
notToss H = T
notToss T = H

instance Random CoinToss where
  random g = let (b, gb) = random g in (if b then H else T, gb)
  randomR = undefined

prompt :: (Read a) => String -> String -> (String -> Maybe a) -> IO a
prompt msg err parse = do
  putStrLn msg
  line <- getLine
  let ans = parse line
  case ans of
    Nothing   -> do
      putStrLn err
      prompt msg err parse
    Just ansB -> return ansB

showCat :: (Show a) => [a] -> String
showCat = concatMap show

data Winner = Player | CPU

-- This may never terminate.
runToss :: (RandomGen g) => [CoinToss] -> [CoinToss] -> g -> ([CoinToss], Winner)
runToss player cpu gen =
  let stream = randoms gen
      run ss@(s:sx)
        | L.isPrefixOf player ss = player
        | L.isPrefixOf cpu ss    = cpu
        | otherwise              = s : run sx
      winner = run stream
  in if L.isSuffixOf player winner
     then (winner, Player)
     else (winner, CPU)

game :: (RandomGen g, Num a, Show a) => Bool -> a -> a -> g -> IO ()
game cpuTurn playerScore cpuScore gen = do
  putStrLn $ "\nThe current score is CPU: " ++ show cpuScore
    ++ ", You: " ++ show playerScore

  let (genA, genB) = split gen
      promptPlayer check =
        prompt "Pick 3 coin sides: " "Invalid input." $ \s ->
          let tosses = parseToss s in
          if check tosses then Just tosses else Nothing
      promptCpu x  = putStrLn $ "I have chosen: " ++ showCat x

  (tosses, winner) <-
    if cpuTurn
    then do
      let cpuChoice = take 3 $ randoms gen
      promptCpu cpuChoice
      playerChoice <- promptPlayer $ \n -> n /= cpuChoice && 3 == length n
      return $ runToss playerChoice cpuChoice genA
    else do
      playerChoice <- promptPlayer $ \n -> 3 == length n
      let cpuChoice = case playerChoice of [a,b,_] -> [notToss b, a, b]
      promptCpu cpuChoice
      return $ runToss playerChoice cpuChoice genA

  putStrLn $ "The sequence tossed was: " ++ showCat tosses

  case winner of
    Player -> do
      putStrLn "You win!"
      game (not cpuTurn) (playerScore + 1) cpuScore genB
    CPU -> do
      putStrLn "I win!"
      game (not cpuTurn) playerScore (cpuScore + 1) genB

main :: IO ()
main = do
  hSetBuffering stdin LineBuffering
  stdgen <- getStdGen
  let (cpuFirst, genA) = random stdgen
  game cpuFirst 0 0 genA


require 'format/printf numeric'

randomize ''                               NB. randomize seed for new session

Vals=: 'HT'                                NB. valid values
input=: 1!:1@<&1:                          NB. get input from user
prompt=: [email protected]                        NB. prompt user for input
checkInput=: 'Choose 3 H/Ts' assert (Vals e.~ ]) , 3 = #
getUserSeq=: (] [ checkInput)@[email protected]
choose1st=: Vals {~ 3 [email protected]$ 2:               NB. computer chooses 1st
choose2nd=: (0 1 1=1 0 1{])&.(Vals&i.)     NB. computer chooses 2nd

playPenney=: verb define
  if. ?2 do.                               NB. randomize first chooser
    Comp=. choose1st ''
    'Computer chose %s' printf <Comp
    You=. getUserSeq 'Choose a sequence of three coin tosses (H/T):'
    'Choose a different sequence to computer' assert You [email protected]: Comp
  else.
    You=. getUserSeq 'Choose a sequence of three coin tosses (H/T):'
    Comp=. choose2nd You
    'Computer chose %s ' printf <Comp
  end.
  Tosses=. Vals {~ 100 [email protected]$ 2
  Result=. (Comp,:You) {[email protected]@E."1 Tosses
  'Toss sequence is %s' printf < (3 + <./ Result) {. Tosses
  echo ('No result';'You win!';'Computer won!') {::~ *-/ Result
)


import java.util.*;

public class PenneysGame {

    public static void main(String[] args) {
        Random rand = new Random();

        String compChoice = "", playerChoice;
        if (rand.nextBoolean()) {

            for (int i = 0; i < 3; i++)
                compChoice += "HT".charAt(rand.nextInt(2));
            System.out.printf("Computer chooses %s%n", compChoice);

            playerChoice = prompt(compChoice);

        } else {

            playerChoice = prompt(compChoice);

            compChoice = "T";
            if (playerChoice.charAt(1) == 'T')
                compChoice = "H";
            compChoice += playerChoice.substring(0, 2);
            System.out.printf("Computer chooses %s%n", compChoice);
        }

        String tossed = "";
        while (true) {
            tossed += "HT".charAt(rand.nextInt(2));
            System.out.printf("Tossed %s%n" , tossed);
            if (tossed.endsWith(playerChoice)) {
                System.out.println("You win!");
                break;
            }
            if (tossed.endsWith(compChoice)) {
                System.out.println("Computer wins!");
                break;
            }
        }
    }

    private static String prompt(String otherChoice) {
        Scanner sc = new Scanner(System.in);
        String s;
        do {
            System.out.print("Choose a sequence: ");
            s = sc.nextLine().trim().toUpperCase();
        } while (!s.matches("[HT]{3}") || s.equals(otherChoice));
        return s;
    }
}


const SLEN = 3

autobet() = randbool(SLEN)
function autobet(ob::BitArray{1})
    rlen = length(ob)
    2 < rlen || return ~ob
    3 < rlen || return [~ob[2], ob[1:2]]
    opt = falses(rlen)
    opt[1] = true
    opt[end-1:end] = true
    ob != opt || return ~opt
    return opt
end
autobet(ob::Array{Bool,1}) = autobet(convert(BitArray{1}, ob))

function pgencode{T<:String}(a::T)
    b = uppercase(a)
    0 < length(b) || return trues(0)
    !ismatch(r"[^HT]+", b) || error(@sprintf "%s is not a HT sequence" a)
    b = split(b, "")
    b .== "H"
end
pgdecode(a::BitArray{1}) = join([i ? "H" : "T" for i in a], "")

function humanbet()
    b = ""
    while length(b) != SLEN  || ismatch(r"[^HT]+", b)
        print("Your bet? ")
        b = uppercase(chomp(readline()))
    end
    return b
end


// version 1.2.10

import java.util.Random

val rand = Random()

val optimum = mapOf(
    "HHH" to "THH", "HHT" to "THH", "HTH" to "HHT", "HTT" to "HHT",
    "THH" to "TTH", "THT" to "TTH", "TTH" to "HTT", "TTT" to "HTT"
)

fun getUserSequence(): String {
    println("A sequence of three H or T should be entered")
    var userSeq: String
    do {
        print("Enter your sequence: ")
        userSeq = readLine()!!.toUpperCase()
    }
    while (userSeq.length != 3 || userSeq.any { it != 'H' && it != 'T' })
    return userSeq
}

fun getComputerSequence(userSeq: String = ""): String {
    val compSeq = if(userSeq == "")
        String(CharArray(3) { if (rand.nextInt(2) == 0) 'T' else 'H' })
    else
        optimum[userSeq]!!
    println("Computer's sequence: $compSeq")
    return compSeq
}

fun main(args: Array<String>) {
    var userSeq: String
    var compSeq: String
    val r = rand.nextInt(2)
    if (r == 0) {
        println("You go first")
        userSeq = getUserSequence()
        println()
        compSeq = getComputerSequence(userSeq)
    }
    else {
        println("Computer goes first")
        compSeq = getComputerSequence()
        println()
        userSeq = getUserSequence()
    }

    println()
    val coins = StringBuilder()
    while (true) {
        val coin = if (rand.nextInt(2) == 0) 'H' else 'T'
        coins.append(coin)
        println("Coins flipped: $coins")
        val len = coins.length
        if (len >= 3) {
            val seq = coins.substring(len - 3, len)
            if (seq == userSeq) {
                println("\nYou win!")
                return
            }
            else if (seq == compSeq) {
                println("\nComputer wins!")
                return
            }
        }
        Thread.sleep(2000) // wait two seconds for next flip
    }
}


function penny_game()
    local player, computer = "", ""
    function player_choose()
        io.write( "Enter your sequence of three H and/or T: " )
        local t = io.read():upper()
        if #t > 3 then t = t:sub( 1, 3 )
        elseif #t < 3 then return ""
        end

        for i = 1, 3 do
            c = t:sub( i, i )
            if c ~= "T" and c ~= "H" then
                print( "Just H's and T's!" )
                return ""
            end
        end
        return t
    end
    function computer_choose()
        local t = ""
        if #player > 0 then
            if player:sub( 2, 2 ) == "T" then
                t = "H"
            else
                t = "T";
            end
            t = t .. player:sub( 1, 2 )
        else
            for i = 1, 3 do
                if math.random( 2 ) == 1 then
                    t = t .. "H"
                else
                    t = t .. "T"
                end
            end
        end
        return t
    end
    if math.random( 2 ) == 1 then
        computer = computer_choose()
        io.write( "My sequence is: " .. computer .. "\n" )
        while( true ) do
            player = player_choose()
            if player:len() == 3 then break end
        end
    else
        while( true ) do
            player = player_choose()
            if player:len() == 3 then break end
        end
        computer = computer_choose()
        io.write( "My sequence is: " .. computer .. "\n" )
    end
    local coin, i = "", 1
    while( true ) do
        if math.random( 2 ) == 1 then
            coin = coin .. "T"
            io.write( "T" )
        else
            coin = coin .. "H"
            io.write( "H" )
        end
        if #coin > 2 then
            local seq = coin:sub( i, i + 2 )
            i = i + 1
            if seq == player then
                print( "\nPlayer WINS!!!" )
                return 1
            elseif seq == computer then
                print( "\nComputer WINS!!!" )
                return -1
            end
        end
    end
end
math.randomseed( os.time() )
local cpu, user = 0, 0
repeat
    r = penny_game()
    if r > 0 then
        user = user + 1
    else
        cpu = cpu + 1
    end
    print( "Player: " .. user .. " CPU: " .. cpu )
    io.write( "Play again (Y/N)? " )
    r = io.read()
until( r == "N" or r == "n" )


randomTorH = function()
    if rnd < 0.5 then return "T" else return "H"
end function

if rnd < 0.5 then
    playerSeq = input("Input your sequence (e.g. HTH): ").upper
    if playerSeq[1] == "T" then compSeq = "H" else compSeq = "T"
    compSeq = compSeq + playerSeq[:2]
    print "I choose: " + compSeq
else
    compSeq = randomTorH + randomTorH + randomTorH
    print "I choose: " + compSeq
    playerSeq = input("Input your sequence (e.g. HTH): ").upper
end if

print "Here we go..."
seq = ""
while true
    flip = randomTorH
    print flip
    seq = seq + flip
    if seq[-3:] == playerSeq then
        print "You win!"
        break
    else if seq[-3:] == compSeq then
        print "I win!"
        break
    end if
    wait
end while


import os, random, sequtils, strutils

randomize()

let first = sample([false, true])

var you, me = ""
if first:
  me = newSeqWith(3, sample("HT")).join()
  echo "I choose first and will win on first seeing $# in the list of tosses." % me
  while you.len != 3 or not allCharsInSet(you, {'H', 'T'}) or you == me:
    stdout.write "What sequence of three Heads/Tails will you win with? "
    you = stdin.readLine()
else:
  while you.len != 3 or not allCharsInSet(you, {'H', 'T'}):
    echo "After you: what sequence of three Heads/Tails will you win with? "
    you = stdin.readLine()
  me = (if you[1] == 'T': 'H' else: 'T') & you[0..1]
  echo "I win on first seeing $# in the list of tosses" % me

var rolled = ""
stdout.write "Rolling:\n  "
while true:
  rolled.add sample("HT")
  stdout.write rolled[^1]
  stdout.flushFile()
  if rolled.endsWith(you):
    echo "\n  You win!"
    break
  elif rolled.endsWith(me):
    echo "\n  I win!"
    break
  sleep(1000)


PROGRAM Penney;

TYPE
    CoinToss = (heads, tails);
    Sequence = array [1..3] of CoinToss;
    Player = record
        bet: Sequence;
        score: integer;
    end;

VAR
    Human, Computer: Player;
    Rounds, Count: integer;

Function TossCoin: CoinToss;
{ Returns heads or tails at random }
Begin
    if random(2) = 1 then TossCoin := Heads
    else TossCoin := tails
End;

Procedure PutToss(toss: CoinToss);
{ Outputs heads or tails as a letter }
Begin
    if toss = heads then write('H')
    else write('T')
End;

Function GetToss: CoinToss;
{ Reads H or T from the keyboard in either lettercase }
var c: char;
Begin
    { Keep reading characters until we get an appropriate letter }
    repeat read(c) until c in ['H', 'h', 'T', 't'];
    { Interpret the letter }
    if c in ['H', 'h'] then GetToss := heads
    else GetToss := tails
End;

Procedure ShowSequence(tosses: Sequence);
{ Outputs three coin tosses at once }
Var
    i: integer;
Begin
    for i := 1 to 3 do PutToss(tosses[i])
End;

Procedure ReadSequence(var tosses: Sequence);
{ Accepts three coin tosses from the keyboard }
Var i: integer;
Begin
    { Get the 3 letters }
    for i := 1 to 3 do tosses[i] := GetToss;
    { Ignore the rest of the line }
    readln
End;

Function Optimum(opponent: Sequence): Sequence;
{ Generates the optimum sequence against an opponent }
Begin
    case opponent[2] of
        heads: Optimum[1] := tails;
        tails: Optimum[1] := heads
    end;
    Optimum[2] := opponent[1];
    Optimum[3] := opponent[2]
End;

Function RandomSequence: Sequence;
{ Generates three random coin tosses }
Var
    i: integer;
Begin
    for i := 1 to 3 do RandomSequence[i] := TossCoin
End;

Function Match(first, second: Sequence): Boolean;
{ Detects whether a sequence of tosses matches another }
Var
    different: boolean;
    i: integer;
Begin
    different := false;
    i := 1;
    while (i <= 3) and not different do begin
        if not (first[i] = second[i]) then different := true;
        i := i + 1
    end;
    Match := not different
End;

Procedure PlayRound(var human, computer: Player);
{ Shows coin tosses and announces the winner }
Var
    { We only ever need to store the 3 most recent tosses in memory. }
    tosses: Sequence;
Begin
    { Start with the first three tosses }
    write('Tossing the coin: ');
    tosses := RandomSequence;
    ShowSequence(tosses);
    { Keep tossing the coin until there is a winner. }
    while not (Match(human.bet, tosses) or Match(computer.bet, tosses)) do begin
        tosses[1] := tosses[2];
        tosses[2] := tosses[3];
        tosses[3] := TossCoin;
        PutToss(tosses[3])
    end;
    { Update the winner's score and announce the winner }
    writeln;
    writeln;
    if Match(human.bet, tosses) then begin
        writeln('Congratulations! You won this round.');
        human.score := human.score + 1;
        writeln('Your new score is ', human.score, '.')
    end
    else begin
        writeln('Yay, I won this round!');
        computer.score := computer.score + 1;
        writeln('My new score is ', computer.score, '.')
    end
End;

{ Main Algorithm }

BEGIN

    { Welcome the player }
    writeln('Welcome to Penney''s game!');
    writeln;
    write('How many rounds would you like to play? ');
    readln(Rounds);
    writeln;
    writeln('Ok, let''s play ', Rounds, ' rounds.');

    { Start the game }
    randomize;
    Human.score := 0;
    Computer.score := 0;

    for Count := 1 to Rounds do begin

        writeln;
        writeln('*** Round #', Count, ' ***');
        writeln;

        { Choose someone randomly to pick the first sequence }
        if TossCoin = heads then begin
            write('I''ll pick first this time.');
            Computer.bet := RandomSequence;
            write(' My sequence is ');
            ShowSequence(Computer.bet);
            writeln('.');
            repeat
                write('What sequence do you want? ');
                ReadSequence(Human.bet);
                if Match(Human.bet, Computer.bet) then
                    writeln('Hey, that''s my sequence! Think for yourself!')
            until not Match(Human.bet, Computer.bet);
            ShowSequence(Human.bet);
            writeln(', huh? Sounds ok to me.')
        end
        else begin
            write('You pick first this time. Enter 3 letters H or T: ');
            ReadSequence(Human.bet);
            Computer.bet := Optimum(Human.bet);
            write('Ok, so you picked ');
            ShowSequence(Human.bet);
            writeln;
            write('My sequence will be ');
            ShowSequence(Computer.bet);
            writeln
        end;

        { Then we can actually play the round }
        writeln('Let''s go!');
        writeln;
        PlayRound(Human, Computer);
        writeln;
        writeln('Press ENTER to go on...');
        readln

    end;

    { All the rounds are finished; time to decide who won }
    writeln;
    writeln('*** End Result ***');
    writeln;
    if Human.score > Computer.score then writeln('Congratulations! You won!')
    else if Computer.score > Human.score then writeln('Hooray! I won')
    else writeln('Cool, we tied.');
    writeln;
    writeln('Press ENTER to finish.');
    readln

END.


#!usr/bin/perl
use 5.020;
use strict;
use warnings;

#Choose who goes first
binaryRand() == 0 ? flipCoin(userFirst()) : flipCoin(compFirst());

#Return a randomly generated 1 or 0
sub binaryRand
{
    return int(rand(2));
}
#Converts 1's and 0's to H's and T's, respectively.
sub convert
{
    my $randNum = binaryRand();
    if($randNum == 0)
    {
        return "T"
    }
    else
    {
        return "H";
    }
}

#Prompts for and returns a user's sequence of 3
sub uSeq
{
    print("Please enter a sequence of 3 of \"H\" and \"T\". EG: HHT\n>");
    my $uString = <STDIN>;

    while(1)
    {
        #Make it uppercase and validate input
        chomp($uString);
        $uString = uc $uString;
        #Check length and content (H's and T's only!)
        if(length $uString == 3 && (substr($uString, 0, 1) =~ /[HT]/ &&
                                    substr($uString, 1, 1) =~ /[HT]/ &&
                                    substr($uString, 2, 1) =~ /[HT]/))
        {
            last;
        }
        else
        {
            print("Error, try again. \n");
            print("Please enter a sequence of 3 of \"H\" and \"T\". EG: HHT\n");
            $uString = <STDIN>;
        }
    }
    return $uString;
}

#Returns an array with two elements: [0] user's seq, [1] random computer seq.
sub compFirst
{
    my $cSeq;
    #Randomly draw a sequence of 3
    for(my $i = 0; $i < 3; $i++)
    {
        $cSeq = $cSeq . convert();
    }

    print("The computer guesses first:\ncomp- $cSeq\n");
    my $uSeq = uSeq();
    print("user- $uSeq\n");
    my @seqArr = ($uSeq, $cSeq);
    return @seqArr;
}

#Returns an array with two elements: [0] user's seq, [1] optimal computer seq.
sub userFirst
{
    print("The user quesses first:\n");
    my $uSeq = uSeq();
    my $cSeq;
    #Generate the optimal sequence based on $uSeq
    my $middle = substr($uSeq, 1, 1);
    $middle eq "H" ? $cSeq = "T" : $cSeq = "H";
    $cSeq = $cSeq . substr($uSeq, 0, 2);

    print("user- $uSeq\ncomp- $cSeq\n");
    my @seqArr = ($uSeq, $cSeq);
    return @seqArr;
}

#Flips a coin, checking both sequences against the contents of the given array
sub flipCoin
{
    my ($uSeq, $cSeq) = @_;
    my $coin;
    while(1)
    {
        $coin = $coin . convert();
        if($coin =~ m/$uSeq/)
        {
            print("The sequence of tosses was: $coin\n");
            say("The player wins! ");
            last;
        }
        elsif($coin =~ m/$cSeq/)
        {
            print("The sequence of tosses was: $coin\n");
            say("The computer wins! ");
            last;
        }
    }
}


function trio(integer pick)
    return substitute_all(sprintf("%03b",pick),"10","HT")
end function

function getuser(integer bot)
integer user
    while 1 do
        user = 8 -- (a bit that clears after 3 shifts)
        printf(1,"Enter your sequence of 3 (H/T):");
        while user>7 do
            integer c = upper(wait_key())
            if c=#1B then abort(0) end if -- (Escape)
            if find(c,"HT") then
                puts(1,c)
                user = and_bits(user*2+(c='H'),0b111111)
            end if
        end while
        if user!=bot then exit end if
        printf(1,"\nYou may not pick the same as Robort!\n")
    end while
    printf(1,"\n")
    return user
end function

function getbot(int user)
    int bot = iff(user=-1?rand(8)-1
                         :4-and_bits(user,2)*2+floor(user/2))
    printf(1,"Robort picks %s\n", {trio(bot)})
    return bot
end function

function rungame(integer user, bot)
    /* We only need to store the last 3 tosses, as 0..7 */
    int last3 = rand(8)-1

    printf(1,"Rolling: %s",{trio(last3)})
    while 1 do
        if user=last3 then
            printf(1,"\nUser wins!\n")
            return 1
        elsif bot=last3 then
            printf(1,"\nRobort wins!\n")
            return 0
        end if
        last3 = and_bits(last3,3)*2+(rand(2)=1)
        printf(1,"%c", iff(and_bits(last3,1) ? 'H' : 'T'))
        sleep(0.5)
    end while
end function

procedure main()
    integer playerwins = 0,
            totalgames = 0,
            robortwins = 0

    /* Just use ctrl-c or Escape to exit */
    while 1 do
        integer user = -1,
                bot  = -1

        printf(1,"\n")
        if rand(2)=1 then
            bot  = getbot(-1)
            user = getuser(bot)
        else
            user = getuser(-1)
            bot  = getbot(user)
        end if

        playerwins += rungame(user, bot)
        totalgames += 1
        robortwins = totalgames-playerwins

        printf(1,"Robort:%d  You:%d  out of %d games\n",
                 {robortwins, playerwins, totalgames})
        printf(1,"==================================\n")
    end while

end procedure
main()


(seed (in "/dev/urandom" (rd 8)))

(setq *S (list 0 0))

(de toss (N)
   (make
      (do N
         (link (if (rand T) "T" "H")) ) ) )

(de comp (A Lst)
   (or
      (for ((I . L) Lst (cddr L) (cdr L))
         (T (fully = A L) I) )
      T ) )

(de score NIL
   (prinl)
   (prinl "Total score:")
   (prinl "^Iuser: " (car *S))
   (prinl "^Icomp: " (cadr *S)) )

(de play NIL
   (let (C (toss 3)  Lst (toss (rand 5 12))  U)
      (prinl)
      (prin "Select toss: ")
      (setq U (in NIL (skip) (line)))
      (prinl "Comp toss: " C)
      (prinl "Toss: " Lst)
      (setq @ (comp U Lst)  @@ (comp C Lst) )
      (cond
         ((< @ @@) (prinl "User win.") (inc *S))
         ((> @ @@) (prinl "Comp win.") (inc (cdr *S)))
         (T (prinl "Draw, lets play again.")) )
      (score) ) )

(de go NIL
   (loop
      (play)
      (T
         (prog
            (prinl)
            (prin "Want play again? Y/N: ")
            (= "N" (uppc (in NIL (char)))) ) ) ) )

(go)


play :- rand1(R), game(R).

game(h) :-
    format('Your turn first!~n'), player_move(P),
    response(P,C), format('I am choosing '), maplist(writec, C), nl,
    rand3(R), maplist(writec,R),
    roll(P, C, R).

game(t) :-
    rand3(C),
    format('I am choosing '), maplist(writec, C), nl,
    player_move(P),
    rand3(R), maplist(writec, R),
    roll(P, C, R).

player_move([P1,P2,P3]) :-
    read_line_to_codes(user_input,Codes),
    maplist(char_code,[P1,P2,P3],Codes).

roll(P, _, P) :- format('~nYou Win!~n'), !.
roll(_, C, C) :- format('~nI Win!~n'), !.

roll(P, C, [_,A,B]) :-
    rand1(R),
    coin_s(R,S),
    write(S),
    roll(P,C,[A,B,R]).

response([A,B,_], [C,A,B]) :- opp(A,C).

writec(A) :- coin_s(A,A1), write(A1).
rand1(R) :- random(V), round(V,I), coin(I,R).
rand3([R1,R2,R3]) :- rand1(R1), rand1(R2), rand1(R3).

coin(0,h). coin(1,t).
coin_s(h, 'H'). coin_s(t, 'T').
opp(h, t). opp(t, h).


from __future__ import print_function
import random
from time import sleep

first = random.choice([True, False])

you = ''
if first:
    me = ''.join(random.sample('HT'*3, 3))
    print('I choose first and will win on first seeing {} in the list of tosses'.format(me))
    while len(you) != 3 or any(ch not in 'HT' for ch in you) or you == me:
        you = input('What sequence of three Heads/Tails will you win with: ')
else:
    while len(you) != 3 or any(ch not in 'HT' for ch in you):
        you = input('After you: What sequence of three Heads/Tails will you win with: ')
    me = ('H' if you[1] == 'T' else 'T') + you[:2]
    print('I win on first seeing {} in the list of tosses'.format(me))

print('Rolling:\n  ', end='')
rolled = ''
while True:
    rolled += random.choice('HT')
    print(rolled[-1], end='')
    if rolled.endswith(you):
        print('\n  You win!')
        break
    if rolled.endswith(me):
        print('\n  I win!')
        break
    sleep(1)    # For dramatic effect


#===============================================================
# Penney's Game Task from Rosetta Code Wiki
# R implementation
#===============================================================

penneysgame <- function() {

  #---------------------------------------------------------------
  # Who goes first?
  #---------------------------------------------------------------

  first <- sample(c("PC", "Human"), 1)

  #---------------------------------------------------------------
  # Determine the sequences
  #---------------------------------------------------------------

  if (first == "PC") { # PC goes first

    pc.seq <- sample(c("H", "T"), 3, replace = TRUE)
    cat(paste("\nI choose first and will win on first seeing", paste(pc.seq, collapse = ""), "in the list of tosses.\n\n"))
    human.seq <- readline("What sequence of three Heads/Tails will you win with: ")
    human.seq <- unlist(strsplit(human.seq, ""))

  } else if (first == "Human") { # Player goest first

    cat(paste("\nYou can choose your winning sequence first.\n\n"))
    human.seq <- readline("What sequence of three Heads/Tails will you win with: ")
    human.seq <- unlist(strsplit(human.seq, "")) # Split the string into characters
    pc.seq <- c(human.seq[2], human.seq[1:2]) # Append second element at the start
    pc.seq[1] <- ifelse(pc.seq[1] == "H", "T", "H") # Switch first element to get the optimal guess
    cat(paste("\nI win on first seeing", paste(pc.seq, collapse = ""), "in the list of tosses.\n"))

  }

  #---------------------------------------------------------------
  # Start throwing the coin
  #---------------------------------------------------------------

  cat("\nThrowing:\n")

  ran.seq <- NULL

  while(TRUE) {

    ran.seq <- c(ran.seq, sample(c("H", "T"), 1)) # Add a new coin throw to the vector of throws

    cat("\n", paste(ran.seq, sep = "", collapse = "")) # Print the sequence thrown so far

    if (length(ran.seq) >= 3 && all(tail(ran.seq, 3) == pc.seq)) {
      cat("\n\nI win!\n")
      break
    }

    if (length(ran.seq) >= 3 && all(tail(ran.seq, 3) == human.seq)) {
      cat("\n\nYou win!\n")
      break
    }

    Sys.sleep(0.5) # Pause for 0.5 seconds

  }
}


#lang racket
;; Penney's Game. Tim Brown 2014-10-15
(define (flip . _) (match (random 2) (0 "H") (1 "T")))

(define (get-human-sequence) ; no sanity checking here!
  (display "choose your winning sequence of 3 H or T > ")
  (drop-right (drop (string-split (string-upcase (read-line)) "") 1) 1))

(define flips->string (curryr string-join "."))

(define (game-on p1 p2)
  (printf "~a chooses: ~a. ~a chooses: ~a~%"
          (car p1) (flips->string (cdr p1)) (car p2) (flips->string (cdr p2)))
  (match-define (list (list name.1 p1.1 p1.2 p1.3) (list name.2 p2.1 p2.2 p2.3)) (list p1 p2))
  (let turn ((seq null))
    (match seq
      [(list-rest (== p1.3) (== p1.2) (== p1.1) _) name.1]
      [(list-rest (== p2.3) (== p2.2) (== p2.1) _) name.2]
      [else
       (let* ((flp (flip)) (seq+ (cons flp else)))
         (printf "new-flip: ~a -> ~a~%" flp (flips->string (reverse seq+))) (turn seq+))])))

(define (play-game)
  (define-values
    (player-1 player-2)
    (match (flip)
      ["H" (printf "Human chooses first: ")
           (define p1 (cons 'Hom-Sap (get-human-sequence)))
           (values p1 (cons 'Computer
                            (match p1
                              [(list _ f1 (and f2 (app (match-lambda ("H" "T") ("T" "H")) ¬f2)) _)
                               (list ¬f2 f1 f2)])))]
      ["T" (printf "Computer chooses first. ")
           (define p1 (cons 'Computer (build-list 3 flip)))
           (printf "~a chooses: ~a~%" (car p1) (flips->string (cdr p1)))
           (values p1 (cons 'Hom-Sap (get-human-sequence)))]))
  (printf "~a wins!~%" (game-on player-1 player-2)))


enum Coin <Heads Tails>;
enum Yay <Yay Good Super Hah Ooh Yipee Sweet Cool Yes Haha>;
enum Boo <Drat Darn Crumb Oops Rats Bah Criminy Argh Shards>;
enum Bozo «'Dude' 'Cha' 'Bzzt' 'Hey' 'Silly dilly' 'Say what!?' 'You numbskull'»;

sub flipping {
    for 1..4 {
        print "-\b";  sleep .1;
        print "\\\b"; sleep .1;
        print "|\b";  sleep .1;
        print "/\b";  sleep .1;
    }
}

sub your-choice($p is copy) {
    loop (my @seq; @seq != 3; $p = "{Bozo.pick}! Please pick exactly 3: ") {
        @seq = prompt($p).uc.comb(/ H | T /).map: {
            when 'H' { Heads }
            when 'T' { Tails }
        }
    }
    @seq;
}

repeat until prompt("Wanna play again? ").lc ~~ /^n/ {
    my $mefirst = Coin.roll;
    print tc "$mefirst I start, {Coin(+!$mefirst).lc} you start, flipping...\n\t";
    flipping;
    say my $flip = Coin.roll;

    my @yours;
    my @mine;

    if $flip == $mefirst {
        print "{Yay.pick}! I get to choose first, and I choose: "; sleep 2; say @mine = |Coin.roll(3);
        @yours = your-choice("Now you gotta choose: ");
        while @yours eqv @mine {
            say "{Bozo.pick}! We'd both win at the same time if you pick that!";
            @yours = your-choice("Pick something different from me: ");
        }
        say "So, you'll win if we see: ", @yours;
    }
    else {
        @yours = your-choice("{Boo.pick}! First you choose: ");
        say "OK, you'll win if we see: ", @yours;
        print "In that case, I'll just randomly choose: "; sleep 2; say @mine = Coin(+!@yours[1]), |@yours[0,1];
    }

    sub check($a,$b,$c) {
        given [$a,$b,$c] {
            when @mine  { say "\n{Yay.pick}, I win, and you lose!"; Nil }
            when @yours { say "\n{Boo.pick}, you win, but I'll beat you next time!"; Nil }
            default     { Coin.roll }
        }
    }

    sleep 1;
    say < OK! Ready? Right... So... Yo!>.pick;
    sleep .5;
    say ("Pay attention now!",
        "Watch closely!",
        "Let's do it...",
        "You feeling lucky?",
        "No way you gonna win this...",
        "Can I borrow that coin again?").pick;
    sleep 1;
    print "Here we go!\n\t";
    for |Coin.roll(3), &check ...^ :!defined {
        flipping;
        print "$_ ";
    }
}


/*REXX program plays/simulates  Penney's Game,  a  two─player  coin toss sequence game. */
__= copies('─', 9)                               /*literal for eye─catching fence.      */
signal on halt                                   /*a clean way out if  CLBF  quits.     */
parse arg # seed .                               /*obtain optional arguments from the CL*/
if #==''  | #==","     then #= 3                 /*Not specified?  Then use the default.*/
if datatype(seed,'W')  then call random ,,seed   /*use seed for RANDOM #s repeatability.*/
wins=0;    do games=1                            /*simulate a number of Penney's games. */
           call game                             /*simulate a single inning of a game.  */
           end   /*games*/                       /*keep at it until  QUIT  or  halt.    */
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
halt:  say;   say __  "Penney's Game was halted.";   say;   exit 13
r:     arg ,$;       do  arg(1);    $=$ || random(100, 9991) // 2;   end;         return $
s:     if arg(1)==1  then return arg(3);   return word(arg(2) 's',1)       /*pluralizer.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
game:  @.=;  [email protected].                                 /*the coin toss sequence so far. */
       toss1= r(1)                                     /*result:   0=computer,   1=CBLF.*/
       if \toss1  then call randComp                   /*maybe let the computer go first*/
       if  toss1  then say __ "You win the first toss, so you pick your sequence first."
                  else say __ "The computer won first toss, the pick was: "    @.comp
                       call prompter                   /*get the human's guess from C.L.*/
                       call randComp                   /*get computer's guess if needed.*/
                                                       /*CBLF:  carbon-based life form. */
       say __  "      your pick:"  @.CBLF              /*echo human's pick to terminal. */
       say __  "computer's pick:"  @.comp              /*  "  comp.'s   "   "     "     */
       say                                             /* [↓]  flip the coin 'til a win.*/
             do  flips=1  until pos(@.CBLF, tosses)\==0   |   pos(@.comp, tosses)\==0
             tosses= tosses || translate( r(1), 'HT', 10)
             end   /*flips*/                           /* [↑]   this is a flipping coin,*/
                                                       /* [↓] series of tosses*/
       say __ "The tossed coin series was: "   tosses
       say
       @@@="won this toss with "   flips   ' coin tosses.'
       if pos(@.CBLF,tosses)\==0  then do;  say __  "You"  @@@;  wins=wins+1;  end
                                  else      say __  "The computer"  @@@
       _=wins;  if _==0  then _='no'
       say __ "You've won"  _  "game"s(wins)  'out of ' games"."
       say;  say copies('╩╦', 79 % 2)'╩';   say
       return
/*──────────────────────────────────────────────────────────────────────────────────────*/
prompter: oops= __ 'Oops!  ';            a=            /*define some handy REXX literals*/
          @a_z= 'ABCDEFG-IJKLMNOPQRS+UVWXYZ'           /*the extraneous alphabetic chars*/
          p=__ 'Pick a sequence of'  #  "coin tosses of  H or T (Heads or Tails) or Quit:"
             do  until  ok;   say;  say p;  pull a     /*uppercase the answer.          */
             if abbrev('QUIT', a, 1)  then exit 1      /*the human wants to  quit.      */
             a= space( translate(a,,@a_z',./\;:_'), 0) /*elide extraneous characters.   */
             b= translate(a, 10, 'HT');   L= length(a) /*translate ───► bin; get length.*/
             ok= 0                                     /*the response is  OK  (so far). */
                 select                                /*verify the user response.      */
                 when \datatype(b, 'B')  then say oops "Illegal response."
                 when \datatype(a, 'M')  then say oops "Illegal characters in response."
                 when L==0               then say oops "No choice was given."
                 when L<#                then say oops "Not enough coin choices."
                 when L>#                then say oops "Too many coin choices."
                 when [email protected].comp          then say oops "You can't choose the computer's" ,
                                                       "choice: "    @.comp
                 otherwise          ok= 1
                 end   /*select*/
             end       /*until ok*/
          @.CBLF= a;           @.CBLF!= b              /*we have the human's guess now. */
          return
/*──────────────────────────────────────────────────────────────────────────────────────*/
randComp: if @.comp\==''  then return                  /*the computer already has a pick*/
          _= @.CBLF!                                   /* [↓] use best-choice algorithm.*/
          if _\==''  then g= left((\substr(_, min(2, #), 1))left(_, 1)substr(_, 3), #)
            do  until g\[email protected].CBLF!;   g= r(#);   end    /*otherwise, generate a choice.  */
          @.comp= translate(g, 'HT', 10)
          return


Toss = [:Heads, :Tails]

def yourChoice
  puts "Enter your choice (H/T)"
  choice = []
  3.times do
    until (c = $stdin.getc.upcase) == "H" or c == "T"
    end
    choice << (c=="H" ? Toss[0] : Toss[1])
  end
  puts "You chose #{choice.join(' ')}"
  choice
end

loop do
  puts "\n%s I start, %s you start ..... %s" % [*Toss, coin = Toss.sample]
  if coin == Toss[0]
    myC = Toss.shuffle << Toss.sample
    puts "I chose #{myC.join(' ')}"
    yC = yourChoice
  else
    yC = yourChoice
    myC = Toss - [yC[1]] + yC.first(2)
    puts "I chose #{myC.join(' ')}"
  end

  seq = Array.new(3){Toss.sample}
  print seq.join(' ')
  loop do
    puts "\n I win!" or break   if seq == myC
    puts "\n You win!" or break if seq == yC
    seq.push(Toss.sample).shift
    print " #{seq[-1]}"
  end
end


extern crate rand;

use std::io::{stdin, stdout, Write};
use std::thread;
use std::time::Duration;

use rand::Rng;

fn toss_coin<R: Rng>(rng: &mut R, print: bool) -> char {
    let c = if rng.gen() { 'H' } else { 'T' };
    if print {
        print!("{}", c);
        stdout().flush().expect("Could not flush stdout");
    }
    c
}

fn gen_sequence<R: Rng>(rng: &mut R, seed: Option<&str>) -> String {
    let mut seq = String::new();
    match seed {
        Some(s) => {
            let mut iter = s.chars();
            let c0 = iter.next().unwrap();
            let next = if c0 == 'H' { 'T' } else { 'H' };
            seq.push(next);
            seq.push(c0);
            seq.push(iter.next().unwrap());
        }
        None => {
            for _ in 0..3 {
                seq.push(toss_coin(rng, false))
            }
        }
    }
    seq
}

fn read_sequence(used_seq: Option<&str>) -> String {
    let mut seq = String::new();
    loop {
        seq.clear();
        println!("Please, enter sequence of 3 coins: H (heads) or T (tails): ");
        stdin().read_line(&mut seq).expect("failed to read line");
        seq = seq.trim().to_uppercase();
        // do the cheapest test first
        if seq.len() == 3
            && seq.chars().all(|c| c == 'H' || c == 'T')
            && seq != used_seq.unwrap_or("")
        {
            return seq;
        }

        println!("Please enter correct sequence!");
    }
}

fn main() {
    let mut rng = rand::thread_rng();

    println!("--Penney's game--");
    loop {
        let useq: String;
        let aiseq: String;
        if rng.gen::<bool>() {
            println!("You choose first!");
            useq = read_sequence(None);
            println!("Your sequence: {}", useq);
            aiseq = gen_sequence(&mut rng, Some(&useq));
            println!("My sequence: {}", aiseq);
        } else {
            println!("I choose first!");
            aiseq = gen_sequence(&mut rng, None);
            println!("My sequence: {}", aiseq);
            useq = read_sequence(Some(&aiseq));
            println!("Your sequence: {}", useq);
        }
        println!("Tossing coins...");
        let mut coins = String::new();
        for _ in 0..2 {
            // toss first 2 coins
            coins.push(toss_coin(&mut rng, true));
            thread::sleep(Duration::from_millis(500));
        }
        loop {
            coins.push(toss_coin(&mut rng, true));
            thread::sleep(Duration::from_millis(500));
            if coins.contains(&useq) {
                println!("\nYou win!");
                break;
            }
            if coins.contains(&aiseq) {
                println!("\nI win!");
                break;
            }
        }

        println!(" Play again? 'Y' to play, 'Q' to exit.");
        let mut input = String::new();
        stdin().read_line(&mut input).expect("failed to read line");
        match input.trim_start().chars().next().unwrap() {
            'Y' | 'y' => continue,
            _ => break,
        }
    }
}


package require Tcl 8.6

oo::class create Player {
    variable who seq seen idx

    constructor {name sequence} {
	set who $name
	set seq $sequence
	set seen {}
	set idx end-[expr {[string length $seq] - 1}]
    }

    method pick {} {
	return $seq
    }

    method name {} {
	return $who
    }

    method match {digit} {
	append seen $digit
	return [expr {[string range $seen $idx end] eq $seq}]
    }
}

oo::class create HumanPlayer {
    superclass Player
    constructor {length {otherPlayersSelection ""}} {
	fconfigure stdout -buffering none
	while true {
	    puts -nonewline "What do you pick? (length $length): "
	    if {[gets stdin pick] < 0} exit
	    set pick [regsub -all {[^HT]} [string map {0 H 1 T h H t T} $pick] ""]
	    if {[string length $pick] eq $length} break
	    puts "That's not a legal pick!"
	}
	set name "Human"
	if {[incr ::humans] > 1} {append name " #$::humans"}
	next $name $pick
    }
}

oo::class create RobotPlayer {
    superclass Player
    constructor {length {otherPlayersSelection ""}} {
	if {$otherPlayersSelection eq ""} {
	    set pick ""
	    for {set i 0} {$i < $length} {incr i} {
		append pick [lindex {H T} [expr {int(rand()*2)}]]
	    }
	} else {
	    if {$length != 3} {
		error "lengths other than 3 not implemented"
	    }
	    lassign [split $otherPlayersSelection ""] a b c
	    set pick [string cat [string map {H T T H} $b] $a $b]
	}
	set name "Robot"
	if {[incr ::robots] > 1} {append name " #$::robots"}
	puts "$name picks $pick"
	next $name $pick
    }
}

proc game {length args} {
    puts "Let's play Penney's Game!"

    # instantiate the players
    set picks {}
    set players {}
    while {[llength $args]} {
	set idx [expr {int(rand()*[llength $args])}]
	set p [[lindex $args $idx] new $length {*}$picks]
	set args [lreplace $args $idx $idx]
	lappend players $p
	lappend picks [$p pick]
    }

    # sanity check
    if {[llength $picks] != [llength [lsort -unique $picks]]} {
	puts "Two players picked the same thing; that's illegal"
    }

    # do the game loop
    while 1 {
	set coin [lindex {H T} [expr {int(rand()*2)}]]
	puts "Coin flip [incr counter] is $coin"
	foreach p $players {
	    if {[$p match $coin]} {
		puts "[$p name] has won!"
		return
	    }
	}
    }
}

game 3 HumanPlayer RobotPlayer


#!/bin/bash
main() {
  printf $'Penney\'s Game\n\n'
  printf 'Flipping to see who goes first ... '

  if [[ $(flip) == H ]]; then
    printf 'I do.\n'
    p2=$(choose_sequence)
    printf 'I choose: %s\n' "$p2"
  else
    printf 'You do.\n'
  fi

  while true; do
    read -p 'Enter your three-flip sequence: ' p1
    p1=$(tr a-z A-Z <<<"$p1")
    case "$p1" in
     "$p2") printf 'Sequence must be different from mine\n';;
     [HT][HT][HT]) break;;
     *) printf $'Sequence must be three H\'s or T\'s\n';;
    esac
  done

  if [ -z "$p2" ]; then
    p2=$(choose_sequence "$p1")
    printf 'I choose: %s\n' "$p2"
  fi

  printf '\nHere we go.  %s, you win; %s, I win.\n' "$p1" "$p2"
  printf 'Flips:'

  flips=
  while true; do
    flip=$(flip)
    printf ' %s' "$flip"
    flips+=$flip
    case "$flips" in
      *$p1) printf $'\nYou win!\n'; exit 0;;
      *$p2) printf $'\nI win!\n'; exit 1;;
    esac
  done
}

choose_sequence() {
  local result
  if (( $# )); then
    case "$1" in
      ?[Hh]?) result=T;;
      *) result=H;;
    esac
    result+="${1%?}"
  else
    result=$(flip)$(flip)$(flip)
  fi
  printf '%s\n' "$result"
}

flip() {
  if (( RANDOM % 2 )); then
    printf '%s\n' H
  else
    printf '%s\n' T
  fi
}

main "[email protected]"


Option Explicit

Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Const HT As String = "H T"

Public Sub PenneysGame()
Dim S$, YourSeq$, ComputeSeq$, i&, Seq$, WhoWin$, flag As Boolean

    Do
        S = WhoWillBeFirst(Choice("Who will be first"))
        If S = "ABORT" Then Exit Do
        Debug.Print S; " start"
        YourSeq = Choice("Your sequence", 3)
        If YourSeq Like "*ABORT*" Then Exit Do
        Debug.Print "Your sequence : " & YourSeq
        ComputeSeq = vbNullString
        For i = 1 To 3
            ComputeSeq = ComputeSeq & Random
        Next i
        Debug.Print "Computer sequence : " & ComputeSeq
        Seq = vbNullString
        Do
            Seq = Seq & Random
            Debug.Print Seq
            Sleep 1000
        Loop While Not Winner(ComputeSeq, YourSeq, Seq, WhoWin)
        Debug.Print WhoWin; " win"
        If MsgBox(WhoWin & " win" & vbCrLf & "Play again?", vbYesNo) = vbNo Then flag = True
        Debug.Print ""
    Loop While Not flag
    Debug.Print "Game over"
End Sub

Private Function WhoWillBeFirst(YourChoice As String) As String
Dim S$
    S = Random
    Select Case YourChoice
        Case "ABORT": WhoWillBeFirst = YourChoice
        Case Else:
            WhoWillBeFirst = IIf(S = YourChoice, "You", "Computer")
    End Select
End Function

Private Function Choice(Title As String, Optional Seq As Integer) As String
Dim S$, i&, t$
    If Seq = 0 Then Seq = 1
    t = Title
    For i = 1 To Seq
        S = vbNullString
        Do
            S = InputBox("Choose between H or T : ", t)
            If StrPtr(S) = 0 Then S = "Abort"
            S = UCase(S)
        Loop While S <> "H" And S <> "T" And S <> "ABORT"
        Choice = Choice & S
        t = Title & " " & Choice
        If Choice Like "*ABORT*" Then Exit For
    Next i
End Function

Private Function Random() As String
Randomize Timer
    Random = Split(HT, " ")(CInt(Rnd))
End Function

Private Function Winner(Cs$, Ys$, S$, W$) As Boolean
    If Len(S) < 3 Then
        Winner = False
    Else
        If Right(S, 3) = Cs And Right(S, 3) = Ys Then
            Winner = True
            W = "Computer & you"
        ElseIf Right(S, 3) = Cs And Right(S, 3) <> Ys Then
            Winner = True
            W = "Computer"
        ElseIf Right(S, 3) = Ys And Right(S, 3) <> Cs Then
            Winner = True
            W = "You"
        End If
    End If
End Function


import "random" for Random
import "io" for Stdin, Stdout
import "timer" for Timer
import "/str" for Str

var rand = Random.new()

var optimum = {
    "HHH": "THH", "HHT": "THH", "HTH": "HHT", "HTT": "HHT",
    "THH": "TTH", "THT": "TTH", "TTH": "HTT", "TTT": "HTT"
}

var getUserSequence = Fn.new {
    System.print("A sequence of three H or T should be entered")
    var userSeq
    while (true) {
        System.write("Enter your sequence: ")
        Stdout.flush()
        userSeq = Str.upper(Stdin.readLine())
        if (userSeq.count == 3 && userSeq.all { |c| c == "H" || c == "T" }) break
    }
    return userSeq
}

var getComputerSequence = Fn.new { |userSeq|
    var compSeq
    if (userSeq == "") {
        var chars = List.filled(3, null)
        for (i in 0..2) chars[i] = (rand.int(2) == 0) ? "T" : "H"
        compSeq = chars.join()
    } else {
        compSeq = optimum[userSeq]
    }
    System.print("Computer's sequence: %(compSeq)")
    return compSeq
}

var userSeq
var compSeq
var r = rand.int(2)
if (r == 0) {
    System.print("You go first")
    userSeq = getUserSequence.call()
    System.print()
    compSeq = getComputerSequence.call(userSeq)
} else {
    System.print("Computer goes first")
    compSeq = getComputerSequence.call("")
    System.print()
    userSeq = getUserSequence.call()
}
System.print()
var coins = ""
while (true) {
    var coin = (rand.int(2) == 0) ? "H" : "T"
    coins = coins + coin
    System.print("Coins flipped: %(coins)")
    var len = coins.count
    if (len >= 3) {
        var seq = coins[len-3...len]
        if (seq == userSeq) {
            System.print("\nYou win!")
            return
        } else if (seq == compSeq) {
            System.print("\nCompter wins!")
            return
        }
    }
    Timer.sleep(2000) // wait two seconds for next flip
}


fcn coinToss{ (0).random(2) and "H" or "T" } // (0).random(2) --> 0<=r<2
reg myBet, yourBet;
if(coinToss()=="H"){ // The toss says I go first
   myBet=(3).pump(String,coinToss);
   println("I bet ",myBet);
   yourBet=ask("Your bet of three (H/T): ")[0,3].toUpper();
}else{
   yourBet=ask("Your bet of three (H/T): ")[0,3].toUpper();
   myBet=((yourBet[1]=="H") and "T" or "H") + yourBet[0,2];
   println("I bet ",myBet);
}
print("Flipping: "); coins:="";
while(1){
   print(toss:=coinToss()); coins=coins + toss;
   if(Void!=coins.find(yourBet)){ println(" You win!"); break; }
   if(Void!=coins.find(myBet))  { println(" I win!"); break; }
   // ignore we both won
}


F partitions(n)
   V p = [BigInt(1)] [+] [BigInt(0)] * n
   L(i) 1 .. n
      V k = 0
      L
         k++
         V j = (k * (3 * k - 1)) I/ 2
         I j > i
            L.break
         I k [&] 1
            p[i] += p[i - j]
         E
            p[i] -= p[i - j]
         j = (k * (3 * k + 1)) I/ 2
         I j > i
            L.break
         I k [&] 1
            p[i] += p[i - j]
         E
            p[i] -= p[i - j]
   R p[n]

print(‘Partitions: ’(0.<15).map(x -> partitions(x)))

V start = time:perf_counter()
print(partitions(6666))
print(time:perf_counter() - start)


#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <gmp.h>

mpz_t* partition(uint64_t n) {
	mpz_t *pn = (mpz_t *)malloc((n + 2) * sizeof(mpz_t));
	mpz_init_set_ui(pn[0], 1);
	mpz_init_set_ui(pn[1], 1);
	for (uint64_t i = 2; i < n + 2; i ++) {
		mpz_init(pn[i]);
		for (uint64_t k = 1, penta; ; k++) {
			penta = k * (3 * k - 1) >> 1;
			if (penta >= i) break;
			if (k & 1) mpz_add(pn[i], pn[i], pn[i - penta]);
			else mpz_sub(pn[i], pn[i], pn[i - penta]);
			penta += k;
			if (penta >= i) break;
			if (k & 1) mpz_add(pn[i], pn[i], pn[i - penta]);
			else mpz_sub(pn[i], pn[i], pn[i - penta]);
		}
	}
	mpz_t *tmp = &pn[n + 1];
	for (uint64_t i = 0; i < n + 1; i ++) mpz_clear(pn[i]);
	free(pn);
	return tmp;
}

int main(int argc, char const *argv[]) {
	clock_t start = clock();
	mpz_t *p = partition(6666);
	gmp_printf("%Zd\n", p);
	printf("Elapsed time: %.04f seconds\n",
		(double)(clock() - start) / (double)CLOCKS_PER_SEC);
	return 0;
}


#include <chrono>
#include <iostream>
#include <vector>
#include <gmpxx.h>

using big_int = mpz_class;

big_int partitions(int n) {
    std::vector<big_int> p(n + 1);
    p[0] = 1;
    for (int i = 1; i <= n; ++i) {
        for (int k = 1;; ++k) {
            int j = (k * (3*k - 1))/2;
            if (j > i)
                break;
            if (k & 1)
                p[i] += p[i - j];
            else
                p[i] -= p[i - j];
            j = (k * (3*k + 1))/2;
            if (j > i)
                break;
            if (k & 1)
                p[i] += p[i - j];
            else
                p[i] -= p[i - j];
        }
    }
    return p[n];
}

int main() {
    auto start = std::chrono::steady_clock::now();
    auto result = partitions(6666);
    auto end = std::chrono::steady_clock::now();
    std::chrono::duration<double, std::milli> ms(end - start);
    std::cout << result << '\n';
    std::cout << "elapsed time: " << ms.count() << " milliseconds\n";
}


program Partition_function_P;

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  Velthuis.BigIntegers,
  System.Diagnostics;

var
  p: TArray<BigInteger>;
  pd: TArray<Integer>;

function PartiDiffDiff(n: Integer): Integer;
begin
  if n and 1 = 1 then
    exit((n + 1) div 2);
  Result := n + 1;
end;

function partDiff(n: Integer): Integer;
begin
  if n < 2 then
    exit(1);

  pd[n] := pd[n - 1] + PartiDiffDiff(n - 1);
  Result := pd[n];
end;

procedure partitionP(n: Integer);
begin
  if n < 2 then
    exit;

  var psum: BigInteger := 0;
  for var i := 1 to n do
  begin
    var pdi := partDiff(i);
    if pdi > n then
      Break;

    var sign: Int64 := -1;

    if (i - 1) mod 4 < 2 then
      sign := 1;

    var t: BigInteger := BigInteger(p[n - pdi]) * BigInteger(sign);
    psum := psum + t;
  end;
  p[n] := psum;
end;

begin
  var stopwatch := TStopwatch.Create;
  const n = 6666;
  SetLength(p, n + 1);
  SetLength(pd, n + 1);
  stopwatch.Start;
  p[0] := 1;
  pd[0] := 1;
  p[1] := 1;
  pd[1] := 1;
  for var i := 2 to n do
    partitionP(i);
  stopwatch.Stop;
  writeln(format('p[%d] = %s', [n, p[n].ToString]));
  writeln('Took ', stopwatch.ElapsedMilliseconds, 'ms');
  Readln;
end.


use Bitwise, skip_operators: true

defmodule Partition do
   def init(), do:
      :ets.new :pN, [:set, :named_table, :private]

   def gpentagonals(), do: Stream.unfold {1, 0}, &next/1
   defp next({m, n}) do
      a = case rem m, 2 do
             0 -> div m, 2
             1 -> m
          end
      {n, {m + 1, n + a}}
   end

   def p(0), do: 1
   def p(n) do
      case :ets.lookup :pN, n do
         [{^n, val}] -> val
         [] ->
            {val, _} = gpentagonals()
                       |> Stream.drop(1)
                       |> Stream.take_while(fn m -> m <= n end)
                       |> Stream.map(fn g -> p(n - g) end)
                       |> Enum.reduce({0, 0},
                              fn n, {a, sgn} -> {
                                          a + (if sgn < 2, do: n, else: -n),
                                          band(sgn + 1, 3)
                                          }
                              end)
            :ets.insert :pN, {n, val}
            val
      end
   end
end

Partition.init
IO.puts Partition.p 6666


-mode(compile).

main(_) ->
    ets:new(pN, [set, named_table, protected]),
    io:format("~w~n", [p(6666)]).

p(0) -> 1;
p(N) ->
    case ets:lookup(pN, N) of
        [{N, Pn}] -> Pn;
        [] ->
            Terms = [p(N - G) || G <- gpentagonals(N)],
            Pn = sum_partitions(Terms),
            ets:insert(pN, {N, Pn}),
            Pn
    end.

sum_partitions(Terms) -> sum_partitions(Terms, 0, 0).
sum_partitions([], _, Sum) -> Sum;
sum_partitions([N|Ns], Sgn, Sum) ->
    Summand = case Sgn < 2 of
        true  -> N;
        false -> -N
    end,
    sum_partitions(Ns, (Sgn+1) band 3, Sum + Summand).

gpentagonals(Max) -> gpentagonals(1, Max, [0]).
gpentagonals(M, Max, Ps = [N|_]) ->
    GP = N + case M rem 2 of
                0 -> M div 2;
                1 -> M
             end,
    if
        GP > Max -> tl(lists:reverse(Ps));
        true -> gpentagonals(M + 1, Max, [GP|Ps])
    end.


// PartionP: Nigel Galloway. April 12th., 2021
let pP g=let rec fN i g e l=seq{yield(l,e+i);yield(-l,e+i+g);yield! fN(i+1)(g+2)(e+i+g)(-l)}
         let N,G=Array.create(g+1) 1I,seq{yield (1I,1);yield! fN 1 3 1 1I}|>Seq.takeWhile(fun(_,n)->n<=g)|>List.ofSeq
         seq{2..g}|>Seq.iter(fun p->N.[p]<-G|>List.takeWhile(fun(_,n)->n<=p)|>Seq.fold(fun Σ (n,g)->Σ+n*N.[p-g]) 0I); N.[g]
printfn "666->%A\n\n6666->%A\n\n123456->%A" (pP 666) pP(6666) (pP 123456)


USING: kernel lists lists.lazy math sequences sequences.extras ;

! Compute the nth pentagonal number.
: penta ( n -- m ) [ sq 3 * ] [ - 2/ ] bi ;

! An infinite lazy list of indices to add and subtract in the
! sequence of partitions to find the next P.
: seq ( -- list )
    1 lfrom [ penta 1 - ] <lazy-map> 1 lfrom [ neg penta 1 - ]
    <lazy-map> lmerge ;

! Reduce a sequence by adding two, subtracting two, adding two,
! etc...
: ++-- ( seq -- n ) 0 [ 2/ odd? [ - ] [ + ] if ] reduce-index ;

! Find the next member of the partitions sequence.
: step ( seq pseq -- seq 'pseq )
    dup length [ < ] curry pick swap take-while over <reversed>
    nths ++-- suffix! ;

: partitions ( m -- n )
    [ seq swap [ <= ] curry lwhile list>array ]
    [ V{ 1 } clone swap [ step ] times last nip ] bi ;


Function PartitionsP(n As UInteger) As ULongInt
    ' if n > 416, the result becomes to large for a unsigned 64bit integer
    Dim As ULongInt p(n)
    Dim As UInteger k, j

    p(0) = 1
    For i As UInteger = 1 To n
        k = 0
        While TRUE
            k += 1
            j = (k * (3*k - 1)) \ 2
            If (j > i) Then Exit While
            If (k And 1) Then
                p(i) += p(i - j)
            Else
                p(i) -= p(i - j)
            End If
            'j = (k * (3*k + 1)) \ 2
            j += k
            If (j > i) Then Exit While
            If (k And 1) Then
                p(i) += p(i - j)
            Else
                p(i) -= p(i - j)
            End If
        Wend
    Next i
    Return p(n)
End Function

Print !"\nPartitionsP: ";
For x As UInteger = 0 To 12
    Print PartitionsP(x);"  ";
Next x

Print !"\n\ndone"
Sleep


package main

import (
    "fmt"
    "math/big"
    "time"
)

var p []*big.Int
var pd []int

func partDiffDiff(n int) int {
    if n&1 == 1 {
        return (n + 1) / 2
    }
    return n + 1
}

func partDiff(n int) int {
    if n < 2 {
        return 1
    }
    pd[n] = pd[n-1] + partDiffDiff(n-1)
    return pd[n]
}

func partitionsP(n int) {
    if n < 2 {
        return
    }
    psum := new(big.Int)
    for i := 1; i <= n; i++ {
        pdi := partDiff(i)
        if pdi > n {
            break
        }
        sign := int64(-1)
        if (i-1)%4 < 2 {
            sign = 1
        }
        t := new(big.Int).Mul(p[n-pdi], big.NewInt(sign))
        psum.Add(psum, t)
    }
    p[n] = psum
}

func main() {
    start := time.Now()
    const N = 6666
    p = make([]*big.Int, N+1)
    pd = make([]int, N+1)
    p[0], pd[0] = big.NewInt(1), 1
    p[1], pd[1] = big.NewInt(1), 1
    for n := 2; n <= N; n++ {
        partitionsP(n)
    }
    fmt.Printf("p[%d)] = %d\n", N, p[N])
    fmt.Printf("Took %s\n", time.Since(start))
}


import java.math.BigInteger;

public class PartitionFunction {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        BigInteger result = partitions(6666);
        long end = System.currentTimeMillis();
        System.out.println("P(6666) = " + result);
        System.out.printf("elapsed time: %d milliseconds\n", end - start);
    }

    private static BigInteger partitions(int n) {
        BigInteger[] p = new BigInteger[n + 1];
        p[0] = BigInteger.ONE;
        for (int i = 1; i <= n; ++i) {
            p[i] = BigInteger.ZERO;
            for (int k = 1; ; ++k) {
                int j = (k * (3 * k - 1))/2;
                if (j > i)
                    break;
                if ((k & 1) != 0)
                    p[i] = p[i].add(p[i - j]);
                else
                    p[i] = p[i].subtract(p[i - j]);
                j += k;
                if (j > i)
                    break;
                if ((k & 1) != 0)
                    p[i] = p[i].add(p[i - j]);
                else
                    p[i] = p[i].subtract(p[i - j]);
            }
        }
        return p[n];
    }
}


function p(n){
    var a = new Array(n+1)
    a[0] = 1n

    for (let i = 1; i <= n; i++){
        a[i] = 0n
        for (let k = 1, s = 1; s <= i;){
            a[i] += (k & 1 ? a[i-s]:-a[i-s])
            k > 0 ? (s += k, k = -k):(k = -k+1, s = k*(3*k-1)/2)
        }
    }

    return a[n]
}

var t = Date.now()
console.log("p(6666) = " + p(6666))
console.log("Computation time in ms: ", Date.now() - t)


{-# language DeriveFunctor #-}

------------------------------------------------------------
-- memoization utilities

data Memo a = Node a (Memo a) (Memo a)
  deriving Functor

memo :: Integral a => Memo p -> a -> p
memo (Node a l r) n
  | n == 0 = a
  | odd n = memo l (n `div` 2)
  | otherwise = memo r (n `div` 2 - 1)

nats :: Memo Int
nats = Node 0 ((+1).(*2) <$> nats) ((*2).(+1) <$> nats)

------------------------------------------------------------
-- calculating partitions

partitions :: Memo Integer
partitions = partitionP <$> nats

partitionP :: Int -> Integer
partitionP n
  | n < 2 = 1
  | otherwise = sum $ zipWith (*) signs terms
  where
    terms = [ memo partitions (n - i)
            | i <- takeWhile (<= n) ofsets ]
    signs = cycle [1,1,-1,-1]

ofsets = scanl1 (+) $ mix [1,3..] [1,2..]
  where
    mix a b = concat $ zipWith (\x y -> [x,y]) a b

main = print $ partitionP 6666


def partDiffDiff($n):
  if ($n % 2) == 1 then ($n+1) / 2 else $n+1 end;

# in:  {n, partDiffMemo}
# out: object with possibly updated memoization
def partDiff:
  .n as $n
  | if .partDiffMemo[$n] then .
    elif $n<2 then .partDiffMemo[$n]=1
    else ((.n=($n-1)) | partDiff)
    | .partDiffMemo[$n] = .partDiffMemo[$n-1] + partDiffDiff($n-1)
    end;

# in:  {n, memo, partDiffMemo}
#      where `.memo[i]` memoizes partitions(i)
#      and   `.partDiffMemo[i]` memoizes partDiff(i)
# out: object with possibly updated memoization
def partitionsM:
  .n as $n
  | if .memo[$n] then .
    elif $n<2 then .memo[$n] = 1
    else label $out
    | foreach range(1; $n+2) as $i (.emit = false | .psum = 0;
        if $i > $n then .emit = true
        else ((.n = $i) | partDiff)
	| .partDiffMemo[$i] as $pd
        | if $pd > $n then .emit=true, break $out
          else {psum, emit} as $local  # for restoring relevant state
	  |  ((.n = ($n-$pd)) | partitionsM)
	  | .memo[$n-$pd] as $increment
	  | . + $local                 # restore
          | if (($i-1)%4)<2
            then .psum += $increment
            else .psum -= $increment
            end
	  end
        end;
        select(.emit) )
    | .memo[$n] = .psum
    end ;

def partitionsP:
  . as $n
  | {n: $n, memo:[], partDiffMemo:[]}
  | partitionsM
  | .memo[$n];

# Stretch goal:
6666 | partitionsP


using Memoize

function partDiffDiff(n::Int)::Int
    isodd(n) ? (n+1)÷2 : n+1
end

@memoize function partDiff(n::Int)::Int
    n<2 ? 1 : partDiff(n-1)+partDiffDiff(n-1)
end

@memoize function partitionsP(n::Int)
    T=BigInt
    if n<2
        one(T)
    else
        psum = zero(T)
        for i ∈ 1:n
            pd = partDiff(i)
            if pd>n
                break
            end
            if ((i-1)%4)<2
                psum += partitionsP(n-pd)
            else
                psum -= partitionsP(n-pd)
            end
        end
        psum
    end
end

n=6666
@time println("p($n) = ", partitionsP(n))


PartitionsP /@ Range[15]
PartitionsP[666]
PartitionsP[6666]


import sequtils, strformat, times
import bignum

func partitions(n: int): Int =
  var p = newSeqWith(n + 1, newInt())
  p[0] = newInt(1)
  for i in 1..n:
    var k = 1
    while true:
      var j = k * (3 * k - 1) div 2
      if j > i: break
      if (k and 1) != 0:
        inc p[i], p[i - j]
      else:
        dec p[i], p[i - j]
      j = k * (3 * k + 1) div 2
      if j > i: break
      if (k and 1) != 0:
        inc p[i], p[i - j]
      else:
        dec p[i], p[i - j]
      inc k
  result = p[n]

let t0 = cpuTime()
echo partitions(6666)
echo &"Elapsed time: {(cpuTime() - t0) * 1000:.2f} ms"


use strict;
use warnings;
no warnings qw(recursion);
use Math::AnyNum qw(:overload);
use Memoize;

memoize('partitionsP');
memoize('partDiff');

sub partDiffDiff { my($n) = @_; $n%2 != 0 ? ($n+1)/2 : $n+1 }

sub partDiff { my($n) = @_; $n<2 ? 1 : partDiff($n-1) + partDiffDiff($n-1) }

sub partitionsP {
    my($n) = @_;
    return 1 if $n < 2;

    my $psum = 0;
    for my $i (1..$n) {
        my $pd = partDiff($i);
        last if $pd > $n;
        if ( (($i-1)%4) < 2 ) { $psum += partitionsP($n-$pd) }
        else                  { $psum -= partitionsP($n-$pd) }
    }
    return $psum
}

print partitionsP($_) . ' ' for 0..25; print "\n";
print partitionsP(6666) . "\n";


with javascript_semantics
function partDiffDiff(integer n)
    return (n+1)/(1+and_bits(n,1))
end function

sequence pd = {1}
function partDiff(integer n)
    while n>length(pd) do
        pd &= pd[$] + partDiffDiff(length(pd))
    end while
    return pd[max(1,n)]
end function

include mpfr.e

sequence pn = {mpz_init(1)}
function partitionsP(integer n)
    mpz res = mpz_init(1)
    while n>length(pn) do
        integer nn = length(pn)+1
        mpz psum = mpz_init(0)
        for i=1 to nn do
            integer pd = partDiff(i)
            if pd>nn then exit end if
            integer sgn = iff(remainder(i-1,4)<2 ? 1 : -1)
            mpz pnmpd = pn[max(1,nn-pd)]
            if sgn=-1 then
                mpz_sub(psum,psum,pnmpd)
            else
                mpz_add(psum,psum,pnmpd)
            end if
        end for
        pn = append(pn,psum)
    end while
    return pn[max(1,n)]
end function

atom t0 = time()
integer n=6666
printf(1,"p(%d) = %s (%s)\n",{n,mpz_get_str(partitionsP(n)),elapsed(time()-t0)})


(de gpentagonals (Max)
   (make
      (let (N 0  M 1)
         (loop
            (inc 'N (if (=0 (& M 1)) (>> 1 M) M))
            (T (> N Max))
            (link N)
            (inc 'M)))))

(de p (N)
   (cache '(NIL) N
      (if (=0 N)
         1
         (let (Sum 0  Sgn 0)
            (for G (gpentagonals N)
               ((if (< Sgn 2) 'inc 'dec) 'Sum (p (- N G)))
               (setq Sgn (& 3 (inc Sgn))))
            Sum))))


from itertools import islice

def posd():
    "diff between position numbers. 1, 2, 3... interleaved with  3, 5, 7..."
    count, odd = 1, 3
    while True:
        yield count
        yield odd
        count, odd = count + 1, odd + 2

def pos_gen():
    "position numbers. 1 3 2 5 7 4 9 ..."
    val = 1
    diff = posd()
    while True:
        yield val
        val += next(diff)

def plus_minus():
    "yield (list_offset, sign) or zero for Partition calc"
    n, sign = 0, [1, 1]
    p_gen = pos_gen()
    out_on = next(p_gen)
    while True:
        n += 1
        if n == out_on:
            next_sign = sign.pop(0)
            if not sign:
                sign = [-next_sign] * 2
            yield -n, next_sign
            out_on = next(p_gen)
        else:
            yield 0

def part(n):
    "Partition numbers"
    p = [1]
    p_m = plus_minus()
    mods = []
    for _ in range(n):
        next_plus_minus = next(p_m)
        if next_plus_minus:
            mods.append(next_plus_minus)
        p.append(sum(p[offset] * sign for offset, sign in mods))
    return p[-1]

print("(Intermediaries):")
print("    posd:", list(islice(posd(), 10)))
print("    pos_gen:", list(islice(pos_gen(), 10)))
print("    plus_minus:", list(islice(plus_minus(), 15)))
print("\nPartitions:", [part(x) for x in range(15)])


#lang racket

(require math/number-theory)

(define σ
  (let ((memo (make-hash)))
    (λ (z)
      (hash-ref! memo z
                 (λ () (apply + (divisors z)))))))

(define p
  (let ((memo (make-hash '((0 . 1)))))
    (λ (n)
      (hash-ref!
       memo n
       (λ ()
         (let ((r (if (zero? n) 1
             (/ (for/sum ((k (in-range (sub1 n) -1 -1)))
                  (* (σ (- n k))
                     (p k)))
                n))))
           (when (zero? (modulo n 1000)) (displayln (cons n r) (current-error-port)))
           r))))))

(map p (range 1 30))
(p 666)
(p 1000)
(p 10000)


/*REXX program calculates and displays a specific value (or a range of)  partitionsP(N).*/
numeric digits 1000                              /*able to handle some ginormous numbers*/
parse arg lo hi .                                /*obtain optional arguments from the CL*/
if lo=='' | lo==","  then lo=  0                 /*Not specified?  Then use the default.*/
if hi=='' | hi==","  then hi= lo                 /* "      "         "   "   "     "    */
@.= 0;    @.0= 1; @.1= 1; @.2= 2; @.3= 3; @.4= 5 /*assign default value and low values. */
!.= @.;   !.1= 1; !.3= 1; !.5= 1; !.7= 1; !.9= 1 /*assign default value and even digits.*/
w= length( commas(hi) )                          /*W:  is used for aligning the index.  */

       do j=lo  to hi                            /*compute a range of  partitionsP.     */
       say right( commas(j), w)    ' '     commas( partP(j) )
       end   /*j*/
exit 0                                           /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
commas: parse arg ?;  do jc=length(?)-3  to 1  by -3; ?=insert(',', ?, jc); end;  return ?
/*──────────────────────────────────────────────────────────────────────────────────────*/
partP:  procedure expose @. !.;  parse arg n     /*obtain number (index) for computation*/
        if @.n\==0  then return @.n              /*Is it already computed?   Return it. */
        #= 0                                               /*initialize part  P  number.*/
               do k=1  for n;  z= n  -  (k*3 - 1) * k % 2  /*compute the partition P num*/
               if z<0  then leave                          /*Is Z negative?  Then leave.*/
               if @.z==0  then x= partP(z)                 /*use recursion if not known.*/
                          else x= @.z                      /*use the pre─computed number*/
               z= z - k                                    /*subtract index (K) from Z. */
               if z<0     then y= 0                        /*Is Z negative? Then set Y=0*/
                          else if @.z==0  then y= partP(z) /*use recursion if not known.*/
                                          else y= @.z      /*use the pre─computed number*/
               if k//2    then #= # +  x + y               /*Odd? Then   sum    X and Y.*/
                          else #= # - (x + y)              /*Even?  "  subtract "  "  " */
               end   /*k*/
        @.n= #;                   return #       /*define and return partitionsP of  N. */


// [dependencies]
// rug = "1.11"

use rug::Integer;

fn partitions(n: usize) -> Integer {
    let mut p = Vec::with_capacity(n + 1);
    p.push(Integer::from(1));
    for i in 1..=n {
        let mut num = Integer::from(0);
        let mut k = 1;
        loop {
            let mut j = (k * (3 * k - 1)) / 2;
            if j > i {
                break;
            }
            if (k & 1) == 1 {
                num += &p[i - j];
            } else {
                num -= &p[i - j];
            }
            j += k;
            if j > i {
                break;
            }
            if (k & 1) == 1 {
                num += &p[i - j];
            } else {
                num -= &p[i - j];
            }
            k += 1;
        }
        p.push(num);
    }
    p[n].clone()
}

fn main() {
    use std::time::Instant;
    let n = 6666;
    let now = Instant::now();
    let result = partitions(n);
    let time = now.elapsed();
    println!("P({}) = {}", n, result);
    println!("elapsed time: {} microseconds", time.as_micros());
}


import BigInt

func partitions(n: Int) -> BigInt {
  var p = [BigInt(1)]

  for i in 1...n {
    var num = BigInt(0)
    var k = 1

    while true {
      var j = (k * (3 * k - 1)) / 2

      if j > i {
        break
      }

      if k & 1 == 1 {
        num += p[i - j]
      } else {
        num -= p[i - j]
      }

      j += k

      if j > i {
        break
      }

      if k & 1 == 1 {
        num += p[i - j]
      } else {
        num -= p[i - j]
      }

      k += 1
    }

    p.append(num)
  }

  return p[n]
}

print("partitions(6666) = \(partitions(n: 6666))")


import "/big" for BigInt

var p = []
var pd = []

var partDiffDiff = Fn.new { |n| (n&1 == 1) ? (n + 1)/2 : n + 1 }

var partDiff = Fn.new { |n|
    if (n < 2) return 1
    pd[n] = pd[n-1] + partDiffDiff.call(n-1)
    return pd[n]
}

var partitionsP = Fn.new { |n|
    if (n < 2) return
    var psum = BigInt.zero
    for (i in 1..n) {
        var pdi = partDiff.call(i)
        if (pdi > n) break
        var sign = (i-1)%4 < 2 ? 1 : -1
        psum = psum + p[n-pdi] * sign
    }
    p[n] = psum
}

var start = System.clock
var N = 6666
p = List.filled(N+1, null)
pd = List.filled(N+1, 0)
p[0] = BigInt.one
p[1] = BigInt.one
pd[0] = 1
pd[1] = 1
for (n in 2..N) partitionsP.call(n)
System.print("p[%(N)] = %(p[N])")
System.print("Took %(System.clock - start) seconds")


*        Pathological floating point problems  03/05/2016
PATHOFP  CSECT
         USING  PATHOFP,R13
SAVEAR   B      STM-SAVEAR(R15)
         DC     17F'0'
STM      STM    R14,R12,12(R13)
         ST     R13,4(R15)
         ST     R15,8(R13)
         LR     R13,R15
         LE     F0,=E'2'
         STE    F0,U             u(1)=2
         LE     F0,=E'-4'
         STE    F0,U+4           u(2)=-4
         LA     R6,3             n=3
         LA     R7,U+4           @u(n-1)
         LA     R8,U             @u(n-2)
         LA     R9,U+8           @u(n)
LOOPN    CH     R6,=H'100'       do n=3 to 100
         BH     ELOOPN
         LE     F4,0(R7)         u(n-1)
         LE     F2,=E'1130'      1130
         DER    F2,F4            1130/u(n-1)
         LE     F0,=E'111'       111
         SER    F0,F2            111-1130/u(n-1)
         LE     F2,0(R7)         u(n-1)
         LE     F4,0(R8)         u(n-2)
         MER    F2,F4            u(n-1)*u(n-2)
         LE     F6,=E'3000'      3000
         DER    F6,F2            3000/(u(n-1)*u(n-2))
         AER    F0,F6            111-1130/u(n-1)+3000/(u(n-1)*u(n-2))
         STE    F0,0(R9)         store into u(n)
         XDECO  R6,PG+0          n
         LE     F0,0(R9)         u(n)
         LA     R0,3             number of decimals
         BAL    R14,FORMATF      format(u(n),'F13.3')
         MVC    PG+12(13),0(R1)  put into buffer
         XPRNT  PG,80            print buffer
         LA     R6,1(R6)         n=n+1
         LA     R7,4(R7)         @u(n-1)
         LA     R8,4(R8)         @u(n-2)
         LA     R9,4(R9)         @u(n)
         B      LOOPN
ELOOPN   L      R13,4(0,R13)
         LM     R14,R12,12(R13)
         XR     R15,R15
         BR     R14
         COPY   FORMATF
         LTORG
PG       DC     CL80' '          buffer
U        DS     100E
         YREGS
         YFPREGS
         END    PATHOFP


with Ada.Text_IO;

procedure Converging_Sequence is

   generic
      type Num is digits <>;
      After: Positive;
   procedure Task_1;

   procedure Task_1 is
      package FIO is new Ada.Text_IO.Float_IO(Num);
      package IIO is new Ada.Text_IO.Integer_IO(Integer);

      procedure Output (I: Integer; N: Num) is
      begin
	 IIO.Put(Item => I, Width => 4);
	 FIO.Put(Item => N, Fore => 4, Aft =>  After, Exp => 0);
	 Ada.Text_IO.New_Line;
      end Output;

      Very_Old: Num :=  2.0;
      Old:      Num := -4.0;
      Now:        Num;
   begin
      Ada.Text_IO.Put_Line("Converging Sequence with" & Integer'Image(After) &
			     " digits");
      for I in 3 .. 100 loop
	 Now := 111.0  - 1130.0   /   Old   + 3000.0  /   (Old * Very_Old);
	 Very_Old := Old;
	 Old := Now;
	 if (I < 9) or else (I=20 or I=30 or I=50 or I=100) then
	    Output(I, Now);
	 end if;
      end loop;
      Ada.Text_IO.New_Line;
   end Task_1;

   type Short is digits(8);
   type Long  is digits(16);

   procedure Task_With_Short is new Task_1(Short, 8);
   procedure Task_With_Long  is new Task_1(Long, 16);
begin
   Task_With_Short;
   Task_With_Long;
end Converging_Sequence;