Compare commits
6 Commits
2347ad523b
...
main
Author | SHA1 | Date | |
---|---|---|---|
ff9c8315c1
|
|||
691c59462a
|
|||
cb63c009cc
|
|||
281cb218b3
|
|||
5bbf188285
|
|||
b70e8d38de
|
17
README.md
17
README.md
@ -1,3 +1,20 @@
|
|||||||
# uckf
|
# uckf
|
||||||
|
|
||||||
A deeply unsatisfying word search.
|
A deeply unsatisfying word search.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
1. [install the Go compiler](https://go.dev/dl/) if you don't have it yet
|
||||||
|
2. clone this repo (`git clone https://git.chromaticdragon.app/kistaro/uckf.git`)
|
||||||
|
3. `go run uckf.go`
|
||||||
|
4. you can use `-n` to specify a different grid size; for example, `go run uckf.go -n 100` will create a 100x100 unsatisfying word search
|
||||||
|
|
||||||
|
### Flags
|
||||||
|
|
||||||
|
* `-n <int>` -- use a grid with edges of length n
|
||||||
|
* `-s` -- summary mode; do not print intermediate grids, only summaries
|
||||||
|
* `-r=false` -- suppress final result (only print a summary for that)
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
This algorithm converges much more quickly than I expected.
|
||||||
|
53
uckf.go
53
uckf.go
@ -9,7 +9,12 @@ import (
|
|||||||
"math/rand"
|
"math/rand"
|
||||||
)
|
)
|
||||||
|
|
||||||
var edgeSize = flag.Int("n", 4, "Cells per side")
|
var (
|
||||||
|
edgeSize = flag.Int("n", 15, "Cells per side")
|
||||||
|
summarize = flag.Bool("s", false, "Summarize when iterating")
|
||||||
|
showResult = flag.Bool("r", true, "Show final result (default true)")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
type scanState int
|
type scanState int
|
||||||
const (
|
const (
|
||||||
@ -34,25 +39,43 @@ func main() {
|
|||||||
board=append(board, fuckingRow)
|
board=append(board, fuckingRow)
|
||||||
}
|
}
|
||||||
|
|
||||||
dump(board, "Starting position")
|
|
||||||
|
|
||||||
var evals [][]fuckness
|
var evals [][]fuckness
|
||||||
for i := 0; i < *edgeSize; i++ {
|
for i := 0; i < *edgeSize; i++ {
|
||||||
evals = append(evals, make([]fuckness, *edgeSize))
|
evals = append(evals, make([]fuckness, *edgeSize))
|
||||||
}
|
}
|
||||||
|
|
||||||
iterations := uint64(0)
|
iterations := uint64(0)
|
||||||
scream := uint64(1)
|
scream := uint64(0)
|
||||||
for(isStillFucked(board, evals)) {
|
for(isStillFucked(board, evals)) {
|
||||||
fuckUp(board, evals)
|
|
||||||
iterations++
|
|
||||||
if iterations >= scream {
|
if iterations >= scream {
|
||||||
dump(board, fmt.Sprint("Iteration", iterations))
|
if (*summarize) {
|
||||||
|
emitSummary(evals, iterations)
|
||||||
|
} else {
|
||||||
|
dump(board, evals, fmt.Sprint("Iteration ", iterations))
|
||||||
|
}
|
||||||
scream = iterations << 1
|
scream = iterations << 1
|
||||||
}
|
}
|
||||||
|
iterations++
|
||||||
|
fuckUp(board, evals)
|
||||||
}
|
}
|
||||||
|
|
||||||
dump(board, "Not a single fuck")
|
if (*showResult) {
|
||||||
|
dump(board, evals, fmt.Sprintf("Not a single fuck (%d iterations)", iterations))
|
||||||
|
} else {
|
||||||
|
emitSummary(evals, iterations)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func emitSummary(evals [][]fuckness, iterations uint64) {
|
||||||
|
nFucked := uint64(0)
|
||||||
|
for _, row := range evals {
|
||||||
|
for _, e := range row {
|
||||||
|
if isFucked(e) {
|
||||||
|
nFucked++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Printf("Iteration %d: %d fucked (%.2f%%)\n", iterations, nFucked, 100 * float64(nFucked)/(float64(*edgeSize * *edgeSize)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func onBoard(i, j int) bool {
|
func onBoard(i, j int) bool {
|
||||||
@ -127,7 +150,7 @@ func mightBeFucked(f fuckness) bool {
|
|||||||
if i == 1 && j == 1 {
|
if i == 1 && j == 1 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if f[i][j] == NotFucked {
|
if f[i][j] != NotFucked {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -142,7 +165,7 @@ func fuckUp(board [][]byte, evals [][]fuckness) {
|
|||||||
if isFucked(e) {
|
if isFucked(e) {
|
||||||
todo = append(todo, [2]int{i, j})
|
todo = append(todo, [2]int{i, j})
|
||||||
} else if mightBeFucked(e) {
|
} else if mightBeFucked(e) {
|
||||||
dump(board, "Oh fuck")
|
dump(board, evals, "Oh fuck")
|
||||||
log.Fatalf("unevaluated fuckness at %d, %d: %v", i, j, e)
|
log.Fatalf("unevaluated fuckness at %d, %d: %v", i, j, e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -195,7 +218,7 @@ func unevaluate(evals [][]fuckness, i, j int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func dump(board [][]byte, title string) {
|
func dump(board [][]byte, evals [][]fuckness, title string) {
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
for i := 0; i < *edgeSize; i++ {
|
for i := 0; i < *edgeSize; i++ {
|
||||||
fmt.Print("--")
|
fmt.Print("--")
|
||||||
@ -203,10 +226,14 @@ func dump(board [][]byte, title string) {
|
|||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println(title)
|
fmt.Println(title)
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
for _, row := range board {
|
for i, row := range board {
|
||||||
for _, r := range row {
|
for j, r := range row {
|
||||||
|
if isFucked(evals[i][j]) {
|
||||||
|
fmt.Printf("%c ", "FUCK"[r])
|
||||||
|
} else {
|
||||||
fmt.Printf("%c ", "fuck"[r])
|
fmt.Printf("%c ", "fuck"[r])
|
||||||
}
|
}
|
||||||
|
}
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user