最長降下の長さ


8

あなたの仕事は、整数の高さのグリッドとして表される「山」を下りる最長の降下の長さを決定することです。「降下」とは、開始セルから、厳密に減少する高さ(つまり、対角線ではなく、同じ高さではない)の直交する隣接セルへのパスです。たとえば、5-4-3-1からは移動できますが、5-5-4-3-3-2-1からは移動できません。このパスの長さは、開始セルから終了セルまでのセルの移動回数です。したがって、5-4-3-1は長さ3です。

入力として長方形のグリッドを受け取り、最長降下を示す整数を出力する必要があります。

1 2 3 2 2
3 4 5 5 5
3 4 6 7 4
3 3 5 6 2
1 1 2 3 1

この山を下りる最長の下りの長さは5です。最長の経路は7から始まり、左、上、左、上、そして左に移動します(7-6-5-4-2-1)。このパスには5つの動きがあるため、パスの長さは5です。

彼らはすべて同じ数かもしれません。

1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1

この高さマップはフラットなので、最長降下は0です(19ではなく、パスシーケンスは厳密に降順でなければならないため)。

高さマップは、1桁の数字よりも大きな数字で構成できます。

10 12 13 14 15 15
17 14 15 15 15 16
18 20 21 15 15 15
21 14 10 11 11 15
15 15 15 15 15 15

ここで最も長いパスは長さ6です(21、20、18、17、14、12、10)。

...さらに大きな数値でも問題ありません。

949858 789874  57848  43758 387348
  5848 454115   4548 448545 216464
188452 484126 484216 786654 145451
189465 474566 156665 132645 456651
985464  94849 151654 151648 484364

ここで最長の降下は長さ7です(786654、484216、484126、474566、156665、151654、151648、132645)

ルールとメモ

  • グリッドは、任意の便利な形式で取得できます。回答でフォーマットを指定してください。
  • 高さマップは完全に長方形で、空ではなく、符号付き32ビット整数の範囲の正の整数のみが含まれていると想定できます。
  • 最長降下経路は、グリッドのどこからでも開始および終了できます。
  • 最長降下経路を記述する必要はありません。その長さのみが必要です。
  • 最短コードの勝利

最後の例はどのように解釈すべきですか?
Peter Taylor

@PeterTaylorどういう意味かわかりません。
Beefster

最後の例は、多桁数字のマトリックスにすぎないと思います
無視の実施形態

@EmbodimentofIgnorance、ああ、そうですね。6に2桁の番号のパスではなく、4を発見するために多くの方が簡単だろう
ピーター・テイラー

1
@Οurous:長方形のみ。ギザギザではありません。
ビーフスター

回答:


8

JavaScriptの(ES7)、 106の103 102  98バイト

f=(m,n=b=-1,x,y,p)=>m.map((r,Y)=>r.map((v,X)=>(x-X)**2+(y-Y)**2-1|v/p?b=n<b?b:n:f(m,n+1,X,Y,v)))|b

オンラインでお試しください!

コメントしました

f = (                        // f = recursive function taking:
  m,                         //   m[]  = input matrix
  n = b = -1,                //   n    = length of the current path; b = best length so far
  x, y,                      //   x, y = coordinates of the previous cell
  p                          //   p    = value of the previous cell
) =>                         //
  m.map((r, Y) =>            // for each row r[] at position Y in m[]:
    r.map((v, X) =>          //   for each value v at position X in r[]:
      (x - X) ** 2 +         //     compute the squared Euclidean distance
      (y - Y) ** 2           //     between (x, y) and (X, Y)
      - 1                    //     if A) the above result is not equal to 1
      | v / p ?              //     or B) v is greater than or equal to p:
        b = n < b ? b : n    //       end of path: update b to n if n >= b
      :                      //     else:
        f(m, n + 1, X, Y, v) //       do a recursive call
    )                        //   end of inner map()
  ) | b                      // end of outer map(); return b

どうやって?

