C # é o principal problema


10

Este quebra-cabeça de programação é inspirado em outra pergunta que foi feita aqui ontem, mas que foi excluída pelo autor ...

O desafio:

Crie um binário executável (Windows .EXE ou Linux) usando o Visual C # (ou seu IDE favorito do C #) que imprime o seguinte texto na saída padrão:

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

... sem usar as 4 letras consecutivas PRINCIPAIS que aparecem em qualquer arquivo de origem!

Notas:

  • Se o seu código fonte contiver o texto remainder(por exemplo), ele conterá as 4 letras consecutivas MAIN, no entanto, se contiver mxainas 4 letras, não seria mais consecutivo, portanto, mxainseria permitido.
  • Você não tem permissão para executar nenhum programa, exceto o C # IDE, nem alterar as configurações do C # IDE para executar outros programas (mas os que normalmente seriam executados, como o compilador C #).

    Caso contrário, você poderia simplesmente dizer: "Eu escrevo um programa Pascal usando o C # IDE e invoco o compilador Pascal nas etapas de 'pré-compilação' do meu projeto C #".

    Isso seria muito simples.

  • Os usuários de um IDE que possam ser estendidos usando "plug-ins" (ou similares) ou que tenham editores de arquivos binários internos (editores hexadecimais) terão uma vantagem muito grande sobre os usuários de outros IDEs C #.

    Portanto, esses talentos também não devem ser usados.

  • É permitido o uso de outros editores não ASCII (como o editor da janela de diálogo)!
  • O usuário que faz a pergunta original proposta usando a barra invertida nos nomes das funções, assim: static void M\u0061in()Como essa resposta já foi lida por outros usuários, ela não será mais aceita!
  • Um usuário perguntou se seria permitido digitar simplesmente um arquivo .EXE no editor de código-fonte e salvar o arquivo como ".exe" em vez de ".cs". Resposta: Não duvido que isso seja possível porque os binários válidos do Windows e Linux contêm NUL bytes. No entanto, se você encontrar um binário válido que possa ser criado dessa maneira, terá uma solução válida.

O nome deste site é "Quebra - cabeças de programação e código de golfe" - este é um "Quebra-cabeça de programação", não "Código de golfe": o desafio é encontrar uma solução funcional para todos os outros usuários, não encontrar uma solução mais curta que todas as outras soluções.

Portanto, o primeiro post que descreve uma solução funcional vence !

Boa sorte!

A propósito: Eu tenho uma solução trabalhando no Visual C # Express 2010.


2
O que me impede de usar meu C # IDE como um editor de texto (ou binário) para digitar diretamente um executável?
— feersum

2
Qual resposta vence o desafio? A primeira resposta válida? Você deve especificar a condição vencedora #
— James

Se o IDE contiver algum editor hexadecimal ou similar, isso NÃO será permitido. Se você conseguir usar o editor de texto ASCII para digitar um arquivo binário válido, isso será permitido. Observe que um arquivo binário válido contém bytes no intervalo de 0x00 a 0x1F!
— Martin Rosenau

2
Eu acho que esse é um desafio interessante. "Escreva um programa C # sem main". No entanto, a maioria das regras trata de quais ferramentas / IDEs usar e banir determinadas abordagens. Eu adoraria ver mais quebra-cabeças de programação (em oposição ao código-golfe), mas este é subespecificado. Eu recomendo usar a sandbox na próxima vez.
— James

4
... Considere a caixa de areia da próxima vez.
— gato

Respostas:


5

Janela C # interativa

Abra a janela interativa do C # (Exibir> Outras janelas> C # interativo no Visual Studio 2015). Suponho que nem todos os IDEs terão isso.

Essa abordagem executa C # na janela interativa para criar um exe em C # que imprime a string desejada sem que o autor nunca tenha escrito main. Como bônus, o IL do exe também não contém main.

Execute o seguinte código na janela interativa

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

Use Environmnent.CurrentDirectorypara ver onde o exe foi criado. Execute-o para observar a saída desejada.

insira a descrição da imagem aqui

IL resultante: insira a descrição da imagem aqui


Na verdade, eu gosto mais deste, então do WPF, porque você não tem Main () na sua Assembléia.
— Htde # 21/16

Sua solução é interessante. É o segundo, então você vencerá se os usuários me convencerem de que o primeiro post não é uma solução válida (por qualquer motivo).
— Martin Rosenau 21/10

Se você me perguntar, não importa realmente qual postagem vence, pois ambas são do mesmo usuário.
— Htde # 21/16

@ hstde - Desculpe, eu não vi isso. Obrigado.
— Martin Rosenau

@ lek Você publicou duas soluções válidas (bem, alguns usuários têm dúvidas sobre a primeira) para ganhar. Parabéns.
— Martin Rosenau

3

Aplicativo WPF

  1. Crie um novo aplicativo WPF. insira a descrição da imagem aqui

  2. Substitua todas as instâncias MainporMeow insira a descrição da imagem aqui

  3. Renomeie MainWindow.xamlpara MeowWindow.xaml. Isso será renomeado automaticamente MainWindow.xaml.cspara MeowWindow.xaml.cs.

insira a descrição da imagem aqui

  1. Nas propriedades do projeto, altere o Tipo de saída para Console Applicationpara que o console seja criado. insira a descrição da imagem aqui

  2. Adicione gravação de console para a sequência de saída desejada em seu MeowWindowconstrutor insira a descrição da imagem aqui

  3. Ctrl + Shift + F para confirmar que não há nenhum mainlugar no diretório de origem. insira a descrição da imagem aqui

  4. F5 / compilar e executar. insira a descrição da imagem aqui

Como funciona

Para aplicativos WPF, o Visual Studio gera obj\Debug\App.g.csqual contém o Mainmétodo O gerado Maincria uma instância do seu aplicativo WPF e o inicia.


Solução interessante. Alguém que acha que essa não é uma solução válida? Se alguém achar que esta publicação não é válida, por favor publique um comentário. Caso contrário, declararei esta solução como a vencedora, porque foi obviamente a primeira publicada.
— Martin Rosenau

@MartinRosenau Eu sinto que desde que você poderia decompor o aplicativo WPF e não haveria um método main que este é inválida, mais fortemente, porque o mesmo usuário postou outra resposta que não tem essa ambiguidade

Acabei de ver que as duas respostas foram postadas pelo mesmo usuário. Nesse caso, esse usuário vencerá de qualquer maneira.
— Martin Rosenau

0

Apenas como referência

Minha idéia foi semelhante à segunda idéia do "leite":

Encontre uma maneira de permitir que o IDE execute o código e grave um executável no disco.

Mencionei explicitamente os binários do Windows e Linux, porque pensei em gravar o arquivo .EXE binário usando, System.IO.File.WriteAllBytes()para que não fosse necessariamente um arquivo .NET EXE.

Meu problema era que o VS Express 2010 parece não ter um console interativo, então tive que encontrar um substituto para isso - encontrei o seguinte:

Crie um projeto DLL com uma janela de diálogo e um controle personalizado; compile o projeto e adicione o controle personalizado à janela de diálogo. O editor da janela de diálogo chamará o código do controle personalizado - e nesse código você poderá gravar o arquivo .EXE no disco ...

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.