Numerical and alphabetical suffixes: Difference between revisions
Content deleted Content added
Thundergnat (talk | contribs) →{{header|Perl 6}}: implement scientific notation conversion at precision far beyond what the significant digits would suggest, tone down rhetoric |
→{{header|Factor}}: add EBNF solution |
||
Line 137: | Line 137: | ||
=={{header|Factor}}== |
=={{header|Factor}}== |
||
===Functional=== |
|||
<lang factor>USING: combinators combinators.short-circuit formatting fry |
<lang factor>USING: combinators combinators.short-circuit formatting fry |
||
grouping grouping.extras kernel literals math math.functions |
grouping grouping.extras kernel literals math math.functions |
||
Line 247: | Line 248: | ||
MAIN: main</lang> |
MAIN: main</lang> |
||
{{out}} |
|||
<pre> |
|||
Numbers: { 2greatGRo, 24Gros, 288Doz, 1,728pairs, 172.8SCOre } |
|||
Result: { 3,456, 3,456, 3,456, 3,456, 3,456 } |
|||
Numbers: { 1,567, +1.567k, 0.1567e-2m } |
|||
Result: { 1,567, 1,567, 1,567 } |
|||
Numbers: { 25.123kK, 25.123m, 2.5123e-00002G } |
|||
Result: { 25,123,000, 25,123,000, 25,123,000 } |
|||
Numbers: { 25.123kiKI, 25.123Mi, 2.5123e-00002Gi, +.25123E-7Ei } |
|||
Result: { 26,343,374.848, 26,343,374.848, 26,975,615.844352, 28,964,846,960.23782 } |
|||
Numbers: { -.25123e-34Vikki, 2e-77gooGols } |
|||
Result: { -33,394.19493810444, 199,999,999,999,999,983,222,784 } |
|||
Numbers: { 9!, 9!!, 9!!!, 9!!!!, 9!!!!!, 9!!!!!!, 9!!!!!!!, 9!!!!!!!!, 9!!!!!!!!! } |
|||
Result: { 362,880, 945, 162, 45, 36, 27, 18, 9, 9 } |
|||
</pre> |
|||
===EBNF=== |
|||
This solution uses Factor's extended Backus-Naur form (EBNF) language to define a grammar for parsing numerical/alphabetical suffix numbers. The goal was to describe as much of the suffix-number as possible in a declarative manner, minimizing the use of actions (Factor code that is run on a rule before being added to the abstract syntax tree) and helper functions. The biggest departure from this goal was to parse the metric/binary suffixes based on their index in a collection, as this method is less verbose than defining a rule for each suffix. |
|||
<lang factor>USING: formatting fry grouping kernel literals math |
|||
math.functions math.parser math.ranges multiline peg.ebnf |
|||
quotations qw sequences sequences.deep splitting strings unicode ; |
|||
IN: rosetta-code.numerical-suffixes.ebnf |
|||
CONSTANT: test-cases { |
|||
qw{ 2greatGRo 24Gros 288Doz 1,728pairs 172.8SCOre } |
|||
qw{ 1,567 +1.567k 0.1567e-2m } |
|||
qw{ 25.123kK 25.123m 2.5123e-00002G } |
|||
qw{ 25.123kiKI 25.123Mi 2.5123e-00002Gi +.25123E-7Ei } |
|||
qw{ -.25123e-34Vikki 2e-77gooGols } |
|||
qw{ |
|||
9! 9!! 9!!! 9!!!! 9!!!!! 9!!!!!! 9!!!!!!! 9!!!!!!!! |
|||
9!!!!!!!!! |
|||
} |
|||
} |
|||
CONSTANT: metric qw{ K M G T P E Z Y X W V U } |
|||
: suffix>quot ( str -- quot ) |
|||
dup [ [ 0 1 ] dip subseq >upper metric index 1 + ] dip |
|||
length 1 = [ 3 * '[ 10 _ ^ * ] ] [ 10 * '[ 2 _ ^ * ] ] if ; |
|||
: ?f>i ( x -- y/n ) dup >integer 2dup [ number= ] 2dip swap ? ; |
|||
GENERIC: commas ( n -- str ) |
|||
M: integer commas number>string <reversed> 3 group |
|||
[ "," append ] map concat reverse rest ; |
|||
M: float commas number>string "." split first2 |
|||
[ string>number commas ] dip "." glue ; |
|||
EBNF: suffix-num [=[ |
|||
sign = [+-] |
|||
digit = [0-9] |
|||
triplet = digit digit digit |
|||
commas = (triplet | digit digit | digit) ([,] triplet)+ |
|||
integer = sign? (commas | digit+) |
|||
exp = [Ee] sign? digit+ |
|||
bfloat = (integer | sign)? [.] digit+ exp? |
|||
float = (bfloat | integer exp) |
|||
number = (float | integer) => [[ flatten "" like string>number ]] |
|||
pairs = [Pp] [Aa] [Ii] [Rr] [s]? => [[ [ 2 * ] ]] |
|||
dozens = [Dd] [Oo] [Zz] [e]? [n]? [s]? => [[ [ 12 * ] ]] |
|||
scores = [Ss] [Cc] [Oo] [r]? [e]? [s]? => [[ [ 20 * ] ]] |
|||
gross = [Gg] [Rr] [o]? [s]? [s]? => [[ [ 144 * ] ]] |
|||
gg = [Gg] [Rr] [Ee] [Aa] [Tt] gross => [[ [ 1728 * ] ]] |
|||
googols = [Gg] [Oo] [Oo] [Gg] [Oo] [Ll] [s]? => [[ [ $[ 10 100 ^ ] * ] ]] |
|||
alpha = (pairs | dozens | scores | gg | gross | googols) |
|||
numeric = ([KkMmGgPpEeT-Zt-z] [Ii]?) => [[ flatten "" like suffix>quot ]] |
|||
ncompnd = numeric+ |
|||
fact = [!]+ => [[ length [ neg 1 swap <range> product ] curry ]] |
|||
suffix = (alpha | ncompnd | fact) |
|||
s-num = number suffix? !(.) => |
|||
[[ >quotation flatten call( -- x ) ?f>i commas ]] |
|||
]=] |
|||
: num-alpha-suffix-demo ( -- ) |
|||
test-cases [ |
|||
dup [ suffix-num ] map |
|||
"Numbers: %[%s, %]\n Result: %[%s, %]\n\n" printf |
|||
] each ; |
|||
MAIN: num-alpha-suffix-demo</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |