एक सर्पिल में एक रानी की सैर


13

एक दूर के राज्य में, एक शतरंज की रानी एक सर्पिल पथ पर एक दैनिक पैदल यात्रा करती है, 1 से लेकर तक की संख्या, सर्पिल nका पालन करने के लिए परवाह नहीं है, लेकिन बस रानी की चाल बना रही है क्योंकि वह शतरंज की बिसात पर होती है। रानी अपनी प्रजा से प्यारी होती है, और वे उसके रास्ते पर आने वाले हर वर्ग पर ध्यान देती हैं। यह देखते हुए कि रानी किसी भी वर्ग पर अपना चलना शुरू कर सकती है और इसे किसी भी वर्ग पर समाप्त कर सकती है, रानी की सबसे छोटी पैदल यात्रा क्या है जो वह ले सकती है?

चुनौती

एक आयताकार ग्रिड पर पूर्णांक के एक सर्पिल को देखते हुए, एक फ़ंक्शन लिखिए जो एक शतरंज रानी की चाल का उपयोग करके इस सर्पिल ग्रिड पर दो नंबरों के बीच कम से कम संभव पथ (गिने गए कोशिकाओं की संख्या की गणना की गई) में से एक को लौटाता है।

उदाहरण के लिए, से 16करने के लिए 25:

25 10 11 12 13
24  9  2  3 14
23  8  1  4 15
22  7  6  5 16
21 20 19 18 17

कुछ संभावित रास्तों में शामिल हैं 16, 4, 2, 10, 25और 16, 5, 1, 9, 25

नियम

  • इनपुट कोई भी दो धनात्मक पूर्णांक होगा।
  • आउटपुट केवल ओर्थोगोनल और विकर्ण चालों का उपयोग करके सर्पिल में पूर्णांक (दोनों समापन बिंदुओं सहित) का एक मार्ग होगा।
  • एक पथ की लंबाई यात्रा की गई कोशिकाओं की संख्या से गिना जाता है।
  • आपका जवाब एक कार्यक्रम या एक समारोह हो सकता है।
  • यह कोड गोल्फ है, इसलिए सबसे छोटी संख्या बाइट्स जीतती है।

हमेशा की तरह, अगर समस्या स्पष्ट नहीं है, तो कृपया मुझे बताएं। गुड लक और गुड गोल्फिंग!

परीक्षण के मामलों

>>> queen_spiral(4, 5)
4, 5
>>> queen_spiral(13, 20)
13, 3, 1, 7, 20
>>> queen_spiral(14, 14)
14
>>> queen_spiral(10, 3)
10, 11, 3
>>> queen_spiral(16, 25)
16, 4, 2, 10, 25
>>> queen_spiral(80, 1)
80, 48, 24, 8, 1


5
आप यह उल्लेख करना चाहते हैं कि आप यात्रा की गई कोशिकाओं की संख्या के हिसाब से सबसे छोटे रास्ते की तलाश कर रहे हैं (यूक्लिडियन दूरी के विपरीत, कहते हैं)।
मार्टिन एंडर

1
क्या यह "राजा के चलने" के रूप में अधिक समझ में नहीं आएगा?
जो राजा

1
@ जोकिंग आह, अब जब आप इसका उल्लेख करते हैं, तो यह एक राजा का चलना चाहिए। हालाँकि, शीर्षक बदलने में थोड़ी देर हो सकती है।
शर्लक

जवाबों:


5

एपीएल (डायलॉग यूनिकोड) , 59 57 बाइट्स एसबीसीएस

{v⍳+\v[⍺],↓⍉↑(|⍴¨×)⊃⍵⍺-.⊃⊂v9 11∘○¨+\0,0j1*{⍵/⍨⌈⍵÷2}⍳⍺⌈⍵}

इसे ऑनलाइन आज़माएं!

-2 बाइट्स @ngn की बदौलत।

बेनामी फ़ंक्शन जो बाएं और दाएं तर्कों के रूप में दो समापन बिंदुओं को स्वीकार करता है।

Ungolfed और यह कैसे काम करता है

