C, 59 ไบต์
i;f(char*s){while(*s&3?*s&9||(i+=i+*s%5):putchar(i),*s++);}
ตัวเลขเวทย์มนตร์หมายเลขเวทย์มนตร์ทุกที่!
(นอกจากนี้ C สั้นกว่า Python, JS, PHP และ Ruby ไม่เคยได้ยินจาก!)
นี่คือฟังก์ชันที่รับสตริงเป็นอินพุตและเอาต์พุตไปยัง STDOUT
เกมส์
โครงสร้างพื้นฐานคือ:
i; // initialize an integer i to 0
f(char*s){
while(...); // run the stuff inside until it becomes 0
}
ที่นี่ "สิ่งที่อยู่ภายใน" คือพวงของรหัสตามด้วยโดย,*s++ที่เครื่องหมายจุลภาคส่งกลับค่าของอาร์กิวเมนต์ที่สองเท่านั้น ดังนั้นสิ่งนี้จะทำงานผ่านสตริงและตั้งค่า*sเป็นตัวละครทุกตัวรวมถึงการต่อท้าย NUL ไบต์ (เนื่องจาก postfix ++คืนค่าก่อนหน้า) ก่อนที่จะออก
ลองดูที่เหลือ:
*s&3?*s&9||(i+=i+*s%5):putchar(i)
การลอกแบบไตรภาคและการลัดวงจรออกไปสิ่ง||นี้สามารถขยายได้
if (*s & 3) {
if (!(*s & 9)) {
i += i + *s % 5;
}
} else {
putchar(i);
}
หมายเลขมายากลเหล่านี้มาจากไหน นี่เป็นตัวแทนไบนารีของตัวละครทั้งหมดที่เกี่ยวข้อง:
F 70 01000110
B 66 01000010
i 105 01101001
z 122 01111010
u 117 01110101
32 00100000
\0 0 00000000
ก่อนอื่นเราต้องแยกช่องว่างและ NUL ออกจากตัวละครที่เหลือ วิธีการทำงานของอัลกอริธึมนี้จะเก็บสะสมของหมายเลข "ปัจจุบัน" และพิมพ์เมื่อใดก็ตามที่มันมาถึงช่องว่างหรือจุดสิ้นสุดของสตริง (เช่น'\0') โดยการสังเกตว่า' 'และ'\0'เป็นตัวอักษรเพียงตัวเดียวที่ไม่มีชุดบิตที่มีนัยสำคัญน้อยที่สุดสองชุดเราสามารถ bitwise และอักขระที่มี0b11ศูนย์เป็นศูนย์ได้ถ้าอักขระนั้นมีช่องว่างหรือ NUL และไม่ใช่ศูนย์
ขุดลึกลงไปในครั้งแรก "ถ้า" FBizuสาขาตอนนี้เรามีตัวละครที่เป็นหนึ่งใน ฉันเลือกที่จะอัปเดตแอคคอมมูเลเตอร์Fของ s และBs เท่านั้นดังนั้นฉันต้องการวิธีการกรองizus สะดวกFและBทั้งสองชุดมีบิตที่สำคัญน้อยที่สองสามหรือเจ็ดและตัวเลขอื่น ๆ ทั้งหมดมีบิตอื่น ๆ อย่างน้อยหนึ่งชุด ในความเป็นจริงพวกเขาทั้งหมดมีบิตที่มีนัยสำคัญน้อยที่สุดที่หนึ่งหรือสี่ ดังนั้นเราสามารถบิตและด้วย0b00001001ซึ่งก็คือ 9 ซึ่งจะให้ 0 FและBและไม่ใช่ศูนย์อื่น ๆ
เมื่อเราได้พิจารณาแล้วว่าเรามีFหรือBเราสามารถ map ให้พวกเขา0และ1ตามลำดับโดยการโมดูลัสของพวกเขา 5 เพราะFเป็น70และเป็นB 66จากนั้นตัวอย่าง
i += i + *s % 5;
เป็นเพียงวิธีการตีกอล์ฟ
i = (i * 2) + (*s % 5);
ซึ่งสามารถแสดงเป็น
i = (i << 1) | (*s % 5);
ซึ่งแทรกบิตใหม่ที่ตำแหน่งสำคัญน้อยที่สุดและเลื่อนทุกอย่างอื่นไป 1
"แต่เดี๋ยวก่อน!" คุณอาจประท้วง "หลังจากที่คุณพิมพ์iจะได้รับการรีเซ็ตเป็น 0 เมื่อใด" ทีนี้putcharมันปลดการทะเลาะกันของมันunsigned charซึ่งมันก็มีขนาด 8 บิต นั่นหมายความว่าทุกอย่างที่ผ่านบิตที่สำคัญน้อยที่สุดที่ 8 (เช่นขยะจากการทำซ้ำก่อนหน้านี้) ถูกโยนทิ้งไปและเราไม่จำเป็นต้องกังวลเกี่ยวกับมัน
ขอบคุณ@ETHproductions ที่แนะนำให้แทนที่57ด้วย9การบันทึกไบต์!