Created
October 14, 2022 20:29
-
-
Save cauesmelo/91647a52fb2622b030824eed2c119ed8 to your computer and use it in GitHub Desktop.
Desafio.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"os" | |
"strconv" | |
) | |
func getInput() int { | |
if len(os.Args) <= 1 { | |
fmt.Print("Usage: go a.out <integer >= 1>") | |
os.Exit(-123) | |
} | |
arg := os.Args[1] | |
input, err := strconv.Atoi(arg) | |
if err != nil || input < 1 { | |
fmt.Printf("wrong input '%s'. Usage: go a.out <integer >= 1>", arg) | |
os.Exit(-124) | |
} | |
return input | |
} | |
// Funcão para calcular valores da semi diagonal | |
func calcValue(x int, y int, input int, upperValue int) int { | |
// Calculo o valor de cada salto com base na posição x | |
var jump = ((input - x) - 1) - (x) | |
// Somo o valor acima, e dou um salto para cada lado(esq, dir, cima, baixo) | |
// Por fim, tiramos um e chegamos ao valor na diagonal do upperValue | |
return upperValue + ((4 * jump) - 1) | |
} | |
// Método para impressão de linha | |
func printLine(line []int) { | |
fmt.Print("[") | |
for i := 0; i < len(line); i++ { | |
fmt.Print(line[i]) | |
if i != len(line)-1 { | |
fmt.Print("\t") | |
} | |
} | |
fmt.Println("]") | |
} | |
// Método para preencher sequencialmente a partir de um valor e posição | |
func fillLine(line []int, startValue int, startPosX int, endPosX int) { | |
var currentValue = startValue | |
for i := startPosX; i <= endPosX; i++ { | |
line[i] = currentValue | |
currentValue++ | |
} | |
} | |
// Método para preencher sequencialmente a partir de um valor e posição em ordem reversa | |
func fillLineReverse(line []int, startValue int, startPosX int, endPosX int) { | |
var currentValue = startValue | |
for i := startPosX; i >= endPosX; i-- { | |
line[i] = currentValue | |
currentValue++ | |
} | |
} | |
// Função auxiliar para calcular o salto a direita | |
func getShiftRight(line int, input int) int { | |
if line > (input / 2) { | |
return input - line | |
} | |
return line | |
} | |
// Função auxiliar para calcular o salto a esquerda | |
func getShiftLeft(shiftRight int) int { | |
if shiftRight == 0 { | |
return 0 | |
} | |
return shiftRight - 1 | |
} | |
func main() { | |
// Recebe input | |
var input = getInput() | |
// Armazena linha anterior, utilizada para cálcular próxima linha | |
var previousLine = make([]int, input) | |
// Array para ir armazenando a linha atual | |
var currentLine = make([]int, input) | |
// Linha atual | |
var posY = 0 | |
// Percorremos por todas as linhas possíveis | |
for posY != input { | |
// Se for a primeira linha, basta preenchermos com uma sequência simples a partir do 1 | |
if posY == 0 { | |
fillLine(currentLine[:], 1, 0, input-1) | |
} | |
// Se não for a primeira linha | |
if posY != 0 { | |
// Calculo a quantidade de saltos à direita | |
var shiftRight = getShiftRight(posY, input) | |
// Calculo a quantidade de saltos a esquerda | |
var shiftLeft = getShiftLeft(shiftRight) | |
// Calculo da semi diagonal | |
var calculatedValue = calcValue(shiftLeft, posY, input, previousLine[shiftLeft]) | |
// Se foi possível calcular, preenche a sequência | |
if calculatedValue <= input*input { | |
var startPosX = shiftLeft | |
var endPosX = input - 1 - shiftRight | |
fillLine(currentLine[:], calculatedValue, startPosX, endPosX) | |
} | |
// Preencho valores saltados a esquerda | |
for i := 0; i < shiftLeft; i++ { | |
currentLine[i] = previousLine[i] - 1 | |
} | |
// Preencho valores saltados a direita | |
for i := input - 1; i >= input-shiftRight; i-- { | |
currentLine[i] = previousLine[i] + 1 | |
} | |
// Se passamos da metade da matriz, já temos valores suficientes para preencher | |
if posY > input/2 { | |
var startPosX = input - shiftRight - 1 | |
var endPosX = shiftLeft | |
var startValue = currentLine[input-shiftRight] + 1 | |
fillLineReverse(currentLine[:], startValue, startPosX, endPosX) | |
} | |
} | |
// Por fim, imprimimos a linha atual | |
printLine(currentLine) | |
// Salvo essa linha na variável auxiliar | |
previousLine = currentLine | |
// Limpo a linha atual | |
currentLine = make([]int, input) | |
// Coloco apontador de linha na próxima posição | |
posY++ | |
} | |
fmt.Println("") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment