Caleb Fangmeier 4 anni fa
parent
commit
b83bc0ad81

+ 8 - 0
.idea/.gitignore

@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
+# Editor-based HTTP Client requests
+/httpRequests/

+ 8 - 0
.idea/538-riddler.iml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="PYTHON_MODULE" version="4">
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$" />
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>

+ 13 - 0
.idea/inspectionProfiles/Project_Default.xml

@@ -0,0 +1,13 @@
+<component name="InspectionProjectProfileManager">
+  <profile version="1.0">
+    <option name="myName" value="Project Default" />
+    <inspection_tool class="PyMethodMayBeStaticInspection" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
+    <inspection_tool class="PyPep8Inspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
+      <option name="ignoredErrors">
+        <list>
+          <option value="E402" />
+        </list>
+      </option>
+    </inspection_tool>
+  </profile>
+</component>

+ 6 - 0
.idea/inspectionProfiles/profiles_settings.xml

@@ -0,0 +1,6 @@
+<component name="InspectionProjectProfileManager">
+  <settings>
+    <option name="USE_PROJECT_PROFILE" value="false" />
+    <version value="1.0" />
+  </settings>
+</component>

+ 7 - 0
.idea/misc.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="JavaScriptSettings">
+    <option name="languageLevel" value="ES6" />
+  </component>
+  <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8" project-jdk-type="Python SDK" />
+</project>

+ 8 - 0
.idea/modules.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/538-riddler.iml" filepath="$PROJECT_DIR$/.idea/538-riddler.iml" />
+    </modules>
+  </component>
+</project>

+ 6 - 0
.idea/other.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="PySciProjectComponent">
+    <option name="PY_SCI_VIEW_SUGGESTED" value="true" />
+  </component>
+</project>

+ 6 - 0
.idea/vcs.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+  </component>
+</project>

+ 119 - 0
2020_07_24/main.py

@@ -0,0 +1,119 @@
+from dataclasses import dataclass
+from math import pi, tan, atan2, sqrt
+
+import numpy as np
+import matplotlib.pyplot as plt
+
+@dataclass
+class Line:
+    x: float
+    y: float
+    angle: float
+
+    def __repr__(self):
+        return f"Line(x={self.x}, y={self.y}, angle={self.angle*180/pi})"
+
+
+def bounce_wall(line):
+    if line.angle > pi:
+        raise ValueError
+    intercept_x = line.x - line.y / tan(line.angle)
+    angle = -line.angle + 2*pi
+    return Line(x=intercept_x, y=0, angle=angle)
+
+
+def bounce_circle(line):
+    x0 = line.x
+    t = tan(line.angle)
+    t2 = t*t
+
+    a = 1 + t2
+    b = 4*t - 2*t2*x0
+    c = t2*x0*x0 - 4*x0*t + 3
+
+    rad = b*b - 4*a*c
+    if rad < 0:
+        raise ValueError
+
+    x1 = (-b + sqrt(rad)) / (2*a)
+    y1 = (x1 - x0)*t
+
+    x2 = (-b - sqrt(rad)) / (2*a)
+    y2 = (x2 - x0)*t
+
+    x, y = (x1, y1) if y1 > y2 else (x2, y2)
+
+    t_tan = (atan2(y+2, x) - pi/2) % (2*pi)
+    angle = (line.angle + 2*(t_tan - line.angle)) % (2*pi)
+    return Line(x=x, y=y, angle=angle)
+
+
+def do_bounces(angle_deg, x=None):
+    if x is not None:
+        angle_deg = np.arctan2(2, x + 2) * 180 / pi
+    lines = [Line(-2, -2, angle_deg*pi/180)]
+    try:
+        while True:
+            lines.append(bounce_wall(lines[-1]))
+            lines.append(bounce_circle(lines[-1]))
+    except ValueError:
+        pass
+    return len(lines)-1, lines
+
+
+def draw_bounces(lines):
+    xs = [line.x for line in lines]
+    ys = [line.y for line in lines]
+    plt.plot([-4, 4], [0, 0])
+    plt.plot(xs, ys)
+    plt.gca().add_patch(plt.Circle((0, -2), radius=1))
+
+    plt.xlim((-1, 1))
+    plt.ylim((-1.8, 0.2))
+
+    plt.show()
+
+
+def count_range(start, end, count=100):
+    xs = np.linspace(start, end, count)
+    angles = np.arctan2(2, xs + 2) * 180 / pi
+    bounces = []
+
+    for angle in angles:
+        count, _ = do_bounces(angle)
+        bounces.append(count)
+
+    plt.plot(xs, bounces)
+    plt.show()
+    return xs, np.array(bounces)
+
+
+def iterative_zoom(start, end, n_iter):
+
+    maxes = []
+    for _ in range(n_iter):
+        xs, bounces = count_range(start, end, 1000)
+        max_x = xs[np.argmax(bounces)]
+        maxes.append(max_x)
+        range_ = end - start
+        start = max_x - 0.05*range_
+        end = max_x + 0.05*range_
+    print(maxes)
+    plt.plot(maxes)
+    plt.show()
+
+
+def main():
+
+    # count_range(-2, 0, 10000)
+    # count_range(-0.824, -0.822, 10000)
+    # count_range(-0.8225, -0.8223, 10000)
+    # count_range(58, 62)
+    # count_range(59, 60)
+    # count_range(59.51, 59.515)
+    # draw_bounces(do_bounces(None, x=-0.8224863249433897)[1])
+    iterative_zoom(-2, 0, 20)
+
+
+if __name__ == '__main__':
+    main()

