Merge branch 'master' of git://projects.elasticdog.com/git/factor
commit
2b042d7cb7
|
@ -14,7 +14,7 @@ $nl
|
||||||
|
|
||||||
HELP: sorted-index
|
HELP: sorted-index
|
||||||
{ $values { "obj" object } { "seq" "a sorted sequence" } { "i" "an index, or " { $link f } } }
|
{ $values { "obj" object } { "seq" "a sorted sequence" } { "i" "an index, or " { $link f } } }
|
||||||
{ $description "Outputs the index and value of the element closest to " { $snippet "elt" } " in the sequence. See " { $link search } " for details." }
|
{ $description "Outputs the index of the element closest to " { $snippet "elt" } " in the sequence. See " { $link search } " for details." }
|
||||||
{ $notes "If the sequence has at least one element, this word always outputs a valid index, because it finds the closest match, not necessarily an exact one. In this respect its behavior differs from " { $link index } "." } ;
|
{ $notes "If the sequence has at least one element, this word always outputs a valid index, because it finds the closest match, not necessarily an exact one. In this respect its behavior differs from " { $link index } "." } ;
|
||||||
|
|
||||||
{ index index-from last-index last-index-from sorted-index } related-words
|
{ index index-from last-index last-index-from sorted-index } related-words
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1 @@
|
||||||
|
Aaron Schaefer
|
|
@ -0,0 +1,16 @@
|
||||||
|
USING: accessors poker poker.private tools.test ;
|
||||||
|
IN: poker.tests
|
||||||
|
|
||||||
|
[ 134236965 ] [ "KD" >ckf ] unit-test
|
||||||
|
[ 529159 ] [ "5s" >ckf ] unit-test
|
||||||
|
[ 33589533 ] [ "jc" >ckf ] unit-test
|
||||||
|
|
||||||
|
|
||||||
|
[ 7462 ] [ "7C 5D 4H 3S 2C" <hand> value>> ] unit-test
|
||||||
|
[ 1601 ] [ "KD QS JC TH 9S" <hand> value>> ] unit-test
|
||||||
|
[ 9 ] [ "6C 5C 4C 3C 2C" <hand> value>> ] unit-test
|
||||||
|
[ 1 ] [ "AC KC QC JC TC" <hand> value>> ] unit-test
|
||||||
|
|
||||||
|
[ "High Card" ] [ "7C 5D 4H 3S 2C" <hand> >value ] unit-test
|
||||||
|
[ "Straight" ] [ "KD QS JC TH 9S" <hand> >value ] unit-test
|
||||||
|
[ "Straight Flush" ] [ "6C 5C 4C 3C 2C" <hand> >value ] unit-test
|
|
@ -0,0 +1,181 @@
|
||||||
|
! Copyright (c) 2009 Aaron Schaefer.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: accessors ascii binary-search combinators kernel locals math
|
||||||
|
math.bitwise math.order poker.arrays sequences splitting ;
|
||||||
|
IN: poker
|
||||||
|
|
||||||
|
! The algorithm used is based on Cactus Kev's Poker Hand Evaluator:
|
||||||
|
! http://www.suffecool.net/poker/evaluator.html
|
||||||
|
|
||||||
|
<PRIVATE
|
||||||
|
|
||||||
|
! Bitfield Format for Card Values:
|
||||||
|
|
||||||
|
! +-------------------------------------+
|
||||||
|
! | xxxbbbbb bbbbbbbb ssssrrrr xxpppppp |
|
||||||
|
! +-------------------------------------+
|
||||||
|
! xxxAKQJT 98765432 CDHSrrrr xxpppppp
|
||||||
|
! +-------------------------------------+
|
||||||
|
! | 00001000 00000000 01001011 00100101 | King of Diamonds
|
||||||
|
! | 00000000 00001000 00010011 00000111 | Five of Spades
|
||||||
|
! | 00000010 00000000 10001001 00011101 | Jack of Clubs
|
||||||
|
|
||||||
|
! p = prime number value of rank (deuce = 2, trey = 3, four = 5, ..., ace = 41)
|
||||||
|
! r = rank of card (deuce = 0, trey = 1, four = 2, ..., ace = 12)
|
||||||
|
! s = bit turned on depending on suit of card
|
||||||
|
! b = bit turned on depending on rank of card
|
||||||
|
! x = bit turned off, not used
|
||||||
|
|
||||||
|
CONSTANT: CLUB 8
|
||||||
|
CONSTANT: DIAMOND 4
|
||||||
|
CONSTANT: HEART 2
|
||||||
|
CONSTANT: SPADE 1
|
||||||
|
|
||||||
|
CONSTANT: DEUCE 0
|
||||||
|
CONSTANT: TREY 1
|
||||||
|
CONSTANT: FOUR 2
|
||||||
|
CONSTANT: FIVE 3
|
||||||
|
CONSTANT: SIX 4
|
||||||
|
CONSTANT: SEVEN 5
|
||||||
|
CONSTANT: EIGHT 6
|
||||||
|
CONSTANT: NINE 7
|
||||||
|
CONSTANT: TEN 8
|
||||||
|
CONSTANT: JACK 9
|
||||||
|
CONSTANT: QUEEN 10
|
||||||
|
CONSTANT: KING 11
|
||||||
|
CONSTANT: ACE 12
|
||||||
|
|
||||||
|
CONSTANT: STRAIGHT_FLUSH 1
|
||||||
|
CONSTANT: FOUR_OF_A_KIND 2
|
||||||
|
CONSTANT: FULL_HOUSE 3
|
||||||
|
CONSTANT: FLUSH 4
|
||||||
|
CONSTANT: STRAIGHT 5
|
||||||
|
CONSTANT: THREE_OF_A_KIND 6
|
||||||
|
CONSTANT: TWO_PAIR 7
|
||||||
|
CONSTANT: ONE_PAIR 8
|
||||||
|
CONSTANT: HIGH_CARD 9
|
||||||
|
|
||||||
|
CONSTANT: RANK_STR { "2" "3" "4" "5" "6" "7" "8" "9" "T" "J" "Q" "K" "A" }
|
||||||
|
|
||||||
|
CONSTANT: VALUE_STR { "" "Straight Flush" "Four of a Kind" "Full House" "Flush"
|
||||||
|
"Straight" "Three of a Kind" "Two Pair" "One Pair" "High Card" }
|
||||||
|
|
||||||
|
: card-rank-prime ( rank -- n )
|
||||||
|
RANK_STR index { 2 3 5 7 11 13 17 19 23 29 31 37 41 } nth ;
|
||||||
|
|
||||||
|
: card-rank ( rank -- n )
|
||||||
|
{
|
||||||
|
{ "2" [ DEUCE ] }
|
||||||
|
{ "3" [ TREY ] }
|
||||||
|
{ "4" [ FOUR ] }
|
||||||
|
{ "5" [ FIVE ] }
|
||||||
|
{ "6" [ SIX ] }
|
||||||
|
{ "7" [ SEVEN ] }
|
||||||
|
{ "8" [ EIGHT ] }
|
||||||
|
{ "9" [ NINE ] }
|
||||||
|
{ "T" [ TEN ] }
|
||||||
|
{ "J" [ JACK ] }
|
||||||
|
{ "Q" [ QUEEN ] }
|
||||||
|
{ "K" [ KING ] }
|
||||||
|
{ "A" [ ACE ] }
|
||||||
|
} case ;
|
||||||
|
|
||||||
|
: card-suit ( suit -- n )
|
||||||
|
{
|
||||||
|
{ "C" [ CLUB ] }
|
||||||
|
{ "D" [ DIAMOND ] }
|
||||||
|
{ "H" [ HEART ] }
|
||||||
|
{ "S" [ SPADE ] }
|
||||||
|
} case ;
|
||||||
|
|
||||||
|
: card-rank-bit ( rank -- n )
|
||||||
|
RANK_STR index 1 swap shift ;
|
||||||
|
|
||||||
|
: card-bitfield ( rank rank suit rank -- n )
|
||||||
|
{
|
||||||
|
{ card-rank-bit 16 }
|
||||||
|
{ card-suit 12 }
|
||||||
|
{ card-rank 8 }
|
||||||
|
{ card-rank-prime 0 }
|
||||||
|
} bitfield ;
|
||||||
|
|
||||||
|
:: (>ckf) ( rank suit -- n )
|
||||||
|
rank rank suit rank card-bitfield ;
|
||||||
|
|
||||||
|
: >ckf ( str -- n )
|
||||||
|
#! Cactus Kev Format
|
||||||
|
>upper 1 cut (>ckf) ;
|
||||||
|
|
||||||
|
: flush? ( cards -- ? )
|
||||||
|
HEX: F000 [ bitand ] reduce 0 = not ;
|
||||||
|
|
||||||
|
: rank-bits ( cards -- q )
|
||||||
|
0 [ bitor ] reduce -16 shift ;
|
||||||
|
|
||||||
|
: lookup ( cards table -- value )
|
||||||
|
[ rank-bits ] dip nth ;
|
||||||
|
|
||||||
|
: unique5? ( cards -- ? )
|
||||||
|
unique5-table lookup 0 > ;
|
||||||
|
|
||||||
|
: map-product ( seq quot -- n )
|
||||||
|
[ 1 ] 2dip [ dip * ] curry [ swap ] prepose each ; inline
|
||||||
|
|
||||||
|
: prime-bits ( cards -- q )
|
||||||
|
[ HEX: FF bitand ] map-product ;
|
||||||
|
|
||||||
|
: hand-value ( cards -- value )
|
||||||
|
{
|
||||||
|
{ [ dup flush? ] [ flushes-table lookup ] }
|
||||||
|
{ [ dup unique5? ] [ unique5-table lookup ] }
|
||||||
|
[
|
||||||
|
prime-bits products-table sorted-index
|
||||||
|
values-table nth
|
||||||
|
]
|
||||||
|
} cond ;
|
||||||
|
|
||||||
|
: >card-rank ( card -- str )
|
||||||
|
-8 shift HEX: F bitand RANK_STR nth ;
|
||||||
|
|
||||||
|
: >card-suit ( card -- str )
|
||||||
|
{
|
||||||
|
{ [ dup 15 bit? ] [ drop "C" ] }
|
||||||
|
{ [ dup 14 bit? ] [ drop "D" ] }
|
||||||
|
{ [ dup 13 bit? ] [ drop "H" ] }
|
||||||
|
[ drop "S" ]
|
||||||
|
} cond ;
|
||||||
|
|
||||||
|
PRIVATE>
|
||||||
|
|
||||||
|
TUPLE: hand
|
||||||
|
{ cards sequence }
|
||||||
|
{ value integer } ;
|
||||||
|
|
||||||
|
M: hand <=> [ value>> ] compare ;
|
||||||
|
M: hand equal?
|
||||||
|
over hand? [ [ value>> ] bi@ = ] [ 2drop f ] if ;
|
||||||
|
|
||||||
|
: <hand> ( str -- hand )
|
||||||
|
" " split [ >ckf ] map
|
||||||
|
dup hand-value hand boa ;
|
||||||
|
|
||||||
|
: hand-rank ( hand -- rank )
|
||||||
|
value>> {
|
||||||
|
{ [ dup 6185 > ] [ drop HIGH_CARD ] } ! 1277 high card
|
||||||
|
{ [ dup 3325 > ] [ drop ONE_PAIR ] } ! 2860 one pair
|
||||||
|
{ [ dup 2467 > ] [ drop TWO_PAIR ] } ! 858 two pair
|
||||||
|
{ [ dup 1609 > ] [ drop THREE_OF_A_KIND ] } ! 858 three-kind
|
||||||
|
{ [ dup 1599 > ] [ drop STRAIGHT ] } ! 10 straights
|
||||||
|
{ [ dup 322 > ] [ drop FLUSH ] } ! 1277 flushes
|
||||||
|
{ [ dup 166 > ] [ drop FULL_HOUSE ] } ! 156 full house
|
||||||
|
{ [ dup 10 > ] [ drop FOUR_OF_A_KIND ] } ! 156 four-kind
|
||||||
|
[ drop STRAIGHT_FLUSH ] ! 10 straight-flushes
|
||||||
|
} cond ;
|
||||||
|
|
||||||
|
: >value ( hand -- str )
|
||||||
|
hand-rank VALUE_STR nth ;
|
||||||
|
|
||||||
|
: >cards ( hand -- str )
|
||||||
|
cards>> [
|
||||||
|
[ >card-rank ] [ >card-suit ] bi append
|
||||||
|
] map " " join ;
|
|
@ -0,0 +1 @@
|
||||||
|
5-card poker hand evaluator
|
|
@ -0,0 +1,4 @@
|
||||||
|
USING: project-euler.054 tools.test ;
|
||||||
|
IN: project-euler.054.tests
|
||||||
|
|
||||||
|
[ 376 ] [ euler054 ] unit-test
|
|
@ -0,0 +1,87 @@
|
||||||
|
! Copyright (c) 2009 Aaron Schaefer.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: arrays io.encodings.ascii io.files kernel math.order poker
|
||||||
|
project-euler.common sequences ;
|
||||||
|
IN: project-euler.054
|
||||||
|
|
||||||
|
! http://projecteuler.net/index.php?section=problems&id=54
|
||||||
|
|
||||||
|
! DESCRIPTION
|
||||||
|
! -----------
|
||||||
|
|
||||||
|
! In the card game poker, a hand consists of five cards and are ranked, from
|
||||||
|
! lowest to highest, in the following way:
|
||||||
|
|
||||||
|
! * High Card: Highest value card.
|
||||||
|
! * One Pair: Two cards of the same value.
|
||||||
|
! * Two Pairs: Two different pairs.
|
||||||
|
! * Three of a Kind: Three cards of the same value.
|
||||||
|
! * Straight: All cards are consecutive values.
|
||||||
|
! * Flush: All cards of the same suit.
|
||||||
|
! * Full House: Three of a kind and a pair.
|
||||||
|
! * Four of a Kind: Four cards of the same value.
|
||||||
|
! * Straight Flush: All cards are consecutive values of same suit.
|
||||||
|
! * Royal Flush: Ten, Jack, Queen, King, Ace, in same suit.
|
||||||
|
|
||||||
|
! The cards are valued in the order:
|
||||||
|
! 2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King, Ace.
|
||||||
|
|
||||||
|
! If two players have the same ranked hands then the rank made up of the
|
||||||
|
! highest value wins; for example, a pair of eights beats a pair of fives (see
|
||||||
|
! example 1 below). But if two ranks tie, for example, both players have a pair
|
||||||
|
! of queens, then highest cards in each hand are compared (see example 4
|
||||||
|
! below); if the highest cards tie then the next highest cards are compared,
|
||||||
|
! and so on.
|
||||||
|
|
||||||
|
! Consider the following five hands dealt to two players:
|
||||||
|
|
||||||
|
! Hand Player 1 Player 2 Winner
|
||||||
|
! ---------------------------------------------------------
|
||||||
|
! 1 5H 5C 6S 7S KD 2C 3S 8S 8D TD
|
||||||
|
! Pair of Fives Pair of Eights Player 2
|
||||||
|
|
||||||
|
! 2 5D 8C 9S JS AC 2C 5C 7D 8S QH
|
||||||
|
! Highest card Ace Highest card Queen Player 1
|
||||||
|
|
||||||
|
! 3 2D 9C AS AH AC 3D 6D 7D TD QD
|
||||||
|
! Three Aces Flush with Diamonds Player 2
|
||||||
|
|
||||||
|
! 4 4D 6S 9H QH QC 3D 6D 7H QD QS
|
||||||
|
! Pair of Queens Pair of Queens
|
||||||
|
! Highest card Nine Highest card Seven Player 1
|
||||||
|
|
||||||
|
! 5 2H 2D 4C 4D 4S 3C 3D 3S 9S 9D
|
||||||
|
! Full House Full House
|
||||||
|
! With Three Fours With Three Threes Player 1
|
||||||
|
|
||||||
|
! The file, poker.txt, contains one-thousand random hands dealt to two players.
|
||||||
|
! Each line of the file contains ten cards (separated by a single space): the
|
||||||
|
! first five are Player 1's cards and the last five are Player 2's cards. You
|
||||||
|
! can assume that all hands are valid (no invalid characters or repeated
|
||||||
|
! cards), each player's hand is in no specific order, and in each hand there is
|
||||||
|
! a clear winner.
|
||||||
|
|
||||||
|
! How many hands does Player 1 win?
|
||||||
|
|
||||||
|
|
||||||
|
! SOLUTION
|
||||||
|
! --------
|
||||||
|
|
||||||
|
<PRIVATE
|
||||||
|
|
||||||
|
: source-054 ( -- seq )
|
||||||
|
"resource:extra/project-euler/054/poker.txt" ascii file-lines
|
||||||
|
[ [ 14 head-slice ] [ 14 tail-slice* ] bi 2array ] map ;
|
||||||
|
|
||||||
|
: player1-win? ( hand1 hand2 -- ? )
|
||||||
|
before? ; inline
|
||||||
|
|
||||||
|
PRIVATE>
|
||||||
|
|
||||||
|
: euler054 ( -- answer )
|
||||||
|
source-054 [ [ <hand> ] map first2 player1-win? ] count ;
|
||||||
|
|
||||||
|
! [ euler054 ] 100 ave-time
|
||||||
|
! 36 ms ave run time - 2.71 SD (100 trials)
|
||||||
|
|
||||||
|
SOLUTION: euler054
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
||||||
! Copyright (c) 2007, 2008 Aaron Schaefer, Samuel Tardieu.
|
! Copyright (c) 2007, 2008, 2009 Aaron Schaefer, Samuel Tardieu.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: definitions io io.files io.pathnames kernel math math.parser
|
USING: definitions io io.files io.pathnames kernel math math.parser
|
||||||
prettyprint project-euler.ave-time sequences vocabs vocabs.loader
|
prettyprint project-euler.ave-time sequences vocabs vocabs.loader
|
||||||
|
@ -14,14 +14,14 @@ USING: definitions io io.files io.pathnames kernel math math.parser
|
||||||
project-euler.037 project-euler.038 project-euler.039 project-euler.040
|
project-euler.037 project-euler.038 project-euler.039 project-euler.040
|
||||||
project-euler.041 project-euler.042 project-euler.043 project-euler.044
|
project-euler.041 project-euler.042 project-euler.043 project-euler.044
|
||||||
project-euler.045 project-euler.046 project-euler.047 project-euler.048
|
project-euler.045 project-euler.046 project-euler.047 project-euler.048
|
||||||
project-euler.049 project-euler.052 project-euler.053 project-euler.055
|
project-euler.049 project-euler.052 project-euler.053 project-euler.054
|
||||||
project-euler.056 project-euler.057 project-euler.059 project-euler.067
|
project-euler.055 project-euler.056 project-euler.057 project-euler.059
|
||||||
project-euler.071 project-euler.073 project-euler.075 project-euler.076
|
project-euler.067 project-euler.071 project-euler.073 project-euler.075
|
||||||
project-euler.079 project-euler.092 project-euler.097 project-euler.099
|
project-euler.076 project-euler.079 project-euler.092 project-euler.097
|
||||||
project-euler.100 project-euler.116 project-euler.117 project-euler.134
|
project-euler.099 project-euler.100 project-euler.116 project-euler.117
|
||||||
project-euler.148 project-euler.150 project-euler.151 project-euler.164
|
project-euler.134 project-euler.148 project-euler.150 project-euler.151
|
||||||
project-euler.169 project-euler.173 project-euler.175 project-euler.186
|
project-euler.164 project-euler.169 project-euler.173 project-euler.175
|
||||||
project-euler.190 project-euler.203 project-euler.215 ;
|
project-euler.186 project-euler.190 project-euler.203 project-euler.215 ;
|
||||||
IN: project-euler
|
IN: project-euler
|
||||||
|
|
||||||
<PRIVATE
|
<PRIVATE
|
||||||
|
|
Loading…
Reference in New Issue