141 lines
2.5 KiB
Go
141 lines
2.5 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/csv"
|
|
"fmt"
|
|
"github.com/lucasb-eyer/go-colorful"
|
|
"image"
|
|
"image/draw"
|
|
"image/png"
|
|
"log"
|
|
"os"
|
|
"strconv"
|
|
)
|
|
|
|
const OutputEnable = false
|
|
const CreateImage = true
|
|
|
|
func main() {
|
|
fmt.Println("Enter Number:")
|
|
var number int
|
|
_, err := fmt.Scanf("%d", &number)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
matrice := make([][]int, number+1)
|
|
|
|
for i := 0; i <= number; i++ {
|
|
matrice[i] = make([]int, number+1)
|
|
for j := 0; j <= number; j++ {
|
|
matrice[i][j] = (j * i) % number
|
|
}
|
|
}
|
|
|
|
// Save it
|
|
if err := csvExport(matrice); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// output it
|
|
if OutputEnable {
|
|
fmt.Print("\t")
|
|
for i := 0; i <= number; i++ {
|
|
fmt.Print(i, "\t")
|
|
}
|
|
fmt.Println()
|
|
|
|
for rownumber, row := range matrice {
|
|
fmt.Print(rownumber, "\t")
|
|
for _, col := range row {
|
|
fmt.Print(col, "\t")
|
|
}
|
|
fmt.Println()
|
|
}
|
|
}
|
|
|
|
// Build an image
|
|
if CreateImage {
|
|
|
|
log.Println("Starting image creation...")
|
|
|
|
size := getImageBlockSize(number)
|
|
lightColor, _ := colorful.Hex("#00fbfb")
|
|
darkColor, _ := colorful.Hex("#330066")
|
|
|
|
img := image.NewRGBA(image.Rect(0, 0, number*size, number*size))
|
|
|
|
for rownumber, row := range matrice {
|
|
for colnumber, col := range row {
|
|
x := colnumber*size - 1
|
|
y := rownumber*size - 1
|
|
draw.Draw(img, image.Rect(x, y, x+size, y+size), &image.Uniform{lightColor.BlendRgb(darkColor, float64(col)/float64(number-1))}, image.ZP, draw.Src)
|
|
}
|
|
}
|
|
|
|
imgpath := strconv.Itoa(number) + "x.png"
|
|
toimg, err := os.Create(imgpath)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
defer toimg.Close()
|
|
|
|
err = png.Encode(toimg, img)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
log.Println("Image saved to " + imgpath)
|
|
}
|
|
}
|
|
|
|
func csvExport(data [][]int) error {
|
|
file, err := os.Create("result.csv")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer file.Close()
|
|
|
|
writer := csv.NewWriter(file)
|
|
defer writer.Flush()
|
|
|
|
//Prepare
|
|
dataStrings := make([][]string, len(data))
|
|
for in := range data {
|
|
dataStrings[in] = make([]string, len(data[in]))
|
|
for in2, val2 := range data[in] {
|
|
dataStrings[in][in2] = strconv.Itoa(val2)
|
|
}
|
|
}
|
|
|
|
for _, value := range dataStrings {
|
|
if err := writer.Write(value); err != nil {
|
|
return err // let's return errors if necessary, rather than having a one-size-fits-all error handler
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func getImageBlockSize(number int) int {
|
|
if number < 1000 {
|
|
return 2
|
|
}
|
|
if number < 600 {
|
|
return 3
|
|
}
|
|
if number < 400 {
|
|
return 4
|
|
}
|
|
if number < 200 {
|
|
return 6
|
|
}
|
|
if number < 100 {
|
|
return 10
|
|
}
|
|
if number < 50 {
|
|
return 15
|
|
}
|
|
|
|
return number
|
|
}
|