Drawing a snowman in ASCII art












0












$begingroup$


I am learning Go and as an exercise I did this challenge from Code Golf (without the golfing), where an ASCII art snowman is drawn from a combination of body parts, based on an 8-digit code taken as command line argument.



For example:



$ ./snowman 12431312

_===_
(-.O)
<( : )
( : )


As a minor extension I decided to use a random code if none is passed.



Coming from Python, I had hoped to use the static typing to my advantage (e. g. by checking at compile time that the definition body parts is valid), but I have the feeling that I am fighting it more than it helps me.



I'd like to know how I can make the code less verbose and repetitive, without giving up the static checks.



snowman.go



package main

import (
"errors"
"fmt"
"math/rand"
"os"
"strconv"
"time"
)

type Snowman [5][7]rune

func (s Snowman) getLine(i int) string {
var line string
for _, c := range s[i] {
line += string(c)
}
return line
}

func (s Snowman) String() string {
var result string
for i := range s {
if i > 0 {
result += "n"
}
result += s.getLine(i)
}
return result
}

type Hat [2][5]rune
type Nose rune
type Eye rune
type LeftArm [2]rune
type RightArm [2]rune
type Torso [3]rune
type Base [3]rune

var hats = [...]Hat{
{{' ', ' ', ' ', ' ', ' '}, {'_', '=', '=', '=', '_'}},
{{' ', '_', '_', '_', ' '}, {'.', '.', '.', '.', '.'}},
{{' ', ' ', '_', ' ', ' '}, {' ', '/', '_', '\', ' '}},
{{' ', '_', '_', '_', ' '}, {'(', '_', '*', '_', ')'}},
}

var noses = [...]Nose{',', '.', '_', ' '}

var eyes = [...]Eye{'.', 'o', 'O', '-'}

var leftArms = [...]LeftArm{{' ', '<'}, {'\', ' '}, {' ', '/'}, {' ', ' '}}

var rightArms = [...]RightArm{{' ', '>'}, {'/', ' '}, {' ', '\'}, {' ', ' '}}

var torsos = [...]Torso{
{' ', ':', ' '},
{']', ' ', '['},
{'>', ' ', '<'},
{' ', ' ', ' '},
}

var bases = [...]Base{
{' ', ':', ' '},
{'"', ' ', '"'},
{'_', '_', '_'},
{' ', ' ', ' '},
}

// newSnowman returns a Snowman with no hat, arms, face, torso, or base.
func newSnowman() Snowman {
var s Snowman
for _, i := range [3]int{0, 1, 4} {
s[i][0] = ' '
s[i][6] = ' '
}
for i := 2; i < 5; i++ {
s[i][1] = '('
s[i][5] = ')'
}
return s
}

func (s *Snowman) setHat(h Hat) {
for i, line := range h {
for j, c := range line {
s[i][j+1] = c
}
}
}

func (s *Snowman) setNose(n Nose) {
s[2][3] = rune(n)
}

func (s *Snowman) setLeftEye(e Eye) {
s[2][2] = rune(e)
}

func (s *Snowman) setRightEye(e Eye) {
s[2][4] = rune(e)
}

func (s *Snowman) setLeftArm(a LeftArm) {
for i, c := range a {
s[i+2][0] = c
}
}

func (s *Snowman) setRightArm(a RightArm) {
for i, c := range a {
s[i+2][6] = c
}
}

func (s *Snowman) setTorso(t Torso) {
for i, c := range t {
s[3][i+2] = c
}
}

func (s *Snowman) setBase(b Base) {
for i, c := range b {
s[4][i+2] = c
}
}

type SnowmanCode [8]int

func snowmanCodeFromString(s string) (SnowmanCode, error) {
var result SnowmanCode
if len(s) != 8 {
return result, errors.New("expected 8 digits")
}
for i, digit := range s {
num, err := strconv.Atoi(string(digit))
if err != nil {
return result, err
}
result[i] = num
}
return result, nil
}

func randomCode() SnowmanCode {
return SnowmanCode{
rand.Intn(len(hats)) + 1,
rand.Intn(len(noses)) + 1,
rand.Intn(len(eyes)) + 1,
rand.Intn(len(eyes)) + 1,
rand.Intn(len(leftArms)) + 1,
rand.Intn(len(rightArms)) + 1,
rand.Intn(len(torsos)) + 1,
rand.Intn(len(bases)) + 1,
}
}

func SnowmanFromCode(c SnowmanCode) (Snowman, error) {
s := newSnowman()
if !(1 <= c[0] && c[0] <= len(hats)) {
return s, errors.New("hat code out of range")
}
if !(1 <= c[1] && c[1] <= len(noses)) {
return s, errors.New("nose code out of range")
}
if !(1 <= c[2] && c[2] <= len(eyes)) {
return s, errors.New("left eye code out of range")
}
if !(1 <= c[3] && c[3] <= len(eyes)) {
return s, errors.New("right eye code out of range")
}
if !(1 <= c[4] && c[4] <= len(leftArms)) {
return s, errors.New("left arm code out of range")
}
if !(1 <= c[5] && c[5] <= len(rightArms)) {
return s, errors.New("right arm code out of range")
}
if !(1 <= c[6] && c[6] <= len(torsos)) {
return s, errors.New("right arm code out of range")
}
if !(1 <= c[7] && c[7] <= len(bases)) {
return s, errors.New("right arm code out of range")
}
s.setHat(hats[c[0]-1])
s.setNose(noses[c[1]-1])
s.setLeftEye(eyes[c[2]-1])
s.setRightEye(eyes[c[3]-1])
s.setLeftArm(leftArms[c[4]-1])
s.setRightArm(rightArms[c[5]-1])
s.setTorso(torsos[c[6]-1])
s.setBase(bases[c[7]-1])
return s, nil
}

func codeFromArgsOrRandom() (SnowmanCode, error) {
if len(os.Args) > 1 {
return snowmanCodeFromString(os.Args[1])
} else {
return randomCode(), nil
}
}

func main() {
rand.Seed(time.Now().UnixNano())
code, err := codeFromArgsOrRandom()
if err != nil {
fmt.Println(err)
return
}
s, err := SnowmanFromCode(code)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(s)
}








share











$endgroup$












  • $begingroup$
    Incidentally, I just had to fix two bugs that I discovered after I posted the code. The first edit got merged into the initial revision, I had to change s.setBase(bases[c[6]-1]) to s.setBase(bases[c[7]-1])
    $endgroup$
    – mkrieger1
    1 min ago
















0












$begingroup$


I am learning Go and as an exercise I did this challenge from Code Golf (without the golfing), where an ASCII art snowman is drawn from a combination of body parts, based on an 8-digit code taken as command line argument.



For example:



$ ./snowman 12431312

_===_
(-.O)
<( : )
( : )


As a minor extension I decided to use a random code if none is passed.



Coming from Python, I had hoped to use the static typing to my advantage (e. g. by checking at compile time that the definition body parts is valid), but I have the feeling that I am fighting it more than it helps me.



I'd like to know how I can make the code less verbose and repetitive, without giving up the static checks.



snowman.go



package main

import (
"errors"
"fmt"
"math/rand"
"os"
"strconv"
"time"
)

type Snowman [5][7]rune

func (s Snowman) getLine(i int) string {
var line string
for _, c := range s[i] {
line += string(c)
}
return line
}

func (s Snowman) String() string {
var result string
for i := range s {
if i > 0 {
result += "n"
}
result += s.getLine(i)
}
return result
}

type Hat [2][5]rune
type Nose rune
type Eye rune
type LeftArm [2]rune
type RightArm [2]rune
type Torso [3]rune
type Base [3]rune

var hats = [...]Hat{
{{' ', ' ', ' ', ' ', ' '}, {'_', '=', '=', '=', '_'}},
{{' ', '_', '_', '_', ' '}, {'.', '.', '.', '.', '.'}},
{{' ', ' ', '_', ' ', ' '}, {' ', '/', '_', '\', ' '}},
{{' ', '_', '_', '_', ' '}, {'(', '_', '*', '_', ')'}},
}

var noses = [...]Nose{',', '.', '_', ' '}

var eyes = [...]Eye{'.', 'o', 'O', '-'}

var leftArms = [...]LeftArm{{' ', '<'}, {'\', ' '}, {' ', '/'}, {' ', ' '}}

var rightArms = [...]RightArm{{' ', '>'}, {'/', ' '}, {' ', '\'}, {' ', ' '}}

var torsos = [...]Torso{
{' ', ':', ' '},
{']', ' ', '['},
{'>', ' ', '<'},
{' ', ' ', ' '},
}

var bases = [...]Base{
{' ', ':', ' '},
{'"', ' ', '"'},
{'_', '_', '_'},
{' ', ' ', ' '},
}

// newSnowman returns a Snowman with no hat, arms, face, torso, or base.
func newSnowman() Snowman {
var s Snowman
for _, i := range [3]int{0, 1, 4} {
s[i][0] = ' '
s[i][6] = ' '
}
for i := 2; i < 5; i++ {
s[i][1] = '('
s[i][5] = ')'
}
return s
}

func (s *Snowman) setHat(h Hat) {
for i, line := range h {
for j, c := range line {
s[i][j+1] = c
}
}
}

func (s *Snowman) setNose(n Nose) {
s[2][3] = rune(n)
}

func (s *Snowman) setLeftEye(e Eye) {
s[2][2] = rune(e)
}

func (s *Snowman) setRightEye(e Eye) {
s[2][4] = rune(e)
}

func (s *Snowman) setLeftArm(a LeftArm) {
for i, c := range a {
s[i+2][0] = c
}
}

func (s *Snowman) setRightArm(a RightArm) {
for i, c := range a {
s[i+2][6] = c
}
}

func (s *Snowman) setTorso(t Torso) {
for i, c := range t {
s[3][i+2] = c
}
}

func (s *Snowman) setBase(b Base) {
for i, c := range b {
s[4][i+2] = c
}
}

type SnowmanCode [8]int

func snowmanCodeFromString(s string) (SnowmanCode, error) {
var result SnowmanCode
if len(s) != 8 {
return result, errors.New("expected 8 digits")
}
for i, digit := range s {
num, err := strconv.Atoi(string(digit))
if err != nil {
return result, err
}
result[i] = num
}
return result, nil
}

func randomCode() SnowmanCode {
return SnowmanCode{
rand.Intn(len(hats)) + 1,
rand.Intn(len(noses)) + 1,
rand.Intn(len(eyes)) + 1,
rand.Intn(len(eyes)) + 1,
rand.Intn(len(leftArms)) + 1,
rand.Intn(len(rightArms)) + 1,
rand.Intn(len(torsos)) + 1,
rand.Intn(len(bases)) + 1,
}
}

func SnowmanFromCode(c SnowmanCode) (Snowman, error) {
s := newSnowman()
if !(1 <= c[0] && c[0] <= len(hats)) {
return s, errors.New("hat code out of range")
}
if !(1 <= c[1] && c[1] <= len(noses)) {
return s, errors.New("nose code out of range")
}
if !(1 <= c[2] && c[2] <= len(eyes)) {
return s, errors.New("left eye code out of range")
}
if !(1 <= c[3] && c[3] <= len(eyes)) {
return s, errors.New("right eye code out of range")
}
if !(1 <= c[4] && c[4] <= len(leftArms)) {
return s, errors.New("left arm code out of range")
}
if !(1 <= c[5] && c[5] <= len(rightArms)) {
return s, errors.New("right arm code out of range")
}
if !(1 <= c[6] && c[6] <= len(torsos)) {
return s, errors.New("right arm code out of range")
}
if !(1 <= c[7] && c[7] <= len(bases)) {
return s, errors.New("right arm code out of range")
}
s.setHat(hats[c[0]-1])
s.setNose(noses[c[1]-1])
s.setLeftEye(eyes[c[2]-1])
s.setRightEye(eyes[c[3]-1])
s.setLeftArm(leftArms[c[4]-1])
s.setRightArm(rightArms[c[5]-1])
s.setTorso(torsos[c[6]-1])
s.setBase(bases[c[7]-1])
return s, nil
}

func codeFromArgsOrRandom() (SnowmanCode, error) {
if len(os.Args) > 1 {
return snowmanCodeFromString(os.Args[1])
} else {
return randomCode(), nil
}
}

func main() {
rand.Seed(time.Now().UnixNano())
code, err := codeFromArgsOrRandom()
if err != nil {
fmt.Println(err)
return
}
s, err := SnowmanFromCode(code)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(s)
}








share











$endgroup$












  • $begingroup$
    Incidentally, I just had to fix two bugs that I discovered after I posted the code. The first edit got merged into the initial revision, I had to change s.setBase(bases[c[6]-1]) to s.setBase(bases[c[7]-1])
    $endgroup$
    – mkrieger1
    1 min ago














0












0








0





$begingroup$


I am learning Go and as an exercise I did this challenge from Code Golf (without the golfing), where an ASCII art snowman is drawn from a combination of body parts, based on an 8-digit code taken as command line argument.



For example:



$ ./snowman 12431312

_===_
(-.O)
<( : )
( : )


As a minor extension I decided to use a random code if none is passed.



Coming from Python, I had hoped to use the static typing to my advantage (e. g. by checking at compile time that the definition body parts is valid), but I have the feeling that I am fighting it more than it helps me.



I'd like to know how I can make the code less verbose and repetitive, without giving up the static checks.



snowman.go



package main

import (
"errors"
"fmt"
"math/rand"
"os"
"strconv"
"time"
)

type Snowman [5][7]rune

func (s Snowman) getLine(i int) string {
var line string
for _, c := range s[i] {
line += string(c)
}
return line
}

func (s Snowman) String() string {
var result string
for i := range s {
if i > 0 {
result += "n"
}
result += s.getLine(i)
}
return result
}

type Hat [2][5]rune
type Nose rune
type Eye rune
type LeftArm [2]rune
type RightArm [2]rune
type Torso [3]rune
type Base [3]rune

var hats = [...]Hat{
{{' ', ' ', ' ', ' ', ' '}, {'_', '=', '=', '=', '_'}},
{{' ', '_', '_', '_', ' '}, {'.', '.', '.', '.', '.'}},
{{' ', ' ', '_', ' ', ' '}, {' ', '/', '_', '\', ' '}},
{{' ', '_', '_', '_', ' '}, {'(', '_', '*', '_', ')'}},
}

var noses = [...]Nose{',', '.', '_', ' '}

var eyes = [...]Eye{'.', 'o', 'O', '-'}

var leftArms = [...]LeftArm{{' ', '<'}, {'\', ' '}, {' ', '/'}, {' ', ' '}}

var rightArms = [...]RightArm{{' ', '>'}, {'/', ' '}, {' ', '\'}, {' ', ' '}}

var torsos = [...]Torso{
{' ', ':', ' '},
{']', ' ', '['},
{'>', ' ', '<'},
{' ', ' ', ' '},
}

var bases = [...]Base{
{' ', ':', ' '},
{'"', ' ', '"'},
{'_', '_', '_'},
{' ', ' ', ' '},
}

// newSnowman returns a Snowman with no hat, arms, face, torso, or base.
func newSnowman() Snowman {
var s Snowman
for _, i := range [3]int{0, 1, 4} {
s[i][0] = ' '
s[i][6] = ' '
}
for i := 2; i < 5; i++ {
s[i][1] = '('
s[i][5] = ')'
}
return s
}

func (s *Snowman) setHat(h Hat) {
for i, line := range h {
for j, c := range line {
s[i][j+1] = c
}
}
}

func (s *Snowman) setNose(n Nose) {
s[2][3] = rune(n)
}

func (s *Snowman) setLeftEye(e Eye) {
s[2][2] = rune(e)
}

func (s *Snowman) setRightEye(e Eye) {
s[2][4] = rune(e)
}

func (s *Snowman) setLeftArm(a LeftArm) {
for i, c := range a {
s[i+2][0] = c
}
}

func (s *Snowman) setRightArm(a RightArm) {
for i, c := range a {
s[i+2][6] = c
}
}

func (s *Snowman) setTorso(t Torso) {
for i, c := range t {
s[3][i+2] = c
}
}

func (s *Snowman) setBase(b Base) {
for i, c := range b {
s[4][i+2] = c
}
}

type SnowmanCode [8]int

func snowmanCodeFromString(s string) (SnowmanCode, error) {
var result SnowmanCode
if len(s) != 8 {
return result, errors.New("expected 8 digits")
}
for i, digit := range s {
num, err := strconv.Atoi(string(digit))
if err != nil {
return result, err
}
result[i] = num
}
return result, nil
}

func randomCode() SnowmanCode {
return SnowmanCode{
rand.Intn(len(hats)) + 1,
rand.Intn(len(noses)) + 1,
rand.Intn(len(eyes)) + 1,
rand.Intn(len(eyes)) + 1,
rand.Intn(len(leftArms)) + 1,
rand.Intn(len(rightArms)) + 1,
rand.Intn(len(torsos)) + 1,
rand.Intn(len(bases)) + 1,
}
}

func SnowmanFromCode(c SnowmanCode) (Snowman, error) {
s := newSnowman()
if !(1 <= c[0] && c[0] <= len(hats)) {
return s, errors.New("hat code out of range")
}
if !(1 <= c[1] && c[1] <= len(noses)) {
return s, errors.New("nose code out of range")
}
if !(1 <= c[2] && c[2] <= len(eyes)) {
return s, errors.New("left eye code out of range")
}
if !(1 <= c[3] && c[3] <= len(eyes)) {
return s, errors.New("right eye code out of range")
}
if !(1 <= c[4] && c[4] <= len(leftArms)) {
return s, errors.New("left arm code out of range")
}
if !(1 <= c[5] && c[5] <= len(rightArms)) {
return s, errors.New("right arm code out of range")
}
if !(1 <= c[6] && c[6] <= len(torsos)) {
return s, errors.New("right arm code out of range")
}
if !(1 <= c[7] && c[7] <= len(bases)) {
return s, errors.New("right arm code out of range")
}
s.setHat(hats[c[0]-1])
s.setNose(noses[c[1]-1])
s.setLeftEye(eyes[c[2]-1])
s.setRightEye(eyes[c[3]-1])
s.setLeftArm(leftArms[c[4]-1])
s.setRightArm(rightArms[c[5]-1])
s.setTorso(torsos[c[6]-1])
s.setBase(bases[c[7]-1])
return s, nil
}

func codeFromArgsOrRandom() (SnowmanCode, error) {
if len(os.Args) > 1 {
return snowmanCodeFromString(os.Args[1])
} else {
return randomCode(), nil
}
}

func main() {
rand.Seed(time.Now().UnixNano())
code, err := codeFromArgsOrRandom()
if err != nil {
fmt.Println(err)
return
}
s, err := SnowmanFromCode(code)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(s)
}








share











$endgroup$




I am learning Go and as an exercise I did this challenge from Code Golf (without the golfing), where an ASCII art snowman is drawn from a combination of body parts, based on an 8-digit code taken as command line argument.



For example:



$ ./snowman 12431312

_===_
(-.O)
<( : )
( : )


As a minor extension I decided to use a random code if none is passed.



Coming from Python, I had hoped to use the static typing to my advantage (e. g. by checking at compile time that the definition body parts is valid), but I have the feeling that I am fighting it more than it helps me.



I'd like to know how I can make the code less verbose and repetitive, without giving up the static checks.



snowman.go



package main

import (
"errors"
"fmt"
"math/rand"
"os"
"strconv"
"time"
)

type Snowman [5][7]rune

func (s Snowman) getLine(i int) string {
var line string
for _, c := range s[i] {
line += string(c)
}
return line
}

func (s Snowman) String() string {
var result string
for i := range s {
if i > 0 {
result += "n"
}
result += s.getLine(i)
}
return result
}

type Hat [2][5]rune
type Nose rune
type Eye rune
type LeftArm [2]rune
type RightArm [2]rune
type Torso [3]rune
type Base [3]rune

var hats = [...]Hat{
{{' ', ' ', ' ', ' ', ' '}, {'_', '=', '=', '=', '_'}},
{{' ', '_', '_', '_', ' '}, {'.', '.', '.', '.', '.'}},
{{' ', ' ', '_', ' ', ' '}, {' ', '/', '_', '\', ' '}},
{{' ', '_', '_', '_', ' '}, {'(', '_', '*', '_', ')'}},
}

var noses = [...]Nose{',', '.', '_', ' '}

var eyes = [...]Eye{'.', 'o', 'O', '-'}

var leftArms = [...]LeftArm{{' ', '<'}, {'\', ' '}, {' ', '/'}, {' ', ' '}}

var rightArms = [...]RightArm{{' ', '>'}, {'/', ' '}, {' ', '\'}, {' ', ' '}}

var torsos = [...]Torso{
{' ', ':', ' '},
{']', ' ', '['},
{'>', ' ', '<'},
{' ', ' ', ' '},
}

var bases = [...]Base{
{' ', ':', ' '},
{'"', ' ', '"'},
{'_', '_', '_'},
{' ', ' ', ' '},
}

// newSnowman returns a Snowman with no hat, arms, face, torso, or base.
func newSnowman() Snowman {
var s Snowman
for _, i := range [3]int{0, 1, 4} {
s[i][0] = ' '
s[i][6] = ' '
}
for i := 2; i < 5; i++ {
s[i][1] = '('
s[i][5] = ')'
}
return s
}

func (s *Snowman) setHat(h Hat) {
for i, line := range h {
for j, c := range line {
s[i][j+1] = c
}
}
}

func (s *Snowman) setNose(n Nose) {
s[2][3] = rune(n)
}

func (s *Snowman) setLeftEye(e Eye) {
s[2][2] = rune(e)
}

func (s *Snowman) setRightEye(e Eye) {
s[2][4] = rune(e)
}

func (s *Snowman) setLeftArm(a LeftArm) {
for i, c := range a {
s[i+2][0] = c
}
}

func (s *Snowman) setRightArm(a RightArm) {
for i, c := range a {
s[i+2][6] = c
}
}

func (s *Snowman) setTorso(t Torso) {
for i, c := range t {
s[3][i+2] = c
}
}

func (s *Snowman) setBase(b Base) {
for i, c := range b {
s[4][i+2] = c
}
}

type SnowmanCode [8]int

func snowmanCodeFromString(s string) (SnowmanCode, error) {
var result SnowmanCode
if len(s) != 8 {
return result, errors.New("expected 8 digits")
}
for i, digit := range s {
num, err := strconv.Atoi(string(digit))
if err != nil {
return result, err
}
result[i] = num
}
return result, nil
}

func randomCode() SnowmanCode {
return SnowmanCode{
rand.Intn(len(hats)) + 1,
rand.Intn(len(noses)) + 1,
rand.Intn(len(eyes)) + 1,
rand.Intn(len(eyes)) + 1,
rand.Intn(len(leftArms)) + 1,
rand.Intn(len(rightArms)) + 1,
rand.Intn(len(torsos)) + 1,
rand.Intn(len(bases)) + 1,
}
}

func SnowmanFromCode(c SnowmanCode) (Snowman, error) {
s := newSnowman()
if !(1 <= c[0] && c[0] <= len(hats)) {
return s, errors.New("hat code out of range")
}
if !(1 <= c[1] && c[1] <= len(noses)) {
return s, errors.New("nose code out of range")
}
if !(1 <= c[2] && c[2] <= len(eyes)) {
return s, errors.New("left eye code out of range")
}
if !(1 <= c[3] && c[3] <= len(eyes)) {
return s, errors.New("right eye code out of range")
}
if !(1 <= c[4] && c[4] <= len(leftArms)) {
return s, errors.New("left arm code out of range")
}
if !(1 <= c[5] && c[5] <= len(rightArms)) {
return s, errors.New("right arm code out of range")
}
if !(1 <= c[6] && c[6] <= len(torsos)) {
return s, errors.New("right arm code out of range")
}
if !(1 <= c[7] && c[7] <= len(bases)) {
return s, errors.New("right arm code out of range")
}
s.setHat(hats[c[0]-1])
s.setNose(noses[c[1]-1])
s.setLeftEye(eyes[c[2]-1])
s.setRightEye(eyes[c[3]-1])
s.setLeftArm(leftArms[c[4]-1])
s.setRightArm(rightArms[c[5]-1])
s.setTorso(torsos[c[6]-1])
s.setBase(bases[c[7]-1])
return s, nil
}

func codeFromArgsOrRandom() (SnowmanCode, error) {
if len(os.Args) > 1 {
return snowmanCodeFromString(os.Args[1])
} else {
return randomCode(), nil
}
}

func main() {
rand.Seed(time.Now().UnixNano())
code, err := codeFromArgsOrRandom()
if err != nil {
fmt.Println(err)
return
}
s, err := SnowmanFromCode(code)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(s)
}






beginner go ascii-art





share














share












share



share








edited 3 mins ago







mkrieger1

















asked 9 mins ago









mkrieger1mkrieger1

1,3881723




1,3881723












  • $begingroup$
    Incidentally, I just had to fix two bugs that I discovered after I posted the code. The first edit got merged into the initial revision, I had to change s.setBase(bases[c[6]-1]) to s.setBase(bases[c[7]-1])
    $endgroup$
    – mkrieger1
    1 min ago


















  • $begingroup$
    Incidentally, I just had to fix two bugs that I discovered after I posted the code. The first edit got merged into the initial revision, I had to change s.setBase(bases[c[6]-1]) to s.setBase(bases[c[7]-1])
    $endgroup$
    – mkrieger1
    1 min ago
















$begingroup$
Incidentally, I just had to fix two bugs that I discovered after I posted the code. The first edit got merged into the initial revision, I had to change s.setBase(bases[c[6]-1]) to s.setBase(bases[c[7]-1])
$endgroup$
– mkrieger1
1 min ago




$begingroup$
Incidentally, I just had to fix two bugs that I discovered after I posted the code. The first edit got merged into the initial revision, I had to change s.setBase(bases[c[6]-1]) to s.setBase(bases[c[7]-1])
$endgroup$
– mkrieger1
1 min ago










0






active

oldest

votes











Your Answer





StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");

StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f215090%2fdrawing-a-snowman-in-ascii-art%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























0






active

oldest

votes








0






active

oldest

votes









active

oldest

votes






active

oldest

votes
















draft saved

draft discarded




















































Thanks for contributing an answer to Code Review Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


Use MathJax to format equations. MathJax reference.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f215090%2fdrawing-a-snowman-in-ascii-art%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

404 Error Contact Form 7 ajax form submitting

How to know if a Active Directory user can login interactively

TypeError: fit_transform() missing 1 required positional argument: 'X'