publish backlog of things

This commit is contained in:
osmarks 2022-02-05 14:45:04 +00:00
parent 78602eabd6
commit 95e84ceb80
47 changed files with 3147 additions and 13 deletions

50
art2.py Normal file
View File

@ -0,0 +1,50 @@
from PIL import Image
import numpy.fft as fft
import numpy as np
import random
import math
w, h = 512, 512
out = np.zeros((w, h, 3))
random.seed(4)
def operate_on_channel(n):
mask = np.full((w, h), 1)
midx, midy = w // 2, h // 2
J = 1
for x in range(midx - J, midx + J + 1):
for y in range(midy - J, midy + J + 1):
mask[x, y] = 0.5
"""
for x in range(w):
for y in range(h):
dist = (x - midx) ** 2 + abs(y - midy) ** 2
#if 1024 > dist > 4:
# mask[x, y] = 1
#mask[x, y] = math.sqrt(dist) / 500
if dist < 256: mask[x, y] = 1
"""
"""
for x in range(w):
for y in range(h):
mask[x, y] = random.uniform(0.7, 1)
"""
channel = fft.ifftshift(mask)
rfft = fft.ifft2(channel)
channel = np.abs(np.real(rfft))
#red2 = np.abs(np.imag(rfft))
#red = np.log(np.abs(np.real(red)))
#red = np.abs(mask)
channel = channel * (255 / np.max(channel))
#red2 = red2 * (255 / np.max(red2))
out[..., n] = channel
for i in range(3):
operate_on_channel(i)
out = Image.fromarray(out, "RGB")
out.save("/tmp/out.png")

27
art3.py Normal file
View File

@ -0,0 +1,27 @@
from PIL import Image
import numpy.fft as fft
import numpy as np
import random
import math
w, h = 512, 512
out = np.zeros((w, h, 3), dtype=np.uint8)
def bitstring(x): return f"{x:06b}"
def concat(l):
out = []
for m in l:
for n in m:
out.append(n)
return "".join(out)
for r in range(2**6):
for g in range(2**6):
for b in range(2**6):
a = concat(zip(*(bitstring(r), bitstring(g), bitstring(b))))
a = int(a, 2)
x, y = a & 0b111111111, a >> 9
out[x, y] = (r << 2, g << 2, b << 2)
out = Image.fromarray(out, "RGB")
out.save("/tmp/out.png")

69
audio-modem.html Normal file
View File

@ -0,0 +1,69 @@
<!DOCTYPE html>
<input type="text" id="text">
<button id="send">do thing</button>
<button id="recv">do thing 2</button>
<canvas id="vis" style="width: 100%; height: 20em; "></canvas>
<script>
const ctx = new AudioContext()
const encoder = new TextEncoder()
const visCanvas = document.querySelector("#vis")
const transmit = bytes => {
const tones = Array.from(bytes).flatMap(x => [x >> 6, x >> 4 & 3, x >> 2 & 3, x & 3])
console.log(tones)
let pos = 0
const oscillator = ctx.createOscillator()
oscillator.connect(ctx.destination)
oscillator.start()
const interval = setInterval(() => {
const tone = tones[pos]
oscillator.frequency.value = [200, 400, 600, 800][tone]
pos++
if (pos == tones.length) {
oscillator.stop()
oscillator.disconnect()
clearInterval(interval)
}
}, 500)
}
const analyzer = ctx.createAnalyser()
//analyzer.smoothingTimeConstant = 0
const CWIDTH = 512
const CWIDTH_MINUS_ONE = 511
const cctx = visCanvas.getContext("2d")
let q = 0;
const visualizerLoop = () => {
const w = analyzer.frequencyBinCount
const frequencyData = new Uint8Array(w)
analyzer.getByteFrequencyData(frequencyData)
const im = cctx.getImageData(1, 0, CWIDTH, w)
let max = -1;
let maxIndex = -1;
for (let i = 0; i < w; i++) {
im.data[(i * CWIDTH + CWIDTH_MINUS_ONE) * 4 + 3] = 255
im.data[(i * CWIDTH + CWIDTH_MINUS_ONE) * 4 + 1] = frequencyData[i]
if (frequencyData[i] > max) {
max = frequencyData[i]
maxIndex = i
}
}
console.log((maxIndex + 1) / w * 24000)
cctx.putImageData(im, 0, 0)
q++
requestAnimationFrame(visualizerLoop)
}
document.querySelector("#send").addEventListener("click", () => {
transmit(encoder.encode(document.querySelector("#text").value))
})
document.querySelector("#recv").addEventListener("click", () => {
navigator.mediaDevices.getUserMedia({video: false, audio: true}).then(stream => {
console.log(stream)
const node = ctx.createMediaStreamSource(stream)
node.connect(analyzer)
visCanvas.height = analyzer.frequencyBinCount
visCanvas.width = CWIDTH
cctx.fillStyle = "black"
cctx.fillRect(0, 0, CWIDTH, analyzer.frequencyBinCount)
requestAnimationFrame(visualizerLoop)
})
})
</script>

78
autoformat.py Normal file
View File

@ -0,0 +1,78 @@
from fractions import Fraction
from functools import reduce
import sys
from math import floor
import random
def interpolate(points):
def mul_polys(p1, p2):
out = [0] * (len(p1) + len(p2) - 1)
for i1, c1 in enumerate(p1):
for i2, c2 in enumerate(p2):
out[i1 + i2] += c1 * c2
return out
def sum_polys(ps):
out = [0] * max(map(len, ps))
for p in ps:
for i, c in enumerate(p):
out[i] += c
return out
def basis(j):
px = points[j][0]
out = []
for x, y in points:
if x != px:
div = px - x
out.append([-Fraction(x, div), Fraction(1, div)])
return reduce(mul_polys, out)
out = []
for i, (x, y) in enumerate(points):
out.append([c * y for c in basis(i)])
return sum_polys(out)
def evaluate(poly, x):
y = 0
for c in reversed(poly):
y *= x
y += c
return y
indents = {"\t": 8, " ": 1, "": Fraction(2, 3), " ": 2, "": 4, "": Fraction(4, 3), "": 0}
def get_indent(line):
i = 0
e = 0
for j, c in enumerate(line):
if c in indents:
i += indents[c]
e = j + 1
else: break
return i, e
with open(sys.argv[1]) as tplfile:
counts = [ (lnum, get_indent(line)[0]) for lnum, line in enumerate(tplfile.readlines()) ]
counts = random.sample(counts, k=4)
poly = interpolate(counts)
lindents = [ (Fraction(size), char) for char, size in indents.items() if size != 0 ]
lindents.sort()
def gen_indent(n):
n = Fraction(abs(n))
out = ""
for (csize, cchar), (nsize, _) in zip(lindents, lindents[1:] + [(100000000000000, " ")]):
nmult = 0
while True:
nxt = nmult + nsize
if nxt <= n:
nmult = nxt
else: break
dif = floor((n - nmult) / csize)
n -= dif * csize
out += cchar * dif
return out
with open(sys.argv[2]) as infile:
for lnum, line in enumerate(infile.readlines()):
line = line[get_indent(line)[1]:]
print(gen_indent(evaluate(poly, lnum)) + line, end="")

23
beep.py
View File

@ -10,8 +10,8 @@ import struct
# disk instead of buffering it all in memory list this. But most sounds will fit in
# memory.
audio = []
sample_rate = 44100.0
sample_rate = 48000.0
phase = 0
def append_silence(duration_milliseconds=500):
num_samples = duration_milliseconds * (sample_rate / 1000.0)
@ -24,10 +24,12 @@ def append_sinewave(
freq=440.0,
duration_milliseconds=500,
volume=1.0):
global audio # using global variables isn't cool.
global phase
num_samples = duration_milliseconds * (sample_rate / 1000.0)
pc = math.tau * freq / sample_rate
for x in range(int(num_samples)):
audio.append(volume * math.sin(2 * math.pi * freq * ( x / sample_rate )))
phase += pc
audio.append(volume * math.sin(phase))
def append_squarewave(
freq=440.0,
@ -54,11 +56,10 @@ def save_wav(file_name):
wav_file.close()
return
#for _ in range(8):
# append_sinewave(volume=1.0, freq=1000.0)
# append_silence()
append_sinewave(freq=500, duration_milliseconds=500)
append_sinewave(freq=1000, duration_milliseconds=500)
append_sinewave(freq=2000, duration_milliseconds=500)
append_sinewave(freq=500, duration_milliseconds=500)
import random
freq = 6
for i in range(160):
append_sinewave(volume=1.0, freq=math.exp(freq), duration_milliseconds=50)
freq += random.uniform(-0.2, 0.2)
freq = max(4.5, min(freq, 9))
save_wav("output.wav")

35
clipstack.py Normal file
View File

@ -0,0 +1,35 @@
import sqlite3, pyperclip, os.path, subprocess, sys
conn = sqlite3.connect(os.path.expanduser("~/.local/share/clipstack.sqlite3"))
conn.executescript("""CREATE TABLE IF NOT EXISTS stack (pos INTEGER PRIMARY KEY, data BLOB NOT NULL)""")
def push(data):
c = conn.cursor()
c.execute("SELECT max(pos) FROM stack")
res = c.fetchone()[0]
if res == None: nxt = 0
else: nxt = res + 1
c.execute("INSERT INTO stack VALUES (?, ?)", (nxt, data))
conn.commit()
def pop():
c = conn.cursor()
c.execute("SELECT * FROM stack ORDER BY pos DESC LIMIT 1")
res = c.fetchone()
if not res: return
pos, data = res
c.execute("DELETE FROM stack WHERE pos = ?", (pos,))
return data
conn.commit()
mode = sys.argv[1]
if mode == "push":
proc = subprocess.run(["xclip", "-selection", "clipboard", "-o"], stdout=subprocess.PIPE)
if proc.returncode == 0:
push(proc.stdout)
print("push")
elif mode == "pop":
data = pop()
if data:
proc = subprocess.run(["xclip", "-selection", "clipboard"], input=data)
print("pop")

View File

@ -0,0 +1,254 @@
<style>
* { box-sizing: border-box;; }
#disp .cell {
width: 32px;
height: 32px;
display: inline-block;
font-family: monospace;
position: relative;
}
.cell img {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
image-rendering: crisp-edges;
image-rendering: pixelated;
}
.cell.selected {
background: yellow;
}
</style>
<div id="disp"></div>
<div id="controls">
<select id="interactmode">
<option selected>select</option>
<option>rotate</option>
<option>place drill</option>
<option>place belt</option>
<option>place inserter</option>
</select>
<button id="step">run step</button>
</div>
<script>
const noiseSeed = Math.random() * (2**32-1)
const hash = (str, seed = 0) => {
let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed
for (let i = 0, ch; i < str.length; i++) {
ch = str.charCodeAt(i)
h1 = Math.imul(h1 ^ ch, 2654435761)
h2 = Math.imul(h2 ^ ch, 1597334677)
}
h1 = Math.imul(h1 ^ (h1>>>16), 2246822507) ^ Math.imul(h2 ^ (h2>>>13), 3266489909)
h2 = Math.imul(h2 ^ (h2>>>16), 2246822507) ^ Math.imul(h1 ^ (h1>>>13), 3266489909)
return 4294967296 * (2097151 & h2) + (h1>>>0)
}
const normalize = ([x, y]) => [x / Math.hypot(x, y), y / Math.hypot(x, y)]
const dot = ([a, b], [c, d]) => a*c+b*d
const cartesianProduct = (xs, ys) => xs.flatMap(x => ys.map(y => [x, y]))
const gradients = cartesianProduct([-1, -0.5, 0.5, 1], [-1, -0.5, 0.5, 1]).map(normalize)
const gradientFor = (x, y) => gradients[hash(x+"."+y, noiseSeed) % gradients.length]
const interpolate = (a0, a1, w) => (a1 - a0) * (3.0 - w * 2.0) * w * w + a0
const perlin = (x, y) => {
const i = Math.floor(x), j = Math.floor(y)
const u = x - i, v = y - j
const n00 = dot(gradientFor(i, j), [u, v])
const n01 = dot(gradientFor(i + 1, j), [u - 1, v])
const n10 = dot(gradientFor(i, j + 1), [u, v - 1])
const n11 = dot(gradientFor(i + 1, j + 1), [u - 1, v - 1])
return interpolate(interpolate(n00, n01, u), interpolate(n10, n11, u), v)
}
const disp = document.querySelector("#disp")
let interactMode = document.querySelector("#interactmode").value
document.querySelector("#interactmode").addEventListener("input", ev => {
interactMode = ev.target.value
console.log(interactMode)
})
const directions = {
0: [0, 1],
1: [-1, 0],
2: [0, -1],
3: [1, 0]
}
const arrows = "→↓←↑"
const grid = {}
const SIZE = 24
for (let x = 0; x < SIZE; x++) {
for (let y = 0; y < SIZE; y++) {
let thing = { type: "empty", direction: 0, x, y }
thing.mapNoise = perlin(x * 3 / SIZE, y * 3 / SIZE)
grid[x+"."+y] = thing
}
}
const noises = Object.values(grid).map(x => x.mapNoise)
noises.sort((a, b) => a - b)
const thresh1 = noises[Math.floor(noises.length * (6/7))]
const thresh2 = noises[Math.ceil(noises.length * (1/12))]
for (const cell of Object.values(grid)) {
if (cell.mapNoise > thresh1) {
cell.type = "ore1"
} else if (cell.mapNoise < thresh2) {
cell.type = "ore2"
}
}
const adjacentAt = (x, y, d) => {
const dir = directions[d]
const nx = x + dir[0], ny = y + dir[1]
return grid[nx+"."+ny]
}
let updateOrder
const itemHandlers = ["drill", "belt"]
const recomputeBelts = () => {
for (const cell of Object.values(grid)) {
delete cell.inext
delete cell.iprev
if (itemHandlers.includes(cell.structure)) {
cell.inext = adjacentAt(cell.x, cell.y, cell.direction)
if (cell.inext) cell.inext.iprev = cell
}
}
for (const cell of Object.values(grid)) {
if (cell.inext) {
if (!cell.iprev) { // root of tree thing
let order = 0
let visited = new Set()
let current = cell
while (current && !visited.has(current) && itemHandlers.includes(current.structure)) {
if (current.order === undefined || current.order < order) {
current.order = order
}
order++
visited.add(current)
current = current.inext
}
}
}
}
const iorder = []
for (const cell of Object.values(grid)) {
if (cell.order !== undefined) {
iorder[cell.order] ||= []
iorder[cell.order].push(cell)
}
}
updateOrder = [].concat(...iorder).reverse()
}
const update = () => {
recomputeBelts()
for (const cell of Object.values(grid)) {
if (cell.type === "inserter") {
}
}
for (const cell of updateOrder) {
if (cell.structure === "drill") {
cell.item = cell.type
}
if (cell.inext && !cell.inext.item) {
if (cell.item) {
cell.inext.item = cell.item
cell.item = null
}
}
}
render()
}
document.querySelector("#step").addEventListener("click", () => {
update()
})
const rotate = (d, e) => (d + e) % 4
const render = () => {
while (disp.firstChild) disp.removeChild(disp.firstChild)
for (let y = 0; y < SIZE; y++) {
for (let x = 0; x < SIZE; x++) {
const cell = document.createElement("span")
cell.id = x+"."+y
cell.classList.add("cell")
const thing = grid[x+"."+y]
const type = thing.type
const layers = []
layers.push("blank")
if (type === "empty") {
} else if (type.startsWith("ore")) {
layers.push({ sprite: type, rotation: hash(cell.id) % 4 })
if (thing.structure === "drill") {
layers.push("drill")
}
}
if (thing.structure === "belt") {
const isInboundBelt = side => {
const newCell = adjacentAt(x, y, rotate(thing.direction, side))
return newCell && newCell.structure === "belt" && newCell.direction == rotate(thing.direction, rotate(side, 2))
}
const left = isInboundBelt(1), back = isInboundBelt(2), right = isInboundBelt(3)
if (left && !back) {
layers.push({ sprite: "belt-corner", reflect: true, rotation: 3 })
if (right) { layers.push("belt-conn") }
}
else if (right && !back) { layers.push({ sprite: "belt-corner", rotation: 1 }) }
else {
layers.push("belt")
if (right) { layers.push("belt-conn") }
if (left) { layers.push({ sprite: "belt-conn", reflect: true }) }
console.log(x, y, right, left)
}
if (thing.item) {
layers.push({ sprite: thing.item, scale: 0.5 })
}
}
if (thing.structure === "inserter") {
console.log("inserter")
layers.push("inserter-base")
layers.push("inserter-arm")
}
if (thing.selected) {
cell.classList.add("selected")
}
for (const layer of layers) {
const im = document.createElement("img")
im.src = `/sprites/${typeof layer === "string" ? layer : layer.sprite}.png`
const transforms = []
if (layer.rotation) { transforms.push(`rotate(${layer.rotation * 90}deg)`) }
if (layer.reflect) { transforms.push(`scaleX(-1)`) }
if (layer.scale) { transforms.push(`scale(${layer.scale})`) }
const transformString = transforms.join(" ")
if (transformString) { im.style.transform = transformString }
cell.appendChild(im)
}
cell.style.transform = `rotate(${thing.direction * 90}deg)`
disp.appendChild(cell)
}
disp.appendChild(document.createElement("br"))
}
}
disp.addEventListener("click", ev => {
const cell = ev.target.parentElement.id
console.log(grid[cell], cell)
if (interactMode === "select") {
grid[cell].selected ^= 1
} else if (interactMode === "place drill") {
if (grid[cell].type.startsWith("ore")) {
grid[cell].structure = "drill"
}
} else if (interactMode === "place belt") {
grid[cell].structure = "belt"
} else if (interactMode === "place inserter") {
grid[cell].structure = "inserter"
} else if (interactMode === "rotate") {
grid[cell].direction++
grid[cell].direction %= 4
}
ev.preventDefault()
render()
})
render()
</script>

