Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

quote optimizer

Name: Anonymous 2012-10-15 19:30


/*
 * File: prog-utils/quote-optimizer.cxx
 *
 * Purpose: Optimizes quotes for you
 *
 * Usage: At this point, you may only pass unoptimized quotes
 * (i.e., >>24>>28\n>>2 ...)
 * Text file input (-i) is supported
 *
 * Build instructions:
 *  g++ quote-optimizer.cxx -o quote-optimizer -std=c++0x -O2
 *
 * Contributors:
 *  Anonymous-san
 *
*/

/*
prog-utils/quote-optimizer
Copyright (C) 2012  Anonymous-san

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.

     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <http://www.gnu.org/licenses/>;.
*/


#include <vector>
#include <list>
#include <string>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <utility>
#include <algorithm>
#include <assert.h>

using namespace std;

vector<uint16_t> parse_quotes(const char *);
vector<string> optimize(vector<uint16_t> *);
int custom_itoa(int val, char * buf);
void get_from_stdin(char *, uint32_t, char **, FILE *);
void get_from_args(char *, uint32_t, char **, FILE *);
void get_from_file(char *, uint32_t, char **, FILE *);
static char * input = NULL;

int main(int argc, char ** argv)
{
  void (*get_from)(char *, uint32_t, char **, FILE *) = get_from_stdin;
  FILE * file = NULL;
  while(*argv != NULL)
  {
    if(!strcmp("--help", *argv)
      || !strcmp("-h", *argv))
    {
      puts("Usage: optimize-quotes [options] [string]"
      "\nOptions: --help [-h], --stdin [-s], --args [-a], --input [-i]");
      exit(1);
    }
    else if(!strcmp("--stdin", *argv)
      || !strcmp("-s", *argv))
    {
      get_from = get_from_stdin;
    }
    else if(!strcmp("--args", *argv)
      || !strcmp("-a", *argv))
    {
      get_from = get_from_args;
      assert(*++argv);
      input = *argv;
    }
    else if(!strcmp("--input", *argv)
      || !strcmp("-i", *argv))
    {
      get_from = get_from_file;
      assert(*++argv);
      file = fopen(*argv, "r");
    }
    ++argv;
  }
  //const char test[] = ">>1\n>>2\n>>7\n>>3\n>>20\n>>4\n>>45>>1>>7>>99";
  char * buf = new char [1024];
  get_from(buf, 1024, argv, file);
  if(file != NULL)
    fclose(file);
  input = input == NULL ? buf : input;
  vector<uint16_t> parsed = parse_quotes(input);
  delete [] buf;
  auto output = optimize(&parsed);

  auto i = begin(output);
  char c = 0;
  for( ; i != end(output); ++i)
  {
    c = ((i + 1) == end(output)) ? '\n' : ',';
    printf("%s%c", i->c_str(), c);
  }

  return 0;
}

void get_from_stdin
(
  char * dest,
  uint32_t n,
  char **,
  FILE *
)
{
  puts("--stdin (default) selected; enter unoptimized quotes");
  fgets(dest, n, stdin);
}

void get_from_args
(
  char * dest,
  uint32_t,
  char ** argv,
  FILE *
)
/*
 * TODO concatenate all arguments instead
 *
 * dummy function for the moment
*/
{
}

void get_from_file
(
  char * dest,
  uint32_t n,
  char **,
  FILE * file
)
{
  uint32_t actually_read = 0;
  static const uint32_t should_read = 128;
  //static const uint32_t max_file_size = 4096;

  do
  {
    actually_read = fread(dest, sizeof(char), should_read, file);
    dest += actually_read;
  } while(actually_read == should_read);

}

vector<uint16_t> parse_quotes
(
  const char * src
)
{
  vector<uint16_t> ret;
  char * buf = new char [20];
  char * pbuf = buf;

  uint8_t read = 0;
  static const uint8_t first_arrow = 0x01;
  static const uint8_t second_arrow = 0x02;
  static const uint8_t number = 0x04;

  while(*src != 0)
  {
    switch(*src)
    {
      case '>':
      {
        if(read ^ first_arrow
          && read ^ second_arrow
          && pbuf != buf)
        {
          *pbuf = 0;
          ret.push_back(atoi(buf));
          pbuf = buf;
        }
        if(read ^ first_arrow)
          read |= first_arrow;
        else if(read ^ second_arrow)
          read |= second_arrow;
        else if(read & first_arrow
          && read & second_arrow)
        {
          puts("Syntax error");
        }
        break;
      }
      case '0': case '1': case '2':
      case '3': case '4': case '5':
      case '6': case '7': case '8':
      case '9':
      {
        if(read ^ number)
          read |= number;
        if(read & second_arrow)
          *(pbuf++) = *src;
        break;
      }
      default:
      {
        /*
        if(read & first_arrow)
          read -= first_arrow;
        if(read & second_arrow)
          read -= second_arrow;
        */
        break;
      }
    }

    ++src;
  }

  *pbuf = 0;
  ret.push_back(atoi(buf));
  pbuf = buf;

  delete [] buf;

  return ret;
}

vector<string> optimize
(
  vector<uint16_t> * src
)
{
  vector<string> ret;
  char * const buf = new char[20];

  //sort
  sort(src->begin(), src->end());

  //set up for reading
  uint8_t read = 0;
  static const uint8_t range = 0x01;
  static const uint8_t item = 0x02;
 
  uint16_t first_in_range = 0;
  uint16_t last_in_range = 0;

  uint16_t last_number_read = 1;

  //reading
  for(auto& i : *src)
  {
    if(i == last_number_read)
      continue;
    if(i == last_number_read + 1)
    {
      if(read ^ range)
      {
        first_in_range = last_number_read;
        read |= range;
      }
    }
    else
    {
      if(read & range)
      {
        last_in_range = last_number_read;
        uint16_t l = custom_itoa(first_in_range, buf);
        buf[l] = '-';
        uint16_t m = custom_itoa(last_in_range, buf + l + 1);
        buf[l + m + 1] = 0;
        ret.push_back(buf);

        read -= range;
      }

      if(read ^ item)
        read |= item;

      uint16_t l = custom_itoa(i, buf);
      ret.push_back(buf);
     
    }
   
    last_number_read = i;
  }

  delete [] buf;

  return ret;
}


int custom_itoa(int val, char * buf)
//stolen code
{
    const unsigned int radix = 10;

    char* p;
    unsigned int a;        //every digit
    int len;
    char* b;            //start of the digit char
    char temp;
    unsigned int u;

    p = buf;

    if (val < 0)
    {
        *p++ = '-';
        val = 0 - val;
    }
    u = (unsigned int)val;

    b = p;

    do
    {
        a = u % radix;
        u /= radix;

        *p++ = a + '0';

    } while (u > 0);

    len = (int)(p - buf);

    *p-- = 0;

    //swap
    do
    {
        temp = *p;
        *p = *b;
        *b = temp;
        --p;
        ++b;

    } while (b < p);

    return len;
}

Name: Anonymous 2012-10-16 17:19

And one that's far less efficient than it should be. Determining how many digits will be emitted is trivial. Then emit them in descending order. NOT emit in reverse and swap them afterwards, that's just a stupid waste of memory accesses.
int custom_itoa(int val, char * buf) {
  return sprintf(buf, '%d', val);

}

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List