[英]Find/simplify overlapping modulo
我有一些代碼可以解決今天的“ Advent of Code Part 2”。 https://adventofcode.com/
我目前有很多硬編碼模數條件,是否有任何簡單的方法可以減少條件數?
因為通常,如果您已經檢查x % 2 == 0
則可以跳過檢查x % 4 == 0
x % 2 == 0
。 但是當涉及到添加時,我很難弄清楚如何簡化。 我可以查找任何建議或資源嗎?
if (delay % 6 == 0)
{
return false;
}
if ((delay +1) % 2 == 0)
{
return false;
}
if ((delay +2) % 4 == 0)
{
return false;
}
if ((delay + 4) % 6 == 0)
{
return false;
}
if ((delay + 6) % 14 == 0)
{
return false;
}
if ((delay + 8) % 8 == 0)
{
return false;
}
if ((delay + 10) % 14 == 0)
{
return false;
}
if ((delay + 12) % 10 == 0)
{
return false;
}
if ((delay + 14) % 10 == 0)
{
return false;
}
if ((delay + 16) % 14 == 0)
{
return false;
}
if ((delay + 18) % 10 == 0)
{
return false;
}
if ((delay + 20) % 10 == 0)
{
return false;
}
if ((delay + 22) % 22 == 0)
{
return false;
}
if ((delay + 24) % 22 == 0)
{
return false;
}
if ((delay + 26) % 18 == 0)
{
return false;
}
if ((delay + 28) % 14 == 0)
{
return false;
}
if ((delay + 32) % 14 == 0)
{
return false;
}
if ((delay + 36) % 16 == 0)
{
return false;
}
if ((delay + 40) % 14 == 0)
{
return false;
}
if ((delay + 44) % 32 == 0)
{
return false;
}
if ((delay + 50) % 18 == 0)
{
return false;
}
if ((delay + 56) % 26 == 0)
{
return false;
}
if ((delay + 58) % 26 == 0)
{
return false;
}
if ((delay + 60) % 26 == 0)
{
return false;
}
if ((delay + 62) % 22 == 0)
{
return false;
}
if ((delay + 64) % 26 == 0)
{
return false;
}
if ((delay + 66) % 26 == 0)
{
return false;
}
if ((delay + 68) % 26 == 0)
{
return false;
}
if ((delay + 70) % 26 == 0)
{
return false;
}
if ((delay + 74) % 26 == 0)
{
return false;
}
if ((delay + 76) % 26 == 0)
{
return false;
}
if ((delay + 80) % 26 == 0)
{
return false;
}
if ((delay + 88) % 26 == 0)
{
return false;
}
doSomeComputation...
我假設delay
總是非負的。 如果您的輸入不能保證這一點,則可以使用修正此問題的版本替換模數調用, 如此答案所示 。 就是說,您發布的邏輯可以用以下方式復制:
const int lcm = 1441440;
int[] residues = new int[]
{
1924,
92644,
132964,
223684,
354724,
395044,
616804,
657124,
788164,
878884,
1009924,
1050244,
1181284,
1272004,
1312324,
1403044
};
if (!residues.Contains(delay % lcm)) return false;
生成方法的說明: lcm
是修改數字的最小公倍數 。 您可以通過詢問WolframAlpha或任何其他方式來獲得該信息。 可以通過簡單地遍歷mod lcm
所有lcm
並檢查已經寫入的邏輯中的哪些lcm
來獲得常數lcm
。 以下代碼是我用來打印出來的代碼,其中myPass
函數只是您上面提供的邏輯。
for (int i = 0; i < 1441440; ++i)
if (myPass(i))
Console.WriteLine("i = {0}", i);
解釋為什么起作用:如果delay
是一個整數, m
是一個正整數, n
是一個可被m
整除的正整數,則delay % m
值等於(delay % n) % m
。 一個例子:假設整數delay
具有delay % lcm == 1924
。 然后,我們得出delay % 6
等於(delay % lcm) % 6
,即1924 % 6
,即4
。 同樣,只要delay % lcm
是硬編碼的殘差列表中的值i
(我們對其進行了測試以匹配if
s中的所有各種條件),那么我們知道delay
與它們匹配,因為-無論如何m
一個特定的if
進行測試-我們以這樣的方式生成列表,我們已經知道i % m
符合條件,現在我們有了(delay % m) == (delay % lcm) % m) == i % m
。
注意:此方法僅可行,因為您的條件集排除了僅具有小模數的許多殘基。 例如,如果存在一個與大型素數比較的外圍條件,則殘基列表很容易變得太大而無法處理。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.