C # - Основна проблема


10

Ця головоломка програмування натхненна ще одним питанням, яке тут було задано вчора, але яке було видалено автором ...

Змагання:

Створіть виконуваний двійковий файл (Windows .EXE або бінарний Linux), використовуючи Visual C # (або ваш улюблений C # IDE), який друкує наступний текст на стандартний вихід:

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

... без використання 4-х послідовних букв ГОЛОВНЕ, що з'являються у жодному вихідному файлі!

Примітки:

  • Якщо ваш вихідний код містить текст remainder(наприклад), він містить 4 послідовних літери ГОЛОВНЕ, однак якщо він містить mxain4 літери, то більше не буде послідовним, тому mxainце буде дозволено.
  • Вам заборонено запускати будь-які програми, окрім C # IDE, а також не змінювати налаштування C # IDE для запуску інших програм (але тих, які, як правило, запускаються, такі як компілятор C #).

    В іншому випадку ви можете просто сказати: "Я пишу програму Pascal за допомогою C # IDE і викликаю компілятор Pascal у кроках" попереднього збирання "мого проекту C #".

    Це було б занадто просто.

  • Користувачі IDE, які можуть бути розширені за допомогою "плагінів" (або подібних) або мають вбудовані редактори двійкових файлів (hex-редактори), мали б занадто велику перевагу перед користувачами інших C # IDE.

    Тому ці функції також не слід використовувати.

  • Використання інших не-ASCII-редакторів (таких як редактор діалогових вікон) явно дозволено!
  • Користувач, який задає оригінальне запитання, запропоноване з використанням зворотної косої риси у назвах функцій, саме так: static void M\u0061in()Оскільки цю відповідь вже прочитали інші користувачі, вона більше не буде прийнята!
  • Користувач запитав, чи буде дозволено просто ввести .EXE-файл у редактор вихідного коду та зберегти файл як ".exe" замість ".cs". Відповідь: Я не сумніваюся, що це можливо, оскільки обидві бінарні файли Windows та Linux містять байти NUL. Однак якщо ви знайдете дійсний двійковий файл, який можна створити таким чином, у вас є дійсне рішення.

Назва цього сайту - "Головоломки та програмування " - це "Головоломка програмування", а не "Код гольф". Завдання полягає в тому, щоб знайти робоче рішення перед усіма іншими користувачами, а не знайти рішення коротше за всіх інших рішення.

Тому перший пост з описом робочого рішення виграє !

Удачі!

До речі: у мене є рішення, що працює під Visual C # Express 2010.


2
Що не дозволяє використовувати мій C # IDE як текстовий (або двійковий) редактор, щоб безпосередньо набрати виконуваний файл?
feersum

2
Яка відповідь перемагає виклик? Перша правильна відповідь? Ви повинні вказати умову виграшу
Джеймс

Якщо IDE містить якийсь шестнадцятковий редактор або подібне, НЕ буде дозволено. Якщо вам вдасться скористатися текстовим редактором ASCII для введення дійсного двійкового файлу, це буде дозволено. Зауважте, що дійсний двійковий файл містить байти в діапазоні від 0x00 до 0x1F!
Мартін Розенау

2
Я думаю, що це загалом цікава проблема. "Написати програму C # без основної". Однак більшість правил стосується того, якими інструментами / IDE користуватися та забороняти певні підходи. Я хотів би бачити більше головоломок з програмуванням (на відміну від коду-гольфу), але це не вказано. Я рекомендую використати пісочницю наступного разу.
Джеймс

4
... Розгляньте пісочницю наступного разу.
кіт

Відповіді:


5

C # Інтерактивне вікно

Відкрийте інтерактивне вікно C # (Перегляд> Інші Windows> C # Interactive у Visual Studio 2015). Я гадаю, що не всі ІДЕ матимуть це.

Цей підхід виконує C # у інтерактивному вікні для того, щоб створити C # exe, який друкує потрібний рядок без того, щоб автор ніколи писав main. Як бонус, ІЛ-код EXE також не містить 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.CurrentDirectoryщоб побачити, де створено exe. Запустіть його, щоб спостерігати потрібний вихід.

введіть тут опис зображення

Результат IL: введіть тут опис зображення


Мені насправді подобається цей кращий, а потім WPF, тому що у вас фактично немає головного () у вашій асамблеї.
hstde

Ваше рішення цікаве. Це другий, тому ви виграєте, якщо користувачі переконають мене, що перший пост не є правильним рішенням (з якої причини).
Мартін Розенау

Якщо ви запитаєте мене, насправді не важливо, яка публікація виграє, оскільки вони обидва є одним і тим же користувачем.
hstde

@hstde - Вибачте, я цього не бачив. Дякую.
Мартін Розенау

@milk Ви розмістили два дійсних рішення (ну, деякі користувачі сумніваються у першому), тому ви виграєте. Вітаю.
Мартін Розенау

3

Застосування WPF

  1. Створіть нову програму WPF. введіть тут опис зображення

  2. Замінити всі екземпляри MainзMeow введіть тут опис зображення

  3. Перейменувати MainWindow.xamlна MeowWindow.xaml. Це автоматично перейменовується MainWindow.xaml.csв MeowWindow.xaml.cs.

введіть тут опис зображення

  1. У властивостях проекту змініть тип вихідного сигналу Console Applicationтак, щоб створювалася консоль. введіть тут опис зображення

  2. Додайте запис консолі для потрібного вихідного рядка у вашому MeowWindowконструкторі введіть тут опис зображення

  3. Ctrl + Shift + F, щоб підтвердити відсутність mainніде у вихідному каталозі. введіть тут опис зображення

  4. F5 / компілювати та запускати. введіть тут опис зображення

Як це працює

Для додатків WPF Visual Studio генерує, obj\Debug\App.g.csякий містить Mainметод. Створений Mainстворює екземпляр програми WPF і запускає його.


Цікаве рішення. Той, хто думає, що це неправдиве рішення? Якщо хтось вважає, що це повідомлення недійсне, будь ласка, опублікуйте коментар. В іншому випадку я оголошу це рішення виграшним, оскільки воно, очевидно, було першим опублікованим.
Мартін Розенау

@MartinRosenau Я вважаю, що оскільки ви могли декомпілювати додаток wpf і був би основний метод, що це недійсно, сильніше, тому що той самий користувач опублікував ще одну відповідь, яка не має цієї двозначності

Я щойно побачив, що обидві відповіді були опубліковані одним і тим же користувачем. У цьому випадку цей користувач все одно виграє.
Мартін Розенау

0

Так само як еталон

Моя ідея була схожа на другу ідею "молока":

Знайдіть спосіб дозволити IDE виконувати код і записати виконуваний файл на диск.

Я чітко згадував бінарні файли Windows та Linux, оскільки думав про те, щоб записати бінарний файл .EXE, використовуючи, System.IO.File.WriteAllBytes()щоб він не був би файлом .NET EXE.

Моя проблема полягала в тому, що VS Express 2010, здається, не має інтерактивної консолі, тому мені довелося знайти заміну на це - я знайшов наступне:

Створіть проект DLL з діалоговим вікном та спеціальним керуванням; складіть проект і додайте користувальницький елемент керування до діалогового вікна. Після цього редактор діалогового вікна зателефонує до коду спеціального елемента керування - і в цьому коді ви можете записати на диск файл .EXE ...

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.