バツyp


6

ゼリー 23 21  20 バイト

-2 Erik the Outgolferに感謝

ŒỤŒPạƝ§ỊẠƲƇœị⁸QƑƇṪL’

オンラインでお試しください!(例ではあまりにも非効率的です-ここでのパスは95 94 93 83 77 40 10そうなるので6得られます)

どうやって?

ŒỤŒPạƝ§ỊẠƲƇœị⁸QƑƇṪL’ - Link: list of lists of integers, M
ŒỤ                   - multi-dimensional indices sorted by values
  ŒP                 - power-set
          Ƈ          - filter, keep those for which:
         Ʋ           -   last four links as a monad:
     Ɲ               -     for each pair of neighbours:
    ạ                -       absolute difference
      §              -     sum each
       Ị             -     insignificant?
        Ạ            -     all?
           œị        - multi-dimensional index into:
             ⁸       -   chain's left argument, M
                Ƈ    - filter, keep only those:
               Ƒ     -   unaffected by?:
              Q      -     de-duplicate
                 Ṫ   - tail
                  L  - length
                   ’ - decrement

3

パイソン2、150 147 140 136 134 132の 125 123 120バイト

l=lambda g,i,j:max(0<g.get(t)<g[i,j]and-~l(g,*t)for d in(-1,1)for t in((i+d,j),(i,j+d)))
lambda g:max(l(g,*t)for t in g)

オンラインでお試しください!

辞書の形式で入力を受け取ります(x, y): value

-7バイトwizzwizz4のおかげで、-2バイトジョナサンアレンのおかげで、-2バイトBMOのおかげで

代替、123 121バイト

l=lambda i,j:max(0<g.get(t)<g[i,j]and-~l(*t)for d in(-1,1)for t in((i+d,j),(i,j+d)))
g=input();print max(l(*t)for t in g)

オンラインでお試しください!

基本的に同じソリューションですが、最後のラムダが実際のプログラムに置き換えられています。私は最初の方が個人的に良いのですが、これgはグローバル変数として使用できるようにすることでバイト数が近くなります。


2

クリーン211 207バイト

import StdEnv,Data.List
z=zipWith
$l=maximum[length k-1\\p<-permutations[(v,[x,y])\\y<-[0..]&u<-l,x<-[0..]&v<-u],(k,[m:n])<-map unzip(subsequences p)|and[all((>)2o sum o map abs)(z(z(-))n[m:n]):z(>)k(tl k)]]

オンラインでお試しください!

list-of-lists-of-integers([[Int]])を取るブルートフォースソリューション。
TIOドライバーは、STDINを介した例と同じ形式を取ります。

TIOで任意の例を実行するには遅すぎ、おそらくローカルでも実行できますが、理論的には機能します。

これは同じことをより速く行い、TIOで3x3または2x4、ローカルで4x4および3x5を実行できます。

インデント:

$ l
    = maximum
        [ length k-1
        \\p <- permutations
            [ (v, [x, y])
            \\y <- [0..] & u <- l
            , x <- [0..] & v <- u
            ]
        , (k, [m: n]) <- map unzip
            (subsequences p)
        | and
            [ all
                ((>) 2 o sum o map abs)
                (zipWith (zipWith (-)) n [m:n])
                :
                zipWith (>) k (tl k)
            ]
        ]

2

Python 3、219バイト

e,m=len,enumerate
b=lambda g,x,y:[b(g,i,j)for o in[-1,1]for i,j in[(x+o,y),(x,y+o)]if e(g)>i>=0<=j<e(g[x])and g[x][y]<g[i][j]]
l=lambda t:e(t)and 1+max(map(l,t))
d=lambda g:max(l(b(g,x,y))for x,r in m(g)for y,_ in m(r))

オンラインでお試しください!

グリッドはリストのリストとして表されます:

[
    [1, 2, 3, 2, 2],
    [3, 4, 5, 5, 5],
    [3, 4, 6, 7, 4],
    [3, 3, 5, 6, 2],
    [1, 1, 2, 3, 1],
]

