#31950: 關於本題在 網頁測試 與 實際評測程式 歧異上的問題


Python_in_one_line (挑戰Python一行 AC 不使用分號、eval()、exe...)

學校 : 新北市立板橋高級中學
編號 : 85952
來源 : [118.150.111.60]
最後登入時間 :
2024-03-13 18:27:09
g751. 聽說只有5%的人能通過這題 -- Ststone | From: [118.150.111.60] | 發表日期 : 2022-09-01 01:49

由於本題中使用的 hash 函數中需要取得單一字元的 Unicode 數值,
鑒於 ZJ 在處理檔案(輸入與輸出)的編碼是使用 UTF-8 ,
在不使用第三方套件的情況之下 C/C++ 實作起來相對複雜,
所以在此假設本題的評測程式使用的語言是  Python  而在網頁端則是使用 JavaScript 進行實作。
由於兩邊是使用不同的語言進行處理,
如果沒處理好的話會生一些語法上的歧異問題,
而本題亦有產生如此問題故特此告知出題者。
 
以下是可能戳到的問題:
對於一些 Unicode 擴展字元來說(好比表情符號:'😀'),
在 JavaScript 中會被視作2個字元,
在 Python 中則是視作1個字元:
# In Python
len('😀')       # 1

// In JavaScript
'😀'.length;    // 2
在網頁端中的 hash 函數 cnt() 裡其中一段如下:
var total = 0;
//console.log(guess.length);
for (var i = 0; i < guess.length; i++) {
    total += guess[i].codePointAt(0);
    answer_array.push(guess[i].codePointAt(0));
    //console.log(guess[i].codePointAt(0));
}
如果評測函數寫成如下:
total = 0
for c in guess:
    total += ord(c)
    answer_array.append(ord(c))
由於兩者對於 Unicode 擴展字元處理上的差異,
兩者所計算出的 total 可能會有所不同,
詳細見以下:
# In Python
ord('😀'[0])   # 128512
ord('😀')      # 128512

// In JavaScript
'😀'[0].codePointAt(0);     // 55357
'😀'[1].codePointAt(0);     // 56832
'😀'.codePointAt(0);        // 128512
好比以 2022/08/31 這天為例,
其種子為 40706 ,
如果在網頁端的測試句子輸入 "👍" 後進行計算將會得到 99.44 分,
但在 ZJ 上輸出僅會得到 26.70 分,
測試可見 解題編號 10114073 ,
不過由於 ZJ 程式碼不能上傳包含 Unicode 擴展字元,
所以這邊採用編碼的方式進行輸出,
可從評分詳細結果發現其效果相當於輸出 "👍" ,
證明對於同樣的測試句子兩邊卻出現截然不同的結果。
可行的解決方法如下,
可以發現在在上面的範例中 JavaScript 對完整的字串 '😀'codePointAt(0) 可以得到與 Python 相同的結果,
所以這邊可以將原字串依照字元進行拆分後再做運算即可,
具體作法如下:
const guess = '😀 Smile Face 😀';
const guess_split = [...guess];     // ['😀', ' ', 'S', 'm', 'i', 'l', 'e', ' ', 'F', 'a', 'c', 'e', ' ', '😀']
不過即使如此,
對於一些複合式 Unicode 擴展字元 (好比表情符號'👨🏻‍🚒')
在處理上還是會有想像中與實際上的差別,
該字串在視覺上會認為是1個字元,
但不管在 Python 或 JavaScript 拆分之後仍然皆會認為是4個字元所組成,
雖然這可能與出題者所想要的效果有所落差,
不過至少該方法可以保證在該部分 Python 與 JavaScript 可以得到相同的結果。
 
再來額外講出題者可能沒有注意到的事情,
如果出題者有注意到的話就直接無視這段吧~~~
對於負數的取模 JavaScript 與 Python 在運算上會得到不同的結果:
# In Python
a =    131 %    7   # 5
b = (-131) %    7   # 2
c =    131 % (-7)   # -2
d = (-131) % (-7)   # -5

