ปริศนาการเขียนโปรแกรมของ m3ph1st0s 3 (C):“ Easy bug” [ปิด]


11

นี่คือลำดับที่สามของซีรีส์ของฉันของปริศนา C / C ++; ในกรณีที่คุณพลาด 2 แรกอยู่ที่นี่: (1) ปริศนาการเขียนโปรแกรมของ m3ph1st0s 1 (C ++) (2) ปริศนาการเขียนโปรแกรมของ m3ph1st0s 2 (C ++): "Call hard!"

ฉันต้องบอกว่าปริศนาของฉันเป็นของแท้ 100% ถ้าไม่ฉันจะพูดในข้อความเสมอ ตัวต่อที่ 3 ของฉันมี 2 ส่วนดังนี้

ปริศนา 3.1

ส่วนนี้ (3.1) ไม่ใช่ตัวต่อดั้งเดิมของฉันมันถูกรวบรวมจากหน้าอินเทอร์เน็ตบางส่วนที่ฉันได้อ่านเมื่อไม่นานมานี้ ฉันใช้ที่นี่เป็นจุดเริ่มต้นและอบอุ่นร่างกายของคุณ แก้ปัญหานี้แล้วย้ายไปยังส่วนที่ 2

บางคนพยายามพิมพ์เครื่องหมาย "+" 20 ครั้งและเกิดขึ้นกับโปรแกรมต่อไปนี้:

#include <stdio.h>
int main() {
   int i;
   int n = 20;
   for( i = 0; i < n; i-- )
      printf("+");
   return 0;
}

ความจริงที่ว่ามันไม่ได้ผลลัพธ์ที่คาดหวังชัดเจน - โปรแกรมไม่สิ้นสุด ซ่อมมัน! ง่าย? ตอนนี้แก้ไขโปรแกรมโดยการเปลี่ยนเพียงตัวละครเดียว - ตัวละครที่ไม่ใช่ช่องว่างของหลักสูตร! สำหรับความท้าทายนี้มี 3 โซลูชั่น ค้นหาทั้งหมด 3 รายการ เพียงเพื่อให้ชัดเจน: โปรแกรมจะต้องส่งสัญญาณ 20 "+" และต้องจบเร็ว ก่อนที่จะวิพากษ์วิจารณ์ฉันในสิ่งที่ "เร็ว" หมายถึงฉันจะบอกว่ามันหมายถึงมากที่สุดไม่กี่วินาที (ซึ่งเป็นวิธีที่มากเกินไป แต่เพียงเพื่อให้ชัดเจน)

ปริศนา 3.2

แก้ไข มันชี้ไปที่ฉันก่อนหน้านี้ว่าวิธีแก้ปัญหาสำหรับตัวปริศนา 3.2.2 อาจขึ้นอยู่กับผู้แปล เพื่อที่จะกำจัดการอภิปรายใด ๆ ที่เป็นไปได้ในเรื่องนี้ฉันจะแก้ไขความคิดและปรับปรุงมันในปริศนาตัวต่อไปเมื่อฉันจะใช้ความระมัดระวังเป็นพิเศษเพื่อไม่ให้เกิดการโต้เถียง อย่างไรก็ตามเพื่อให้ไขปริศนานี้ดำเนินต่อไปฉันจะทำการดัดแปลงเล็กน้อยสำหรับ 3.2.2 (การแก้ปัญหาจะง่ายขึ้น แต่สะอาดกว่า)

เมื่อฉันเห็นภาพปริศนาครั้งแรกฉันพบว่ามันยอดเยี่ยมมาก ฉันจัดการเพื่อแก้ปัญหา แต่ไม่ทันทีเพราะต้องมีการเอาใจใส่อย่างระมัดระวัง หากคุณอยู่ที่นี่ก็หมายความว่าคุณแก้ไขได้เช่นกัน หากคุณทำเช่นนั้นด้วยการเขียนโปรแกรมเพื่อแทนที่ตัวอักษรที่เป็นไปได้ทั้งหมดด้วยค่าที่เป็นไปได้ทั้งหมดและทดสอบทุกวิธีคุณจะสูญเสีย แม้ว่าผู้ชายที่ทำงานอย่างหนัก ขณะนี้มีการแก้ไขโปรแกรมที่เขียน 20 "+" สัญญาณ:

