第 9 講:魚(yú)不止可以吃,也可以當(dāng)技巧用
我們進(jìn)入一個(gè)新的技巧。這個(gè)技巧有一個(gè)比較好吃的名字:魚(yú)(Fish)。
有些地方魚(yú)也可以叫鏈列。不過(guò)這個(gè)詞語(yǔ)已經(jīng)棄用,因?yàn)椤斑^(guò)時(shí)”了。
Part 1?X-Wing

如圖所示,可以觀(guān)察到,r18兩行里,能放下6的地方現(xiàn)在僅剩4個(gè)單元格,而且這4個(gè)單元格又恰好構(gòu)成矩形的形狀。那么不論如何,6的擺放位置只可以是對(duì)角兩格的填數(shù)情況是一樣的。換句話(huà)說(shuō),要么左上角r1c2和右下角r8c6同時(shí)填6,要么右上角r1c6和左下角r8c2同時(shí)填6,沒(méi)有其它情況。
注意,馬上要得到的這一點(diǎn)很重要!雖說(shuō)我們無(wú)法確定6的確切位置,但我們可以發(fā)現(xiàn),6在c26里的填數(shù)也必須只能在r18c26四個(gè)單元格里。因?yàn)閯偛诺恼f(shuō)明已經(jīng)得到了,兩種情況里必須得有一個(gè)情況是對(duì)的,我們此時(shí)假設(shè)我們聚焦于c2來(lái)看,第一種情況下,c2里會(huì)填入一個(gè)6在r1c2上;而第二種情況下c2里會(huì)填入一個(gè)6在r8c2上。這使得兩種情況里,都會(huì)出現(xiàn)一個(gè)6在r18c2里;同理,聚焦于c6也是如此:第一種情況下填入到的地方是r8c6;而第二種情況則填入到r1c6。
雖說(shuō)文字有些繞,我覺(jué)得你應(yīng)該能明白我想表達(dá)的意思。那么既然這樣的結(jié)構(gòu)除了在r18里保證出現(xiàn)6,還能保證c26里也各有一個(gè)6在這四個(gè)單元格里,那么很顯然,c26的其余位置都不能再填入6了,畢竟這兩列的6已經(jīng)只能放在r18c26里了。所以其余位置的6都可以被刪除,于是有r9c2, r379c6 <> 6。
這個(gè)技巧的巧妙之處在于,它的推理邏輯和之前我們說(shuō)到過(guò)的一個(gè)技巧:組合區(qū)塊很類(lèi)似。在組合區(qū)塊里,我們也是把區(qū)塊當(dāng)成了這樣的形式,然后發(fā)現(xiàn)只能處于結(jié)構(gòu)對(duì)角線(xiàn)的兩格的填數(shù)情況才是一樣的。這種結(jié)構(gòu)實(shí)際上被稱(chēng)之為魚(yú)或鏈列,而魚(yú)和數(shù)組一樣,也是有規(guī)格(階)一說(shuō)的,所以這個(gè)魚(yú)的規(guī)格是涉及兩行兩列,因此被稱(chēng)為二階,一般我們稱(chēng)這種結(jié)構(gòu)叫做二階魚(yú)(不過(guò)這個(gè)技巧一般用的是英文名X-Wing)。這個(gè)魚(yú)的階(Order/Size)跟數(shù)組的階差不多,魚(yú)的階指的是涉及的定義域區(qū)域總數(shù)。比如這里涉及的定義域區(qū)域是兩個(gè):r1和r8,所以是2階的。
二階魚(yú)(X-Wing)有時(shí)候也被叫做二鏈列。
Part 2 一些術(shù)語(yǔ)
在魚(yú)的體系里,充滿(mǎn)著各種詭異可怕的術(shù)語(yǔ),但不要怕,我們這里提到一部分我們常用的,而復(fù)雜和難懂的術(shù)語(yǔ),當(dāng)后面用到的時(shí)候,我們才會(huì)提及。
定義域(Defining Set/Base Set):結(jié)構(gòu)被定義下來(lái)的位置,比如這個(gè)例子里,定義域?yàn)閞18(因?yàn)槲覀儼l(fā)現(xiàn)r18里填入6的位置只有四格,所以稱(chēng)這種東西叫做定義域)。
刪除域(或者叫刪數(shù)域,Secondary Set/Cover Set):能刪除候選數(shù)情況的區(qū)域,比如這里的c26就是這個(gè)魚(yú)的刪除域。
魚(yú)身(Body):結(jié)構(gòu)涉及的所有單元格,比如前面這個(gè)示例下的r18c26就是魚(yú)身。
目前就只需要提及這樣幾個(gè)簡(jiǎn)單的術(shù)語(yǔ)。
Part 3 三鏈列/劍魚(yú)(Swordfish)
那么既然魚(yú)也有規(guī)格,那么何不把它擴(kuò)展到三階的情況呢?我們來(lái)看看三階的情況。
3-1 一個(gè)奇怪的例子

