Haskell, 1074 characters
main=interact$unlines.(\f@(l:_)->let a=(length l,length f)in head.filter(網(0,0)a).計(0,0)a$f).lines
橋=結"─═"数;結=zip;網 置@(右,下) 域@(幅,高) 地|下>=高=實|右>=幅=網(0,下+1)域 地|目 置 地`含`島
=折((&&).折((&&).not.(`含`島))實)實(潔 置 域 地)|實=網(右+1,下)域 地
導=[(種,動)|動<-[1,-1],種<-"─═│║"];潔 置 域 地=折(拡 置 域)(換 地 置 '0')導
拡 置 域(種,動)地|([地],置)<-続(行 置 種 動)域 種 動 種 地=潔 置 域 地|實=地
計 置@(右,下)域@(幅,高)地|下>=高=[地]|右>=幅=計(0,下+1)域 地|[価]<-目 置 地`価`島
=見込(価-環 置 域 地)>>=折(\種->(fst.続(行 置 種 1)域 種 1' '=<<))[地]>>=計(右+1,下)域
|實=計(右+1,下)域 地;見込 価|価<0=[]|価>4=[]|實=[[""],["─","│"],["─│","║","═"],["─║","═│"],["═║"]]!!価
続 置 域 種 動 空 地|存 置 域=建 置 域 種 動 空 地|實=([],置)
建 置 域 種 動 空 地|目 置 地`含`島=([地],置)|目 置 地==空=続(行 置 種 動)域 種 動 空(換 地 置 種)
|實=([],置);存(右,下)(幅,高)|右>=0,幅>右,0<=下=高>下|實=not 實;環 置 域 地=折(環行 置 域 地)0導
環行 置 域 地(種,動)数|置<-行 置 種 動,存 置 域,事<-目 置 地,事==種,[価]<-事`価`(橋++桥)=数+価|實=数
行(右,下)種 数|種`含`橋=(右+数,下)|實=(右,下+数);目(右,下)地=地!!下!!右;島=結"12345678"数
換 地(右,下)事|(上に,線:下に)<-捌 下 地,(左,古:右)<-捌 右 線=上に++(左++(事:右)):下に
折=foldl.flip;捌 0覧=([],覧);捌 数(物:覧)|(一覧,他)<-捌(数-1)覧=(物:一覧,他);實=1>0;数=[1..]
価 _[]=[];価 事((物,数):覧)|事==物=[数]|實=価 事 覧;含 事 覧|[_]<-価 事 覧=實|實=1<0;桥=結"│║"数
Originally, I had it even more purely Japanese by also implementing the primitive functions in terms of simple pattern matching and list combinations:
Haskell, 1192
main=interact$unlines.(\f@(l:_)->let a=(length l,length f)in head.filter(網(0,0)a).計(0,0)a$f).lines
橋=結合"─═"数;結合 []_=[];結合(事:覧)(物:一覧)=(事,物):結合 覧 一覧
網 置@(右,下) 域@(幅,高) 地|下>=高=實|右>=幅=網(0,下+1)域 地|目 置 地`含`島
=折る((&&).折る((&&).反対.(`含`島))實)實(潔 置 域 地)|實=網(右+1,下)域 地
導=[(種,動)|動<-[1,-1],種<-"─═│║"];潔 置 域 地=折る(拡 置 域)(換 地 置 '0')導
拡 置 域(種,動)地|([地],置)<-続(行 置 種 動)域 種 動 種 地=潔 置 域 地|實=地
計 置@(右,下)域@(幅,高)地|下>=高=[地]|右>=幅=計(0,下+1)域 地|[価]<-目 置 地`価`島
=見込(価-環 置 域 地)>>=折る(\種->(一.続(行 置 種 1)域 種 1' '=<<))[地]>>=計(右+1,下)域
|實=計(右+1,下)域 地;見込 価|価<0=[]|価>4=[]|實=[[""],["─","│"],["─│","║","═"],["─║","═│"],["═║"]]!!価
続 置 域 種 動 空 地|存 置 域=建 置 域 種 動 空 地|實=([],置)
建 置 域 種 動 空 地|目 置 地`含`島=([地],置)|目 置 地==空=続(行 置 種 動)域 種 動 空(換 地 置 種)
|實=([],置);存(右,下)(幅,高)|右>=0,幅>右,0<=下=高>下|實=反対 實;環 置 域 地=折る(環行 置 域 地)0導
環行 置 域 地(種,動)数|置<-行 置 種 動,存 置 域,事<-目 置 地,事==種,[価]<-事`価`結 橋 桥=数+価|實=数
行(右,下)種 数|種`含`橋=(右+数,下)|實=(右,下+数);一(第,第二)=第;目(右,下)地=地!!下!!右;島=結合"12345678"数
換 地(右,下)事|(上に,線:下に)<-捌 下 地,(左,古:右)<-捌 右 線=結 上に(結 左(事:右):下に);変 関[]=[]
変 関(物:覧)=関 物:変 関 覧;折る 関 物[]=物;折る 関 物(事:覧)=折る 関(関 事 物)覧;捌 0覧=([],覧)
捌 数(物:覧)|(一覧,他)<-捌(数-1)覧=(物:一覧,他);實=1>0;反対 真|真=1<0|實=實;数=[1..];結=(++)
価 _[]=[];価 事((物,数):覧)|事==物=[数]|實=価 事 覧;含 事 覧|[_]<-価 事 覧=實|實=1<0;桥=結合"│║"数
$ make ; def0 +RTS -M1g < test-25x25.txt
ghc -o bin/def0 golfed0.hs -rtsopts -O2
[1 of 1] Compiling Main ( golfed0.hs, golfed0.o )
Linking bin/def0 ...
2─2─2──2 1 1─2─2──2──2─2
│ │ │1─3═5══4══4─2│
2 2─4─5══5═4═2│2──1 │ │3
│ 2│ ║1│ 1─3═3─2│ │ 2║
│ ║3═4│4══4─4═5─4─3──2 │3
...
runs in ≈3 minutes on my i5.
Commented version:
type Board = [[Char]]
type Location = (Int,Int)
type BoardDimensions = (Int,Int)
main=interact$unlines.(\f@(l:_)
->let a=(length l,length f) -- dimensions of the field from the input
in head.filter(網(0,0)a) -- ↙− determine all possible ways to build bridges
{- ↑ -} .計(0,0)a $ f ).lines
-- and use the first that is simply connected.
-- islands, bridges
島=結合"12345678"数; 橋=結合"─═"数; 桥=結合"│║"数; 数=[1..]
-- each with the associated "value" from the natural numbers _↗
-- plan & commit the building of bridges
計 :: Location -> BoardDimensions -> Board -> [Board]
計 置@(右,下) 域@(幅,高) 地
|下>=高=[地] -- Walk over the board until every location was visited.
|右>=幅=計(0,下+1)域 地
|[価]<-目 置 地`価`島 -- When there is an island, read it's "value" 価
=見込(価-環 置 域 地) -- substract the value of the already-built bridges; fetch the ways to build bridges with the remaining value
>>=折る(\種->(一.続(行 置 種 1)域 種 1' '=<<))[地] -- for each of these ways, try to build a bridge.
>>=計(右+1,下)域 -- for every possibility where that was successful, go on with the resultant board.
|實=計(右+1,下)域 地
-- Ways to build bridges with value 価:
見込 :: Int -> [[Char]]
見込 価
|価<0=[] -- not possible to build bridges with negative value
|価>4=[] -- nor with value >4 (we're always building south- / eastwards)
|實=[ [""] -- value 0
,["─","│"] -- value 1
,["─│","║","═"],["─║","═│"],["═║"]]!!価 -- ... and so on
-- continue, if Location is on the board, with the building of a bridge of type 種
続 :: Location -> BoardDimensions -> Char -> Int -> Char -> Board -> ([Board],Location)
続 置 域 種 動 空 地
|存 置 域=建 置 域 種 動 空 地
|實=([],置)
-- build that bridge,
建 :: Location -> BoardDimensions -> Char -> Int -> Char -> Board -> ([Board],Location)
建 置 域 種 動 空 地
|目 置 地`含`島=([地],置) -- but if we've reached an island we're done
|目 置 地==空 -- if we're in water or what else (空, can also take on the value of 種 if we only want to check if the bridge is already there)
=続(行 置 種 動)域 種 動 空(換 地 置 種) -- place (換) the bridge and go (行く) to the next location
|實=([],置) -- if we've reached something else (i.e. crossing bridges), return no result.
-- number of connections present at location 置
環 :: Location -> BoardDimensions -> Board -> Int
環 置 域 地=折る(環行 置 域 地)0導 -- for all neighbouring positions
環行 置 域 地(種,動)数
|置<-行 置 種 動,存 置 域 -- if they're on the board
,事<-目 置 地,事==種 -- and there's a bridge in the correct direction
,[価]<-事`価`結 橋 桥=数+価 -- check its value and sum it to the previous ones
|實=数 -- if there's no bridge there, don't sum anything
導=[(種,動)|動<-[1,-1],種<-"─═│║"] -- directions to go
-- -- -- -- -- -- -- -- -- -- -- --
-- test for connectedness:
網 :: Location -> BoardDimensions -> Board -> Bool
網 置@(右,下) 域@(幅,高) 地 -- Walk over the board until an island is
|下>=高=實 -- found. 潔 marks all islands connected to
|右>=幅=網(0,下+1)域 地 -- that island; then check if any unmarked
|目 置 地`含`島=折る((&&).折る((&&).反対.(`含`島))實)實(潔 置 域 地) -- islands are left in the
|實=網(右+1,下)域 地 -- result.
-- mark islands connected to the one at 置:
潔 :: Location -> BoardDimensions -> Board -> Board
潔 置 域 地 =折る(拡 置 域)(換 地 置 '0')[(種,動)|動<-[1,-1],種<-"─═│║"]
-- mark the island at 置 with '0', then, for all the possible ways to go...
-- Proceed with the marking in some direction
拡 :: Location -> BoardDimensions -> (Char,Int) -> Board -> [[Char]]
拡 置 域(種,動)地 -- if an island is found in the given direction, give control to 潔 there
|([地],置)<-続(行 置 種 動)域 種 動 種 地=潔 置 域 地
|實=地 -- if none is found (i.e. there was no bridge), just return the board without further marking
-- -- -- -- -- -- -- -- -- -- -- --
-- Primitives:
存 :: Location -> BoardDimensions -> Bool
存(右,下)(幅,高)|右>=0,幅>右,0<=下=高>下|實=反対 實 -- check if (右,下) is on the board
行 :: Location -> Char->Int -> Location
行(右,下)種 数|種`含`橋=(右+数,下)|實=(右,下+数) -- go in some direction (determined by where 種 leads to)
目 :: Location -> Board -> Char
目(右,下)地=地!!下!!右 -- lookup what's at location (右,下)
-- replace what's at (右,下) with 事
換 :: Board -> Location -> Char -> Board
換 地(右,下)事|(上に,線:下に)<-捌 下 地,(左,古:右)<-捌 右 線=結 上に(結 左(事:右):下に)
変 :: (a -> b) -> [a] -> [b]
変 関[]=[] -- Standard Haskell map function (just noticed I didn't actually use it at all)
変 関(物:覧)=関 物:変 関 覧
折る :: (b -> a -> a) -> a -> [b] -> a
折る 関 物[]=物 -- equivalent 折る=foldl.flip
折る 関 物(事:覧)=折る 関(関 事 物)覧
捌 0覧=([],覧)
捌 数(物:覧)|(一覧,他)<-捌(数-1)覧=(物:一覧,他) -- splitAt
實=1>0 --true
反対 真|真=1<0|實=實 -- not
結=(++) -- list linking
一(第,第二)=第 -- fst
価 :: Eq a => a -> [(a,b)] -> [b]
価 _[]=[] -- lookup function
価 事((物,数):覧)|事==物=[数]|實=価 事 覧
含 :: Eq a => a -> [(a,b)] -> Bool
含 事 覧|[_]<-価 事 覧=實|實=1<0 -- equivalent 含 x = elem x . map fst
結合 []_=[] -- zip
結合(事:覧)(物:一覧)=(事,物):結合 覧 一覧
1 1
being input? \$\endgroup\$1 1
, which is a valid puzzle and it should be handled correctly. \$\endgroup\$