@@ -3,6 +3,9 @@ import Data.Char (isDigit)
3
3
import Data.List (sort , group , sortBy , nub , groupBy )
4
4
import Data.Data
5
5
import Data.Function (on )
6
+ import Debug.Trace
7
+ import System.Directory (doesFileExist , removeFile )
8
+ import Control.Monad (when )
6
9
7
10
data HandType a = HighCard { value :: a }
8
11
| OnePair { value :: a }
@@ -13,40 +16,70 @@ data HandType a = HighCard {value :: a}
13
16
| FiveKind { value :: a }
14
17
deriving (Eq ,Ord ,Show , Typeable , Data )
15
18
19
+ upgrade :: HandType [Int ] -> Int -> HandType [Int ]
20
+ upgrade x i
21
+ | i > 0 = case x of
22
+ HighCard a-> OnePair a
23
+ OnePair a-> ThreeKind a
24
+ TwoPair a -> case i of
25
+ 1 -> FullHouse a
26
+ 2 -> FourKind a
27
+ _ -> error " Invalid number of jokers" -- Only possible Cases are XXJJY and XXYYJ (so i = 1 or i = 2)
28
+ ThreeKind a -> case i of
29
+ 1 -> FourKind a
30
+ 3 -> FourKind a
31
+ _ -> error " Invalid number of jokers" -- Only possible Cases are XXXJY and XJJJY (so i = 1 or i = 3)
32
+ FullHouse a -> FiveKind a
33
+ FourKind a -> FiveKind a
34
+ FiveKind a -> FiveKind a
35
+ | i == 0 = x
36
+ | otherwise = error (" Invalid number of jokers - you tried upgrading " ++ show i ++ " times for " ++ show x)
16
37
17
- charToInt :: Char -> Int
18
- charToInt ' A' = 1000
19
- charToInt ' K' = 500
20
- charToInt ' Q' = 400
21
- charToInt ' J' = 300
22
- charToInt ' T' = 200
23
- charToInt x = read [x] :: Int
38
+
39
+ charToInt :: Char -> Bool -> Int
40
+ charToInt ' A' _ = 1000
41
+ charToInt ' K' _ = 500
42
+ charToInt ' Q' _ = 400
43
+ charToInt ' J' partB
44
+ | partB = 0
45
+ | otherwise = 200
46
+ charToInt ' T' _ = 10
47
+ charToInt x _ = read [x] :: Int
24
48
25
49
type Bid = Int
26
50
type Pair a = (HandType a , Bid )
27
51
28
-
29
- -- getHandType :: String -> HandType String
30
- getHandType xs
31
- | getNumberOf 5 == 1 = FiveKind $ map charToInt xs
32
- | getNumberOf 4 == 1 && getNumberOf 1 == 1 = FourKind $ map charToInt xs
33
- | getNumberOf 2 == 1 && getNumberOf 3 == 1 = FullHouse $ map charToInt xs
34
- | getNumberOf 3 == 1 && getNumberOf 1 == 2 = ThreeKind $ map charToInt xs
35
- | getNumberOf 2 == 1 = OnePair $ map charToInt xs
36
- | getNumberOf 2 == 2 = TwoPair $ map charToInt xs
37
- | length (nub sortedInt) == 1 = HighCard $ map charToInt xs
52
+ getHandType partB xs
53
+ | getNumberOf 5 == 1 = FiveKind $ map (`charToInt` partB) xs
54
+ | getNumberOf 4 == 1 && getNumberOf 1 == 1 = FourKind $ map (`charToInt` partB) xs
55
+ | getNumberOf 2 == 1 && getNumberOf 3 == 1 = FullHouse $ map (`charToInt` partB) xs
56
+ | getNumberOf 3 == 1 && getNumberOf 1 == 2 = ThreeKind $ map (`charToInt` partB) xs
57
+ | getNumberOf 2 == 1 = OnePair $ map (`charToInt` partB) xs
58
+ | getNumberOf 2 == 2 = TwoPair $ map (`charToInt` partB) xs
59
+ | length (nub sortedInt) == 1 = HighCard $ map (`charToInt` partB) xs
38
60
where sorted = sortBy (\ (_, val1 ) (_, val2) -> compare val2 val1) $ map (\ x -> (x, length x)) $ group $ sort xs
39
61
sortedInt = map snd sorted
40
62
getNumberOf x = length $ filter (== x) sortedInt
41
63
42
- -- parse :: [[String]] -> [Pair]
43
- parse [[] ] = []
44
- parse [] = []
45
- parse (x: xs) = (getHandType $ head x, read (head $ tail x) :: Int ) : parse xs
64
+ getHandTypeWithJokers xs
65
+ | jokers == 0 = handTypeWithoutJokers
66
+ | otherwise = upgrade handTypeWithoutJokers jokers
67
+ where jokers = length $ filter (== ' J' ) xs
68
+ handTypeWithoutJokers = getHandType True xs
69
+ parse _ [[] ] = []
70
+ parse _ [] = []
71
+ parse f (x: xs) = (f $ head x, read (head $ tail x) :: Int ) : parse f xs
72
+
46
73
74
+ toFile :: String -> [Pair [Int ]] -> IO ()
75
+ toFile _ [] = return ()
76
+ toFile name ((x,y): xs) = do
77
+ appendFile name (show x ++ " " ++ show y ++ " \n " )
78
+ toFile name xs
47
79
48
80
main :: IO ()
49
81
main = do
50
82
contents <- readFile " inputs/input"
51
- let clean = zipWith (\ x y -> snd y * x) [1 .. ] $ concat . groupBy (\ x y -> toConstr (fst x) == toConstr (fst y) ) . sort . parse . map words $ lines contents
52
- print . sum $ clean
83
+ let solve1 = sum $ zipWith (\ x y -> snd y * x) [1 .. ] $ concat . groupBy (\ x y -> toConstr (fst x) == toConstr (fst y) ) . sort $ parse (getHandType False ) (map words $ lines contents)
84
+ let solve2 = sum $ zipWith (\ x y -> snd y * x) [1 .. ] $ concat . groupBy (\ x y -> toConstr (fst x) == toConstr (fst y) ) . sort . parse getHandTypeWithJokers $ map words $ lines contents
85
+ print solve1 >> print solve2
0 commit comments