如圖所示,變成三階后,這個(gè)例子實(shí)際上就比以前的結(jié)構(gòu)看起來(lái)要復(fù)雜太多了:?jiǎn)卧裆婕暗臄?shù)量就從4飛升到了9,漲了一倍還多。沒(méi)關(guān)系,別怕。
由于這個(gè)結(jié)構(gòu)涉及恰好3 * 3 = 9個(gè)單元格(乘號(hào)用“*”代替,除號(hào)用“/”代替,方便打字,后同),即三行三列,顯然這說(shuō)明了在魚(yú)身里必須填入剛好3個(gè)4,而且還不能違背數(shù)獨(dú)規(guī)則(即同一個(gè)區(qū)域里有相同的數(shù)字)。那么,你隨便放置這些4,你都會(huì)發(fā)現(xiàn),因?yàn)槭侨腥械慕Y(jié)構(gòu),所以為了保證行列宮之間不出現(xiàn)重復(fù)的沖突,數(shù)字只能錯(cuò)開(kāi)分布,而且4的位置也必須得在c567的每一列里都恰好要出現(xiàn)一個(gè)4才行。這是顯然的,因?yàn)橹挥腥械年P(guān)系,每一行放一個(gè)4還不重復(fù)的話(huà),對(duì)于列的角度而言,由于列也恰好是三個(gè),所以必須是每一列都有一個(gè)4。這便使得c567之中各有一個(gè)4出現(xiàn)在魚(yú)身里。于是,刪除域便形成了:c567,所以c567的其余單元格的候選數(shù)4都將被刪除。
這個(gè)結(jié)構(gòu)由于是三階的,所以稱(chēng)為三階魚(yú),而由于它的技巧英文名叫做Swordfish,所以這個(gè)結(jié)構(gòu)也總被稱(chēng)為劍魚(yú)。不過(guò)??雌饋?lái)似乎二鏈列的邏輯和三鏈列差別有點(diǎn)大,不過(guò)……你可以試試看,用現(xiàn)在這里的三鏈列的思維套用到二鏈列上,你就會(huì)發(fā)現(xiàn),二鏈列實(shí)際上也可以用這個(gè)邏輯來(lái)理解,之前只是為了方便理解,直接寫(xiě)上了二鏈列它自己?jiǎn)为?dú)的視角罷了(其實(shí)這兩種說(shuō)法是等價(jià)的)。
同理,三階魚(yú)有時(shí)候也被叫做三鏈列。
3-2 奇怪的事情發(fā)生了
慢著,你是不是沒(méi)有看到r9c7啊,這不是唯一余數(shù)嗎(一個(gè)單元格就只有一個(gè)候選數(shù)的時(shí)候,就可以稱(chēng)這個(gè)單元格是唯一余數(shù)了,這和我們之前學(xué)到的唯一余數(shù)的邏輯是一樣的)。很明顯,出了這些數(shù)字后,豈不是4就顯然不能這么放了,而是這樣:

是的。但我想告訴你,這不影響我們使用魚(yú)技巧。換言之,這種殘缺(Incomplete)的結(jié)構(gòu)依然是可以使用魚(yú)技巧的。這是為什么呢?這是因?yàn)槲覀冊(cè)趧偛湃溋械倪壿嫷臅r(shí)候,并不關(guān)心內(nèi)部是否有殘缺,而僅僅是看到結(jié)構(gòu)涉及三行三列后,為了保證每一行列都要出現(xiàn)一個(gè)數(shù)字4,那么必然要讓4放置在行列互不沖突的三個(gè)單元格上,而結(jié)構(gòu)是否殘缺并不會(huì)影響最終4要每一列都有一個(gè)的要求。所以,這種魚(yú)依然是可行的,并且刪除域、定義域依然不會(huì)發(fā)生變化,只是魚(yú)身少了一格r8c5。
那么,我們?cè)賮?lái)看兩則示例(左圖和右圖),來(lái)好好體會(huì)和理解剛才我們說(shuō)到的殘缺。