View File

@ -0,0 +1,48 @@
import os, csv, re, itertools, numpy, collections, json
rawbuffer = bytearray()
with open("/tmp/input.csv") as f:
r = csv.reader(f)
for row in r:
channel, timestamp, message, _ = row
message = re.sub("<@!?[0-9]+>", "", message)
message = re.sub("<:([A-Za-z0-9_-]+):[0-9]+>", lambda match: match.group(1), message)
rawbuffer += (message.strip() + " ").encode("utf-8")
#print(rawbuffer.count(b"\x0f"))
#raise SystemExit()
print(len(rawbuffer))
buffer = numpy.array(rawbuffer, dtype=numpy.uint16)
dc = {}
for newindex in range(256, 1024):
freqs = collections.Counter(zip(buffer, buffer[1:]))
(fst, snd), count = freqs.most_common(1)[0]
print(newindex, count, repr(chr(fst)), repr(chr(snd)))
dc[newindex] = int(fst), int(snd)
pending = False
newbuffer = numpy.zeros_like(buffer)
z = 0
for code in buffer:
if pending:
if code == snd:
newbuffer[z] = newindex
z += 1
pending = False
continue
else:
newbuffer[z] = fst
z += 1
pending = False
if code == fst:
pending = True
else:
newbuffer[z] = code
z += 1
buffer = newbuffer[:z]
with open("compr.json", "w") as f:
json.dump({
"dicts": dc,
"frequencies": dict(collections.Counter(map(int, buffer)))
}, f, separators=",:")

158
code-guessing/codexsoln.py Normal file
View File

@ -0,0 +1,158 @@
# Programs are to validate JSON according to the JSON spec (https://www.json.org/), with the exception that you may assume that the string will consist entirely of the classic printable ASCII characters (codepoints 32-127, horizontal tabs, and newlines).
# You may additionally assume that the input will not be nested more than 16 levels.
def entry(string):
if string == "":
return True
elif string[0] == '{':
return entry_object(string)
elif string[0] == '[':
return entry_array(string)
elif string[0] == '"':
return entry_string(string)
elif string[0] in '-0123456789':
return entry_number(string)
elif string[0] == 't':
return entry_true(string)
elif string[0] == 'f':
return entry_false(string)
elif string[0] == 'n':
return entry_null(string)
else:
return False
def entry_object(string):
if string[0] != '{':
return False
string = string[1:]
if string[0] == '}':
return True
while True:
if not entry_string(string):
return False
if not entry_colon(string):
return False
if not entry(string):
return False
if string[0] == '}':
return True
if not entry_comma(string):
return False
def entry_array(string):
if string[0] != '[':
return False
string = string[1:]
if string[0] == ']':
return True
while True:
if not entry(string):
return False
if string[0] == ']':
return True
if not entry_comma(string):
return False
def entry_string(string):
if string[0] != '"':
return False
string = string[1:]
while True:
if string[0] == '"':
return True
if string[0] == '\\':
string = string[1:]
if string[0] == 'u':
string = string[1:]
if not string[0] in '0123456789abcdef':
return False
string = string[1:]
if not string[0] in '0123456789abcdef':
return False
string = string[1:]
if not string[0] in '0123456789abcdef':
return False
string = string[1:]
if not string[0] in '0123456789abcdef':
return False
string = string[1:]
elif string[0] == '"':
pass
elif string[0] == '\\':
pass
elif string[0] == '/':
pass
elif string[0] == 'b':
pass
elif string[0] == 'f':
pass
elif string[0] == 'n':
pass
elif string[0] == 'r':
pass
elif string[0] == 't':
pass
else:
return False
else:
string = string[1:]
def entry_number(string):
if string[0] not in '-0123456789':
return False
string = string[1:]
if string[0] == '.':
string = string[1:]
if string[0] not in '0123456789':
return False
string = string[1:]
if string[0] in 'eE':
string = string[1:]
if string[0] in '+-':
string = string[1:]
if string[0] not in '0123456789':
return False
string = string[1:]
if string[0] not in '0123456789':
return False
string = string[1:]
return True
def entry_colon(string):
if string[0] != ':':
return False
string = string[1:]
return True
def entry_comma(string):
if string[0] != ',':
return False
string = string[1:]
return True
def entry_true(string):
if string[0:4] != 'true':
return False
string = string[4:]
return True
def entry_false(string):
if string[0:5] != 'false':
return False
string = string[5:]
return True
def entry_null(string):
if string[0:4] != 'null':
return False
string = string[4:]
return True
def main():
string = input()
if entry(string):
print("Valid JSON")
else:
print("Invalid JSON")
if __name__ == "__main__":
main()

117
code-guessing/codexsoln2.py Normal file
View File

@ -0,0 +1,117 @@
# Programs are to validate JSON according to the JSON spec (https://www.json.org/), with the exception that you may assume that the string will consist entirely of the classic printable ASCII characters (codepoints 32-127, horizontal tabs, and newlines).
# You may additionally assume that the input will not be nested more than 16 levels.
def entry(string):
string = string.strip()
if len(string) == 0:
return True
if string[0] == '{':
return object(string)
elif string[0] == '[':
return array(string)
elif string[0] in '-0123456789':
return number(string)
elif string[0] == '"':
return string(string)
else:
return False
def object(string):
if string[0] != '{':
return False
string = string[1:]
if string[0] == '}':
return True
string = string.strip()
if string[0] != '"':
return False
string = string[1:]
if string[0] != ':':
return False
string = string[1:]
string = string.strip()
if not entry(string):
return False
string = string.strip()
if string[0] == '}':
return True
if string[0] != ',':
return False
string = string[1:]
string = string.strip()
if not object(string):
return False
string = string.strip()
if string[0] != '}':
return False
return True
def array(string):
if string[0] != '[':
return False
string = string[1:]
if string[0] == ']':
return True
string = string.strip()
if not entry(string):
return False
string = string.strip()
if string[0] == ']':
return True
if string[0] != ',':
return False
string = string[1:]
string = string.strip()
if not array(string):
return False
string = string.strip()
if string[0] != ']':
return False
return True
def number(string):
if string[0] not in '-0123456789':
return False
string = string[1:]
if string[0] == '.':
string = string[1:]
if string[0] not in '0123456789':
return False
string = string[1:]
while string[0] in '0123456789':
string = string[1:]
if string[0] not in '0123456789':
return False
string = string[1:]
if string[0] not in 'eE':
return False
string = string[1:]
if string[0] not in '+-':
return False
string = string[1:]
if string[0] not in '0123456789':
return False
string = string[1:]
while string[0] in '0123456789':
string = string[1:]
return True
def string(string):
if string[0] != '"':
return False
string = string[1:]
while string[0] != '"':
if string[0] == '\\':
string = string[1:]
if string[0] not in '"\\/bfnrt':
return False
string = string[1:]
else:
string = string[1:]
return True
def main():
string = input()
print(entry(string))
if __name__ == "__main__":
main()

