Rafraîchissoir

By Shahed Nooshmand

Apple News launches new audio features and local news

I love that image of the iPhone showing «Apple News Today» in Podcasts with five stars based on one rating.

Llamas could help fight COVID-19

Well, they are the spitting image of health.

Twitter accounts of Elon Musk, Bill Gates, Apple and just about any other person or company are being abused by cryptocurrency scammer(s)

How the fuck could this be happening?

Famous artworks mask up for coronavirus prevention

Even David who’s naked all the time is wearing a mask.

OnePlus Nord reveal

How could someone link to this video and not mention that priceless look on Marques’ face shortly after 3:44?

Anyway. Excellent video.

Google just put a photo of the Pixel 4A on its store

“Wi-Fi the way it should be.”

Perl Weekly Challenge: week 68

Task #1

You are given a matrix of size M x N having only 0s and 1s.

Write a script to set the entire row and column to 0 if an element is 0.

Here’s my solution:

#!/usr/bin/env raku

my $M = 3;
my $N = 3;

my @matrix = [1, 0, 1],
             [1, 1, 1],
             [1, 0, 1];
my @result = [1 xx $N] xx $M;

@result[$_] = [0 xx $N] if 0 ∈ @matrix[$_] for ^$M;
@result[*; $_] = [0 xx $M] if 0 ∈ @matrix[*; $_] for ^$N;

.put for @result;

It’s very easy to follow. Every row that contains 0 zeroes an entire row in the @result matrix, and every column that contains 0 zeroes an entire column. The trick is the use of subscripts and Arrays (as opposed to Lists).

Task #2

You are given a singly linked list $L as below:

L0 →  L1 →  … →  Ln-1 →  Ln

Write a script to reorder list as below:

L0 →  Ln →  L1 →  Ln-1 →  L2 →  Ln-2 →

This one required a bit of cheating:

#!/usr/bin/env raku

my @list = 1 => 2, 2 => 3, 3 => 4, 4 => Nil;

for ^@list/2 {
	my $A := @list[$_];
	my $Z := @list[* - 1 - $_];
	($A, $Z) = ($A.key => $Z.key), ($Z.key => $A.value);
}

@list[*/2] = @list[*/2].key => Nil;

say @list.map({.key, .value}).flat[^*/2].join(" → ");

(Well, it didn’t require cheating. I just chose the way that involved cheating.)

Bill Nye explains masks

Speaking of wearing masks, wear a mask. Listen to the science guy.

Don’t close your MacBook, MacBook Air, or MacBook Pro with a cover over the camera

For a species so reluctant to wearing masks during a pandemic these humans are sure paranoid with this whole webcam covering thing.

Dieter Bohn on editing alarms in iOS

In the Clock app in iOS, if you want to edit an alarm you have to first tap the Edit button in the top left corner, and of course that infuriates Dieter. He wants to do it with just a tap on the alarm itself. Makes sense.

Before iOS 10, tapping anywhere in the World Clock view would switch between analogue and digital. With the iOS 10 update, Apple — alongside switching to a hideous new dark theme — removed the analogue clock. (From the iPhone World Clock view that is; the iPad still has the analogue clocks and the app icon is practically an analogue clock on both the iPad and the iPhone.)

It really makes sense to be able to edit an alarm by just tapping on it. Obviously that shouldn’t be the only way. The Edit button should still be present for discoverability. But the one-tap shourtcut is a reasonable feature to ask for.

Having said that, I’d still rather have the analogue clock.

Can you trust MKBHD?

Marques Brownlee:

If I ever say something positive about a product in a video it’s because I genuinely think it’s good, and if I ever say something bad about a product it’s because I genuinely think it’s bad. I have absolutely no concern about my relationship with a company changing because of something I say in a review, because I plan on saying the truth every time.

So if a company gets mad or doesn’t want to send review devices anymore or invite me to events, whatever it is, because of what I said in a review — because of a truth that I spoke about their product — that actually looks worse on them.

His Q&A (or “AMA”) on Reddit is also worth checking out.

No, I don’t need to learn more about Time Machine. Good day, sir!

Jude Law would make an excellent Hook.

«The rise and fall of Adobe Flash»

An extraordinary article.

A lot of compelling surveys, lately.

The size of a 5.4-inch dummy iPhone 12

This is exactly what I wanted: a series of decent pictures comparing the 4-, 4.7- and 5.4-inch sizes from different angles. Well done, iZac!

According to the ruler, the new size is a little too close to the iPhone 7, a little too far from the SE. Our new hero does make a good point, however:

From handling it I can say it does feel like a bit more of a stretch than the SE, which just nestles very comfortably in my hand. BUT, although it’s nearer to the 7, I will note that it feels a lot more manageable because the square profile and flat side lets you actually grip the device.

Overall, I think I can get used to it and finally retire my stalwart SE.

Amen.

As long as we still get the stickers …

The iPhone power adapter survey

Interesting.

Perl Weekly Challenge: week 67

This may be the shortest it’ll ever be.

Task #1

You are given two integers $m and $n. Write a script print all possible combinations of $n numbers from the list 1 2 3 … $m.

Sure:

raku -e '(1..$m).combinations($n).say'

Task #2

Remember telephone keypads?

raku -e "say [X~] [|('a'..'o').rotor(3), <p q r s>, <t u v>, <w x y z>][35.comb.map(*-2)]"

It’s really just a bunch of brackets.

Rebound Prime

I mean just look at the totally real experience of a totally real member:

“Rebound Prime has made me happier, more successful in life and with friends, richer, taller, and better at juggling.”

Shmohn Shmoltz, real Rebound Prime subscriber

Life-changing.

“It’s like this, we built a great car, we haven’t built the engine, so we put a golf cart battery in there to make it go for a little bit.”

Colour me greedy.

Apple announces this year’s Apple Design Award winners

Excellent choices. I’m very pleased with the inclusion of StaffPad in particular. StaffPad is a great example of an iPad app that actually costs something sustainable, on par with desktop-class apps.

It’s a bit strange for such a Mac-focused WWDC to only award iOS (and iPadOS) apps and not macOS apps. (Sayonara Wild Hearts and Where Cards Fall don’t count.)

This webpage did not contact any trackers.

Perl Weekly Challenge: week 66

Task #1

You are given two integers $M and $N.

Write a script to divide the given two integers i.e. $M / $N without using multiplication, division and mod operator and return the floor of the result of the division.

Everyone knows this one:

sub MAIN(Int $M, Int $N) {
	die "Error: division by zero" unless $N;
	my $m = abs $M;
	my $n = abs $N;
	my $d = 0;
	++$d while ($m -= $n) ≥ 0;
	say ($M < 0 xor $N < 0) ?? -$d - 1 !! $d;
}

Classic.

Task #2

You are given an integer $N.

Write a script to check if the given number can be expressed as mn where m and n are positive integers. Otherwise print 0.

Please make sure m > 1 and n > 1.

BONUS: If there are more than one ways to express the given number then print all possible solutions.

Here you go:

raku -e 'say .key ~ .value.comb.map: {(8304, 185, 178, 179, |(8308..8313))».chr[$_]} for (2..$N.sqrt).map({$_ => $N.log: $_}).grep: {.value == .value.floor}'

One could do without the superscripts, of course.

Microsoft announces “new approach to retail”, i.e. it’s closing most of its retail stores

Sometimes you have to leave the business to stay in the business.

The world changes so fast: yesterday it was about 20-Watt chargers, today it’s about emptier boxes.

