<commit_before>mod card {
    use std::fmt;
    use std::iter::AdditiveIterator;
    use std::ops::Add;
    use std::slice;

    pub fn score(hand: Vec<Card>, start_card: Card) -> i32 {
        let mut with_start = hand.clone();
        with_start.push(start_card);
        2 * count_15s(&with_start)
            + 2 * count_pairs(&with_start)
            + score_runs(&with_start)
    }

    fn count_15s(cards: &Vec<Card>) -> i32 {
        power_set(&mut cards.iter()).iter()
            .filter(|ref x| x.iter().map(|ref x| x.rank.value()).sum() == 15)
            .count() as i32
    }

    fn count_pairs(cards: &Vec<Card>) -> i32 {
        power_set(&mut cards.iter()).iter()
            .filter(|&x| x.len() == 2)
            .filter(|ref x| x[0].rank == x[1].rank)
            .count() as i32
    }

    fn score_runs(cards: &Vec<Card>) -> i32 {
        let mut cpy = cards.clone();
        cpy.sort();
        let mut runs = Vec::new();
        let mut run: Vec<Card> = Vec::new();
        for card in cpy.iter() {
            //println!("Looking at {} and {}", card, run);
            if run.len() == 0 || run[run.len()-1].clone().rank + Rank(1) == card.rank {
                run.push(card.clone())
            } else {
                if run.len() > 1 {
                    runs.push(run);
                }
                run = Vec::new();
                run.push(card.clone());
            }
        }
        if run.len() > 1 {
            runs.push(run);
        }
        runs.iter()
            .map(|x| x.len() as i32)
            .sum()
    }

    fn power_set<'a, T: Clone + 'a>(items: &mut slice::Iter<'a,T>) -> Vec<Vec<T>> {
        let mut power = Vec::new();
        match items.next() {
            None       => power.push(Vec::new()),
            Some(item) => {
                for mut set in power_set(items).into_iter() {
                    power.push(set.clone());
                    set.push(item.clone());
                    power.push(set);
                }
            }
        }
        power
    }

    #[derive(PartialEq, Eq, PartialOrd, Ord, Clone)]
    struct Card {
        rank: Rank,
        suit: Suit,
    }

    pub fn new(rank: i32, suit: char) -> Card {
        Card{rank: Rank(rank), suit: from_char(suit)}
    }

    impl fmt::Show for Card {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            write!(f, "{}{}", self.rank, self.suit)
        }
    }

    #[derive(PartialEq, Eq, PartialOrd, Ord, Clone)]
    enum Suit {
        Spades,
        Hearts,
        Clubs,
        Diamonds,
    }

    impl Suit {
        pub fn to_char(&self) -> char {
            match *self {
                Suit::Spades   => 'S',
                Suit::Hearts   => 'H',
                Suit::Diamonds => 'D',
                Suit::Clubs    => 'C',
            }
        }
    }

    impl fmt::Show for Suit {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                    write!(f, "{}", self.to_char())
        }
    }

    pub fn from_char(a: char) -> Suit {
        match a {
            'S'=> Suit::Spades,
            'H'=> Suit::Hearts,
            'C'=> Suit::Clubs,
            'D'=> Suit::Diamonds,
            _  => panic!("Not a suit")
        }
    }

    #[derive(PartialEq, Eq, PartialOrd, Ord, Clone)]
    struct Rank(i32);

    impl fmt::Show for Rank {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            let value = match *self {
                Rank(13) => "K".to_string(),
                Rank(12) => "Q".to_string(),
                Rank(11) => "J".to_string(),
                Rank(aa) => aa.to_string(),
            };
            write!(f, "{}", value)
        }
    }

    impl Rank {
        fn value(&self) -> i32 {
            let Rank(x) = *self;
            if x > 10 {
                10
            } else {
                x
            }
        }
    }

    impl Add for Rank {
        type Output = Rank;

        fn add(self, rhs: Rank) -> Rank {
            let (Rank(lh), Rank(rh)) = (self, rhs);
            Rank(lh + rh)
        }
    }

}