रानी पहले तिरछी चलती है, इसलिए यह प्रत्येक संख्या के निर्देशांक को पूर्व-गणना करने के लिए पर्याप्त है max(start,end)

समन्वय-उत्पन्न एल्गोरिथ्म संबंधित चुनौती पर कई उत्तरों से प्रेरित है , लेकिन मौजूदा उत्तरों में से कुछ से थोड़ा अलग है:

  • 10 की आवश्यक बाध्यता को देखते हुए
  • 1-आधारित श्रेणी उत्पन्न करें r=1 2 3 4 5 6 7 8 9 10
  • प्रत्येक संख्या के आधे हिस्से की छत लें n=1 1 2 2 3 3 4 4 5 5
  • के प्रत्येक आइटम को दोहराने rसे n1 2 3 3 4 4 5 5 5 6 6 6 7 7 7 7 8 8 8 8 9 9 9 9 9 10 10 10 10 10
  • 0. की प्रारंभिक बिंदु के साथ, काल्पनिक इकाई की शक्ति का संचयी योग लें (यह हिस्सा जुड़े हुए विभिन्न पायथन समाधानों के लिए सामान्य है)

फिर, एक बार निर्देशांक के वेक्टर vके लिए तैयार है, हम आसानी से सर्पिल सूचकांक और निर्देशांकों का उपयोग कर के बीच में बदल सकते हैं v[i]और v⍳coord(के पहले सूचकांक खोजने coordमें v)।

 Define a function; ⍺=start, ⍵=end
f←{
   Construct a vector of spiral coordinates v
  v9 11∘○¨+\0,0j1*{⍵/⍨⌈⍵÷2}⍳⍺⌈⍵
                             ⍺⌈⍵   max of start, end
                                  range of 1 to that number
                   {⍵/⍨⌈⍵÷2}   for each number n of above, copy itself ceil(n/2) times
               0j1*   raise imaginary unit to the power of above
           +\0,       prepend 0 and cumulative sum
                      (gives vector of coordinates as complex numbers)
    9 11∘○¨   convert each complex number into (real, imag) pair
  v          assign it to v

   Extract start and end coordinates
  a w←(⍺⊃v)(⍵⊃v)

   Compute the path the Queen will take
  v⍳+\(a),↓⍉↑(|⍴¨×)w-a
                    w-a   coordinate difference (end-start)
              (|⍴¨×)      generate abs(x) copies of signum(x) for both x- and y-coords
                          e.g. 4 -> (1 1 1 1), ¯3 -> 1 ¯1 ¯1)
           ↓⍉↑   promote to matrix (with 0 padding), transpose and split again
                 (gives list of steps the Queen will take)
    +\(a),      prepend the starting point and cumulative sum
                 (gives the path as coordinates)
  v   index into the spiral vector (gives the spiral numbers at those coordinates)
}

(⍵⊃v)-⍺⊃v->⊃⍵⍺-.⊃⊂
ngn

(⍺⌷v)->v[⍺]
ngn

3

गणितज्ञ 615 530 बाइट्स

यह एक संख्या ग्रिड का निर्माण करता है, इसे एक ग्राफ में परिवर्तित करता है, और फिर दो संख्याओं के बीच सबसे छोटा रास्ता खोजता है जो इनपुट थे।


UnGolfed

numberSpiralमैथवर्ल्ड प्राइम स्पाइरल से है । यह एन उलम स्पिरल ( प्रिम्स को उजागर किए बिना) द्वारा एक एन बनाता है ।

findPathसंख्या ग्रिड को एक ग्राफ में परिवर्तित करता है। संख्या ग्रिड पर मान्य रानी चालें हैं।


numberSpiral[n_Integer?OddQ]:= 
  Module[{a,i=(n+1)/2,j=(n+1)/2,cnt=1,dir=0,len,parity,vec={{1,0},{0,-1},{-1,0},{0,1}}},a=Table[j+n(i-1),{i,n},{j,n}];Do[Do[Do[a[[j,i]]=cnt++;{i,j}+=vec[[dir+1]],{k,len}];dir=Mod[dir+1,4],{parity,0,1}],{len,n-1}];a];  

