Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
2
Task/Sparkline-in-unicode/00-META.yaml
Normal file
2
Task/Sparkline-in-unicode/00-META.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
from: http://rosettacode.org/wiki/Sparkline_in_unicode
|
||||
33
Task/Sparkline-in-unicode/00-TASK.txt
Normal file
33
Task/Sparkline-in-unicode/00-TASK.txt
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
A [[wp:Sparkline|sparkline]] is a graph of successive values laid out horizontally
|
||||
where the height of the line is proportional to the values in succession.
|
||||
|
||||
|
||||
;Task:
|
||||
Use the following series of Unicode characters to create a program
|
||||
that takes a series of numbers separated by one or more whitespace or comma characters
|
||||
and generates a sparkline-type bar graph of the values on a single line of output.
|
||||
|
||||
The eight characters: <code>'▁▂▃▄▅▆▇█'</code><br>
|
||||
(Unicode values U+2581 through U+2588).
|
||||
|
||||
Use your program to show sparklines for the following input,
|
||||
here on this page:
|
||||
# 1 2 3 4 5 6 7 8 7 6 5 4 3 2 1
|
||||
# 1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5
|
||||
:(note the mix of separators in this second case)!
|
||||
|
||||
;Notes:
|
||||
* A space is not part of the generated sparkline.
|
||||
* The sparkline may be accompanied by simple statistics of the data such as its range.
|
||||
* A suggestion emerging in later discussion (see [[Talk:Sparkline_in_unicode|Discussion]] page) is that the bounds between bins should ideally be set to yield the following results for two particular edge cases:
|
||||
|
||||
:: <code>"0, 1, 19, 20" -> ▁▁██</code>
|
||||
:: (Aiming to use just two spark levels)
|
||||
|
||||
:: <code>"0, 999, 4000, 4999, 7000, 7999" -> ▁▁▅▅██</code>
|
||||
:: (Aiming to use just three spark levels)
|
||||
|
||||
:: It may be helpful to include these cases in output tests.
|
||||
* You may find that the unicode sparklines on this page are rendered less noisily by Google Chrome than by Firefox or Safari.
|
||||
<br><br>
|
||||
|
||||
1
Task/Sparkline-in-unicode/APL/sparkline-in-unicode-1.apl
Normal file
1
Task/Sparkline-in-unicode/APL/sparkline-in-unicode-1.apl
Normal file
|
|
@ -0,0 +1 @@
|
|||
sparkln←{'▁▂▃▄▅▆▇█'[⌊0.5+7×⍵÷⌈/⍵]}
|
||||
4
Task/Sparkline-in-unicode/APL/sparkline-in-unicode-2.apl
Normal file
4
Task/Sparkline-in-unicode/APL/sparkline-in-unicode-2.apl
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
sparkln 1 2 3 4 5 6 7 8 7 6 5 4 3 2 1
|
||||
▂▃▄▅▅▆▇█▇▆▅▅▄▃▂
|
||||
sparkln 1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5
|
||||
▂▁▄▃▆▅█▇
|
||||
|
|
@ -0,0 +1,316 @@
|
|||
use AppleScript version "2.4"
|
||||
use framework "Foundation"
|
||||
use scripting additions
|
||||
|
||||
on run
|
||||
unlines(map(¬
|
||||
compose(compose(unlines, sparkLine), readFloats), ¬
|
||||
{"0, 1, 19, 20", "0, 999, 4000, 4999, 7000, 7999", ¬
|
||||
"0, 1000, 4000, 5000, 7000, 8000", ¬
|
||||
"1 2 3 4 5 6 7 8 7 6 5 4 3 2 1", ¬
|
||||
"1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5"}))
|
||||
end run
|
||||
|
||||
|
||||
-- sparkLine :: [Float] -> [String]
|
||||
on sparkLine(xs)
|
||||
set ys to sort(xs)
|
||||
set mn to item 1 of ys
|
||||
set mx to item -1 of ys
|
||||
set n to length of xs
|
||||
set mid to (n div 2)
|
||||
set w to (mx - mn) / 8
|
||||
|
||||
script bound
|
||||
on |λ|(x)
|
||||
mn + (w * x)
|
||||
end |λ|
|
||||
end script
|
||||
set lbounds to map(bound, enumFromTo(1, 7))
|
||||
|
||||
script spark
|
||||
on |λ|(x)
|
||||
script flipGT
|
||||
on |λ|(b)
|
||||
b > x
|
||||
end |λ|
|
||||
end script
|
||||
script indexedBlock
|
||||
on |λ|(i)
|
||||
item i of "▁▂▃▄▅▆▇"
|
||||
end |λ|
|
||||
end script
|
||||
maybe("█", indexedBlock, findIndex(flipGT, lbounds))
|
||||
end |λ|
|
||||
end script
|
||||
|
||||
script str
|
||||
on |λ|(x)
|
||||
x as string
|
||||
end |λ|
|
||||
end script
|
||||
|
||||
{concat(map(spark, xs)), ¬
|
||||
unwords(map(str, xs)), ¬
|
||||
"Min " & mn as string, ¬
|
||||
"Mean " & roundTo(mean(xs), 2) as string, ¬
|
||||
"Median " & bool(item mid of xs, ((item mid of xs) + ¬
|
||||
(item (mid + 1) of xs)) / 2, even(n)), ¬
|
||||
"Max " & mx as string, ""}
|
||||
end sparkLine
|
||||
|
||||
|
||||
-- GENERIC -------------------------------------------------
|
||||
|
||||
-- Just :: a -> Maybe a
|
||||
on Just(x)
|
||||
{type:"Maybe", Nothing:false, Just:x}
|
||||
end Just
|
||||
|
||||
-- Nothing :: Maybe a
|
||||
on Nothing()
|
||||
{type:"Maybe", Nothing:true}
|
||||
end Nothing
|
||||
|
||||
-- bool :: a -> a -> Bool -> a
|
||||
on bool(f, t, p)
|
||||
if p then
|
||||
t
|
||||
else
|
||||
f
|
||||
end if
|
||||
end bool
|
||||
|
||||
-- compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
|
||||
on compose(f, g)
|
||||
script
|
||||
property mf : mReturn(f)
|
||||
property mg : mReturn(g)
|
||||
on |λ|(x)
|
||||
mf's |λ|(mg's |λ|(x))
|
||||
end |λ|
|
||||
end script
|
||||
end compose
|
||||
|
||||
-- concat :: [[a]] -> [a]
|
||||
-- concat :: [String] -> String
|
||||
on concat(xs)
|
||||
set lng to length of xs
|
||||
if 0 < lng and string is class of (item 1 of xs) then
|
||||
set acc to ""
|
||||
else
|
||||
set acc to {}
|
||||
end if
|
||||
repeat with i from 1 to lng
|
||||
set acc to acc & item i of xs
|
||||
end repeat
|
||||
acc
|
||||
end concat
|
||||
|
||||
-- enumFromTo :: Int -> Int -> [Int]
|
||||
on enumFromTo(m, n)
|
||||
if m ≤ n then
|
||||
set lst to {}
|
||||
repeat with i from m to n
|
||||
set end of lst to i
|
||||
end repeat
|
||||
return lst
|
||||
else
|
||||
return {}
|
||||
end if
|
||||
end enumFromTo
|
||||
|
||||
-- even :: Int -> Bool
|
||||
on even(x)
|
||||
0 = x mod 2
|
||||
end even
|
||||
|
||||
-- Takes a predicate function and a list and
|
||||
-- returns Just( the 1-based index of the first
|
||||
-- element ) in the list satisfying the predicate
|
||||
-- or Nothing if there is no such element.
|
||||
-- findIndex(isSpace, "hello world")
|
||||
--> {type:"Maybe", Nothing:false, Just:6}
|
||||
|
||||
-- findIndex(even, [3, 5, 7, 8, 9])
|
||||
--> {type:"Maybe", Nothing:false, Just:4}
|
||||
|
||||
-- findIndex(isUpper, "all lower case")
|
||||
--> {type:"Maybe", Nothing:true}
|
||||
-- findIndex :: (a -> Bool) -> [a] -> Maybe Int
|
||||
on findIndex(p, xs)
|
||||
tell mReturn(p)
|
||||
set lng to length of xs
|
||||
repeat with i from 1 to lng
|
||||
if |λ|(item i of xs) then return Just(i)
|
||||
end repeat
|
||||
return Nothing()
|
||||
end tell
|
||||
end findIndex
|
||||
|
||||
-- foldl :: (a -> b -> a) -> a -> [b] -> a
|
||||
on foldl(f, startValue, xs)
|
||||
tell mReturn(f)
|
||||
set v to startValue
|
||||
set lng to length of xs
|
||||
repeat with i from 1 to lng
|
||||
set v to |λ|(v, item i of xs, i, xs)
|
||||
end repeat
|
||||
return v
|
||||
end tell
|
||||
end foldl
|
||||
|
||||
-- map :: (a -> b) -> [a] -> [b]
|
||||
on map(f, xs)
|
||||
tell mReturn(f)
|
||||
set lng to length of xs
|
||||
set lst to {}
|
||||
repeat with i from 1 to lng
|
||||
set end of lst to |λ|(item i of xs, i, xs)
|
||||
end repeat
|
||||
return lst
|
||||
end tell
|
||||
end map
|
||||
|
||||
-- mean :: [Num] -> Num
|
||||
on mean(xs)
|
||||
script
|
||||
on |λ|(a, x)
|
||||
a + x
|
||||
end |λ|
|
||||
end script
|
||||
foldl(result, 0, xs) / (length of xs)
|
||||
end mean
|
||||
|
||||
-- | The 'maybe' function takes a default value, a function, and a 'Maybe'
|
||||
-- value. If the 'Maybe' value is 'Nothing', the function returns the
|
||||
-- default value. Otherwise, it applies the function to the value inside
|
||||
-- the 'Just' and returns the result.
|
||||
-- maybe :: b -> (a -> b) -> Maybe a -> b
|
||||
on maybe(v, f, mb)
|
||||
if Nothing of mb then
|
||||
v
|
||||
else
|
||||
tell mReturn(f) to |λ|(Just of mb)
|
||||
end if
|
||||
end maybe
|
||||
|
||||
-- Lift 2nd class handler function into 1s class script wrapper
|
||||
-- mReturn :: First-class m => (a -> b) -> m (a -> b)
|
||||
on mReturn(f)
|
||||
if script is class of f then
|
||||
f
|
||||
else
|
||||
script
|
||||
property |λ| : f
|
||||
end script
|
||||
end if
|
||||
end mReturn
|
||||
|
||||
-- readFloats :: String -> [Float]
|
||||
on readFloats(s)
|
||||
script asReal
|
||||
on |λ|(n)
|
||||
n as real
|
||||
end |λ|
|
||||
end script
|
||||
map(asReal, splitRegex("[\\s,]+", s))
|
||||
end readFloats
|
||||
|
||||
-- regexMatches :: String -> String -> [[String]]
|
||||
on regexMatches(strRegex, strHay)
|
||||
set ca to current application
|
||||
-- NSNotFound handling and and High Sierra workaround due to @sl1974
|
||||
set NSNotFound to a reference to 9.22337203685477E+18 + 5807
|
||||
set oRgx to ca's NSRegularExpression's regularExpressionWithPattern:strRegex ¬
|
||||
options:((ca's NSRegularExpressionAnchorsMatchLines as integer)) ¬
|
||||
|error|:(missing value)
|
||||
set oString to ca's NSString's stringWithString:strHay
|
||||
|
||||
script matchString
|
||||
on |λ|(m)
|
||||
script rangeMatched
|
||||
on |λ|(i)
|
||||
tell (m's rangeAtIndex:i)
|
||||
set intFrom to its location
|
||||
if NSNotFound ≠ intFrom then
|
||||
text (intFrom + 1) thru (intFrom + (its |length|)) of strHay
|
||||
else
|
||||
missing value
|
||||
end if
|
||||
end tell
|
||||
end |λ|
|
||||
end script
|
||||
end |λ|
|
||||
end script
|
||||
|
||||
script asRange
|
||||
on |λ|(x)
|
||||
range() of x
|
||||
end |λ|
|
||||
end script
|
||||
map(asRange, (oRgx's matchesInString:oString ¬
|
||||
options:0 range:{location:0, |length|:oString's |length|()}) as list)
|
||||
end regexMatches
|
||||
|
||||
|
||||
-- roundTo :: Float -> Int -> Float
|
||||
on roundTo(x, n)
|
||||
set d to 10 ^ n
|
||||
(round (x * d)) / d
|
||||
end roundTo
|
||||
|
||||
-- sort :: Ord a => [a] -> [a]
|
||||
on sort(xs)
|
||||
((current application's NSArray's arrayWithArray:xs)'s ¬
|
||||
sortedArrayUsingSelector:"compare:") as list
|
||||
end sort
|
||||
|
||||
-- splitRegex :: Regex -> String -> [String]
|
||||
on splitRegex(strRegex, str)
|
||||
set lstMatches to regexMatches(strRegex, str)
|
||||
if length of lstMatches > 0 then
|
||||
script preceding
|
||||
on |λ|(a, x)
|
||||
set iFrom to start of a
|
||||
set iLocn to (location of x)
|
||||
|
||||
if iLocn > iFrom then
|
||||
set strPart to text (iFrom + 1) thru iLocn of str
|
||||
else
|
||||
set strPart to ""
|
||||
end if
|
||||
{parts:parts of a & strPart, start:iLocn + (length of x) - 1}
|
||||
end |λ|
|
||||
end script
|
||||
|
||||
set recLast to foldl(preceding, {parts:[], start:0}, lstMatches)
|
||||
|
||||
set iFinal to start of recLast
|
||||
if iFinal < length of str then
|
||||
parts of recLast & text (iFinal + 1) thru -1 of str
|
||||
else
|
||||
parts of recLast & ""
|
||||
end if
|
||||
else
|
||||
{str}
|
||||
end if
|
||||
end splitRegex
|
||||
|
||||
-- unlines :: [String] -> String
|
||||
on unlines(xs)
|
||||
set {dlm, my text item delimiters} to ¬
|
||||
{my text item delimiters, linefeed}
|
||||
set str to xs as text
|
||||
set my text item delimiters to dlm
|
||||
str
|
||||
end unlines
|
||||
|
||||
-- unwords :: [String] -> String
|
||||
on unwords(xs)
|
||||
set {dlm, my text item delimiters} to ¬
|
||||
{my text item delimiters, space}
|
||||
set s to xs as text
|
||||
set my text item delimiters to dlm
|
||||
return s
|
||||
end unwords
|
||||
18
Task/Sparkline-in-unicode/Arturo/sparkline-in-unicode.arturo
Normal file
18
Task/Sparkline-in-unicode/Arturo/sparkline-in-unicode.arturo
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
bar: "▁▂▃▄▅▆▇█"
|
||||
barcount: to :floating dec size bar
|
||||
|
||||
while ø [
|
||||
line: input "Numbers separated by spaces: "
|
||||
numbers: to [:floating] split.words line
|
||||
mn: min numbers
|
||||
mx: max numbers
|
||||
extent: mx-mn
|
||||
sparkLine: new ""
|
||||
loop numbers 'n [
|
||||
i: to :integer barcount*(n-mn)//extent
|
||||
'sparkLine ++ bar\[i]
|
||||
]
|
||||
print ["min:" round.to:1 mn "max:" round.to:1 mx]
|
||||
print sparkLine
|
||||
print ""
|
||||
]
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
SetFormat, FloatFast, 0.1
|
||||
strings := ["1 2 3 4 5 6 7 8 7 6 5 4 3 2 1"
|
||||
, "1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5"]
|
||||
|
||||
Loop, % strings.MaxIndex()
|
||||
{
|
||||
SL := Sparklines(strings[A_Index])
|
||||
MsgBox, % "Min: " SL["Min"] ", Max: " SL["Max"] ", Range: " SL["Rng"] "`n" SL["Chars"]
|
||||
}
|
||||
|
||||
Sparklines(s)
|
||||
{
|
||||
s := RegexReplace(s, "[^\d\.]+", ",")
|
||||
Loop, Parse, s, `,
|
||||
{
|
||||
Max := A_LoopField > Max ? A_LoopField : Max
|
||||
Min := !Min ? Max : A_LoopField < Min ? A_LoopField : Min
|
||||
}
|
||||
Rng := Max - Min
|
||||
Loop, Parse, s, `,
|
||||
Chars .= Chr(0x2581 + Round(7 * (A_LoopField - Min) / Rng))
|
||||
return, {"Min": Min, "Max": Max, "Rng": Rng, "Chars": Chars}
|
||||
}
|
||||
68
Task/Sparkline-in-unicode/C++/sparkline-in-unicode.cpp
Normal file
68
Task/Sparkline-in-unicode/C++/sparkline-in-unicode.cpp
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <locale>
|
||||
|
||||
class Sparkline {
|
||||
public:
|
||||
Sparkline(std::wstring &cs) : charset( cs ){
|
||||
}
|
||||
virtual ~Sparkline(){
|
||||
}
|
||||
|
||||
void print(std::string spark){
|
||||
const char *delim = ", ";
|
||||
std::vector<float> data;
|
||||
// Get first non-delimiter
|
||||
std::string::size_type last = spark.find_first_not_of(delim, 0);
|
||||
// Get end of token
|
||||
std::string::size_type pos = spark.find_first_of(delim, last);
|
||||
|
||||
while( pos != std::string::npos || last != std::string::npos ){
|
||||
std::string tok = spark.substr(last, pos-last);
|
||||
// Convert to float:
|
||||
std::stringstream ss(tok);
|
||||
float entry;
|
||||
ss >> entry;
|
||||
|
||||
data.push_back( entry );
|
||||
|
||||
last = spark.find_first_not_of(delim, pos);
|
||||
pos = spark.find_first_of(delim, last);
|
||||
}
|
||||
|
||||
// Get range of dataset
|
||||
float min = *std::min_element( data.begin(), data.end() );
|
||||
float max = *std::max_element( data.begin(), data.end() );
|
||||
|
||||
float skip = (charset.length()-1) / (max - min);
|
||||
|
||||
std::wcout<<L"Min: "<<min<<L"; Max: "<<max<<L"; Range: "<<(max-min)<<std::endl;
|
||||
|
||||
std::vector<float>::const_iterator it;
|
||||
for(it = data.begin(); it != data.end(); it++){
|
||||
float v = ( (*it) - min ) * skip;
|
||||
std::wcout<<charset[ (int)floor( v ) ];
|
||||
}
|
||||
std::wcout<<std::endl;
|
||||
|
||||
}
|
||||
private:
|
||||
std::wstring &charset;
|
||||
};
|
||||
|
||||
int main( int argc, char **argv ){
|
||||
std::wstring charset = L"\u2581\u2582\u2583\u2584\u2585\u2586\u2587\u2588";
|
||||
|
||||
// Mainly just set up utf-8, so wcout won't narrow our characters.
|
||||
std::locale::global(std::locale("en_US.utf8"));
|
||||
|
||||
Sparkline sl(charset);
|
||||
|
||||
sl.print("1 2 3 4 5 6 7 8 7 6 5 4 3 2 1");
|
||||
sl.print("1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5");
|
||||
|
||||
return 0;
|
||||
}
|
||||
47
Task/Sparkline-in-unicode/C/sparkline-in-unicode.c
Normal file
47
Task/Sparkline-in-unicode/C/sparkline-in-unicode.c
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
#include<string.h>
|
||||
#include<stdlib.h>
|
||||
#include<locale.h>
|
||||
#include<stdio.h>
|
||||
#include<wchar.h>
|
||||
#include<math.h>
|
||||
|
||||
int main(int argC,char* argV[])
|
||||
{
|
||||
double* arr,min,max;
|
||||
char* str;
|
||||
int i,len;
|
||||
if(argC == 1)
|
||||
printf("Usage : %s <data points separated by spaces or commas>",argV[0]);
|
||||
else{
|
||||
arr = (double*)malloc((argC-1)*sizeof(double));
|
||||
for(i=1;i<argC;i++){
|
||||
len = strlen(argV[i]);
|
||||
|
||||
if(argV[i][len-1]==','){
|
||||
str = (char*)malloc(len*sizeof(char));
|
||||
strncpy(str,argV[i],len-1);
|
||||
arr[i-1] = atof(str);
|
||||
free(str);
|
||||
}
|
||||
else
|
||||
arr[i-1] = atof(argV[i]);
|
||||
if(i==1){
|
||||
min = arr[i-1];
|
||||
max = arr[i-1];
|
||||
}
|
||||
else{
|
||||
min=(min<arr[i-1]?min:arr[i-1]);
|
||||
max=(max>arr[i-1]?max:arr[i-1]);
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n%Max : %lf,Min : %lf,Range : %lf\n",max,min,max-min);
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
|
||||
for(i=1;i<argC;i++){
|
||||
printf("%lc", (wint_t)(9601 + (int)ceil((arr[i-1]-min)/(max-min)*7)));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
15
Task/Sparkline-in-unicode/Clojure/sparkline-in-unicode.clj
Normal file
15
Task/Sparkline-in-unicode/Clojure/sparkline-in-unicode.clj
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
(defn sparkline [nums]
|
||||
(let [sparks "▁▂▃▄▅▆▇█"
|
||||
high (apply max nums)
|
||||
low (apply min nums)
|
||||
spread (- high low)
|
||||
quantize #(Math/round (* 7.0 (/ (- % low) spread)))]
|
||||
(apply str (map #(nth sparks (quantize %)) nums))))
|
||||
|
||||
(defn spark [line]
|
||||
(if line
|
||||
(let [nums (read-string (str "[" line "]"))]
|
||||
(println (sparkline nums))
|
||||
(recur (read-line)))))
|
||||
|
||||
(spark (read-line))
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
(defun buckets (numbers)
|
||||
(loop with min = (apply #'min numbers)
|
||||
with max = (apply #'max numbers)
|
||||
with width = (/ (- max min) 7)
|
||||
for base from (- min (/ width 2)) by width
|
||||
repeat 8
|
||||
collect (cons base (+ base width))))
|
||||
|
||||
(defun bucket-for-number (number buckets)
|
||||
(loop for i from 0
|
||||
for (min . max) in buckets
|
||||
when (and (<= min number) (< number max))
|
||||
return i))
|
||||
|
||||
(defun sparkline (numbers)
|
||||
(loop with buckets = (buckets numbers)
|
||||
with sparks = "▁▂▃▄▅▆▇█"
|
||||
with sparkline = (make-array (length numbers) :element-type 'character)
|
||||
with min = (apply #'min numbers)
|
||||
with max = (apply #'max numbers)
|
||||
for number in numbers
|
||||
for i from 0
|
||||
for bucket = (bucket-for-number number buckets)
|
||||
do (setf (aref sparkline i) (char sparks bucket))
|
||||
finally (format t "Min: ~A, Max: ~A, Range: ~A~%" min max (- max min))
|
||||
(write-line sparkline)))
|
||||
|
||||
(defun string->numbers (string)
|
||||
(flet ((delimiterp (c)
|
||||
(or (char= c #\Space) (char= c #\,))))
|
||||
(loop for prev-end = 0 then end
|
||||
while prev-end
|
||||
for start = (position-if-not #'delimiterp string :start prev-end)
|
||||
for end = (position-if #'delimiterp string :start start)
|
||||
for number = (read-from-string string t nil :start start :end end)
|
||||
do (assert (numberp number))
|
||||
collect number)))
|
||||
|
||||
(defun string->sparkline (string)
|
||||
(sparkline (string->numbers string)))
|
||||
|
||||
(string->sparkline "1 2 3 4 5 6 7 8 7 6 5 4 3 2 1")
|
||||
(string->sparkline "1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5")
|
||||
16
Task/Sparkline-in-unicode/D/sparkline-in-unicode.d
Normal file
16
Task/Sparkline-in-unicode/D/sparkline-in-unicode.d
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
void main() {
|
||||
import std.stdio, std.range, std.algorithm, std.conv,
|
||||
std.string, std.regex;
|
||||
|
||||
"Numbers please separated by space/commas: ".write;
|
||||
immutable numbers = readln
|
||||
.strip
|
||||
.splitter(r"[\s,]+".regex)
|
||||
.array /**/
|
||||
.to!(real[]);
|
||||
immutable mm = numbers.reduce!(min, max);
|
||||
writefln("min: %4f, max: %4f", mm[]);
|
||||
immutable bars = iota(9601, 9609).map!(i => i.to!dchar).dtext;
|
||||
immutable div = (mm[1] - mm[0]) / (bars.length - 1);
|
||||
numbers.map!(n => bars[cast(int)((n - mm[0]) / div)]).writeln;
|
||||
}
|
||||
50
Task/Sparkline-in-unicode/Delphi/sparkline-in-unicode.delphi
Normal file
50
Task/Sparkline-in-unicode/Delphi/sparkline-in-unicode.delphi
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
program Sparkline_in_unicode;
|
||||
|
||||
{$APPTYPE CONSOLE}
|
||||
|
||||
//Translated from: https://www.arduino.cc/reference/en/language/functions/math/map/
|
||||
function map(x, in_min, in_max, out_min, out_max: Double): Double;
|
||||
begin
|
||||
Result := ((x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min);
|
||||
end;
|
||||
|
||||
procedure Normalize(var Values: TArray<Double>; outMin, outMax: Double);
|
||||
var
|
||||
i: Integer;
|
||||
inMax, inMin, value: Double;
|
||||
begin
|
||||
if Length(Values) = 0 then
|
||||
Exit;
|
||||
|
||||
inMin := Values[0];
|
||||
inMax := Values[0];
|
||||
|
||||
for value in Values do
|
||||
begin
|
||||
if value > inMax then
|
||||
inMax := value;
|
||||
if value < inMin then
|
||||
inMin := value;
|
||||
end;
|
||||
|
||||
for i := 0 to High(Values) do
|
||||
Values[i] := map(Values[i], inMin, inMax, outMin, outMax);
|
||||
end;
|
||||
|
||||
function Sparkline(Values: TArray<Double>): UnicodeString;
|
||||
var
|
||||
value: Double;
|
||||
const
|
||||
CHARS: UnicodeString = #$2581#$2582#$2583#$2584#$2585#$2586#$2587#$2588;
|
||||
begin
|
||||
Result := '';
|
||||
Normalize(Values, 1, 8);
|
||||
for value in Values do
|
||||
Result := Result + CHARS[Trunc(value)];
|
||||
end;
|
||||
|
||||
begin
|
||||
writeln(Sparkline([1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1]));
|
||||
writeln(Sparkline([1.5, 0.5, 3.5, 2.5, 5.5, 4.5, 7.5, 6.5]));
|
||||
Readln;
|
||||
end.
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
defmodule RC do
|
||||
def sparkline(str) do
|
||||
values = str |> String.split(~r/(,| )+/)
|
||||
|> Enum.map(&elem(Float.parse(&1), 0))
|
||||
{min, max} = Enum.min_max(values)
|
||||
IO.puts Enum.map(values, &(round((&1 - min) / (max - min) * 7 + 0x2581)))
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
str1 = "1 2 3 4 5 6 7 8 7 6 5 4 3 2 1"
|
||||
str2 = "1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5"
|
||||
|
||||
RC.sparkline(str1)
|
||||
IO.puts "" # newline
|
||||
RC.sparkline(str2)
|
||||
22
Task/Sparkline-in-unicode/F-Sharp/sparkline-in-unicode.fs
Normal file
22
Task/Sparkline-in-unicode/F-Sharp/sparkline-in-unicode.fs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
open System
|
||||
open System.Globalization
|
||||
open System.Text.RegularExpressions
|
||||
|
||||
let bars = Array.map Char.ToString ("▁▂▃▄▅▆▇█".ToCharArray())
|
||||
|
||||
while true do
|
||||
printf "Numbers separated by anything: "
|
||||
let numbers =
|
||||
[for x in Regex.Matches(Console.ReadLine(), @"-?\d+(?:\.\d*)?") do yield x.Value]
|
||||
|> List.map (fun x -> Double.Parse(x, CultureInfo.InvariantCulture))
|
||||
if numbers.Length = 0 then System.Environment.Exit(0)
|
||||
if numbers.Length = 1 then
|
||||
printfn "A sparkline for 1 value is not very useful... ignoring entry"
|
||||
else
|
||||
let min, max = List.min numbers, List.max numbers
|
||||
printfn "min: %5f; max: %5f" min max
|
||||
let barsCount = float (bars.GetUpperBound(0))
|
||||
numbers
|
||||
|> List.map (fun x -> bars.[int ((x - min)/(max - min) * barsCount)])
|
||||
|> String.Concat
|
||||
|> printfn "%s"
|
||||
68
Task/Sparkline-in-unicode/FALSE/sparkline-in-unicode.false
Normal file
68
Task/Sparkline-in-unicode/FALSE/sparkline-in-unicode.false
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
{
|
||||
variables:
|
||||
s: sign (1 or -1)
|
||||
u: current number
|
||||
f: current number fraction length
|
||||
v: current number is valid
|
||||
t: number of numbers read
|
||||
x: biggest fraction
|
||||
y: smallest number (without fraction)
|
||||
z: biggest number (without fraction)
|
||||
}
|
||||
|
||||
{function a: test if top is 0-9, without popping the value, codes 48-57 are in range}
|
||||
[$$47>\57>~&]a:
|
||||
|
||||
{function b: test if top is ',' or ' ', without popping the value}
|
||||
[$$',=\' =|]b:
|
||||
|
||||
{function c: read a number from the input, given that the first character of the input is already on the stack}
|
||||
[
|
||||
1s:0u:0f:0v: {reset values}
|
||||
|
||||
$'-=[1_s:%^]? {if (it is negative) set the sign value to -1 move to next}
|
||||
[a;!][48-u;10*+u:1_v:^]# {while (isnumber) do number = number * 10 + decimal and set valid number and move to next}
|
||||
$'.=[ {if (it is a decimal) move forward and read fraction}
|
||||
%^
|
||||
[a;!][48-u;10*+u:f;1+f:1_v:^]# {while (isnumber) do number = number * 10 + decimal and increase fraction length and set valid number and move to next}
|
||||
]?
|
||||
$$'-=\'.=|[0v:]? {if next charachter is a '-' or a '.', set invalid}
|
||||
]c:
|
||||
|
||||
{function d: normalize number/fraction from stack to max fraction and push that number}
|
||||
[
|
||||
[$x;=~][1+\10*\]# {while (fraction != max) fraction + 1, value * 10}
|
||||
% {pop fraction}
|
||||
]d:
|
||||
|
||||
0t:
|
||||
0x:
|
||||
1_v: { nothing read, so we are still valid }
|
||||
^[b;!][%^]# {read away any initial separators}
|
||||
[$1_=~v;&][ {while input != -1 and valid input, leaving input on the stack}
|
||||
c;! {read a number}
|
||||
t;1+t:u;s;*f;@ {increase count, push number * sign and fraction length onto the stack and bring input back up}
|
||||
f;x;>[f;x:]? {set fraction to biggest of current and previous biggest}
|
||||
[b;!][%^]# {while (isseparator) move forward}
|
||||
]#
|
||||
v;~["error at charachter ",]? {if invalid number, tell them when}
|
||||
v;[ {if last number also valid, do the math}
|
||||
% {pop the -1}
|
||||
t;2*1-q: {var q: points to next value}
|
||||
0p: {var p: whether min/max have been set}
|
||||
[q;1+t;>][ {while q + 1 > t}
|
||||
q;ø {current number}
|
||||
q;ø {current fraction}
|
||||
d;! {normalize}
|
||||
p;[$y;\>[$y:]? $z;>[$z:]?]? {compare min/max}
|
||||
p;~[1_p:$y:$z:]? {if (first)) set min/max}
|
||||
q;1-q: {move pointer}
|
||||
]#
|
||||
|
||||
t;q: {point q to first value}
|
||||
[q;0>][ {while q > 0}
|
||||
q;1-øy;-7*z;y;-/ {(number - minvalue) * 7 / (maxvalue - minvalue), should result in 0..7}
|
||||
9601+, {print character}
|
||||
q;1-q: {move pointer}
|
||||
]#
|
||||
]?
|
||||
18
Task/Sparkline-in-unicode/Factor/sparkline-in-unicode.factor
Normal file
18
Task/Sparkline-in-unicode/Factor/sparkline-in-unicode.factor
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
USING: formatting kernel math math.order math.parser
|
||||
math.statistics sequences splitting ;
|
||||
|
||||
: sparkline-index ( v min max -- i )
|
||||
[ drop - 8 * ] [ swap - /i ] 2bi 0 7 clamp 9601 + ;
|
||||
|
||||
: (sparkline) ( seq -- new-seq )
|
||||
dup minmax [ sparkline-index ] 2curry "" map-as ;
|
||||
|
||||
: sparkline ( str -- new-str )
|
||||
", " split harvest [ string>number ] map (sparkline) ;
|
||||
|
||||
{
|
||||
"1 2 3 4 5 6 7 8 7 6 5 4 3 2 1"
|
||||
"1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5"
|
||||
"0, 1, 19, 20"
|
||||
"0, 999, 4000, 4999, 7000, 7999"
|
||||
} [ dup sparkline "%u -> %s\n" printf ] each
|
||||
74
Task/Sparkline-in-unicode/Go/sparkline-in-unicode.go
Normal file
74
Task/Sparkline-in-unicode/Go/sparkline-in-unicode.go
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println("Numbers please separated by space/commas:")
|
||||
sc := bufio.NewScanner(os.Stdin)
|
||||
sc.Scan()
|
||||
s, n, min, max, err := spark(sc.Text())
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
if n == 1 {
|
||||
fmt.Println("1 value =", min)
|
||||
} else {
|
||||
fmt.Println(n, "values. Min:", min, "Max:", max)
|
||||
}
|
||||
fmt.Println(s)
|
||||
}
|
||||
|
||||
var sep = regexp.MustCompile(`[\s,]+`)
|
||||
|
||||
func spark(s0 string) (sp string, n int, min, max float64, err error) {
|
||||
ss := sep.Split(s0, -1)
|
||||
n = len(ss)
|
||||
vs := make([]float64, n)
|
||||
var v float64
|
||||
min = math.Inf(1)
|
||||
max = math.Inf(-1)
|
||||
for i, s := range ss {
|
||||
switch v, err = strconv.ParseFloat(s, 64); {
|
||||
case err != nil:
|
||||
case math.IsNaN(v):
|
||||
err = errors.New("NaN not supported.")
|
||||
case math.IsInf(v, 0):
|
||||
err = errors.New("Inf not supported.")
|
||||
default:
|
||||
if v < min {
|
||||
min = v
|
||||
}
|
||||
if v > max {
|
||||
max = v
|
||||
}
|
||||
vs[i] = v
|
||||
continue
|
||||
}
|
||||
return
|
||||
}
|
||||
if min == max {
|
||||
sp = strings.Repeat("▄", n)
|
||||
} else {
|
||||
rs := make([]rune, n)
|
||||
f := 8 / (max - min)
|
||||
for j, v := range vs {
|
||||
i := rune(f * (v - min))
|
||||
if i > 7 {
|
||||
i = 7
|
||||
}
|
||||
rs[j] = '▁' + i
|
||||
}
|
||||
sp = string(rs)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
def sparkline(List<Number> list) {
|
||||
def (min, max) = [list.min(), list.max()]
|
||||
def div = (max - min) / 7
|
||||
list.collect { (char)(0x2581 + (it-min) * div) }.join()
|
||||
}
|
||||
def sparkline(String text) { sparkline(text.split(/[ ,]+/).collect { it as Double }) }
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
["1 2 3 4 5 6 7 8 7 6 5 4 3 2 1", "1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5"].each { dataset ->
|
||||
println " Dataset: $dataset"
|
||||
println "Sparkline: ${sparkline(dataset)}"
|
||||
}
|
||||
57
Task/Sparkline-in-unicode/Haskell/sparkline-in-unicode-1.hs
Normal file
57
Task/Sparkline-in-unicode/Haskell/sparkline-in-unicode-1.hs
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
import Data.List.Split (splitOneOf)
|
||||
import Data.Char (chr)
|
||||
|
||||
|
||||
toSparkLine :: [Double] -> String
|
||||
toSparkLine xs = map cl xs
|
||||
where
|
||||
top = maximum xs
|
||||
bot = minimum xs
|
||||
range = top - bot
|
||||
cl x = chr $ 0x2581 + floor (min 7 ((x - bot) / range * 8))
|
||||
|
||||
makeSparkLine :: String -> (String, Stats)
|
||||
makeSparkLine xs = (toSparkLine parsed, stats parsed)
|
||||
where
|
||||
parsed = map read $ filter (not . null) $ splitOneOf " ," xs
|
||||
|
||||
data Stats = Stats
|
||||
{ minValue, maxValue, rangeOfValues :: Double
|
||||
, numberOfValues :: Int
|
||||
}
|
||||
|
||||
instance Show Stats where
|
||||
show (Stats mn mx r n) =
|
||||
"min: " ++
|
||||
show mn ++
|
||||
"; max: " ++
|
||||
show mx ++ "; range: " ++ show r ++ "; no. of values: " ++ show n
|
||||
|
||||
stats :: [Double] -> Stats
|
||||
stats xs =
|
||||
Stats
|
||||
{ minValue = mn
|
||||
, maxValue = mx
|
||||
, rangeOfValues = mx - mn
|
||||
, numberOfValues = length xs
|
||||
}
|
||||
where
|
||||
mn = minimum xs
|
||||
mx = maximum xs
|
||||
|
||||
drawSparkLineWithStats :: String -> IO ()
|
||||
drawSparkLineWithStats xs = putStrLn sp >> print st
|
||||
where
|
||||
(sp, st) = makeSparkLine xs
|
||||
|
||||
main :: IO ()
|
||||
main =
|
||||
mapM_
|
||||
drawSparkLineWithStats
|
||||
[ "0, 1, 19, 20"
|
||||
, "0, 999, 4000, 4999, 7000, 7999"
|
||||
, "1 2 3 4 5 6 7 8 7 6 5 4 3 2 1"
|
||||
, "1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5"
|
||||
, "3 2 1 0 -1 -2 -3 -4 -3 -2 -1 0 1 2 3"
|
||||
, "-1000 100 1000 500 200 -400 -700 621 -189 3"
|
||||
]
|
||||
37
Task/Sparkline-in-unicode/Haskell/sparkline-in-unicode-2.hs
Normal file
37
Task/Sparkline-in-unicode/Haskell/sparkline-in-unicode-2.hs
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import Data.Bifunctor (bimap)
|
||||
import Data.List (findIndex)
|
||||
import Data.List.Split (splitOneOf)
|
||||
import Data.Maybe (maybe)
|
||||
|
||||
------------------------ SPARK LINE ----------------------
|
||||
|
||||
sparkLine :: [Float] -> String
|
||||
sparkLine [] = ""
|
||||
sparkLine xxs@(x : xs) =
|
||||
fmap
|
||||
( maybe '█' ("▁▂▃▄▅▆▇" !!)
|
||||
. flip findIndex lbounds
|
||||
. (<)
|
||||
)
|
||||
xxs
|
||||
where
|
||||
(mn, mx) = foldr (bimap . min <*> max) (x, x) xs
|
||||
w = (mx - mn) / 8
|
||||
lbounds = (mn +) . (w *) <$> [1 .. 7]
|
||||
|
||||
--------------------------- TEST -------------------------
|
||||
main :: IO ()
|
||||
main =
|
||||
mapM_ putStrLn $
|
||||
sparkLine . parseFloats
|
||||
<$> [ "0, 1, 19, 20",
|
||||
"0, 999, 4000, 4999, 7000, 7999",
|
||||
"1 2 3 4 5 6 7 8 7 6 5 4 3 2 1",
|
||||
"1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5"
|
||||
]
|
||||
|
||||
parseFloats :: String -> [Float]
|
||||
parseFloats =
|
||||
fmap read
|
||||
. filter (not . null)
|
||||
. splitOneOf " ,"
|
||||
7
Task/Sparkline-in-unicode/J/sparkline-in-unicode-1.j
Normal file
7
Task/Sparkline-in-unicode/J/sparkline-in-unicode-1.j
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
spkln =: verb define
|
||||
y spkln~ 4 u:16b2581+i.8 NB. ▁▂▃▄▅▆▇█
|
||||
:
|
||||
'MIN MAX' =. (<./ , >./) y
|
||||
N =. # x
|
||||
x {~ <. (N-1) * (y-MIN) % MAX-MIN
|
||||
)
|
||||
1
Task/Sparkline-in-unicode/J/sparkline-in-unicode-2.j
Normal file
1
Task/Sparkline-in-unicode/J/sparkline-in-unicode-2.j
Normal file
|
|
@ -0,0 +1 @@
|
|||
spkln =: (4 u:16b2581+i.8)&$: : ([ {~ <:@#@[ <.@* ] (- % >./@[ - ]) <./@])
|
||||
1
Task/Sparkline-in-unicode/J/sparkline-in-unicode-3.j
Normal file
1
Task/Sparkline-in-unicode/J/sparkline-in-unicode-3.j
Normal file
|
|
@ -0,0 +1 @@
|
|||
spkln =: (u:9601+i.8)&$: : ([ {~ ((<.@* <:@#)~ ((- % (- >./))~ <./)))
|
||||
41
Task/Sparkline-in-unicode/Java/sparkline-in-unicode.java
Normal file
41
Task/Sparkline-in-unicode/Java/sparkline-in-unicode.java
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
public class Sparkline
|
||||
{
|
||||
String bars="▁▂▃▄▅▆▇█";
|
||||
public static void main(String[] args)
|
||||
{
|
||||
Sparkline now=new Sparkline();
|
||||
float[] arr={1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1};
|
||||
now.display1D(arr);
|
||||
System.out.println(now.getSparkline(arr));
|
||||
float[] arr1={1.5f, 0.5f, 3.5f, 2.5f, 5.5f, 4.5f, 7.5f, 6.5f};
|
||||
now.display1D(arr1);
|
||||
System.out.println(now.getSparkline(arr1));
|
||||
}
|
||||
public void display1D(float[] arr)
|
||||
{
|
||||
for(int i=0;i<arr.length;i++)
|
||||
System.out.print(arr[i]+" ");
|
||||
System.out.println();
|
||||
}
|
||||
public String getSparkline(float[] arr)
|
||||
{
|
||||
float min=Integer.MAX_VALUE;
|
||||
float max=Integer.MIN_VALUE;
|
||||
for(int i=0;i<arr.length;i++)
|
||||
{
|
||||
if(arr[i]<min)
|
||||
min=arr[i];
|
||||
if(arr[i]>max)
|
||||
max=arr[i];
|
||||
}
|
||||
float range=max-min;
|
||||
int num=bars.length()-1;
|
||||
String line="";
|
||||
for(int i=0;i<arr.length;i++)
|
||||
{
|
||||
|
||||
line+=bars.charAt((int)Math.ceil(((arr[i]-min)/range*num)));
|
||||
}
|
||||
return line;
|
||||
}
|
||||
}
|
||||
158
Task/Sparkline-in-unicode/JavaScript/sparkline-in-unicode.js
Normal file
158
Task/Sparkline-in-unicode/JavaScript/sparkline-in-unicode.js
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
(() => {
|
||||
'use strict';
|
||||
|
||||
const main = () => {
|
||||
|
||||
// sparkLine :: [Num] -> String
|
||||
const sparkLine = xs => {
|
||||
const hist = dataBins(8)(xs);
|
||||
return unlines([
|
||||
concat(map(
|
||||
i => '▁▂▃▄▅▆▇█' [i],
|
||||
hist.indexes
|
||||
)),
|
||||
unwords(xs),
|
||||
[
|
||||
'Min: ' + hist.min,
|
||||
'Mean: ' + hist.mean.toFixed(2),
|
||||
'Median: ' + hist.median,
|
||||
'Max: ' + hist.max,
|
||||
].join('\t'),
|
||||
''
|
||||
]);
|
||||
};
|
||||
|
||||
|
||||
// dataBins :: Int -> [Num] ->
|
||||
// {indexes:: [Int], min:: Float, max:: Float,
|
||||
// range :: Float, lbounds :: [Float]}
|
||||
const dataBins = intBins => xs => {
|
||||
const
|
||||
iLast = intBins - 1,
|
||||
ys = sort(xs),
|
||||
mn = ys[0],
|
||||
mx = last(ys),
|
||||
rng = mx - mn,
|
||||
w = rng / intBins,
|
||||
lng = xs.length,
|
||||
mid = lng / 2,
|
||||
lbounds = map(
|
||||
i => mn + (w * i),
|
||||
enumFromTo(1, iLast)
|
||||
);
|
||||
return {
|
||||
indexes: map(
|
||||
x => {
|
||||
const mb = findIndex(b => b > x, lbounds);
|
||||
return mb.Nothing ? (
|
||||
iLast
|
||||
) : mb.Just;
|
||||
},
|
||||
xs
|
||||
),
|
||||
lbounds: lbounds,
|
||||
min: mn,
|
||||
median: even(lng) ? (
|
||||
sum([ys[mid - 1], ys[mid]]) / 2
|
||||
) : ys[Math.floor(mid)],
|
||||
mean: sum(xs) / lng,
|
||||
max: mx,
|
||||
range: rng
|
||||
};
|
||||
};
|
||||
|
||||
// numbersFromString :: String -> [Float]
|
||||
const numbersFromString = s =>
|
||||
map(x => parseFloat(x, 10),
|
||||
s.split(/[,\s]+/)
|
||||
);
|
||||
|
||||
return unlines(map(
|
||||
compose(sparkLine, numbersFromString),
|
||||
[
|
||||
'0, 1, 19, 20',
|
||||
'0, 999, 4000, 4999, 7000, 7999',
|
||||
'1 2 3 4 5 6 7 8 7 6 5 4 3 2 1',
|
||||
'1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5'
|
||||
]
|
||||
));
|
||||
};
|
||||
|
||||
// GENERIC FUNCTIONS ----------------------------
|
||||
|
||||
// Just :: a -> Maybe a
|
||||
const Just = x => ({
|
||||
type: 'Maybe',
|
||||
Nothing: false,
|
||||
Just: x
|
||||
});
|
||||
|
||||
// Nothing :: Maybe a
|
||||
const Nothing = () => ({
|
||||
type: 'Maybe',
|
||||
Nothing: true,
|
||||
});
|
||||
|
||||
// compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
|
||||
const compose = (f, g) => x => f(g(x));
|
||||
|
||||
// concat :: [[a]] -> [a]
|
||||
// concat :: [String] -> String
|
||||
const concat = xs =>
|
||||
0 < xs.length ? (() => {
|
||||
const unit = 'string' !== typeof xs[0] ? (
|
||||
[]
|
||||
) : '';
|
||||
return unit.concat.apply(unit, xs);
|
||||
})() : [];
|
||||
|
||||
|
||||
// enumFromTo :: (Int, Int) -> [Int]
|
||||
const enumFromTo = (m, n) =>
|
||||
Array.from({
|
||||
length: 1 + n - m
|
||||
}, (_, i) => m + i);
|
||||
|
||||
// even :: Int -> Bool
|
||||
const even = n => 0 === n % 2;
|
||||
|
||||
// last :: [a] -> a
|
||||
const last = xs =>
|
||||
0 < xs.length ? xs.slice(-1)[0] : undefined;
|
||||
|
||||
// map :: (a -> b) -> [a] -> [b]
|
||||
const map = (f, xs) =>
|
||||
(Array.isArray(xs) ? (
|
||||
xs
|
||||
) : xs.split('')).map(f);
|
||||
|
||||
// sort :: Ord a => [a] -> [a]
|
||||
const sort = xs => xs.slice()
|
||||
.sort((a, b) => a < b ? -1 : (a > b ? 1 : 0));
|
||||
|
||||
|
||||
// findIndex :: (a -> Bool) -> [a] -> Maybe Int
|
||||
const findIndex = (p, xs) => {
|
||||
const
|
||||
i = (
|
||||
'string' !== typeof xs ? (
|
||||
xs
|
||||
) : xs.split('')
|
||||
).findIndex(p);
|
||||
return -1 !== i ? (
|
||||
Just(i)
|
||||
) : Nothing();
|
||||
};
|
||||
|
||||
// sum :: [Num] -> Num
|
||||
const sum = xs => xs.reduce((a, x) => a + x, 0);
|
||||
|
||||
// unlines :: [String] -> String
|
||||
const unlines = xs => xs.join('\n');
|
||||
|
||||
// unwords :: [String] -> String
|
||||
const unwords = xs => xs.join(' ');
|
||||
|
||||
// MAIN ---
|
||||
return main();
|
||||
})();
|
||||
9
Task/Sparkline-in-unicode/Jq/sparkline-in-unicode.jq
Normal file
9
Task/Sparkline-in-unicode/Jq/sparkline-in-unicode.jq
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
def sparkline:
|
||||
min as $min
|
||||
| ( (max - $min) / 7 ) as $div
|
||||
| map( 9601 + (. - $min) * $div )
|
||||
| implode ;
|
||||
|
||||
def string2array:
|
||||
def tidy: select( length > 0 );
|
||||
[split(" ") | .[] | split(",") | .[] | tidy | tonumber];
|
||||
18
Task/Sparkline-in-unicode/Julia/sparkline-in-unicode.julia
Normal file
18
Task/Sparkline-in-unicode/Julia/sparkline-in-unicode.julia
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
function sparklineit(arr)
|
||||
sparkchars = '\u2581':'\u2588'
|
||||
dyn = length(sparkchars)
|
||||
lo, hi = extrema(arr)
|
||||
b = @. max(ceil(Int, dyn * (arr - lo) / (hi - lo)), 1)
|
||||
return join(sparkchars[b])
|
||||
end
|
||||
|
||||
v = rand(0:10, 10)
|
||||
println("$v → ", sparklineit(v))
|
||||
v = 10rand(10)
|
||||
println("$(round.(v, 2)) → ", sparklineit(v))
|
||||
|
||||
lines = strip.(split("""
|
||||
1 2 3 4 5 6 7 8 7 6 5 4 3 2 1
|
||||
1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5""", "\n"))
|
||||
arrays = map(lin -> split(lin, r"\s+|\s*,\s*") .|> s -> parse(Float64, s), lines)
|
||||
foreach(v -> println("$v → ", sparklineit(v)), arrays)
|
||||
22
Task/Sparkline-in-unicode/Kotlin/sparkline-in-unicode.kotlin
Normal file
22
Task/Sparkline-in-unicode/Kotlin/sparkline-in-unicode.kotlin
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
internal const val bars = "▁▂▃▄▅▆▇█"
|
||||
internal const val n = bars.length - 1
|
||||
|
||||
fun <T: Number> Iterable<T>.toSparkline(): String {
|
||||
var min = Double.MAX_VALUE
|
||||
var max = Double.MIN_VALUE
|
||||
val doubles = map { it.toDouble() }
|
||||
doubles.forEach { i -> when { i < min -> min = i; i > max -> max = i } }
|
||||
val range = max - min
|
||||
return doubles.fold("") { line, d -> line + bars[Math.ceil((d - min) / range * n).toInt()] }
|
||||
}
|
||||
|
||||
fun String.toSparkline() = replace(",", "").split(" ").map { it.toFloat() }.toSparkline()
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val s1 = "1 2 3 4 5 6 7 8 7 6 5 4 3 2 1"
|
||||
println(s1)
|
||||
println(s1.toSparkline())
|
||||
val s2 = "1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5"
|
||||
println(s2)
|
||||
println(s2.toSparkline())
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
command sparklines listOfNums
|
||||
local utfbase=0x2581
|
||||
local tStats, utfp, tmin,tmax,trange
|
||||
put listOfNums into tStats
|
||||
replace ", " with space in tStats
|
||||
replace space with comma in tStats
|
||||
put min(tStats) into tmin
|
||||
put max(tStats) into tmax
|
||||
put tmax - tmin into trange
|
||||
put "Min:" && tmin && tab into plot
|
||||
put "Max:" && tmax && tab after plot
|
||||
put "Range:" && trange && tab after plot
|
||||
put "Mean" && average(tStats) && tab after plot
|
||||
put "Stdev:" && standardDeviation(tStats) && tab after plot
|
||||
put "Variance:" && variance(tStats) && return after plot
|
||||
|
||||
repeat for each item i in tStats
|
||||
put (round(i - tmin/trange * 7)) + utfbase into utfp
|
||||
put numToCodepoint(utfp) after plot
|
||||
end repeat
|
||||
put plot
|
||||
end sparklines
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
Module CheckIt {
|
||||
Function Row$(a) {
|
||||
def item$(a)=str$(car(a)#val(0),0)
|
||||
rep$=item$(a)
|
||||
while len(a)
|
||||
rep$+=", "+item$(a)
|
||||
a=cdr(a)
|
||||
End While
|
||||
=rep$
|
||||
}
|
||||
Font "Dejavu Sans Mono"
|
||||
Cls
|
||||
Const bar$="▁▂▃▄▅▆▇█"
|
||||
Document doc$
|
||||
data1=(1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1)
|
||||
data2=(1.5, 0.5, 3.5, 2.5, 5.5, 4.5, 7.5, 6.5)
|
||||
SparkLine(data1)
|
||||
SparkLine(data2)
|
||||
Clipboard doc$
|
||||
Sub SparkLine(dat as array)
|
||||
Local min=dat#min(), range=(dat#max()-dat#min()), range1=7/range
|
||||
Local item, rep$="Input:"+Row$(dat)+{
|
||||
}
|
||||
item=each(dat)
|
||||
While item
|
||||
rep$+=Mid$(bar$,(array(item)-min)*range1+1 ,1)
|
||||
End While
|
||||
rep$+=" ("+str$(range,1033)+")"
|
||||
doc$=rep$+{
|
||||
}
|
||||
Report rep$
|
||||
End Sub
|
||||
}
|
||||
Checkit
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
Module CheckIt {
|
||||
Font "Dejavu Sans Mono"
|
||||
Cls
|
||||
Const bar$="▁▂▃▄▅▆▇█"
|
||||
Document doc$
|
||||
data1$="1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1"
|
||||
data2$="1.5, 0.5, 3.5, 2.5, 5.5, 4.5, 7.5, 6.5"
|
||||
SparkLine(data1$)
|
||||
SparkLine(data2$)
|
||||
Clipboard doc$
|
||||
Sub SparkLine(dat$)
|
||||
dat=(param(dat$))
|
||||
Rem dat=eval$("("+dat$+")")
|
||||
Local min=dat#min(), range=(dat#max()-dat#min()), range1=7/range
|
||||
Local item, rep$="Input:"+dat$+{
|
||||
}
|
||||
item=each(dat)
|
||||
While item
|
||||
rep$+=Mid$(bar$,(array(item)-min)*range1+1 ,1)
|
||||
End While
|
||||
rep$+=" ("+str$(range,1033)+")"
|
||||
doc$=rep$+{
|
||||
}
|
||||
Report rep$
|
||||
End Sub
|
||||
}
|
||||
Checkit
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
Module CheckIt {
|
||||
Function ExtractDat(dat$) {
|
||||
Flush
|
||||
Stack dat$
|
||||
=array([])
|
||||
}
|
||||
Font "Dejavu Sans Mono"
|
||||
Cls
|
||||
Const bar$="▁▂▃▄▅▆▇█"
|
||||
Document doc$
|
||||
data1$="1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1"
|
||||
data2$="1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5 "
|
||||
SparkLine(data1$)
|
||||
SparkLine(data2$)
|
||||
Clipboard doc$
|
||||
Sub SparkLine(dat$)
|
||||
dat=ExtractDat(dat$)
|
||||
Rem dat=eval$("("+dat$+")")
|
||||
Local min=dat#min(), range=(dat#max()-dat#min()), range1=7/range
|
||||
Local item, rep$="Input:"+dat$+{
|
||||
}
|
||||
item=each(dat)
|
||||
While item
|
||||
rep$+=Mid$(bar$,(array(item)-min)*range1+1 ,1)
|
||||
End While
|
||||
rep$+=" ("+str$(range,1033)+")"
|
||||
doc$=rep$+{
|
||||
}
|
||||
Report rep$
|
||||
End Sub
|
||||
}
|
||||
Checkit
|
||||
|
|
@ -0,0 +1 @@
|
|||
toSparkline[data_String] := FromCharacterCode[Round[7 Rescale@Flatten@ImportString[data, "Table", "FieldSeparators" -> {" ", ","}]] + 16^^2581];
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/* NetRexx */
|
||||
options replace format comments java crossref symbols nobinary
|
||||
|
||||
runSample(arg)
|
||||
return
|
||||
|
||||
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
method sparkline(spark) private static
|
||||
spark = spark.changestr(',', ' ')
|
||||
bars = '\u2581 \u2582 \u2583 \u2584 \u2585 \u2586 \u2587 \u2588'
|
||||
barK = bars.words()
|
||||
nmin = spark.word(1)
|
||||
nmax = nmin
|
||||
-- get min & max values
|
||||
loop iw = 1 to spark.words()
|
||||
nval = spark.word(iw)
|
||||
nmin = nval.min(nmin)
|
||||
nmax = nval.max(nmax)
|
||||
end iw
|
||||
range = nmax - nmin + 1
|
||||
slope = ''
|
||||
loop iw = 1 to spark.words()
|
||||
point = Math.ceil((spark.word(iw) - nmin + 1) / range * barK)
|
||||
slope = slope || bars.word(point)
|
||||
end iw
|
||||
return slope nmin nmax range
|
||||
|
||||
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
method runSample(arg) private static
|
||||
-- sample data setup
|
||||
parse arg vals
|
||||
sparks = 0
|
||||
sparks[0] = 0
|
||||
if vals = '' then do
|
||||
si = sparks[0] + 1; sparks[0] = si; sparks[si] = 1 2 3 4 5 6 7 8 7 6 5 4 3 2 1
|
||||
si = sparks[0] + 1; sparks[0] = si; sparks[si] = '1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5'
|
||||
end
|
||||
else do
|
||||
loop until vals = ''
|
||||
-- split input on a ! character
|
||||
parse vals lst '!' vals
|
||||
si = sparks[0] + 1; sparks[0] = si; sparks[si] = lst
|
||||
end
|
||||
end
|
||||
-- run the samples
|
||||
loop si = 1 to sparks[0]
|
||||
vals = sparks[si]
|
||||
parse sparkline(vals) slope .
|
||||
say 'Input: ' vals
|
||||
say 'Sparkline: ' slope
|
||||
say
|
||||
end si
|
||||
|
||||
return
|
||||
18
Task/Sparkline-in-unicode/Nim/sparkline-in-unicode.nim
Normal file
18
Task/Sparkline-in-unicode/Nim/sparkline-in-unicode.nim
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import rdstdin, sequtils, strutils
|
||||
|
||||
const bar = ["\u2581", "\u2582", "\u2583", "\u2584", "\u2585", "\u2586", "\u2587", "\u2588"]
|
||||
const barcount = float(bar.high)
|
||||
|
||||
while true:
|
||||
let
|
||||
line = readLineFromStdin "Numbers please separated by space/commas: "
|
||||
numbers = line.split({' ', ','}).filterIt(it.len != 0).map(parseFloat)
|
||||
mn = min(numbers)
|
||||
mx = max(numbers)
|
||||
extent = mx - mn
|
||||
var sparkline = ""
|
||||
for n in numbers:
|
||||
let i = int((n - mn) / extent * barcount)
|
||||
sparkline.add bar[i]
|
||||
echo "min: ", mn.formatFloat(precision = 0), "; max: ", mx.formatFloat(precision = -1)
|
||||
echo sparkline
|
||||
38
Task/Sparkline-in-unicode/OCaml/sparkline-in-unicode.ocaml
Normal file
38
Task/Sparkline-in-unicode/OCaml/sparkline-in-unicode.ocaml
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
let before_first_bar = 0x2580
|
||||
let num_bars = 8
|
||||
|
||||
let sparkline numbers =
|
||||
let max_num = List.fold_left max 0. numbers in
|
||||
let scale = float_of_int num_bars /. max_num in
|
||||
let bars = Buffer.create num_bars in
|
||||
let add_bar number =
|
||||
let scaled = scale *. number |> Float.round |> int_of_float in
|
||||
if scaled <= 0 then
|
||||
(* Using underscore character to differentiate between zero and one *)
|
||||
Buffer.add_char bars '_'
|
||||
else
|
||||
scaled + before_first_bar |> Uchar.of_int |> Buffer.add_utf_8_uchar bars
|
||||
in
|
||||
List.iter add_bar numbers;
|
||||
Buffer.contents bars
|
||||
|
||||
let print_sparkline line =
|
||||
Printf.printf "Numbers: %s\n" line;
|
||||
line
|
||||
|> String.trim
|
||||
|> String.split_on_char ' '
|
||||
|> List.map (String.split_on_char ',')
|
||||
|> List.flatten
|
||||
|> List.filter_map (function
|
||||
| "" -> None
|
||||
| number -> Some (float_of_string number))
|
||||
|> sparkline
|
||||
|> print_endline
|
||||
|
||||
let () =
|
||||
"0 0 1 1; 0 1 19 20; 0 999 4000 4999 7000 7999;
|
||||
1 2 3 4 5 6 7 8 7 6 5 4 3 2 1;
|
||||
1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5 "
|
||||
|> String.trim
|
||||
|> String.split_on_char ';'
|
||||
|> List.iter print_sparkline
|
||||
29
Task/Sparkline-in-unicode/Perl/sparkline-in-unicode.pl
Normal file
29
Task/Sparkline-in-unicode/Perl/sparkline-in-unicode.pl
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
binmode(STDOUT, ":utf8");
|
||||
our @sparks=map {chr} 0x2581 .. 0x2588;
|
||||
sub sparkline :prototype(@) {
|
||||
my @n=map {0+$_} grep {length} @_ or return "";
|
||||
my($min,$max)=($n[0])x2;
|
||||
if (@n>1) {
|
||||
for (@n[1..$#n]) {
|
||||
if ($_<$min) { $min=$_ }
|
||||
elsif ($_>$max) { $max=$_ }
|
||||
}
|
||||
}
|
||||
my $sparkline="";
|
||||
for(@n) {
|
||||
my $height=int( $max==$min ? @sparks/2 : ($_-$min)/($max-$min)*@sparks );
|
||||
$height=$#sparks if $height>$#sparks;
|
||||
$sparkline.=$sparks[$height];
|
||||
}
|
||||
my $summary=sprintf "%d values; range %s..%s", scalar(@n), $min, $max;
|
||||
return wantarray ? ($summary, "\n", $sparkline, "\n") : $sparkline;
|
||||
}
|
||||
|
||||
# one number per line
|
||||
# print sparkline( <> );
|
||||
|
||||
# in scalar context, get just the sparkline without summary or trailing newline
|
||||
# my $sl=sparkline( <> ); print $sl;
|
||||
|
||||
# one sparkline per line
|
||||
print sparkline( split /[\s,]+/ ) while <>;
|
||||
30
Task/Sparkline-in-unicode/Phix/sparkline-in-unicode.phix
Normal file
30
Task/Sparkline-in-unicode/Phix/sparkline-in-unicode.phix
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
|
||||
<span style="color: #7060A8;">requires</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1.0.2"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- (a fix for JS)</span>
|
||||
<span style="color: #008080;">include</span> <span style="color: #000000;">builtins</span><span style="color: #0000FF;">\</span><span style="color: #000000;">unicode_console</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
|
||||
|
||||
<span style="color: #008080;">constant</span> <span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"0 1 19 20"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"0 0 1 1"</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #008000;">"0 999 4000 4999 7000 7999"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"1 1 2 2 3 3"</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #008000;">"1 2 3 4 5 6 7 8 7 6 5 4 3 2 1"</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #008000;">"1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5"</span><span style="color: #0000FF;">}</span>
|
||||
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">ti</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split_any</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #008000;">" ,"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #0000FF;">{{</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]}}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">scanf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">],</span><span style="color: #008000;">"%f"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #004080;">atom</span> <span style="color: #000000;">mn</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">min</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #000000;">mx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">max</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #000000;">range</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">mx</span><span style="color: #0000FF;">-</span><span style="color: #000000;">mn</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Min :%g, Max :%g, Range :%g\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">mn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">mx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">range</span><span style="color: #0000FF;">})</span>
|
||||
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">unicode_console</span><span style="color: #0000FF;">()</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">ti</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">#2581</span> <span style="color: #0000FF;">+</span> <span style="color: #7060A8;">min</span><span style="color: #0000FF;">(</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">((</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]-</span><span style="color: #000000;">mn</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">range</span><span style="color: #0000FF;">*</span><span style="color: #000000;">8</span><span style="color: #0000FF;">))</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">utf32_to_utf8</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">)})</span>
|
||||
<span style="color: #008080;">else</span>
|
||||
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"unicode is not supported\n"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<!--
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
(de sparkLine (Lst)
|
||||
(let (Min (apply min Lst) Max (apply max Lst) Rng (- Max Min))
|
||||
(for N Lst
|
||||
(prin
|
||||
(char (+ 9601 (*/ (- N Min) 7 Rng)) ) ) )
|
||||
(prinl) ) )
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
(sparkLine (str "1 2 3 4 5 6 7 8 7 6 5 4 3 2 1"))
|
||||
(sparkLine (scl 1 (str "1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5")))
|
||||
25
Task/Sparkline-in-unicode/Python/sparkline-in-unicode-1.py
Normal file
25
Task/Sparkline-in-unicode/Python/sparkline-in-unicode-1.py
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Unicode: 9601, 9602, 9603, 9604, 9605, 9606, 9607, 9608
|
||||
bar = '▁▂▃▄▅▆▇█'
|
||||
barcount = len(bar)
|
||||
|
||||
def sparkline(numbers):
|
||||
mn, mx = min(numbers), max(numbers)
|
||||
extent = mx - mn
|
||||
sparkline = ''.join(bar[min([barcount - 1,
|
||||
int((n - mn) / extent * barcount)])]
|
||||
for n in numbers)
|
||||
return mn, mx, sparkline
|
||||
|
||||
if __name__ == '__main__':
|
||||
import re
|
||||
|
||||
for line in ("0 0 1 1; 0 1 19 20; 0 999 4000 4999 7000 7999;"
|
||||
"1 2 3 4 5 6 7 8 7 6 5 4 3 2 1;"
|
||||
"1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5 ").split(';'):
|
||||
print("\nNumbers:", line)
|
||||
numbers = [float(n) for n in re.split(r'[\s,]+', line.strip())]
|
||||
mn, mx, sp = sparkline(numbers)
|
||||
print(' min: %5f; max: %5f' % (mn, mx))
|
||||
print(" " + sp)
|
||||
170
Task/Sparkline-in-unicode/Python/sparkline-in-unicode-2.py
Normal file
170
Task/Sparkline-in-unicode/Python/sparkline-in-unicode-2.py
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
'''Sparkline in Unicode'''
|
||||
|
||||
from functools import reduce
|
||||
import operator
|
||||
import re
|
||||
|
||||
|
||||
# ------------------- LABELLED SPARKLINE -------------------
|
||||
|
||||
# sparkLine :: [Float] -> [String]
|
||||
def sparkLine(xs):
|
||||
'''Unicode sparkline summary of a
|
||||
list of floating point numbers.
|
||||
'''
|
||||
def go(xs):
|
||||
ys = sorted(xs)
|
||||
mn, mx = ys[0], ys[-1]
|
||||
n = len(xs)
|
||||
mid = n // 2
|
||||
w = (mx - mn) / 8
|
||||
lbounds = list(map(lambda i: mn + (w * i), range(1, 8)))
|
||||
le = curry(operator.le)
|
||||
|
||||
# spark :: Float -> Char
|
||||
def spark(x):
|
||||
def go(i):
|
||||
return '▁▂▃▄▅▆▇'[i]
|
||||
return maybe('█')(go)(
|
||||
findIndex(le(x))(lbounds)
|
||||
)
|
||||
return [
|
||||
''.join(map(spark, xs)),
|
||||
' '.join(map(str, xs)),
|
||||
'\t'.join([
|
||||
'Min ' + str(mn),
|
||||
'Mean ' + str(round(mean(xs), 2)),
|
||||
'Median ' + str(
|
||||
(ys[mid - 1] + ys[mid]) / 2 if even(n) else (
|
||||
ys[mid]
|
||||
)
|
||||
),
|
||||
'Max ' + str(mx)
|
||||
]),
|
||||
''
|
||||
]
|
||||
return go(xs) if xs else []
|
||||
|
||||
|
||||
# -------------------------- TEST --------------------------
|
||||
# main :: IO ()
|
||||
def main():
|
||||
'''Tested on some sample lists.
|
||||
'''
|
||||
print(
|
||||
unlines(map(
|
||||
compose(compose(unlines, sparkLine), readFloats),
|
||||
[
|
||||
"0, 1, 19, 20",
|
||||
"0, 999, 4000, 4999, 7000, 7999",
|
||||
"1 2 3 4 5 6 7 8 7 6 5 4 3 2 1",
|
||||
"1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5"
|
||||
]
|
||||
))
|
||||
)
|
||||
|
||||
|
||||
# ------------------------ GENERIC -------------------------
|
||||
|
||||
# Just :: a -> Maybe a
|
||||
def Just(x):
|
||||
'''Constructor for an inhabited Maybe (option type) value.
|
||||
Wrapper containing the result of a computation.
|
||||
'''
|
||||
return {'type': 'Maybe', 'Nothing': False, 'Just': x}
|
||||
|
||||
|
||||
# Nothing :: Maybe a
|
||||
def Nothing():
|
||||
'''Constructor for an empty Maybe (option type) value.
|
||||
Empty wrapper returned where a computation is not possible.
|
||||
'''
|
||||
return {'type': 'Maybe', 'Nothing': True}
|
||||
|
||||
|
||||
# compose :: ((a -> a), ...) -> (a -> a)
|
||||
def compose(*fs):
|
||||
'''Composition, from right to left,
|
||||
of a series of functions.
|
||||
'''
|
||||
def go(f, g):
|
||||
def fg(x):
|
||||
return f(g(x))
|
||||
return fg
|
||||
return reduce(go, fs, lambda x: x)
|
||||
|
||||
|
||||
# curry :: ((a, b) -> c) -> a -> b -> c
|
||||
def curry(f):
|
||||
'''A curried function derived
|
||||
from an uncurried function.
|
||||
'''
|
||||
return lambda x: lambda y: f(x, y)
|
||||
|
||||
|
||||
# even :: Int -> Bool
|
||||
def even(x):
|
||||
'''True if x is an integer
|
||||
multiple of two.
|
||||
'''
|
||||
return 0 == x % 2
|
||||
|
||||
|
||||
# findIndex :: (a -> Bool) -> [a] -> Maybe Int
|
||||
def findIndex(p):
|
||||
'''Just the first index at which an
|
||||
element in xs matches p,
|
||||
or Nothing if no elements match.
|
||||
'''
|
||||
def go(xs):
|
||||
try:
|
||||
return Just(next(
|
||||
i for i, v in enumerate(xs) if p(v)
|
||||
))
|
||||
except StopIteration:
|
||||
return Nothing()
|
||||
return go
|
||||
|
||||
|
||||
# maybe :: b -> (a -> b) -> Maybe a -> b
|
||||
def maybe(v):
|
||||
'''Either the default value v, if m is Nothing,
|
||||
or the application of f to x,
|
||||
where m is Just(x).
|
||||
'''
|
||||
return lambda f: lambda m: v if (
|
||||
None is m or m.get('Nothing')
|
||||
) else f(m.get('Just'))
|
||||
|
||||
|
||||
# mean :: [Num] -> Float
|
||||
def mean(xs):
|
||||
'''The arithmetic mean of the numeric
|
||||
values in xs.
|
||||
'''
|
||||
return sum(xs) / float(len(xs))
|
||||
|
||||
|
||||
# readFloats :: String -> [Float]
|
||||
def readFloats(s):
|
||||
'''A list of floats parsed from
|
||||
a numeric string delimited by
|
||||
commas and/or white space.
|
||||
'''
|
||||
return list(map(
|
||||
float,
|
||||
re.split(r'[\s,]+', s)
|
||||
))
|
||||
|
||||
|
||||
# unlines :: [String] -> String
|
||||
def unlines(xs):
|
||||
'''A single string formed by the intercalation
|
||||
of a list of strings with the newline character.
|
||||
'''
|
||||
return '\n'.join(xs)
|
||||
|
||||
|
||||
# MAIN ---
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
23
Task/Sparkline-in-unicode/R/sparkline-in-unicode-1.r
Normal file
23
Task/Sparkline-in-unicode/R/sparkline-in-unicode-1.r
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
bars <- intToUtf8(seq(0x2581, 0x2588), multiple = T) # ▁ ▂ ▃ ▄ ▅ ▆ ▇ █
|
||||
n_chars <- length(bars)
|
||||
|
||||
sparkline <- function(numbers) {
|
||||
mn <- min(numbers)
|
||||
mx <- max(numbers)
|
||||
interval <- mx - mn
|
||||
|
||||
bins <- sapply(
|
||||
numbers,
|
||||
function(i)
|
||||
bars[[1 + min(n_chars - 1, floor((i - mn) / interval * n_chars))]]
|
||||
)
|
||||
sparkline <- paste0(bins, collapse = "")
|
||||
|
||||
return(sparkline)
|
||||
}
|
||||
|
||||
sparkline(c(1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1))
|
||||
sparkline(c(1.5, 0.5, 3.5, 2.5, 5.5, 4.5, 7.5, 6.5))
|
||||
sparkline(c(0, 999, 4000, 4999, 7000, 7999))
|
||||
sparkline(c(0, 0, 1, 1))
|
||||
sparkline(c(0, 1, 19, 20))
|
||||
6
Task/Sparkline-in-unicode/R/sparkline-in-unicode-2.r
Normal file
6
Task/Sparkline-in-unicode/R/sparkline-in-unicode-2.r
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[1] "▂▁▄▃▆▅█▇"
|
||||
[1] "▁▂▃▄▅▆▇█▇▆▅▄▃▂▁"
|
||||
[1] "▂▁▄▃▆▅█▇"
|
||||
[1] "▁▁▅▅██"
|
||||
[1] "▁▁██"
|
||||
[1] "▁▁██"
|
||||
67
Task/Sparkline-in-unicode/REXX/sparkline-in-unicode-1.rexx
Normal file
67
Task/Sparkline-in-unicode/REXX/sparkline-in-unicode-1.rexx
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/* Rexx */
|
||||
|
||||
parse arg aaa
|
||||
call runSample aaa
|
||||
return
|
||||
|
||||
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
sparkline:
|
||||
procedure
|
||||
parse arg spark
|
||||
spark = changestr(',', spark, ' ')
|
||||
bars = '▁ ▂ ▃ ▄ ▅ ▆ ▇ █'
|
||||
barK = words(bars)
|
||||
nmin = word(spark, 1)
|
||||
nmax = nmin
|
||||
-- get min & max values
|
||||
do iw = 1 to words(spark)
|
||||
nval = word(spark, iw)
|
||||
nmin = min(nval, nmin)
|
||||
nmax = max(nval, nmax)
|
||||
end iw
|
||||
range = nmax - nmin + 1
|
||||
slope = ''
|
||||
do iw = 1 to words(spark)
|
||||
point = ceiling((word(spark, iw) - nmin + 1) / range * barK)
|
||||
slope = slope || word(bars, point)
|
||||
end iw
|
||||
return slope nmin nmax range
|
||||
|
||||
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
ceiling:
|
||||
procedure
|
||||
parse arg ceil
|
||||
return trunc(ceil) + (ceil > 0) * (ceil \= trunc(ceil))
|
||||
floor:
|
||||
procedure
|
||||
parse arg flor
|
||||
return trunc(flor) - (flor < 0) * (flor \= trunc(flor))
|
||||
|
||||
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
runSample:
|
||||
procedure
|
||||
-- sample data setup
|
||||
parse arg vals
|
||||
sparks = 0
|
||||
sparks.0 = 0
|
||||
if vals = '' then do
|
||||
si = sparks.0 + 1; sparks.0 = si; sparks.si = 1 2 3 4 5 6 7 8 7 6 5 4 3 2 1
|
||||
si = sparks.0 + 1; sparks.0 = si; sparks.si = '1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5'
|
||||
end
|
||||
else do
|
||||
do until vals = ''
|
||||
-- split input on a ! character
|
||||
parse var vals lst '!' vals
|
||||
si = sparks.0 + 1; sparks.0 = si; sparks.si = lst
|
||||
end
|
||||
end
|
||||
-- run the samples
|
||||
do si = 1 to sparks.0
|
||||
vals = sparks.si
|
||||
parse value sparkline(vals) with slope .
|
||||
say 'Input: ' vals
|
||||
say 'Sparkline: ' slope
|
||||
say
|
||||
end si
|
||||
|
||||
return
|
||||
25
Task/Sparkline-in-unicode/REXX/sparkline-in-unicode-2.rexx
Normal file
25
Task/Sparkline-in-unicode/REXX/sparkline-in-unicode-2.rexx
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/*REXX program displays a sparkline (spark graph) for a group of values. */
|
||||
if arg()==0 then do /*Optional arguments? Then use defaults*/
|
||||
call sparkGraph 1 2 3 4 5 6 7 8 7 6 5 4 3 2 1
|
||||
call sparkGraph '1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5'
|
||||
end
|
||||
else call sparkGraph arg(1)
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
ceil: procedure; parse arg ?; _=trunc(?); return _+(?>0)*(?\=_)
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
sparkGraph: procedure; parse arg x; say ' input: ' x /*echo the values.*/
|
||||
x= translate(x, ' ', ",") /*remove any superfluous commas. */
|
||||
$= '▁▂▃▄▅▆▇█'; L= length($) /*chars to be used for the graph.*/
|
||||
xmin= word(x, 1); xmax= xmin /*assume a minimum and a maximum.*/
|
||||
|
||||
do n=2 to words(x); _= word(x, n) /*examine successive words in X.*/
|
||||
xmin= min(_, xmin) /*find the minimum value in X. */
|
||||
xmax= max(_, xmax) /* " " maximum " " " */
|
||||
end /*n*/
|
||||
z=
|
||||
do j=1 for words(x) /*build the output spark graph. */
|
||||
z= z || substr($, ceil( ( word(x, j) -xmin+1) / (xmax -xmin+1) * L), 1)
|
||||
end /*j*/
|
||||
|
||||
say 'output: ' z; say; return /*show the output, + a blank line*/
|
||||
13
Task/Sparkline-in-unicode/Racket/sparkline-in-unicode-1.rkt
Normal file
13
Task/Sparkline-in-unicode/Racket/sparkline-in-unicode-1.rkt
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#lang racket (require syntax/parse)
|
||||
|
||||
(define bars "▁▂▃▄▅▆▇█")
|
||||
(define bar-count (string-length bars))
|
||||
|
||||
(define (sparks str)
|
||||
(define ns (map string->number (string-split str #rx"[ ,]" #:repeat? #t)))
|
||||
(define mn (apply min ns))
|
||||
(define bar-width (/ (- (apply max ns) mn) (- bar-count 1)))
|
||||
(apply string (for/list ([n ns]) (string-ref bars (exact-floor (/ (- n mn) bar-width))))))
|
||||
|
||||
(sparks "1 2 3 4 5 6 7 8 7 6 5 4 3 2 1")
|
||||
(sparks "1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5")
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
"▁▂▃▄▅▆▇█▇▆▅▄▃▂▁"
|
||||
"▂▁▄▃▆▅█▇"
|
||||
7
Task/Sparkline-in-unicode/Raku/sparkline-in-unicode.raku
Normal file
7
Task/Sparkline-in-unicode/Raku/sparkline-in-unicode.raku
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
constant @bars = '▁' ... '█';
|
||||
while prompt 'Numbers separated by anything: ' -> $_ {
|
||||
my @numbers = map +*, .comb(/ '-'? [[\d+ ['.' \d*]?] | ['.' \d+]] /);
|
||||
my ($mn,$mx) = @numbers.minmax.bounds;
|
||||
say "min: $mn.fmt('%5f'); max: $mx.fmt('%5f')";
|
||||
say @bars[ @numbers.map: { @bars * ($_ - $mn) / ($mx - $mn) min @bars - 1 } ].join;
|
||||
}
|
||||
8
Task/Sparkline-in-unicode/Ruby/sparkline-in-unicode.rb
Normal file
8
Task/Sparkline-in-unicode/Ruby/sparkline-in-unicode.rb
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
bar = ('▁'..'█').to_a
|
||||
loop {print 'Numbers please separated by space/commas: '
|
||||
numbers = gets.split(/[\s,]+/).map(&:to_f)
|
||||
min, max = numbers.minmax
|
||||
puts "min: %5f; max: %5f"% [min, max]
|
||||
div = (max - min) / (bar.size - 1)
|
||||
puts min == max ? bar.last*numbers.size : numbers.map{|num| bar[((num - min) / div).to_i]}.join
|
||||
}
|
||||
17
Task/Sparkline-in-unicode/Rust/sparkline-in-unicode.rust
Normal file
17
Task/Sparkline-in-unicode/Rust/sparkline-in-unicode.rust
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
const BARS: &'static str = "▁▂▃▄▅▆▇█";
|
||||
|
||||
fn print_sparkline(s: &str){
|
||||
let v = BARS.chars().collect::<Vec<char>>();
|
||||
let line: String = s.replace(",", " ").split(" ")
|
||||
.filter(|x| !x.is_empty())
|
||||
.map(|x| v[x.parse::<f64>().unwrap().ceil() as usize - 1])
|
||||
.collect();
|
||||
println!("{:?}", line);
|
||||
}
|
||||
|
||||
fn main(){
|
||||
let s1 = "1 2 3 4 5 6 7 8 7 6 5 4 3 2 1";
|
||||
print_sparkline(s1);
|
||||
let s2 = "1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5";
|
||||
print_sparkline(s2);
|
||||
}
|
||||
25
Task/Sparkline-in-unicode/S-lang/sparkline-in-unicode.slang
Normal file
25
Task/Sparkline-in-unicode/S-lang/sparkline-in-unicode.slang
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
% Just to demonstrate alternate ways of defining unicode:
|
||||
private variable spchrs = "\u{2581}\u{2582}\u{2583}\u{2584}\u{2585}\u{2586}\u{2587}\u{2588}";
|
||||
private variable spchrs_alt = "▁▂▃▄▅▆▇█";
|
||||
|
||||
define sparkline(arrstr)
|
||||
{
|
||||
variable a = strtok(arrstr, " \t,"), alen = length(a), out = "";
|
||||
a = atof(a);
|
||||
variable amin = min(a), amax = max(a), span = amax - amin, i, d;
|
||||
|
||||
_for i (0, alen-1, 1)
|
||||
if (span != 0) {
|
||||
% int() truncates; adding .5 here to round:
|
||||
d = int((a[i] - amin) * 7.0 / span + 0.5);
|
||||
out += substr(spchrs, d+1, 1);
|
||||
}
|
||||
else
|
||||
out += substr(spchrs, 4, 1);
|
||||
|
||||
print(out);
|
||||
}
|
||||
|
||||
if (not _slang_utf8_ok) error("Sorry, UTF8 mode is not on.");
|
||||
sparkline("1 2 3 4 5 6 7 8 7 6 5 4 3 2 1");
|
||||
sparkline("1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5 ");
|
||||
16
Task/Sparkline-in-unicode/Scala/sparkline-in-unicode.scala
Normal file
16
Task/Sparkline-in-unicode/Scala/sparkline-in-unicode.scala
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
def mkSparks( numStr:String ) : String =
|
||||
numStr.split( "[\\s,]+" ).map(_.toFloat) match {
|
||||
case v if v.isEmpty => ""
|
||||
case v if v.length == 1 => "\u2581"
|
||||
case v =>
|
||||
(for( i <- v;
|
||||
s = "\u2581\u2582\u2583\u2584\u2585\u2586\u2587\u2588".toCharArray;
|
||||
d = (v.max - v.min) / (s.length - 1)
|
||||
) yield s( ((i - v.min) / d).toInt)).mkString
|
||||
}
|
||||
|
||||
println( mkSparks( "1 2 3 4 5 6 7 8 7 6 5 4 3 2 1" ) )
|
||||
println( mkSparks( "1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5" ) )
|
||||
|
||||
// A random test...
|
||||
println( mkSparks( Stream.continually( math.abs(util.Random.nextInt % 8)).take(64).mkString(" ") ))
|
||||
53
Task/Sparkline-in-unicode/Seed7/sparkline-in-unicode.seed7
Normal file
53
Task/Sparkline-in-unicode/Seed7/sparkline-in-unicode.seed7
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
$ include "seed7_05.s7i";
|
||||
include "scanfile.s7i";
|
||||
include "float.s7i";
|
||||
include "utf8.s7i";
|
||||
|
||||
const func array float: readDataLine is func
|
||||
result
|
||||
var array float: data is 0 times 0.0;
|
||||
begin
|
||||
write("Numbers separated by anything: ");
|
||||
IN.bufferChar := getc(IN);
|
||||
skipSpace(IN);
|
||||
while IN.bufferChar <> '\n' do
|
||||
data &:= float parse getNumber(IN);
|
||||
skipSpace(IN);
|
||||
if IN.bufferChar = ',' then
|
||||
IN.bufferChar := getc(IN);
|
||||
end if;
|
||||
skipSpace(IN);
|
||||
end while;
|
||||
end func;
|
||||
|
||||
|
||||
const proc: main is func
|
||||
local
|
||||
const string: bars is "▁▂▃▄▅▆▇█";
|
||||
var array float: data is 0 times 0.0;
|
||||
var float: min is 0.0;
|
||||
var float: max is 0.0;
|
||||
var float: number is 0.0;
|
||||
var integer: index is 0;
|
||||
begin
|
||||
OUT := STD_UTF8_OUT;
|
||||
data := readDataLine;
|
||||
while length(data) >= 1 do
|
||||
min := data[1];
|
||||
max := data[1];
|
||||
for number range data do
|
||||
if number < min then
|
||||
min := number;
|
||||
end if;
|
||||
if number > max then
|
||||
max := number;
|
||||
end if;
|
||||
end for;
|
||||
for number range data do
|
||||
index := succ(min(trunc((number - min) * 8.0 / max), 7));
|
||||
write(bars[index]);
|
||||
end for;
|
||||
writeln;
|
||||
data := readDataLine;
|
||||
end while;
|
||||
end func;
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
put sparklineGraph of "1 2 3 4 5 6 7 8 7 6 5 4 3 2 1"
|
||||
put sparklineGraph of "1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5"
|
||||
put sparklineGraph of "0, 1, 19, 20"
|
||||
put sparklineGraph of "0, 999, 4000, 4999, 7000, 7999"
|
||||
|
||||
to handle sparklineGraph of input
|
||||
put each word delimited by " ," of input into numbers
|
||||
put the lowestValue of numbers into bottom
|
||||
put the highestValue of numbers into top
|
||||
put top - bottom into range -- total range of values
|
||||
put range/8 into step -- the size of each incremental step in the graph
|
||||
|
||||
repeat with each number in numbers
|
||||
put (trunc((number - bottom) / step) + 1) but no more than 8 into symbolNum
|
||||
put character symbolNum of "▁▂▃▄▅▆▇█" after graph
|
||||
end repeat
|
||||
put !" (range: [[bottom]] to [[top]])" after graph
|
||||
return graph
|
||||
end sparklineGraph
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
var bar = @('▁'..'█');
|
||||
loop {
|
||||
print 'Numbers, please, separated by space/commas: ';
|
||||
var numbers = read(String).trim.split(/[\s,]+/).map{.to_n};
|
||||
var (min, max) = numbers.minmax;
|
||||
say "min: %5f; max: %5f"%(min, max);
|
||||
var div = ((max - min) / bar.end);
|
||||
say (min == max ? bar.last*numbers.len : numbers.map{|num| bar[(num - min) / div]}.join);
|
||||
}
|
||||
15
Task/Sparkline-in-unicode/Tcl/sparkline-in-unicode-1.tcl
Normal file
15
Task/Sparkline-in-unicode/Tcl/sparkline-in-unicode-1.tcl
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
package require Tcl 8.6
|
||||
|
||||
proc extractValues {series} {
|
||||
return [regexp -all -inline {\d+(?:\.\d*)?|\.\d+} $series]
|
||||
}
|
||||
proc renderValue {min max value} {
|
||||
set band [expr {int(8*($value-$min)/(($max-$min)*1.01))}]
|
||||
return [format "%c" [expr {0x2581 + $band}]]
|
||||
}
|
||||
proc sparkline {series} {
|
||||
set values [extractValues $series]
|
||||
set min [tcl::mathfunc::min {*}$values]
|
||||
set max [tcl::mathfunc::max {*}$values]
|
||||
return [join [lmap v $values {renderValue $min $max $v}] ""]
|
||||
}
|
||||
8
Task/Sparkline-in-unicode/Tcl/sparkline-in-unicode-2.tcl
Normal file
8
Task/Sparkline-in-unicode/Tcl/sparkline-in-unicode-2.tcl
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
set data {
|
||||
"1 2 3 4 5 6 7 8 7 6 5 4 3 2 1"
|
||||
"1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5"
|
||||
}
|
||||
foreach series $data {
|
||||
puts "Series: $series"
|
||||
puts "Sparkline: [sparkline $series]"
|
||||
}
|
||||
71
Task/Sparkline-in-unicode/VBScript/sparkline-in-unicode.vb
Normal file
71
Task/Sparkline-in-unicode/VBScript/sparkline-in-unicode.vb
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
'Sparkline
|
||||
|
||||
sub ensure_cscript()
|
||||
if instrrev(ucase(WScript.FullName),"WSCRIPT.EXE")then
|
||||
createobject("wscript.shell").run "CSCRIPT //nologo """ &_
|
||||
WScript.ScriptFullName &"""" ,,0
|
||||
wscript.quit
|
||||
end if
|
||||
end sub
|
||||
|
||||
class bargraph
|
||||
private bar,mn,mx,nn,cnt
|
||||
|
||||
Private sub class_initialize()
|
||||
bar=chrw(&h2581)&chrw(&h2582)&chrw(&h2583)&chrw(&h2584)&chrw(&h2585)&_
|
||||
chrw(&h2586)&chrw(&h2587)&chrw(&h2588)
|
||||
nn=8
|
||||
end sub
|
||||
|
||||
|
||||
public function bg (s)
|
||||
a=split(replace(replace(s,","," ")," "," ")," ")
|
||||
|
||||
mn=999999:mx=-999999:cnt=ubound(a)+1
|
||||
for i=0 to ubound(a)
|
||||
a(i)=cdbl(trim(a(i)))
|
||||
if a(i)>mx then mx=a(i)
|
||||
if a(i)<mn then mn=a(i)
|
||||
next
|
||||
|
||||
ss="Data: "
|
||||
for i=0 to ubound(a) :ss=ss & right (" "& a(i),6) :next
|
||||
|
||||
ss=ss+vbcrlf + "sparkline: "
|
||||
|
||||
for i=0 to ubound(a)
|
||||
x=scale(a(i))
|
||||
'wscript.echo mn,mx, a(i),x
|
||||
ss=ss & string(6,mid(bar,x,1))
|
||||
next
|
||||
bg=ss &vbcrlf & "min: "&mn & " max: "& mx & _
|
||||
" cnt: "& ubound(a)+1 &vbcrlf
|
||||
end function
|
||||
|
||||
private function scale(x)
|
||||
if x=<mn then
|
||||
scale=1
|
||||
elseif x>=mx then
|
||||
scale=nn
|
||||
else
|
||||
scale=int(nn* (x-mn)/(mx-mn)+1)
|
||||
end if
|
||||
end function
|
||||
|
||||
end class
|
||||
|
||||
ensure_cscript
|
||||
|
||||
set b=new bargraph
|
||||
wscript.stdout.writeblanklines 2
|
||||
wscript.echo b.bg("1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1")
|
||||
wscript.echo b.bg("1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5")
|
||||
wscript.echo b.bg("0, 1, 19, 20")
|
||||
wscript.echo b.bg("0, 999, 4000, 4999, 7000, 7999")
|
||||
set b=nothing
|
||||
|
||||
wscript.echo "If bars don't display correctly please set the the console " & _
|
||||
"font to DejaVu Sans Mono or any other that has the bargrph characters" & _
|
||||
vbcrlf
|
||||
|
||||
wscript.stdout.write "Press any key.." : wscript.stdin.read 1
|
||||
56
Task/Sparkline-in-unicode/Wren/sparkline-in-unicode.wren
Normal file
56
Task/Sparkline-in-unicode/Wren/sparkline-in-unicode.wren
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
import "io" for Stdin, Stdout
|
||||
import "/pattern" for Pattern
|
||||
|
||||
var p = Pattern.new("[,+1/s|+1/s,|+1/s|,]")
|
||||
|
||||
var spark = Fn.new { |s0|
|
||||
var ss = p.splitAll(s0)
|
||||
var n = ss.count
|
||||
var vs = List.filled(n, 0)
|
||||
var min = 1/0
|
||||
var max = -min
|
||||
var i = 0
|
||||
for (s in ss) {
|
||||
var v = Num.fromString(s)
|
||||
if (v.isNan || v.isInfinity) Fiber.abort("Infinities and NaN not supported.")
|
||||
if (v < min) min = v
|
||||
if (v > max) max = v
|
||||
vs[i] = v
|
||||
i = i + 1
|
||||
}
|
||||
var sp
|
||||
if (min == max) {
|
||||
sp = "▄" * n
|
||||
} else {
|
||||
var rs = List.filled(n, null)
|
||||
var f = 8 / (max - min)
|
||||
var j = 0
|
||||
for (v in vs) {
|
||||
var i = (f * (v - min)).floor
|
||||
if (i > 7) i = 7
|
||||
rs[j] = String.fromCodePoint(0x2581 + i)
|
||||
j = j + 1
|
||||
}
|
||||
sp = rs.join()
|
||||
}
|
||||
return [sp, n, min, max]
|
||||
}
|
||||
|
||||
while (true) {
|
||||
System.print("Numbers please separated by spaces/commas or just press return to quit:")
|
||||
Stdout.flush()
|
||||
var numbers = Stdin.readLine().trim()
|
||||
if (numbers == "") break
|
||||
var res = spark.call(numbers)
|
||||
var s = res[0]
|
||||
var n = res[1]
|
||||
var min = res[2]
|
||||
var max = res[3]
|
||||
if (n == 1) {
|
||||
System.print("1 value = %(min)")
|
||||
} else {
|
||||
System.print("%(n) values. Min: %(min) Max: %(max)")
|
||||
}
|
||||
System.print(s)
|
||||
System.print()
|
||||
}
|
||||
9
Task/Sparkline-in-unicode/Zkl/sparkline-in-unicode-1.zkl
Normal file
9
Task/Sparkline-in-unicode/Zkl/sparkline-in-unicode-1.zkl
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
var sparks=[0x2581..0x2588].apply("toString",-8); // int.toString(-8)-->UTF-8
|
||||
var sl=(sparks.len()-1);
|
||||
|
||||
fcn sparkLine(xs){
|
||||
min:=(0.0).min(xs); max:=(0.0).max(xs); // min/max are float reguardless of xs
|
||||
range:=max-min; // float
|
||||
println("Range [",min,"-",max,"]", xs);
|
||||
xs.pump(String,'wrap(x){ sparks[(x - min)*sl/range] }).println();
|
||||
}
|
||||
3
Task/Sparkline-in-unicode/Zkl/sparkline-in-unicode-2.zkl
Normal file
3
Task/Sparkline-in-unicode/Zkl/sparkline-in-unicode-2.zkl
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
one:="1 2 3 4 5 6 7 8 7 6 5 4 3 2 1".split(" ").apply("toInt");
|
||||
two:=("1.5, 0.5 3.5, 2.5 5.5 4.5 7.5, 6.5" - ",").split(" ").apply("toFloat");
|
||||
sparkLine(one); sparkLine(two);
|
||||
5
Task/Sparkline-in-unicode/Zoea/sparkline-in-unicode.zoea
Normal file
5
Task/Sparkline-in-unicode/Zoea/sparkline-in-unicode.zoea
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
program: sparkline
|
||||
input: '1 2, 3 4.5 5 6,7 8'
|
||||
derive: [1,2,3,4.5,5,6,7,8]
|
||||
derive: [1,2,3,4,5,6,7,8]
|
||||
output: '▁▂▃▄▅▆▇█'
|
||||
Loading…
Add table
Add a link
Reference in a new issue