Panjang Keturunan Terpanjang

8

Tugas Anda adalah menentukan panjang keturunan terpanjang di bawah "gunung" yang direpresentasikan sebagai kisi-kisi bilangan bulat. "Keturunan" adalah setiap jalur dari sel awal ke sel yang berdekatan secara ortogonal dengan ketinggian yang sangat menurun (yaitu tidak diagonal dan tidak dengan ketinggian yang sama). Misalnya, Anda dapat beralih dari 5-4-3-1 tetapi tidak 5-5-4-3-3-2-1. Panjang jalur ini adalah berapa banyak pergerakan sel yang ada dari sel awal ke sel akhir, sehingga 5-4-3-1 adalah panjang 3.

Anda akan menerima kotak persegi panjang sebagai input dan Anda harus menampilkan bilangan bulat yang menunjukkan penurunan terpanjang.

Contohnya

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

Panjang keturunan terpanjang di gunung ini adalah 5. Jalur terpanjang dimulai pada 7, bergerak ke kiri, ke atas, ke kiri, ke atas, lalu ke kiri (7-6-5-4-2-1). Karena ada 5 gerakan di jalur ini, panjang jalur adalah 5.

Mereka mungkin semua nomor yang sama.

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

Karena peta ketinggian ini datar, penurunan terpanjang adalah 0. (bukan 19, karena urutan jalur harus benar-benar turun)

Peta ketinggian dapat terdiri dari angka yang lebih besar dari angka satu digit.

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

Jalur terpanjang di sini adalah panjang 6. (21, 20, 18, 17, 14, 12, 10)

... Dan jumlah yang lebih besar juga baik-baik saja.

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

Keturunan terpanjang di sini adalah panjang 7. (786654, 484216, 484126, 474566, 156665, 151654, 151648, 151648, 132645)

Aturan dan Catatan

  • Kisi dapat diambil dalam format apa pun yang nyaman. Tentukan format Anda dalam jawaban Anda.
  • Anda dapat mengasumsikan bahwa peta ketinggian berbentuk persegi panjang sempurna, tidak kosong, dan hanya berisi bilangan bulat positif dalam rentang bilangan bulat 32-bit yang ditandatangani.
  • Jalur turun terpanjang dapat dimulai dan berakhir di mana saja di grid.
  • Anda tidak perlu menjelaskan jalur penurunan terpanjang dengan cara apa pun. Hanya panjangnya yang dibutuhkan.
  • Kode terpendek menang
Beefster
sumber
Bagaimana seharusnya contoh terakhir ditafsirkan?
Peter Taylor
@ PeterTaylor Saya tidak yakin apa yang Anda maksud.
Beefster
Saya pikir contoh terakhir hanyalah sebuah matriks angka multi-digit
Perwujudan Ketidaktahuan
@EmbodimentofIgnorance, ah, ya, begitu. Akan jauh lebih mudah untuk menemukan jalan dengan angka dua digit daripada 4 sampai 6.
Peter Taylor
1
@ Οurous: hanya persegi panjang. Tidak bergerigi.
Beefster

Jawaban:

8

JavaScript (ES7),  106 103 102  98 byte

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

Cobalah online!

Berkomentar

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

Bagaimana?

Selama iterasi pertama, , dan semuanya tidak terdefinisi dan kedua tes ( A dan B dalam komentar) dievaluasi ke NaN , yang memicu panggilan rekursif. Oleh karena itu, semua sel dianggap sebagai titik awal yang mungkin dari jalur.xyp

Arnauld
sumber
6

Jelly ,  23 21  20 byte

-2 Terima kasih kepada Erik the Outgolfer

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

Cobalah online! (terlalu tidak efisien untuk contoh - path di sini95 94 93 83 77 40 10begitu6dihasilkan)

Bagaimana?

ŒỤŒ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
Jonathan Allan
sumber
3

Python 2, 150 147 140 136 134 132 125 123 120 byte

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)

Cobalah online!

Mengambil input dalam bentuk kamus (x, y): value.

-7 byte terima kasih kepada wizzwizz4, -2 byte terima kasih kepada Jonathan Allen, -2 byte terima kasih kepada BMO

Alternatif, 123 121 byte

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)

Cobalah online!

Pada dasarnya solusi yang sama, hanya dengan lambda akhir digantikan oleh program yang sebenarnya. Saya pribadi lebih suka yang pertama, tetapi yang ini mendekati jumlah byte dengan memungkinkan guntuk digunakan sebagai variabel global.

ArBo
sumber
2

Bersih , 211 207 byte

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)]]

Cobalah online!

Solusi brute force mengambil daftar-daftar-bilangan bulat ( [[Int]]).
Driver TIO mengambil format yang sama dengan contoh melalui STDIN.

Terlalu lambat untuk menjalankan salah satu contoh pada TIO dan mungkin juga secara lokal, tetapi bekerja secara teori.

Yang ini melakukan hal yang sama lebih cepat, dapat melakukan 3x3 atau 2x4 pada TIO dan 4x4 dan 3x5 secara lokal.

Bertakuk:

$ 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)
            ]
        ]
Suram
sumber
2

Python 3 , 219 byte

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))

Cobalah online!

Kisi direpresentasikan sebagai daftar daftar:

[
    [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],
]

Kode ungolf asli:

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))
Nishioka
sumber
2

Haskell , 188 186 byte

-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

Cobalah online!

notElem(not.).(#)+4

Cobalah online!

Penjelasan & Tidak Disatukan

Strategi: Cobalah secara rekursif semua jalur yang layak, catat entri yang dikunjungi dan maksimalkan panjangnya.

elemnotElem(#)elemmaximize0

safeMaximum = foldl max 0

Sekarang kita siap mendefinisikan fungsi rekursif kita 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
          ]
      ]
ბიმო
sumber
Bagaimana cara ini mengambil grid? Daftar daftar?
Beefster
@Beefster: Ya, katanya [[Integer]]adalah daftar daftar. Meskipun dalam TIO tertaut Anda memiliki pembungkus parse :: String -> [[Integer]], st. Anda dapat menggunakan string yang dipisah pada spasi dan baris baru.
ბიმო
1

Python 3, 263 227 byte

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())

Cobalah online!

-2 byte terima kasih kepada BMO

Mengambil kisi-kisi dalam format {(0, 0): 1, (1, 0): 2, ...}. Format ini dapat dihasilkan dari format contoh menggunakan fungsi utilitas berikut:

lambda s,e=enumerate:{(x,y):int(n)for y,l in e(s.split('\n'))for x,n in e(l.split())}
wizzwizz4
sumber