C#が主な問題です


10

このプログラミングパズルは、昨日ここで質問されたが、作者によって削除された別の質問に触発されました...

チャレンジ:

Visual C#(またはお気に入りのC#IDE)を使用して実行可能バイナリ(Windows .EXEまたはLinuxバイナリ)を作成します。これにより、次のテキストが標準出力に出力されます。

Main() is the main method of C# programs!

...ソースファイルに表示される4つの連続する文字MAINを使用せずに

ノート:

  • ソースコードにテキストが含まれている場合remainder(たとえば)、4つの連続した文字MAINが含まれmxainていますが、4つの文字が含まれている場合、連続していないためmxain許可されます。
  • C#IDE以外のプログラムを実行することは許可されていません。また、C#IDEの設定を変更して他のプログラムを実行することもできます(ただし、C#コンパイラなど、通常は実行されるプログラム)。

    それ以外の場合は、「C#IDEを使用してPascalプログラムを作成し、C#プロジェクトの「事前ビルド」ステップでPascalコンパイラーを呼び出す」と簡単に言うことができます。

    これは単純すぎるでしょう。

  • 「プラグイン」(または同様のもの)を使用して拡張できるIDEのユーザー、または組み込みのバイナリファイルエディター(16進数エディター)を持つIDEは、他のC#IDEのユーザーに比べて非常に大きな利点があります。

    したがって、これらの機能も使用しないでください。

  • 他の非ASCIIエディター(ダイアログウィンドウエディターなど)の使用は明示的に許可されています!
  • このように関数名にバックスラッシュを使用して提案された元の質問をするユーザー:static void M\u0061in()この回答はすでに他のユーザーによって読まれているため、これ以上は受け入れられません!
  • ユーザーは、ソースコードエディターに.EXEファイルを単に入力して、「。cs」ではなく「.exe」としてファイルを保存することを許可するかどうかを尋ねました。回答:有効なWindowsとLinuxの両方のバイナリにNULバイトが含まれているため、これが可能であることは間違いありません。ただし、この方法で作成できる有効なバイナリが見つかった場合は、有効なソリューションがあります。

このサイトの名前は「Programming Puzzles Code Golf」です。これは「Code Golf」ではなく「Programming Puzzle」です。課題は、他のすべてのユーザーより先に実用的なソリューションを見つけることであり、他のすべてより短いソリューションを見つけることではありませんソリューション。

したがって、有効なソリューションを説明する最初の投稿が勝利します。

幸運を!

ちなみに、私はVisual C#Express 2010で動作するソリューションを持っています。


2
C#IDEをテキスト(またはバイナリ)エディターとして使用して実行可能ファイルを直接入力できないのはなぜですか。
feersum

2
どちらの答えが挑戦に勝ちますか?最初の有効な答えは?勝利条件を指定する必要があります
James

IDEに16進エディターなどが含まれている場合、これは許可されません。ASCIIテキストエディタを使用して有効なバイナリファイルを入力できた場合、これは許可されます。有効なバイナリファイルには、0x00〜0x1Fの範囲のバイトが含まれていることに注意してください。
Martin Rosenau

2
これは全体的に興味深い課題だと思います。「メインなしでC#プログラムを書く」。ただし、ほとんどのルールは、どのツール/ IDEを使用し、特定のアプローチを禁止するかに関するものです。(コードゴルフではなく)プログラミングパズルをもっと見たいと思っていますが、これは具体的ではありません。次回はサンドボックスを使用することをお勧めします。
ジェームズ

4
... 次回はサンドボックスを検討してください。

回答:


5

C#インタラクティブウィンドウ

C#インタラクティブウィンドウを開きます([表示]> [その他のウィンドウ]> [Visual Studio 2015のC#インタラクティブ])。すべてのIDEがこれを備えているとは限りません。

このアプローチは、作成者がこれまでに記述しなくても目的の文字列を出力するC#exeを作成するために、インタラクティブウィンドウでC#を実行しますmain。ボーナスとして、exeのILも含まれていませんmain

インタラクティブウィンドウで次のコードを実行します。

