The Ordinal Sparkline
Tags: perl, python, theweeklychallenge
Published: 2022-08-28 08:43:21

## Weekly challenge 179

[Challenge](https://theweeklychallenge.org/blog/perl-weekly-challenge-179/), [My solution](https://github.com/manwar/perlweeklychallenge-club/tree/master/challenge-179/sgreen)

## Task 1: Ordinal Number Spelling

### Task

You are given a positive number, `$n`. Write a script to spell the ordinal number.

### My solution

This turned out to be a little more complex than I thought it was, especially around some edge cases. Sure there are Python and Perl modules that already do this, but that's not the spirit of completing these challenges.

I start by defining four lists (arrays in Perl). `numbers` has the words for the first 19 numbers, so one, two, three, etc. `tens` has the words for twenty, thirty, etc. The `ordinal` list has the ordinal words for the first 19 numbers, like first, second, third. Finally the `thousands` list has the words we use for thousand, million and billion. I'm not handling anything 10<sup>12</sup> or larger.

Next I split up the numbers into blocks of three from the right. So 12345 becomes `[345, 12]`.

Then it's time to print out the words for each block.

1. If the number is 0 (for example the middle block in 1,000,234), do nothing
2. If the number is evenly divisible by 100, print the words for that number.
1. If the number is greater than 100, print the words for the hundreds number and the word ' and '. Change the number to be the remainder from 100.
1. If the number is greater than 19, print the tens words, and change the number to be the remainder from 10.
1. Print the number between one and nineteen. If this is the first block, use the `ordinal` list, otherwise use the `numbers` list.
1. Finally, if this is not the first block, add the appropriate thousands word.

There is also an edge case where the solution is divisible by 100. In this case, we have never use the `ordinal` list. When this occurs, I add the string 'th' to the end of the string.

When writing this blog, I also realized that we also didn't print the ordinal word if the number is divisible by 10 (except hundred and ten). I've added some code to also handle this. Thankfully for all the `tens` words we can replace 'y' with 'ieth' to get the right word.

Then it's a matter of pieces the bits together to produce the final string.

### Examples

```
$ ./ch-1.py 11
eleventh

$ ./ch-1.py 62
sixty second

$ ./ch-1.py 99
ninety ninth
```

## Task 2: Unicode Sparkline

### Task

You are given a list of positive numbers, `@n`.

Write a script to print sparkline in Unicode for the given list of numbers.

### My solution

First off, I'll give attribute of the solution to [Rosetta Code](https://rosettacode.org/wiki/Sparkline_in_unicode#Python), under a [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) license.

Thankfully both Python 3 and Perl support unicode out of the box, so we don't need to do anything special to support it.

The code defines the following variables:

* `bar` the string `▁▂▃▄▅▆▇█` (I use a list for the Perl solution), and `barcount` the length of the list.
* `mn` and `mx` the minimum and maximum values from the list.
* `extent` the difference between the two values.

It then goes through each value of `@n` and uses the equation `(n - mn) / extent * barcount` to work out which bar to display.

### Examples

```
$ ./ch-2.py 1 2 3 4 5 6 7 8
▁▂▃▄▅▆▇█

$ ./ch-2.py 1 8 2 7 3 6 10
▁▇▁▆▂▅█
```