2,653 karma · joined September 22, 2013
andrew at $DOMAIN
(-t 32 -ngl 100 -c 8192 -fa -ctk q8_0 -ctv q8_0 -m models/gemma-3-27b-it-qat-q4_0.gguf)
> On the way to an Inklings meeting, he gave some money to a street beggar, and I made the usual objection: "Won't he just spend it on drink?"
> Lewis answered, "Yes, but if I kept it, so would I."
https://web.archive.org/web/20210717220213/https://www.ncron...
> [1] That is, three windows of the same size side-by-side.
`C-x +` (M-x balance-windows) for those who don't know . There's also M-x balance-windows-area.
* Implementation/header pairs in C++
* Language REPLs (e.g., Python)
* Quick calculations in Calc while coding
* Checking dates on the calendar
* Magit status
* Diff buffers (especially diff-buffer-with-file)
* Listing neighboring files with dired
* Notes on a code base/task in an Org mode file import z3
res = [("bbababbabb", 7), ("baaababaaa", 5), ("baaabbbaba", 3), ("bbaaabbaaa", z3.Int("x"))]
key = [z3.Int(f"k{i}") for i in range(10)]
z = z3.Solver()
z.add([z3.Sum([ord(a) == k for a, k in zip(r[0], key)]) == r[1] for r in res])
z.check()
print(z.model()[res[-1][1]])In other words, decompose the problem into one of finding where the ray crosses the X grid lines and the Y grid lines, and the mental image is:
+-------+-------+-------+ | | | | -------------------------
| | | ^ | | | | ^ | ^
| | | / | | | | / | /
| | | / | | | | / | /
+-------+-------+-*-----+ | | | / | ------------------*------
| | |/ | | | |/ | /
| | * | | | * | /
| | /| | | | /| | /
+-------+-----*-+-------+ = | | / | | U --------------*----------
| | / | | | | / | | /
| | / | | | | / | | /
| | / | | | | / | | /
+-------+-*-----+-------+ | | / | | ----------*--------------
| |/ | | | |/ | | /
| * | | | * | | /
| o| | | | o| | | o
+-------+-------+-------+ | | | | -------------------------
Now, if our ray has origin o, and direction d, the position of any point along the ray for a t-value is: x' = o.x + t * d.x
y' = o.y + t * d.y.
Where's the first grid intersection in X? Assuming d.x is positive, it'll be at ceil(o.x). So solve for t: ceil(o.x) = x' = o.x + t * d.x
t = (ceil(o.x) - o.x) / d.x.
Then, since the grid lines are spaced 1 unit apart, every subsequent intersection will be 1/d.x further along in t. In other words, the ray t-values of all the grid crossing in X are stream generated by a simple linear function: ((ceil(o.x) - o.x)/d.x) + step * 1/d.x.
And exactly the same thing applies in Y for the Y grid crossings.So let's say that we have a ray with origin (0.8, 0.2) and a direction of (0.5, 0.25). Then we get:
X-crossings = [0.4, 2.4, 4.4, 6.4, 8.4, 10.4, ...]
Y-crossings = [3.2, 7.2, 11.2, 15.2, ...]
Then we merge those two infinite ordered streams: [0.4, 2.4, 3.2, 4.4, 6.4, 7.2, 8.4, 10.4, 11.2, ...]
X X Y X X Y X X Y ...
and those are the t-values where we walk from one cell to another. Keeping track of which value came from which stream tells us whether the step is in X or in Y (it's always one or the other - a DDA never takes a diagonal step). Continue lazily generating and merging the stream this way until you run into something, run out of bounds, or just decide you've gone far enough to stop.Obviously, there's some fiddliness when the direction has negative components or worse, zero, but it's not to hard to work out the adjustments for those cases. Likewise, you also want to be very careful about handling the case where the ray origin is exactly on a cell boundary. But again, focusing on just one dimension at a time helps when reasoning all that out.
Generalizing the concept to a DDA in 3D on a voxel grid isn't much harder, either: now you find the stream of Z-crossings as well and do a 3-way merge.
(If you ever want to vectorize grid traversal across multiple rays, there are some tricks to that in a 2006 SIGGRAPH paper that I worked on: https://www.sci.utah.edu/~wald/Publications/2006/CGT/grid.pd...)
- "Please" = Call to action for the model to perform a task that I either just described or am about to describe within this prompt. In other words, this conversational turn is not just about feeding more context to it, but I've given it everything I think it needs and it should go ahead and start.
- "Thank you" = I am satisfied with the results that it provided for that task and want to move on to something else now, where the new thing is contextually related to the recent task. (If I wanted an entirely unrelated task, I'd just start a new conversation with a fresh context.)
Before that, I tended to write Python in a much more imperative style, since C++ is my main language; think for loops and appending to lists. Thanks to AoC, I'm now addicted to comprehensions for transforming and filtering, know the standard library cold, and write much more concise, Pythonic code.
A copy of the original paper can be found here and is nice and easy to read, with pseudocode: https://web.archive.org/web/20190223095317id_/http://pdfs.se...
Alternatively for the non-random and arbitrary N case here, an approach based on Phyllotaxis that samples a Fermat spiral every ~137.508 degrees (i.e., the golden angle, or the golden ratio fraction of a circle) also works pretty well: https://en.wikipedia.org/wiki/Fermat%27s_spiral#The_golden_r.... It works nicely for any N, even if the N isn't square or close to square (just choose the scaling appropriately, e.g., c = 1/sqrt(N)).
You've clearly taken things waaay farther. Nicely done.
Has anyone used both and could compare them?
> Sci-Fi Author: In my book I invented the Torment Nexus as a cautionary tale
> Tech Company: At long last, we have created the Torment Nexus from classic sci-fi novel Don't Create The Torment Nexus
- I can get a good idea of the temporal behavior of the program, and I can just scroll up to see earlier state, rather than having to restart the program in the debugger. (I know that "time travel" debuggers exist, but I've found them finicky.) I can scrub back and forth through time just by scrolling.
- I can compare runs by diffing the logs. Sometimes that alone is enough to show where things start going amiss. Or I can keep instrumented logs from baseline runs.
- If there's a personally useful set of printf statements in an area that I'm in a lot, I can save those off to a patch file or a local branch. I don't have to reapply my breakpoints / watchpoints in the debugger each time. Easy persistence.
(That said, I do like to start with a debugger when tackling reproducible crashes.)
First I've heard of this. As a long-time vanilla Emacs user, I'm using consult-ripgrep and rg-project for ripgrep interfaces, consult-buffer for fast buffer and file switching, Eglot for LSP integration (mainly with clangd), etc. I've also got org-mode for note taking, magit for speedy Git manipulation, etc.
And all without any visible menus or clutter.
I suspect that a power Emacs user and a power Neovim user are more akin here to each other than to VS Code users.
Fairly recently, I was calling one who was napping to let her know I was about to dispense them. She woke up, lifted her head, perked her ears and watched me when I called her name. She was clearly paying attention but not moving from her spot. Then I said the magic word and the reaction was startlingly immediate - she leapt up and ran right to me, then followed until I got them out and poured some out.