209 lines
3.5 KiB
Go
209 lines
3.5 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"errors"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
func main() {
|
|
width := 50
|
|
height := 6
|
|
if len(os.Args) >= 2 {
|
|
width = atoi(os.Args[1])
|
|
}
|
|
if len(os.Args) >= 3 {
|
|
height = atoi(os.Args[2])
|
|
}
|
|
input := stdinToStringSlice()
|
|
|
|
d := CreateDisplay(width, height)
|
|
for idx, ins := range input {
|
|
fmt.Println(idx, ins)
|
|
d.ClearScreen()
|
|
d.ProcInstruction(ins)
|
|
d.PrintScreen()
|
|
time.Sleep(time.Millisecond * 25)
|
|
}
|
|
fmt.Println("Voltage Used: ", d.GetVoltage())
|
|
}
|
|
|
|
type Display struct {
|
|
Width int
|
|
Height int
|
|
Screen [][]bool
|
|
}
|
|
|
|
func CreateDisplay(w, h int) *Display {
|
|
d := Display{Width: w, Height: h}
|
|
for i := 0; i < h; i++ {
|
|
var row []bool
|
|
for j := 0; j < w; j++ {
|
|
row = append(row, false)
|
|
}
|
|
d.Screen = append(d.Screen, row)
|
|
}
|
|
return &d
|
|
}
|
|
|
|
func (d *Display) ClearScreen() {
|
|
fmt.Print("\033[H\033[2J")
|
|
}
|
|
|
|
func (d *Display) PrintScreen() {
|
|
fmt.Print("\u250C")
|
|
for i := 0; i < d.Width; i++ {
|
|
fmt.Print("\u2500")
|
|
}
|
|
fmt.Println("\u2510")
|
|
for y := range d.Screen {
|
|
fmt.Print("\u2502")
|
|
for x := range d.Screen[y] {
|
|
if d.Screen[y][x] {
|
|
fmt.Print("\u2588")
|
|
} else {
|
|
fmt.Print(" ")
|
|
}
|
|
}
|
|
fmt.Println("\u2502")
|
|
}
|
|
fmt.Print("\u2514")
|
|
for i := 0; i < d.Width; i++ {
|
|
fmt.Print("\u2500")
|
|
}
|
|
fmt.Println("\u2518")
|
|
}
|
|
|
|
func (d *Display) SetWidth(w int) {
|
|
d.Width = w
|
|
}
|
|
|
|
func (d *Display) SetHeight(h int) {
|
|
d.Height = h
|
|
}
|
|
|
|
func (d *Display) ProcInstruction(ins string) {
|
|
pts := strings.Fields(ins)
|
|
switch pts[0] {
|
|
case "rect":
|
|
if len(pts) < 2 {
|
|
return
|
|
}
|
|
dim := strings.Split(pts[1], "x")
|
|
bldX := atoi(dim[0])
|
|
bldY := atoi(dim[1])
|
|
d.CreateRect(bldX, bldY)
|
|
case "rotate":
|
|
if len(pts) < 5 {
|
|
return
|
|
}
|
|
args := strings.Split(pts[2], "=")
|
|
switch pts[1] {
|
|
case "row":
|
|
if args[0] != "y" {
|
|
return
|
|
}
|
|
d.RotateRow(atoi(args[1]), atoi(pts[4]))
|
|
case "column":
|
|
if args[0] != "x" {
|
|
return
|
|
}
|
|
d.RotateCol(atoi(args[1]), atoi(pts[4]))
|
|
}
|
|
}
|
|
}
|
|
|
|
func (d *Display) CreateRect(x, y int) {
|
|
if y >= d.Height && x >= d.Width {
|
|
fmt.Println(" Error creating rect", x, y)
|
|
return
|
|
}
|
|
for i := 0; i < y; i++ {
|
|
for j := 0; j < x; j++ {
|
|
d.Screen[i][j] = true
|
|
}
|
|
}
|
|
}
|
|
|
|
func (d *Display) RotateRow(y, dist int) {
|
|
orig, err := d.GetRow(y)
|
|
if err != nil {
|
|
fmt.Println(err.Error())
|
|
os.Exit(1)
|
|
return
|
|
}
|
|
for i := range orig {
|
|
d.Screen[y][(i+dist)%d.Width] = orig[i]
|
|
}
|
|
}
|
|
|
|
func (d *Display) RotateCol(x, dist int) {
|
|
orig, err := d.GetCol(x)
|
|
if err != nil {
|
|
fmt.Println(err.Error())
|
|
os.Exit(1)
|
|
return
|
|
}
|
|
|
|
for i := range orig {
|
|
d.Screen[(i+dist)%d.Height][x] = orig[i]
|
|
}
|
|
}
|
|
|
|
func (d *Display) GetRow(y int) ([]bool, error) {
|
|
var ret []bool
|
|
if d.Height <= y {
|
|
return ret, errors.New("Invalid Row Requested")
|
|
}
|
|
for i := 0; i < d.Width; i++ {
|
|
ret = append(ret, d.Screen[y][i])
|
|
}
|
|
return ret, nil
|
|
}
|
|
|
|
func (d *Display) GetCol(x int) ([]bool, error) {
|
|
var ret []bool
|
|
if d.Width <= x {
|
|
return ret, errors.New("Invalid Column Requested")
|
|
}
|
|
for i := 0; i < d.Height; i++ {
|
|
ret = append(ret, d.Screen[i][x])
|
|
}
|
|
return ret, nil
|
|
}
|
|
|
|
func (d *Display) GetVoltage() int {
|
|
var ret int
|
|
for i := range d.Screen {
|
|
for j := range d.Screen[i] {
|
|
if d.Screen[i][j] {
|
|
ret++
|
|
}
|
|
}
|
|
}
|
|
return ret
|
|
}
|
|
|
|
func stdinToStringSlice() []string {
|
|
var input []string
|
|
scanner := bufio.NewScanner(os.Stdin)
|
|
for scanner.Scan() {
|
|
input = append(input, scanner.Text())
|
|
}
|
|
return input
|
|
}
|
|
|
|
func atoi(i string) int {
|
|
var ret int
|
|
var err error
|
|
if ret, err = strconv.Atoi(i); err != nil {
|
|
log.Fatal("Invalid Atoi")
|
|
}
|
|
return ret
|
|
}
|