C # เป็นปัญหาหลัก


10

ปริศนาการเขียนโปรแกรมนี้ได้รับแรงบันดาลใจจากคำถามอื่นที่ถูกถามเมื่อวานนี้ แต่ถูกลบโดยผู้เขียน ...

ความท้าทาย:

สร้างไบนารีที่รันได้ (Windows .EXE หรือไบนารี Linux) โดยใช้ Visual C # (หรือ C # IDE ที่คุณชื่นชอบ) ซึ่งพิมพ์ข้อความต่อไปนี้ไปยังเอาต์พุตมาตรฐาน:

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

... โดยไม่ต้องใช้ตัวอักษรต่อเนื่อง 4 ตัวหลักปรากฏในไฟล์ต้นฉบับ!

หมายเหตุ:

  • หากซอร์สโค้ดของคุณมีข้อความremainder(ตัวอย่าง) มันจะมีตัวอักษรต่อเนื่องกัน 4 ตัวหลักอย่างไรก็ตามถ้ามันมีmxainตัวอักษร 4 ตัวจะไม่ต่อเนื่องกันดังนั้นmxainจะได้รับอนุญาต
  • คุณไม่ได้รับอนุญาตให้เรียกใช้โปรแกรมใด ๆ ยกเว้น C # IDE หรือเปลี่ยนการตั้งค่าของ C # IDE เพื่อเรียกใช้โปรแกรมอื่น (แต่โปรแกรมที่ปกติจะรันเช่นคอมไพเลอร์ C #)

    มิฉะนั้นคุณก็สามารถพูดได้ว่า: "ฉันเขียนโปรแกรมภาษาปาสคาลโดยใช้ C # IDE และเรียกใช้ตัวแปลภาษาปาสคาลในขั้นตอน 'สร้างล่วงหน้า' ของโครงการ C # ของฉัน"

    มันจะง่ายเกินไป

  • ผู้ใช้ของ IDE ที่สามารถขยายได้โดยใช้ "ปลั๊กอิน" (หรือคล้ายกัน) หรือที่มีการสร้างขึ้นในการแก้ไขไฟล์ไบนารี (ฐานสิบหกบรรณาธิการ) จะมีมากเกินไปได้เปรียบที่มีขนาดใหญ่กว่าผู้ใช้อื่น ๆ IDEs C #

    ดังนั้นคุณสมบัติเหล่านี้จึงไม่ควรใช้

  • การใช้งานอื่นที่ไม่ใช่ ASCII-Editors (เช่นตัวแก้ไขหน้าต่างโต้ตอบ) ได้รับอนุญาตอย่างชัดเจน!
  • ผู้ใช้ถามคำถามเดิมที่เสนอโดยใช้เครื่องหมายแบ็กสแลชในชื่อฟังก์ชันดังนี้: static void M\u0061in()เนื่องจากคำตอบนี้ถูกอ่านโดยผู้ใช้คนอื่นแล้วจะไม่ได้รับการยอมรับอีกต่อไป!
  • ผู้ใช้ถามว่าจะอนุญาตให้พิมพ์ไฟล์. EXE ในตัวแก้ไขซอร์สโค้ดหรือไม่และบันทึกไฟล์เป็น ".exe" แทนที่จะเป็น ".cs" คำตอบ: ฉันสงสัยว่ามันเป็นไปได้เพราะทั้งไบนารี Windows และ Linux ที่ถูกต้องมี NUL ไบต์ อย่างไรก็ตามหากคุณพบว่าไบนารีที่ถูกต้องที่สามารถสร้างวิธีนี้คุณมีทางออกที่ถูกต้อง

ชื่อของไซต์นี้คือ "การเขียนโปรแกรมปริศนา&รหัสกอล์ฟ" - นี่คือ "การเขียนโปรแกรมปริศนา" ไม่ใช่ "รหัสกอล์ฟ": ความท้าทายคือการหาวิธีการแก้ปัญหาการทำงานก่อนที่ผู้ใช้อื่น ๆ ทั้งหมดไม่หาวิธีสั้นกว่าอื่น ๆ การแก้ปัญหา

ดังนั้นโพสต์แรกที่อธิบายวิธีการแก้ปัญหาการทำงานชนะ !

โชคดี!

โดยวิธีการ: ฉันมีวิธีแก้ปัญหาทำงานภายใต้ Visual C # Express 2010


2
อะไรทำให้ฉันไม่สามารถใช้ C # IDE เป็นตัวแก้ไขข้อความ (หรือไบนารี) เพื่อพิมพ์สิ่งที่เรียกใช้งานได้โดยตรง
feersum

2
คำตอบใดที่ชนะการท้าทาย คำตอบแรกที่ถูกต้อง? คุณควรระบุเงื่อนไขการชนะ
James

หาก IDE มีตัวแก้ไขเลขฐานสิบหกบางตัวหรือที่คล้ายกันสิ่งนี้จะไม่ได้รับอนุญาต หากคุณจัดการเพื่อใช้ตัวแก้ไขข้อความ ASCII เพื่อพิมพ์ในไฟล์ไบนารีที่ถูกต้องสิ่งนี้จะได้รับอนุญาต โปรดทราบว่าไฟล์ไบนารีที่ถูกต้องมีไบต์ในช่วง 0x00 ถึง 0x1F!
Martin Rosenau

