diff options
| author | Abigail <abigail@abigail.be> | 2021-03-31 15:05:40 +0200 |
|---|---|---|
| committer | Abigail <abigail@abigail.be> | 2021-03-31 15:05:40 +0200 |
| commit | 39ebc15e335d36f52a0240e1cc9ed5e36f1a4fb2 (patch) | |
| tree | 7a5c6b3fd7a4840254fb9fae21d3aa8c61f34beb | |
| parent | 51f1e35114bff4bddd2119641fe329afcb416874 (diff) | |
| download | perlweeklychallenge-club-39ebc15e335d36f52a0240e1cc9ed5e36f1a4fb2.tar.gz perlweeklychallenge-club-39ebc15e335d36f52a0240e1cc9ed5e36f1a4fb2.tar.bz2 perlweeklychallenge-club-39ebc15e335d36f52a0240e1cc9ed5e36f1a4fb2.zip | |
AWK solution for week 106, part 2
| -rw-r--r-- | challenge-106/abigail/awk/ch-2.awk | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/challenge-106/abigail/awk/ch-2.awk b/challenge-106/abigail/awk/ch-2.awk new file mode 100644 index 0000000000..0a4a23750b --- /dev/null +++ b/challenge-106/abigail/awk/ch-2.awk @@ -0,0 +1,71 @@ +#!/usr/bin/awk + +# +# See ../README.md +# + +# +# Run as: awk -f ch-2.awk < input-file +# + +# +# We're creation the decimal expansion of the fraction N / D +# by performing long division. +# +# First, we calculate the part before the decimal point, by +# doing integer division of N / D. +# We're then left to do division of N' / D, where N' initially +# is N % D. +# We then repeatedly find new digits by calculating the integer +# division of (10 * N' / D) (which gives us a new digit in the +# decimal expansion), and then setting N' = 10 * N' % D. +# The fraction will have a finite decimal expansion if during the +# process N' becomes 0. Otherwise, it repeats, and it repeats +# as soon as have a N' which we've already seen. +# To calculate the repeating part, we keep track of how far we +# were in calculating the expansion for which N'. +# +# 22/7 \0.318 +# 0 int (7 / 22) == 0, so 0 before decimal point +# -- +# 7 N = N % D +# 66 3 * D +# -- +# 4 N = (10 * N) % D <--+ +# 22 1 * D | +# -- | Same, so '18' +# 18 N = (10 * N) % D | is the repeating +# 176 8 * D | part +# --- | +# 4 N = (10 * N) % D <--+ +# +# This implementation is based on the one given on Wikipedia: +# https://en.wikipedia.org/wiki/Repeating_decimal. +# + +function long_division (numerator, denominator) { + base = 10 + fraction = sprintf ("%d.", numerator / denominator) + position = length (fraction) + delete seen + + numerator %= denominator + + while (!seen [numerator]) { + if (!numerator) { + return fraction + } + seen [numerator] = position + fraction = fraction int (base * numerator / denominator) + numerator = base * numerator % denominator + position ++ + } + + return substr (fraction, 1, seen [numerator]) "(" \ + substr (fraction, 1 + seen [numerator]) ")" +} + + +{ + print long_division($1, $2) +} |