«I Just Go Into Jiggle Mode»

Cleverly funny.

Back Tap

Finally a good way to launch the camera app.

“Play sound on startup”

The chime is officially, intentionally back. Evident from the keynote.

It’s funny how the updated interface guidelines say “macos”.

«’Twas the Night Before Dub Dub»

Apt.

«You Download the App and it Doesn’t Work»

Lanny Bose:

In defending Apple’s policy to TechCrunch, Phil Schiller stated (as quoted above), “You download the app and it doesn’t work, that’s not what we want on the store.”

If this site is doing its job, it’s pointing out the uneven nature by which Apple chooses to enforce this standard, as well as the types of businesses it has decided to extract economic rent from.

Oh, it’s doing its job, alright.

You miss one day and it redirects to Nickelodeon.

Perl Weekly Challenge: week 65

Task #1

You are given two positive numbers $N and $S.

Write a script to list all positive numbers having exactly $N digits where sum of all digits equals to $S.

Here’s one solution:

(10**($N-1)..^10**$N).grep(*.comb.sum == $S).say

Task #2

You are given a string $S. Write a script print all possible partitions that gives Palindrome. Return -1 if none found.

Please make sure, partition should not overlap. For example, for given string “abaab”, the partition “aba” and “baab” would not be valid, since they overlap.

Example 1

Input: $S = 'aabaab'
Ouput:
 There are 3 possible solutions.
 a) 'aabaa'
 b) 'aa', 'baab'
 c) 'aba'

I usually don’t include the examples since they’re irrelevant. This time, though, I am baffled. I seriously don’t understand the example.

I think the confusion lies in the definition of partition. A partition of a string is supposedly a group of non-overlapping, non-empty substrings of it that, if concatenated in order, make up the string. In the example, b is indeed, under this definition, a partition of $S. But a and c are only substrings. I really don’t get how those could be “possible solutions”.

Anyway, here’s my solution:

.values.map(~*).say for $S ~~ m:ex« ^ (\w+ <?{$/ eq $/.flip}>)* $ »

Given the example string, "aabaab", this is the result:

(aabaa b)
(aa baab)
(aa b aa b)
(aa b a a b)
(a aba a b)
(a a baab)
(a a b aa b)
(a a b a a b)

Seems alright to me.

This Trump Cook guy posts some controversial tweets. (Also see «Apple Execs Increasingly Worried About Tim Cook».)

I was starting to forget what football was; and apparently, so were they.

It’s amusing how some wish they all had names and some wish none of them did.

Apple Developer app for Mac

If it’s a Catalyst app — which it likely is — they’ve done a fairly okay job. A few flaws I noticed after a couple of minutes of trying it out:

This is the app’s first release for macOS, so a few shortcomings here and there are no big deal. But WWDC is next week and I doubt the app will receive any “meaningful” update by then. And hey, we all know unselectable text areas are never going away.

Perl Weekly Challenge: week 64

Task #1

Given an m × n matrix with non-negative integers, write a script to find a path from top left to bottom right which minimizes the sum of all numbers along its path. You can only move either down or right at any point in time.

Classic. Here’s one solution:

#!/usr/bin/env raku

my @matrix = [1, 2, 3],
             [4, 5, 6],
             [7, 8, 9];
say "{.sum} ({.join: ' → '})" given min paths(@matrix, 0, 0), by => &sum;


sub paths(@matrix, $i, $j) {
	my @paths;
	my $pivot = @matrix[$i][$j];
	my $right = @matrix[$i][$j+1];
	my $down  = @matrix[$i+1][$j];

	with $right {
		@paths.push: |paths(@matrix, $i, $j + 1).map: { $pivot, |$_ }
	}
	with $down {
		@paths.push: |paths(@matrix, $i + 1, $j).map: { $pivot, |$_ }
	}
	without $right // $down {
		return $pivot
	}

	return @paths
}

I’m not super happy with it, but at least it’s self-explanatory.

Task #2

You are given a string $S and an array of words @W.

Write a script to find out if $S can be split into sequence of one or more words as in the given @W.

Print the all the words if found otherwise print 0.

Speaking of self-explanatory:

say $S ~~ m«^(@W)+$» ?? $0 !! 0

Doesn’t get any simpler than this. (Does it?)

“A weapon that tells the story”

It’s fascinating, the essential role people’s phones play in today’s crime scenes — the witness.

“You’re a damn good cop, Jim Gordon.”

Wil Shipley on the state of the App Store

His argument for upgrade pricing is holy:

If I buy a Mac or iPhone from Apple I can trade it in towards a new one when I upgrade, but users can’t do the same thing for software. All the developers I know are suffering right now because Apple has prevented us from offering special upgrade pricing. It’s completely unsustainable to ask developers to continue supporting their apps but also to forbid them from charging upgrades.

[…]

I know Phil specifically says he doesn’t want to hear about upgrade pricing any more, but Phil also is working for the world’s richest company, which sells hardware and gives software away. Those of us who only sell software can’t afford to give it away.

Well said.

Fear of scripting

Dr. Drang:

Think of how many badly made websites you visit on an average day and realize that there’s a JavaScript programmer who is certainly no smarter than you behind every one of them. If you’re automating things using a visual tool like Shortcuts or Keyboard Maestro or Automator, you already are scripting.

True.

It’s a good thing I didn’t replace myself with a bot to write this blog.

Android 11 Beta is available today

The improvements in privacy are outstanding:

With one-time permissions you can grant apps access to your microphone, camera or location, just that one time. The next time the app needs access to these sensors, it will have to ask you for permission again.

In addition, if you haven’t used an app for an extended period of time, we will “auto-reset” all of the permissions associated with that app and notify you of the same. You can always choose to re-grant the app permissions the next time you open the app.

iOS has had one-time permissions since 13, but this “auto-reset” thing is new and cool.

«Brilliant Hardware in the Valley of the Software Slump»

An excellent piece by Craig Mod on “the software slump”. It’s so well put together, I have a hard time quoting anything from it; I don’t want to spoil it.

What rats can teach us about empathy and racism

I wondered today if racism existed in animals too, and based on this very recent episode of UChicago’s podcast (from three months ago), it does.

It’s quite fascinating, and very brief too running just over 20 minutes. There’s even full transcript in case you don’t want to listen. Here’s just one amazing piece:

And so what we found was that if an albino rat, a white albino rat, had lived with a black cape rat, just one, he'd help any black cape rat. But if he had never seen a black Cape Rat before, he would never help black cape rat. So that was really quite amazing. But it suggests that there's this incredible effect of environment. And it really begs the question of whether there's any role for genetics. And that's how we got to what we call the Mogli experiment.

Now all we have to do is get rid of Shere Khan.

Yours truly, interviewed by Mohammad Anwar

I was blessed to be chosen as the champion of the Perl Weekly Challenge for May.

You can go read the interview. It’s very short, so it’ll probably take just two minutes.

Perl Weekly Challenge: week 63

Make way for the champion.

Task #1

Define sub last_word($string, $regexp) that returns the last word matching $regexp found in the given string, or undef if the string does not contain a word matching $regexp.

Here’s the function definition:

sub last-word(Str $string, Regex $regex) {
	.return when $regex for $string.words.reverse
}

It stops looping as soon as it finds a word that matches. If it never finds such word, it doesn’t return anything, which evaluates to Nil. (There is no undef in Raku.)

Task #2