findPath[v1_, v2_] := 
  Module[{f, z, k},
    (*f  creates edges between each number and its neighboring squares *)
    f[sp_,n_]:=n<->#&/@(sp[[Sequence@@#]]&/@(Position[sp,n][[1]]/.{r_,c_}:>Cases[{{r-1,c},{r+1,c},{r,c-1},{r,c+1},{r-1,c-1},{r-1,c+1},{r+1,c+1}, {r+1,c-1}},{x_,y_}/; 0<x<k&&0<y<k]));k=If[EvenQ[
     z=\[LeftCeiling]Sqrt[Sort[{v1, v2}][[-1]]]\[RightCeiling]],z+1,z];
    FindShortestPath[Graph[Sort/@Flatten[f[ns=numberSpiral[k],#]&/@Range[k^2]] //Union],v1,v2]]

उदाहरण

findPath[4,5]
findPath[13,22]
findPath[16,25]
numberSpiral[5]//Grid

{4,5}

{} 13,3,1,7,22

{} 16,4,1,9,25

ग्रिड


80 से 1 तक के सबसे छोटे रास्ते में 5, 6 नहीं, कोने हैं।

findPath[80,1]
numberSpiral[9]//Grid

{80, 48, 24, 8, 1}

अस्सी एक ग्रिड


golfed

u=Module;
w@n_:=u[{a,i=(n+1)/2,j=(n+1)/2,c=1,d=0,l,p,v={{1,0},{0,-1},{-1,0},{0,1}}},
a=Table[j+n(i-1),{i,n},{j,n}];
Do[Do[Do[a[[j,i]]=c++;{i,j}+=v[[d+1]],{k,l}];d=Mod[d+1,4],{p,0,1}],{l,n-1}];a];
h[v1_,v2_]:=u[{f,z},
s_~f~n_:=n<->#&/@(s[[Sequence@@#]]&/@(Position[s,n][[1]]/.{r_,c_}:> 
Cases[{{r-1,c},{r+1,c},{r,c-1},{r,c+1},{r-1,c-1},{r-1,c+1},{r+1,c+1},{r+1,c-1}},{x_,y_}/;0<x<k&&0<y<k]));
k=If[EvenQ[z=\[LeftCeiling]Sqrt[Sort[{v1,v2}][[-1]]]\[RightCeiling]],z+1,z];
FindShortestPath[g=Graph[Sort/@Flatten[f[ns=w@k,#]&/@Union@Range[k^2]]],v1,v2]]

2

स्काला (830 बाइट्स)

चार परस्पर पुनरावर्ती कार्यों का उपयोग करके एक वर्ग 2 डी सरणी में सर्पिल बनाता है। पथ सूची बनाने के लिए एक और पुनरावर्ती खोज।

def P(s:Int,e:Int):List[Int]={
import scala.math._
type G=Array[Array[Int]]
type I=Int
type T=(I,I)
def S(z:I)={def U(g:G,x:I,y:I,c:I,r:I):Unit={for(i<-0 to r.min(y)){g(y-i)(x)=c+i}
if(r<=y)R(g,x,y-r,c+r,r)}
def R(g:G,x:I,y:I,c:I,r:I)={for(i<-0 to r){g(y)(x+i)=c+i}
D(g,x+r,y,c+r,r+1)}
def D(g:G,x:I,y:I,c:I,r:I)={for(i<-0 to r){g(y+i)(x)=c+i}
L(g,x,y+r,c+r,r)}
def L(g:G,x:I,y:I,c:I,r:I)={for(i<-0 to r){g(y)(x-i)=c+i}
U(g,x-r,y,c+r,r+1)}
val g=Array.ofDim[I](z,z)
U(g,z/2,z/2,1,1)
g}
def C(n:I,g:G):T={var(x,y)=(0,0)
for(i<-g.indices){val j=g(i).indexOf(n)
if(j>=0){x=j
y=i}}
(x,y)}
def N(n:Int)=if(n==0)0 else if(n<0)-1 else 1
def Q(a:T,b:T):List[T]={val u=N(b._1-a._1)
val v=N(b._2-a._2)
if(u==0&&v==0)b::Nil else a::Q((a._1+u,a._2+v),b)}
val z=ceil(sqrt(max(s,e))).toInt|1
val p=S(z)
Q(C(s,p),C(e,p)).map{case(x,y)=>p(y)(x)}}

Ungolfed

  import scala.math._
  type Grid=Array[Array[Int]]
  def spiral(size: Int) = {
    def up(grid:Grid, x: Int, y: Int, c: Int, r: Int): Unit = {
      for (i <- 0 to r.min(y)) {
        grid(y-i)(x) = c + i
      }
      if (r <= y)
        right(grid,x,y-r,c+r,r)
    }
    def right(grid:Grid, x: Int, y: Int, c: Int, r: Int) = {
      for (i <- 0 to r) {
        grid(y)(x+i) = c + i
      }
      down(grid,x+r,y,c+r,r+1)
    }
    def down(grid:Grid, x: Int, y: Int, c: Int, r: Int) = {
      for (i <- 0 to r) {
        grid(y+i)(x) = c + i
      }
      left(grid,x,y+r,c+r,r)
    }
    def left(grid:Grid, x: Int, y: Int, c: Int, r: Int) = {
      for (i <- 0 to r) {
        grid(y)(x-i) = c + i
      }
      up(grid,x-r,y,c+r,r+1)
    }
    val grid = Array.ofDim[Int](size,size)
    up(grid,size/2,size/2,1,1)
    grid
  }
  def findPath(start: Int, end: Int): List[Int] = {
    def findCoords(n: Int, grid: Grid): (Int, Int) = {
      var (x,y)=(0,0)
      for (i <- grid.indices) {
        val j = grid(i).indexOf(n)
        if (j >= 0) {
          x = j
          y = i
        }
      }
      (x,y)
    }
    def sign(n: Int) = if (n == 0) 0 else if (n < 0) -1 else 1
    def path(stc: (Int, Int), enc: (Int, Int)) : List[(Int, Int)] = {
      val dx = sign(enc._1 - stc._1)
      val dy = sign(enc._2 - stc._2)
      if (dx == 0 && dy == 0) {
        enc :: Nil
      } else {
        stc :: path((stc._1 + dx, stc._2 + dy), enc)
      }
    }
    val size = ceil(sqrt(max(start, end))).toInt | 1
    val spir = spiral(size)
    path(findCoords(start, spir),findCoords(end, spir)).
      map { case (x, y) => spir(y)(x) }
  }

2

रूबी, 262 218 216 बाइट्स

यह मेरे पायथन उत्तर का एक बंदरगाह है । गोल्फ सुझाव का स्वागत करते हैं।

संपादित करें: जॉर्डन और उनके सुझावों , और d=[0]*n=m*m;*e=c=0;*t=a, के लिए 45 बाइट्स धन्यवाद । से एक और बाइट के लिए ।.rect0<=>xx,y=(e[a]-g=e[b]).rect; t<<d[(g.real+x)*m+g.imag+y](x+y*1i)(x+y.i)

->a,b{m=([a,b].max**0.5).to_i+1;d=[0]*n=m*m;*e=c=0;*t=a
n.times{|k|d[c.real*m+c.imag]=k+1;e<<c;c+=1i**((4*k+1)**0.5-1).to_i}
x,y=(e[a]-g=e[b]).rect
(x+=0<=>x;y+=0<=>y;t<<d[(g.real+x)*m+g.imag+y])while(x+y.i).abs>0
t}

Ungolfed:

def q(a,b)
  m = ([a,b].max**0.5).to_i+1
  n = m*m
  d = [0]*n
  c = 0
  *e = c   # same as e=[0]
  *t = a   # same as t=[a]

  (1..n).each do |k|
    d[c.real * m + c.imag] = k+1
    e << c
    c += 1i**((4*k+1)**0.5-1).to_i
  end

  x, y = (e[a] - g=e[b]).rect

  while (x+y.i).abs > 0 do
    if x<0
      x += 1
    elsif x>0
      x += -1
    end

    if y<0
      y += 1
    elsif y>0
      y -= 1
    end

    t << d[(g.real+x)*m+g.imag+y]
  end

  return t
end

आपको q=अपने उत्तर से हटा देना चाहिए क्योंकि आप इसकी बाइट्स नहीं गिन रहे हैं। c=0;e=[c];t=[a]को छोटा किया जा सकता है *e=c=0;*t=a। आप (के लिए ) के z=e[a]-e[b];x,y=z.real,z.imagसाथ x,y=(e[a]-e[b]).rectऔर x+=x<0?1:x>0?-1:0साथ बदल सकते हैं । मुझे लगता है कि यह 229 बाइट्स हो जाता है। x+=0<=>xy
जॉर्डन

यदि आप 1-आयामी सरणी पर स्विच करते हैं तो आप 6 और बाइट्स बचा सकते हैं। के dसाथ आरंभ की d=[0]*m*mजगह, फिर के d[c.real][c.imag]साथ d[c.real*m+c.imag]और d[e[b].real+x][e[b].imag+y]साथ बदलें d[(e[b].real+x)*m+e[b].imag+y]
जॉर्डन

मेरी पिछली टिप्पणी पर 2-बाइट सुधार: t<<d[(e[b].real+x)*m+e[b].imag+y]को छोटा किया जा सकता है u,v=e[b].rect;t<<d[(u+x)*m+v+y]
जॉर्डन

d=[0]*m*mकरने के लिए d=[0]*n=m*mऔर (m*m).timesकरने के लिए बदलकर दो और बाइट्स n.times। वह 219 है।
जॉर्डन

आप को बदलने के द्वारा दो अतिरिक्त बाइट्स बचा सकता है x,y=(e[a]-e[b]).rectके लिए x,y=(e[a]-g=e[b]).rect, हटाने u,v=e[b].rectऔर बदलते t<<d[(u+x)*m+v+y]करने के लिए t<<d[(g.real+x)*g.imag+v+y](मूल रूप से मेरी दूसरी करने वाली अंतिम टिप्पणी को वापस लाने में)।
जॉर्डन

1

पायथन 3, 316 बाइट्स

यह उत्तर सर्पिल (जटिल संख्याओं का उपयोग करके) के निर्देशांक को देखता है aऔर bविकर्ण चाल को पहले जोड़ता है, फिर ऑर्थोगोनल चाल चलता है।

def q(a,b):
 m=int(max(a,b)**.5)+1;d=[];c=0;e=[c];t=[a]
 for i in range(m):d+=[[0]*m]
 for k in range(m*m):d[int(c.real)][int(c.imag)]=k+1;e+=[c];c+=1j**int((4*k+1)**.5-1)
 z=e[a]-e[b];x,y=int(z.real),int(z.imag)
 while abs(x+y*1j):x+=(x<0)^-(x>0);y+=(y<0)^-(y>0);t+=[d[int(e[b].real)+x][int(e[b].imag)+y]]
 return t

Ungolfed:

def queen_spiral(a,b):
    square_size = int(max(a,b)**.5)+1
    complex_to_spiral = []
    complex = 0
    spiral_to_complex = [c] # add 0 first, so that it's 1-indexed later
    result = [a]

    for i in range(square_size):
        complex_to_spiral.append([0]*square_size) # the rows of the spiral

    for k in range(square_size**2):
        row = int(complex.real)
        column = int(complex.imag)
        complex_to_spiral[row][column] = k+1 # 1-indexing

        spiral_to_complex.append(complex)

        quarter_turns = int((4*k+1)**.5-1)
        complex += 1j**quarter_turns

    z = spiral_to_complex[a] - spiral_to_complex[b]
    v = spiral_to_complex[b]
    x, y = int(z.real), int(z.imag)
    r, s = int(v.real), int(v.imag)

    while abs(x+y*1j):
        if x < 0:
            x += 1
        elif x > 0:
            x += -1
        # else x == 0, do nothing
        if y < 0:
            y += 1
        elif y > 0:
            y += -1

        vertex = complex_to_spiral[r+x][s+y]
        result.append(vertex)
    return result
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.