2
ฉันคิดว่านี่เป็นความท้าทายที่น่าสนใจโดยรวม "เขียนโปรแกรม C # โดยไม่มีหลัก" อย่างไรก็ตามกฎส่วนใหญ่เกี่ยวกับเครื่องมือ / IDE ที่จะใช้และห้ามวิธีการบางอย่าง ฉันชอบที่จะเห็นปริศนาการเขียนโปรแกรมเพิ่มเติม (ตรงข้ามกับโค้ดกอล์ฟ) แต่อันนี้ไม่ได้ระบุไว้ ฉันขอแนะนำให้ใช้Sandboxครั้งต่อไป
James

4
... พิจารณากล่องทรายครั้งต่อไป
แมว

คำตอบ:


5

หน้าต่างแบบโต้ตอบ C #

เปิดหน้าต่าง C # Interactive (ดู> Windows อื่น ๆ > C # Interactive ใน Visual Studio 2015) ฉันคิดว่า IDEs ทั้งหมดจะไม่มีสิ่งนี้

วิธีการนี้จะดำเนินการ 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.CurrentDirectoryเพื่อดูว่า exe ถูกสร้างขึ้นที่ใด เรียกใช้เพื่อสังเกตผลลัพธ์ที่ต้องการ

ป้อนคำอธิบายรูปภาพที่นี่

ส่งผลให้ IL: ป้อนคำอธิบายรูปภาพที่นี่


ฉันชอบอันนี้ดีกว่าแล้วก็ WPF เพราะคุณไม่มี Main () ในสภาของคุณ
hstde

ทางออกของคุณน่าสนใจ มันเป็นรายการที่สองดังนั้นคุณจะชนะถ้าผู้ใช้ควรโน้มน้าวใจฉันว่าการโพสต์แรกนั้นไม่ใช่ทางออกที่ถูกต้อง (ด้วยเหตุผลใดก็ตาม)
Martin Rosenau

หากคุณถามฉันว่าไม่สำคัญว่าการโพสต์ใดจะชนะเพราะทั้งคู่เป็นผู้ใช้คนเดียวกัน
hstde

@hstde - ขออภัยฉันไม่เห็นสิ่งนี้ ขอบคุณ
Martin Rosenau

@milk คุณโพสต์โซลูชันที่ถูกต้องสองรายการ (ผู้ใช้บางคนมีข้อสงสัยเกี่ยวกับโซลูชั่นแรก) เพื่อให้คุณชนะ ขอแสดงความยินดี
Martin Rosenau

3

แอปพลิเคชัน WPF

  1. สร้างแอปพลิเคชัน WPF ใหม่ ป้อนคำอธิบายรูปภาพที่นี่

  2. แทนที่ทุกกรณีMainด้วยMeow ป้อนคำอธิบายรูปภาพที่นี่

  3. เปลี่ยนชื่อไปMainWindow.xaml MeowWindow.xamlนี้จะเปลี่ยนชื่อโดยอัตโนมัติเพื่อMainWindow.xaml.csMeowWindow.xaml.cs

ป้อนคำอธิบายรูปภาพที่นี่

  1. ในคุณสมบัติของโปรเจ็กต์เปลี่ยนประเภทเอาต์พุตเป็นConsole Applicationดังนั้นจึงสร้างคอนโซล ป้อนคำอธิบายรูปภาพที่นี่

  2. เพิ่ม console write สำหรับเอาต์พุตสตริงที่ต้องการในMeowWindowConstructor ของคุณป้อนคำอธิบายรูปภาพที่นี่

  3. Ctrl + Shift + F เพื่อยืนยันว่าไม่มีmainที่ใดในไดเรกทอรีต้นทาง ป้อนคำอธิบายรูปภาพที่นี่

  4. F5 / รวบรวมและเรียกใช้ ป้อนคำอธิบายรูปภาพที่นี่

มันทำงานอย่างไร

สำหรับแอปพลิเคชั่น WPF นั้น Visual Studio จะสร้างobj\Debug\App.g.csซึ่งมีMainวิธีการดังกล่าว สิ่งที่สร้างขึ้นMainจะสร้างอินสแตนซ์ของแอป WPF ของคุณและเริ่มต้นมัน


ทางออกที่น่าสนใจ ใครที่คิดว่านี่ไม่ใช่ทางออกที่ถูกต้อง? หากใครคิดว่าโพสต์นี้ไม่ถูกต้องโปรดโพสต์ความคิดเห็น มิฉะนั้นฉันจะประกาศทางออกนี้ผู้ชนะเพราะเห็นได้ชัดว่าเป็นคนแรกที่โพสต์
Martin Rosenau

@MartinRosenau ฉันรู้สึกว่าเนื่องจากคุณสามารถแยกแอปพลิเคชัน wpf และจะมีวิธีการหลักที่ว่านี้ไม่ถูกต้องมากขึ้นอย่างยิ่งเพราะผู้ใช้รายเดียวกันโพสต์คำตอบอื่นที่ไม่มีความคลุมเครือนี้

ฉันเพิ่งเห็นว่าคำตอบทั้งคู่ถูกโพสต์โดยผู้ใช้รายเดียวกัน ในกรณีนี้ผู้ใช้รายนี้จะเป็นผู้ชนะต่อไป
Martin Rosenau

0

เป็นการอ้างอิง

ความคิดของฉันคล้ายกับแนวคิดที่สองของ "milk":

ค้นหาวิธีปล่อยให้ 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.