Numerical and alphabetical suffixes: Difference between revisions

Content added Content deleted
(→‎{{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>