Language detail: C++

Coverage: 67.67%
number of '+' ratings
contribution for coverage

Unsolved challenges

codes

Feed

Used modules

next >>

LL Golf Hole 6 - 10進数を2進数に基数変換する (Nested Flatten)

2進数限定、桁数固定です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#include <bitset>
#include <iostream>

int main(int, char* [])
{
    int n;
    std::cin >> n;
    std::cout << std::bitset<32>(n) << std::endl;

    return 0;
}
LL Golf Hole 5 - 最上位の桁を数え上げる (Nested Flatten)
mattsanさんの#7145を参考に標準入力に対応しつつgolf化.
164bytes. 改行5,空白4省略可で実質155bytes
本当はoperator<()を定義してcout<cin とかやりたかったけど、短さを優先しました。
1
2
3
4
5
6
7
#include<iostream>
using namespace std;
void f(ostream&o,istream&i){
  int c=0,d=1,n;i>>n;
  while(c<=n)o<<c<<"\n"&&(c+=d)&&c/d/10&&(d*=10);
}
main(){f(cout,cin);}
別関数に分けずにベタでmain内に書いたほうがよっぽど短かった orz
というわけで元コードは自分で-1.
116btyes.実質109bytes
1
2
3
4
5
#include<iostream>
main(){
  int c=0,d=1,n;std::cin>>n;
  while(c<=n)std::cout<<c<<"\n"&&(c+=d)&&c/d/10&&(d*=10);
}

標準入力に対応させてみました

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <cstdlib>
#include <cstring>

void func(int m, int n = 0)
{
    char buf[BUFSIZ];
    int i = 1;
    int size = ::strlen(::itoa(n, buf, 10)) - 1;

    std::cout << n << std::endl;
    while(size--) i *= 10;
    if(m > n) return func(m, n+i);
}

int main(int argc, char* argv[])
{
    argc == 2 ? func(::atoi(argv[1])) : func(300);
}

ちょっと不格好かなぁ…。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>

void count(int n)
{
    int d = 1;
    int i = 0;
    while(i <= n)
    {
        std::cout << i << std::endl;
        i += d;
        if((i / (d * 10) > 0))
        {
            d *= 10;
        }
    }
}

int main(int, char* [])
{
    count(300);

    return 0;
}
LL Golf Hole 4 - 文章から単語の索引を作る (Nested Flatten)

Boost(1.35.0)を使ってどうにかこうにか。

もはやGolfではないです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <iterator>
#include <algorithm>
#include <boost/asio.hpp>
#include <boost/regex.hpp>

using namespace std;
using namespace boost;
using namespace boost::asio;

typedef vector<string>            Strings;
typedef map<string, vector<int> > Dic;

int main()
{
    ip::tcp::iostream src( "www.gnu.org", "http" );

    src << "GET /licenses/gpl.txt HTTP/1.0\r\n"
        << "Host: www.gnu.org\r\n"
        << "\r\n"
        << flush;

    // 読み込み
    Strings lines;
    string  s;
    bool    body = false;
    while(getline(src, s))
    {
        if(body) lines.push_back(s);
        if(s == "\r") body = true;
    }

    // 解析
    regex re("¥¥w+");
    Dic   dic;
    int   lineno = 1;
    for(Strings::const_iterator i = lines.begin(); i != lines.end(); ++i)
    {
        sregex_iterator ri(i->begin(), i->end(), re);
        sregex_iterator end;
        for(; ri != end; ++ri)
        {
            dic[ri->str()].push_back(lineno);
        }
        ++lineno;
    }

    // 書き出し
    for(Dic::const_iterator i = dic.begin(); i != dic.end(); ++i)
    {
        cout << i->first << ":";
        copy(i->second.begin(), i->second.end(), ostream_iterator<int>(cout, ","));
        cout << endl;
    }

    return 0;
}
LL Golf Hole 3 - 13日の金曜日を数え上げる (Nested Flatten)