Given a word made up of an arbitrary number of x and y characters, that word can be rotated as follows: For the ith rotation (starting at i = 1), i % length(word) characters are moved from the front of the string to the end. Thus, for the string xyxx, the initial (i = 1) % 4 = 1 character (x) is moved to the end, forming yxxx. On the second rotation, (i = 2) % 4 = 2 characters (yx) are moved to the end, forming xxyx, and so on. […]

Your task is to write a function that takes a string of xs and ys and returns the minimum non-zero number of rotations required to obtain the original string.

This is a rather straightforward problem with a rather straightforward solution. You keep looping and modifying the string until you get back where you started — a repeat-until. But that’s not what I’m going to do. I’m going to solve this problem mathematically.

Suppose the number we’re looking for, i.e. the number of rotations necessary, is \(r\). Considering the fact that whole rotations and no roation are practically the same, by the time we’re done we’ve had made \(\sum\limits_{i=1}^r i = \frac{r(r+1)}{2}\) character transformations. Therefore, it seems that for any string of length \(n\), the number of rotations \(r\) is the smallest positive integer to satisfy \(n \mid \frac{r(r+1)}{2}\) (i.e. “\(n\) divides \(\frac{r(r+1)}{2}\)”). Knowing this, finding \(r\) is much easier.

More precisely, if a string of length \(n\) is the concatenation of \(\frac{n}{p}\) equal strings of length \(p\), it’s enough to rotate the first \(p\)-substring, because the rest of the string doesn’t need to change. So, the smallest \(r\) for \(n\) is the smallest \(r\) for the smallest \(p\).

Here’s an example:

$$xyxyxy \rightarrow yxyxyx \rightarrow yxyxyx \rightarrow xyxyxy$$

And here’s the script:

#!/usr/bin/env raku

say find-r “xyxyxy”;

sub find-r($string) {
	my $p = find-p $string;
	.return when $_ × ($_ + 1) ÷ 2 %% $p for 1..∞
}

sub find-p($string) {
	my $n = chars $string;
	.return when $string.substr(^$_) x $n ÷ $_ eq $string for |(1..$n ÷ 2).grep($n %% *), $n
}

Which gives 3.

Marques Brownlee: «Reflecting on the Color of My Skin»

Assuming reCAPTCHA works, there are over ten thousand “humans” who disliked this. “‘Peace’ you said?”

«Speaking up on racism»

A message from Tim Cook:

This is a moment when many people may want nothing more than a return to normalcy, or to a status quo that is only comfortable if we avert our gaze from injustice. As difficult as it may be to admit, that desire is itself a sign of privilege. George Floyd’s death is shocking and tragic proof that we must aim far higher than a “normal” future, and build one that lives up to the highest ideals of equality and justice.

In the words of Martin Luther King, “Every society has its protectors of status quo and its fraternities of the indifferent who are notorious for sleeping through revolutions. Today, our very survival depends on our ability to stay awake, to adjust to new ideas, to remain vigilant and to face the challenge of change.”

Half a century later, that quote is as current as if it were from this morning.

The fact that they were unwise enough to do it in the first place leaves little hope that they are and increases the chance that they will, unfortunately: If those who watched that narcissistic YouTube ad let’s collect signatures as a birthday gift to our “beloved” president and actually signed aren’t embarrassed and rethinking their life decisions right now, they’ll probably also reelect that sack of poop.

“… and then you fuck the plant.”

“Be David Caruso in Jade.”

«The Zane Lowe Interview Series»

The MacRumors post is very misleading. It’s true that the show is backed by Apple Music, but you don’t have to be an Apple Music member to listen to it. You don’t even have to use Apple’s Podcasts app — I just searched Overcast for “Zane Lowe” and found it.

It’s a podcast.

Perl Weekly Challenge: week 62

Task #1

Write a script that takes a list of email addresses (one per line) and sorts them first by the domain part of the email address, and then by the part to the left of the @ (known as the mailbox).

Note that the domain is case-insensitive, while the mailbox part is case sensitive. (Some email providers choose to ignore case, but that’s another matter entirely.)

Here’s a one-liner:

raku -e '.key.put for <name@example.org rjt@cpan.org Name@example.org rjt@CPAN.org user@alpha.example.org>.map({/(.+) "@" (.+)/; $_ => [$1.fc, ~$0]}).sort(*.value)'

Straightforward, isn’t it?

Task #2

Your job is to write a script to work with a three dimensional chess cube, M×M×M in size, and find a solution that maximizes the number of queens that can be placed in that cube without attacking each other. Output one possible solution.

Unfortunately, I couldn’t do this in one line. You can see the rather long solution, however, on GitHub.

More Judas than Mark.

So this is how liberty dies — with thunderous applause.”

“For a safe and secure society.”

I’m starting to like this jack person.

Hey Siri, what’s the weather like in Cape Canaveral?

«Apple Glasses Already Here»

Staying subscribed to the CARS RSS feed pays off sometimes.

Maybe neither is better.

«A Wake-Up Call for Microsoft»

Linus Tech Tips, reviewing the new Surface Book:

This is Harold.

Harold has a hard time making decisions.

That’s why Harold got the Surface Book 3.

A Catalyst version of Messages, 9to5Mac says

This doesn’t make sense. The only appeal of Catalyst to me is that it makes bringing an iOS app not present on the Mac to the Mac easier. You could argue that it’s good for maintenance purposes where instead of worrying about two separate things, you only put your time into one thing. True, but that doesn’t apply here — Apple is a trillion-dollar company, not a nameless bunch of hackers who want to heat people with microwaves.

The only reason Apple is doing this (if it is, of course) is to have another proof of concept for Catalyst.

Perl Weekly Challenge: week 61

Task #1

Given a list of 4 or more numbers, write a script to find the contiguous sublist that has the maximum product. The length of the sublist is irrelevant; your job is to maximize the product.

Here you go:

raku -e 'say (for ^$_ X ^$_ -> (\a, \b) { $_ => [*] |$_ given $_[a..b] }).max(*.value) given <2 5 -1 3>'

It’s very simple. The trick is really in the $_s (if that’s how you pluralise $_). Just for fun, I’m gonna replace each $_ with the value it holds.

raku -e 'say (for ^<2 5 -1 3> X ^<2 5 -1 3> -> (\a, \b) { <2 5 -1 3>[a..b] => [*] |<2 5 -1 3>[a..b] }).max(*.value)'

Task #2

You are given a string containing only digits (0..9). The string should have between 4 and 12 digits.

Write a script to print every possible valid IPv4 address that can be made by partitioning the input string.

For the purpose of this challenge, a valid IPv4 address consists of four “octets” i.e. A, B, C and D, separated by dots (.).

Each octet must be between 0 and 255, and must not have any leading zeroes. (e.g., 0 is OK, but 01 is not.)

Here’s my solution:

raku -e '$_[0].join(".").say for "25525511135" ~~ m:ex«^ ( 0 || <[1..9]> \d* <?{ $/ ≤ 255 }> ) ** 4 $»;'

It may not seem like much, but it’s doing exactly what the problem says. The string of numbers is exhaustively matched against what the problem defines as a valid IPv4 address. The pattern tries different ways to partition the string into four numbers (note the ** 4), each of which is either 0, or a number whose leftmost digit is not 0 and which isn’t greater than 255. Each “octet” is captured in the same group 0, so the group is actually a list of octets which we then join using dots — and that’s our address.

«A farewell to The Quick Brown Fox»