fn main() {
    let cards = vec![
        card::new(12, 'H'),
        card::new(11, 'S'),
        card::new(10, 'S'),
        card::new(5, 'C'),
        ];
    println!("{}", card::score(cards, card::new(4, 'D')));
}<commit_msg>Score flush. Print score pretty.<commit_after>mod card {
    use std::fmt;
    use std::iter::AdditiveIterator;
    use std::ops::Add;
    use std::slice;

    pub fn score(hand: Vec<Card>, start_card: Card, crib: bool) -> i32 {
        let mut with_start = hand.clone();
        with_start.push(start_card.clone());
        let fifteens = count_15s(&with_start);
        let pairs = count_pairs(&with_start);
        let flushpoints = score_flushes(&hand, start_card, crib);
        let runpoints = score_runs(&with_start);
        println!("fifteens: {}", fifteens);
        println!("pairs:    {}", pairs);
        println!("flush:    {} points", flushpoints);
        println!("runs:     {} points", runpoints);
        2 * fifteens
            + 2 * pairs
            + flushpoints
            + runpoints
    }

    fn count_15s(cards: &Vec<Card>) -> i32 {
        power_set(&mut cards.iter()).iter()
            .filter(|ref x| x.iter().map(|ref x| x.rank.value()).sum() == 15)
            .count() as i32
    }

    fn count_pairs(cards: &Vec<Card>) -> i32 {
        power_set(&mut cards.iter()).iter()
            .filter(|&x| x.len() == 2)
            .filter(|ref x| x[0].rank == x[1].rank)
            .count() as i32
    }

    fn score_runs(cards: &Vec<Card>) -> i32 {
        let mut cpy = cards.clone();
        cpy.sort();
        let mut runs = Vec::new();
        let mut run: Vec<Card> = Vec::new();
        for card in cpy.iter() {
            //println!("Looking at {} and {}", card, run);
            if run.len() == 0 || run[run.len()-1].clone().rank + Rank(1) == card.rank {
                run.push(card.clone())
            } else {
                if run.len() > 1 {
                    runs.push(run);
                }
                run = Vec::new();
                run.push(card.clone());
            }
        }
        if run.len() > 1 {
            runs.push(run);
        }
        runs.iter()
            .map(|x| x.len() as i32)
            .sum()
    }

    fn score_flushes(cards: &Vec<Card>, start: Card, crib: bool) -> i32 {
        let mut cards = cards.clone();
        let expected_suit = cards.pop().unwrap().suit;
        let four_flush = cards.iter()
            .fold(true, |so_far, next| so_far && next.suit == expected_suit);
        match (four_flush, start.suit==expected_suit, !crib) {
            (true, true, _)      => 5,
            (true, false, true)  => 4,
            (true, false, false) => 0,
            (false, _, _)        => 0,
        }
    }

    fn power_set<'a, T: Clone + 'a>(items: &mut slice::Iter<'a,T>) -> Vec<Vec<T>> {
        let mut power = Vec::new();
        match items.next() {
            None       => power.push(Vec::new()),
            Some(item) => {
                for mut set in power_set(items).into_iter() {
                    power.push(set.clone());
                    set.push(item.clone());
                    power.push(set);
                }
            }
        }
        power
    }

    #[derive(PartialEq, Eq, PartialOrd, Ord, Clone)]
    struct Card {
        rank: Rank,
        suit: Suit,
    }

    pub fn new(rank: i32, suit: char) -> Card {
        Card{rank: Rank(rank), suit: from_char(suit)}
    }

    impl fmt::Show for Card {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            write!(f, "{}{}", self.rank, self.suit)
        }
    }

    #[derive(PartialEq, Eq, PartialOrd, Ord, Clone)]
    enum Suit {
        Spades,
        Hearts,
        Clubs,
        Diamonds,
    }

    impl Suit {
        pub fn to_char(&self) -> char {
            match *self {
                Suit::Spades   => 'S',
                Suit::Hearts   => 'H',
                Suit::Diamonds => 'D',
                Suit::Clubs    => 'C',
            }
        }
    }

    impl fmt::Show for Suit {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                    write!(f, "{}", self.to_char())
        }
    }

    pub fn from_char(a: char) -> Suit {
        match a {
            'S'=> Suit::Spades,
            'H'=> Suit::Hearts,
            'C'=> Suit::Clubs,
            'D'=> Suit::Diamonds,
            _  => panic!("Not a suit")
        }
    }

    #[derive(PartialEq, Eq, PartialOrd, Ord, Clone)]
    struct Rank(i32);

    impl fmt::Show for Rank {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            let value = match *self {
                Rank(13) => "K".to_string(),
                Rank(12) => "Q".to_string(),
                Rank(11) => "J".to_string(),
                Rank(aa) => aa.to_string(),
            };
            write!(f, "{}", value)
        }
    }

    impl Rank {
        fn value(&self) -> i32 {
            let Rank(x) = *self;
            if x > 10 {
                10
            } else {
                x
            }
        }
    }

    impl Add for Rank {
        type Output = Rank;

        fn add(self, rhs: Rank) -> Rank {
            let (Rank(lh), Rank(rh)) = (self, rhs);
            Rank(lh + rh)
        }
    }

}

fn main() {
    let cards = vec![
        card::new(5, 'H'),
        card::new(5, 'D'),
        card::new(5, 'C'),
        card::new(11, 'S'),
        ];
    println!("{}", card::score(cards, card::new(5, 'S'), false));
}
{'fraction_non_alphanumeric': 0.16927736006683375, 'fraction_numerical': 0.011695906432748537, 'mean_word_length': 1.3930534732633684, 'pattern_counts': {'":': 0, '<': 22, '<?xml version=': 0, '>': 89, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2229466', 'n_tokens_mistral': 3195, 'n_tokens_neox': 3061, 'n_words': 691}