Part 4 四階魚(yú)(Jellyfish)
三階的結(jié)構(gòu)大體的邏輯就可以理解成“三行的結(jié)構(gòu)只出現(xiàn)在不同的三列里”,那么四階就依葫蘆畫(huà)瓢:“四行的結(jié)構(gòu)只出現(xiàn)在不同的四列里”。不過(guò)……這個(gè)例子是反過(guò)來(lái)了。

如圖所示。這一次我們把c2378當(dāng)成定義域。
發(fā)現(xiàn),c2378里能放置9的位置只出現(xiàn)在r1247這樣不同的四行上。為了我們要在這個(gè)c2378里每一列都放上一個(gè)9,還得不同行列(不產(chǎn)生沖突),我們發(fā)現(xiàn),唯有把9放置在r1247,每一列都有一個(gè)9的時(shí)候,才不會(huì)沖突。所以,r1247就是這個(gè)結(jié)構(gòu)的刪除域了。不過(guò)這個(gè)例子厲害的地方在于,所有紅色的數(shù)字都可以刪除掉,而且除了r2c5有一個(gè)1外,它的刪數(shù)基本上占滿(mǎn)了整行,足足19個(gè)刪數(shù)。
這個(gè)例子的規(guī)格是4,所以叫四階魚(yú)或四鏈列(Jellyfish)。
Part 5 魚(yú)的互補(bǔ)
在魚(yú)里,好像我們也沒(méi)有說(shuō)到五階甚至更高規(guī)格的魚(yú),這一點(diǎn)是為什么呢?難道它和數(shù)組一樣?是的。魚(yú)也有互補(bǔ),而正是因?yàn)樗谢パa(bǔ),所以才不存在五階甚至更高規(guī)格的魚(yú)。如圖所示,這是兩個(gè)魚(yú)的互補(bǔ)情況。