1
code-guessing/compr.json Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,95 @@
import json, numpy, math, functools, base64
real_bped = numpy.frombuffer(base64.b64decode('ZQAgAHQAIABzACAAdABoAGkAbgBkACAAZQByAGEAbgB5ACAAbwAgAG8AbgAgACAAbwB1AG8AcgBnACAAZQBuAGEAbAAEAQ4BYQAgAHIAZQBhAHIAaQACASAAAwF0AAkBcwB0AGkAAQFpAHQAbwBtAGEAdAAgAHcAeQAMAWgAYQBlAAUBZgAgACwAIABsAAgBdQBzAAcBBQFsACAAZQACAUkAIAAGASAAYwBoAG8AdwALAQsBZQBzAAMBAAFhAHMAZQBjAB4BIABrACAAdgAAAWwAaQB0AGkAbQAgACcAAQFsAG8ADQEgAHIAbwAnAAIBbAAAAW0AYQAKASAABwEgAGUAbAAEASAAYgB1AGEAAQFsAGUAYQBjAGkAYwBpAHMAFgEAAWkAIABtAAABDwEgAGEAYgBvACEBbgBvAGkAbAByAGEAaAAgAHAAOgEuACAAawAAAXUAbgBnAG8AQgEBAXYABgFvAHAAcwAbAaMA4gBpAAMBgwBbAV0BXQFzAGUAKwEgAGkAZABjABsBcwAJAW0ACAFvAGQAJAEAARoBOwFJACcAcgBpAGAAYAB3AGgAbwBsAGYAOQFiAGUAHwEzAXMAaABhAAIBdQByABABIwFlAG0AZQB4AGEAZwAKACwBYQBkAHMAaQB0AHQAYgAAAT4AIABgACAACgEAAU4BAQEGAQABdQBjAOIAjQAUAQABAwEVAXQABgEMAQEBbgA3AXAAIABuAGUAEAEgAAwBbABkAG8AYwA/ASkAKQBmAA0BAwFDAQ8BdABpAHIAcABwAAoBNwE0AVQBKgEgAGIAMAFhAAgBWgFlAC4ALgAkAQEBXAEgAHAAZQB0AHIAbwBmAHAAbwBtAGUAAwERAWEAZgFpACEBYwAKAR8BAQFkAGUAZAAJAXAAbACXAaMBMQAxAHMAdQB0AGEAiwEFAWQAaQBzAAEBZACUAWcAZQBtAG8AHAFpAHQAbwAPAQEBcQB1AG4ACQEdAWgAXgFeAQQBZwAwADAAYQBtAGMAZQFiAG8AbgAgAHkAJwFnAGgAdQBsAEEAQQApACAAPwAgAAcBZwBlAGEAAwFlABoBAAFoATYBcgAgAAwBbgB3AA0BEAFsAGoAmwFnAFABGwEgAG4AYAE+AD4AdQB0ABYBFQFPASYBawARAVoBAAFwABMBZgByAGUAdgBrAGUAbQBtAHAABgEvAC8AIAEXAXcAnAE8ADwAvgEAAWYAgQFwAHMABwEBAWEAeQBkAEcBYwANAXQAAgFAASYBbQBwABwBAAFoAHoBWAEIAToA4AFSAdEBYwAAAUYBIABiAXAAYQAFAZ0BWQEKACAAcwBwAGgAYAEeAcwBTAGGAWsAAgH3ATwBYwAHAWYABAFvAAUBOgAgACgAKAArACsA7wHmAQUC8QFSAWIAEAEmARgBcgBJAB0BBAGFARwBOwEYAXUAHwECAT0AIABMATwBdwByAHMAAAEWAUMBQwAgAGUAGAFuACsBdgEAARABYwEHAWQAYQBKAS0BAgFvAGIAcgAAAXcApgEwACAAdQBtAFYBAQLbAdIBEgFiAGMAIAAPAWQACgEjAW0ADQFwABQBLgBiAS0BcwA1AUoBZQBkAMIBAQEpAi8AsgEBAQoBAgF3ASwBEQEXAUABbAB3ACAAPQFUAWwAJgF0ACkBBgECAXgAIAAxADYAZwBpAHIBAAEEAQABMQGNAWEAkwH/ATcBYQBhAGgAAAF2ACkBaABpAHMABgFsAHkAHQGmAXYAZQAxADIAOAFvALoBugEEAWQALwFtAGoBYAAeAScAAwGAAWYAaQAUASAAJwIAAWYAVQGMAS0BZgBmAHMAYwAHAXkAYQBpADUBPgEDASkBYQB2AGkAJwBoAGgANQFtAIIBtQB2AGkAcAB1ABYBZQBsAMcBtAE+AXQAdQBzAC8AVQKHAXcAZQBmAGUAdwBxATMANABtAHUAzQEFAQQBdABiAAgBYgByADgBJgHiAIAAcwBvAGkAlgHiAIYAmQGiAcQBxAFzAG0A6QHqAeUBMgFmAGEAEwFzAbUBCQFiAC8BZwB1AAQBMgFjAG8AZQBwAAMCUwBtAHQBZAJ1AGcAAAFwARkBAwEgAC0BAQFwAHIAbQAHAWkAHQFrACAByQEIAW0ABAEoAEsAYwBsAB0BnAEPAQUBRQEyASgBsQHnARcBEwFjAGgAZQBrANMBZgAhAV8BAAFrABYCaQB6AOgBAgEiACAAbQCRAQoBDgFlAFgBaQBmAEwBIwFWAWwAYgA8AUUBawCgAXMArwEFARMBeAFkAGEBMgBiAAoAagFEACAArgJ9AXQAcgFkAAYBFAEFATEAIABMACAAswGwAU0CrQJhAHAAAwEMAnQAdwBtApYBYQFlAGwAFAFzAEABcAGuAQYBZQA0ACAAGgEIAWcAUQHyAd4BbAAaAXQAIAFkAAABdQBwAGMAcgBsAD0BdwDXAawChwHKAgkBAwFLAXkALQFPAh0CGgFpADAAMgBvAFsCOAA2ACoBBwF0AAABBwKlAjUBCgF1AIgBpAExAVMAIAB6AmQAMwAyAA0CmwJ3AJgBJAERAVABBAEEAUgBHwGTAaMCeQB5AGUAXwAgAB8BHwFhAGYAdAB5AHYCkABsAAQBaAEzAS8BAQESAXMAYgAgAJ8BSAFuAXoB4gCIAGkAPAEjAhkBNQAgAG8BFwFzACIBMQAwAAQBAQE9AQgBMwAgAHkB7QFpAG0AeQDIAXQAZQBzAGwBtwIhAWYAkgEyACAAggG6ABECygEeAR0BQQBQADYANQBpAAUBOQA5ADcAMwB3AFwBbAAcAR8BBQFWAQEBYgD2AWIAIwEHAkQBdwCuAXUAAAFOAgoA3AI/AgoBSAFrAQgBPQF5AAEBTQEwAXQADAFyAG0AAgFzAHkAFgMuAmYARQFjAK4BFQESAWgBNgIvAQABKQA7AIwBJwFnAG4ANQA1AIYCFwI2ADQARQFjANwBSwEiAVcBMwAwAJ4BCAFUAmMAkgEgAJkBfgFkADABOgA6AG8AbwBdAjYBcgBVAV8AXwDFAgYBEgFjABQBZAAtAQABRwGHAW4BSwFGAnIA4gCKAHAAaABmAGwA3wFzAGICAQFpAO0BmgGaAV8BbQA4AWMAdgBvAA0BCAEZA3sBcAAAAWsBSwFvAGsAdgAQAXMAYQH1AU8BOAA3ADkAMABiAW0AKgEwAWgAgAFfAicBFgGBAisBwAFuAREBAgOwAQwBwwISATgBcwAwARYBgAFtAAoBGAEUAW0AHAEdAQ0BMQA1AAQBGAHUAdQBDAF0ABoBAgFzADwCdgEnARUBLgF3AOwBqQJ5AUsCSwJuAC4ADAFzAOMB4wE5A3MBbAEFATABAQFjAHIBZwAPAS8ANwBZASAAcwBRARQBbgIPAWcAdwAAAU8BbAClAXQAaQFwAGEAdQBtAGUBdAARARMBBQFoAEABawEJAW8AWAF8AHwAjgGOAeIAjgCJA5UACwIVAmIAaQBFAWYCYgBsAHAAPAEWAUsBaQEtAv4CUQG3AcoBaAAVAXMCiwA9AccCbQAQAWkAGAEvAUcDRQEAAWsAJwEHAQgB8QIpAasBqwFiAOECEQEuATUBYwBiAHkAdgAgAGcACQEHA7UCXQAgACgBbwETAS8ByQE2AbkBdQJvADgBEwEAAUoCMgEYAWQAngEHASoBFAEJAoEBFwEuAR0BcgDaAXMAawF1Ar4CIQFsABsCBAIgAHMAGgIqAccBbgAaAosBZAC8AhIBaAASARABqwI2ADgALAEsAXUAAgHiALUAwwOXAIkB4QEyADAAZQAiAWsBgAFVAbICYgBzAI8BAAEPATUBbwBRAQ8B8wEGARwBbQAqAnQBAgFjAGQAYQAEAR0BAAE7ACAA3AEpAWQAmAEHAXQAzgEyAYkBIAFoAQUBdwCfAo0DcwF5ADICrQFUAWIAbAEtACAAQgFPASUBLgEUAQgBZgBpAfIBNgErAW4AYQBBARYBDAJiACkBdgARARoBEQFkACkBdQFwALsBAgFvADIB/AI8ATQBYwBEARQBQQJBAngCeAKEApECKwECAb8DCAF0AGkBcwBsAGMCCAF3AGEA1QEAAUcBUQHdATIB'), dtype=numpy.uint32)
bped_inv = {}
for i in range(256, 1024):
x = real_bped[i - 256]
a, b = x & 0xFFFF, x >> 16
bped_inv[a, b] = i
N_bits = 14
X_bits = 2 ** N_bits
mask = X_bits - 1
qfreqs = numpy.frombuffer(base64.b64decode('AQEBAQEBAQEBAUwBAQEBAQEBAQEBAQEBAQEBAQEBAQGyDTEUDwoKMko0ECE3RFY6N0tFNjctJTA4LxwXGSMeFAQsGB8WIRERDycNFxchEhweBR0jHwsKDQkHBioKIw0vLWd8pH6MbW9qciJPU2JjSYkJYaGdVDxJM0giEwwTDAECBQQEBgEBAgICAwUJAgEBAQIBAgQCAQMEAgEBAQEBBAIBBAECAgQBBgEBAgEBAQMBAQEEAQEBAgIBAQEBAQEBAQEGCQQDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ8GAQEBAQEBAQEBAQEDBAEBAQEBAQEBAQEBAQEBAUVbfj1ZOU0yPx1EIxZCFzxBZZRxN10ealWKLhxGKQoWXg5qMiJ0I0JlNTUSCR5MLhxIJSY1HS4FKygZFBQmOC8fSA8XOxk0Iyg/IBoRNhcTHRsXOwYfFzASHQEBDgEBIgkZCyIyEBEvARcBDRktFx8ZIQ4VGSQSHCAaDCAmHh8lBQsQJCQSEQcaGCIBDRQOHCEXEQsFIQsCEQ0LCQEMEhcVHRMBFRcBHh4eHQ0dGAQSDBENEg8QGxUbFQEUFRkFGRMZChkBGRgGEAgKGAULERcXBAYMBREWDRUWEAYJEAkOAQ8UBRUIAgoKCAgUDQUUARQBBA0UDAsBEhMSEhISEgURAxIFCQESARIMEQsCCBAREQkRERELBwkREAUKEAcQEA8PDwcPDg8CDwEJDw8IBw4ODgkPDg4HDg4NDg0HDQ4FDQEODQ0OBg4NDQgBDAQFBA0NDAwGAQwNDQ0MAwsGBwYMDAUHAQwFDAsMCwwMAQULCwwMBgsBAwwBDAMMCwsMCwoECwwFCwMLCgsLCwsKCwsKBgsLCgsKCwoKCgIKCgsECgoKAgoBCQoKAwoEAQEBCgkJBAkKAwoBCQkKCQQJAwkKCQkCCQIJBAcJAQkJCAkJCQkJCAkJCQkJCAkJAQkJCAkCCAkICAgGCAgJCAgHCAgIAQgICAgICQgJCAgDCAIIBwgBCAgIBwIICAYICAgHCAcICAcHCAEICAEHBwgHBwgIBwgIBwcHBwYICAgHBwcHBggGBwcGBQYGAQgHBwgHBwcHBwcHBwQBBwcHBwcGBwcHBwYHBgcGBwcGBwYHBgcHBwcHBwcGBAcHBgcHBgcDBgcEBwYGBwcHBwYGBwYGBgYFBgcHBwYGBAQBBgYHAQYGBgYGBgYGBQUGBgYGBgYCBgUFBQYGBgYGBQYGBgYFBgUFBQUGBgYGBgQFBAYFBgYBBQQFAQUFBQYFBQYGBgUGBQUEBQUGBQQFBQYFBgUFBQUGBQUFBQUFBQYGBgYFBQYEBQQFBQIDBQYFBQUFBQUEBQ=='), dtype=numpy.uint8)
cdf = numpy.insert(numpy.cumsum(qfreqs, dtype=numpy.uint16), 0, 0)
@functools.cache
def icdf(y):
for i, x in enumerate(cdf):
if y < x: return i - 1
def decompress_bpe(s):
s = numpy.array(s, dtype=numpy.uint16)
while True:
r = numpy.zeros(len(s) * 2, dtype=numpy.uint16)
z = 0
for c in s:
if c > 255:
x = real_bped[c - 256]
a, b = x & 0xFFFF, x >> 16
r[z] = a
z += 1
r[z] = b
z += 1
else:
r[z] = c
z += 1
if z == len(s): break
s = r[:z]
return bytes(s.astype(numpy.uint8))
def compress_bpe(s):
s = numpy.array(bytearray(s), dtype=numpy.uint16)
while True:
r = numpy.zeros_like(s)
z = 0
used = False
for pair in zip(s, s[1:]):
if used:
used = False
else:
mp = bped_inv.get(pair)
if mp:
r[z] = mp
z += 1
used = True
else:
r[z] = pair[0]
z += 1
used = False
if not used:
r[z] = s[-1]
z += 1
if z == len(s): break
s = r[:z]
return s
def compress_ans(bpes):
def C(x, s):
s_count = int(qfreqs[s])
return (x // s_count) * X_bits + int(cdf[s]) + (x % s_count)
x = 1
for symbol in bpes:
x = C(x, symbol)
return len(bpes), x
def decompress_ans(ilen, num):
def D(x):
slot = x & mask
sym = icdf(slot)
prev_state = (x // X_bits) * int(qfreqs[sym]) + slot - int(cdf[sym])
return sym, prev_state
x = num
syms = []
for _ in range(ilen):
sym, x = D(x)
syms.append(sym)
syms.reverse()
return syms
def compress(s):
l, x = compress_ans(compress_bpe(s))
return l.to_bytes(4, "little") + x.to_bytes(math.ceil(x.bit_length() / 8), "little")
def decompress(s):
l, x = s[:4], s[4:]
return decompress_bpe(decompress_ans(int.from_bytes(l, "little"), int.from_bytes(x, "little")))

366
code-guessing/fib.c Normal file
View File

@ -0,0 +1,366 @@
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <complex.h>
#include <string.h>
#include <stdlib.h>
#define nfibs 93
#define what int64_t
#define the fibs
#define fuck [
#define did nfibs
#define you ]
#define just =
#define fucking {
#define say 0
#define about ,
#define me 1
#define YOU ,
#define little 0
#define bitch }
#define i ;
#define ll void
#define have initf
#define YoU (
#define know )
#define I {
#define graduated for
#define top (
#define of int
#define my k
#define class =
#define in 2
#define tHe ;
#define navy k
#define seals <
#define and nfibs
#define ve k
#define been ++
#define involved )
#define In {
#define numerous fibs
#define secret [
#define raids k
#define on ]
#define al_quaeda =
#define anD fibs
#define i_ [
#define haVE k
#define over -
#define three 1
#define hundred ]
#define confirmed +
#define kills fibs
#define am k
#define trained -
#define gorilla ]
#define warfare ;
#define aNd }
#define I_ }
#define m bool
#define thE iusol
#define TOp [
#define sniper nfibs
#define IN ]
#define THE =
#define entire {
#define us 0
#define armed }
#define forces ;
#define yoU int
#define are bsectf
#define nothing (
#define to int64_t
#define Me n
#define but ,
#define JUsT int
#define another aa
#define target ,
#define i__ int
#define will b
#define wipe )
#define YOu {
#define The while
#define FuCK (
#define out aa
#define with <
#define precision b
#define THe )
#define likes {
#define which mid
#define has =
#define never (
#define BEEN aa
#define seen +
#define before b
#define ON )
#define this >>
#define earth 1
#define mark ;
#define My if
#define fuCkINg (
#define words fibs
#define yOu [
#define think mid
#define can <
#define get n
#define away )
#define With {
#define saying aa
#define that =
#define shit mid
#define TO +
#define ovEr ;
#define ThE }
#define internet else
#define Think {
#define again b
#define fucker =
#define as mid
#define we ;
#define speak }
#define aM return
#define contacting aa
#define MY ;
#define SecrEt }
#define network int
#define oF sumf
#define spies (
#define across int64_t
#define tHE trg
#define usa )
#define aND {
#define your int
#define ip pt
#define is =
#define being bsectf
#define traced (
#define right trg
#define now ,
#define so 0
#define yOU ,
#define better nfibs
#define prepare )
#define FOr ;
#define the_ if
#define storm (
#define maggot fibs
#define ThE_ [
#define STorm pt
#define THAT ]
#define wipes ==
#define ouT trg
#define pathetic {
#define LitTLe iusol
#define thing [
#define You pt
#define call ]
#define yOur =
#define life true
#define you_ ;
#define re return
#define FuCKINg 1
#define dead ;
#define kid }
#define I__ for
#define CAN (
#define be int
#define anywhere k
#define anytime =
#define And pt
#define i___ -
#define cAN 1
#define kill ;
#define You_ k
#define iN >
#define OvER 1
#define seven ;
#define hUndred k
#define ways --
#define AND )
#define tHat {
#define s if
#define jusT (
#define WitH iusol
#define mY [
#define bare k
#define hands ]
#define not )
#define only continue
#define AM ;
#define I___ iusol
#define extensively [
#define trAInEd k
#define unarmed =
#define combat true
#define bUT ;
#define i____ if
#define Have (
#define access sumf
#define tO (
#define eNtIRe -
#define arsenal fibs
#define Of [
#define THE_ k
#define united ]
#define states )
#define marine )
#define corps return
#define ANd 1
#define WILl iusol
#define use [
#define it k
#define To ]
#define its =
#define full false
#define extent ;
#define to_ }
#define WiPe return
#define YoUR 0
#define miserable ;
#define ass }
#define off long
#define tHE_ *
#define face f
#define OF (
#define tHe_ int64_t
#define continent trg
#define LIttle int
#define ShIT *
#define iF length
#define OnLY )
#define could if
#define hAvE (
#define known fibs
#define whAt [
#define unholy 2
#define retribution ]
#define YouR ==
#define clever )
#define comment initf
#define was (
#define aBout )
#define To_ ;
#define bring memset
#define down (
#define upon iusol
#define maybe 0
#define would nfibs
#define hAVE )
#define held ;
#define YOUR sumf
#define FUCkIng (
#define tongue trg
#define buT )
#define couldn *
#define t length
#define YoU_ =
#define didn 0
#define T ;
#define AnD for
#define NOw (
#define RE k
#define paying =
#define The_ 0
#define price ;
#define YOU_ k
#define goddamn <
#define idiot nfibs
#define wiLl k
#define shIT ++
#define fury )
#define all {
#define OVEr if
#define and_ iusol
#define wilL k
#define drown ]
#define in_ )
#define iT {
#define Re *
#define FuCkING length
#define DEad )
#define kiddo ++
#define WhAT ;
#define f___ }
#define DID int
#define yOU_ j
#define f___ing 0
#define type ;
#define AbOuT long
#define ME *
#define yOu_ out
#define lITTLe =
#define bitcH calloc
#define I____ (
#define Ll *
#define HAVe length
#define Know sizeof
#define gRADUaTED uint64_t
#define ToP )
#define of_ )
#define CLaSs for
#define at (
#define mit int
#define aNd_ k
#define i_____ =
#define Ve 0
#define bEEN ;
#define INVoLVED k
#define IN_ <
#define NUmeRouS nfibs
#define secreT ;
#define wITH ++
#define anonymous )
#define HAve (
#define oVer iusol
#define threE [
#define hUNdReD k
#define coNfIRMEd ]
#define ddoses )
#define Am out
#define trAined [
#define In_ j
#define online ]
#define trolling =
#define anD_ k
#define M j
#define thE_ ++
#define tOp ;
#define hacker }
#define iN_ }
#define THe_ return
#define ENTirE out
#define world ;
#define YOu_ }
#define aRe int
#define NOthinG main
#define mE )
#define BUt {
#define juSt initf
#define AnotHER (
#define virus )
#define host ;
#define WilL (
#define wIpE int
#define yoU_ k
#define F___ 0
#define oUt ;
#define wITh k
#define PReCiSiON <
#define the__ 100
#define LIKeS ;
#define oF_ k
#define WHICH ++
#define Has )
#define nevEr {
#define BeEN sumf
#define sEen (
#define befoRE 1
#define InTeRNET sumf
#define mArK (
#define my_ 2
#define f___Ing )
#define wORds ;
#define ThinK }
what the fuck did you just fucking say about me YOU little bitch i ll have YoU know I graduated top of my class in tHe navy seals and i ve been involved In numerous secret raids on al_quaeda anD i_ haVE over three hundred confirmed kills i_ am trained in gorilla warfare aNd I_ m thE TOp sniper IN THE entire us armed forces yoU are nothing to Me but JUsT another target i__ will wipe YOu The FuCK out with precision THe likes of which has never BEEN seen before ON this earth mark My fuCkINg words yOu think you can get away With saying that shit TO me ovEr ThE internet Think again fucker as we speak I_ aM contacting MY SecrEt network oF spies across tHE usa aND your ip is being traced right now so yOU better prepare FOr the_ storm maggot ThE_ STorm THAT wipes ouT THe pathetic LitTLe thing You call yOur life you_ re FuCKINg dead kid I__ CAN be anywhere anytime And i___ cAN kill You_ iN OvER seven hUndred ways AND tHat s jusT WitH mY bare hands not only AM I___ extensively trAInEd IN unarmed combat bUT i____ Have access tO tHE eNtIRe arsenal Of THE_ united states marine corps ANd i WILl use it To its full extent to_ WiPe YoUR miserable ass off tHE_ face OF tHe_ continent yOU LIttle ShIT iF OnLY YOu could hAvE known whAt unholy retribution YouR little clever comment was aBout To_ bring down upon yOU maybe YOU would hAVE held YOUR FUCkIng tongue buT you_ couldn t YoU_ didn T AnD NOw yoU RE paying The_ price YOU_ goddamn idiot i wiLl shIT fury all OVEr YoU and_ yOu wilL drown in_ iT YoU Re FuCkING DEad kiddo WhAT ThE f___ DID yOU_ just f___ing type AbOuT ME yOu_ lITTLe bitcH I____ Ll HAVe yOU Know I____ gRADUaTED ToP of_ MY CLaSs at mit aNd_ i_____ Ve bEEN INVoLVED IN_ NUmeRouS secreT raids wITH anonymous aND i____ HAve oVer threE hUNdReD coNfIRMEd ddoses I Am trAined In_ online trolling anD_ i M thE_ tOp hacker iN_ THe_ ENTirE world YOu_ aRe NOthinG tO mE BUt juSt AnotHER virus host I__ WilL wIpE yoU_ THE F___ oUt wITh PReCiSiON the__ LIKeS oF_ WHICH Has nevEr BeEN sEen befoRE ON tHe InTeRNET mArK my_ f___Ing wORds YOu_ ThinK

73
code-guessing/fib.py Normal file
View File

@ -0,0 +1,73 @@
import subprocess
import ctypes
import tempfile
import bisect
fibs = [0, 1]
def make_fibs(n):
while fibs[-1] < n:
fibs.append(fibs[-1] + fibs[-2])
def dfs(target, inuse=set()):
make_fibs(target)
end_index = bisect.bisect_left(fibs, target)
if fibs[end_index] == target and target not in inuse:
return inuse | {end_index}
for i, possibility in enumerate(fibs[end_index:1:-1]):
reali = end_index - i
if reali in inuse: continue
new = inuse | {reali}
if result := dfs(target - possibility, new): return result
make_fibs(2**63)
print(len(fibs))
"""
raise SystemExit()
for i in range(2, 10000):
print("doing", i)
res = dfs(i)
print(res)
assert sum(map(lambda x: fibs[x], res)) == i, "numbers do not sum to thing"
assert tuple(sorted(set(res))) == tuple(sorted(res)), "things are not unique"
"""
def c_wrapper(file):
print("Compiling", file)
temp = tempfile.mktemp(prefix="lib-compile-")
print(temp)
if subprocess.run(["gcc", file, "-o", temp, "-shared", "-fPIC"]).returncode != 0:
raise ValueError("compilation failed")
library = ctypes.CDLL(temp)
entry = library.f
entry.restype = ctypes.POINTER(ctypes.c_int64)
def wrapper(n):
vlen_ptr = ctypes.c_int(0)
out = entry(n, ctypes.byref(vlen_ptr))
l_out = []
for i in range(vlen_ptr.value):
#print(out[i])
l_out.append(out[i])
return l_out
return wrapper
def gollariosolver(n):
#print(n, "is n")
x = bisect.bisect_left(fibs, n)
out = set()
z = 0
for i in range(x, 0, -1):
#print("gollario", i, z, fibs[i])
if (y := fibs[i] + z) <= n:
z = y
out.add(i)
if z == n:
return out
print(fibs[12]+ fibs[23] + fibs[34])
c_code = c_wrapper("fib.c")
for i in range(2, 2**16):
res = c_code(i)
#res = gollariosolver(i)
assert sum(map(lambda x: fibs[x], res)) == i, "numbers do not sum to thing"
assert tuple(sorted(set(res))) == tuple(sorted(res)), "things are not unique"

71
code-guessing/fibinput.c Normal file
View File

@ -0,0 +1,71 @@
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <complex.h>
#include <string.h>
#include <stdlib.h>
#define nfibs 93
int64_t fibs[nfibs] = {0, 1, 0};
void initf() {
for (int k = 2; k < nfibs; k++) {
fibs[k] = fibs[k-1] + fibs[k-2];
}
}
bool iusol[nfibs] = {0};
int bsectf(int64_t n, int aa, int b) {
while (aa < b) {
int mid = (aa + b) >> 1;
if (fibs[mid] < n) { aa = mid + 1; }
else { b = mid; }
}
return aa;
}
int sumf(int64_t trg) {
int pt = bsectf(trg, 0, nfibs);
if (fibs[pt] == trg) {
iusol[pt] = true;
return 1;
}
for (int k = pt - 1; k > 1; k--) {
if (iusol[k]) continue;
iusol[k] = true;
if (sumf(trg - fibs[k])) return 1;
iusol[k] = false;
}
return 0;
}
long*f(int64_t trg, int*length) {
if (fibs[2] == 0) initf();
memset(iusol, 0, nfibs);
sumf(trg);
*length = 0;
for (int k = 0; k < nfibs; k++) {
if (iusol[k]) {
(*length)++;
}
}
int j = 0;
long*out = calloc(*length, sizeof(uint64_t));
for (int k = 0; k < nfibs; k++) {
if (iusol[k]) {
out[j] = k;
j++;
}
}
return out;
}
int main() {
initf();
for (int k = 0; k < 100; k++) {
sumf(1);
sumf(2);
}
}

70
code-guessing/fiborig.c Normal file
View File

@ -0,0 +1,70 @@
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <complex.h>
#include <string.h>
#include <stdlib.h>
#define nfibs 93
int64_t fibs[nfibs] = {0, 1, 0};
void initf() {
for (int i = 2; i < nfibs; i++) {
fibs[i] = fibs[i-1] + fibs[i-2];
}
}
bool iusol[nfibs] = {0};
int bsectf(int64_t n, int a, int b) {
while (a < b) {
int mid = (a + b) >> 1;
if (fibs[mid] < n) { a = mid + 1; }
else { b = mid; }
}
return a;
}
int sumf(int64_t target) {
int pt = bsectf(target, 0, nfibs);
if (fibs[pt] == target) {
iusol[pt] = true;
return 1;
}
for (int i = pt - 1; i > 1; i--) {
if (iusol[i]) continue;
iusol[i] = true;
if (sumf(target - fibs[i])) return 1;
iusol[i] = false;
}
return 0;
}
long*f(int64_t target, int*length) {
if (fibs[2] == 0) initf();
memset(iusol, 0, nfibs);
sumf(target);
*length = 0;
for (int i = 0; i < nfibs; i++) {
if (iusol[i]) {
(*length)++;
}
}
int j = 0;
long*out = calloc(*length, sizeof(uint64_t));
for (int i = 0; i < nfibs; i++) {
if (iusol[i]) {
out[j] = i;
j++;
}
}
return out;
}
int main() {
initf();
for (int i = 0; i < 100; i++) {
sumf(1);
sumf(2);
}
}

1
code-guessing/freqs.json Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
entry = lambda s: __import__("regex").fullmatch(r"""[\t\n ]*(?:(?:\[[\t\n ]*(?:|(?R)|(?R)(?:,[\t\n ]*(?R)[\t\n ]*)*)[\t\n ]*])|(?:{(?:[\t\n ]*|(?:[\t\n ]*"(?:[^"\\\n]|\\["\\/bfnrt]|\\u[0-9a-fA-F]{4})*"[\t\n ]*:[\t\n ]*(?R)[\t\n ]*)|(?:(?:[\t\n ]*"(?:[^"\\\n]|\\["\\/bfnrt]|\\u[0-9a-fA-F]{4})*"[\t\n ]*:[\t\n ]*(?R)[\t\n ]*)(?:,(?:[\t\n ]*"(?:[^"\\\n]|\\["\\/bfnrt]|\\u[0-9a-fA-F]{4})*"[\t\n ]*:[\t\n ]*(?R)[\t\n ]*))*))})|(?:true|false|null|\-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?|"(?:[^"\\\n]|\\["\\/bfnrt]|\\u[0-9a-fA-F]{4})*"))[\t\n ]*""", s, 1<<8)

View File

@ -0,0 +1,30 @@
import json, math, random
N_bits = 14
X_bits = 2 ** 14
with open("compr.json", "r") as f:
with open("freqs.json", "w") as g:
rawfreqs = { int(k): v for k, v in json.load(f)["frequencies"].items() }
for i in range(1024):
if i not in rawfreqs:
rawfreqs[i] = 1
bpe_freqs = sorted(rawfreqs.items(), key=lambda x: x[1])
total = sum(map(lambda x: x[1], bpe_freqs))
table = { k[0]: 1 for k in bpe_freqs }
for i, freq in bpe_freqs:
val = max(freq / total * X_bits - 1, 0)
print(val)
n = math.floor(val)
q = val - n
x = n + (random.random() < q)
table[i] += x
diff = X_bits - sum(table.values())
adjust = random.choices(list(filter(lambda x: table[x] > 1, range(1024))), k=abs(diff))
if diff > 0:
for a in adjust:
table[a] += 1
elif diff < 0:
for a in adjust:
table[a] -= 1
print(diff, sum(table.values()))
json.dump(table, g)

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 B

296
code-guessing/test7.py Normal file
View File

@ -0,0 +1,296 @@
import sys
import importlib
import subprocess
import ctypes
import random
import traceback
import textwrap
import json
import os
import shutil
try:
from tqdm import tqdm, trange
except ImportError:
print("`tqdm` not found. there will be no progress bars")
def tqdm(x):
return x
trange = range
filename = sys.argv[1]
if filename.endswith(".py"):
print("importing as Python...")
module = importlib.import_module(filename.removesuffix(".py"))
print("done.")
try:
entry = module.entry
except AttributeError:
print("module is missing entrypoint `entry`. aborting.")
sys.exit(1)
elif filename.endswith(".c"):
print("compiling as C with `gcc`...")
obj = "./" + filename.removesuffix(".c") + ".so"
rc = subprocess.call(["gcc", "-shared", "-fPIC", *sys.argv[2:], filename, "-o", obj])
if rc != 0:
print("compilation failed. aborting.")
sys.exit(rc)
lib = ctypes.CDLL(obj)
try:
entry = lambda s: lib.entry(s.encode())
except AttributeError:
print("library is missing entrypoint `entry`. aborting.")
sys.exit(1)
elif filename.endswith(".rs"):
print("compiling as Rust...")
os.makedirs("./entry-rs/src", exist_ok=True)
with open("./entry-rs/Cargo.toml", "w") as f:
f.write("""
[package]
name = "entry-rs"
version = "0.1.0"
edition = "2021"
[lib]
name = "entry_rs"
crate-type = ["cdylib"]
[dependencies.pyo3]
version = "0.14.5"
features = ["extension-module"]
""")
with open("./entry-rs/src/lib.rs", "w") as f:
f.write("""
use pyo3::prelude::*;
mod entry_impl;
use entry_impl::entry;
#[pyfunction]
fn wrapped_entry(s: &str) -> PyResult<bool> {
Ok(entry(s))
}
#[pymodule]
fn entry_rs(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(wrapped_entry, m)?)?;
Ok(())
}
""")
shutil.copyfile(filename, "./entry-rs/src/entry_impl.rs")
os.chdir("entry-rs")
rc = subprocess.call(["cargo", "build", "--release"])
os.chdir("..")
if rc != 0:
print("compilation failed. aborting.")
sys.exit(1)
sys.path.append("./entry-rs/target/release")
os.rename("./entry-rs/target/release/libentry_rs.so", "./entry-rs/target/release/entry_rs.so")
module = importlib.import_module("entry_rs")
entry = module.wrapped_entry
else:
print("unrecognized file extension")
sys.exit(1)
tests = [
("zero", "0", True),
("leadingws", "\n\t 0", True),
("trailingws", "0\n\t ", True),
("one", "1", True),
("negativezero", "-0", True),
("negativeone", "-1", True),
("wsisbadhere", "- 1", False),
("multidigit", "100", True),
("leadingzero", "01", False),
("noplus", "+1", False),
("decimal", "1.0", True),
("leadingdot", ".0", False),
("trailingdot", "0.", False),
("bigdecimal", "13847432.35809092", True),
("scientific", "1e2", True),
("bigscientific", "-2376420.0033533e533", True),
("capitalscientific", "2E3", True),
("scientificminus", "2e-3", True),
("scientificplusisokay", "2E+3", True),
("nowshere", "2 e + 3", False),
("integerexponent", "2e3.0", False),
("emptystring", r'""', True),
("notemptystring", r'"not empty"', True),
("escapes", r'"\n\t\r\f\b\/"', True),
("unicodeescape", r'"\uaA0b"', True),
("moreescapes", r'"\\ \" "', True),
("evilescape", r'"\"', False),
("manybackslashes", r'"\\\\\\\\"', True),
("evilmanybackslashes", r'"\\\\\\\\\"', False),
("invalidescape", r'"\j"', False),
("invalidunicodeescape", r'"\u000j"', False),
("bigstring", r'"greetings people. this is a big string. \\[}[{]}}\"&*%4783.02 I am trying to break your code. am I doing a good job?\nplease say I am\\\\"', True),
("emptyarray", "[]", True),
("lessemptyarray", "[0]", True),
("evenlessemptyarray", "[0, 1]", True),
("heterogenousarray", '[0, 2.0, "string"]', True),
("unclosedarray", "[0", False),
("trailingcomma", "[0,]", False),
("leadingcomma", "[,0]", False),
("leadingcommaobj", '{,"bee":-4}', False),
("gap", "[0,,1]", False),
("nesting", "[[], [1, [2, []], [3, 4]]]", True),
("hugenest", "[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]", True),
("emptyobject", "{}", True),
("singletonobject", r'{"key": "value"}', True),
("imaginebeinghetero", r'{"key": "value", "otherkey": 1}', True),
("keysarestrings", "{0: 0}", False),
("dupesareokay", r'{"key": 0, "key": 1}', True),
("stillnotrailingcomma", r'{"key": "value",}', False),
("mixing", r'[0, {"O.O": [{"object in a list in an object in a list\nwhat will it do": "it will do this"}]}]', True),
("whitespacesilliness", '[ \t 0 , { "whitespace4all" : \n {"woah" :[\n [ \n ] ,0 ]} \t}]', True),
("true", "true", True), # hehe
("false", "false", True),
("null", "null", True),
("nototherstuff", "asdf", False),
("alltogethernow", r"""
{
"this": "a JSON value",
"people": [
{
"name": "christina",
"value": 1e100
},
{
"name": "everyone else probably\nidk",
"value": 0.0e0
}
],
"peoplecoolerthanchristina": {
"value": null,
"ready": false,
"status": "still processing"
}
}
""", True),
("noextradata", '["stuff"]extra stuff', False),
]
print("beginning testing suite")
failures = 0
for test_name, value, result in tqdm(tests):
print(f"`{test_name}`... ", end="")
try:
r = entry(value)
except BaseException:
print("error")
traceback.print_exc()
failures += 1
continue
if bool(r) == result:
print("ok")
else:
failures += 1
print("failed")
print(f"for test `{test_name}`:")
print(textwrap.indent(value, " "*2))
print(f"entry returned {r} when {result} was expected\n")
if not failures:
print("test suite finished, all ok")
else:
print(f"test suite finished. {failures} tests failed\n\n")
print("skipping randomized testing because your program is clearly broken and the output from those isn't very helpful for finding bugs")
sys.exit(2)
l = [r'\"', r'\\', r'\b', r'\f', r'\n', r'\r', r'\t', rf"\u{random.randint(0x0000, 0xFFFF):04{random.choice('xX')}}", *map(chr, range(ord(" "), ord("}")+1))]
l.remove("\\")
l.remove('"')
def gen_random_string():
s = '"'
for _ in range(random.randint(0, 8)):
s += random.choice(l)
s += '"'
return wsify(s)
def wsify(s):
return s + random.choice(" \t\n")*random.randint(0, 2)
def gen_random_json(n=1):
if n >= 12:
t = random.choice(["sentinel", "number", "string"])
else:
t = random.choice(["sentinel", "number", "array", "object", "string", "string", "number", "sentinel"])
if t == "sentinel":
return wsify(random.choice(["true", "false", "null"]))
elif t == "string":
return gen_random_string()
elif t == "array":
return wsify("[") + wsify(",").join(gen_random_json(n+1) for _ in range(5)) + wsify("]")
elif t == "object":
return wsify("{") + wsify(",").join(gen_random_string() + ":" + gen_random_json(n+1) for _ in range(5)) + wsify("}")
elif t == "number":
nt = random.choice(["int", "decimal", "sci"])
if nt == "int":
r = str(random.randint(0, 1000000000))
elif nt == "decimal":
r = str(random.uniform(0, 1000000000))
elif nt == "sci":
e = random.choice(["e", "E"])
p = random.choice(["+", "-", ""])
r = f"{random.uniform(0, 1000000000)}{e}{p}{random.randint(0, 1000000000)}"
else:
assert False
return "-"*random.randint(0, 1) + r
else:
assert False
print("beginning randomized testing.")
random_failures = 0
for _ in trange(100):
j = gen_random_json()
tr = True
if random.randint(0, 1):
j = list(j)
for _ in range(20):
t = random.choice(["insert", "remove", "replace", "replace", "replace"])
if not j and t in ("remove", "replace"):
continue
idx = random.randrange(0, len(j)+(t == "insert"))
c = random.choice(["\n", "\t", " ", *map(chr, range(ord(" "), ord("}")+1))])
if t == "replace":
j[idx] = c
elif t == "insert":
j.insert(idx, c)
elif t == "remove":
j.pop(idx)
j = "".join(j)
try:
json.loads(j)
except json.JSONDecodeError:
tr = False
try:
r = entry(j)
except BaseException:
print("error")
traceback.print_exc()
random_failures += 1
continue
if bool(r) != tr:
print("randomized test case failed:")
print(textwrap.indent(j, " "*2))
print(f"entry returned {r} when {tr} was expected\n")
random_failures += 1
if not random_failures:
print("randomized testing finished. all ok\n\n")
else:
print(f"randomized testing finished with {random_failures} failures\n\n")
print("overall report:")
overall = failures + random_failures
if not overall:
print("no failures detected. all seems well!")
else:
print(f"{overall} failures detected overall. you have some bugs to fix")
sys.exit(2)

77
code-guessing/thingy.py Normal file
View File

@ -0,0 +1,77 @@
# -*- coding: utf-8 -*-
"""
Created on Mon Mar 30 08:37:12 2015
@author: jonathan
"""
import clang.cindex
import clang.enumerations
import random
# set the config
clang.cindex.Config.set_library_file("/lib/libclang.so")
class Tokenizer:
# creates the object, does the inital parse
def __init__(self, path):
self.index = clang.cindex.Index.create()
self.tu = self.index.parse(path)
self.path = self.extract_path(path)
# To output for split_functions, must have same path up to last two folders
def extract_path(self, path):
return "".join(path.split("/")[:-2])
# tokenizes the contents of a specific cursor
def full_tokenize_cursor(self, cursor):
return [ token.spelling for token in cursor.get_tokens() ]
# tokenizes the entire document
def full_tokenize(self):
cursor = self.tu.cursor
return self.full_tokenize_cursor(cursor)
copypasta = """
What the fuck did you just fucking say about me, you little bitch? I'll have you know I graduated top of my class in the Navy Seals, and I've been involved in numerous secret raids on Al-Quaeda, and I have over three hundred confirmed kills. I am trained in gorilla warfare and I'm the top sniper in the entire US Armed Forces. You are nothing to me but just another target. I will wipe you the fuck out with precision the likes of which has never been seen before on this Earth, mark my fucking words. You think you can get away with saying that shit to me over the Internet? Think again, fucker. As we speak, I am contacting my secret network of spies across the USA and your IP is being traced right now so you better prepare for the storm, maggot. The storm that wipes out the pathetic little thing you call your life. You're fucking dead, kid. I can be anywhere, anytime, and I can kill you in over seven hundred ways, and that's just with my bare hands. Not only am I extensively trained in unarmed combat, but I have access to the entire arsenal of the United States Marine Corps and I will use it to its full extent to wipe your miserable ass off the face of the continent, you little shit. If only you could have known what unholy retribution your little clever comment was about to bring down upon you, maybe you would have held your fucking tongue. But you couldn't, you didn't, and now you're paying the price, you goddamn idiot. I will shit fury all over you and you will drown in it. You're fucking dead, kiddo.
What the f--- did you just f---ing type about me, you little bitch? I'll have you know I graduated top of my class at MIT, & I've been involved in numerous secret raids with Anonymous, & I have over three hundred confirmed DDoSes. I am trained in online trolling & I'm the top hacker in the entire world. You are nothing to me but just another virus host. I will wipe you the f--- out with precision the likes of which has never been seen before on the Internet, mark my f---ing words. You think you can get away with typing that shit to me over the Internet? Think again, f---er. As we chat over IRC I am tracing your IP with my damn bare hands so you better prepare for the storm, maggot. The storm that wipes out the pathetic little thing you call your computer. You're f---ing dead, kid. I can be anywhere, anytime, & I can hack into your files in over seven hundred ways, & that's just with my bare hands. Not only am I extensively trained in hacking, but I have access to the entire arsenal of every piece of malware ever created & I will use it to its full extent to wipe your miserable ass off the face of the world wide web, you little shit. If only you could have known what unholy retribution your little clever comment was about to bring down upon you, maybe you would have held your f---ing fingers. But you couldn't, you didn't, & now you're paying the price, you goddamn idiot. I will shit code all over you & you will drown in it. You're f---ing dead, kiddo.
""".lower().replace("-", "_").replace("&", " and ")
for punct in "?'.,":
copypasta = copypasta.replace(punct, " ")
copypasta = [ x.strip() for x in copypasta.split(" ") if x.strip() ]
import sys
if len(sys.argv) != 2:
print("please provide a file argument")
exit(1)
def modcase(s):
return "".join([ c.upper() if random.randint(0, 1) else c.lower() for c in s ] )
tok = Tokenizer(sys.argv[1]) # path to a C++ file
results = tok.full_tokenize()
tmap = {"if": None, "for": None}
seq = []
for cpasta, c in zip(copypasta, results):
while cpasta in tmap and tmap[cpasta] != c:
for i in range(200):
tr = modcase(cpasta)
if tr not in tmap or tmap[tr] == c:
cpasta = tr
break
else: cpasta += "_"
tmap[cpasta] = c
seq.append(cpasta)
print("""#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <complex.h>
#include <string.h>
#include <stdlib.h>
#define nfibs 93""")
for k, v in tmap.items():
if v: print(f"#define {k} {v}")
print(" ".join(seq))

249
code-guessing/tictac.html Normal file
View File

@ -0,0 +1,249 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tic-Tac-Toe</title>
<style>
.row {
width: fit-content;
height: 4em;
}
.layer {
margin: 1em;
width: fit-content;
border: 1px solid black;
display: inline-block;
}
.cell {
width: 4em;
height: 4em;
display: inline-block;
border: 1px solid gray;
}
.cell-1 {
background: blue;
}
.cell-2 {
background: red;
}
</style>
</head>
<body>
<div id="screen"></div>
<div id="controls"><button id="rotate">Rotate View</button></div>
<div id="info"></div>
<script id="game-logic">
var size = 4
var gsize = size ** 3
var grid = new Uint8Array(gsize)
var range = Array(size).fill(null).map((_, index) => index)
function packCoord([l, r, c]) {
return l + r * size + c * size * size
}
function cartesianProduct(xss) {
var prods = [[]]
for (const xs of xss) {
prods = xs.flatMap(x => prods.map(p => p.concat([x])))
}
return prods
}
function rotateArray(xs, by) {
return xs.slice(by).concat(xs.slice(0, by))
}
function zip(xs, ys) {
return xs.map((x, i) => [x, ys[i]])
}
var inPlaneDiagonals = cartesianProduct([[zip(range, range), zip(range, range.map(x => x).reverse())], range]).map(([diag, a]) => diag.map(([b, c]) => [a, b, c]))
var throughLayerLines = cartesianProduct([range, range]).map(withinLayerPosition => range.map(i => withinLayerPosition.concat([i]))).concat(inPlaneDiagonals)
var winConditions = throughLayerLines.concat(throughLayerLines.map(l => l.map(c => rotateArray(c, 1))), throughLayerLines.map(l => l.map(c => rotateArray(c, 2))))
function insertDiagonalFrom(row, cell) {
var diagonal = []
var dirR = row == 0 ? 1 : -1
var dirC = cell == 0 ? 1 : -1
for (var layer = 0; layer < size; layer++) {
diagonal.push([layer, row, cell])
row += dirR
cell += dirC
}
winConditions.push(diagonal)
}
insertDiagonalFrom(0, 0)
insertDiagonalFrom(0, size - 1)
insertDiagonalFrom(size - 1, 0)
insertDiagonalFrom(size - 1, size - 1)
winConditions = winConditions.map(w => w.map(packCoord))
function containsWin(grid, real) {
outer: for (var winCondition of winConditions) {
var fst = grid[winCondition[0]]
for (var i = 1; i < winCondition.length; i++) {
var val = grid[winCondition[i]]
if (val != fst || val == 0) {
continue outer
}
}
return fst
}
}
function unfilledLineLocation(grid, player) {
outer: for (var winCondition of winConditions) {
var count = 0
var last = null
for (var i = 0; i < winCondition.length; i++) {
if (grid[winCondition[i]] === player) {
count++
} else if (grid[winCondition[i]] == 0) {
last = winCondition[i]
} else {
continue outer
}
}
if (count == size - 1) { return last }
}
}
function possibleMoves(grid) {
var out = []
for (var i = 0; i < gsize; i++) {
if (!grid[i]) {
out.push(i)
}
}
return out
}
function set(grid, cell, val) {
var out = new Uint8Array(grid.length)
out.set(grid)
out[cell] = val
return out
}
function otherPlayer(p) {
return 3 - p
}
function randomPick(xs) {
return xs[Math.floor(xs.length * Math.random())]
}
function runRandomGame(grid, player) {
var targetPlayer = player
while (true) {
var moves = possibleMoves(grid)
if (moves.length === 0) {
return 0
}
grid = set(grid, randomPick(moves), player)
var winner = containsWin(grid)
if (winner === targetPlayer) {
return 1
} else if (winner === otherPlayer(targetPlayer)) {
return -1
}
player = otherPlayer(player)
}
}
function scoreGrid(grid, player) {
let score = 0
for (let i = 0; i < 100; i++) {
score += runRandomGame(grid, player)
}
return score
}
function findBestMove(grid, player) {
var nextLoc = unfilledLineLocation(grid, player)
if (nextLoc != null) { return nextLoc }
nextLoc = unfilledLineLocation(grid, otherPlayer(player))
if (nextLoc != null) { return nextLoc }
var bestscore = -Infinity
var best = null
var moves = possibleMoves(grid)
for (const p of moves) {
var optn = scoreGrid(set(grid, p, player), player)
if (optn > bestscore) {
bestscore = optn
best = p
}
}
return best
}
</script>
<script>
var workerGlue = `
onmessage = event => {
postMessage(findBestMove(...event.data))
}
`
var worker = new Worker(`data:application/javascript;base64,${btoa(document.getElementById("game-logic").innerHTML + workerGlue)}`)
var screen = document.getElementById("screen")
var info = document.getElementById("info")
var rotation = 0
document.getElementById("rotate").onclick = () => {
rotation += 1
rotation %= 3
render()
}
var currentPlayer = 1
function render() {
var html = ""
for (var l = 0; l < size; l++) {
html += '<div class="layer">'
for (var r = 0; r < size; r++) {
html += '<div class="row">'
for (var c = 0; c < size; c++) {
var coord = packCoord(rotateArray([l, r, c], rotation))
html += `<div class="cell cell-${grid[coord]}" id="cell-${coord}"></div>`
}
html += '</div>'
}
html += '</div>'
}
screen.innerHTML = html
info.innerHTML = `Player ${currentPlayer}'s turn`
}
function reset() {
grid = new Uint8Array(gsize)
currentPlayer = 1
render()
}
function onTurn(move) {
grid[move] = currentPlayer
currentPlayer = otherPlayer(currentPlayer)
render()
var winner = containsWin(grid)
if (winner != null) {
alert(`${winner} wins!`)
reset()
return true
}
}
worker.onmessage = event => {
onTurn(event.data)
}
window.onclick = event => {
if (currentPlayer != 1) { return }
var [start, coord] = event.target.id.split("-")
coord = parseInt(coord)
if (isNaN(coord) || typeof coord != "number" || start != "cell") { return }
if (grid[coord]) { return }
if (!onTurn(coord)) {
worker.postMessage([grid, currentPlayer])
}
}
render()
</script>
</body>
</html>

142
code-guessing/token_map.csv Normal file
View File

@ -0,0 +1,142 @@
NUM,20
STRING,21
CHAR,22
BOOL,23
LITERAL,24
std,25
cout,26
cin,27
vector,28
pair,29
string,30
NULL,31
size_t,32
DEC,33
REF,34
USE,35
IDENT,36
=,37
+=,38
-=,39
*=,40
/=,41
%=,42
&=,43
|=,44
^=,45
<<=,46
>>=,47
+,48
-,49
*,50
/,51
%,52
~,53
&,54
|,55
^,56
<<,57
>>,58
!,59
&&,60
||,61
==,62
!=,63
<,64
>,65
<=,66
>=,67
.,68
",",69
[,70
],71
:,72
::,73
->,74
?,75
alignas,76
alignof,77
and,78
and_eq,79
asm,80
auto,81
bitand,82
bitor,83
bool,84
break,85
case,86
catch,87
char,88
class,89
compl,90
const,91
constexpr,92
const_cast,93
continue,94
decltype,95
default,96
delete,97
do,98
double,99
else,100
enum,101
explicit,102
export,103
extern,104
false,105
float,106
for,107
friend,108
goto,109
if,110
inline,111
int,112
long,113
mutable,114
namespace,115
new,116
noexcept,117
not,118
not_eq,119
nullptr,120
operator,121
or,122
or_eq,123
private,124
protected,125
public,126
register,127
return,128
short,129
signed,130
sizeof,131
static,132
static_cast,133
struct,134
switch,135
template,136
this,137
thread_local,138
throw,139
true,140
try,141
typedef,142
typeid,143
typename,144
union,145
unsigned,146
using,147
virtual,148
void,149
volatile,150
wchar_t,151
while,152
xor,153
xor_eq,154
.*,155
->*,156
++,157
--,158
__func__,159
#,160
reinterpret_cast,161
1 NUM 20
2 STRING 21
3 CHAR 22
4 BOOL 23
5 LITERAL 24
6 std 25
7 cout 26
8 cin 27
9 vector 28
10 pair 29
11 string 30
12 NULL 31
13 size_t 32
14 DEC 33
15 REF 34
16 USE 35
17 IDENT 36
18 = 37
19 += 38
20 -= 39
21 *= 40
22 /= 41
23 %= 42
24 &= 43
25 |= 44
26 ^= 45
27 <<= 46
28 >>= 47
29 + 48
30 - 49
31 * 50
32 / 51
33 % 52
34 ~ 53
35 & 54
36 | 55
37 ^ 56
38 << 57
39 >> 58
40 ! 59
41 && 60
42 || 61
43 == 62
44 != 63
45 < 64
46 > 65
47 <= 66
48 >= 67
49 . 68
50 , 69
51 [ 70
52 ] 71
53 : 72
54 :: 73
55 -> 74
56 ? 75
57 alignas 76
58 alignof 77
59 and 78
60 and_eq 79
61 asm 80
62 auto 81
63 bitand 82
64 bitor 83
65 bool 84
66 break 85
67 case 86
68 catch 87
69 char 88
70 class 89
71 compl 90
72 const 91
73 constexpr 92
74 const_cast 93
75 continue 94
76 decltype 95
77 default 96
78 delete 97
79 do 98
80 double 99
81 else 100
82 enum 101
83 explicit 102
84 export 103
85 extern 104
86 false 105
87 float 106
88 for 107
89 friend 108
90 goto 109
91 if 110
92 inline 111
93 int 112
94 long 113
95 mutable 114
96 namespace 115
97 new 116
98 noexcept 117
99 not 118
100 not_eq 119
101 nullptr 120
102 operator 121
103 or 122
104 or_eq 123
105 private 124
106 protected 125
107 public 126
108 register 127
109 return 128
110 short 129
111 signed 130
112 sizeof 131
113 static 132
114 static_cast 133
115 struct 134
116 switch 135
117 template 136
118 this 137
119 thread_local 138
120 throw 139
121 true 140
122 try 141
123 typedef 142
124 typeid 143
125 typename 144
126 union 145
127 unsigned 146
128 using 147
129 virtual 148
130 void 149
131 volatile 150
132 wchar_t 151
133 while 152
134 xor 153
135 xor_eq 154
136 .* 155
137 ->* 156
138 ++ 157
139 -- 158
140 __func__ 159
141 # 160
142 reinterpret_cast 161

View File

@ -0,0 +1,16 @@
import regex
"""
WHITESPACE = r"[\t\n ]*"
NUMBER = r"\-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?"
ARRAY = f"(?:\[{WHITESPACE}(?:|(?R)|(?R)(?:,{WHITESPACE}(?R){WHITESPACE})*){WHITESPACE}])"
STRING = r'"(?:[^"\\\n]|\\["\\/bfnrt]|\\u[0-9a-fA-F]{4})*"'
TERMINAL = f"(?:true|false|null|{NUMBER}|{STRING})"
PAIR = f"(?:{WHITESPACE}{STRING}{WHITESPACE}:{WHITESPACE}(?R){WHITESPACE})"
OBJECT = f"(?:{{(?:{WHITESPACE}|{PAIR}|(?:{PAIR}(?:,{PAIR})*))}})"
VALUE = f"{WHITESPACE}(?:{ARRAY}|{OBJECT}|{TERMINAL}){WHITESPACE}"
print(VALUE)
def entry(s):
return regex.fullmatch(VALUE, s, regex.V1)
"""
entry = lambda s: __import__("regex").fullmatch(r"""[\t\n ]*(?:(?:\[[\t\n ]*(?:|(?R)|(?R)(?:,[\t\n ]*(?R)[\t\n ]*)*)[\t\n ]*])|(?:{(?:[\t\n ]*|(?:[\t\n ]*"(?:[^"\\\n]|\\["\\/bfnrt]|\\u[0-9a-fA-F]{4})*"[\t\n ]*:[\t\n ]*(?R)[\t\n ]*)|(?:(?:[\t\n ]*"(?:[^"\\\n]|\\["\\/bfnrt]|\\u[0-9a-fA-F]{4})*"[\t\n ]*:[\t\n ]*(?R)[\t\n ]*)(?:,(?:[\t\n ]*"(?:[^"\\\n]|\\["\\/bfnrt]|\\u[0-9a-fA-F]{4})*"[\t\n ]*:[\t\n ]*(?R)[\t\n ]*))*))})|(?:true|false|null|\-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?|"(?:[^"\\\n]|\\["\\/bfnrt]|\\u[0-9a-fA-F]{4})*"))[\t\n ]*""", s, regex.V1)

BIN
esolangs-iceberg/above.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
esolangs-iceberg/below.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
esolangs-iceberg/bottom.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -0,0 +1,178 @@
<!DOCTYPE html>
<html lang="en"><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Esolangs Iceberg Meme</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<style>
body {
background: black;
text-align: center;
max-width: 1200px;
margin: auto;
color: white;
font-family: "Ubuntu", sans-serif;
}
ul {
margin: 0;
padding: 0;
}
li {
display: inline-block;
margin: 10px 20px;
font-weight: bold;
vertical-align: text-bottom;
}
li * {
color: white;
}
li a {
text-decoration: none;
}
li:nth-child(5n+0) {
transform: translateY(5px);
}
li:nth-child(5n+1) {
transform: translateY(-5px);
}
li:nth-child(5n+2) {
transform: translateY(0px);
}
li:nth-child(5n+3) {
transform: translateY(7px);
}
li:nth-child(5n+4) {
transform: translateY(2px);
}
li, h2 {
text-shadow: 1px 1px 2px black, 1px -1px 2px black, -1px -1px 2px black, -1px 1px 2px black, 1px 1px 2px black, 2px 2px 4px black;
}
.monospace, .monospace * {
font-family: "Ubuntu Mono", monospace;
word-break: break-all;
}
.aboveTheIceberg,
.onTheIceberg,
.belowTheWater,
.middleOfTheIceberg,
.bottomOfTheIceberg,
.belowTheIceberg {
border: 2px solid purple;
background-size: cover;
background-position: center;
padding: 4em;
}
.aboveTheIceberg {
background-image: url(above.jpg);
}
.onTheIceberg {
background-image: url(oniceberg.jpg);
}
.belowTheWater {
background-image: url(belowwater.jpg);
}
.middleOfTheIceberg {
background-image: url(middle.jpg);
}
.bottomOfTheIceberg {
background-image: url(bottom.jpg);
}
.belowTheIceberg {
background-image: url(below.jpg);
}
</style>
</head>
<body>
<p>Esolangs Iceberg</p>
<div class="iceberg">
<div class="aboveTheIceberg">
<ul>
<li>Macron development hell</li>
<li>50 votes</li>
<li>Code guessing</li>
<li>#rap-battles</li>
<li>APIONET</li>
<li>Apioforms incurse</li>
<li>Write some cool messages here!</li>
</ul>
</div>
<div class="onTheIceberg">
<ul>
<li>Macron/Micron split</li>
<li>#r9k-test</li>
<li>Esoserver</li>
<li>NSFW Esolangs</li>
<li>Olivia Time</li>
<li>type class struggle tweets</li>
<li>Programmer socks</li>
<li>GEORGE is all</li>
<li>First-star rule</li>
<li>garbage terminal</li>
</ul>
</div>
<div class="belowTheWater">
<ul>
<li>Project COMPARTMENTAL SLATS</li>
<li>Petcruel</li>
<li>Iterated prisoner's dilemma competition</li>
<li>CG5</li>
<li>LyricLy deliveries</li>
<li>Epicbot downtime</li>
<li>HelloBoi golfing</li>
<li>ASCIIpy spam day</li>
</ul>
</div>
<div class="middleOfTheIceberg">
<ul>
<li>Macron is an assembler</li>
<li>ABR typerace cheat</li>
<li>APL conspiracy</li>
<li>heavpoot is osmarks</li>
<li>second #staff-only channel</li>
<li>colin</li>
<li>less than 10% of users are frequently active</li>
<li>cyber PC diagram</li>
</ul>
</div>
<div class="bottomOfTheIceberg">
<ul>
<li>baidicoot was owner</li>
<li>Emu War Online</li>
<li>FungeChessBot</li>
<li>#club-penguin</li>
<li>macron compilers and interpreters are equivalent</li>
<li>two layer "?choose" recursion limit</li>
<li>GPT-based chatbot deployment</li>
</ul>
</div>
<div class="belowTheIceberg">
<ul>
<li>The real purpose of Lowlight</li>
<li>gollark was demoted for being cis</li>
<li>Typing Speeder harvests messages for blackmail</li>
<li>all esolangs members are gollark alts</li>
<li>Palaiologos' memetics research</li>
</ul>
</div>
</div>
</body></html>

BIN
esolangs-iceberg/middle.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

32
gpu_mandelbrot.py Normal file
View File

@ -0,0 +1,32 @@
import torch
import torchvision.transforms.functional as T
import math
torch.set_grad_enabled(False)
device = torch.device("cuda:0")
size = 6144
steps = 2048
xs = torch.linspace(-1, 1, size, dtype=torch.cfloat, device=device).tile(size, 1)
ys = torch.linspace(-1, 1, size, dtype=torch.cfloat, device=device).tile(size, 1).t() * 1j
zs = xs + ys
ws = zs.clone()
aws = abs(ws)
dead = torch.zeros_like(xs, dtype=torch.bool, device=device)
counts = torch.zeros_like(xs, dtype=torch.float, device=device)
for i in range(steps):
zs *= zs
zs += ws
dead |= abs(zs) > 4
counts += torch.where(dead, 1, 0)
zero = torch.zeros((size, size, 3), dtype=torch.float, device=device)
blue = torch.zeros((size, size, 3), dtype=torch.float, device=device)
blue[..., 2] = 1
itr = torch.log((steps - counts) / steps)
itr /= math.log(steps)
m = itr.reshape((size, size, 1)).repeat_interleave(3, -1)
z = m * blue
i = T.to_pil_image(z.permute(2, 0, 1))
i.save("/tmp/mandel.png")

2
ptt.py
View File

@ -11,7 +11,7 @@ import threading
scriptdir = os.path.dirname(os.path.abspath(sys.argv[0]))
red, green = os.path.join(scriptdir, "red.png"), os.path.join(scriptdir, "green.png")
l_key = keyboard.KeyCode(65312)
l_key = keyboard.Key.f8
source = "alsa_input.usb-0c76_USB_PnP_Audio_Device-00.mono-fallback"
MuteSetEvent, EVT_MUTE_SET_EVENT = wx.lib.newevent.NewEvent()

View File

@ -0,0 +1,64 @@
<!DOCTYPE html>
<meta charset="utf8">
<canvas id="canvas-but-good" width=768 height=768></canvas>
<div id="info"></div>
<script>
const canv = document.getElementById("canvas-but-good")
const info = document.getElementById("info")
const centerX = canv.width / 2
const centerY = canv.height / 2
const scale = 0.5
const G = 0.1
const vzero = [0, 0]
const vadd = ([a, b], [c, d]) => [a + c, b + d]
const vscale = (a, [b, c]) => [a * b, a * c]
const vsub = (a, b) => vadd(vscale(-1, a), b)
const vmag = ([a, b]) => Math.hypot(a, b)
const vnorm = v => vscale(1 / vmag(v), v)
const vsum = vs => vs.reduce(vadd, vzero)
const objects = [] /*[
{ x: [0.5, 0.25], v: vzero, m: 1 },
{ x: [-0.25, -0.5], v: vzero, m: 0.5 },
{ x: [0.25, 0.75], v: vzero, m: 2 }
]*/
for (let i = 0; i < (4 * Math.PI); i += Math.PI / 12) {
objects.push({ x: [ Math.cos(i), Math.sin(i) ], v: vzero, m: Math.exp(Math.random() - 0.5) })
}
const ctx = canv.getContext("2d")
let previousTimestamp = null
function step(timestamp) {
const previousPreviousTimestamp = previousTimestamp
previousTimestamp = timestamp
if (!timestamp) {
return
}
const timestep = (timestamp - previousPreviousTimestamp) / 1000
ctx.fillStyle = "black"
ctx.fillRect(0, 0, canv.width, canv.height)
var i = 0
for (const object of objects) {
object.x = vadd(object.x, vscale(timestep, object.v))
const F = vsum(objects.filter(x => x !== object).map(x =>
vscale(G * (object.m * x.m) * (vmag(vsub(object.x, x.x)) ** 2), vnorm(vsub(object.x, x.x)))
))
object.v = vadd(object.v, vscale(timestep, vscale(1 / object.m, F)))
//console.log(F, object.x, object.v)
ctx.beginPath()
const disp = vscale(scale, object.x)
ctx.arc(centerX + disp[0] * centerX, centerY + disp[1] * centerY, 4 * Math.cbrt(object.m), 0, 2 * Math.PI, false)
ctx.fillStyle = `hsl(${i * 73}deg, 100%, 60%)`
ctx.fill()
i++
}
info.innerText = "Total E_k is " + objects.map(x => 1/2 * x.m * vmag(x.v) ** 2).reduce((a, b) => a + b).toString()
requestAnimationFrame(step)
}
requestAnimationFrame(step)
</script>

63
steganography.py Normal file
View File

@ -0,0 +1,63 @@
from PIL import Image
import numpy.fft as fft
import numpy as np
import random
import math
with Image.open("/tmp/in.png") as im:
rgb_im = im.convert("RGB")
data = np.asarray(rgb_im, dtype=np.uint8)
out = np.zeros_like(data)
#out2 = np.zeros_like(data)
random.seed(4)
def operate_on_channel(n):
red = data[..., n]
red = fft.fft2(red)
red = fft.fftshift(red)
w, h = red.shape
mask = np.full_like(red, 1)
midx, midy = w // 2, h // 2
print(red.shape)
J = 48
for x in range(midx - J, midx + J + 1):
for y in range(midy - J, midy + J + 1):
mask[x, y] = random.uniform(0.0, 2.0)
"""
for x in range(w):
for y in range(h):
dist = (x - midx) ** 2 + abs(y - midy) ** 2
#if 1024 > dist > 4:
# mask[x, y] = 1
#mask[x, y] = math.sqrt(dist) / 500
if dist < 256: mask[x, y] = 1
"""
"""
for x in range(w):
for y in range(h):
mask[x, y] = random.uniform(0.7, 1)
"""
red = fft.ifftshift(red * mask)
rfft = fft.ifft2(red)
red = np.abs(np.real(rfft))
#red2 = np.abs(np.imag(rfft))
#red = np.log(np.abs(np.real(red)))
#red = np.abs(mask)
red = red * (255 / np.max(red))
#red2 = red2 * (255 / np.max(red2))
out[..., n] = red
#out2[..., n] = red2
for i in range(3):
operate_on_channel(i)
out = Image.fromarray(out, "RGB")
out.save("/tmp/out.png")
#out2 = Image.fromarray(out2, "RGB")
#out2.save("/tmp/out2.png")

472
tictactoe.html Normal file
View File

@ -0,0 +1,472 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tic-Tac-Toe</title>
<style>
.row {
width: fit-content;
height: 4em;
}
.layer {
margin: 1em;
width: fit-content;
border: 1px solid black;
display: inline-block;
}
.cell {
width: 4em;
height: 4em;
display: inline-block;
border: 1px solid gray;
}
.cell-1 {
background: blue;
}
.cell-2 {
background: red;
}
.highlight {
background: yellow;
width: 50%;
height: 50%;
top: 25%;
left: 25%;
position: relative;
}
.view3d .layer {
display: block;
margin-bottom: 0;
margin-top: 0;
transform: rotateX(60deg) rotateZ(-45.8deg);
margin-left: 4em;
}
.view3d .layer + .layer {
margin-top: -4em;
}
.control, .control button, .control select {
border: 1px solid black;
border-radius: 0;
padding: 0.3em;
}
.control select {
transform: translateY(-1px)
}
#info {
font-size: 1.5em;
padding: 1rem;
}
</style>
</head>
<body>
<div id="screen"></div>
<div id="info"></div>
<div id="controls">
<button id="rotate" class="control">Rotate View</button>
<span class="control"><input type="checkbox" name="view3d" id="view3d"><label for="view3d">3D</label></span>
<span class="control"><input type="checkbox" name="lineassist" id="lineassist"><label for="lineassist">Line Assist</label></span>
<span class="control">
<select id="opponent">
<option value="ai1">"AI" v1</option>
<option value="ai2">"AI" v2</option>
<option value="human">Local Human</option>
</select>
Select Opponent
</span>
</div>
<script id="game-logic">
var size = 4
var gsize = size ** 3
var grid = new Uint8Array(gsize)
var range = Array(size).fill(null).map((_, index) => index)
function packCoord([l, r, c]) {
return l + r * size + c * size * size
}
function cartesianProduct(xss) {
var prods = [[]]
for (const xs of xss) {
prods = xs.flatMap(x => prods.map(p => p.concat([x])))
}
return prods
}
function rotateArray(xs, by) {
return xs.slice(by).concat(xs.slice(0, by))
}
function zip(xs, ys) {
return xs.map((x, i) => [x, ys[i]])
}
var inPlaneDiagonals = cartesianProduct([[zip(range, range), zip(range, range.map(x => x).reverse())], range]).map(([diag, a]) => diag.map(([b, c]) => [a, b, c]))
var throughLayerLines = cartesianProduct([range, range]).map(withinLayerPosition => range.map(i => withinLayerPosition.concat([i]))).concat(inPlaneDiagonals)
var winConditions = throughLayerLines.concat(throughLayerLines.map(l => l.map(c => rotateArray(c, 1))), throughLayerLines.map(l => l.map(c => rotateArray(c, 2))))
function insertDiagonalFrom(row, cell) {
var diagonal = []
var dirR = row == 0 ? 1 : -1
var dirC = cell == 0 ? 1 : -1
for (var layer = 0; layer < size; layer++) {
diagonal.push([layer, row, cell])
row += dirR
cell += dirC
}
winConditions.push(diagonal)
}
insertDiagonalFrom(0, 0)
insertDiagonalFrom(0, size - 1)
insertDiagonalFrom(size - 1, 0)
insertDiagonalFrom(size - 1, size - 1)
winConditions = winConditions.map(w => w.map(packCoord))
var lineLookup = Array(gsize).fill(null).map((_, index) => winConditions.map((w, c) => [w, c]).filter(([w, c]) => w.includes(index)).map(x => x[0]))
function containsWin(grid, last) {
outer: for (var winCondition of (last ? lineLookup[last] : winConditions)) {
var fst = grid[winCondition[0]]
for (var i = 1; i < winCondition.length; i++) {
var val = grid[winCondition[i]]
if (val != fst || val == 0) {
continue outer
}
}
return fst
}
}
function unfilledLineLocation(grid, player, last) {
outer: for (var winCondition of (last ? lineLookup[last] : winConditions)) {
var count = 0
var last = null
for (var i = 0; i < winCondition.length; i++) {
if (grid[winCondition[i]] === player) {
count++
} else if (grid[winCondition[i]] == 0) {
last = winCondition[i]
} else {
continue outer
}
}
if (count == size - 1) { return last }
}
}
// heuristic score for minmax - rate position based on difference in uncontested lines
function heuristicScore(grid, player) {
var self = 0
var other = 0
outer: for (var winCondition of winConditions) {
var count = 0
var fst = null
for (var i = 0; i < winCondition.length; i++) {
var val = grid[winCondition[i]]
if (val != 0) {
if (!fst) {
fst = val
}
if (val != fst) {
continue outer
} else {
count++
}
}
}
if (count > 0) {
if (fst === player) {
self += 1 << count
} else {
other += 1 << count
}
}
}
return self - other
}
function possibleMoves(grid) {
var out = []
for (var i = 0; i < gsize; i++) {
if (!grid[i]) {
out.push(i)
}
}
return out
}
function set(grid, cell, val) {
var out = new Uint8Array(grid.length)
out.set(grid)
out[cell] = val
return out
}
function otherPlayer(p) {
return 3 - p
}
function randomPick(xs) {
return xs[Math.floor(xs.length * Math.random())]
}
function hash(ar, seed=0) {
let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed
for (let i = 0, ch; i < ar.length; i++) {
ch = ar[i]
h1 = Math.imul(h1 ^ ch, 2654435761)
h2 = Math.imul(h2 ^ ch, 1597334677)
}
h1 = Math.imul(h1 ^ (h1>>>16), 2246822507) ^ Math.imul(h2 ^ (h2>>>13), 3266489909)
//h2 = Math.imul(h2 ^ (h2>>>16), 2246822507) ^ Math.imul(h1 ^ (h1>>>13), 3266489909)
return /*4294967296 * (2097151 & h2) + */(h1>>>0)
}
function runRandomGame(grid, player) {
var targetPlayer = player
while (true) {
var moves = possibleMoves(grid)
if (moves.length === 0) {
return 0
}
var move = randomPick(moves)
grid = set(grid, move, player)
var winner = containsWin(grid, move)
if (winner === targetPlayer) {
return 1
} else if (winner === otherPlayer(targetPlayer) || unfilledLineLocation(grid, otherPlayer(player), move)) {
return -1
}
player = otherPlayer(player)
}
}
function scoreGrid(grid, player) {
let score = 0
for (let i = 0; i < 128; i++) {
score += runRandomGame(grid, player)
}
return score
}
function brokenMctsPolicy(grid, player) {
// hardcoded limited nonstupidity
var nextLoc = unfilledLineLocation(grid, player)
if (nextLoc != null) { return nextLoc }
nextLoc = unfilledLineLocation(grid, otherPlayer(player))
if (nextLoc != null) { return nextLoc }
var bestscore = -Infinity
var best = null
var moves = possibleMoves(grid)
for (const p of moves) {
var optn = scoreGrid(set(grid, p, player), player)
if (optn > bestscore) {
bestscore = optn
best = p
}
}
return best
}
function minimax(grid, depth, forPlayer, maximizingPlayer, alpha, beta, last=null) {
var winner = containsWin(grid, last)
if (winner) {
return winner === forPlayer ? 100000 : -100000
}
if (depth === 0) {
return heuristicScore(grid, forPlayer)
}
var moves = possibleMoves(grid)
if (moves.length === 0) { // draw
return 99999
}
if (maximizingPlayer) {
var value = -Infinity
for (var move of moves) {
value = Math.max(value, minimax(set(grid, move, forPlayer), depth - 1, forPlayer, false, alpha, beta, move))
if (value >= beta) {
break
}
alpha = Math.max(alpha, value)
}
return value
}
else {
value = Infinity
for (var move of moves) {
value = Math.min(value, minimax(set(grid, move, otherPlayer(forPlayer)), depth - 1, forPlayer, true, alpha, beta, move))
if (value <= alpha) {
break
}
beta = Math.min(beta, value)
}
return value
}
}
function minimaxPolicy(grid, player) {
var best = -Infinity
var optn = null
for (var move of possibleMoves(grid)) {
var r = minimax(set(grid, move, player), 3, player, false, -Infinity, Infinity)
if (r > best) {
optn = move
best = r
}
}
return optn
}
var policies = {
ai1: brokenMctsPolicy,
ai2: minimaxPolicy
}
</script>
<script>
// copyright (2022 CE) © © © osmarks.net hypercomputational tetrational metahexagonal industrial - unsigned integer division
var workerGlue = `
onmessage = event => {
var [policy, ...args] = event.data
postMessage(policies[policy](...args))
}
`
var highlight = new Uint8Array(gsize)
var worker = new Worker(`data:application/javascript;base64,${btoa(document.getElementById("game-logic").innerHTML + workerGlue)}`)
var screen = document.getElementById("screen")
var info = document.getElementById("info")
var rotation = 0
document.getElementById("rotate").onclick = () => {
rotation += 1
rotation %= 3
render()
}
function set3D() {
if (document.getElementById("view3d").checked) {
screen.classList.add("view3d")
} else {
screen.classList.remove("view3d")
}
}
document.getElementById("view3d").onclick = set3D
set3D()
var currentPlayer = 1
var gameOver = false
function render() {
var html = ""
for (var l = 0; l < size; l++) {
html += '<div class="layer">'
for (var r = 0; r < size; r++) {
html += '<div class="row">'
for (var c = 0; c < size; c++) {
var coord = packCoord(rotateArray([l, r, c], rotation))
var hl = ""
if (highlight[coord]) {
hl = `<div class="highlight" style="background: hsl(${highlight[coord] * 20 + 40}deg, 100%, 60%)"></div>`
}
html += `<div class="cell cell-${grid[coord]}" id="cell-${coord}">${hl}</div>`
}
html += '</div>'
}
html += '</div>'
}
screen.innerHTML = html
if (!gameOver) info.innerHTML = `Player ${currentPlayer}'s turn`
}
function reset() {
gameOver = false
grid = new Uint8Array(gsize)
currentPlayer = 1
render()
}
var opponent = document.querySelector("#opponent")
function opponentIsAI() {
return opponent.value.startsWith("ai")
}
function onTurn(move) {
if (gameOver) return true
grid[move] = currentPlayer
currentPlayer = otherPlayer(currentPlayer)
render()
var winner = containsWin(grid)
var isDraw = possibleMoves(grid).length === 0
if (winner != null || isDraw) {
setTimeout(() => {
if (winner) {
info.innerHTML = `${winner} wins! Click to reset.`
} else {
info.innerHTML = "Draw! Click to reset."
}
var el = () => {
reset()
info.removeEventListener("click", el)
}
info.addEventListener("click", el)
gameOver = true
})
return true
}
}
function findTarget(ev) {
var target = ev.target
if (target.classList.contains("highlight")) {
return target.parentNode
} else {
return target
}
}
worker.onmessage = event => {
onTurn(event.data)
}
var holdHighlight = false
screen.onmousemove = event => {
var [start, coord] = findTarget(event).id.split("-")
var coord = parseInt(coord)
if (holdHighlight) {
if (event.shiftKey) {
holdHighlight = !holdHighlight
}
return
}
highlight = new Uint8Array(gsize)
if (!isNaN(coord) && typeof coord == "number" && start == "cell" && document.getElementById("lineassist").checked) {
highlight = new Uint8Array(gsize)
for (var [line, id] of lineLookup[coord].map((x, i) => [x, i])) {
for (var pos of line) {
highlight[pos] = id + 1
}
}
}
if (event.shiftKey) {
holdHighlight = true
}
render()
return
}
screen.onclick = event => {
if (gameOver) return
holdHighlight = false
if (currentPlayer != 1 && opponentIsAI()) { return }
var [start, coord] = findTarget(event).id.split("-")
var coord = parseInt(coord)
if (isNaN(coord) || typeof coord != "number" || start != "cell") { return }
if (grid[coord]) { return }
if (!onTurn(coord) && opponentIsAI()) {
worker.postMessage([opponent.value, grid, currentPlayer])
}
}
render()
</script>
</body>
</html>