読者です 読者をやめる 読者になる 読者になる

とくにあぶなくないRiSKのブログ

危ないRiSKのブログだったかもしれない。本当はRiSKだけどググラビリティとか取得できるIDの都合でsscriskも使ったり。

Restricted Words

C++

CodeIQのRestricted Wordsという問題に挑戦しました。

挑戦者求む!【言語指定】Restricted Words by @cielavenir cielavenir│CodeIQ

標準出力に Hello World と出力するプログラムを作成して下さい。

ただし、数値、文字及び文字列リテラルを解答に含めることはできません。 Perlのqqやqw、Rubyの%Q、%q、%wなども避けたほうが評価が高くなります。 言語仕様をフル活用して下さい!

私はC++11で回答しました。2回目に提出したコードは以下の通り。

// C++11
// 再提出。mの要素数指定を間違えていました。

#include<cstdio>
int main(){
 enum{ n, p, i, d, x, o, c = i * o };
 constexpr char s[]{
  i, i, i, i, i, i, i, i, o, n, i, i, i, i, i, i, i, i, i, n, i, i, i, i, i, i,
  i, i, i, i, i, i, n, i, i, i, i, p, p, p, d, c, n, x, n, i, i, i, i, i, x, i,
  i, i, i, i, i, i, x, x, i, i, i, x, n, x, p, p, i, i, i, i, i, i, i, i, i, i,
  i, i, i, i, i, x, n, x, i, i, i, x, d, d, d, d, d, d, x, d, d, d, d, d, d, d,
  d, x
 };
 char m[c]{};
 auto q = m;
 for(auto t = s; t < s + sizeof(s); ++t)
  switch(*t) {
  case n: ++q; break;
  case p: --q; break;
  case i: ++*q; break;
  case d: --*q; break;
  case x: putchar(*q); break;
  case o:
   if(!*q)
    for(int a{}; ; ++t){
     if(*t == o) ++a; if(*t == c) --a;
     if(!a) break;
    }
   break;
  case c:
   for(int a{}; ;){
    if(*t == c) ++a; if(*t == o) --a;
    --t;
    if(!a) break;
   }
   break;
  }
}

0とか1を得てそっからごにょればいいというのはすぐに分かりました。それで、初めは面白く0とか1を得る方法考えたのですが、それだと他の人とすぐにかぶりそうだなと思いました。

そこで、ごにょる部分で他の人とかぶらないような方法を考えたところ、C++brainfuckを実装し提出すれば面白い(あるいは怒られる?)かなという発想に。

enumのn, p, i, d, x, o, cとかはbrainfuckの各命令に対応しています(使用しない,は実装していません)。本当はbrainfuckの部分をconstexpr対応しようかとも思ったのですが、コードが長くなる気がしたのでやめました。

結果は、評価5でした。