Thank goodness Siracusa retweeted Atwood, or I wouldn’t have found this.

I’ve always questioned the use of pangrams for font proofing. More designers should use text that looks like what people actually type. Nothing feels more rewarding than a tour of Jonathan Hoefler’s – the Jonathan Hoefler’s — process of coming up with a good proofing text.

This essay is awesome.

London, Canada?

It seems to work as expected for those in England — or at least the same time zone as England, which feels obvious and not helpful at the same time. I’m not in the zone but still get England on all of my devices. Which is the “correct” answer.

I mean no offence to London, Canada, but how many people are really likely to mean “London, Canada” — and not “London, England” — when they just say “London”? Not as many as if it were the other way around, I bet.

I do wonder, and this may be a simple thing, but I wonder what the algorithm actually is in case of similar names. I thought I had it with the likelihood theory, but apparently not.

Looking at some reviews of the new Surface Headphones got me very interested in them. Naturally, I headed over to the webpage and bam! Double-spaced sentences.

Ironic, isn’t it?

Spotify’s «The Joe Rogan Experience»

Remember: “All podcasts are shows; not all shows are podcasts.”

Congratulations on the deal if it works out well, but this is a dick move. A software design aesthete, like yours truly if he says so himself, who might prefer a fine app such as Overcast, would have to put up with Spotify’s cruddy app and sign up for an account to listen to this so-called “podcast” and perhaps only this so-called “podcast”. Now, I never listened to the podcast to begin with and I certainly don’t plan on starting now, so all I have to put up with is Gruber’s take that:

If Howard Stern’s fans followed him to Sirius satellite radio — which at the time he made the move required not just a subscription to the service but dedicated hardware to receive the satellite transmission — it seems like a sure bet that most of Rogan’s fans will follow him to Spotify.

Tell me — am I a bad person for wishing that they won’t?

Apple Watch Pride Edition Sport Band

So obvious and yet so beautiful.

Alright. Let’s see how good of a Fred Jones Zac Efron is.

“The pig went to Mexico to learn Spanish.” said the bilingual green owl.

Perl Weekly Challenge: week 60

A little quiet, this week.

Task #1

Write a script that accepts a number and returns the Excel Column Name it represents and vice-versa.

Excel columns start at A and increase lexicographically using the 26 letters of the English alphabet, A..Z. After Z, the columns pick up an extra “digit”, going from AA, AB, etc., which could (in theory) continue to an arbitrary number of digits. In practice, Excel sheets are limited to 16,384 columns.

Raku has string sequences. In fact, "A"..* is an infinite sequence of Excel column names. This makes solving the problem rather easy.

Here’s the one-liner:

raku -e 'say { $^a ~~ Str ?? .antipairs.grep(*.key eq $^a)[0].value + 1 !! $_[$^a - 1] given "A"..* }($_) for (28, "AD")'

And here’s the output:

AB
30

Task #2

Write a script that accepts list of positive numbers (@L) and two positive numbers $X and $Y.

The script should print all possible numbers made by concatenating the numbers from @L, whose length is exactly $X but value is less than $Y.

Assuming we know @L, $X and $Y, this is my solution:

raku -e 'say ($X > 1 ?? [X~] @L xx $X !! @L).grep(* !~~ /^0.+/).grep(* < $Y)'

Note that [X~] @L xx 1 is just [X~] @L, which we avoid by checking $X > 1.

I do not fear the naked banana.

Scunthorpe Sans

VOLE.wtf:

A s*** font that f***ing censors bad language automatically

It’s able to detect the words f***, s***, p***, t***, w***, c*** and dozens more, but with a special exemption for “Scunthorpe”; that town has suffered enough.

Stunningly, “ass” is okay but “arse” isn’t.

Pine.blog

Cool.

Apple Books for Authors

Super neat new website. Writing tips, design advice, publishing help and more all in one place as they should always have been. The timing, nevertheless, feels right.

I adore the comparison to Kindle.

«In These Difficult Times»

“Lift your spirits. Lift your breasts.”

Perl Weekly Challenge: week 59

Task #1

You are given a linked list and a value k. Write a script to partition the linked list such that all nodes less than k come before nodes greater than or equal to k. Make sure you preserve the original relative order of the nodes in each of the two partitions.

raku -e 'put join " → ", |.grep(* < 3), |.grep(* ≥ 3) given « 1 4 3 2 5 2 »'

Because grep preserves the relative order of the nodes, this script works.

Task #2

Let me just quote the whole thing, first:

Helper Function

For this task, you will most likely need a function f(a,b) which returns the count of different bits of binary representation of a and b.

For example, f(1,3) = 1, since:

Binary representation of 1 = 01

Binary representation of 3 = 11

There is only 1 different bit. Therefore the subroutine should return 1. Note that if one number is longer than the other in binary, the most significant bits of the smaller number are padded (i.e., they are assumed to be zeroes).

Script Output

You script should accept n positive numbers. Your script should sum the result of f(a,b) for every pair of numbers given:

For example, given 2, 3, 4, the output would be 6, since f(2,3) + f(2,4) + f(3,4) = 1 + 2 + 3 = 6

Again, there is a one-liner for this:

raku -e '(2..4).combinations(2).map({ (.comb Z≠ sprintf("\%0{.chars}b", @_.min).comb).grep(1) given @_.max.base(2) }).sum.say'

The helper function is the block that’s run via map. Since the number of necessary bits to represent a number is potentially more for the greater number, for each pair of numbers we first convert the bigger one to binary and pad the other one’s binary with enough zeros to make them equal in length. Then we zip each of one’s bits to the corresponding bit in the other number with ; for each pair of equal bits we get a False, and for each pair of different bits we get a True. By grepping 1, we only get the Trues, and when used in a numeric context such as sum, the list acts as its own cardinal, i.e. the number of Trues, i.e. the number of different bits. Hence, the script returns 6.

These Middleditch & Schwartz specials are very good.

Do not use blades to open

I once opened a box with my trusty Cardsharp. Had to buy a new jacket.

Surface Book 3 is announced and, surprising absolutely no one, doesn’t support Thunderbolt

OK. You’re concerned about security. You wanna sell your crappy dock with your proprietary connector. I get it. But “we believe [the customers] will have the performance that they need” is bullshit.

WWDC20 will begin on June 22nd

If you’re lucky you’ll get good seats.

So it wasn’t 14 inches.

Thirsty koalas lick trees

This is a truly eye-opening discovery.

One koala was caught lapping up rainwater for more than 30 minutes, at “a steady pace” of two licks per second.

Now think about the amount of water that goes to waste every time someone keeps the water running for no reason when brushing their teeth or taking a shower — or, contemporarily, washing their hands.

«A Parks and Recreation Special»

Bye bye, Li’l Sebastion.

Good Omens: Lockdown

“To the world…”

Perl Weekly Challenge: week 58

Here goes:

Task #1

Compare two given version number strings v1 and v2 such that:

The version numbers are non-empty strings containing only digits, and the dot (“.”) and underscore (“_”) characters. (“_” denotes an alpha/development version, and has a lower precedence than a dot, “.”).

Raku has a type Version, and it even supports comparing via <=>, but v1.2_5 is the same as v1.2._.5 and so v1.2 > v1.2_5. It’s not hard to work around this, and I’ve come up with a gross solution on GitHub.

Task #2

Write a script to arrange people in a lineup according to how many taller people are in front of each person in line. You are given two arrays. @H is a list of unique heights, in any order. @T is a list of how many taller people are to be put in front of the corresponding person in @H. The output is the final ordering of people’s heights, or an error if there is no solution.

