WIP: every type of hand has its array

This commit is contained in:
Davide Oddone 2023-12-07 22:10:27 +01:00
parent 4ca1366d87
commit e14b5277fa

View File

@ -0,0 +1,185 @@
package main
import (
"fmt"
"strings"
"bufio"
// "math"
"os"
"strconv"
// "regexp"
"sync"
)
var mapSeeds = map[string]int{
"A": 13,
"K": 12,
"Q": 11,
"J": 10,
"T": 9,
"9": 8,
"8": 7,
"7": 6,
"6": 5,
"5": 4,
"4": 3,
"3": 2,
"2": 1,
}
type Game struct {
mu sync.Mutex
ranks []int
// 0: High card, 1: One pair, 2: Two pair, 3: Three of a kind
// 4: Full house, 5: Four of a kind, 6: Five of a kind
typeOfHand [7][]string
}
func (g *Game) DetermineType(cards string, index int, wg *sync.WaitGroup) int {
// We create a map and we check the length. Depending on the length, we
// insert the string in a specific type
m := make(map[string]int)
for i := 0; i < len(cards); i++ {
key := string(cards[i])
m[key] = mapSeeds[key]
}
// Now, depending on the number of elements in the map, we can assign
// append cards to a specific rank
mapSize := len(m)
switch mapSize {
// Five of a kind
case 1:
g.mu.Lock()
g.typeOfHand[6] = append(g.typeOfHand[6], cards)
g.mu.Unlock()
// Four of a kind || Full House
case 2:
//call func
i := FullOrFour(cards)
g.mu.Lock()
g.typeOfHand[i] = append(g.typeOfHand[i], cards)
g.mu.Unlock()
// Three of a kind || Two pair
case 3:
i := ThreeOrTwo(cards)
g.mu.Lock()
g.typeOfHand[i] = append(g.typeOfHand[i], cards)
g.mu.Unlock()
// One pair
case 4:
g.mu.Lock()
g.typeOfHand[1] = append(g.typeOfHand[1], cards)
g.mu.Unlock()
// High card
case 5:
g.mu.Lock()
g.typeOfHand[0] = append(g.typeOfHand[0], cards)
g.mu.Unlock()
}
wg.Done()
return 1
}
func ThreeOrTwo(cards string) int {
m := make(map[string]int)
for i := 0; i < len(cards); i++ {
key := string(cards[i])
m[key] += 1
}
// m[i] returns 0 if the element is not in the map. I take advantage
// of that
for i := range mapSeeds {
// If an element has 3 values, we have a three of a kind
if m[i] == 3 {
return 4
/// If an element has 2 values, we have a two pair
} else if m[i] == 2 {
return 3
}
}
return -1
}
func FullOrFour(cards string) int {
m := make(map[string]int)
for i := 0; i < len(cards); i++ {
key := string(cards[i])
m[key] += 1
}
// m[i] returns 0 if the element is not in the map. I take advantage
// of that
for i := range mapSeeds {
// If an element has four values, we have a Four of a kind
if m[i] == 4 {
return 5
/// If an element has 3 values, we have a four of a kind
} else if m[i] == 3 {
return 4
}
}
return -1
}
func check(e error) {
if e != nil {
panic(e)
}
}
func PrintAndWait(x ...any) {
fmt.Print(x...)
fmt.Scanln()
}
func main() {
file, err := os.Open("./inputs/day07_input")
check(err)
defer file.Close()
// Struct for multiple races
g := Game{}
m := make(map[string]int)
// Variable where we store every line in the file
lines := make([]string, 0)
scanner := bufio.NewScanner(file)
for scanner.Scan() {
lines = append(lines, scanner.Text())
}
// Array of strings, set of cards
var cards []string
// Array of int, bet
var bet []int
// Now, split the lines
for i := 0; i < len(lines); i++ {
tempString := strings.Split(lines[i], " ")
cards = append(cards, tempString[0])
tempNum, _ := strconv.Atoi(tempString[1])
bet = append(bet, tempNum)
}
// Rank will be from 1 to len(lines)
g.ranks = make([]int, len(lines))
// What do we know for sure? 5 identical seeds are the highest ranks,
// 5 completely different seeds are the lowest ranks.
// We can iterate for every set of cards, and do different things
// if the map we build has one element, five elements or the worst
// case (two, three or four elements).
//
// Two identical: 4oK or FH
// Three identical: 3oK or 22
// Four identical: 12
//
// Will try to call a different function for every line
var wg sync.WaitGroup
wg.Add(len(lines))
for i := 0; i < len(lines); i++ {
go g.DetermineType(cards[i], i, &wg)
}
wg.Wait()
PrintAndWait(g.typeOfHand)
_ = m
}