无锡锡山山无锡

谢益辉 2017-02-24

看到落园里一篇关于地名的文章,想起前年我在老家冻成狗的时候曾经码了几行代码暴力求解一个无聊的问题,也就是著名的“无锡锡山山无锡”一联的下联是否可以纯用地名去对。从码农的角度来说,无非就是寻找两个地名,满足几个条件:上下级关系、上级地名的后一个字和下级地名的前一个字相同、对联形式为 AB BC C AB。放狗一搜,找个地名数据库,捯饬捯饬,把所有可能的结果输出出来看能否找到有意义的一联就好了。我们的口号是,好记性不如烂键盘。

op = options(stringsAsFactors = FALSE)
# 看强迫症如我,三个变量名一定都是四个字母才舒坦
prov = read.csv('http://pastebin.com/raw/9Gi2VyBV')
city = read.csv('http://pastebin.com/raw/BfmSHgWz')
dist = read.csv('http://pastebin.com/raw/bru0rWAY')
options(op)

x1 = merge(prov, city, by = 'pid')  # 省 - 市
x2 = merge(city, dist, by = 'cid')  # 市 - 区

# 省的第二字与市的第一字相同的行
x3 = x1[substr(x1$prov, 2, 2) == substr(x1$city, 1, 1),]
x4 = substr(x3$prov, 1, 2)  # 省名前两字
x5 = substr(x3$city, 1, 2)  # 市名前两字
# 按 AB BC C AB 格式打印
cat(paste0(x4, x5, substr(x5, 2, 2), x4), sep = '\n')

# 市与区的处理类似
x3 = x2[substr(x2$city, 2, 2) == substr(x2$district, 1, 1),]
x4 = substr(x3$city, 1, 2)
x5 = substr(x3$district, 1, 2)
cat(paste0(x4, x5, substr(x5, 2, 2), x4), sep = '\n')

结果如下。如果只管形式,也许能挑出两句人话来,但上联实在太巧,不仅仅是形式的问题,还有它具体的意义(锡山确实不产锡),所以我只能宣布这个问题从纯地名的角度来说无解,也就是说,这个优化问题的约束条件太多导致无解。

江苏苏州州江苏
山东东营营山东
河南南阳阳河南
广东东莞莞广东
陕西西安安陕西
青海海东东青海
青海海北北青海
青海海南南青海
青海海西西青海

天津津南南天津
保定定兴兴保定
保定定州州保定
晋城城区区晋城
临汾汾西西临汾
呼和和林林呼和
乌海海勃勃乌海
乌海海南南乌海
抚顺顺城城抚顺
本溪溪湖湖本溪
丹东东港港丹东
阜新新邱邱阜新
无锡锡山山无锡
南通通州州南通
合肥肥东东合肥
合肥肥西西合肥
三明明溪溪三明
吉安安福福吉安
淄博博山山淄博
潍坊坊子子潍坊
临沂沂南南临沂
临沂沂水水临沂
武汉汉阳阳武汉
武汉汉南南武汉
襄樊樊城城襄樊
河源源城城河源
阳江江城城阳江
北海海城城北海
贵港港北北贵港
贵港港南南贵港
成都都江江成都
自贡贡井井自贡
广元元坝坝广元
六盘盘县县六盘
临沧沧源源临沧
红河河口口红河
延安安塞塞延安
商洛洛南南商洛
固原原州州固原
昌吉吉木木昌吉

说起这种为对而对的对联,平日老奶奶过马路都不扶的我,在晚清对联中我只服张之洞的无情对:

树已半枯休纵斧
果然一点不相干

这种东西不能多看,否则容易走火入魔,从此看见任何东西只要不成对就觉得通体不舒畅。更可怕的是,本来有时候只是想写一句话,然后一言不合就开始对下联