วงแหวนเว็บ

neizod's speculation

insufficient data for meaningful answer

$\frac12 < \lfloor\bmod(\lfloor\frac{y}{17}\rfloor 2^{-17\lfloor x\rfloor-\bmod(\lfloor y\rfloor,17)}, 2) \rfloor$

Saturday, December 18, 2021, 07:33 AM

(อ)สมการสุดมหัศจรรย์ที่เหล่าเนิร์ดคณิตศาสตร์คลั่งไคล้ หนึ่งในนั้นคงจะมีสูตรของ Tupper อยู่ในอ้อมอกอ้อมใจของใครหลายคนเป็นแน่ เพราะเมื่อพล็อตกราฟสูตรดังกล่าวออกมาดูแล้วจะพบว่ามันมีหน้าตาดังนี้

ซึ่งก็คือสูตรของตัวมันเองยังไงหละ!!!

แต่ความมหัศจรรย์ที่ไร้คำอธิบายก็คงกลายเป็นไสยศาสตร์ของขลังที่ห้ามต้องแตะ เพราะงั้นเรามาแกะอสมการนี้ดูกันดีกว่าว่ามันทำงานยังไง

ก่อนอื่นสังเกตว่าอสมการดังกล่าวมีตัวเลขแปลกปลอมที่ไม่ควรจะเห็นบ่อยๆ ซึ่งก็คือ $17$ ที่ปรากฏถึงสามครั้ง เลขนี้มันหมายความว่ายังไงกันนะ?

เริ่มจากค่า $17$ ตัวแรกที่เห็นใน $\lfloor\frac{y}{17}\rfloor$ ถ้าเราลองแทนค่า $y$ บางค่าดู จะเห็นว่าผลลัพธ์ย่อยแค่ส่วนนี้จะถูกแบ่งออกเป็นช่วงๆ ตามค่า $y$ โดยแต่ละช่วงมีความกว้าง $17$ หน่วย (เช่น ช่วงของ $0 \le y \lt 17$ นั้นให้ผลลัพธ์เท่ากับ $0$ เหมือนกันหมด) ซึ่งก็คือถ้าเราอยากเห็นผลลัพธ์ที่แตกต่างออกไป ก็ต้องเปลี่ยนค่า $y$ ไปครั้งละ $17$ หน่วย

ต่อมาข้ามไปดู $17$ ตัวท้ายสุด $\bmod(\lfloor y\rfloor, 17)$ คราวนี้ถ้าลองไล่แทนค่า $y$ แบบเดิมดู จะกลายเป็นว่าผลลัพธ์ย่อยให้ค่าแตกต่างกันออกไปในแต่ละช่วงของ $y$ แล้ว อย่างไรก็ตามหากเปลี่ยนค่า $y$ แบบก้าวกระโดดข้ามช่วงครั้งละ $17$ หน่วย จะกลายเป็นเห็นผลลัพธ์ซ้ำตรงกับของเดิมพอดี

ซึ่งก็คือสูตรนี้ใบ้เราว่า ให้เราพล็อตกราฟตามแกน $Y$ สูงครั้งละ $17$ หน่วย และเราสามารถ “ดึง” เอาค่า $y$ ออกมาใช้งานต่อได้ โดยเราจะแบ่งมันออกเป็นสองส่วน ได้แก่ ส่วนของจำนวนเต็ม $q$ กับส่วนของเศษเหลือ $r$ ซึ่งคำนวณผ่านการนำ $\lfloor y\rfloor$ ไปหารด้วย $17$ นั่นเอง

ย้อนกลับมาดูค่า $17$ ตัวตรงกลางที่เมื่อกี้ข้ามไป คราวนี้ดูทั้ง $-17\lfloor x\rfloor -r$ อย่าลืมว่า $r$ เป็นจำนวนเต็มที่ $0 \le r \lt 17$ นี่เป็นการบอกคร่าวๆ ว่าเราจะพยายามประกอบร่างตัวเลขใหม่ขึ้นมาให้มันครอบคลุมเซตของจำนวนเต็มทั้งหมด

