C # est le principal problème


10

Ce puzzle de programmation est inspiré d'une autre question qui a été posée ici hier mais qui a été supprimée par l'auteur ...

Le défi:

Créez un binaire exécutable (binaire Windows .EXE ou Linux) en utilisant Visual C # (ou votre IDE C # préféré) qui imprime le texte suivant sur la sortie standard:

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

... sans utiliser les 4 lettres consécutives MAIN apparaissant dans n'importe quel fichier source!

Remarques:

  • Si votre code source contient le texte remainder(par exemple) il contient les 4 lettres consécutives MAIN, mais s'il contient mxainles 4 lettres ne seraient plus consécutives doncmxain serait donc autorisé.
  • Vous n'êtes pas autorisé à exécuter des programmes sauf l'IDE C # ni à modifier les paramètres de l'IDE C # pour exécuter d'autres programmes (mais ceux qu'il exécuterait normalement, comme le compilateur C #).

    Sinon, vous pourriez simplement dire: «J'écris un programme Pascal en utilisant l'IDE C # et j'invoque le compilateur Pascal dans les étapes de« pré-construction »de mon projet C #».

    Ce serait trop simple.

  • Les utilisateurs d'un IDE qui peut s'étendre à l'aide de "plug-ins" (ou similaires) ou qui ont des éditeurs de fichiers binaires intégrés (hex-éditeurs) auraient un avantage trop important sur les utilisateurs d'autres IDE C #.

    Par conséquent, ces valeurs ne doivent pas non plus être utilisées.

  • L'utilisation des autres éditeurs non ASCII (tels que l'éditeur de fenêtre de dialogue) est explicitement autorisée!
  • L'utilisateur posant la question d'origine a proposé d'utiliser la barre oblique inverse dans les noms de fonction comme ceci: static void M\u0061in() Parce que cette réponse a déjà été lue par d'autres utilisateurs, elle ne sera plus acceptée!
  • Un utilisateur a demandé s'il serait autorisé à taper simplement un fichier .EXE dans l'éditeur de code source et à enregistrer le fichier en tant que ".exe" au lieu de ".cs". Réponse: Je doute que cela soit possible car les binaires Windows et Linux valides contiennent des octets NUL. Cependant, si vous trouvez un binaire valide qui peut être créé de cette façon, vous avez une solution valide.

Le nom de ce site est "Programming Puzzles & Code Golf" - c'est un "Programming Puzzle", pas "Code Golf": Le défi est de trouver une solution de travail avant tous les autres utilisateurs, pas de trouver une solution plus courte que toutes les autres solutions.

Par conséquent, le premier article décrivant une solution de travail gagne !

Bonne chance!

Au fait: j'ai une solution fonctionnant sous Visual C # Express 2010.


2
Qu'est-ce qui m'empêche d'utiliser mon IDE C # comme éditeur de texte (ou binaire) pour taper directement un exécutable?
feersum

2
Quelle réponse remporte le défi? La première réponse valable? Vous devez spécifier la condition gagnante
James

Si l'EDI contient un éditeur hexadécimal ou similaire, cela ne sera PAS autorisé. Si vous parvenez à utiliser l'éditeur de texte ASCII pour taper un fichier binaire valide, cela serait autorisé. Notez qu'un fichier binaire valide contient des octets dans la plage 0x00 à 0x1F!
Martin Rosenau

2
Je pense que c'est globalement un défi intéressant. Msgstr "Ecrire un programme C # sans main". Cependant, la plupart des règles concernent les outils / IDE à utiliser et interdisent certaines approches. J'adorerais voir plus d'énigmes de programmation (par opposition au code-golf) mais celui-ci est sous-spécifié. Je recommanderais d'utiliser le bac à sable la prochaine fois.
James

4
... Pensez au bac à sable la prochaine fois.
chat

Réponses:


5

Fenêtre interactive C #

Ouvrez la fenêtre interactive C # (Affichage> Autres fenêtres> C # interactif dans Visual Studio 2015). Je suppose que tous les IDE n'auront pas cela.

