<commit_before>package main

import (
	"fmt"
	"image"
	"image/color"
	"image/png"
	"math/cmplx"
	"os"
	"sync"

	"github.com/krasoffski/gomill/htcmap"
)

const (
	xmin, ymin    = -2.2, -1.2
	xmax, ymax    = +1.2, +1.2
	width, height = 1536, 1024
	factor        = 10
	factor2       = factor * factor
	workers       = 4
)

type point struct {
	x, y int
}

type pixel struct {
	point
	c color.Color
}

func xCord(x int) float64 {
	return float64(x)/(width*factor)*(xmax-xmin) + xmin
}

func yCord(y int) float64 {
	return float64(y)/(height*factor)*(ymax-ymin) + ymin
}

func superSampling(p *point) color.Color {

	var xCords, yCords [factor]float64
	var subPixels [factor2]color.Color

	// Single calculation of required coordinates for super sampling.
	for i := 0; i < factor; i++ {
		xCords[i] = xCord(p.x + i)
		yCords[i] = yCord(p.y + i)
	}

	// Instead of calculation coordinate only fetching required one.
	for iy := 0; iy < factor; iy++ {
		for ix := 0; ix < factor; ix++ {
			// Using one dimension array because do not care about pixel order,
			// because at the end we are calculating avarage for all sub-pixels.
			subPixels[iy*factor+ix] = mandelbrot(complex(xCords[ix], yCords[iy]))
		}
	}

	var rAvg, gAvg, bAvg float64

	for _, c := range subPixels {
		r, g, b, _ := c.RGBA()
		rAvg += float64(r) / factor2
		gAvg += float64(g) / factor2
		bAvg += float64(b) / factor2
	}
	return color.RGBA64{uint16(rAvg), uint16(gAvg), uint16(bAvg), 0xFFFF}
}

func main() {

	img := image.NewRGBA(image.Rect(0, 0, width, height))

	points := make(chan *point)
	pixels := make(chan *pixel)

	go func() {
		for py := 0; py < height*factor; py += factor {
			for px := 0; px < width*factor; px += factor {
				points <- &point{px, py}
			}
		}
		close(points)
	}()

	var wg sync.WaitGroup
	for i := 0; i < workers; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			for {
				p, ok := <-points
				if !ok {
					return
				}
				c := superSampling(p)
				pixels <- &pixel{point{p.x, p.y}, c}

			}
		}()
	}
	go func() {
		for p := range pixels {
			img.Set(p.x/factor, p.y/factor, p.c)
		}
	}()
	wg.Wait()
	close(pixels)

	if err := png.Encode(os.Stdout, img); err != nil {
		fmt.Fprintf(os.Stderr, "error encoding png: %s", err)
		os.Exit(1)
	}
}

func mandelbrot(z complex128) color.Color {
	const iterations = 255
	const contrast = 15

	var v complex128
	for n := uint8(0); n < iterations; n++ {
		v = v*v + z
		vAbs := cmplx.Abs(v)
		if vAbs > 2 {
			// smooth := float64(n) + 1 - math.Log(math.Log(vAbs))/math.Log(2)
			r, g, b := htcmap.AsUInt8(float64(n*contrast), 0, iterations)
			return color.RGBA{r, g, b, 255}
		}
	}
	return color.Black
}<commit_msg>Refactoring but not sure it is better then before.<commit_after>package main

import (
	"fmt"
	"image"
	"image/color"
	"image/png"
	"math/cmplx"
	"os"
	"sync"

	"github.com/krasoffski/gomill/htcmap"
)

const (
	xmin, ymin    = -2.2, -1.2
	xmax, ymax    = +1.2, +1.2
	width, height = 1536, 1024
	factor        = 2
	factor2       = factor * factor
	workers       = 4
)

type point struct {
	x, y int
}

type pixel struct {
	point
	c color.Color
}

func xCord(x int) float64 {
	return float64(x)/(width*factor)*(xmax-xmin) + xmin
}

func yCord(y int) float64 {
	return float64(y)/(height*factor)*(ymax-ymin) + ymin
}

func superSampling(p *point) color.Color {

	var xCords, yCords [factor]float64
	var subPixels [factor2]color.Color

	// Single calculation of required coordinates for super sampling.
	for i := 0; i < factor; i++ {
		xCords[i] = xCord(p.x + i)
		yCords[i] = yCord(p.y + i)
	}

	// Instead of calculation coordinate only fetching required one.
	for iy := 0; iy < factor; iy++ {
		for ix := 0; ix < factor; ix++ {
			// Using one dimension array because do not care about pixel order,
			// because at the end we are calculating avarage for all sub-pixels.
			subPixels[iy*factor+ix] = mandelbrot(complex(xCords[ix], yCords[iy]))
		}
	}

	var rAvg, gAvg, bAvg float64

	for _, c := range subPixels {
		r, g, b, _ := c.RGBA()
		rAvg += float64(r) / factor2
		gAvg += float64(g) / factor2
		bAvg += float64(b) / factor2
	}
	return color.RGBA64{uint16(rAvg), uint16(gAvg), uint16(bAvg), 0xFFFF}
}

func producer(width, height, factor int) <-chan *point {
	out := make(chan *point)
	go func() {
		defer close(out)
		for py := 0; py < height*factor; py += factor {
			for px := 0; px < width*factor; px += factor {
				out <- &point{px, py}
			}
		}
	}()
	return out
}

// Do not like here that return rw chan from executor. Think about that.
func executer(wg *sync.WaitGroup, in <-chan *point) chan *pixel {
	out := make(chan *pixel)
	for i := 0; i < workers; i++ {
		id := i
		wg.Add(1)
		go func() {
			defer wg.Done()
			fmt.Fprintf(os.Stderr, "#%02d started\n", id)
			for {
				p, ok := <-in
				if !ok {
					fmt.Fprintf(os.Stderr, "#%02d stopped\n", id)
					return
				}
				fmt.Fprintf(os.Stderr, "#%02d got %v\n", id, p)
				c := superSampling(p)
				out <- &pixel{point{p.x, p.y}, c}
				fmt.Fprintf(os.Stderr, "#%02d did %v\n", id, p)
			}
		}()
	}
	return out
}

func mandelbrot(z complex128) color.Color {
	const iterations = 255
	const contrast = 15

	var v complex128
	for n := uint8(0); n < iterations; n++ {
		v = v*v + z
		vAbs := cmplx.Abs(v)
		if vAbs > 2 {
			// smooth := float64(n) + 1 - math.Log(math.Log(vAbs))/math.Log(2)
			r, g, b := htcmap.AsUInt8(float64(n*contrast), 0, iterations)
			return color.RGBA{r, g, b, 255}
		}
	}
	return color.Black
}

func main() {

	var wg sync.WaitGroup
	img := image.NewRGBA(image.Rect(0, 0, width, height))

	points := producer(width, height, factor)
	pixels := executer(&wg, points)

	go func() {
		for p := range pixels {
			img.Set(p.x/factor, p.y/factor, p.c)
		}
	}()

	wg.Wait()
	// TODO: figure out better way to close chan pixels.
	close(pixels)

	if err := png.Encode(os.Stdout, img); err != nil {
		fmt.Fprintf(os.Stderr, "error encoding png: %s", err)
		os.Exit(1)
	}
}
{'fraction_non_alphanumeric': 0.16108857336037863, 'fraction_numerical': 0.030256930358350236, 'mean_word_length': 2.9446666666666665, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '108333', 'n_tokens_mistral': 2752, 'n_tokens_neox': 2438, 'n_words': 655}