Present for You
Go / main.go
package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"regexp"
	"strconv"
	"strings"
	"unicode"
)

func main() {
	filePath := "[LINE]肉の会.txt"

	file, err := os.Open(filePath)
	if err != nil {
		fmt.Println("ファイルのオープンに失敗しました:", err)
		return
	}
	defer file.Close()

	scanner := bufio.NewScanner(file)
	pricePerItem := 0

	if scanner.Scan() {
		firstLine := scanner.Text()
		pricePerItem = extractPricePerItem(firstLine)
		if pricePerItem == 0 {
			fmt.Println("最初の行に有効な価格が見つかりませんでした。")
			return
		}
	}

	summary := make(map[string]int)
	allTotal := 0

	for scanner.Scan() {
		line := scanner.Text()
		allTotal += processLine(line, summary)
	}

	if err := scanner.Err(); err != nil {
		fmt.Println("読み取り中にエラーが発生しました:", err)
	}

	printResults(summary, allTotal, pricePerItem)
}

func extractPricePerItem(line string) int {
	re := regexp.MustCompile(`(\d+)\s*원`)
	match := re.FindStringSubmatch(line)
	if len(match) > 1 {
		price, err := strconv.Atoi(match[1])
		if err == nil {
			return price
		}
	}
	return 0
}

func processLine(line string, summary map[string]int) int {
	re := regexp.MustCompile(`\d{2}:\d{2} `)
	match := re.FindStringIndex(line)
	if match == nil {
		return 0
	}

	afterTime := line[match[1]:]

	lastNumber := extractLastNumber(line)
	if lastNumber == -1 {
		return 0
	}

	name := strings.TrimSpace(afterTime[:strings.LastIndex(afterTime, " ")])

	summary[name] += lastNumber

	return lastNumber
}

func extractLastNumber(line string) int {
	if strings.HasSuffix(line, "個") {
		numberStr := extractNumberBeforeSuffix(line, "個")
		if numberStr != "" {
			num, err := strconv.Atoi(numberStr)
			if err == nil {
				return num
			}
		}
		return -1
	}

	lastNumber := extractNumberAfterSpace(line)
	if lastNumber != "" {
		num, err := strconv.Atoi(lastNumber)
		if err == nil {
			return num
		}
	}

	return -1
}

func extractNumberBeforeSuffix(line, suffix string) string {
	index := strings.LastIndex(line, suffix)
	if index == -1 || index == 0 {
		return ""
	}

	numberStr := strings.TrimSpace(line[:index])
	lastNumber := ""
	for i := len(numberStr) - 1; i >= 0; i-- {
		if unicode.IsDigit(rune(numberStr[i])) {
			lastNumber = string(numberStr[i]) + lastNumber
		} else {
			break
		}
	}
	return lastNumber
}

func extractNumberAfterSpace(line string) string {
	lastSpaceIndex := strings.LastIndex(line, " ")
	if lastSpaceIndex == -1 || lastSpaceIndex == len(line)-1 {
		return ""
	}

	numberStr := line[lastSpaceIndex+1:]
	for _, ch := range numberStr {
		if !unicode.IsDigit(ch) {
			return ""
		}
	}
	return numberStr
}

func printResults(summary map[string]int, allTotal int, pricePerItem int) {
	fmt.Printf("合計: %d 個\n\n", allTotal)

	for name, total := range summary {
		trueResult := int(math.Round((float64(total) / float64(allTotal)) * float64(pricePerItem)))
		fmt.Printf("%s 合計: %d 個, %d원\n", name, total, trueResult)
	}
}