200/1 = Arithmetic slices
You are given an array of integers, @array. Write a script to find out all Arithmetic Slices for the given array of integers. An integer array is called arithmetic if it has at least 3 elements and the differences between any three consecutive elements are the same.
Example:
Input: @array = (1,2,3,4)
Output: (1,2,3), (2,3,4), (1,2,3,4)
For ease, I decided to start by creating an array @diff, where $diff[$j] = $array[$j + 1] - $array[$j] - so I am looking for runs of 3 or more identical numbers in @diff.
I move along @diff, maintaining a value $run_starts which is the index into @array where the current run of identical values of $diff[$j] starts, and $this_diff which is that value. Whenever I reach a $j which is not equal to $this_diff I know that $array[$j] is the end of the current run and potentially the start of another run.
Having identified a run of identical values of $diff[$j]:
- if it is less than 3 long I ignore it
- if it is 3 long, then I add it to the output
- if it is more than 3 long I add all its subsets as well - as in the example above
200/2 = Seven segment 200
A seven segment display is an electronic component used to display digits. The segments are labelled 'a' through 'g' as shown:
The encoding of each digit can thus be represented compactly as a truth table:my @truth =
qw<abcdef bc abdeg abcdg bcfg acdfg acdefg abc abcdefg abcfg>;
For example, $truth[1] = ‘bc’. The digit 1 would have segments ‘b’ and ‘c’ enabled.
Write a program that accepts any decimal number and draws that number as a horizontal sequence of ASCII seven segment displays, similar to the following:
Given a digit to display, the truth table tells us which segments to 'light up', for example 'abdeg' for 2. We need to start with a blank 7x7 matrix and populate the appropriate positions with a symbol - either | or -. I decided to do that using another lookup table, which I created like this:
$digit[ord('a')] = '-00 -01 -02 -03 -04 -05 -06';
$digit[ord('b')] = '|16 |26';
$digit[ord('c')] = '|46 |56';
$digit[ord('d')] = '-60 -61 -62 -63 -64 -65 -66';
$digit[ord('e')] = '|40 |50';
$digit[ord('f')] = '|10 |20';
$digit[ord('g')] = '-30 -31 -32 -33 -34 -35 -36';
For each letter, a to g, I can then determine the symbol and the positions needed, for example 'a' needs a '-' in row 0, column 0; in row 0 column 1 and so on.
I build up the display in an 2-dimensional array @display, which is 7 rows high and 9n characters wide, where n is the number of digits to be displayed (9 rather than 7 to allow two blanks between successive digits). And this is how I do it:
$segments = $truth[$1];
while ($segments =~ m|(.)|g) {
$points = $digit[ord($1)];
while ($points =~ m|(.)(\d)(\d)|g) {
$display[$2][$3 + $offset] = $1;
}
}
Then it's just a case of printing @display with a \n after each row.
No comments:
Post a Comment