3.2.1: แทรกตัวอักษรเดี่ยวหนึ่งตัวและไม่มีอะไรเพิ่มเติมในรหัสเพื่อให้ผลลัพธ์นั้นถูกต้องและให้ผลลัพธ์ที่เหมือนกันในโปรแกรมที่ถูกแก้ไขทั้ง 3 ตัว จำเป็นต้องพูดจดหมายต้องอยู่ก่อนการปิดล้อม} ของ main (ฉันบอกว่าเพราะฉันไม่ต้องการที่จะได้ยินคนที่เพิ่งเขียนจดหมายหลังจากรายการ

แก้ไข (ดูตะโกน) - สำหรับคำถามสุดท้ายเหล่านี้ให้พิจารณาว่าตัวนับ i เริ่มต้นจาก -1 แทนที่จะเป็น 0

3.2.1.5: ทำซ้ำปัญหาก่อนหน้านี้ทั้งหมดโดยใช้เงื่อนไขว่าเอาต์พุตมีสัญญาณอย่างน้อย 19 "+" (แต่ยังคงเป็นเอาต์พุต จำกัด ) อนุญาตให้เปลี่ยนช่องว่างได้ ตอนนี้คุณอาจพบวิธีแก้ไขปัญหามากกว่าในกรณีแรก สิ่งเหล่านี้จะเหมาะกับคำถาม 3.2.2

3.2.2: เลือกค่าอื่นเพื่อเริ่มต้นตัวแปร n เพื่อให้ผลลัพธ์ที่ได้จะยังคงเหมือนเดิมสำหรับโปรแกรมที่ถูกแก้ไขอย่างน้อยหนึ่งโปรแกรมใน 3.2.1.5 (ไม่จำเป็นสำหรับพวกเขาทั้งหมด)

LAST EDIT1 : การเปลี่ยนโปรแกรมเพื่อให้สัญญาณ 21 "+" ยังคงเป็นทางออกที่ดีเนื่องจากข้อความต้นฉบับไม่ได้พูดว่า "แน่นอน" 20 สัญญาณ อย่างไรก็ตามการส่งออกไม่มีที่สิ้นสุดเป็นสิ่งต้องห้าม เห็นได้ชัดว่านี่ไม่ได้หมายความว่าเราทุกคนจะเริ่มส่งสัญญาณ "+" หลายร้อยรายการเนื่องจากไม่ได้รับอนุญาต แต่การกำจัดผลลัพธ์ที่สวยงาม 21 รายการนั้นไม่ได้อยู่ในจิตวิญญาณของการแข่งขันครั้งนี้

LAST EDIT2 : การพิจารณา LAST EDIT1 และการยอมรับการเปลี่ยนแปลงพื้นที่ดูเหมือนว่าตอนนี้เรามีวิธีแก้ปัญหาที่เป็นไปได้ 5 ข้อซึ่งสี่ข้อได้ตอบไปแล้ว ความท้าทายที่ผ่านมา แต่ยังไม่ได้รับการสัมผัสและฉันต้องทำให้มันชัดเจนอีกครั้ง: nจะต้องกำหนดค่าอื่น , การแก้ปัญหาที่กำหนด 20 ถึง n โดยเทคนิคบางอย่างจะไม่ทำมัน (เช่น n = 20L) ฉันชอบที่จะเห็นทางออกที่ 3 ที่ไม่เปลี่ยนช่องว่าง

LAST EDIT3 : ฉันได้แก้ไขคำถามสุดท้ายแล้วโปรดอ่าน!

ความท้าทายคือการไขปริศนาทั้งสองส่วน คนแรกที่ทำมันชนะ

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


ฉันถือว่าการเปลี่ยนอักขระหนึ่งตัวรวมถึงการเปลี่ยนช่องว่างเป็นอักขระที่ไม่ใช่ช่องว่างด้วยหรือไม่ ถ้าเป็นเช่นนั้นฉันคิดว่าฉันได้ค้นพบคำตอบทั้ง 3 ข้อสำหรับตอนที่ 1
mellamokb

โอ้ .. เสียใจ .. ฉันมีความคิดที่จะปฏิเสธอย่างชัดเจน แต่ฉันลืมไปแล้ว ฉันจะแก้ไขตอนนี้ ขอบคุณสำหรับการถาม
Bogdan Alexandru

โอ้ดี. เพราะฉันไม่สามารถหาคำตอบใด ๆ ส่วน 3.2.2 สำหรับปัจจุบัน 3 การแก้ปัญหาของฉัน ... ผมคิดว่าวิธีการที่ผมต้องมองหาอีกหนึ่ง :)
mellamokb

ใช่ :) ขอให้โชคดีในเรื่องนั้น
Bogdan Alexandru