และเมื่อถอยออกมามองภาพรวมของทั้งอสมการ โดยมองผ่านแว่นตาโปรแกรมเมอร์ที่ทำงานบนเลขฐานสอง จะเห็นว่า $2^{-p}$ ก็คือการเลื่อนบิตไปทางขวาเป็นจำนวน $p$ ครั้ง ส่วน $\bmod(n,2)$ คือการเก็บบิตที่มีค่าต่ำสุดมาใช้คำนวณต่อ รวมกันแล้วก็คือเราต้องการแค่ไล่เช็คว่าแต่ละบิตใน $q$ มีค่าเป็น 0 หรือ 1 เท่านั้นแหละ (แต่ต้นทางเขียนเป็นภาษาคณิตศาสตร์ผ่านอสมการการหาค่าเท็จ/จริงด้วย $\frac12 < \lfloor\cdots\rfloor$ ไปงั้น) โดยเราสร้างดัชนีว่าต้องการชี้ไปที่บิตที่เท่าไหร่ ผ่านการเอา $x$ กับ $y$ มายำกัน โดยแทรกค่า $q$ แฝงไว้กับตัวแปร $y$ นั่นเอง

นี่หมายความว่าอสมการข้างต้นมันก็ไม่ได้วิเศษมหัศจรรย์อะไรขนาดนั้น เพราะมันก็เป็นเพียงแค่การ enumerate การพล๊อตภาพที่มีความสูง $17$ หน่วย (และยาวเท่าไหร่ก็ได้) ทุกรูปแบบ ซึ่งภาพผลลัพธ์ก็จะขึ้นกับค่าตั้งต้น $q$ โดยไล่พล็อตบิตที่มีค่าต่ำสุดเป็นพิกเซลเริ่มที่มุมบนซ้าย บิตถัดมาจะไล่ลงไปตามแกน $Y$ เรื่อยๆ จนเมื่อแถวแนวตั้งไล่เลขครบ $17$ บิต ก็จะวนกลับขึ้นไปที่ด้านบนสุดพร้อมขยับในแนวแกน $X$ ไปทางขวา $1$ หน่วย ไล่พล็อตลงล่างจนครบอีกแล้วค่อยๆ ขยับวนไปทางขวาเรื่อยๆ นั่นเอง

ดัชนีตำแหน่งของพิกเซลตัวอย่างบางพิกเซล กริดถูกกลับด้านซ้ายขวาเพื่อความสะดวกในการพล็อตแล้ว

ดังนั้นคำถามจริงๆ แล้วก็คือเราต้องการค่า $q=\lfloor\frac{y}{17}\rfloor$ เท่าไหร่เพื่อให้ได้ภาพนั้นกันหละ? ตรงนี้ไม่ใช่งานยากแล้ว แต่เป็นงานถึกแทนเพราะเราก็แค่ไล่ออกแบบว่าต้องเปิดปิดพิกเซลไหนบ้าง แล้วก็เอาข้อมูลนั้นมาร้อยเรียงเป็นตัวเลขฐานสองก็เสร็จสิ้น ซึ่งอันที่จริงก็ยังทำได้อีกหลายวิธีมากๆ แต่ในเปเปอร์ต้นทาง (ที่พล็อตแบบสลับด้านแกน $X$) ได้ให้ค่าดังกล่าว (ผ่าน $k=17q$) ไว้ดังนี้

k = 17*floor(y/17) = 960939379918958884971672962127852754715004339660129306651505519271702802395266424689642842174350718121267153782770623355993237280874144307891325963941337723487857735749823926629715517173716995165232890538221612403238855866184013235585136048828693337902491454229288667081096184496091705183454067827731551705405381627380967602565625016981482083418783163849115590225610003652351370343874461848378737238198224849863465033159410054974700593138339226497249461751545728366702369745461014655997933798537483143786841806593422227898388722980000748404719

อยากลองเขียนเป็นโค้ด? ระวังแค่ว่าเราต้องทำงานกับตัวเลขขนาดใหญ่มากๆ เพราะนอกจากนั้นก็สามารถลดทอนสูตรข้างต้นลงเหลือเป็นโค้ดง่ายๆ ด้วยการเลื่อนบิตได้ ดังนี้

def f(x, y):
    q, r = divmod(y, 17)
    return bool((q >> 17*x+r) % 2)

for y in range(k, k+17):
    for x in reversed(range(106)):
        print(' ▉'[f(x,y)], end='')
    print()

แน่นอนว่าเราสามารถเปลี่ยนค่า k เป็นค่าอื่นๆ ที่น่าสนใจได้ เช่น

k = 170858557905417978829128239217472162595935968217581069913375205865507367098696572969412461203905446736829218392208338571960279757975859129905839246398599551621608122760168639833583668823268921595150138422041159186319904285738876312105490036626126625434233371834068102168151195388648336791737005908097051895327223087808210533698779397593282595308903423967833321275846479666744055562498990116313304186617099314453030594456329178305520016813652088351091914667354339386586899688883613271898627584622833793175814504438167116064138379119153417619

neizod

author