If we go from tallest to shortest, and each time insert the person who’s supposed to be behind t people at index t (starting with 0, of course) we have our answer.

This works because we know the new guy is shorter than everyone already in the line, so obviously there are t people taller than the person whose postition is t.

The only time we don’t get an answer is when there aren’t enough people to place in front of someone; the language can actually take care of this for us.

So, assuming we know @H and @T, this is the solution:

#!/usr/bin/env raku

my @Q;
@Q.splice: .value, 0, .key for (@H Z=> @T).sort: -*.key;
print @Q;

Which gives the answer for that 1000-person list in about 1 second.

Now, let’s assume this is the input:

@H = 1;
@T = 1;

Absurdly, this input is asking for someone taller than Sultan Kösen, which causes splice to fail due to an out-of-range offset argument, and so the interpreter throws us an error.

I understand the situation we’re in, but shouldn’t that package have arrived by now?

iPhone SE’s Haptic Touch doesn’t work with notifications and it’s not a bug

It doesn’t work on the original SE either. Until today, I was trying to convince myself that it’s probably because it doesn’t have a Taptic Engine, even though that was obviously bull since all the other features were there. Now I’m pretty sure it’s just because it’s called SE.

Which video call apps can you trust?

In total, 12 apps met Mozilla’s Minimum Security Standards: Zoom, Google Duo/HangoutsMeet, Apple FaceTime, Skype, Facebook Messenger, WhatsApp, Jitsi Meet, Signal, Microsoft Teams, BlueJeans, GoTo Meeting, and Cisco WebEx.

Three products did not meet Mozilla’s Minimum Security Standards: Houseparty, Discord, and Doxy.me.

Their guide seems legit, but the fact that 12 out of 15 “met Mozilla’s Minimum Security Standards” — capital ‘M’, capital ‘S’ — raises some concerns of its own.

Practicing the coding challenges

Brent Simmons:

Consider a question like this:

You need to add two numbers and get a sum. But, importantly, the digits of those numbers are stored in arrays, and they’re backwards.

The return value also needs to be in a backwards array.

[…]

In production code, if a problem like this came up, I’d ask “How the hell did we get here?” and try to backtrack and figure out what insanity caused this, because it’s just not right.

But, if this code were truly needed, I’d write code the way I normally would, with clarity in mind first.

And then, if my tools told me it was too inefficient with time or space, I’d figure out a more efficient version.

These questions, then, are able to test what you might come up with when you’re in that position.

The thing is, what I would most want to know is how people write code for the 99% of time when they’re not in that position. That’s not being tested here.

It is true that these sorts of problems don’t reflect the majority of tasks a software engineer faces in their work, and the solutions they expect are even less realistic compared to the average programmer’s workflow. Coincidentally, co-hosts of the Accidental Tech Podcast talked about this very topic in the very recent episode.

Still, it’s good to be prepared; and the problems do sometimes tend to get fun and are well worth the time spent thinking about them.

As a quarantine pastime, I started subscribing to Daily Coding Problem which does what it says on the box. And if there’s any reality replicated in these challenges, it’s that the problems were actually asked by big companies like Apple, Amazon, Google, etc. I solved the problems the first two weeks but now I’m just guilty-marking them as read.

And of course you can’t forget the Perl Weekly Challenge which I’ve been participating in for a while now.

Follow-up: Not mine — his. Again, he’s telling the truth. Anyone who argues is just closing their eyes to reality.

John Conway solved mathematical problems with his bare hands

“… once decided to drop math for a little while to memorize the world’s capital cities.”

Is every YouTube ad in Russia 18+?

«The first modern pandemic»

I haven’t read any other pandemic-related article with as much accuracy and detail as this one. The writing’s coming from Bill Gates alone should give the reader a grasp of how informative and credible it is.

Ubuntu 20.04 LTS arrives

This update looks very impressive. I haven’t used Ubuntu in a while, but I’ve decided to give this one a try.

And I love the new mascot.

«Middle-Aged Mutant Ninja Turtles»

The cold open is shockingly funny.

Perl Weekly Challenge: week 57

One-liners, once more.

Task #1

This is an easy one: invert a full binary tree.

raku -e 'say (sub ($_) { .isa(Pair) ?? (.key => .value.reverse.map: { samewith $^a }) !! $_ })(1 => (2 => (4, 5), 3 => (6, 7)))'

It’s not even that complicated. We write an anonymous subroutine (call it λ if you want) that checks if the input is a parent-children Pair in which case it reverses the children, or is not a Pair and returns the input as is. This is the same notation as last week’s binary tree problem.

You’ll note the use of samewith for recursive calls. Every child itself has to go through the same anonymous subroutine, and samewith does just that.

Task #2

Write a script to find the shortest unique prefix for each each word in the given list. The prefixes will not necessarily be of the same length.

Here’s one way to do it:

raku -e 'say (my @words = get.words).map: { m« ^.+? <?{1 == @words.grep: *.starts-with: ~$/}> » ?? ~$/ !! Nil }'

The regex matches the first few characters of each string minimally until it finds a prefix that’s not found in anything else. If no unique prefix is found, Nil is returned. So for this:

blue black orange brown brownish

We get this:

(blu bla o Nil browni)

Which does it for this week.

«The heavy truth about the iPad Pro’s Magic Keyboard»

Some people, for whatever reason, are trying to have their cake and eat it too when it comes to iPad keyboards. The fact that iPad itself is a lightweight machine — a Kryptonian baby, actually — has no effect on the laws of physics. You keep it naked, it’s lightweight. You want to add a good, stable keyboard? Sure, but you won’t be finding a zero-pound one of those any time soon. It will add some weight. Obviously.

Now Jason Snell is resolving this misunderstanding among other ones, so spot on, writing for Macworld:

I’ve seen a lot of criticism of the Magic Keyboard that seems to ignore the fact that Apple also still makes the Smart Keyboard Folio, a thinner, lighter, and cheaper—but more limited—product. Having seen the first hands-on reports about the Magic Keyboard, I’m not surprised at all that Apple chose to keep the Smart Keyboard Folio around. If you’re someone who likes to carry your iPad around with a keyboard attached, but doesn’t use the keyboard all that much, the Magic Keyboard is probably going to be overkill.

And that’s okay, just like it’s okay if you don’t buy an Apple Pencil. The Apple Pencil is a spectacular tool for some users, and a complete waste of money for others. This is where the iPad Pro is today. A core product surrounded by an array of optional accessories. If one of them doesn’t work for you, keep moving—there’s probably an alternative out there.

This is one of those good well don’t buy it then pieces of writing. No one seems to be complaining about how heavy their bag gets when carrying two laptops; (a) because no one is travelling around, everyone’s at home practising social distancing (No? Well, they should be.) and (b) because people seldom wish to carry two laptops as one seems sufficient. How is it that all of a sudden people start complaining about the presumably noticeable weight the Magic Keyboard will add to their everyday carry? I’m not telling anyone to pick between their “iPad laptop” and their “laptop laptop”. I’m just pointing out that 2 > 1 and there’s nothing wrong with it.

I’ve been twiddling with blog post IDs, so JSON feed readers might have marked all items as unread or even displayed duplicates. Sorry for the inconvenience.

Looney Tunes Cartoons on HBO Max

What?

«The King of iPad Keyboard Mountain»

Good overview and crisp attention to details, as you’d expect from Craig Mod.