+ 40 - 0
2020_08_01/main.py

@@ -0,0 +1,40 @@
+import numpy as np
+
+
+def fill_and_mark(t, stud, pos):
+    t[:, pos] = 'x'
+    t[stud, :] = 'x'
+    ys, xs = np.diag_indices_from(t)
+    xs = (xs + pos) % len(t)
+    ys = (ys + stud) % len(t)
+    t[ys, xs] = 'x'
+    t[stud, pos] = 'o'
+
+
+def main():
+    n = 9
+
+    t_init = np.full((n, n), ' ', dtype=str)
+    fill_and_mark(t_init, 0, 0)
+
+    sols = []
+    stack = [(t_init, 1)]
+    while stack:
+        t, curr_stud = stack.pop()
+
+        if curr_stud == n:
+            sols.append(t)
+            continue
+
+        for pos in np.argwhere(t[curr_stud] == ' '):
+            t_new = t.copy()
+            fill_and_mark(t_new, curr_stud, pos)
+            stack.append((t_new, curr_stud+1))
+
+    print('number of solutions: ', len(sols))
+    for solution in sols:
+        print(solution)
+
+
+if __name__ == "__main__":
+    main()

+ 95 - 0
2020_08_08/main.py

@@ -0,0 +1,95 @@
+from fractions import Fraction as F
+from collections import defaultdict
+from itertools import product
+from math import factorial
+
+
+class NematodeNumber:
+
+    P = F(1, 2)
+
+    def __init__(self, n):
+        if isinstance(n, int):
+            self._val = defaultdict(lambda: F(0))
+            self._val[n] = F(1)
+        else:
+            self._val = n
+
+    @classmethod
+    def _breed(cls, n):
+
+        def binom(n, k):
+            n_choose_k = factorial(n) // (factorial(k) * factorial(n - k))
+            return n_choose_k * cls.P**k * (1 - cls.P)**(n - k)
+
+        leftover, pairs = n % 2, n // 2
+        result = defaultdict(lambda: F(0))
+        for n_bab in range(pairs + 1):
+            prob = binom(pairs, n_bab)
+            result[pairs*2 + n_bab + leftover] = prob
+        return result
+
+    def __add__(self, other):
+        left = self._val
+        right = other._val
+        result = defaultdict(lambda: F(0))
+        for (l, lp), (r, rp) in product(left.items(), right.items()):
+            for b, bp in self._breed(l+r).items():
+                result[b] += lp*rp*bp
+        return NematodeNumber(result)
+
+    def __pow__(self, exponent):
+        base = self._val
+        for _ in range(exponent):
+            next_ = defaultdict(lambda: F(0))
+            for n, np in base.items():
+                for b, bp in self._breed(n).items():
+                    next_[b] += np*bp
+            base = next_
+        return NematodeNumber(base)
+
+    def __repr__(self):
+        return repr(self._val)
+
+    def expectation_value(self):
+        return sum(val*prob for (val, prob) in self._val.items())
+
+def limit():
+    one = NematodeNumber(1)
+    base_result = one + one
+    for i in range(1, 30):
+        res = base_result ** i
+        print(f"{i: 3}: {res.expectation_value()}")
+    """
+      1: 3.0
+      2: 3.625
+      3: 4.40625
+      4: 5.3828125 -> 5 49/128
+      5: 6.603515625
+      6: 8.12939453125
+      7: 10.0367431640625
+      8: 12.420928955078125
+      9: 15.401161193847656
+     10: 19.12645149230957
+     11: 23.783064365386963
+     12: 29.603830456733704
+     13: 36.87978807091713
+     14: 45.97473508864641
+     15: 57.343418860808015
+     16: 71.55427357601002
+     17: 89.31784197001252
+    """
+
+
+def main():
+    # r1 = add({2: F(1)}, {2: F(1)})
+    # print(r1)
+    # r2 = add(r1, r1)
+    # print(r2)
+    # print(exp({2: F(1)}, 2))
+    # val = exp(add({1: F(1)}, {1: F(1)}), 4)
+    limit()
+    # print(float(expectation_value(val)))
+
+if __name__ == "__main__":
+    main()

+ 6 - 0
requirements.txt

@@ -0,0 +1,6 @@
+ipython
+numpy
+matplotlib
+matplotboard
+jupyter
+jupyter-book