using System.Reflection;
using System.Reflection.Emit;
var appMeow = (dynamic)System.Type.GetType("System.AppDom" + "ain").GetProperty("CurrentDom" + "ain", BindingFlags.GetProperty | BindingFlags.Static | BindingFlags.Public).GetValue(null);
var asmName = new AssemblyName("MEOW");
var asmBuilder = appMeow.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave);
var module = asmBuilder.DefineDynamicModule("MEOW", "MEOW.exe");
var typeBuilder = module.DefineType("Meow", TypeAttributes.Public);
var entryPoint = typeBuilder.DefineMethod("EntryPoint", MethodAttributes.Static | MethodAttributes.Public);
var il = entryPoint.GetILGenerator();
il.Emit(OpCodes.Ldstr, "Meow() is the meow method of C# programs!");
il.Emit(OpCodes.Ldstr, "eow");
il.Emit(OpCodes.Ldstr, "ain");
il.EmitCall(OpCodes.Call, typeof(string).GetMethod("Replace", new[] { typeof(string), typeof(string) }), null);
il.EmitCall(OpCodes.Call, typeof(Console).GetMethod("Write", new[] { typeof(string) }), null);
il.Emit(OpCodes.Ret);
var type = typeBuilder.CreateType();
asmBuilder.SetEntryPoint(type.GetMethods()[0]);
asmBuilder.Save("MEOW.exe");

Environmnent.CurrentDirectoryexeが作成された場所を確認するために使用します。実行して、目的の出力を確認します。

ここに画像の説明を入力してください

結果のIL: ここに画像の説明を入力してください


アセンブリにはMain()がまったく含まれていないため、実際にはWPFのほうが好きです。
hstde 2016年

あなたの解決策は興味深いものです。これは2番目のものなので、最初の投稿が有効な解決策ではないことをユーザーが私に納得させれば、あなたは勝つでしょう(どんな理由であれ)。
Martin Rosenau

あなたが私に尋ねた場合、どちらの投稿も同じユーザーによるものであるため、どちらの投稿が勝っても問題はありません。
hstde 2016年

@hstde-申し訳ありませんが、これは見当たりませんでした。ありがとう。
Martin Rosenau

@milkあなたは2つの有効な解決策を投稿しました(まあ、一部のユーザーは最初の解決策に疑問を持っています)。おめでとう。
Martin Rosenau 2016年

3

WPFアプリケーション

  1. 新しいWPFアプリケーションを作成します。 ここに画像の説明を入力してください

  2. のすべてのインスタンスMainMeow ここに画像の説明を入力してください

  3. 名前MainWindow.xamlをに変更しMeowWindow.xamlます。これにより、自動的にに名前が変更さMainWindow.xaml.csMeowWindow.xaml.csます。

ここに画像の説明を入力してください

  1. プロジェクトのプロパティで、出力タイプをに変更しConsole Applicationて、コンソールを作成します。 ここに画像の説明を入力してください

  2. MeowWindowコンストラクター で目的の出力文字列のコンソール書き込みを追加しますここに画像の説明を入力してください

  3. Ctrl + Shift + F mainで、ソースディレクトリに何もないことを確認します。 ここに画像の説明を入力してください

  4. F5 /コンパイルして実行します。 ここに画像の説明を入力してください

使い方

WPFアプリケーションの場合、Visual Studio obj\Debug\App.g.csMainメソッドを含むものを生成します。生成されMainたコードは、WPFアプリのインスタンスを作成して起動します。


興味深いソリューション。これは有効な解決策ではないと思う人はいますか?この投稿が有効ではないと思われる場合は、コメントを投稿してください。そうでなければ、私はこのソリューションが明らかに最初に投稿されたものであるため、このソリューションを勝者と宣言します。
Martin Rosenau

@MartinRosenau wpfアプリを逆コンパイルでき、これが無効である主な方法があるため、同じユーザーがこのあいまいさのない別の回答を投稿したため、より強く感じます

私はちょうど両方の回答が同じユーザーによって投稿されたのを見ました。この場合、このユーザーがとにかく勝ちます。
Martin Rosenau

0

参考として

私の考えは「牛乳」の2番目の考えに似ていました。

IDEにコードを実行させ、実行可能ファイルをディスクに書き込む方法を見つけます。

WindowsおよびLinuxのバイナリについては、バイナリ.EXEファイルを使用しSystem.IO.File.WriteAllBytes()て.NET EXEファイルである必要はないので、明示的に記述しました。

私の問題は、VS Express 2010にインタラクティブコンソールがないように見えるため、代わりのコンソールを探す必要があったことです。次のことがわかりました。

ダイアログウィンドウとカスタムコントロールを使用してDLLプロジェクトを作成します。プロジェクトをコンパイルし、カスタムコントロールをダイアログウィンドウに追加します。ダイアログウィンドウエディターは、カスタムコントロールのコードを呼び出します。このコードでは、.EXEファイルをディスクに書き込むことができます...

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.