diff --git a/puzzle-hunt/.gitignore b/puzzle-hunt/.gitignore
new file mode 100644
index 0000000..1d17dae
--- /dev/null
+++ b/puzzle-hunt/.gitignore
@@ -0,0 +1 @@
+.venv
diff --git a/puzzle-hunt/.ruby-version b/puzzle-hunt/.ruby-version
new file mode 100644
index 0000000..00750ed
--- /dev/null
+++ b/puzzle-hunt/.ruby-version
@@ -0,0 +1 @@
+3
diff --git a/puzzle-hunt/gogoat.go b/puzzle-hunt/gogoat.go
new file mode 100644
index 0000000..33d6043
--- /dev/null
+++ b/puzzle-hunt/gogoat.go
@@ -0,0 +1,60 @@
+package main
+
+import (
+ "fmt"
+ "time"
+)
+
+func main() {
+ for i := 6000; i < 10000; i++ {
+ time.Sleep(time.Second / 15.0)
+ fmt.Println(i)
+ fmt.Println(goat(i))
+ }
+}
+
+// Goat.
+func goat(food int) (poop string) {
+
+ food=food ^0x33bee6
+ c:="^"+ "][n"+
+ "_"+ "]"+
+ "_"+ "n"+
+ "^]"+ "[n"+
+ "^]"+ "[n"+
+ "^]"+ "[n"+
+ "^Y["+ "n^@"+ "ZJr"+ "TCv"+
+ "V]A\\nX;"+ "Y\\JP^ZmSN^ERffTRvRXKZ="+ "Kkztxz<["+
+ "_RN^DRFbTRvVIAX<ikY\\xr<[oCN^ERffXX?VMIZ<ik>Fzz<[_BN^ERJS"+
+ "xIovYC\\nXq\\Nxp_[_SN^][n^?[n?][n^][n^][n^]Sn^LJLRNnLSl"+
+ "JN"+ "?????????y[n^QSj^QG>^?[n^][N_QAbLU["+ "n^"+
+ "U[fNUC?>?QdRASL_TKnRL[n^Q[fNQKo??;`"+
+ "\\T[L>TKl^\\[n^U[fNUR??=?`\\UKM^TKN"+
+ "^\\[n^U[j^USM>]WxL]R\\RDJn^\\[n^][n"+
+ "^][oR"+ "]YsdQOn^U[NLM[n"+ "^][n^"+ "][o"+ "^L;bi"+ "d[n\\"+ "][lPQ"+
+ "[>^"+ "QSDFUQwL]JfNv"+ ";NN"+ ""+ ""+ "]"+ "K"+ "l"+ "^"+ "Q"+ "S"+
+ ">^Y"+ "ZfJUSvNU[@LT;N?"+ "=o<"+ ""+ ""+ ""+ ""+ "?qw>^"+ "YKbBUUn"+ "NU[bLR["+
+ "N>=kplqs>^X[dFUWfNU[jLZQBmqe"+ ""+ ""+ ""+ "p"+ "m"+ "q"+ "w"+ ">"+ "^"+
+ "X[dNUsfL??;=xQbLqQ`LQSn_>;"+ "l^_"+ ""+ ""+ "[n^_["+ "j"+ "M"+ "x"+ "A"+
+ "bmqQ@LQ[n^M_?w=ZLRNJN^iAb"+
+ "LQQBlQ_n^E[fHDInN_SlPqA"+ "bLqQF"+ "lQ_n^"+ "AYfN]"+
+ "SfN=SnTQBbDAtZmq_n^ESfL"+ "]"+ "Q"+ "f"+ "O"+ "="+ "S"+
+ "nPQX"+ "bHqp"+ "zlu[n^T"+ "CFN]SfO"+ "][nZQXB"+
+ "Hqdzm"+ "u_n^U"+ "J"+ "f"+ "l"+ "U"+ "S"+ "f"+
+ "MUSnZAYFHqAjLU[n^"+ "]"+ "Z"+ "n"+ ">"+ "]"+ "["+
+ "n>][n^AYd"+
+ "rlQfLQ[n^]K"+ "n_][o>][n^@YfW]YfLQ[n^]Kn_][o^][n\\TIfZ]Yf\\Q[n"
+ for i:=0;i< len(c)<<1;i++{
+ if i%48>0 {
+ poop+=
+ map
+
+ [bool] string{ false : " ",true:"██"}[
+ byte( food >> uint (6*( i>>
+ 1&3 )))& map[ int] byte {0:
+ 56,1 :7}[ i&1] &c[i >>1]>0]}else {//
+ poop+= "" +"\n"/*> beef &<*/ } }
+
+ return
+}
+
diff --git a/puzzle-hunt/red-vs-blue.py b/puzzle-hunt/red-vs-blue.py
new file mode 100644
index 0000000..c0d5e4c
--- /dev/null
+++ b/puzzle-hunt/red-vs-blue.py
@@ -0,0 +1,155 @@
+from itertools import *
+from z3 import *
+
+row_rules = [
+ [17, 4],
+ [17, 1, 3],
+ [14, 2, 3],
+ [12, 1, 3],
+ [9, 2, 2, 1],
+
+ [2, 7, 1, 4],
+ [4, 4, 3, 1, 1],
+ [1, 3, 2, 1, 3, 1, 1],
+ [3, 2, 3, 2],
+ [3, 1, 2, 3, 1],
+
+ [2, 5, 2, 1, 3, 1],
+ [1, 8, 1, 2, 3],
+ [1, 11, 1, 1],
+ [2, 1, 2, 6, 4, 2],
+ [1, 1, 4, 3, 1],
+
+ [2, 2, 1, 3, 2],
+ [1, 2, 3, 1],
+ [1, 2, 1, 3],
+ [4, 2, 1],
+ [3, 1, 2],
+
+ [3, 2, 1],
+ [3, 1, 1, 2],
+ [3, 2, 1],
+ [3, 2, 2],
+ [3, 2, 1],
+
+ [4, 3, 2],
+ [2, 3, 3, 1],
+ [3, 4, 4],
+ [6, 1, 1],
+ [4],
+]
+
+col_rules = [
+ [3, 2, 2, 1, 1, 11],
+ [3, 3, 2, 1, 2, 11],
+ [3, 4, 2, 3, 6, 2],
+ [3, 4, 3, 6, 1],
+ [3, 7, 1, 6],
+
+ [3, 4, 4, 7],
+ [3, 2, 6, 6],
+ [3, 8, 3, 1],
+ [3, 8, 2, 1],
+ [3, 8, 2, 2],
+
+ [3, 6, 1, 1],
+ [3, 3, 2, 6],
+ [3, 1, 4, 5],
+ [3, 4, 2, 5],
+ [6, 7, 1, 4],
+
+ [6, 9, 2, 4],
+ [6, 1, 9, 1, 3],
+ [6, 4, 9, 2, 3],
+ [4, 6, 9, 1, 2],
+ [2, 1, 3, 9, 2, 2],
+
+ [4, 1, 2, 11, 1],
+ [6, 5, 9, 2],
+ [7, 6, 6, 4],
+ [6, 6, 4, 6],
+ [1, 7, 6, 1, 8],
+
+ [1, 1, 3, 6, 10],
+ [2, 1, 1, 4, 12],
+ [2, 1, 2, 1, 1, 14],
+ [3, 1, 3, 16],
+ [3, 4, 18],
+]
+
+def pairwise(iterable):
+ "s -> (s0,s1), (s1,s2), (s2, s3), ..."
+ a, b = tee(iterable)
+ next(b, None)
+ return zip(a, b)
+
+def cell(x, y):
+ return Bool(f"cell-{x},{y}")
+
+def row(y):
+ return [cell(x, y) for x in range(0, len(col_rules))]
+
+def col(x):
+ return [cell(x, y) for y in range(0, len(row_rules))]
+
+s = Solver()
+
+for x, col_rule in enumerate(col_rules):
+ stripe_name = f"col-{x}"
+ stripe_constraints = col_rule
+ stripe = col(x)
+ group_count = len(stripe_constraints)
+ group_start = [Int(f"{stripe_name}-{i}-start") for i in range(0, group_count)]
+ group_end = [Int(f"{stripe_name}-{i}-end") for i in range(0, group_count)]
+
+ # # Start and end of each group
+ for i in range(0, group_count):
+ s.add(group_start[i] >= 0, group_start[i] < len(stripe))
+ s.add(group_end[i] >= 0, group_end[i] < len(stripe))
+ s.add(group_end[i] - group_start[i] == stripe_constraints[i] - 1)
+
+ # Gap between each group and following group
+ for i, j in pairwise(range(0, group_count)):
+ s.add(group_start[j] >= group_end[i] + 2)
+
+ # Cells
+ for k in range(0, len(stripe)):
+ cell_in_specific_group = [
+ And(k >= group_start[i], k <= group_end[i])
+ for i in range(0, group_count)
+ ]
+ s.add(stripe[k] == Or(*cell_in_specific_group))
+
+for y, row_rule in enumerate(row_rules):
+ stripe_name = f"row-{y}"
+ stripe_constraints = row_rule
+ stripe = row(y)
+ group_count = len(stripe_constraints)
+ group_start = [Int(f"{stripe_name}-{i}-start") for i in range(0, group_count)]
+ group_end = [Int(f"{stripe_name}-{i}-end") for i in range(0, group_count)]
+
+ # # Start and end of each group
+ for i in range(0, group_count):
+ s.add(group_start[i] >= 0, group_start[i] < len(stripe))
+ s.add(group_end[i] >= 0, group_end[i] < len(stripe))
+ s.add(group_end[i] - group_start[i] == stripe_constraints[i] - 1)
+
+ # Gap between each group and following group
+ for i, j in pairwise(range(0, group_count)):
+ s.add(group_start[j] >= group_end[i] + 2)
+
+ # Cells
+ for k in range(0, len(stripe)):
+ cell_in_specific_group = [
+ And(k >= group_start[i], k <= group_end[i])
+ for i in range(0, group_count)
+ ]
+ s.add(stripe[k] == Not(Or(*cell_in_specific_group)))
+
+s.check()
+m = s.model()
+
+for y in range(0, len(row_rules)):
+ row = "".join(["█" if m[cell(x,y)] else " " for x in range(0, len(col_rules))])
+ print(row)
+
diff --git a/puzzle-hunt/requirements.txt b/puzzle-hunt/requirements.txt
new file mode 100644
index 0000000..80b9109
--- /dev/null
+++ b/puzzle-hunt/requirements.txt
@@ -0,0 +1 @@
+z3-solver==4.8.10.0
diff --git a/puzzle-hunt/shell.nix b/puzzle-hunt/shell.nix
new file mode 100644
index 0000000..797c2ac
--- /dev/null
+++ b/puzzle-hunt/shell.nix
@@ -0,0 +1,10 @@
+{ pkgs ? import <nixpkgs> {} }:
+
+pkgs.mkShell {
+ nativeBuildInputs = [
+ pkgs.go
+ pkgs.python3
+ pkgs.ruby_3_0
+ pkgs.z3
+ ];
+}
diff --git a/puzzle-hunt/words.rb b/puzzle-hunt/words.rb
new file mode 100644
index 0000000..0d0a0e8
--- /dev/null
+++ b/puzzle-hunt/words.rb
@@ -0,0 +1,12 @@
+words = File.read("/usr/share/dict/words")
+ .downcase
+ .split("\n")
+
+# haystack = words.select {|w| w =~ /^...ve$/ }
+# p haystack.select {|x|
+# words.include?("#{x[0]}o#{x[1]}#{x[2]}t")
+# }
+
+puts words
+ .select {|x| x.size == 6 }
+ .select {|x| x =~ /hy|h....y/ }