C # è il problema principale


10

Questo puzzle di programmazione è ispirato a un'altra domanda che è stata posta qui ieri ma che è stata eliminata dall'autore ...

La sfida:

Crea un file binario eseguibile (binario Windows .EXE o Linux) usando Visual C # (o il tuo IDE C # preferito) che stampa il seguente testo sull'output standard:

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

... senza usare le 4 lettere consecutive MAIN che appaiono in nessun file sorgente!

Appunti:

  • Se il tuo codice sorgente contiene il testo remainder(ad esempio) contiene le 4 lettere consecutive MAIN, tuttavia se contiene mxainle 4 lettere non sarebbe più consecutivo, quindi mxainsarebbe consentito.
  • Non è consentito eseguire alcun programma tranne l'IDE C # né modificare le impostazioni dell'IDE C # per eseguire altri programmi (ma quelli che verrebbe normalmente eseguito come il compilatore C #).

    Altrimenti potresti semplicemente dire: "Scrivo un programma Pascal usando l'IDE C # e invoco il compilatore Pascal nei passaggi 'pre-build' del mio progetto C #".

    Questo sarebbe troppo semplice.

  • Gli utenti di un IDE che possono estendersi utilizzando "plug-in" (o simili) o che hanno editor di file binari (hex-editor) integrati avrebbero un vantaggio troppo grande rispetto agli utenti di altri IDE C #.

    Pertanto, anche questi caratteri non devono essere utilizzati.

  • L'uso degli altri editor non ASCII (come l'editor della finestra di dialogo) è esplicitamente consentito!
  • L'utente che pone la domanda originale proposta utilizzando la barra rovesciata nei nomi delle funzioni in questo modo: static void M\u0061in()poiché questa risposta è già stata letta da altri utenti, non verrà più accettata!
  • Un utente ha chiesto se fosse consentito digitare semplicemente un file .EXE nell'editor del codice sorgente e salvare il file come ".exe" anziché ".cs". Risposta: Non dubito che ciò sia possibile perché entrambi i binari validi di Windows e Linux contengono byte NUL. Tuttavia, se trovi un file binario valido che può essere creato in questo modo, hai una soluzione valida.

Il nome di questo sito è "Puzzle di programmazione e Code Golf" - questo è un "Puzzle di programmazione", non "Code Golf": la sfida è trovare una soluzione funzionante prima di tutti gli altri utenti, non trovare una soluzione più breve di tutte le altre soluzioni.

Pertanto vince il primo post che descrive una soluzione funzionante !

In bocca al lupo!

A proposito: ho una soluzione che funziona con Visual C # Express 2010.


2
Cosa mi impedisce di usare il mio IDE C # come editor di testo (o binario) per digitare direttamente un eseguibile?
feersum

2
Quale risposta vince la sfida? La prima risposta valida? Dovresti specificare le condizioni vincenti
James,

Se l'IDE contiene un editor esadecimale o simile, questo NON sarebbe consentito. Se si riesce a utilizzare l'editor di testo ASCII per digitare un file binario valido, ciò sarebbe consentito. Si noti che un file binario valido contiene byte nell'intervallo da 0x00 a 0x1F!
Martin Rosenau,

2
Penso che nel complesso sia una sfida interessante. "Scrivi un programma C # senza main". Tuttavia, la maggior parte delle regole riguarda gli strumenti / IDE da utilizzare e il divieto di determinati approcci. Mi piacerebbe vedere più enigmi di programmazione (al contrario del code-golf) ma questo non è specificato. Consiglio di usare la sandbox la prossima volta.
James,

4
... Considera la sandbox la prossima volta.
cat

Risposte:


5

Finestra interattiva C #

Apri la finestra interattiva di C # (Visualizza> Altre finestre> C # Interactive in Visual Studio 2015). Suppongo che non tutti gli IDE avranno questo.

Questo approccio esegue C # nella finestra interattiva per creare un exe C # che stampa la stringa desiderata senza che l'autore abbia mai scritto main. Come bonus, anche l'IL dell'exe non contiene main.

Esegui il seguente codice nella finestra interattiva

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

Usa Environmnent.CurrentDirectoryper vedere dove è stato creato l'exe. Eseguirlo per osservare l'output desiderato.

inserisci qui la descrizione dell'immagine

IL risultante: inserisci qui la descrizione dell'immagine


In realtà mi piace di più questo, quindi quello del WPF, perché in realtà non hai Main () nella tua Assemblea.
hstde

La tua soluzione è interessante È il secondo, quindi vincerai se gli utenti dovessero convincermi che il primo post non è una soluzione valida (per quale motivo).
Martin Rosenau,

Se me lo chiedi, non importa quale post vince, poiché sono entrambi dello stesso utente.
hstde

@hstde - Siamo spiacenti, non l'ho visto. Grazie.
Martin Rosenau,

@milk Hai pubblicato due soluzioni valide (beh, alcuni utenti hanno dubbi sul primo), quindi vinci. Congratulazioni.
Martin Rosenau,

3

Applicazione WPF

  1. Crea una nuova applicazione WPF. inserisci qui la descrizione dell'immagine

  2. Sostituisci tutte le istanze di MainconMeow inserisci qui la descrizione dell'immagine

  3. Rinomina MainWindow.xamlin MeowWindow.xaml. Questo verrà automaticamente rinomina MainWindow.xaml.csa MeowWindow.xaml.cs.

inserisci qui la descrizione dell'immagine

  1. Nelle proprietà del progetto, modifica il Tipo di output in Console Applicationmodo da creare la console. inserisci qui la descrizione dell'immagine

  2. Aggiungi console write per la stringa di output desiderata nel MeowWindowcostruttore inserisci qui la descrizione dell'immagine

  3. Ctrl + Maiusc + F per confermare che non c'è nessun mainposto nella directory di origine. inserisci qui la descrizione dell'immagine

  4. F5 / compilare ed eseguire. inserisci qui la descrizione dell'immagine

Come funziona

Per le applicazioni WPF, Visual Studio genera obj\Debug\App.g.csquale contiene il Mainmetodo. Il generato Maincrea un'istanza della tua app WPF e la avvia.


Soluzione interessante. Qualcuno che pensa che questa non sia una soluzione valida? Se qualcuno ritiene che questo post non sia valido, si prega di inviare un commento. Altrimenti dichiarerò questa soluzione quella vincente perché era ovviamente la prima pubblicata.
Martin Rosenau,

@MartinRosenau Sento che dal momento che potresti decompilare l'app wpf e ci sarebbe un metodo principale che questo non è valido, più fortemente perché lo stesso utente ha pubblicato un'altra risposta che non ha questa ambiguità

Ho appena visto che entrambe le risposte sono state pubblicate dallo stesso utente. In questo caso questo utente vincerà comunque.
Martin Rosenau,

0

Proprio come riferimento

La mia idea era simile alla seconda idea di "latte":

Trova un modo per consentire all'IDE di eseguire il codice e scrivere un eseguibile sul disco.

Ho menzionato esplicitamente i binari di Windows e Linux perché ho pensato di scrivere il file .EXE binario usando System.IO.File.WriteAllBytes() modo che non fosse necessariamente un file EXE .NET.

Il mio problema era che VS Express 2010 non sembra avere una console interattiva, quindi ho dovuto trovare un sostituto per questo - ho trovato quanto segue:

Creare un progetto DLL con una finestra di dialogo e un controllo personalizzato; compilare il progetto e aggiungere il controllo personalizzato alla finestra di dialogo. L'editor della finestra di dialogo chiamerà quindi il codice del controllo personalizzato e in questo codice è possibile scrivere il file .EXE sul disco ...

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.