days 13,14,15
This commit is contained in:
parent
97a068bfc3
commit
cccd9976df
4 changed files with 400 additions and 0 deletions
176
13/13.go
Normal file
176
13/13.go
Normal file
|
@ -0,0 +1,176 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type firewall struct {
|
||||||
|
pos int
|
||||||
|
size int
|
||||||
|
current int
|
||||||
|
up bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// cat input | go run 13.go
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(os.Stdin)
|
||||||
|
|
||||||
|
var fwdata = make(map[int]firewall)
|
||||||
|
|
||||||
|
for scanner.Scan() {
|
||||||
|
|
||||||
|
s := strings.Split(scanner.Text(), ": ")
|
||||||
|
pos, _ := strconv.Atoi(s[0])
|
||||||
|
size, _ := strconv.Atoi(s[1])
|
||||||
|
fwdata[pos] = firewall{pos, size - 1, 0, true}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(RunFirewall(fwdata, 0))
|
||||||
|
// We only need to do this once with RunFirewallFast
|
||||||
|
fwdata = ResetHash(fwdata)
|
||||||
|
|
||||||
|
start := time.Now()
|
||||||
|
|
||||||
|
fmt.Println(FindDelay(fwdata))
|
||||||
|
|
||||||
|
t := time.Now()
|
||||||
|
elapsed := t.Sub(start)
|
||||||
|
fmt.Println(elapsed)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func ResetHash(fw map[int]firewall) map[int]firewall {
|
||||||
|
for k, v := range fw {
|
||||||
|
v.current = 0
|
||||||
|
fw[k] = v
|
||||||
|
}
|
||||||
|
return fw
|
||||||
|
}
|
||||||
|
|
||||||
|
func FindDelay(fw map[int]firewall) int {
|
||||||
|
|
||||||
|
// Work out the final position.
|
||||||
|
var keys []int
|
||||||
|
for k := range fw {
|
||||||
|
keys = append(keys, k)
|
||||||
|
}
|
||||||
|
sort.Ints(keys)
|
||||||
|
endpos := keys[len(keys)-1]
|
||||||
|
|
||||||
|
// Using an array instead of hashmap drops from 300ms to 125 on my machine for my solution (3.96 million delay)
|
||||||
|
var t []int
|
||||||
|
for x := 0; x <= endpos; x++ {
|
||||||
|
t = append(t, (fw[x].size * 2))
|
||||||
|
}
|
||||||
|
|
||||||
|
Loop:
|
||||||
|
for i := 0; ; i++ {
|
||||||
|
// You can see earlier, slower (~300ms) version of this inner loop as a function below. This brings it down to ~100ms.
|
||||||
|
for j := i; j <= i+endpos; j++ {
|
||||||
|
p := t[j-i]
|
||||||
|
if p != 0 && j%p == 0 {
|
||||||
|
continue Loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
|
// slower hashmap version
|
||||||
|
/*
|
||||||
|
for i := 0; ; i++ {
|
||||||
|
_, caught := RunFirewallFast(fw, i, endpos)
|
||||||
|
if !caught {
|
||||||
|
fmt.Println(i)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
// Well, the obvious solution is incredibly slow, and we don't need
|
||||||
|
// to resolve the full 'caught' number, so we can make this dramatically faster.
|
||||||
|
// It took less time to rewrite this than to run the result using RunFirewall...
|
||||||
|
func RunFirewallFast(fw map[int]firewall, delay int, endpos int) (int, bool) {
|
||||||
|
for j := delay; j <= delay+endpos; j++ {
|
||||||
|
a, exists := fw[j-delay]
|
||||||
|
if exists {
|
||||||
|
interval := a.size * 2
|
||||||
|
if j%interval == 0 {
|
||||||
|
return 0, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func RunFirewall(fw map[int]firewall, delay int) (int, bool) {
|
||||||
|
caught := 0
|
||||||
|
caughtBool := false
|
||||||
|
|
||||||
|
var keys []int
|
||||||
|
for k := range fw {
|
||||||
|
keys = append(keys, k)
|
||||||
|
}
|
||||||
|
sort.Ints(keys)
|
||||||
|
|
||||||
|
endpos := keys[len(keys)-1]
|
||||||
|
mypos := -1
|
||||||
|
|
||||||
|
for i := 0; ; i++ {
|
||||||
|
|
||||||
|
// Start moving after the delay
|
||||||
|
if i >= delay {
|
||||||
|
mypos++
|
||||||
|
}
|
||||||
|
|
||||||
|
// Have we been caught?
|
||||||
|
_, exists := fw[mypos]
|
||||||
|
if exists && mypos >= 0 && fw[mypos].current == 0 {
|
||||||
|
caught = caught + (fw[mypos].pos * (fw[mypos].size + 1))
|
||||||
|
fmt.Println("Caught", mypos, caught, i, delay)
|
||||||
|
caughtBool = true
|
||||||
|
// Skip further rounds if we're just looking for the delay
|
||||||
|
if delay > 0 {
|
||||||
|
return 0, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// End!
|
||||||
|
if mypos == endpos {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move scanners for this round
|
||||||
|
for _, k := range keys {
|
||||||
|
c := fw[k]
|
||||||
|
|
||||||
|
if c.current == c.size {
|
||||||
|
c.up = false
|
||||||
|
}
|
||||||
|
if c.current == 0 {
|
||||||
|
c.up = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.up {
|
||||||
|
c.current++
|
||||||
|
} else {
|
||||||
|
c.current--
|
||||||
|
}
|
||||||
|
|
||||||
|
fw[k] = c
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return caught, caughtBool
|
||||||
|
|
||||||
|
}
|
36
13/13_test.go
Normal file
36
13/13_test.go
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
var test = map[int]firewall{
|
||||||
|
0: {0, 2, 0, true},
|
||||||
|
1: {1, 1, 0, true},
|
||||||
|
4: {4, 3, 0, true},
|
||||||
|
6: {6, 3, 0, true},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFindDelay(t *testing.T) {
|
||||||
|
test = ResetHash(test)
|
||||||
|
v := FindDelay(test)
|
||||||
|
if v != 10 {
|
||||||
|
t.Error(
|
||||||
|
"For", test,
|
||||||
|
"expected 10",
|
||||||
|
"got", v,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRunFirewall(t *testing.T) {
|
||||||
|
test = ResetHash(test)
|
||||||
|
v, _ := RunFirewall(test, 0)
|
||||||
|
if v != 24 {
|
||||||
|
t.Error(
|
||||||
|
"For", test,
|
||||||
|
"expected 24",
|
||||||
|
"got", v,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
131
14/14.go
Normal file
131
14/14.go
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
//"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// go run 14.go "input"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
s := os.Args[1]
|
||||||
|
ones := 0
|
||||||
|
|
||||||
|
squareSize := 128
|
||||||
|
grid := make([][]int, squareSize)
|
||||||
|
|
||||||
|
for x := 0; x < squareSize; x++ {
|
||||||
|
lineSeed := fmt.Sprint(s, "-", x)
|
||||||
|
hash := MakeHash(lineSeed)
|
||||||
|
ones += CountOnes(hash)
|
||||||
|
grid[x] = BuildGrid(hash)
|
||||||
|
}
|
||||||
|
|
||||||
|
regionCount := 1
|
||||||
|
for y := 0; y < squareSize; y++ {
|
||||||
|
for x := 0; x < squareSize; x++ {
|
||||||
|
grid, regionCount = CountRegions(grid, x, y, regionCount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(ones)
|
||||||
|
fmt.Println(regionCount-1)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func CountRegions (grid [][]int, x int, y int, regionCount int) ([][]int, int) {
|
||||||
|
if x < 0 || x >= len(grid) || y < 0 || y >= len(grid) {
|
||||||
|
return grid,regionCount
|
||||||
|
}
|
||||||
|
|
||||||
|
if grid[x][y] == -1 {
|
||||||
|
return grid, regionCount
|
||||||
|
}
|
||||||
|
|
||||||
|
if grid[x][y] == 0 {
|
||||||
|
grid[x][y] = regionCount
|
||||||
|
grid,_ = CountRegions(grid, x+1, y, regionCount)
|
||||||
|
grid,_ = CountRegions(grid, x-1, y, regionCount)
|
||||||
|
grid,_ = CountRegions(grid, x, y+1, regionCount)
|
||||||
|
grid,_ = CountRegions(grid, x, y-1, regionCount)
|
||||||
|
regionCount++
|
||||||
|
}
|
||||||
|
|
||||||
|
return grid, regionCount
|
||||||
|
}
|
||||||
|
|
||||||
|
func BuildGrid (s string) []int {
|
||||||
|
y := make([]int, len(s))
|
||||||
|
|
||||||
|
for i := range s {
|
||||||
|
if s[i] == 49 {
|
||||||
|
y[i] = 0
|
||||||
|
} else {
|
||||||
|
y[i] = -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return y
|
||||||
|
}
|
||||||
|
|
||||||
|
func CountOnes (s string) int {
|
||||||
|
count := 0
|
||||||
|
for x := range s {
|
||||||
|
if s[x] == 49 {
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func MakeHash (s string) string {
|
||||||
|
|
||||||
|
size := 256
|
||||||
|
appendList := []byte{17, 31, 73, 47, 23}
|
||||||
|
|
||||||
|
s = s + string(appendList)
|
||||||
|
|
||||||
|
list := make([]int, size)
|
||||||
|
for i := 0; i < size; i++ {
|
||||||
|
list[i] = i
|
||||||
|
}
|
||||||
|
|
||||||
|
pos := 0
|
||||||
|
skip := 0
|
||||||
|
|
||||||
|
for j := 0; j < 64; j++ {
|
||||||
|
for x := range s {
|
||||||
|
|
||||||
|
i := int(s[x])
|
||||||
|
|
||||||
|
// Reverse the section
|
||||||
|
r := i/2
|
||||||
|
|
||||||
|
for y := 0; y < r; y++ {
|
||||||
|
bottom := (pos+y) % size
|
||||||
|
top := (pos+i-y-1) % size
|
||||||
|
tmp := list[bottom]
|
||||||
|
list[bottom] = list[top]
|
||||||
|
list[top] = tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = (pos+i+skip) % size
|
||||||
|
skip++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret := ""
|
||||||
|
for a:=0; a<16; a++ {
|
||||||
|
r := list[a*16]
|
||||||
|
for b:=1; b<16; b++ {
|
||||||
|
xorpos := (a*16)+b
|
||||||
|
r = r ^ list[xorpos]
|
||||||
|
}
|
||||||
|
ret = ret + fmt.Sprintf("%08b", r) //+ " "
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
|
||||||
|
}
|
57
15/15.go
Normal file
57
15/15.go
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// go run 15.go inputA inputB
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
genA,_ := strconv.Atoi(os.Args[1])
|
||||||
|
genB,_ := strconv.Atoi(os.Args[2])
|
||||||
|
|
||||||
|
rounds1 := 40000000
|
||||||
|
rounds2 := 5000000
|
||||||
|
|
||||||
|
fmt.Println(Calc(genA, genB, 1,1,rounds1))
|
||||||
|
fmt.Println(Calc(genA, genB, 4,8,rounds2))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func Calc (genA int, genB int, modA int, modB int, rounds int) int {
|
||||||
|
genAFactor := 16807
|
||||||
|
genBFactor := 48271
|
||||||
|
div := 2147483647
|
||||||
|
judge := 0
|
||||||
|
|
||||||
|
for i := 0; i < rounds; i++ {
|
||||||
|
|
||||||
|
for {
|
||||||
|
genA = (genA * genAFactor) % div
|
||||||
|
if genA % modA == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
genB = (genB * genBFactor) % div
|
||||||
|
if genB % modB == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tA := genA
|
||||||
|
tA = tA % 65536
|
||||||
|
|
||||||
|
tB := genB
|
||||||
|
tB = tB % 65536
|
||||||
|
|
||||||
|
if tA == tB {
|
||||||
|
judge++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return judge
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue