Move code out of cmd
This commit is contained in:
10
day1/example.txt
Normal file
10
day1/example.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
L68
|
||||
L30
|
||||
R48
|
||||
L5
|
||||
R60
|
||||
L55
|
||||
L1
|
||||
L99
|
||||
R14
|
||||
L82
|
||||
4503
day1/input.txt
Normal file
4503
day1/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
147
day1/main.go
Normal file
147
day1/main.go
Normal file
@@ -0,0 +1,147 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func main() {
|
||||
debug := flag.Bool("debug", false, "Debug flag.")
|
||||
flag.Parse()
|
||||
|
||||
d1 := dial{n: 50}
|
||||
d2 := dial{n: 50}
|
||||
if *debug {
|
||||
fmt.Println("LINE d1 d2")
|
||||
fmt.Println(" 50 50")
|
||||
}
|
||||
|
||||
sc := bufio.NewScanner(os.Stdin)
|
||||
for sc.Scan() {
|
||||
if sc.Text() == "" {
|
||||
log.Fatal("empty line")
|
||||
}
|
||||
n, err := strconv.ParseUint(sc.Text()[1:], 10, 0)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
i := int(n)
|
||||
if sc.Text()[0] == 'L' {
|
||||
i = -int(n)
|
||||
}
|
||||
|
||||
// if err := handleLine(d1.Add1, sc.Text()); err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
if err := handleLine(d1.Add1, sc.Text()); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if err := handleLine(d2.Add2, sc.Text()); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if *debug {
|
||||
fmt.Printf("%+4d %2d %2d (%+3d %+3d)\n", i, d1.n, d2.n, d1.lastClicks, d2.lastClicks)
|
||||
}
|
||||
}
|
||||
if err := sc.Err(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Println("zeros:", d1.zeros, d2.zeros)
|
||||
fmt.Println("zero passes:", d1.zeroClicks, d2.zeroClicks)
|
||||
}
|
||||
|
||||
func handleLine(add func(int), line string) error {
|
||||
if line == "" {
|
||||
return errors.New("empty line")
|
||||
}
|
||||
n, err := strconv.ParseUint(line[1:], 10, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch line[0] {
|
||||
case 'L':
|
||||
add(-int(n))
|
||||
return nil
|
||||
case 'R':
|
||||
add(int(n))
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("unexpected line: %q", line)
|
||||
}
|
||||
}
|
||||
|
||||
type dial struct {
|
||||
n int
|
||||
lastClicks int
|
||||
zeros int
|
||||
zeroClicks int
|
||||
}
|
||||
|
||||
func (d *dial) Add1(n int) {
|
||||
wasAtZero := d.n == 0
|
||||
d.n += n
|
||||
step := +100
|
||||
if d.n < 0 {
|
||||
step = -100
|
||||
}
|
||||
d.lastClicks = 0
|
||||
for d.n < 0 || d.n > 99 {
|
||||
d.lastClicks++
|
||||
d.n -= step
|
||||
}
|
||||
if d.lastClicks > 0 && wasAtZero {
|
||||
d.lastClicks--
|
||||
}
|
||||
if d.n == 0 {
|
||||
d.zeros++
|
||||
if d.lastClicks == 0 {
|
||||
d.lastClicks++
|
||||
}
|
||||
}
|
||||
d.zeroClicks += d.lastClicks
|
||||
}
|
||||
|
||||
func (d *dial) Add2(diff int) {
|
||||
n := d.n + diff
|
||||
|
||||
var clicks int
|
||||
switch {
|
||||
case n < 0:
|
||||
wasAtZero := d.n == 0
|
||||
for n < 0 {
|
||||
if wasAtZero {
|
||||
wasAtZero = false
|
||||
} else {
|
||||
clicks++
|
||||
}
|
||||
n += 100
|
||||
}
|
||||
if n == 0 && !wasAtZero {
|
||||
clicks++
|
||||
}
|
||||
|
||||
case n > 99:
|
||||
for n > 99 {
|
||||
clicks++
|
||||
n -= 100
|
||||
}
|
||||
|
||||
default:
|
||||
if n == 0 && d.n != 0 {
|
||||
clicks++
|
||||
}
|
||||
}
|
||||
|
||||
if n == 0 {
|
||||
d.zeros++
|
||||
}
|
||||
d.n = n
|
||||
d.lastClicks = clicks
|
||||
d.zeroClicks += clicks
|
||||
}
|
||||
80
day1/main_test.go
Normal file
80
day1/main_test.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_dial_Add2(t *testing.T) {
|
||||
tests := []struct {
|
||||
start int
|
||||
turn int
|
||||
want int
|
||||
wantClicks int
|
||||
}{
|
||||
{
|
||||
start: 50,
|
||||
turn: 300,
|
||||
want: 50,
|
||||
wantClicks: 3,
|
||||
},
|
||||
{
|
||||
start: 50,
|
||||
turn: -300,
|
||||
want: 50,
|
||||
wantClicks: 3,
|
||||
},
|
||||
|
||||
{
|
||||
start: 0,
|
||||
turn: -100,
|
||||
want: 0,
|
||||
wantClicks: 1,
|
||||
},
|
||||
{
|
||||
start: 1,
|
||||
turn: -101,
|
||||
want: 0,
|
||||
wantClicks: 2,
|
||||
},
|
||||
{
|
||||
start: 99,
|
||||
turn: -199,
|
||||
want: 0,
|
||||
wantClicks: 2,
|
||||
},
|
||||
|
||||
{
|
||||
start: 0,
|
||||
turn: 100,
|
||||
want: 0,
|
||||
wantClicks: 1,
|
||||
},
|
||||
{
|
||||
start: 99,
|
||||
turn: 101,
|
||||
want: 0,
|
||||
wantClicks: 2,
|
||||
},
|
||||
{
|
||||
start: 1,
|
||||
turn: 199,
|
||||
want: 0,
|
||||
wantClicks: 2,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
name := fmt.Sprintf("R%d", tt.turn)
|
||||
if tt.turn < 0 {
|
||||
name = fmt.Sprintf("L%d", -tt.turn)
|
||||
}
|
||||
t.Run(name, func(t *testing.T) {
|
||||
d := dial{n: tt.start}
|
||||
d.Add2(tt.turn)
|
||||
assert.Equal(t, tt.want, d.n, "dial")
|
||||
assert.Equal(t, tt.wantClicks, d.zeroClicks, "clicks")
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user