This commit is contained in:
lda committed 2026-10-03 03:04:20 +07:00 Verified
commit 51b6dbe5d4
14 files changed
+453

No files matched your search

+10
View File
@@ -0,0 +1,10 @@
# Python-generated files
__pycache__/
*.py[oc]
build/
dist/
wheels/
*.egg-info
# Virtual environments
.venv
+1
View File
@@ -0,0 +1 @@
3.14
View File
Whitespace-only changes.
+17
View File
@@ -0,0 +1,17 @@
[project]
name = "whatcryption"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
authors = [
{ name = "lda", email = "[email protected]" }
]
requires-python = ">=3.14"
dependencies = []
[project.scripts]
whatcryption = "whatcryption:main"
[build-system]
requires = ["uv_build>=0.12.19,<0.13.0"]
build-backend = "uv_build"
+49
View File
@@ -0,0 +1,49 @@
from itertools import islice
from whatcryption.app import App
from whatcryption.pairs.bulls import MORE_bulls
from whatcryption.pairs.index_mapper import index_mapper
from whatcryption.pairs.simple import counter
from whatcryption.thing import thing
def main() -> None:
print("whatcryption")
def app_gen() -> App:
things = [
thing(
mapper=index_mapper([2, 0, 1, 3]),
counter=counter(4, n, c),
)
for n, c in [(1, 0), (2, 1), (3, 1), (0, 2)]
]
return_mapper = MORE_bulls([1, 0, 3, 2])
app = App(
things=things,
return_mapper=return_mapper,
)
return app
app = app_gen()
print(f"{app.things = }")
x = [0, 1, 1, 0, 3, 2, 3, 1, 0, 2, 1, 3, 2, 0, 2, 3, 1, 1, 0, 1, 2]
xi = iter(x)
c = [app.run(next(xi))]
print(f"{app.things = }")
print(f"{c = }")
assert app.things[0].can_propagate_rotation() is True
c = [*c, app.run(next(xi))]
assert app.things[0].can_propagate_rotation() is False
assert app.things[1].can_propagate_rotation() is True
print(f"{app.things = }")
c = [*c, *(app.run(i) for i in islice(xi, 3))]
print(f"{app.things = }")
c = [*c, *(app.run(i) for i in xi)]
app2 = app_gen()
c2 = [app2.run(i) for i in c]
assert c2 == x, f"c2 = {c2}, x = {x}"
+56
View File
@@ -0,0 +1,56 @@
from whatcryption.pairs.bulls import MORE_bulls, bulls
from whatcryption.thing import thing
class App:
def __init__(
self,
things: list[thing],
return_mapper: MORE_bulls,
opt_mapper: bulls | None = None,
):
superverify(return_mapper, things, opt_mapper)
self.opt_mapper: bulls | None = opt_mapper
self.things: list[thing] = things
self.return_mapper: MORE_bulls = return_mapper
def __repr__(self) -> str:
return f"App(things={self.things}, return_mapper={self.return_mapper}, opt_mapper={self.opt_mapper})"
def run(self, i: int) -> int:
if self.opt_mapper:
i = self.opt_mapper.forward(i)
for this in self.things:
i = this.forward(i)
i = self.return_mapper.forward(i)
for this in reversed(self.things):
# it feels like you put something in the stack then pop it...
i = this.backward(i)
propagate_rotation = True
for this in self.things: # then IDFK what this shit is
this.rotate_if_(propagate_rotation)
propagate_rotation = propagate_rotation and this.can_propagate_rotation()
if self.opt_mapper:
i = self.opt_mapper.backward(i)
return i
def superverify(
return_mapper: MORE_bulls, things: list[thing], opt_mapper: bulls | None
):
"on super g"
if not return_mapper:
raise ValueError("return_mapper must not be None")
if not things:
raise ValueError("things must not be empty")
if opt_mapper is not None and not isinstance(opt_mapper, bulls):
raise ValueError("opt_mapper must be a bulls instance or None")
if not all(len(this) == len(return_mapper) for this in things):
raise ValueError(
"All things must have the same length, and the same length as return_mapper"
)
if opt_mapper is not None and len(opt_mapper) != len(return_mapper):
raise ValueError("opt_mapper must have the same length as return_mapper")
+62
View File
@@ -0,0 +1,62 @@
from whatcryption.pairs.bulls import bulls
int2str = "abcdefghijklmnopqrstuvwxyz"
str2int = {c: i for i, c in enumerate(int2str)}
def swaps_to_(swaps: list[tuple[int, int]], l: int) -> list[int]:
"""
Convert a list of swaps to a permutation of range(l).
Arguments:
swaps (list[tuple[int, int]]): a list of swaps
l (int): the length of the permutation
Returns:
list[int]: a permutation of range(l)
"""
p = list(range(l))
for a, b in swaps:
p[a], p[b] = p[b], p[a]
return p
def verify_swap_list(swaps: list[tuple[int, int]]):
"""
Verify that a list of swaps is valid.
Arguments:
swaps (list[tuple[int, int]]): a list of swaps
Raises:
ValueError: if there is (a, b) but also (b, c) in the list.
"""
seen = set()
for i, (a, b) in enumerate(swaps):
if a in seen or b in seen:
raise ValueError(
f"Invalid swap list: {swaps} at index {i}, at pair ({a}, {b}); either number has already been swapped in a previous pair."
)
seen.add(a)
seen.add(b)
def swaps_to_BULLS(swaps: list[tuple[int, int]], l: int, cls: type[bulls]) -> list[int]:
"""
Convert a list of swaps to a BULLS permutation of range(l).
since its bullshit.
Arguments:
swaps (list[tuple[int, int]]): a list of swaps
l (int): the length of the permutation
cls (type[bulls]): the class of BULLS to use for verification
Returns:
list[int]: a BULLS permutation of range(l)
"""
if not issubclass(cls, bulls):
raise TypeError(f"cls must be a subclass of bulls, got {cls}")
verify_swap_list(swaps)
p = swaps_to_(swaps, l)
cls.verify(p)
return p
+63
View File
@@ -0,0 +1,63 @@
"some bullshit"
from .index_mapper import index_mapper
class bulls(index_mapper):
"""forward(x) = backward(x) = i[x]. i[i[x]] = x"""
@staticmethod
def verify(i: list[int]):
super(bulls, bulls).verify(i)
for id, x in enumerate(i):
if i[x] != id:
raise ValueError(
f"bulls: i[i[x]] != x, i[i[{x}]] = i[{i[x]}] = {id} != {x}"
)
class MORE_bulls(bulls):
@staticmethod
def verify(i: list[int]):
super(MORE_bulls, MORE_bulls).verify(i)
for id, x in enumerate(i):
if id == x:
raise ValueError(
f"MORE_bulls: i[x] should not equal x, but i[{x}] == {id}"
)
if __name__ == "__main__":
# test bulls
i = [2, 1, 0, 4, 3]
m = bulls(i)
for x in range(len(i)):
assert m.forward(x) == i[x]
assert m.backward(x) == i[x], "this"
try:
i = [3, 1, 0, 2]
m = bulls(i)
except ValueError as e:
print(f"caught expected exception: {e}")
# because i[0] = 3, but i[3] = 2 != 0
# test MORE_bulls
i = [2, 3, 0, 1]
m = MORE_bulls(i)
for x in range(len(i)):
assert m.forward(x) == i[x]
assert m.backward(x) == i[x]
try:
i = [3, 1, 4, 0, 2]
m = MORE_bulls(i)
except ValueError as e:
print(f"caught expected exception: {e}")
# because i[1] = 1.
try:
i = [3, 1, 0, 2]
m = MORE_bulls(i)
except ValueError as e:
print(f"caught expected exception: {e}")
# inheritance
+67
View File
@@ -0,0 +1,67 @@
"""
thing <-> index
thing2 <-> index2
index <-> index2
thing <-> index <-> index2 <-> thing2
"""
class index_mapper:
def __init__(self, i: list[int]):
"""
Arguments:
i (list[int]): a permutation of range(len(i))
"""
self.verify(i)
self._i = [*i]
self._r = {v: k for k, v in enumerate(i)}
self._l = len(i)
def __repr__(self) -> str:
return f"index_mapper(i={self._i})"
def __len__(self) -> int:
return self._l
def forward(self, x: int) -> int:
return self._i[x % self._l]
def backward(self, x: int) -> int:
return self._r[x % self._l]
@staticmethod
def verify(i: list[int]):
if not i:
raise ValueError("index_mapper: i must not be empty")
if set(i) != set(range(len(i))): # this also clears uniqueness
raise ValueError("index_mapper: i must be a permutation of range(len(i))")
if __name__ == "__main__":
# test index_mapper
i = [4, 2, 0, 1, 3]
m = index_mapper(i)
for x in range(len(i)):
assert m.forward(x) == i[x]
assert m.backward(i[x]) == x
# usage example
i = [4, 2, 0, 1, 3]
m = index_mapper(i)
l = len(i)
def _r(o):
print(f"offset = {o}")
for x in range(l):
s = x + o
f = m.forward(s % l)
print(f"forward({x + o} % {l} = {s % l}) = {f}")
b = m.backward(f)
print(f"backward({f}) = {b}")
_r(2)
_r(3)
+30
View File
@@ -0,0 +1,30 @@
class counter:
def __init__(self, l: int, n: int, c: int):
self.l = l
self.n = n % l
self.init(c)
def __len__(self) -> int:
return self.l
def __repr__(self) -> str:
return f"counter(l={self.l}, n={self.n}, c={self.c})"
def init(self, c: int):
self.c = c % self.l
def forward(self, x: int) -> int:
return (x + self.c) % self.l
def backward(self, x: int) -> int:
return (x - self.c) % self.l
def can_propagate_rotation(self) -> bool:
return self.c == self.n
def rotate(self, by: int = 1):
self.init(self.c + by)
def rotate_if_(self, can_rotate: bool):
if can_rotate:
self.rotate()
+34
View File
@@ -0,0 +1,34 @@
from whatcryption.pairs.index_mapper import index_mapper
from whatcryption.pairs.simple import counter
class thing:
"dont switch up the attributes, dont use them after passed. make a new instance"
def __init__(self, mapper: index_mapper, counter: counter) -> None:
if len(mapper) != counter.l:
raise ValueError(
f"thing: mapper length {len(mapper)} must match counter length {counter.l}"
)
self.mapper = mapper
self.counter = counter
def forward(self, x: int) -> int:
x = self.counter.forward(x)
return self.mapper.forward(x)
def backward(self, x: int) -> int:
x = self.mapper.backward(x)
return self.counter.backward(x)
def rotate_if_(self, can_rotate: bool):
self.counter.rotate_if_(can_rotate)
def can_propagate_rotation(self) -> bool:
return self.counter.can_propagate_rotation()
def __len__(self) -> int:
return len(self.mapper)
def __repr__(self) -> str:
return f"thing(mapper={self.mapper}, counter={self.counter})"
+9
View File
@@ -0,0 +1,9 @@
from typing import Protocol
class twowayable(Protocol):
def forward(self, x: int) -> int:
raise NotImplementedError
def backward(self, x: int) -> int:
raise NotImplementedError
+47
View File
@@ -0,0 +1,47 @@
# thats why elixir is THE language
from collections.abc import Callable, Sequence
def ouoe[T](*c: Callable[[T], T]) -> Callable[[T], T]:
"pipe"
def f(x: T) -> T:
for c_ in c:
x = c_(x)
return x
return f
def LOL[F, T](
e: Callable[[F], Callable[[T], T]],
o: Callable[[F], Callable[[T], T]],
f: Sequence[F],
m: Callable[[T], T],
):
"""
for each object in f, apply e(object) to the input, then apply m to the result, then apply o(object) in reverse order to the result of m
"""
def x(q: T) -> T:
for i in f:
q = e(i)(q)
m(q)
for i in reversed(f):
q = o(i)(q)
return q
return x
if __name__ == "__main__":
def f(x: int) -> int:
return x + 1
def g(x: int) -> int:
return x * 2
h = ouoe(f, g)
print(h(3)) # Output: 8
Generated
+8
View File
@@ -0,0 +1,8 @@
version = 1
revision = 3
requires-python = ">=3.14"
[[package]]
name = "whatcryption"
version = "0.1.0"
source = { editable = "." }