The Perl weekly challenge has a new challenge with two parts every week. Moreover, this week hosts challenge 256, a round number. Let’s solve it in Uiua.
You can explore the solutions in a live Uiua pad. The pad also contain the tests shown in the problem statement. If pressing “Runs” displays nothing, it means that every test executed successfully.
But first be warned, the character set used in Uiua is… somewhat unusual.
The challenge description is:
You are given an array of distinct words,
@words
. Write a script to find the maximum pairs in the given array. The words$words[i]
and$words[j]
can be a pair one is reverse of the other.
In other words (ah ah), we have to find the number of words whose reverse representation is also present in the array and divide this by 2 (so that each word and its reverse representation is counted only once). From the examples, we can also understand that a word cannot be a reverse of itself (for example, “aa” is not to be counted).
Let’s create a word One
containing a possible solution.
One ← /+♭↧⊞<.⇡⧻⟜⊞≍⟜∵⇌
Does it work?
One {"aa" "ab" "cd" "dc" "efx" "ba"}
=> 2
Indeed, “ab” and “ba” form a pair, “cd” and “dc” form another one, “aa” is ignored, and “efx” has no counterpart.
Let’s analyze the One
function. In Uiua, execution starts from the right. ⇌
means reverse, and ∵
is the each modifier. So ∵⇌
will apply reverse on each element of the array at the top of the stack.
∵⇌ {"aa" "ab" "cd" "dc" "efx" "ba"}
=> {"aa" "ba" "dc" "cd" "xfe" "ab"}
⟜
is the on
modifier, new in Uiua 0.9.0. It preserves the element at the top of the stack by restoring it after it has executed its argument. So ⟜∵⇌
will consume the array at the top of the stack and let two element on the stack: the original array at the top, and the array with reverse words below it.
By calling the ⊞
table modifier on the ≍
match function, a matrix will be built by applying the ≍
function to every pair made of an argument of the first array and an argument of a second array (think of a cartesian product with the ≍
function). ≍
returns 1 if two arrays are equivalent (same shape and same content, or same strings) and 0 otherwise.
In our case, the matrix looks like that:
⊞≍⟜∵⇌ {"aa" "ab" "cd" "dc" "efx" "ba"}
=>
╭─
╷ 1 0 0 0 0 0
0 0 0 0 0 1
0 0 0 1 0 0
0 0 1 0 0 0
0 0 0 0 0 0
0 1 0 0 0 0
╯
The first one is at index [0 0]
and corresponds to “aa” matching itself when reversed. The second one is at index [1 5]
: “ab” matches “ba”. Of course, we also have a 1 at index [5 1]
, since “ba” matches “ab”.
Our matrix is symetrical. Since we do not want to count every pair twice, we have to keep only one half of the matrix. Also, since we do not want words to match themselves when reversed, such as “aa”, we will exclude the diagonal. Filling a square matrix with 1 under the diagonal and 0 everywhere else is easy by using the ⊞
table modifier on the <
lower than operator:
⊞< [0 1 2] [0 1 2]
=>
╭─
╷ 0 0 0
1 0 0
1 1 0
╯
We can produce the two [0 1 2]
arrays by using the ⇡
range function followed by the .
duplicate function:
⊞<.⇡3
=>
╭─
╷ 0 0 0
1 0 0
1 1 0
╯
Since we do not know the size of the words list in advance, we will use the ⧻
length function on the words list. We will ensure we still have it by prefixing the ⊞≍
table match by ⟜
on:
⊞<.⇡⧻⟜⊞≍⟜∵⇌ {"aa" "ab" "cd" "dc" "efx" "ba"}
=>
╭─
╷ 1 0 0 0 0 0
0 0 0 0 0 1
0 0 0 1 0 0
0 0 1 0 0 0
0 0 0 0 0 0
0 1 0 0 0 0
╯
╭─
╷ 0 0 0 0 0 0
1 0 0 0 0 0
1 1 0 0 0 0
1 1 1 0 0 0
1 1 1 1 0 0
1 1 1 1 1 0
╯
Note that the top of the stack is represented… at the bottom. Now, by using the ↧
minimum operator, we can force elements of the first matrix to be kept only if the second matrix contains a one. This will eliminate any entry not located under the diagonal:
↧⊞<.⇡⧻⟜⊞≍⟜∵⇌ {"aa" "ab" "cd" "dc" "efx" "ba"}
=>
╭─
╷ 0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 1 0 0 0
0 0 0 0 0 0
0 1 0 0 0 0
╯
This matrix can be transformed into a flat array using the ♭
deshape function. Then the ones and zeroes can be all added together by using the +
add function, prefixed by the /
reduce modifier which applies its function argument between the values of the flat array. As a consequence, the resut here is 2, as expected.
The second part of the challenge is:
Write a script to merge the given strings by adding in alternative order starting with the first string. If a string is longer than the other then append the remaining at the end.
For example, merging “abc” and “12345” should give “a1b2c345”, while merging “abcde” and “123” would yield “a1b2c3de”.
An incorrect solution would be
Two ← ▽≠@\0.♭⍉⬚@\0⊟
and appears to work:
Two "abc" "12345"
=> "a1b2c345"
This solution works by putting both strings in an array by using the ⊟
couple function, modified by ⬚@\0
set fill character to NUL. It means that strings will be completed by NUL characters (@\0
in Uiua) so that they have the same length, in order to put them in one array:
⬚@\0⊟ "abc" "12345"
=>
╭─
╷ "abc\0\0"
"12345"
╯
We can then ⍉
transpose this array
⍉⬚@\0⊟ "abc" "12345"
=>
╭─
╷ "a1"
"b2"
"c3"
"\04"
"\05"
╯
then ♭
deshape it as a flat array
♭⍉⬚@\0⊟ "abc" "12345"
=> "a1b2c3\04\05"
NUL characters @\0
can be reverse-identified ≠
in a copy .
of the array
≠@\0.♭⍉⬚@\0⊟ "abc" "12345"
=>
"a1b2c3\04\05"
[1 1 1 1 1 1 0 1 0 1]
Using ▽
keep only keep the non-NUL, identified by a 1:
▽≠@\0.♭⍉⬚@\0⊟ "abc" "12345"
=> "a1b2c345"
However, this solution is incorrect: nothing in the problem statement indicates that NUL cannot be contained in the input strings. Since we have no reserved character, we cannot use this technique without risking having a bug.
A longer but correct solution is:
Two ← ⊂⊂♭⍉⊟⊃(↙|↙⊙◌|↘|↘⊙◌)↧∩⧻,,
It seems to work:
Two "abc" "12345"
=> "a1b2c345"
The ,
over function copies the second element from the top of the stack to the top. Using ,,
over over duplicates the two top elements.
The ∩
both modifier applied to ⧻
length replaces the top two elements of the stack by their respective lengths, whose minimum is computed by ↧
minimum:
↧∩⧻,, "abc" "12345"
=>
"12345"
"abc"
3
(don’t forget that the top of the stack is shown at the bottom)
We will now use the ⊃
fork modifier to call four functions with the same view of the stack. All used arguments will be removed from the stack, and the results will be pushed from right to left:
↘⊙◌
means ↘
drop followed by dip pop: dip pop is a planet manipulation, which retains the first and third argument on the stack, on which we apply drop to remove some elements from an array. In other words, if the stack contains 3 "abc" "12345"
(3 being at the top of the stack), we replace if with "45"
which is "12345"
with 3 elements dropped.↘
drop with the same 3 "abc"
stack (it only uses two elements) returns ""
, since "abc"
only has 3 elements↙
take is the oposite of ↘
drop and keeps the first elements in an array. ↙⊙◌ 3 "abc" "12345"
will return “123”↙ 3 "abc"
will return "abc"
Using those four functions with the ⊃
fork modifier yields:
⊃(↙|↙⊙◌|↘|↘⊙◌) 3 "abc" "12345"
=>
"45"
""
"123"
"abc"
On the stack, starting from the top, we know have two strings with identical length that we must mix, "abc"
and "123"
, followed by two strings, one being empty, that must be concatenated to the mixed string to get the result.
Note that since the length we use is the minimum of the two strings length, we know that:
↙
take and ↘
drop will always succeed since the given index never exceeds the string length.↙
take will return strings of the same length, which can be easily put together in a matrix without requiring a fill character to make the lengths match since they are equal.↘
drop will be empty.By combining and mixing our two strings as we did in the first attempt using ♭⍉⊟
deshape transpose couple, that is couple then transpose then deshape, we just have to use ⊂
join twice to combine all three strings:
⊂⊂♭⍉⊟ "abc" "123" "" "45"
=> "a1b2c345"
and that’s it. Now, our strings can contain all possible unicode characters and our solution will work.
]]>Sabqponm
abcryxxl
accszExk
acctuvwj
abdefghi
In the first part, you must go from S
to E
with the shortest number of steps. You can only go from a letter (e.g., t
)
to the next in the alphabet (u
), or to a letter that comes sooner in the alphabet (e.g., a
, d
or m
). The starting point S
counts
as a
, and the ending point E
counts as z
. The second part is identical, except that you may start either from S
or from any a
place,
whichever gives the shortest path to E
.
Of course this was an ideal problem for my pathfinding
library, as it features both a convenient Matrix
type
to hold the map, and pathfinding algorithms such as breadth-first search (BFS). I ended up writing the following code:
use pathfinding::prelude::{bfs, Matrix};
fn parse(input: &str) -> (Matrix<u8>, (usize, usize), (usize, usize)) {
let mut m = Matrix::from_rows(input.lines().map(str::bytes)).unwrap();
let s = m.indices().find(|p| m[*p] == b'S').unwrap();
let e = m.indices().find(|p| m[*p] == b'E').unwrap();
m[s] = b'a';
m[e] = b'z';
(m, s, e)
}
fn part1(input: &str) -> usize {
let (m, s, e) = &parse(input);
bfs(
s,
|&p| m.neighbours(p, false).filter(move |&q| m[q] <= m[p] + 1),
|&p| p == *e,
)
.unwrap()
.len()
- 1
}
fn part2(input: &str) -> usize {
let (m, _, e) = &parse(input);
bfs(
e,
|&p| m.neighbours(p, false).filter(move |&q| m[p] <= m[q] + 1),
|&p| m[p] == b'a',
)
.unwrap()
.len()
- 1
}
The interesting line here is
let (m, s, e) = &parse(input);
which can trigger the following questions to the less-experienced Rust user:
&parse(input)
to a tuple (m, s, e)
?parse(input)
not destroyed at the end of the statement? How come the reference stays alive?In Rust, assignment with let
uses irrefutable pattern-matching. As long as the types match, Rust will accept the assignment to the free variables present in the pattern.
For example, the following code will match, as a couple always matches a couple, and it will assign 10 to a
and 20 to b
:
let (a, b) = (10, 20);
This following code does not compile though, because Some(x)
doesn’t cover all cases of the type Option<i32>
of the expression (even though the compiler could know that only the Some
variant is used):
let Some(x) = Some(42);
| let Some(x) = Some(42);
| ^^^^^^^ pattern `None` not covered
When the expression being matched against is a reference (such as in &parse(input)
), Rust separates the patterns in two categories:
&
, a constant, a wildcard _
.struct
name, an enum
or union
variant, a tuple, an array. Those are called non-reference patterns.Our pattern (m, s, e)
belongs to the non-reference pattern category. The Rust compiler will attempt to modify the pattern so that it can match by prepending &
in front of it, and adding a ref
before all free variables which are not preceded by ref
already (for mutable references, ref mut
is added instead). In our case, it means that our assignment
let (m, s, e) = &parse(input);
will be rewritten as:
let &(ref m, ref s, ref e) = &parse(input);
Recall what using ref
in front of a variable does in a pattern: the pattern will match as usual, but the variable will be bound to a reference on the part it matches instead of to the part itself. Since parse(input)
returns a (Matrix<u8>, (usize, usize), (usize, usize))
, the variables will be of the following types:
m
will have type &Matrix<u8>
s
and e
will have type &(usize, usize)
The rules for dropping objects indicate that a temporary value created in a statement will be destroyed at the end of the statement. For example, the following code will not compile:
use std::ops::Deref;
fn main() {
let s: &str = String::from("foobar").deref();
println!("s = {s}");
}
| let s: &str = String::from("foobar").deref();
| ^^^^^^^^^^^^^^^^^^^^^^ temporary value is freed at the end of this statement
| |
| creates a temporary value which is freed while still in use
| println!("s = {s}");
| - borrow later used here
because the temporary value returned by String::from("foobar")
is destroyed at the end of the statement. .deref()
returns a &str
reference whose lifetime cannot be larger than the temporary string itself and cannot be stored in s
to be used later.
However, the following code will compile and run just fine:
fn main() {
let s: &str = &String::from("foobar");
println!("s = {s}");
}
although to convert from String
to &str
the same function .deref()
as above is called implicitly by the compiler. Why is that?
The temporary object created by String::from("foobar")
is subject to a temporary lifetime extension. In a let
statement, the lifetime of a temporary object whose reference is taken directly (with &
or through a ref
binding) is extended to match the lifetime of the variable in which the reference is stored. Tuples components (as well as struct
, …) may benefit from an extended lifetime as well. This is not the case if the reference is created only to call a method: in this case, the temporary object and the reference lifetimes will not be extended.
In our case,
let (m, s, e) = &parse(input);
the lifetime of the references created to store in m
, s
, and e
and of the references temporary values are extended to be respectively the same as those of the m
, s
, and e
variables.
Originally, I intended on writing this:
let (m, s, e) = parse(input);
which uses no references at all. However, the move
in the following expression is necessary in order to capture the p
local variable in the filter()
anonymous function:
bfs(,
s|&p| m.neighbours(p, false).filter(move |&q| m[q] <= m[p] + 1),
|&p| p == *e,
)
Rust does not offer a way of selectively capturing variables. By writing move
in front of the anonymous function, it forces the compiler to capture (or copy if the variable implements the Copy
trait) all variables appearing in the function. As Matrix<_>
does not implement Copy
(copying a large matrix can be expensive), the whole matrix m
would be captured in addition to p
. This is not good as we need to keep the matrix around, and we do not want to clone it at every step of the algorithm.
In order for the anonymous function not to capture the matrix itself, I wanted m
to be a reference to the matrix: an immutable reference implements Copy
, which means that the anonymous function will receive a copy of the reference to the matrix and will not capture the matrix itself, which is why without further thinking I added a &
to the initialization expression, knowing what would happen.
Could I have done differently? Of course, instead of using a non-reference pattern and a temporary lifetime extension I could have used the simpler statement (but this is not the first idea that popped in my head):
let (ref m, s, e) = parse(input);
In this case, m
would be having type &Matrix<u8>
as expected, and s
and e
would be having type (usize, usize)
(without a reference).
But if I had done this, I could not have written this blog post (the first real one in more than 5 years) then, which touches on topics I teach to my graduate students.
The research team of Autonomous and Critical Embedded Systems of Telecom ParisTech is looking for a tenured Associate Professor (Maître de Conference, permanent position) in the area of concurrent and distributed systems. The candidate is expected to strengthen the research force of the school by contributing to ongoing and future projects related to fundamentals and systems aspects of distributed computing. A specific focus will be given to investigations on the power and limitations of blockchain-like systems. To ensure smooth integration into the research program of ACES and Telecom ParisTech, it is desired for the candidate to share interests in one or more of the following areas: system verification, security, embedded systems, autonomic systems, Internet of Things.
The candidate is also expected to join the teaching curriculum of the department of Computer Science of Telecom ParisTech on a variety of subjects in computer science, with a specialization on distributed systems (modeling, design, programming, analysis, …), set up new courses and educational tools on emerging disciplines.
Send files by electronic mail to recrutement@telecom-paristech.fr or postal mail to Télécom ParisTech - DRH - B659 - 46 rue Barrault - 75634 Paris Cedex 13
16th of March, 2018
For more details (in French): follow this link
]]>Le paquet french-numbers permet de choisir entre les formes féminine (vingt-et-une) et masculine (vingt-et-un), ainsi qu’entre l’orthographe pré-réforme de 1990 (dans laquelle les tirets ne se placent qu’entre les termes représentant des nombres inférieurs à cent : vingt-deux mille trente-trois) et celle post-réforme (vingt-deux-mille-trente-trois).
Afin d’automatiser les tests, j’ai cherché en vain des fichiers contenant sous un format exploitable une longue liste de nombres pour pouvoir la comparer avec la sortie de ces fonctions. Afin de faciliter la vie pour ceux qui passeront après moi, voici en fichier texte :
french-number --prefix 0 9999
) ;french-number --prefix --no-reform 0 9999
).L’utilitaire french-number
est livré en exemple avec le paquet french-numbers
pour Rust.
Si vous trouvez une erreur, merci de me la signaler.
]]>Ma dernière aventure date de samedi dernier. Pour me rendre à un dîner dans le 3è arrondissement, je choisis de prendre une Autolib et réserve une place à l’arrivée. La voiture qui m’est attribuée est une Utilib, version utilitaire de l’Autolib, et le trajet se passe sans encombres jusqu’à la station d’arrivée en un peu moins de 30 minutes. Mais une fois à la station où la place a été réservée, une mauvaise surprise m’attend : aucune place n’est disponible malgré la confirmation de la réservation sur l’ordinateur de bord de la voiture. J’appelle donc le service clients d’Autolib, qui m’indique qu’il y a une anomalie sur la station concernée, qu’aucune autre place Autolib n’est disponible dans les environs, et qu’ils m’autorisent à me garer « sur une place de stationnement légale qui doit être à proximité de la station ». Comme si, après avoir fait un trajet en Autolib, j’avais envie de m’éloigner de mon point d’arrivée et de refaire le trajet à pied en sens inverse.
Après avoir tourné dans le quartier, force est de constater que trouver une place autorisée dans le 3è arrondissement un samedi soir à 21h00 est quasiment impossible en un temps raisonnable. Voyant à proximité le parking payant Étienne Marcel, je réussis à entrer à nouveau en communication avec le service clients (après deux tentatives infructueuses lors desquelles les conseillers Autolib ne m’entendaient pas). Après avoir confirmé qu’il n’y avait toujours pas de place disponible Autolib à proximité, ni de station Autolib en maintenance sur laquelle j’aurais pu être autorisé à me garer, le conseiller refuse ma demande de pouvoir garer la voiture dans le parking public sous prétexte qu’il y a une barrière (c’est le principe de tout parking payant, j’aurais pu laisser le ticket dans la voiture et Autolib aurait pu prendre en charge les quelques euros de frais de stationnement étant donné que le problème initial vient d’une anomalie, confirmée, de la station à laquelle j’avais réservé une place).
Le conseiller clientèle Autolib m’informe alors que des places viennent de se libérer dans une autre station de l’arrondissement et m’invite à m’y rendre. Il m’informe que pour palier mon désagrément un geste commercial de 15 minutes gratuites sera « demandé » sur une prochaine location d’Autolib.
D’un naturel prudent, je vérifie quand-même que la facturation de ma location en cours s’arrêterait bien à partir du moment où le service clients m’avait demandé de tourner dans le quartier pour trouver une place suite au dysfonctionnement de leur station. À ce moment, le conseiller m’annonce que non, que ma location en cours continuait à tourner et que j’en serai facturé de l’intégralité. Lorsque je lui annonce que cela fait déjà plus de 15 minutes que je tourne, à leur demande, pour pouvoir garer la voiture, il me répond qu’il ne peut rien y faire, qu’il ne peut pas demander plus que les 15 minutes de geste commercial (je m’attendais a minima à un remboursement). Il faut, d’après lui, que je fasse une réclamation à travers le site d’Autolib, alors qu’ils disposent déjà de la totalité des informations nécessaires pour traiter cette anomalie.
Pour résumer :
Finalement, un trajet en Uber m’aurait coûté moins cher et aurait pris la moitié du temps. Au moment où Autolib m’indique que mon contrat arrive bientôt à échéance et me propose de le renouveller ou non, cet incident ne me donne pas très envie de continuer avec eux. Que se passera-t-il en cas de problème plus important ? Suis-je le seul à avoir des problèmes avec leur manière de traiter les incidents dus à une anomalie de leur système ?
]]>In order to allow my readers to privately use my site, I chose to equip it with a StartSSL one-year free certificate. To make it relatively safe against NSA and other agencies eavesdropping, I opted for a 4096 bit key size… except that my FFS (fat-finger syndrome) kicked in when I generated the certificate signature request, and my certificate has a 4906 bit [sic!] key size.
Because the key size is larger than 4096 bits or because it is not a power of two or a multiple of 512 bits, Chrome on OSX warns users that their connection may have been hijacked (thanks to Yann Pujante for the screenshot):
So, to summarize, a non-standard certificate size on my side makes OSX think that something fishy is happening: it does not flag the certificate as invalid, nor as unrecognized, but assumes that the connection to the server is being intercepted.
Some users have also attempted to access my secure website using Safari. One of them told me that the browser crashed, and another one that it displayed only a blank page. However, Firefox on OSX, which uses its own certificate validation, works just fine. As do other browsers, including Chrome, on GNU/Linux or Windows operating systems.
So it looks like the problem lies on Apple’s side. I attempted to renew my free certificate from StartSSL to make it more standard, but I have to wait until the previous one expires or to pay revocation fees. So unless an Apple user pays to get me a 4096 bit one-year SSL certificate (certificate signing request available on demand), they will have to wait for this one to be renewed in late August or for Apple to accept various or more secure keys. Which one will happen first?
And Google, you should also fix Chrome by not using OSX system libraries for certificate verification.
]]>Bitcoins can be regarded as cash, i.e. bills and coins. They can be mixed together, split into parts, and they can be rendered pretty untraceable if you wish so by mixing them into laundering pools or by never mixing them as if you had several cash wallets. As with cash, you get one major problem: crooks may try to fool you into accepting bitcoins that will later prove worthless, as they may try to fool you into accepting counterfeited money.
The bitcoin network, also called the blockchain, or transaction log, is in fact acting as a “validator” for a transaction. When a transaction is included in the blockchain, it means that other bitcoin participants will regard it as valid, and that its recipient will be able to spend the bitcoins in further transactions. A new block is added to the blockchain every 10 minutes in average. As bitcoin operates mostly on a computing power basis, it is deemed safer to wait until a few more blocks are produced on top of the block containing a given transaction to consider it irrevocable, as it is unlikely that anyone will get enough computing power by themselves to revert this chain of trust.
Similarly, money in your wallet is only worth something if a merchant or a bank accepts it as valid. As long as you keep it by yourself, you may not be 100% sure that you do not own counterfeited bills and coins that you will not be able to convert into goods, services or other currencies.
Does that mean that instant payments are impossible with bitcoins? Certainly not, there are several schemes that let you accept instant payments without using instant transfers, the same way that when you pay with a debit or credit card, the merchant does not receive the money immediately on its bank account but delivers the goods anyway.
As the recipient of a bitcoin transaction, if only small amounts are involved, you may want to trust the sender as soon as you get the transaction. You may want to check that it has been broadcast to major sites such as blockchain.info, and that no double-spend (i.e., another use of the same money) has been spotted. There is a good chance that the transaction will be included in a later block as those hubs are usually well connected to miners.
Another alternative is to let a third-party take the risk. Such an entity is called a bank. If the sender and the receiver both have an account at the same bank, and the bank is the sole holder of the bitcoins (by owning the corresponding private keys necessary to spend them), it can do an immediate transfer from one account to another, as it knows that no other transaction will contain the same bitcoins.
Note that it is enough for the recipient to trust the sender’s bank. In this case, the transaction would be similar to a cashier’s check, on which the bank signature guarantees that the given amount will eventually be paid. As with a cashier’s check, you will need a way to ensure that the bank is the true originator of the transaction. That may be done by signing a copy of the transaction with GnuPG for example, or by using a trusted bitcoin address as the sender side of the transaction.
If you dislike or distrust banks, or if you came to bitcoins precisely to avoid the need for banks, note that other schemes exist while others are still to be invented. For example, a third-party entity could contract with merchants and guarantee that the amount going through them will be payed even if the transaction proves not to be confirmed, in exchange for a fee. It would work like a fully automated insurance company, that would for example only wait for the transaction to be broadcast widely enough before confirming the payment (a few seconds). In exchange, they will themselves broadcast immediately a similar transaction (minus a fee) from a trusted bitcoin address and the merchant will accept it immediately. If the amount is over a predefined limit, the insurance company could wait for one confirmation before broadcasting the trusted transaction.
As one can see, bitcoin is largely similar to cash. The blockchain is built by all the participants (miners create new blocks, others validate them) and acts as a distributed giant counterfeited money detector. As in real life, individuals and business take a risk when they accept cash without putting it through such a detector first. The bitcoin system is similar: you need extra work, or extra time, to ensure that the money you receive is genuine. If you do not want to wait, someone has to take the risk, and this is likely to cost some money.
]]>Bitcoin Central, a service by Paymium, has stopped all operations because their hosting provider OVH suffered from a fatal flaw in their password reset procedure that lead to the compromission of the Bitcoin Central servers. Fortunately, they had been cautious enough not to keep a lot of bitcoins in their online wallet, and only suffered the loss of a few hundredth bitcoins that they will cover with their own funds. They will restart their operations on a more secure infrastructure in the future, but in the meantime the service has been stopped. Instawire, an instant deposit service also by Paymium, had been stopped a few weeks earlier already.
Bitcoin-24 is no longer available either because the Polish and German authorities has locked their bank accounts in Poland and in Germany. They are currently pursuing legal ways to unlock those accounts which contain user funds.
Bitmarket.eu was suffering from a lack of manpower and decided to shut down the site and to stop trading. They aim at being replaced by Bitalo, an unknown service whose gates are still closed.
#bitcoin-otc and LocalBitcoins seem to be the only survivors from the list of exchange platforms I surveyed nine months ago, although LocalBitcoins introduced trade fees since then. Those two systems have one thing in common: they put two persons in touch, instead of acting as a middleman in an automated currency trading system.
It looks like the events are forcing bitcoin to be what it was designed for: a peer-to-peer way of circulating wealth.
]]>When you develop an embedded system, those two choices still hold when you need to put a thread to sleep:
Most real-time operating systems provide the programmer with two options to put a thread to sleep. The first one typically takes a number of system ticks during which the thread will stay asleep. It will then be woken up after the given time. In ChibiOS/RT, this is done with:
(delayInSystemTicks); chThdSleep
The second option takes an absolute date at which the thread should be woken up. Again, in ChibiOS/RT, a function allows the programmer to do that:
(futureDate); chThdSleepUntil
If you want to run a doSomething()
function every 12 milliseconds, with a system tick being configured as 1 millisecond, you could want to write:
for (;;) {
();
doSomething(12);
chThdSleep}
but this would be improper, as you wait for 12 milliseconds between the end of the previous doSomething()
call and the beginning of the next one. If, from time to time, doSomething()
gets preempted by a high-priority task or an interrupt routine and takes a few milliseconds to run, you will slowly accumulate the drift.
A more proper way of writing it is to use absolute delays, as in:
= chTimeGetNow();
systime_t time for (;;) {
();
doSomething+= 12;
time (time);
chThdSleepUntil}
chTimeGetNow()
returns the initial date at which we execute the first doSomething()
call, and will use this basis and add 12 milliseconds at a time to this initial date. Even if sometimes doSomething()
takes 5 milliseconds to run, then the subsequent chThdSleepUntil()
will sleep for only 7 milliseconds instead of 12. No drift will ever get accumulated.
However, there is a caveat. What if, in your soft real-time system, where some deadlines can occasionally be missed, doSomething()
takes more than 12 milliseconds to execute?
Embedded systems are usually designed to run forever, or at least for long enough so that the internal variable used to represent the number of elapsed system ticks will wrap around 0 and restart from its lowest value. For example, if an unsigned 32 bits variable is used to represent the number of milliseconds elapsed since the system start time, then before 50 days it will start from 0 again because the highest representable value (231 − 1) will have been reached.
Let’s assume that doSomething()
was last executed at time = t0. The current time is now t0 + 15, and we ask the system to wait until t0 + 12. That is in the past, so no sleeping should occur, right? Wrong, for ChibiOS/RT, this represents the future, as this value will be reached in about 49.7 days. Which means that you will not execute doSomething()
for more than seven weeks just because your 12 milliseconds deadline has been missed by 3 milliseconds.
The author of ChibiOS/RT has ackowledged this issue and even included an article into the knowledge base. However, in his view, this function should only be used on hard real-time systems where deadlines will be met inconditionally. This is a perfectly reasonable position, and on some systems with 16 bits time counters, trying to guess if the user meant a past time rather than a future time would cut the maximum resolution in half and only let a maximum timespan of about 32 seconds.
Another operating system, FreeRTOS, uses a clever way of dealing with those situations by adding another parameter to the sleeping function representing the latest wakeup time. This way, by comparing three time values (the current time, the latest wakeup time and the latest wakeup time + the expected delay cycle), the system is able to determine whether the next wakeup time has been reached already (in which case it does not sleep), or if sleeping is still needed. As long as the time spent since the next wakeup is smaller than a full timer cycle (49.7 days for 32 bits, 65.5 seconds for 16 bits, all that with a milliseconds system tick), the result will be non-ambiguous.
The following snippet allows you to use a similar functionality in ChibiOS/RT:
void sleepUntil(systime_t *previous, systime_t period)
{
= *previous + period;
systime_t future ();
chSysLock= chTimeNow();
systime_t now int mustDelay = now < *previous ?
(now < future && future < *previous) :
(now < future || future < *previous);
if (mustDelay)
(future - now);
chThdSleepS();
chSysUnlock*previous = future;
}
Like its FreeRTOS counterpart vTaskDelayUntil()
, it takes care of incrementing the variable pointed onto by the previous
parameter by the number of system ticks given in period
. The logic to know if we have to sleep (captured in the mustDelay
assignment) is the following:
If the current time (now
) is smaller than the previous wakeup, it means that the time counter has wrapped around 0. In this case, we have to sleep if the future wakeup time is smaller than the previous one (otherwise, it means that the future value has not wrapped around 0 and has been passed by the current time) and if it is greater than the current time (otherwise, it means that the future value has wrapped around 0 as well but is still behind the current time).
If the current time is greater or equal than the previous wakeup, we have to sleep either if the future wakeup time is after the current time, or if the future wakeup time is before the previous time, meaning that the future wakeup time computation has wrapped around 0 while the current time still hasn’t.
This way, we get a safer, easier to use function which allows for occasional missed deadlines in a soft real-time system:
= chTimeGetNow();
systime_t time for (;;) {
();
doSomething(&time, 12);
sleepUntil}
/dev/ttyUSB0
(or 1, or n) and others/dev/ttyACM0
(or 1,
or n) when they are plugged into the host computer, while they seem to be acting as UART devices
(RS-232-like) over USB in both
cases? Have you wondered why example USB firmwares for
microcontrollers always end up with names such as /dev/ttyACM0
and never
as /dev/ttyUSB0
?
Warning: this is a Linux specific post, although it also contains genuine pieces of USB culture.
ttyACM
mean?The USB implementors forum organization has described how devices conforming to the Communications Device Class (CDC) should present themselves to the USB host. The USB implementors forum also specified how CDC subclasses should act, including for those devices intended to talk with each other over the public switched telephone network (PSTN). Those are known as modems because the data goes through a modulation operation on the sending side, which transforms the bits into analog signals that can be carried over phone wires, and then through a demodulation operation on the receiving side to convert the analog signal back into the original bits.
To discuss with the modem, the host USB driver must use one of the existing control models. For example, the direct line control model controls how data is exchanged between the host and the modem through an audio class interface, with the host taking charge of the modulation, demodulation, data compression (such as V.42bis) and error correction (such as V.42). This model is used by some USB soft modems, which are very cheap because they mostly contain a DSP chip and some amplification and line adaptation layers.
Another control model, aptly named abstract control model or ACM, lets the modem hardware perform the analog functions, and require that it supports the ITU V.250 (also known as Hayes in its former life) command set, either in the data stream or as a separate control stream through the communication class interface. When the commands are multiplexed with the data in the data stream, an escape sequence such as Hayes 302 (also known as “1 sec +++ 1 sec”) or TIES (that nobody remembers) must allow the host to put the modem into command mode.
When developping on a USB-enabled embedded microcontroller that needs
to exchange data with a computer over USB, it is tempting to use a
standardized way of communication which is well supported by virtually
every operating system. This is why most people choose to
implement CDC/PSTN with ACM (did you notice that the Linux kernel
driver for /dev/ttyACM0
is named cdc_acm
?) because it is the
simplest way to exchange raw data.
But what about the mandatory V.250 command set? It is almost never
implemented in such devices, but since the host has no reason to
spontaneously generate V.250 commands by itself, the device will never
have to answer them. Pretending the embedded device is a modem is the
simplest way to communicate with it, even though it will probably never
perform any modulation or demodulation task. Linux will not know that
the device is lying, and will have it show up as /dev/ttyS0
.
ttyUSB
mean?Sometimes, the embedded microcontroller does not come with a hardware USB interface. While it is possible to use a software-only USB stack, the additional constraints put onto the CPU and the usually small storage size often lead board designers to include a dedicated UART to USB bridge. Several vendors, such as FTDI or Prolific sell dedicated chips for a few euros.
Those vendors opted not to lie to the host computer in having the chips announce themselves as USB modems when they were not. Each vendor defined its own (usually proprietary) protocols, with commands allowing to control functions of the chips such as setting the baud rate or controlling additional signals used to implement hardware flow control.
When it is practical to do so, Linux groups devices with similar
functionalities under the same default device or interface names. For
example, the UARTs present on your computer (if any) will be named
/dev/ttyS0
and /dev/ttyS1
even if one of them is a legacy 16550 chip and the other one is a MAX3100 SPI-controlled UART.
Similarly, the devices offering UART-over-USB functionalities are named /dev/ttyUSB0
, /dev/ttyUSB1
, and so on, even though they are in fact using distinct device drivers.
So, when you see a /dev/ttyACM0
popping up, you can try to send it the escape sequence followed by AT commands, but there is a good chance that the device only pretends to be a modem and will happily send those characters to the core application without even considering intercepting them. If it is a /dev/ttyS0
, do not try, unless the device behind the USB-UART bridge understands those command by itself (this is the case for the XBee chip).