Мы вышли из-под контроля, Доктор!


11

Доктор, пытаясь убежать от сил Далеков, решил отправить их по кругу, путешествуя по разным карманам пространства по спирали.

В зависимости от характера доступного пространства-времени, Доктор должен ввести в ТАРДИС управление высотой и шириной раздела пространства и своей точкой входа, с которой начинается спираль.

Раздел пространства может быть представлен как сетка h x w, заполненная последовательными целыми числами слева направо, сверху вниз, начиная с 1.

Начальная позиция указывается как rc для строки и столбца ... Исходя из этого, программное обеспечение ТАРДИС должно выпустить упорядоченный список целых чисел, полученный путем спирали наружу в направлении против часовой стрелки из строки r столбца c , начиная вверх ...

Ваша задача как компаньона Доктора состоит в том, чтобы запрограммировать ТАРДИС на получение четырех чисел в формате height width row columnи определить, в каком секторе пространства ТАРДИС должен пройти, чтобы соответствовать спиральному движению, описанному ниже ...

Вход 1

5 5 3 3

(Сетка 5 х 5, начиная с позиции 3,3)

Выход 1

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

Объясняя вывод

Оригинальная сетка введите описание изображения здесь

Генерируемая спираль введите описание изображения здесь

Вход 2

2 4 1 2

(2 х 4 сетки, начиная с позиции 1,2)

Выход 2

2 1 5 6 7 3 8 4

Объясняя вывод

Немного отличается, поскольку спираль теперь должна вращаться вокруг сетки, чтобы генерировать соответствующий результат ...

Оригинальная сетка введите описание изображения здесь

Генерируемая спираль введите описание изображения здесь

Правила:

  1. Это код-гольф, поэтому самая короткая длина кода получает одобрение.

  2. Приведенные выше примеры должны быть использованы для проверки вашего кода. Если это не обеспечивает соответствующий вывод, что-то не так ...

  3. В вашем ответе должны быть указаны варианты кода для игры в гольф и в гольф ...

Удачи!


Могу ли я указать вам на draw.io, где можно быстро сделать довольно разумные рисунки (у вас отличная разборчивость в вашей рисованной версии ... просто я не вижу красных кружков). Рассмотрим i.stack.imgur.com/xbLSA.png как пример того, что можно сделать. Обратите внимание, что в него встроен xml, поэтому, если вы идете в draw.io, вы можете импортировать из URL.

Я учту это для моей следующей потребности в рисовании, @MichaelT, спасибо ...
WallyWest

1
Я публикую ответ с функцией, возвращающей массив в качестве вывода. Это приемлемо?
edc65

@ edc65 Mate, мы с тобой вернемся назад на CG, я позволю для этого функцию S (h, w, r, c) или тому подобное ... :)
WallyWest

Ответы:


3

JavaScript (ES6) 124 163 177

Редактировать совершенно по- другому, не нужно массив для хранения посещенных ячеек. Используя тот факт, что сторона спирали увеличивается на 1 после каждых 2 витков.

// New way
f=(h,w,y,x)=>
  (e=>{
    for(o=[],d=i=t=l=0;l<w*h;i<t?i+=2:[i,d,e]=[1,-e,d,++t])
      o[l]=y*w-w+x,l+=x>0&x<=w&y>0&y<=h,x+=d,y-=e
  })(1)||o


// Golfed
g=(h,w,y,x)=>
  (g=>{
    for(e=n=0;n<h*w;)g[[n%w+1,-~(n/w)]]=++n;
    for(o=[g[[x,y]]],l=d=1;l<n;l+=!!(o[l]=g[[x+=d,y+=e]]))
      g[[x,y]]=0,
      g[[x+e,y-d]]!=0&&([d,e]=[e,-d])
  })([])||o



// Not golfed
u=(h,w,y,x)=>{
  var i,j,dx,dy,kx,ky,o,n,
    g={} // simulate a 2dimensional array using a hashtable with keys in the form 'x,y'

  for(n=i=0; i++<h;) // fill grid (probably better done in a single loop)
    for(j=0; j++<w;)
      g[[j,i]] = ++n;
  o=[g[[x,y]]] // starting point in output
  dx=1, dy=0 // start headed right
  
  for(; !o[w*h-1]; ) // loop until all w*h position are put in output
  {
    g[[x, y]] = 0 // mark current position to avoid reusing
    kx=dy, ky=-dx // try turning left
    if(g[[x+kx, y+ky]] != 0) // check if position marked
    { // found a valid position
      dx=kx, dy=ky // change direction
    }
    x+=dx, y+=dy // move
    k=g[[x, y]] // get current value
    if (k) o.push(k) // put in output list if not 'undefined' (outside grid)
  }
  return o
}

// TEST - In FireFox

out=x=>O.innerHTML+=x+'\n';
[
 [[5,5,3,3],'13 8 7 12 17 18 19 14 9 4 3 2 1 6 11 16 21 22 23 24 25 20 15 10 5'],
 [[2,4,1,2],'2 1 5 6 7 3 8 4']
].forEach(t=>out(t[0] + '\n Result: ' + f(...t[0])+'\n Check:  ' + t[1]))

test=()=>
{
  var r, i=I.value.match(/\d+/g), h=i[0]|0, w=i[1]|0, y=i[2]|0, x=i[3]|0
  if (y>h||x>w) r = 'Invalid input'
  else r = f(h,w,y,x)
  out(i+'\n Reault: ' +r)
}
<pre id=O></pre>
Your test:<input id=I><button onclick="test()">-></button>


Удивительный гольф! С 300 до 163 ... Я
снимаю

1
@WallWest с этим комментарием вы подталкиваете меня, чтобы сделать лучше. Thnx
edc65

Ницца! Мое решение на Python было намного длиннее, но я подумал, что все в порядке, вы используете лучший метод. Теперь вы используете то же самое, и это еще короче ... У меня есть работа. :)
randomra

@randomra Я все еще хотел бы видеть это ...
WallyWest

2

Питон 3, 191

Вероятно, не очень хороший результат, но здесь все сказано:

def f(b,a,d,c):
 p,r,l,s,h=c+1j*d,-1j,1,0,0
 for _ in [0]*((a+b)**2):x,y=p.real,p.imag;0<x<a+1and 0<y<b+1and print(int((y-1)*a+x),end=' ');p+=r;s=(s+1)%l;t=s==0;h=(h+t)%2;l+=h<t;r*=(-1j)**t 

Мы движемся по спирали, увеличивая длину стороны после каждой секунды поворота. Если наша позиция находится внутри данной сетки, мы печатаем ее соответствующий номер.

Переменные:

  • сложная позиция
  • х и у координаты положения
  • это направление
  • s - позиция на текущей стороне
  • l - длина текущей стороны
  • h - четность порядкового номера текущей стороны
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.