1
@ardnew: ฉันไม่เชื่อว่า OP ได้เปลี่ยนเจตนาเดิมของคำถาม ฉันเห็นด้วยมีวิธีที่ดีกว่าในการแก้ไขคำถามมากกว่าการแก้ไขกลุ่มของการแก้ไขในตอนท้าย ... แต่มันก็ยังอยู่ในใจของคำถามเดียวกันโดยมีบางสิ่งที่ชัดเจน
mellamokb

คำตอบ:


8

3.1

for( i = 0;-i < n; i-- )
for( i = 0; i < n; n-- )
for( i = 0; i + n; i-- )

การเปลี่ยนแปลงใด ๆ เหล่านี้จะทำให้สัญญาณของโปรแกรมออก 20 '+' อันนี้อยู่ใกล้:

for( i = 0;~i < n; i-- )

มันส่งสัญญาณ 21 '+'

3.2.1

ฉันพบวิธีอย่างน้อย 112 วิธีในการแก้ปัญหานี้โดยการแทรกจดหมายหนึ่งฉบับ ไม่ใช่ว่าทุกคนจะทำงานกับคอมไพเลอร์

int n = 20L;
int n = 20f;
int n = 20d;
uint n = 20;

for( i = 0L; ... )
for( i = 0f; ... )
for( i = 0d; ... )

iprintf("+");
printf("+x");
printf("x+");

สำหรับสองคนสุดท้ายให้เปลี่ยนตัวอักษรใด ๆxเพื่อให้คำตอบที่เป็นไปได้ 104 ข้อ การใช้หนึ่งในสองบรรทัดสุดท้ายจะเปลี่ยนเอาต์พุต แต่เอาต์พุตจะยังคงเหมือนเดิมสำหรับโปรแกรมที่ถูกแก้ไขทั้ง 3 โปรแกรม

3.2.2

ทั้งหมดที่ฉันได้เกิดขึ้นกับบางสิ่งบางอย่างที่ได้รับการโยนกลับไปยังหมายเลข 20 intในการมอบหมายให้

int n = 20L;
int n = 20.001;
int n = 20.999;
int n = 20 + 0x100000000L;

ใช่คุณมีคำตอบเหมือนกันทุกประการ (ฉันไม่ได้โพสต์ไว้ก่อนหน้านี้เพราะฉันไม่มีคำตอบทุกอย่าง) ฉันคิดว่าคำตอบของ 3.2.2 อยู่ในคำตอบข้อที่สามถึง 3.1 ที่เราไม่เคยพบ (และเชื่อฟังกฎที่ไม่อนุญาตให้เปลี่ยนพื้นที่)
mellamokb

เมื่อวันที่ 3.2.1, ผมไม่แน่ใจว่าเกี่ยวกับfและdต่อท้ายสำหรับintประเภท (ดีdสำหรับการใด ๆประเภทสำหรับเรื่องที่) แต่มีไม่กี่คนที่คุณซ้ายปิด: int n = 20l, และint n = 20U int n = 20uนอกจากนี้ฉันไม่เชื่อว่าuintเป็นตัวระบุประเภทมาตรฐานใน C หรือ C ++ คุณกำลังใช้คอมไพเลอร์ตัวใดสำหรับสิ่งเหล่านี้
ardnew

คุณทำได้ดีมากที่นี่ แต่ยังไม่เสร็จสมบูรณ์! ก่อนอื่นการแก้ปัญหา ~ i ยังดีอยู่! ความต้องการคือการส่งสัญญาณ 20 "+" สัญญาณดังนั้น 21 ยังคงเป็นทางออกที่ดี (ทางออกที่ไม่ดีเพียงอย่างเดียวคือการส่งออกไม่มีที่สิ้นสุด) ซึ่งหมายความว่าคุณได้ค้นพบ 4 โซลูชั่น! และสิ่งที่ตลกคือฉันยังมีอีกหนึ่ง :) เกี่ยวกับ 3.2.2 มันไม่ดีเนื่องจากฉันต้องเปลี่ยนค่า V เป็นพิเศษโดยไม่ต้องทำเทคนิคเพื่อทำให้มัน 20 :)
Bogdan Alexandru

1
และทั้งโซลูชัน -i และ ~ i เปลี่ยนช่องว่างดังนั้นฉันจะพิจารณาโซลูชัน "บางส่วน" โซลูชันที่สมบูรณ์แบบที่ 3 ต้องเปลี่ยนอักขระที่ไม่ใช่ช่องว่างตามที่ระบุในข้อความทดสอบ
Bogdan Alexandru

