summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--histogram.cpp167
1 files changed, 84 insertions, 83 deletions
diff --git a/histogram.cpp b/histogram.cpp
index 5bb2133..855776d 100644
--- a/histogram.cpp
+++ b/histogram.cpp
@@ -3,140 +3,141 @@
#include <vector>
#include <algorithm>
#include <cmath>
+#include <cstdint>
#include <cstring>
#include <cassert>
-using namespace std;
+static const char *argv0;
-const char *argv0;
-
-void usage(){
- cerr<<"Usage: "<<argv0<<" [<lowbound> <highbound>] [<nbins>]"<<endl
- <<"Prints a simple histogram of stdin data in your terminal, using"<<endl
- <<"either the given lower and upper bounds, or the minimum and"<<endl
- <<"maximum extracted from the data."<<endl
- <<"The number of bins can also be passed."<<endl
- <<"Data on stdin is assumed to be a list of floating-point values."<<endl;
+void usage() {
+ std::cerr << "Usage: " << argv0 << " [<lowbound> <highbound>] [<nbins>]" << std::endl
+ << "Prints a simple histogram of stdin data in your terminal, using" << std::endl
+ << "either the given lower and upper bounds, or the minimum and" << std::endl
+ << "maximum extracted from the data." << std::endl
+ << "The number of bins can also be passed." << std::endl
+ << "Data on stdin is assumed to be a list of floating-point values." << std::endl;
}
-double parsefloat(const char *s,const char *errprefix){
+double parsefloat(const char *s, const char *errprefix) {
char *endp;
- double v=strtod(s,&endp);
- if(!s[0]||*endp){
- cerr<<errprefix<<" '"<<s<<"'"<<endl;
+ double v = strtod(s, &endp);
+ if (!s[0] || *endp) {
+ std::cerr << errprefix << " '" << s << "'" << std::endl;
usage();
exit(1);
}
return v;
}
-int parseint(const char *s,const char *errprefix){
+int64_t parseint(const char *s, const char *errprefix) {
char *endp;
- int v=strtol(s,&endp,10);
- if(!s[0]||*endp){
- cerr<<errprefix<<" '"<<s<<"'"<<endl;
+ int64_t v = strtoll(s, &endp, 10);
+ if (!s[0] || *endp) {
+ std::cerr << errprefix << " '" << s << "'" << std::endl;
usage();
exit(1);
}
return v;
}
-int main(int argc,char **argv){
- argv0=argv[0];
+int main(int argc, char **argv) {
+ argv0 = argv[0];
- const int BARWIDTH=80;
+ const int64_t BARWIDTH = 80;
- double low,high;
+ double low, high;
bool havebounds;
- int nbins=10;
-
- if(argc==1){
- havebounds=false;
- } else if(argc==2){
- havebounds=false;
- nbins=parseint(argv[1],"Invalid number");
- } else if(argc==3){
- havebounds=true;
- low=parsefloat(argv[1],"Invalid number");
- high=parsefloat(argv[2],"Invalid number");
- } else if(argc==4){
- havebounds=true;
- low=parsefloat(argv[1],"Invalid number");
- high=parsefloat(argv[2],"Invalid number");
- nbins=parseint(argv[3],"Invalid number");
+ int64_t nbins = 10;
+
+ if (argc == 1) {
+ havebounds = false;
+ } else if (argc == 2) {
+ havebounds = false;
+ nbins = parseint(argv[1], "Invalid number");
+ } else if (argc == 3) {
+ havebounds = true;
+ low = parsefloat(argv[1], "Invalid number");
+ high = parsefloat(argv[2], "Invalid number");
+ } else if (argc == 4) {
+ havebounds = true;
+ low = parsefloat(argv[1], "Invalid number");
+ high = parsefloat(argv[2], "Invalid number");
+ nbins = parseint(argv[3], "Invalid number");
} else {
usage();
return 1;
}
- if(nbins<1){
- cerr<<"histogram: Invalid number of bins '"<<nbins<<"'"<<endl;
+ if (nbins < 1) {
+ std::cerr << "histogram: Invalid number of bins '" << nbins << "'" << std::endl;
usage();
return 1;
}
- if(havebounds&&high<=low){
- cerr<<"histogram: high <= low"<<endl;
+ if (havebounds && high <= low) {
+ std::cerr << "histogram: high <= low" << std::endl;
usage();
return 1;
}
- double minval=INFINITY,maxval=-INFINITY;
- vector<double> values;
- while(true){
+ double minval = INFINITY, maxval = -INFINITY;
+ std::vector<double> values;
+ while (true) {
double v;
- cin>>v;
- if(!cin)break;
+ std::cin >> v;
+ if (!std::cin) break;
values.push_back(v);
- if(v<minval)minval=v;
- if(v>maxval)maxval=v;
+ if (v < minval) minval = v;
+ if (v > maxval) maxval = v;
}
- if(!havebounds){
- low=minval;
- high=maxval;
+ if (!havebounds) {
+ low = minval;
+ high = maxval;
}
- sort(values.begin(),values.end());
+ std::sort(values.begin(), values.end());
- vector<int> histogram(nbins);
+ std::vector<int64_t> histogram(nbins);
- int binidx=0,tally=0,maxtally=-1;
- for(double v : values){
- if(v<low||v>high){
- // cerr<<"Point "<<v<<" out of range!"<<endl;
+ int64_t binidx = 0, tally = 0, maxtally = -1;
+ for (double v : values) {
+ if (v < low || v > high) {
+ // cerr << "Point " << v << " out of range!" << endl;
continue;
}
- int bin=(v-low)/(high-low)*nbins;
- if(bin==nbins)bin--;
- assert(bin>=0&&bin<nbins);
- if(bin!=binidx){
- histogram[binidx]=tally;
- if(tally>maxtally)maxtally=tally;
- binidx=bin;
- tally=0;
+ int64_t bin = (v - low) / (high - low) * nbins;
+ if (bin == nbins) bin--;
+ assert(bin >= 0 && bin < nbins);
+ if (bin != binidx) {
+ histogram[binidx] = tally;
+ if (tally > maxtally) maxtally = tally;
+ binidx = bin;
+ tally = 0;
}
tally++;
}
- histogram[binidx]=tally;
- if(tally>maxtally)maxtally=tally;
+ histogram[binidx] = tally;
+ if (tally > maxtally) maxtally = tally;
- if(maxtally==0){
- cerr<<"histogram: No data in range"<<endl;
+ if (maxtally == 0) {
+ std::cerr << "histogram: No data in range" << std::endl;
return 1;
}
- char fullbar[BARWIDTH+1];
- memset(fullbar,'#',BARWIDTH);
- fullbar[BARWIDTH]='\0';
- char emptybar[BARWIDTH+1];
- memset(emptybar,' ',BARWIDTH);
- emptybar[BARWIDTH]='\0';
-
- for(int i=0;i<(int)histogram.size();i++){
- int tally=histogram[i];
- int width=BARWIDTH*tally/maxtally;
- cout<<fullbar+BARWIDTH-width<<emptybar+width
- <<" ["<<setw(11)<<low+(double)i/nbins*(high-low)<<" - "<<setw(11)<<low+(double)(i+1)/nbins*(high-low)<<")]"[i==(int)histogram.size()-1]
- <<" ["<<tally<<"]"<<endl;
+ char fullbar[BARWIDTH + 1];
+ memset(fullbar, '#', BARWIDTH);
+ fullbar[BARWIDTH] = '\0';
+ char emptybar[BARWIDTH + 1];
+ memset(emptybar, ' ', BARWIDTH);
+ emptybar[BARWIDTH] = '\0';
+
+ for (size_t i = 0; i < histogram.size(); i++) {
+ int64_t tally = histogram[i];
+ int64_t width = BARWIDTH * tally / maxtally;
+ char terminator = ")]"[i == histogram.size() - 1];
+ std::cout << fullbar + BARWIDTH - width << emptybar + width
+ << " [" << std::setw(11) << low + (double)i / nbins * (high - low) << " - "
+ << std::setw(11) << low + (double)(i + 1) / nbins * (high - low) << terminator
+ << " [" << tally << "]" << std::endl;
}
}