// In JavaScript
const w =    131 %    7;    // 5
const x = (-131) %    7;    // -5
const y =    131 % (-7);    // 5
const z = (-131) % (-7);    // -5
不過由於輸入的數值皆是非負整數應該沒有這方面的問題... 嗎... ?
事實上在網頁端的 hash 函數 g(x) 就會產生這問題:
function g(x) {
    x = x%30000;
    return Math.floor(((x - 1) * (x + 2) + Math.floor(x / 4) - (x % 3)) % 48763);
}
可以發現到若當 g(x) 的輸入值取 30000 的餘數為 0 或 1 時,
由於上述提到的性質此時 g(x) 將會分別回傳負整數 -2 和 -1 。
說這麼多但是這樣真的會產生問題嗎?
以技術上來說可能會,
因為 g(x) 有參與 index 的計算(用於 cnt() 內進行 swap),
所以可能有機會計算出負數的 index 導致 crash 。
但以結論來說不會,
不過這只是因為剛好在呼叫 g(x) 時都會加上其它數值導致最終結果為非負,
實際上我有稍微驗證過無論如何調整輸入數值(合理日期產生的 seed 與 測試句子),
應該是不會產生負數 index 的情況, (這邊僅進行簡單的計算與測試無法完全保證)
也因為如此我無法判別這是故意設計如此還是碰巧如此,
故仍在此告知出題者。
 
好了~~~
大致應該就是這樣了,
個人覺得這是個有趣的題目,
不過在一些細節上沒有考慮完整是蠻可惜的,
期待出題者能夠繼續出如此有趣的題目~~~ OwO
 
#31952: Re: 關於本題在 網頁測試 與 實際評測程式 歧異上的問題


Ststone1687 (Ststone)

學校 : 新北市立板橋高級中學
編號 : 124999
來源 : [140.114.89.50]
最後登入時間 :
2024-11-11 12:43:06
g751. 聽說只有5%的人能通過這題 -- Ststone | From: [114.34.121.104] | 發表日期 : 2022-09-01 21:43

謝謝學長 學長好強 orz

關於這些問題,會再另外找時間來做修正並更新相關內容,詳細情況可能等弄完之後再來這邊發個文之類的OwO

然後如果有其他人成功找到了其他的問題也歡迎下發一併提出。

 
#31958: Re: 關於本題在 網頁測試 與 實際評測程式 歧異上的問題


fire5386 (becaidorz)

學校 : 國立清華大學
編號 : 115822
來源 : [140.114.253.147]
最後登入時間 :
2024-10-03 15:39:22
g751. 聽說只有5%的人能通過這題 -- Ststone | From: [36.230.138.226] | 發表日期 : 2022-09-02 11:55

謝謝學長 學長好強 orz

關於這些問題,會再另外找時間來做修正並更新相關內容,詳細情況可能等弄完之後再來這邊發個文之類的OwO

然後如果有其他人成功找到了其他的問題也歡迎下發一併提出。

石頭好電 Ststorzne

 
#32180: Re: 關於本題在 網頁測試 與 實際評測程式 歧異上的問題


Ststone1687 (Ststone)

學校 : 新北市立板橋高級中學
編號 : 124999
來源 : [140.114.89.50]
最後登入時間 :
2024-11-11 12:43:06
g751. 聽說只有5%的人能通過這題 -- Ststone | From: [101.136.116.217] | 發表日期 : 2022-09-19 07:28

目前已經將所遇到之問題修復了,若後續仍有人測出類似問題等等也歡迎提出,會再進行追蹤。
題外話,題序有改過了,這裡偷偷提示一下,如果你看不懂新的題序到底在寫什麼,那有蠻大的機率是你沒有真的AC這題。
 
ZeroJudge Forum