LLでないですし、ぜんぜん短くありませんし(ry

えーっと。ほとんどCです。

「今日から」の部分が一番面倒くさいことになってしまいました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <ctime>
#include <iostream>

int dayOfWeek(int y, int m, int d)
{
    if((m == 1) || (m == 2))
    {
        y--;
        m += 12;
    }
    return (y + y / 4 - y / 100 + y / 400 + (13 * m + 8) / 5 + d) % 7;
}

int main(int, char* [])
{
    std::time_t today   = std::time(0);
    std::tm*    todayTm = std::localtime(&today);

    int count = 0;
    int m     = (todayTm->tm_mday <= 13) ? todayTm->tm_mon : todayTm->tm_mon + 1;
    for(int y = todayTm->tm_year + 1900; y <= 2013; ++y)
    {
        while(m <= 12)
        {
            if(dayOfWeek(y, m ,13) == 5)
            {
                std::cout << y << "/" << m << "/13" << std::endl;
                ++count;
            }
            ++m;
        }
        m = 1;
    }
    std::cout << "total: " << count << std::endl;

    return 0;
}
LL Golf Hole 2 - 文字列に含まれる単語の最初の文字を大文字にする (Nested Flatten)

LLでないですし、ぜんぜん短くありませんし、多バイト文字のこと考えられてませんが、例示ということで。

標準入力から入力し、標準出力へ出力します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <cctype>
#include <string>
#include <iostream>
#include <iterator>
#include <algorithm>

std::string capitalize(const std::string& s)
{
    std::string result(s);
    if(result.size() > 0)
    {
        result[0] = std::toupper(result[0]);
    }
    return result;
}

int main(int, char* [])
{
    std::istream_iterator<std::string> srcBegin(std::cin);
    std::istream_iterator<std::string> srcEnd;
    std::ostream_iterator<std::string> dst(std::cout, " ");
    std::transform(srcBegin, srcEnd, dst, capitalize);

    return 0;
}
2次元ランダムウォーク (Nested Flatten)
まずはシンプルなところで。
   1   0  -1
   2   0   0
   3   0   1
   4  -1   1
   5  -2   1
   6  -1   1
   7   0   1
   8  -1   1
   9  -1   0
  10  -1   1
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <cstdlib>
#include <complex>
#include <iostream>
#include <iomanip>

int main(int args, char* argv[])
{
    std::complex<int> d[] =
    {
        std::complex<int>( 1,  0),
        std::complex<int>( 0,  1),
        std::complex<int>(-1,  0),
        std::complex<int>( 0, -1)
    };

    std::complex<int> p(0, 0);

    for(int i = 1; i <= 10; ++i)
    {
        p += d[std::rand() % 4];
        std::cout << std::setw(4) << i
                  << std::setw(4) << p.real()
                  << std::setw(4) << p.imag()
                  << std::endl;
    }

    return 0;
}
環境変数の取得 (Nested Flatten)

ついでにC++とQtで。 QMapを返すものがあるのかとおもい、探してみましたけど、検索能力が低く、見つけることができませんでした。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#include <QtCore>
#include <QtDebug>

#include <cstdlib>

int main(void)
{
        QStringList env = QProcess::systemEnvironment();
        QStringListIterator itr(env);
        QMap<QString, QString> envMap;
        while(itr.hasNext()) {
                QString str = itr.next();
                envMap[str.section('=', 0, 0)] = str.section('=', 1, 1);
        }

        qDebug() << envMap["PATH"];

        return EXIT_SUCCESS;
}
比較しないソートの作成 (Nested Flatten)

皆さんのコードを参考に実装してみましたが、イテレータのサンプルみたいになってしまいました orz

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

template<typename InputIterator, typename OutputIterator>
void sort(int min, int max, InputIterator begin, InputIterator end, OutputIterator dst)
{
    std::vector<int> counts(max - min + 1);
    for(InputIterator i = begin; i != end; ++i)
    {
        ++counts[*i - min];
    }

    for(std::size_t i = 0; i < counts.size(); ++i)
    {
        std::vector<int> c(counts[i], i + min);
        std::copy(c.begin(), c.end(), dst);
    }
}

int main(int, char* [])
{
    static const int array[] = { -1, 9, 4, 8, 9, 6, 3, 9, 5, 2 };
    std::vector<int> dst;

    // ソート; dst に並べ替えられた値が入ります
    sort(-1, 10, array, array + (sizeof(array) / sizeof(*array)), std::back_inserter(dst));

    // 結果表示
    std::copy(dst.begin(), dst.end(), std::ostream_iterator<int>(std::cout, ", "));

    return 0;
}
設定ファイルから値を取得 (Nested Flatten)

読み込みは手を抜いてしまいました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>

struct Price
{
    std::string name;
    int         cost;
};

Price loadPrice(std::istream& in)
{
    Price result = { "", 0 };

    std::string line;
    while(std::getline(in, line))
    {
        std::string::size_type p = line.find("=");
        std::string key          = line.substr(0, p);
        std::string value        = line.substr(p + 1);
        if(key == "ITEM_NAME")
        {
            result.name = value;
        }
        else if(key == "ITEM_COST")
        {
            std::stringstream ss;
            ss << value;
            ss >> result.cost;
        }
    };

    return result;
}

void showPrice(const Price& price)
{
    std::cout << "「" << price.name << "」は" << static_cast<int>(price.cost * 1.05) << "円(税込み)" << std::endl;
}

int main(int, char* [])
{
    std::ifstream source("ShowPrice.ini");
    if(source.good())
    {
        Price price = loadPrice(source);
        showPrice(price);
    }
    return 0;
}
Boost.Spirit を使って。
Javaのpropertiesファイルみたいな
KEY = VALUE
KEY2 = VALUE2
:
形式のファイルを読み込みます。

#で始まる行はコメントとして読み飛ばします。
また、KEYに使えるのがアルファベット、数字、
アンダーバー、ハイフンのみという制約が
あります。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include <iostream>
#include <map>
#include <string>
#include <stdexcept>
#include <fstream>

#include <boost/spirit.hpp>
#include <boost/spirit/actor/assign_actor.hpp>
#include <boost/spirit/actor/insert_at_actor.hpp>
#include <boost/algorithm/string/trim.hpp>

class PropertyFileReader
{
    public:
        //! key-value paired map type
        typedef std::map<std::string, std::string> property_map_type;

    public:
        static property_map_type
            read(
                    std::istream& is
                );

};


PropertyFileReader::property_map_type
PropertyFileReader::read(
        std::istream& is
        )
{
    using namespace boost::spirit;

    property_map_type prop;
    property_map_type::key_type prop_key;

    rule<> comment_r = comment_p("#");
    rule<> name_r = (alpha_p | ch_p('_')) >> *( alnum_p | ch_p('_') | ch_p('-'));
    rule<> key_r = name_r[assign_a(prop_key)];
    rule<> value_r = (*(anychar_p - eol_p))[insert_at_a(prop, prop_key)];

    rule<> kvpair_r = (key_r >> *blank_p >> ch_p('=') >> *blank_p >> value_r);

    rule<> commentline_r = *blank_p >> comment_r;
    rule<> emptyline_r = *blank_p >> eol_p;
    rule<> kvpairline_r = *blank_p >> kvpair_r >> eol_p;

    rule<> prop_r = *( commentline_r || emptyline_r || kvpairline_r ) >> end_p;

    // slurp stream
    std::string content;
    while ( !is.eof() ) {
        std::string line;
        std::getline(is,line);
        content += line + "\n";
    }

    parse_info<> result = parse(content.c_str(), prop_r);

    if ( !result.full ) {
        throw std::runtime_error("couldn't parse properties");
    }

    // trim following white spaces in value
    for ( property_map_type::iterator it = prop.begin(); it != prop.end(); ++it )
        boost::algorithm::trim(it->second);

    return prop;
}

int main(int c, char** v)
{
  if ( c != 3 ) {
    std::cout << "usage " << v[0] << " <property file> <key name>\n";
    return 0;
  }

  try {
    PropertyFileReader::property_map_type map(
        PropertyFileReader().read(std::ifstream(v[1])) );

    std::cout << v[2] << " = " << map[std::string(v[2])] << "\n";
  }
  catch ( const std::exception& e ) {
    std::cerr << "ERROR: " << e.what() << "\n";
    return 1;
  }
  return 0;
}
コメントの削除 (Nested Flatten)

ストリームを使っているだけで実質Cですね…。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <iostream>

static void decomment(std::istream& in, std::ostream& out)
{
    in.unsetf(std::ios::skipws);

    char c;
    char prev = 0;

    while(in >> c)
    {
        if(c == '/')
        {
            prev = c;
            in >> c;
            if(c == '*')
            {
                do
                {
                    while((in >> c) && (c != '*'))
                    {
                        if(c == '\n')
                        {
                            out << c;
                        }
                    }
                } while((in >> c) && (c != '/'));

                c = ' ';
            }
            else if(c == '/')
            {
                while((in >> c) && (c != '\n'))
                    ; // NOP
            }
            else
            {
                out << prev;
            }
        }
        else if((c == '"') && (prev != '\\') && (prev != '\''))
        {
            do
            {
                out << c;
                if(c == '\\')
                {
                    in >> c;
                    out << c;
                }
            } while((in >> c) && (c != '"'));
        }

        out << c;
        prev = c;
    }
}

int main(int, char*[])
{
    decomment(std::cin, std::cout);

    return 0;
}
C++で書いてみました。
が、C++を書いた気にならない...

ちなみに、#if 0 ~ #endif は「コメント」ではないと思っているので対応していません。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include <iostream>
#include <fstream>

/* g++ -o decomment decomment.cpp */

// decomment
void decomment(
    std::ostream& os,
    std::istream& is
    )
{
  bool blc, olc; /* in block/one-line comment */
  bool str, chr; /* in string/char literal */

  blc=olc=str=chr=false;

  char c,pc='\0';
  while ( is.get(c) ) {
    // escape
    if ( c == '\\' ) {
      if ( !olc && !blc ) {
        if ( pc == '/' )
          os.put('/');
        os.put(c);
      }
      is.get(c);
      if ( !olc && !blc )
        os.put(c);
    }
    // end of one-line comment
    else if ( olc && (c == '\n' || c == '\r') ) {
      olc = false;
      os.put(c);
      pc = '\0';
      continue;
    }
    // end of block comment
    else if ( blc && pc == '*' && c == '/' ) {
      blc = false;
      pc = '\0';
      continue;
    }
    // start of one-line comment
    else if ( pc == '/' && c == '/' && !str && !chr && !blc ) {
      olc = true;
      pc = '\0';
      continue;
    }
    // start of block comment
    else if ( pc == '/' && c == '*' && !str && !chr && !olc ) {
      blc = true;
      pc = '\0';
    }
    // start/end of char literal
    else if ( !olc && !blc && c == '\'' ) {
      chr = !chr;
      if ( pc == '/' )
        os.put('/');
      os.put(c);
    }
    // start/end of string literal
    else if ( !olc && !blc && c == '\"' ) {
      str = !str;
      if ( pc == '/' )
        os.put('/');
      os.put(c);
    }
    else {
      if ( pc == '/' && !olc && !blc )
        os.put('/');
      if ( c != '/' && !olc && !blc )
        os.put(c);
    }
    pc = c;
  }
}

namespace {
  const char* test = "//\
                      " "/*" "hoge" "*/"
                      /* / * /* // */ "hige";
}
int main(int c, char** v)
{
  (void)test;
  if ( c < 2 ) {
    std::cout << "usage: " << v[0] << " <C++ source file>\n";
    return 0;
  }

  std::ifstream ifs(v[1]);
  if ( !ifs ) {
    std::cerr << "failed to open " << v[1] << "\n";
    return 1;
  }
  decomment(std::cout, ifs);
  return 0;
}
RFC 4180対応版 CSVレコードの分解 (Nested Flatten)
変態的と名高い(?) Boost.Spirit で解析。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <vector>
#include <string>
#include <exception>
#include <stdexcept>

#include <boost/spirit.hpp>
#include <boost/spirit/actor/push_back_actor.hpp>
#include <boost/spirit/actor/clear_actor.hpp>

typedef std::vector<std::string> csv_elem_t;

std::vector<csv_elem_t>
parse_csv(
    std::string lines
    )
{
  using namespace boost::spirit;

  std::vector<csv_elem_t> csv;
  csv_elem_t e;

  rule<> element_r = *((anychar_p - ch_p('"')) | str_p("\"\""));
  rule<> quoted_r = ch_p('"') >> element_r[push_back_a(e)] >> ch_p('"');

  rule<> naked_r = (*(anychar_p - ch_p('"') - ch_p(',') - eol_p))[push_back_a(e)];

  rule<> record_r = list_p((quoted_r|naked_r), ch_p(','));
  rule<> csv_r = list_p(record_r[push_back_a(csv,e)][clear_a(e)], eol_p) >> end_p;

  parse_info<> result = parse(lines.c_str(), csv_r);

  if ( !result.full ) {
    throw std::runtime_error("failed to parse");
  }

  typedef std::vector<csv_elem_t>::iterator csv_list_iter;
  typedef csv_elem_t::iterator csv_iter;
  for ( csv_list_iter clit = csv.begin(); clit != csv.end(); ++clit ) {
    for ( csv_iter cit = clit->begin(); cit != clit->end(); ++cit ) {
      std::string::size_type idx=0;
      while ( (idx = cit->find("\"\"", idx)) != std::string::npos ) {
        cit->replace(idx, 2, "\""); ++idx;
      }
    }
  }

  return csv;
}

int main()
{
  try {
    std::vector<csv_elem_t> csv =
      parse_csv("\"aaa\",\"b\nbb\",\"ccc\",zzz,\"y\"\"Y\"\"y\",xxx");

    std::cout << "total records: " << csv.size() << "\n";

    typedef std::vector<csv_elem_t>::const_iterator csv_list_iter;
    typedef csv_elem_t::const_iterator csv_iter;
    int l = 1;
    for ( csv_list_iter clit = csv.begin(); clit != csv.end(); ++clit,++l ) {
      std::cout << "#" << l << "\n";
      int i = 1;
      for ( csv_iter cit = clit->begin(); cit != clit->end(); ++cit,++i ) {
        std::cout << i << " => " << *cit << "\n";
      }
    }
  }
  catch ( std::exception& e ) {
    std::cerr << e.what() << "\n";
  }
  return 0;
}