However, he does make an error, I think, where he says the keys “have the same 1mm travel distance as the latest butterfly mechanism found on the 13″ MacBook Pro”. Butterfly keyboards have neve had a millimetre of travel, as far as I know, and the further travel has only recently been resurrected on their portables with the new “Magic Keyboard” on the 16-inch MacBook Pro, the Air and now the iPad Pro. Hence, the “feels about 50% farther” might actually be about 50% further.

“Turtle sex”

“Sex, of the less interesting sort”.

Perl Weekly Challenge: week 56

No dumb one-liners this week.

Task #1

You are given an array @N of positive integers (sorted) and another non negative integer k.

Write a script to find if there exists 2 indices i and j such that A[i] - A[j] = k and i != j.

It should print the pairs of indices, if any such pairs exist.

The easiest way to do this is probably with two nested loops. This is the general solution for a given array of numbers, and perhaps the best one at O(n²) since you’d have to sum up every two numbers in the array.

With this particular problem, however, we can do better; since we know the array is sorted. We can iterate over the array at O(n) and look for a correct number in the array which meets our diff constraint using binary search at O(log n), which gets us down to O(n log n).

Assuming there is a sub infix:« 🔎 » ($needle, @haystack) that returns the index of $needle in @haystack or Nil, the following would print out all the right pairs of indices:

(There are a couple of implementations of binary search in Raku on Rosetta Code.)

#!/usr/bin/env raku

my @N = 2, 7, 9;
my $k = 2;

for ^@N -> $i {
	my $j = (@N[$i] + $k) 🔎 @N[$i+1..*];
	say $i, " ", 1 + $i + $j with $j
}

Which operates at O(log n!), which is practically O(n log n).

Task #2

You are given a binary tree and a sum, write a script to find if the tree has a path such that adding up all the values along the path equals the given sum. Only complete paths (from root to leaf node) may be considered for a sum.

Here’s the example script:

#!/usr/bin/env raku

multi paths(Pair $tree) {
	|paths($tree.value).map: {$tree.key, |$_}
}
multi paths(Positional $nodes) {
	$nodes.map: { paths $_ }
}
multi paths($leaf) { $leaf }

my $tree = 5 => (4 => 11 => (7, 2),
                 8 => (9 => 1, 13));
say %(paths($tree).map: {.sum => $_}){22}

In the above notation, each parent is the key of a Pair, and its children are the value of that Pair. The variable $tree is therefore a representation of the binary tree below, as came in the text of the task.

      5
     / \
    4   8
   /   / \
  11  13  9
 /  \      \
7    2      1

The paths subroutine returns a list of all the paths in the tree, obviously. When its argument is a single leaf at the bottom of the tree, it act as the identity function. When its argument is a list of nodes, it returns a list of all the paths for each node, recursively calling paths. For arguments in form of a Pair, i.e. a parent and its child(ren) … well … you know what happens.

Note that we use | to flatten the list of different paths because of the function’s recursive nature. Without it, paths $tree would give the following abstract:

((5 ((4 (11 7)) (4 (11 2)))) (5 ((8 ((9 1))) (8 13))))

Which is sort of correct, but makes calculating the sums harder.

The final statement maps every possible path sum in the tree to the path that produces it, hence the program will say:

(5 4 11 2)

If we asked for 21 instead of 22, it would say:

(Any)

Which means no path in the binary tree has a sum of 21.

«90 Classic Looney Tunes Cartoons You Can Watch Right Now»

Everyone’ll probably go through the list and say where’s foo or bar. Nevertheless, this is a fine selection. Some are my own favourite, and many I’ve regretfully never seen before. Not for long.

«Peek Into The Future With iPad Pro»

An excellent article throughout. They’ve done a wonderful job of not only explaining but showcasing iPad Pro’s lidar, even if it turns out to be just a blue whale mouth scanner.

Heaviness aside, the animations they’re using in iPhone SE’s page are extremely good. That privacy one in particular.

“A popular design”

Oughta love the B&W.

«A Trackpad and a Mouse Walk Into an iPad…»

Brilliant and consice, as usual.

It still feels disappointing to me — seeing the iPad, a totally different beast, turn into just another laptop. On the bright side, it’s turning into a damn good laptop.

John Conway dies of COVID-19

It is the sad but truthful game of life.

Speaking of crazy, it’s downright Arkhamic that my perfectly valid feed gets a warning because “title should not be blank”. It’s called microblogging, damn it!

I finally did my homework and hooked up an Atom feed in addition to the JSON feed. It was trivial, really, but not as straightforward as JSON, which is why I put it off until today. The only reason I finally did it is that ironically NetNewsWire’s Safari extension doesn’t detect JSON feeds, and the greyed-out button in the toolbar was driving me crazy.

BBEdit: on this day, 1992

“It’s a ghastly vintage.”

Perl Weekly Challenge: week 55

Here are my solutions for this week’s problems.

Task #1

You are given a binary number B, consisting of N binary digits 0 or 1: s0, s1, …, s(N-1).

Choose two indices L and R such that 0 ≤ L ≤ R < N and flip the digits s(L), s(L+1), …, s(R). By flipping, we mean change 0 to 1 and vice-versa.

[…]

Write a script to find the indices (L,R) that results in a binary number with maximum number of 1s. If you find more than one maximal pair L,R then print all of them.

Here’s my rather standard solution:

#!/usr/bin/env raku

multi postcircumfix:<[ ]> (Str $_, Range \ran) { .substr(ran) }

my $num = “010”;
my %flips;

for ^$num.chars -> $L {
	for $L..^$num.chars -> $R {
		%flips{“$L\t$R”} = +($num[^$L] ~ (TR/01/10/ given $num[$L..$R]) ~ $num[$R^..*]).comb.grep: 1
	}
}

say .key for %flips.grep: *.value == max %flips.values

Even though it doesn’t make sense semantically, I’ve overloaded the [ ] opeartor for substringing, because that seems to be a trend in many languages.

Each pair of left and right boundaries is mapped to the number of 1s found in the resulting string after the flip; the TR/// given takes care of flipping 0s and 1s in the range (L, R), and after grepping all the 1s out we turn it into a number — i.e. the number of 1s.

In the end, the pairs that produced the maximum number of 1s are printed (or said).

Task #2

Write a script to print all possible wave arrays for an integer array N of arbitrary length.

Sure thing:

raku -e '.put for (my \N = [1, 2, 3, 4]).permutations.grep: { all do $_[0](|$_[1]) for |(&infix:«≥», &infix:«≤») xx * Z ($^n[^(*−1)] Z $^n[1..*]) }'

I wish I could do some sort of zigzag reduction on the arrays, going back and forth between and . There’s no easy way to do that, as far as I know, so here’s what we’re gonna do instead.

First, we define our own zigzag sequence of and which goes on forever. Then, for each permutation of N, we check to see if putting the operators in between the numbers, in order, results in a correct comparison.

To do the comparisons, we pair each element (except the last one, obviously) with the next. Then we apply our sequence of comparison operators to our list of paired numbers. Basically, we make a new pair where the first item is the comparison operator and the second is the pair of numbers to compare. We can then simply call the operator like any function with the two numbers as arguments.

It would have been nice if the zipping and the calling could be done at once, but I don’t think that’s feasible.

«Creativity goes on»

Yes.

To pat myself on the back, Rafraîchissoir is a flourishing creation of social distancing.

The “Clips” found on iOS 14 code

