I’ve been doing the Weekly
Challenges. The
latest
involved . (Note that this ends today.)
Task 1: Second Largest Digit
You are given an alphanumeric string.
Write a script to find the second largest distinct digit in the
given string. Return -1 if none found.
So: find the digits, make a list of distinct ones, return the second
largest. In Perl:
sub secondlargestdigit($a) {
Split the string, find the digits, and put them into a pseudo-set.
my %p = map {$_ => 1} grep /[0-9]/, split '', $a;
Sort the entries of that pseudo-set in descending order.
my @k = reverse sort keys %p;
If we have enough of them, return the second, otherwise -1.
if (scalar @k > 1) {
$k[1];
} else {
-1;
}
}
PostScript is pleasingly straightforward (though it relies on some of
my library functions).
/secondlargestdigit {
Get a list.
s2a
Filter it for digits.
{
dup 48 ge exch 57 le and
} filter
Take just the unique digits.
toset keys
Sort in reverse order.
quicksort reverse
If it's long enough, return the value of the second digit, otherwise
-1.
dup length 1 gt {
1 get 48 sub
} {
pop -1
} ifelse
} bind def
Task 2: Sum of Words
You are given three strings consisting of lower case English letters
"a" to "j" only. The letter value of a = 0, b = 1, c = 3, etc.
Write a script to find if sum of first two strings return the third
string.
The examples of leading "a" (i.e. leading zero) make it clear that
there are multiple allowable representations of any given number.
Therefore I write only one direction of conversion, from this
representation to an integer, and then compare integer values.
In Lua:
function l2n(a)
Establish a reference value for "a".
local a0 = string.byte("a")
Initialise the accumulator.
local t = 0
For each "digit",
for _, c in ipairs(split(a)) do
Multiply the previous accumulator value by 10, and add the new digit's
value.
t = t * 10 + string.byte(c) - a0
end
return t
end
Then the target function becomes trivial:
function sumofwords(a, b, c)
return l2n(a) + l2n(b) == l2n(c)
end
Again I find the PostScript pleasing (and I'm always glad not to have
to use local variables).
/l2n {
Put a zero accumulator on the stack below the input string.
0 exch
For each character of that string,
s2a {
Swap with the accumulator, multiply it by 10, then add character and
subtract "a" (PostScript only works in ASCII as far as I know,
certainly on any system I have access to),
exch
10 mul
add
97 sub
} forall
} bind def
Then it's just a matter of converting all the inputs and checking for
equality.
/sumofwords {
3 1 roll
l2n exch
l2n exch
add
exch
l2n eq
} bind def
Full code on
codeberg.
- Posted by Andrew at
11:22am on
24 June 2026
I have a background in desktop publishing, so I have always wanted to learn PostScript. It's great that you know it! I've always thought of it in terms of placing text and graphics on a page, so it's cool it can do filtering and reverse sorts. Unless these are your library functions? ^^. I know too little about the language to know. I only know it uses a stack, and that's all I know about it, ^^. There are plenty of tools for turning PostScript into PDF, so I've always wished I knew enough about postscript to use Perl to create custom documents to PDF. For now, I assume I can tweak existing PDFs to update or customise their content, using modules such as PDF::Data, but yes - I'd certainly love to dynamically generate postscript and then send the postscript to a PDF printer, =).
Where/When/How did you learn PostScript?
Would be fascinated to know!
Yours,
Andrew M
- Posted by RogerBW at
04:33pm on
24 June 2026
A side note first: PDF::API2 is my universal tool for furkling with PDF files.
As for PostScript: my libraries are at codeberg and, indeed, map/filter and quicksort are things I've added there (one of the things I like about it is how easy it is simply to define new functions that become first class in terms of what one can do with them). How I got started, though… I'm short of blog posts in the stack, so I'll write that up as a separate post and it'll go up in a few days.
- Posted by Andrew at
06:44pm on
24 June 2026
Cool! And yes, I did click through to your codeberg, when I noticed your original link at the end of the article, =).
A quick google reveals there are different coloured PostScript books, and in addition, someone has made a PDF guide too...so there seem to be a few entry points.
What of Adobe's modern use of PDF both in place of postscript and Encapsulated PostScript? Perhaps I should straight up be learning PDF instead of PostScript these days, if interested in programming magazine layout automations? ^_^.
Thanks for the PDF::API2 tip! =). A google earlier, threw up both that and PDF::Builder which is apparently based off of PDF::API2...!?
Am always learning, so there's tonnes I don't know, ^_^. It's great to hear you vouch for PDF::API2 ...!
I had learned of PDF::Data via a Perl Conference talk I saw on Youtube from a few years back (from the 2024 event), ^_^. https://www.youtube.com/watch?v=fzEWyELP5hI
Anyway - I look forwards to the blog post in a few days, =D.
- Posted by RogerBW at
06:59pm on
24 June 2026
This is in the blog post I've just been writing, but I started with the Red Book (PDF linked from the PostScript Wikipedia page) and a specific thing I was trying to achieve. That's the approach that generally works for me learning a new thing. If I had the same problem now I'd probably just generate the PDF directly with PDF::API2; to a first approximation, everyone has a PDF viewer already, while they don't have GhostScript.
On the other hand, having read the PDF standard, it's clear to me that in the transition from PostScript it was deliberately stripped of anything that might make it a programming language.
And, as I've written elseblog, my standard approach to generating a PDF with serious layout is now Typst.