The local feed (icon of two people) is content from everyone with an "@qoto.org" account, and a good general purpose place to find new things. The home feed (icon of a house) is content from people you follow, so a better representation of your interests but you won't find as much novelty here. The federated feed (icon of a globe) is the combination of everyone followed by anyone with a "@qoto.org" account, so it's got the most variety but is like trying to drink from a fire hose.
>While you are obviously free to ignore a POLITICS.txt it's pretty obvious it's a rather short sighted decision, at least from a professional perspective.
The problem is that this *isn't* obvious. The various other files you commonly see - LICENCE.txt, CHANGELOG.txt, CONTRIBUTING.txt, etc. - are relevant to specific audiences, and the rest of the world can safely ignore them. It isn't at all obvious until I've read it whether I can ignore POLITICS.txt (in fact, the first time I read it, I was expecting it to contain warnings about exporting cryptography). That's why I think the introduction should detail who's expected to be familiar with its content.
> For example you might build your software upon a library specifically designed to be broken, just to put shame on developers who don't give a shit about politics!
Only insofar as that's true of *any* documentation. You could equally put your warning in a document called RELIGION.txt to spite developers who don't care about that instead.
> The fact is that when you decide to depend on my work, you decide to depend on my goals. Writing down my political goals I let you know what to expect.
Traditionally, developers let people know what to expect by maintaining a roadmap for the project.
It's quite a bit clearer now! Cutting out the snarky jabs at people who "pretend technology exists or has ever existed separate from the natural tendency for human agents to consolidate power" and "[mere] vague principles that corporate entities routinely ignore" has helped a lot. You could probably go even further with this, cutting everything before "This document outlines...".
On the other hand, I still don't understand the target audience. It would be nice if fairly early on you say, "This document is required reading for contributors; users can skip it," or whatever is appropriate to your vision for who reads it.
Answer
@jeffcliff@niu.moe
It's a substitution cipher encoding coordinates for a point outside Saskatoon (52.069N, 106.3892W).
It literally turns out to be
"north five two zero six nine zero zero west one zero six three eight nine two zero" and I just guessed at the decimal separators. But the longitude has an extra digit, which implies it ought to be (0.5N, 1.0W), (5.2N, 10.6W), or (52N, 106W), and the other points are over water. If you ignore the precision, you can also derive points in Ghana and the British Isles.
Since this isn't nearly as established a convention as some other forms of repo boilerplate, you probably want to briefly describe when I must read this document. For example, I should read a Code of Conduct before interacting with others in your project space, the licence before distributing your code, etc.
I got through your introductory paragraph and thought, "Why do your politics matter to me?" As a user I care about how the software helps me reach my goals, not yours.
@mngrif I think I was one notch up from "zero notifications." I may see if I can't fix tusky and just submit a patch for the post-length thing. In all other respects I think I prefer it.
@mngrif I tried fedilab again after your comments but it still munches battery - even the lite version is eating as much as the screen itself. So I'm back on tusky, plus the web client for anything that blows the 500 char limit.
Octave solution & discussion
Pretty straightforward. Might be possible to improve on the factorial one by counting factors, because computers can generally calculate x^n faster than just multiplying it out, so if you figure out that the answer would be 2^a * 3^b * 5^c... it could outpace the naive 1 * 2 * 3 * ... * n method.
That said, I tried such an approach and while it does scale better than linear, the upfront cost is high enough that the breakeven point is way past anything my computer can represent in floating point. So for practical use, this is what I'd put forward.
function term = fibonacci(index)
root = sqrt(5);
term = (((1 + root)/2).^index - ((1 - root)/2).^index) ./ root; end;
function number = factorial(argument)
number = ones(size(argument));
for factor = 1:max(argument)
number(argument >= factor) *= factor; end; end;
Here's a #toyprogrammingchallenge requiring a bit of algebra.
For any four non-collinear points A, B, C, and D in three-dimensional space, there is a unique hyperbolic paraboloid H containing the lines AB, BC, CD, and AD (that is, every point on any of these lines is also on the surface of H). Write a program that accepts Cartesian coordinate triplets representing A, B, C, and D and prints an equation in x, y, and z that is satisfied if and only if <x, y, z> is a point on H.
Your program's output may differ from the examples but should be optimised for human readability. Combine like terms, omit terms equal to zero and avoid unnecessary factors (e.g. prefer "x = y" to "2x + 0 = 4y - 2y" even though both describe the same surface).
Example 1 input:
<0, 1, -1>; <1, 0, 1>; <0, -1, -1>; <-1, 0, 1>
Example 1 output:
z = x² - y²
Example 2 input:
<1, 1, 1>; <1, 0, -1>; <-1, 1, -1>; <-1, 0, 1>
Example 2 output:
2y = xz + 1
Example 3 input:
<0, 1, 1>; <0, 1, -1>; <0, -1, -1>; <0, -1, 1>
Example 3 output:
x = 0
@freemo So I can clear my notifications all at once. But I can't figure out how to dismiss a given notification (for example, the notification that you replied to me) without clearing all the rest. Going by the documentation here[1] it seems like it should be possible.
1: https://docs.joinmastodon.org/api/rest/notifications/#post-api-v1-notifications-dismiss
I see in Mastodon's API there is a call to dismiss a specific notification. Is there a way to do this from the web frontend?
I see things like this all over the place, is there something else you meant?
Octave solution
This was super straightforward. Linear in time and space, plus whatever the sort algorithm needs (by default it's nlogn in Octave but you can implement other ones).
function room_count = min_rooms(class_times)
[~, indices] = sort(class_times'(1:numel(class_times)));
current = 0;
room_count = 0;
for index = indices
if mod(index, 2)
current++;
room_count = max(room_count, current);
else
current--; end; end; end;
Invoking the Octave solution
Call with two arguments, both mandatory: a string to justify and a linewidth to justify to. Returns a 2D array of chars. Where it can, the words touch both sides simultaneously. Sometimes it's not possible to fit more than one word on a line, in which case it is left justified, padded with spaces.
> justify_text('I walked until midnight in the storm, then I went home and took a sauna for an hour and a half. It was all clear. I listened to my heart and saw if there were any signs of my destiny in the sky, and there were none - there were just snowflakes.', 16)
ans =
I walked until
midnight in the
storm, then I
went home and
took a sauna for
an hour and a
half. It was all
clear. I
listened to my
heart and saw if
there were any
signs of my
destiny in the
sky, and there
were none -
there were just
snowflakes.
Octave solution
Matlab normally represents strings as 1D arrays of chars. It's not usual to put chars in an 2D array because all the rows would have to be the same length, and that's pretty inflexible. Octave is happy to make such an array just as it would with any other type, though, and here that's exactly what we want.
function array = justify_text(string, width)
words = strtrunc(strsplit(string), width);
array = zeros(0, width);
line_length = 0;
start_index = 1;
for word_index = 1:numel(words)
this_word = words{word_index};
if line_length + numel(this_word) > width
array = [array; render_words(start_index, word_index - 1)];
start_index = word_index;
line_length = numel(this_word) + 1;
else
line_length += numel(this_word) + 1; end; end;
array = [array; render_words(start_index, numel(words))];
function this_line = render_words(start_index, end_index)
chars_raw = cellfun(@numel, words(start_index:end_index));
total_padding = width - sum(chars_raw);
if start_index == end_index
this_line = [words{start_index} repmat(' ', 1, total_padding)];
else
base_padding = floor(total_padding / (end_index - start_index));
extra_padding = rem(total_padding, end_index - start_index);
next_char = 1;
for index = start_index:end_index
this_padding = 0;
if index < end_index
this_padding = base_padding;
if index - start_index < extra_padding
this_padding++; end; end;
this_line(next_char:(next_char + chars_raw(index - start_index + 1) - 1)) = words{index};
next_char += chars_raw(index - start_index + 1);
this_line(next_char:(next_char + this_padding - 1)) = repmat(' ', 1, this_padding);
next_char += this_padding; end; end; end; end;
Octave solution
Should be fairly easy to modify for other bracket types, just add them to the lists at the top and bottom (using the same index for an open bracket and its corresponding close bracket).
function valid = is_balanced(string)
open_brackets = '({[';
close_brackets = ')}]';
expecting = false(size(string));
valid = true;
expected_bracket = [];
for index = 1:numel(string)
if ismember(string(index), open_brackets)
expecting(index) = true;
expected_bracket = strchr(open_brackets, string(index));
elseif ismember(string(index), close_brackets)
if expected_bracket == strchr(close_brackets, string(index))
expecting(find(expecting, 1, 'last')) = false;
expected_bracket = strchr(open_brackets, string(find(expecting, 1, 'last')));
else
valid = false; end; end; end;
if any(expecting)
valid = false; end; end;
Why did you choose to specify the language for this one? For the freebies that's not so much of an issue but this is the sort of problem that is kind of a pain if you're working in a language where you're not familiar with its features.
Think of edges in a directed graph as arrows, which you can follow in the direction they point but not in the opposite direction. The edge <1, 2, 40> allows you to go *from* node 1 *to* node 2, while <2, 1, 84> allows you to go *to* node 1 *from* node 2. So if you exclude the edge you suggested, the graph no longer satisfies the third condition (k-hop rule) because it's no longer possible to get from node 4 to node 1 in two hops (shortest path is 4->2->3->1, which is three hops).
Electoral math, CW for length (3108 characters hidden)
Canada just had a parliamentary election yesterday. Seat breakdown is as follows, per the CBC:
Liberal 157
Conservative 121
Bloc Quebecois 32
New Democrat 24
Green 3
Independent 1
There will almost certainly be a minority government, led by the centre-left Liberals and supported by one or more of the further-left Bloc, NDP, and Greens.
The Liberal party achieved this result despite winning zero seats in the less populous western provinces outside of the Vancouver and Winnipeg metropolitan areas, and I'm starting to see people repeat the claim that a US-style electoral college would stop city voters from "ruling over" rural voters. I'm skeptical of this argument when Americans cite it as a Divine wisdom encapsulated in the Constitution, so I got the preliminary data from Elections Canada and simulated an electoral college.
First, I supposed each province and territory had a number of electors equal to the number of seats it currently gets in the House of Commons, and awarded all its electors to the winner of the popular vote within its boundaries (the Liberals came away with NL, PE, NS, NB, QC, ON, YT, and NT, while the Conservatives prevailed in MB, SK, AB, and BC; the New Democrats won only NU). The seat totals end up as follows:
Liberal 233
Conservative 104
New Democrat 1
Essentially, what happens is that the Liberals get a massive boost from narrow wins in very populous provinces, while the Conservatives already own most of the seats in the western provinces, so coming away with *all* of them doesn't come close to balancing things out. The Bloc came a close second in Quebec but end up with nothing to show for it and the NDP's scattered support doesn't pay off.
Canada, however, has a complicated formula for allocating seats to each province, which no longer matches up well with population distribution because some regions have grown faster than others. So I simulated it again with US-style rules where electors are distributed among provinces according to current population, while territories get zero (Canada doesn't have elected senators, so I set each province's minimum at one elector rather than three as in the States). Turns out not to make a big difference:
Liberal 230
Conservative 108
This masks some interesting stuff going on behind the scenes - Atlantic Canada is overrepresented, losing eleven electors across four provinces, while Ontario is underrepresented and picks up ten when this is corrected. Because these are all Liberal victories anyway, the net effect is only a loss of one (the other two correspond to the territories no longer being eligible for electors, which are mainly redistributed to western provinces).
This should be evidence against the idea that importing electoral features from the US will make Canada's political landscape more like that of America. Using either scheme, allocating a whole province at a time really changes things, but not in a way that helps strengthen rural Canada's voice. Every other party loses seats to the Liberals, which pushes them from a minority government to a very lopsided majority.