I never give a hoot about these “found on whatever-OS whatever-version code” stuff, and this one’s no different. Here are some of my opinions anyway:

I should add in the end that I am greatly annoyed by this whole idea. The reason I don’t have YouTube installed on my iPhone isn’t that I’m poor or that I want to keep the app count where it is so that the icons reach the end of the last row in the last home screen. No. I don’t have YouTube installed on my iPhone because YouTube’s iOS app sucks. Does it suck more than their mobile website? Maybe it does, maybe it doesn’t. It certainly sucks enough that poor people like me are willing to live without it rather than with it and a new home screen that otherwise would not exist.

Now you’re telling me YouTube links are gonna open in a baby version of that same app? If the father is a green-faced, tornadic suit of a man, God alone knows what will come of his son.

Stephen Hackett’s bracket

I’m not very good at picking one of two things I like. One day, somebody asked me to pick between Superman and Spider-Man; I took so long to think, they left the room.

But looking at these brackets, I might just pick the Titanium PowerBook G4 too. I’ve always liked the look of it and the fact that it had black keys. The Aluminium PowerBooks are a step back in this regard, if you ask me. Nowadays, the whole computer industry seems lost — if only for the non-black key caps.

And boy, you oughta love the back ports.

Still, you could ask me tomorrow and I might give you a different answer. So rationally, I am going to say that my favourite Mac is my own — a 2018 MacBook Air — which isn’t included in the brackets.

And no, I have not yet made up my mind on Superman vs Spider-Man.

«iPhone SE vs. iPhone 9»

I will bet a dozen face masks and a roll of toilet paper that they’ll call it “SE”.

“I’ve shenaned once, I’ll shenan again.”

Robot or Not: tabs or spaces

Once again, ducks vs rabbits.

Meanwhile, I’m at home fussing about my head rush.

«The hunt for the next potential coronavirus animal host»

This has been one of my concerns since the beginning, especially with cats who are all over the map and, according to this research, happen to be good carriers too.

Perl Weekly Challenge: week 54

Here are my solutions for this week’s tasks:

Task #1

Write a script to accept two integers n (>=1) and k (>=1). It should print the kth permutation of n integers.

Here’s a one-liner for that:

raku -e 'say [~] (1..get).permutations[get−1]'

The only thing to note is that the first get is our ‘n’ and the second one is our ‘k’, which we get in that order.

Task #2

Ah, the Collatz conjecture. Here you go:

raku -e 'put “\e[F\e[K” ~ join “ → ”, (prompt(“\n”).trim-trailing, -> \n { n %% 2 ?? n ÷ 2 !! 3 × n + 1 } … 1)'

Here’s how it works: we get a number, start a sequence with it, put it into ‘n’, and calculate the next term based on whether ‘n’ is even or not. We keep doing this until we reach 1.