元のゴルフされていないコード:

def potential_neighbours(x, y):
    return [(x-1, y), (x+1, y), (x, y-1), (x, y+1)]

def neighbours(grid, x, y):
    result = []
    for i, j in potential_neighbours(x, y):
        if 0 <= i < len(grid) and 0 <= j < len(grid[x]) and grid[x][y] < grid[i][j]:
            result += [(i, j)]
    return result

def build_tree(grid, x, y):
    return [build_tree(grid, i, j) for i, j in neighbours(grid, x, y)]

def longest_path_in_tree(tree):
    if len(tree) == 0:
        return 0
    return 1 + max(map(longest_path_in_tree, tree))

def longest_descent(grid):
    trees = [build_tree(grid, x, y) for x, row in enumerate(grid) for y, _ in enumerate(row)]
    return max(map(longest_path_in_tree, trees))

2

Haskell188 186バイト

-XNoMonomorphismRestriction

f m|c<-[0..length(m!!0)-1],r<-[0..length m-1]=h[g[(x,y)]|x<-r,y<-c,let g((x,y):p)=h[1+g(k:p)|i<-[-1,1],k@(u,v)<-[(x+i,y),(x,y+i)],u#r,v#c,m!!u!!v<m!!x!!y,not$k#p]]
(#)=elem
h=foldl max 0

オンラインでお試しください!

notElem(not.).(#)+4

オンラインでお試しください!

説明とゴルフ

戦略:実行可能なすべてのパスを再帰的に試行し、アクセスしたエントリを追跡して、長さを最大化します。

elemnotElem(#)elemmaximize0

safeMaximum = foldl max 0

これで、再帰関数を定義する準備ができましたfun :: [[Integer]] -> Integer

fun xs
  | c <- [0..length(m!!0)-1]             -- all possible indices of xs' columns
  , r <- [0..length m-1]                 -- all possible indices of xs' rows
  = safeMaximum                          -- maximize ..
      [ g [(x,y)]                        -- .. initially we haven't visited any others
      | x <- c, y<-r                     -- .. all possible entries
-- For the purpose of golfing we define g in the list-comprehension, it takes all visited entries (p) where (x,y) is the most recent
      , let g((x,y):p) = safeMaximum     -- maximize ..
          [ 1 + g(k:p)                   -- .. recurse, adding (x,y) to the visited nodes & increment (the next path will be 1 longer)
          | i <- [-1,1]                  -- offsets [left/up,right/down]
          , k@(u,v) <-[(x+i,y),(x,y+i)]  -- next entry-candidate
          , u#c, v#r                     -- make sure indices are in bound ..
          , m!!u!!v < m!!x!!y            -- .. , the the path is decreasing
          , not$(u,v)#p                  -- .. and we haven't already visited that element
          ]
      ]

これはどのようにグリッドを取るのですか?リストのリスト?
Beefster

@Beefster:はい、[[Integer]]リストのリストです。リンクされたTIOにはラッパーがありますがparse :: String -> [[Integer]]、st。スペースと改行で分割された文字列を使用できます。
ბიმო

1

Python 3 263 227バイト

def f(m):
 p={(x,y):[c for i in[-1,1]for c in[(x,y+i),(x+i,y)]]for x,y in m};d={c:0 for c in p if not p[c]}
 while len(p)-len(d):
  for c in p:
   for b in p[c]:
    if b in d:d[c]=max(d[b]+1,d.get(c,0))
 return max(d.values())

オンラインでお試しください!

-2おかげバイトBMOを

形式でグリッドを取得します{(0, 0): 1, (1, 0): 2, ...}。このフォーマットは、次のユーティリティ関数を使用してサンプルフォーマットから生成できます。

lambda s,e=enumerate:{(x,y):int(n)for y,l in e(s.split('\n'))for x,n in e(l.split())}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.