如圖所示,這是兩個(gè)互補(bǔ)的魚(yú)結(jié)構(gòu),隨便先看哪個(gè)例子都行。
比如左圖,我們作為“基準(zhǔn)”示例來(lái)看,它實(shí)際上是一個(gè)有殘缺的三階魚(yú)結(jié)構(gòu),而刪數(shù)也都是成立的(這一點(diǎn)我這里就不再說(shuō)明了,因?yàn)檫@個(gè)例子在之前是有出現(xiàn)的,所以就請(qǐng)你自行推理了)。
不過(guò),我們把剩下沒(méi)有被涂色的單元格里(白色)的所有5都找到,然后按照正交(Orthogonal)的形式畫(huà)出定義域。所謂的正交,就是說(shuō),如果原來(lái)是行,那與之正交的就是列;如果是列,與之正交的就是行。那么因?yàn)椤盎鶞?zhǔn)”示例的定義域是行,所以我們正交的例子的定義域就必須是若干個(gè)列。
此時(shí),我們又得到了右圖的這個(gè)魚(yú),雖然它也是殘缺的,但是我們只轉(zhuǎn)變了定義域和刪除域的情況,但發(fā)現(xiàn),其實(shí)刪數(shù)卻沒(méi)有絲毫變化,這一點(diǎn)和我們之前數(shù)組的顯隱性互補(bǔ)很類(lèi)似,刪數(shù)是一樣的,所以我們才稱(chēng)這兩個(gè)魚(yú)互補(bǔ)。
正是因?yàn)檫@種形式的出現(xiàn),所以我們才不可能擁有超過(guò)4階的魚(yú)結(jié)構(gòu):盤(pán)面整體是9階的,如果某個(gè)數(shù)字在n個(gè)正交的行列里都沒(méi)有出現(xiàn),則說(shuō)明這個(gè)數(shù)字一旦形成魚(yú)結(jié)構(gòu),那么它的最高規(guī)格就不能超過(guò)9 - n。而如果在這個(gè)數(shù)里能找到一個(gè)m階的魚(yú),那與之互補(bǔ)的魚(yú)的階數(shù)必然是9 - n - m,但因?yàn)閚不能超過(guò)4,所以9 - n - m這個(gè)數(shù)是永遠(yuǎn)都不可以超過(guò)4的。說(shuō)起來(lái)很學(xué)術(shù),實(shí)際上對(duì)照?qǐng)D上說(shuō)就很清晰:如果把所有5都畫(huà)出來(lái),然后行列都標(biāo)出來(lái)就會(huì)發(fā)現(xiàn),它實(shí)際上只占據(jù)六行六列。既然魚(yú)存在互補(bǔ),那么兩個(gè)魚(yú)的規(guī)格之和就必須是6,你不能因?yàn)榛パa(bǔ),規(guī)格之和都超過(guò)6了,這顯然不可能(畢竟6行6列只能最多填入6個(gè)這個(gè)數(shù)進(jìn)去,規(guī)格之和超過(guò)6就意味著兩種魚(yú)內(nèi),填這個(gè)數(shù)的總量已經(jīng)超過(guò)6個(gè)了,我們只能填6了,所以這就矛盾了)。
所以,魚(yú)的規(guī)格也不可能超過(guò)4。
Part 6 說(shuō)一下命名
還是老規(guī)矩,和數(shù)組一樣,說(shuō)一下普通魚(yú)的名稱(chēng)。
因?yàn)槠胀~(yú)都有自己的名詞,是用魚(yú)來(lái)表示的,所以每一個(gè)階的魚(yú)都有自己的名字,如下:
二階魚(yú):X-Wing;
三階魚(yú):Swordfish(劍魚(yú));
四階魚(yú):Jellyfish(水母);
五階魚(yú):Squirmbag/Starfish(海星);
六階魚(yú):Whale(鯨魚(yú));
七階魚(yú):Leviathan(海怪,傳說(shuō)里的海中之妖怪)。
其中五鏈列的Squirmbag和Starfish是等價(jià)的兩個(gè)說(shuō)法,意思是一樣的,都指的是五鏈列,用法沒(méi)有絲毫區(qū)別。但是Squirmbag這個(gè)詞語(yǔ)沒(méi)有中文釋義,甚至連直譯都沒(méi)有,不過(guò)這個(gè)詞語(yǔ)是Squirm(蠕動(dòng))和bag(包)的自然拼接詞,至于為什么,我稍后會(huì)作出說(shuō)明。
和數(shù)組一樣,它沒(méi)有八鏈列和九鏈列,因?yàn)閯偛诺墓礁嬖V我們,9 - n - m的n和m不論隨便怎么取值,它們不可能存在(即使存在,也變?yōu)榕懦记闪耍?/p>
你可能會(huì)很好奇兩個(gè)地方。第一,為什么二鏈列有一個(gè)自己?jiǎn)为?dú)的名字,而不是一個(gè)魚(yú);第二,在之前的邏輯討論和理論討論里,為什么數(shù)組和普通魚(yú)的關(guān)聯(lián)性會(huì)如此大?
先來(lái)解決第一個(gè)問(wèn)題。因?yàn)樵谧铋_(kāi)始,魚(yú)這個(gè)體系的建立是基于三鏈列的,而不是二鏈列,二鏈列在最開(kāi)始也有自己的視角,所以當(dāng)發(fā)現(xiàn)了魚(yú)體系后,才知道二鏈列也屬于這個(gè)體系,因此只是歸到了魚(yú)體系里,而沒(méi)有單獨(dú)為它取名;而另一方面,之所以這個(gè)體系要被稱(chēng)為魚(yú),是因?yàn)閺娜溋虚_(kāi)始,這個(gè)結(jié)構(gòu)的長(zhǎng)相類(lèi)似于美國(guó)的一種軍用雙翼飛機(jī),叫Fairey Swordfish。
現(xiàn)在再來(lái)說(shuō)一下五鏈列的名稱(chēng)Squirmbag。這個(gè)詞語(yǔ)目前都沒(méi)有比較合適的翻譯,它起源于Stringbag(網(wǎng)袋)一詞。和三鏈列的來(lái)源Fairey Swordfish一樣,Stringbag是這架飛機(jī)的昵稱(chēng),所以為了保留其“含義”,于是保留了bag(包、袋子),把string(串)換成了squirm(蠕動(dòng))。
Part 7 魚(yú)的另外一種理解思維:降維
下面我們來(lái)說(shuō)一下剛才可能會(huì)困惑的第二個(gè)問(wèn)題,為什么數(shù)組和普通魚(yú)關(guān)聯(lián)會(huì)如此之大。實(shí)際上,解釋這一點(diǎn)只需要一句話(huà):數(shù)組和普通魚(yú)是同構(gòu)的。所謂的同構(gòu),就是不同的體系里說(shuō)法不一樣,但代替的事物、核心和邏輯全部是相同的。不過(guò)說(shuō)明這一點(diǎn)我們需要借助一個(gè)“工具”——降維。
我們?cè)囅胍幌?,如果我們把一個(gè)盤(pán)面看作是一整個(gè)區(qū)域X(即一行或一列),然后把盤(pán)面的一行或一列看作是這個(gè)區(qū)域X的一個(gè)單元格,然后把一行或一列的一個(gè)單元格看成X里一個(gè)單元格的一個(gè)候選數(shù)。說(shuō)白了就是把盤(pán)面看成區(qū)域,區(qū)域看成格,格看成候選數(shù)。這么看有啥特殊么?是有的,我們來(lái)看看如下這個(gè)例子,我想表達(dá)什么。