Cette approche exécute C # dans la fenêtre interactive afin de créer un exe C # qui imprime la chaîne souhaitée sans que l'auteur ait jamais écrit main . En bonus, l'IL de l'exe ne contient pas non plus main.

Exécutez le code suivant dans la fenêtre interactive

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");

Utilisez Environmnent.CurrentDirectorypour voir où l'exe a été créé. Exécutez-le pour observer la sortie souhaitée.

entrez la description de l'image ici

IL résultant: entrez la description de l'image ici


En fait, j'aime mieux celui-ci, puis celui de WPF, car vous n'avez en fait aucun Main () dans votre assemblage.
hstde

Votre solution est intéressante. C'est le second, donc vous gagnerez si les utilisateurs me convainquent que le premier message n'est pas une solution valide (pour quelle raison que ce soit).
Martin Rosenau

Si vous me demandez, peu importe le post qui gagne, car ils sont tous les deux du même utilisateur.
hstde

@hstde - Désolé, je n'ai pas vu ça. Merci.
Martin Rosenau

@milk Vous avez publié deux solutions valides (enfin, certains utilisateurs ont des doutes sur la première), alors vous gagnez. Toutes nos félicitations.
Martin Rosenau

3

Application WPF

  1. Créez une nouvelle application WPF. entrez la description de l'image ici

  2. Remplacer toutes les instances de MainparMeow entrez la description de l'image ici

  3. Renommer MainWindow.xamlpour MeowWindow.xaml. Ce sera automatiquement renommé MainWindow.xaml.csen MeowWindow.xaml.cs.

entrez la description de l'image ici

  1. Dans les propriétés du projet, changez le type de sortie pour Console Applicationque la console soit créée. entrez la description de l'image ici

  2. Ajouter une écriture de console pour la chaîne de sortie souhaitée dans votre MeowWindowconstructeur entrez la description de l'image ici

  3. Ctrl + Maj + F pour confirmer qu'il n'y a mainnulle part dans le répertoire source. entrez la description de l'image ici

  4. F5 / compiler et exécuter. entrez la description de l'image ici

Comment ça fonctionne

Pour les applications WPF, Visual Studio génère obj\Debug\App.g.csqui contient la Mainméthode. Le généré Maincrée une instance de votre application WPF et la démarre.


Solution intéressante. Quiconque pense que ce n'est pas une solution valable? Si quelqu'un pense que ce message n'est pas valide, veuillez poster un commentaire. Sinon, je déclarerai cette solution gagnante car il s'agit bien évidemment de la première publiée.
Martin Rosenau

@MartinRosenau Je pense que puisque vous pouvez décompiler l'application wpf et qu'il y aurait une méthode principale pour que cela ne soit pas valide, plus fortement parce que le même utilisateur a posté une autre réponse qui n'a pas cette ambiguïté

Je viens de voir que les deux réponses ont été publiées par le même utilisateur. Dans ce cas, cet utilisateur gagnera quand même.
Martin Rosenau

0

Juste comme référence

Mon idée était similaire à la deuxième idée de "lait":

Trouvez un moyen de laisser l'EDI exécuter du code et d'écrire un exécutable sur le disque.

J'ai mentionné explicitement les binaires Windows et Linux parce que j'ai pensé à écrire le fichier binaire .EXE en utilisant System.IO.File.WriteAllBytes() donc ce ne serait pas nécessairement un fichier EXE .NET.

Mon problème était que VS Express 2010 ne semble pas avoir de console interactive, j'ai donc dû trouver un remplaçant pour cela - j'ai trouvé ce qui suit:

Créez un projet DLL avec une fenêtre de dialogue et un contrôle personnalisé; compilez le projet et ajoutez le contrôle personnalisé à la fenêtre de dialogue. L'éditeur de fenêtre de dialogue appellera alors le code du contrôle personnalisé - et dans ce code, vous pouvez écrire le fichier .EXE sur le disque ...

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.