1
คุณไม่เข้าใจปัญหา ฉันบอกว่าการดัดแปลงจะให้ผลลัพธ์เหมือนกับโปรแกรมที่ถูกดัดแปลง นั่นคือฉันมีโปรแกรมที่ถูกต้อง C1, C2, C3 หลังจากการแทรกตัวละครฉันมี P1, P2, P3 ความต้องการคือ: P1 มีเอาต์พุตเดียวกันกับ C1, P2 มีเอาต์พุตเดียวกันกับ C2, P3 มีเอาต์พุตเดียวกันกับ C3 ไม่ใช่ P1, P2, P3 ที่มีเอาต์พุตเหมือนกัน
Bogdan Alexandru

2

3.1

อีกหนึ่งปริศนา แต่วิธีแก้ปัญหาปกติน่าเบื่อแล้วมีอะไรพิเศษไหม?

แนวทางที่หนึ่ง:

#include <stdio.h>
int main() {
   int i;
   int n = 20;
   for( i = 0; i < n; i++ )
      printf("+");
   return 0;
}

ฉันตัดสินใจที่จะเปลี่ยนแปลงตัวละครเพียงตัวเดียวนั่นคือ-. ไม่มีการเปลี่ยนแปลงอักขระอื่น-ใดนอกจาก

แนวทางที่สอง:

#include <stdio.h>
int main() {
   int i=printf("++++++++++++++++++++");exit(0);
   int n = 20;
   for( i = 0; i < n; i-- )
      printf("+");
   return 0;
}

การเปลี่ยนแปลงนี้ว่าตัวละครตัวหนึ่ง - อัฒภาคหลังจากที่เข้าสู่int i=printf("++++++++++++++++++++");exit(0);

แนวทางที่สาม:

#include <stdix.h>
int main() {
   int i;
   int n = 20;
   for( i = 0; i < n; i-- )
      printf("+");
   return 0;
}

สิ่งนี้จะโหลดstdix.hส่วนหัวของระบบ ในระบบรวมถึงเส้นทางใส่ไฟล์ต่อไปนี้เรียกว่า stdix.h มันจะต้องมีเนื้อหาดังต่อไปนี้

static inline void printf(const char *string) {
    int i;
    for(i = 0; i < 20; i--)
        putchar('+');
    exit(0);
}

3.2

ตอนนี้ใส่ตัวอักษรหนึ่งตัว ดีที่ง่ายแทนที่ด้วยint main() int main(a)สิ่งนี้ไม่ถูกต้องตามมาตรฐาน แต่ใครจะสนใจ?


0

ปริศนา 3.1 คำตอบ

  1. เปลี่ยนi--เป็นn--(สาธิต: http://ideone.com/l0Y10 )
  2. เปลี่ยนi < nเป็นi + n(สาธิต: http://ideone.com/CAqWO )
  3. เปลี่ยนไป[SPACE]i < n -i < n(สาธิต: http://ideone.com/s5Z2r )

ปริศนา 3.2.1

เปลี่ยนint n = 20เป็นint n = 20L(เพิ่มLไปยังท้าย)

ปริศนา 3.2.2

ยังไม่พบคำตอบ ...


ทางออกที่ดีเป็นมาตรฐานสำหรับ 3.1 และ 3.2.1
Bogdan Alexandru

0

3.1

  1. เปลี่ยนi--เป็นn--
  2. i<n ถึง -i<n
  3. (น่าเสียดายที่คำตอบไม่ถูกต้องเพราะฉันไม่ได้ตรวจสอบกับคอมไพเลอร์ก่อนที่จะเห็นคำตอบอื่น ๆ )

3.2.1

int n = 20 

ถึง

uint n = 20

(คอมไพเลอร์ขึ้นอยู่กับ ... )

3.2.2

int n =-20L;

for(i = -1; i%n; i--)

พิมพ์ 19 + int n = 20L;สัญญาณเช่นเดียวกับกับ อย่างไรก็ตามฉันจะไม่คิดอะไรถ้าฉันไม่เห็นคำตอบอื่น ๆ ของ 3.2.1


0
#include <stdio.h>
int main() {
   int i;
   int n = 20;
   for( i = 0; i < n; i++  )
      printf("+");
        printf("\n");
   return 0;
}

1
ตรวจสอบให้แน่ใจว่าได้เพิ่มภาษาโปรแกรมและจำนวนตัวอักษรลงในคำตอบของคุณ
Timtech

1
@Timtech เหตุใดตัวละครจึงนับ นี่ไม่ใช่ code-golf
ภูมิใจ haskeller

1
@Timtech ยังรวมถึงภาษาทำไม? นี่เป็นความท้าทายเฉพาะด้านภาษา
ภูมิใจ haskeller
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.