#!/usr/bin/perl -w

# Script to generate sample decks for the "Half in the Bag" trick.
# Phil Carmody, 2018-06-12
# Placed in the public domain, do whatsoever thou wilt therewith.

use strict;
use warnings;

# Select the rule for each of the suits: high/low odd/even all/none
if(scalar(@ARGV)!=4) { die ("need 4 discriminators for H C D S, each h/l/o/e/a/n"); }

my @r=();
my @u=();
my @l=();
my %d=();
for my $s (qw/H C D S/) {
    my $d=shift(@ARGV);
    $d{$s}=$d;
    if ($d eq 'h') { # High, which leaves 7 undecided
	push(@r, map { "$s$_" }(qw/K Q J T 9 8/));
	push(@l, map { "$s$_" }(qw/7/));
	push(@u, map { "$s$_" }(qw/A 2 3 4 5 6/));
    } elsif($d eq 'l') { # Low, which leaves 7 undecided
	push(@r, map { "$s$_" }(qw/A 2 3 4 5 6/));
	push(@l, map { "$s$_" }(qw/7/));
	push(@u, map { "$s$_" }(qw/K Q J T 9 8/));
    } elsif($d eq 'o') { # Odds
	push(@r, map { "$s$_" }(qw/A 3 5 7 9 J K/));
	push(@u, map { "$s$_" }(qw/2 4 6 8 T Q/));
    } elsif($d eq 'e') { # Evens
	push(@r, map { "$s$_" }(qw/2 4 6 8 T Q/));
	push(@u, map { "$s$_" }(qw/A 3 5 7 9 J K/));
    } elsif($d eq 'a') { # All
	push(@r, map { "$s$_" }(qw/A 2 3 4 5 6 7 8 9 T J Q K/));
    } elsif($d eq 'n') { # None
	push(@u, map { "$s$_" }(qw/A 2 3 4 5 6 7 8 9 T J Q K/));
    } else { die("letter $d isn't h/l/o/e/a/n"); }
}

if(scalar(@r)>26) { die("too many ruly cards: @r"); }
if(scalar(@u)>26) { die("too many ruly cards: @u"); }
if(scalar(@l)>0) { printf STDERR ("symmetry breaking with @l:\n"); }
# "Hash entries are returned in an apparently random order."
my %l = map { rand() => $_ }(@l);
@l = values(%l);
while(scalar(@r)<26) {
    print STDERR ("Evaluating discriminator '".
		  substr($l[0],0,1)." ".$d{substr($l[0],0,1)}.
		  "', $l[0] is ruly\n");
    push(@r,shift(@l));
}
while(scalar(@u)<26) {
    print STDERR ("Evaluating discriminator '".
		  substr($l[0],0,1)." ".$d{substr($l[0],0,1)}.
		  "', $l[0] is unruly\n");
    push(@u,shift(@l));
}

my %r = map { rand() => $_ }(@r);
@r = values(%r);
my %u = map { rand() => $_ }(@u);
@u = values(%u);

my @d = map { ($r[$_], $u[$_]) } (0..25);
print((join " ", map { substr($_,0,1); } @d), "\n"),
print((join " ", map { substr($_,1,1); } @d), "\n"),