如圖所示。這個(gè)魚(yú)的定義域是c349,按列來(lái)看。可以發(fā)現(xiàn),2的位置只能出現(xiàn)于不同的三行里,所以這三行里必須得各有一個(gè)2才能放滿(mǎn)3個(gè)2。
這個(gè)時(shí)候,我們換一個(gè)降維視角來(lái)看:我們把這個(gè)盤(pán)面的九個(gè)列看成同一個(gè)區(qū)域的九個(gè)不同的單元格(比如這個(gè)例子里用到的是c349,降維就相當(dāng)于看作是某個(gè)區(qū)域里的第3、4、9個(gè)單元格)。然后我們針對(duì)于盤(pán)面的這幾列,每一列都看看2的出現(xiàn)位置,c3里2的位置只有第1格和第8格出現(xiàn),降維就對(duì)應(yīng)了剛才說(shuō)到的“某個(gè)區(qū)域的第3格”里只有候選數(shù)1和8;同理,c4里2的位置只出現(xiàn)在r78c4,所以降維后表達(dá)的意思是“某個(gè)區(qū)域的第4格”里候選數(shù)只有7和8;而c9同理,降維后變?yōu)楹蜻x數(shù)1和7。
而單純觀(guān)察候選數(shù)序列:{18}、{78}、{17},顯然它們是構(gòu)成三數(shù)組的,因?yàn)橐粋€(gè)區(qū)域下的這三個(gè)單元格卻只包含三種不同的數(shù)字1、7、8,所以?xún)?nèi)部的填數(shù)必須得是一個(gè)1、一個(gè)7和一個(gè)8。因此我們只需要關(guān)心1、7、8確實(shí)是確實(shí)都出現(xiàn)了即可。那么還原回去,因?yàn)槿龜?shù)組成立,所以原來(lái)的那個(gè)普通魚(yú)的刪數(shù)就完全成立了。按照三數(shù)組的邏輯,刪數(shù)是這個(gè)區(qū)域里剩余位置的1、7、8;那么倒回去看普通魚(yú),這個(gè)意思就是“刪除第1、7、8行其余位置的2”。

技巧信息
二階魚(yú):難度3.2。
三階魚(yú):難度3.8。
四階魚(yú):難度5.2。
其他更高階的魚(yú)可以互補(bǔ)成低階魚(yú),所以難度不作分析。
名詞解釋
魚(yú)(Fish):表示今天講的這些技巧,它們統(tǒng)稱(chēng)魚(yú)。魚(yú)的嚴(yán)格定義是“所有同數(shù)技巧”(包括排除法),但至于這個(gè)嚴(yán)格定義為什么這么說(shuō),我們將在后面才會(huì)解釋。
階、規(guī)格(Order/Size):表示魚(yú)結(jié)構(gòu)的大?。ǘx域的總區(qū)域個(gè)數(shù))。
定義域(Defining Set/Base Set):通過(guò)分情況討論,和假設(shè)所有填數(shù)情況的所處區(qū)域。
刪除域、刪數(shù)域(Secondary Set/Cover Set):魚(yú)結(jié)構(gòu)刪除數(shù)字的所有區(qū)域。
魚(yú)身(Body):所有魚(yú)結(jié)構(gòu)涉及的單元格序列。
殘缺(Incomplete):結(jié)構(gòu)缺失其中一部分,但依舊不影響推理思路的特殊形式。
正交(Orthogonal):結(jié)構(gòu)按行和列互相轉(zhuǎn)換的形式。在魚(yú)的互補(bǔ)里得以體現(xiàn),有時(shí)候也稱(chēng)之為轉(zhuǎn)置(Transpose),但是正交一般說(shuō)明兩個(gè)互補(bǔ)結(jié)構(gòu)之間的關(guān)系是正交的;而轉(zhuǎn)置則指的是行和列轉(zhuǎn)換的過(guò)程。
降維(Dimension Reduction):專(zhuān)用于魚(yú)的技巧里,表示一種思維方式,將里面的行/列轉(zhuǎn)換為單元格,所有這個(gè)行/列下的九個(gè)單元格轉(zhuǎn)換為候選數(shù)1到9,然后把每個(gè)填數(shù)位置比作是一個(gè)候選數(shù)序列。當(dāng)這樣的候選數(shù)構(gòu)成數(shù)組時(shí),也可以表示為原本的魚(yú)是成立的。