package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
//  file, _ := os.Open("test")
  file, _ := os.Open("input")
  defer file.Close()
  scanner := bufio.NewScanner(file)
  diskMap := []string{}
  for scanner.Scan() {
    line := scanner.Text()
    diskMap = append(diskMap, strings.Split(line, "")...)
  }
  fileID := 0
  blockSize := 0
  blockSizes := []int{}
  freeSpace := 0
  freeSpaces := []int{}
  blocks := []string{}
  for i := range diskMap {
    if i % 2 == 0 {
      blockSize, _ = strconv.Atoi(diskMap[i])
      blockSizes = append(blockSizes, blockSize)
      for j:=0;j<blockSize;j++ {
        blocks = append(blocks, strconv.Itoa(fileID))
      }
      fileID++
    } else {
      freeSpace, _ = strconv.Atoi(diskMap[i])
      freeSpaces = append(freeSpaces, freeSpace)
      for j:=0;j<freeSpace;j++ {
        blocks = append(blocks, ".")
      }
    }
  }
  if len(freeSpaces) < len(blockSizes) {
    freeSpaces = append(freeSpaces, 0)
  }
  //TRY3
  for id:=fileID-1;id>=0;id-- {
    idPositions := findIDpositions(blocks,id)
    for moveTo:=0;moveTo<=id;moveTo++ {
      if moveTo==id {
        continue
      }
      if len(idPositions) <= freeSpaces[moveTo] {
        //find the spaces after the moveTo
        idSpacePositions := findSpacesAfterID(blocks,moveTo,freeSpaces[moveTo])
        //assign id to spaces for each len(idPositions)
        for i:=0;i<blockSizes[id];i++ {
          blocks[idSpacePositions[i]]=strconv.Itoa(id)
          blocks[idPositions[i]] = "."
          freeSpaces[moveTo]--
        }
        break
        //assign new id positions to idPositions
        //assign space to each idPositions
      }
    }
    fmt.Println(blocks)
  }
  checksum := 0
  for i := range blocks {
    blockID, _ := strconv.Atoi(blocks[i])
    checksum = checksum + i * blockID
  }
  fmt.Println(checksum)
}


func findIDpositions(blocks []string, id int) []int {
  positions := []int{}
  for i := range blocks {
    if blocks[i] == strconv.Itoa(id) {
      positions = append(positions, i)
    }
  }
  return positions
}

func findSpacesAfterID(blocks []string, id, idSpaces int) []int {
  spaces := []int{}
  idPositions := findIDpositions(blocks,id)
  for i:=idPositions[len(idPositions)-1];i<len(blocks);i++ {
    if blocks[i] == "." {
      spaces = append(spaces, i)
    }
    if len(spaces) == idSpaces {
      break
    }
  }
  return spaces
}