To make the result look nicer, we put an arrow between the terms. The “\e[F\e[K” is just two ANSI escape codes; \e[F takes the cursor to the beginning of the previous line, and \e[K clears to the end of the line. This way, when we enter 23 as input, instead of having to look at this:

23
23 → 70 → 35 → 106 → 53 → 160 → 80 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1

We simply see this:

23 → 70 → 35 → 106 → 53 → 160 → 80 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1

Now we get to the Extra credit:

Have your script calculate the sequence length for all starting numbers up to 1000000 (1e6), and output the starting number and sequence length for the longest 20 sequences.

Lazy people like me might be tempted to solve this problem with the following one-liner:

raku -e '.put for (gather {take $_ => +($_, { $_ %% 2 ?? $_ ÷ 2 !! 3 × $_ + 1 } … 1) for 1..^1e6}).sort(−*.value)[^20]'

What this script does is that it basically maps every number from one up to a million to the size of its corresponding hailstone sequence, and then sorts the map by those sizes, takes out the top 20, and shows them.

However, this script is slow. Like, really slow. It’s so slow, it hurts my impatience.

The issue, I think, is that for every number we are generating a whole sequence all the way down to 1. That takes time. Instead, we could generate as much of it as we need, and use a previously generated sequence to complete it. For example, given 10, since we know the “8 → 4 → 2 → 1” already, we just calculate the “10 → 5 → 16 → 8”.

So, here’s a script that keeps track of previous sequences and reuses them when needed:

#!/usr/bin/env raku

my %hail = 1 => 1;

for 1..^1e6 {
	my $n = $_;
	my $i = 0;
	until %hail{$n}:exists {
		$n = $n %% 2 ?? $n ÷ 2 !! $n × 3 + 1;
		$i++
	}
	%hail{$_} = $i + %hail{$n}
}

.put for %hail.sort(−*.value)[^20]

This one took about two minutes, which is still a lot. But this time, it’s not the algorithm’s fault. With a few changes, the Raku script above becomes the following Perl script:

#!/usr/bin/env perl

my %hail = (1 => 1);

for (1..1e6-1) {
	my $n = $_;
	my $i = 0;
	until (exists $hail{$n}) {
		$n = $n % 2 ? $n * 3 + 1 : $n / 2;
		$i++
	}
	$hail{$_} = $i + $hail{$n}
}

print "$_	$hail{$_}\n" for (sort { $hail{$b} <=> $hail{$a} } keys %hail)[0..19]

Which took about 9 seconds to finish.

Cards Against Humanity: Family Edition

This is awesome in so many ways: the cards are funny, the FAQ are funny, even the terms of service are funny. And the website is so well-written. Their HTML source looks a lot better than mine. Other than a warning and an error, it’s rock solid. Oh, also, it’s such a sweet thing in these bitter times.

This year’s April Fools’ joke is on all of us.

Sam L. Jackson: «Stay the fuck at home»

He beat me to the “Quarantino” joke.

«Dark Sky Has a New Home»

The app is now available as an “Apple app” on the App Store, and is still $3.99. When Apple acquired Workflow, they made it free and then eventually remodelled it into Shortcuts. I predict a similar fate for Dark Sky, as a paid weather app doesn’t feel very Apple-y.

I’m surprised that they’ve dropped the Android app, but if my prediction turns out to be true, it’s obviously the right move.

«Goodbye iMore & Vector (Kinda)»

I knew the day would come when Rene Ritchie decides to work on his own. Ever since Vector kicked off, he’s proven to be a very capable one-man band. I hope him a successful new career and look forward to watching him again on YouTube, later this week.

Perl Weekly Challenge: week 53

After a year, I’ve finally decided to take part in the Perl Weekly Challenge. Here are my solutions for the 53rd week:

Task #1

We have the following matrix:

1 2 3
4 5 6
7 8 9

The goal is to rotate it 90/180/270 degrees clockwise.

First, here’s my somewhat one-line solution:

raku -e 'my @M = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]; .put for (@M = reverse(do @M[*;$_] for ^@M[0]) for ^(get() / 90 % 4 || 4))[*-1]'

I’m not saying somewhat just because it’s way longer than a normal line, but because for me “a line” means “a statement”. My solution “clearly” has two statements. I couldn’t do it with a single statement, because then I couldn’t have modified the matrix; and there’s just not enough $_.

The basis of my script is to use positive angles for counterclockwise rotations and negative angles for clockwise rotations. And I’m not limiting it to just those three angles. This is just sentimental, really.

So. We got our degrees. Since after four 90-degree rotations we’ll be back where we started, we find the number of times we have to rotate modulo 4. The || 4 is so that we don’t get Effective index out of range in case the angle is a multiple of 360.

Each time, we use each column, which is easily accessible via two-dimensional subscripting [*;$_], as a row in our matrix. After this, we reverse the matrix because otherwise it’ll look upside down. (Duh!)

Since our inner loop returns all rotations in order, we take out the last one and put it on screen, row by row.

Task #2

This is the problem:

Write a script to accept an integer 1 <= N <= 5 that would print all possible strings of size N formed by using only vowels (a, e, i, o, u).

The string should follow the following rules:

And this is the solution:

raku -e '.say for <a e i o u>.combinations(get).map(*.permutations.map(*.join))[*;*].grep({!m/ao|au|ea|eo|eu|oe|oi|ua|ui/}).sort'

It’s a pretty straightforward and kinda lame one-liner. (But at least it is one.) We find all combinations of a given size — which we get — out of the five letters we have. Then, for each combination we calculate every permutation and turn it into a word — via join. After that, we can find the ones that do not match that simple pattern, which are basically the ones that follow the rules.

Here’s something else about iPad Pro’s Magic Keyboard: There isn’t enough room for a legit “command”, so they’ve downsized it to a cosy “cmd”.

Kuo says ARM Macs in 2021

My theory is that they already have a bunch of processors prepared to ship; they just don’t know what to call them yet.

«Deciphering the visual language of Humboldt squid»

Reading this after watching Dolittle is really something.

I find Daffy Duck’s siding with tabs very reassuring.

Just finished Spyder.

Why are they making me wait until Friday when «Future Nostalgia» has already leaked?

Universal Purchase

I’m not sure many apps will move to this model. Not because it’s a bad model, but because it’s just not worth it. Current apps would have to be redistributed which means they’ll lose their ratings and reviews (and possibly their current users); and new apps wouldn’t make enough money if sold for less for all the platforms, or lose customers’ interest if they have to pay multi-device money for an app they’d only use on one device. And, as far as I see, there’s no way to use both models and keep everybody happy.

Also, many free apps like Bear use a subscription method for cross-platform distribution, which I’d bet works better for them than a one-time purchase.

Update: Apparently, according to MacStories, the cross-platform subscription method mentioned above was previously a workaround by the developer. Now, with universal purchase, it doesn’t have to be. So yeah, there is at least one benefit to the new model.

Another update: One very important thing I missed was Catalyst and now that I consider it, universal purchase would work brilliantly for Catalyst apps. Because the app was (mostly) written once, it makes sense to also charge the user once. So yeah, there are at least two benefits to the new model.

Here’s something I found out today: the Magic Keyboard you see via AR on Apple’s website isn’t actually the Magic Keyboard they’re gonna ship. The AR one says “alt” instead of “⌥” and doesn’t show the “⌃” above “control”. Also, there’s an “enter” above “return”. It also has a useless “fn” key instead of the globe. The one they’re advertising on their website and are planning to ship in May is exactly like the ones found on their notebooks.

My guess is that they’re using old, pre–butterfly era key models for the AR renders, which were presumably converted to USDZ from whatever their old format was.

Other than some typography though, what you see is what you get.

«The changing nature of Apple product releases»

Good analysis. The format of the iPad Pro cursor video seems fit for an online-only conference, and I certainly think that is how it’ll be in June.

Spyder

I’ve played the first two levels and I can qualify it as fun. One thing that bugs me about it, though, is the constant changing of the camera angle. I don’t think it’ll happen as frequently on an iPad as it does on an iPhone, but it is annyoying nonetheless. Also, it is not available (yet?) on the Mac.

One interesting thing about Spyder: it’s the first Arcade game to get a gameplay video on Apple’s YouTube channel.

«Never believe it’s not so»

Dr. Drang makes some good points on the stability of the new Magic Keyboard for iPad Pro.

Two scenarios which occur to me quite a lot with my notebook are using the device with it resting against my lap, tilted towards me when lying down; and carrying it with the lid open, holding the keyboard deck. The first one seems to be a non-issue according to this section of “How to correctly use a computer”, but still the ad only shows attaching the keyboard when it was already against your lap, which brings us to the yet-to-be-answered question of how stable it is when you’re carrying it around by holding just the keyboard deck, whether it’s from one room to another, or simply from your belly to your lap.

«How Fast Does a Virus Spread?»

Truly fascinating. Dr. Drang had a related article a few days ago.

(Speaking of whom, he also has a graph of COVID‑19 cases in the US, updated daily.)

«Some People»

“Ultimately though, we are all in this together.”

Audible: «Stories Help»

Stories entertain. They teach. They keep young minds engaged. And they bring us together.

That’s why, for as long as schools are closed, we will be open. Keeping to our founding belief that the spoken word can be inspiring and transporting in deeply intimate ways, we have created Stories.Audible.com—a place where anyone, in any country, can enjoy unlimited streaming of hundreds of titles for kids and families for free.

This isn’t just a good thing during the pandemic. It’s a wonderful thing in general. And this is the best part:

There’s no log in and no need to be an Audible member. Just visit Stories.Audible.com and start listening!

Done.

covid.observer

This website presents the very same data but from a less-panic perspective.

Interestingly it’s, much like this blog, powered by Raku.

Serif: «Our response to COVID‑19»

With all that’s going on right now due to the COVID‑19 pandemic and in response to the many stories we’re hearing from the creative community about how they’re being severely impacted, we felt it was our responsibility to try to offer as much support as possible during this incredibly difficult time.

That’s why we’ve put in place three new measures which we hope will help at least some of you out there. These are:

This is delightfully heart-warming. The whole announcement is written so humanly. I hope other companies will follow.

«How to correctly use a computer»

This has to be the best ad I’ve seen in a while. Clever and on point.

What is the point of this ad, though? It sure seems like Apple is out of its mind, dissing every “computer” — including the new MacBook Air that was announced on the very same day — and saying how the iPad Pro outperforms it and all that. Yes. And it makes total sense.

The whole theme of this ad is modern vs traditional computing. The iPad is clearly modern, and the Mac is clearly traditional, and there’s room for both. After all, this ad won’t change abyone’s mind about computers. A traditional user, i.e. a user who’s already voluntarily using a “computer”, will not be tempted to buy an iPad instead of a Mac (or whatever other computer). Where the iPad shines is (dare I say) modern computing, i.e. it targets non-traditional users.

Take the “treat your computer with respect” part of the video for example. I can’t imagine the person drawing on the iPad ever doing that either on or to a Mac. I can’t picture ’em doing that to a Cintiq, either. Both the iPad and the Mac are worthy of respect, sure, but iPad is the only one that doesn’t need it. Mac is scary, iPad isn’t.

Also, this ad never conveyed to me once that there’s anything wrong with a traditional computer. If anything, this ad tells me there are two correct ways to use a computer. I would buy the new MacBook Air even if all they advertised it with was a black screen saying “It runs BBEdit.” (Well, actually, I wouldn’t buy the new MacBook Air because I already have the old one and am writing on it right now — in BBEdit.) And maybe I would buy the new iPad Pro if it ran BBEdit, but that won’t make me a modern user. And that is the point of this ad: it’s not so much about the computer or even the user as it is about the use and the “how to”; and for the modern user, the iPad is more useful.

«iPad Pro Cursor with Craig Federighi»

Nice (for the most part).

Now that the iPad has proper mouse and trackpad support, wouldn’t it be great if you could also define your own keyboard shortcuts in, you know, Shortcuts? An automation trigger would do nicely.

I just did a grep /..oir/ and it brought me here.