Алгоритмическое плетение - на день матери

11

Задача:

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

  • Количество нитей всегда будет нечетным и составляет от 3 до 6000 (включительно).
  • Когда вы начнете, пряди будут разделены на 2 (почти) равные группы, leftи right. leftБудет иметь еще одну прядь при запуске.

Для ввода 7:

/ / / / \ \ \
1 2 3 4 5 6 7
  • На каждой итерации самая внешняя нить стороны с большим количеством прядей будет помещена в центр в противоположном направлении. Центр определяются как между противоположными стоящими нитями: ////middle\\\.

1 итерация ввода 7 (нить 1 была перемещена в центр):

/ / / \ \ \ \
2 3 4 1 5 6 7

Пример:

Входные данные:

3 4

Расчеты:

1 2 3
 \
2 1 3
   /
2 3 1
 \
3 2 1
   /
3 1 2

Выход:

3 1 2

Правила:

  • Вам не нужно отображать косые черты для направления нитей, только цифры.
  • Вам нужно только отобразить числа после последней итерации.
  • Ваш вывод будет идентификатором нитей, разделенных пробелами
  • Вход будет в виде: strands [space] iterations
  • Количество нитей всегда будет нечетным, а 3 <= x <= 6000
  • Это , поэтому выигрывает самый короткий код!
Доктор
источник
3
Разве это не будет от 3 до 5999, так как 6000 не является странным, поэтому у вас не будет «до 6000»?
kitcar2000
так что выход 11 2будет 2345611178910?
Мартин Эндер
1
@Howard Ваше представление нарушило мои изменения
TheDoctor
1
@TheDoctor Мой ответ был там до вашего изменения.
Говард
1
Я думаю, что ваш пример должен прочитать 123 -> 213 -> 231 -> 321 -> 312.
Говард

Ответы:

6

GolfScript, 33 символа

~\),(@{:^1$[=]:y-.,2//y*^~}*;' '*

Ввод должен быть предоставлен на stdin.

Примеры (вы можете проверить онлайн ):

> 7 1
2 3 4 1 5 6 7

> 3 4
3 1 2

> 11 2
2 3 4 5 6 11 1 7 8 9 10
Говард
источник
6

Python: 179 240 , 152 символа

Во-первых, 179

Для Nцепей и iитераций этот ответ использует O(1)пространство и O(N)время. Я просто вычисляю конечную позицию каждой цепи, никогда не перебирая промежуточные позиции!

большое редактирование: обдумайте этот ответ, поменяв условные выражения на булеву алгебру. Я также написал длинное объяснение того, как это работает. TL; DR: формульные шаблоны, деление по модулю.

from sys import *
N,i=map(int,stdin.readline().split())
h,t=N/2,3*N
f=lambda p:(p>N)*(t/2-(p&-2))+p/2+1
for s in xrange(N):print f((2*s+1+(s>h)*(t-4*s-2)+i*(N+1-N*(s!=h)))%(2*N)),

Сейчас 152

Это более разумный питон для гольфа. (редактировать: спасибо Алексу Торнтону за редактирование со 165 по 152)

from sys import*;l=map;r=range;n,m=l(int,stdin.readline().split());b=r(1,n+1)
for k in r(m):v=b.pop((0,n-1)[k%2]);b.insert(n/2,v)
print' '.join(l(str,b)
wrongu
источник
Играйте в гольф еще дальше до 151, если вам интересно: pastebin.com/1pbwax6s
Алекс Торнтон
простые изменения, но очень эффективные. благодаря!
Мину
Я думаю , вы могли бы сократить его еще дальше, удаляя lи vпеременные и изменяя insertк уступке среза.
user2357112 поддерживает Monica
Я уверен, что гольф может быть короче. Честно говоря, я просто ожидал комментариев к первому, если что-нибудь!
Миссу
Я все равно написал объяснение и обновил пост :)
Мину
2

Питон 2 (109) / Питон 3 (121)

Python 2

s,n=map(int,raw_input().split())
b=range(s)
for i in range(n):b[s/2:s/2]=[b.pop(0-i%2)]
for x in b:print x+1,

Python 3

s,n=map(int,input().split())
b=list(range(s))
for i in range(n):b[s//2:s//2]=[b.pop(0-i%2)]
for x in b:print(x+1,end=' ')

Код, должно быть, был подкуплен Python 2, чтобы продемонстрировать его преимущества в игре в гольф по сравнению с Python 3: диапазоны - это списки, округление до целого числа, печать не начинается с новой строки. Странно 0-i%2, потому что -i%2оценивает как (-i)%2.

Вероятно, существует более эффективный подход, чем итерация, а именно вычисление каждого конечного результата напрямую. Операция плетения имеет период 2 * с, поэтому она не может быть такой сложной.

XNOR
источник
2

Руби, 105

Просто много манипуляций с сетами. Нажмите, поп, назад и сдвиг! Я пытался не преобразовывать входные данные в целые числа, но он добавил около 20 символов.

n,i=$*.map(&:to_i)
f=l=(1..n).to_a
t=r=l.pop(n/2).reverse
i.times{f,t=t<<f.shift,f}
$><<(l+r.reverse)*' '

lи r( leftи right) являются очередями «потока». rightперевернут, поэтому мы начинаем тянуть снаружи.

tи f( toи from) начинаются как rightи left, соответственно, но по мере продолжения мы меняем их местами, так что мы всегда можем сместить последний «поток» с fromи выдвинуть его в to( f,t=t<<f.shift,f). Это экономит много места.

Тогда мы просто перевернем rightв конце.

Changelog:

2.2 105 о да, карта может взять проц

2.1 108 И на самом деле, просто перевернуть вещи как часть манипуляции.

2.0 116 не используйте этот временный массив. Вместо этого используйте две переменные-указатели, которыми мы можем манипулировать и продолжаем перенаправлять. Тогда только отображать конец

1.0 123 начальная идея

Не тот Чарльз
источник
0

Java, 270 символов

golfed:

import java.util.*;class B{public static void main(String[] a){int n=Integer.valueOf(a[0]),t=Integer.valueOf(a[1]),i=0;List<Integer> r=new ArrayList<Integer>();for(;i<n;i++){r.add(i+1);}for(i=0;i<t;i++){int k=i%2==0?0:n-1;r.add(n/2,r.remove(k));}System.out.println(r);}}

ун-golfed:

import java.util.*;
public class Braid {
    public static void main(String[] args) {
        int num = Integer.valueOf(args[0]);
        int iterations = Integer.valueOf(args[1]);

        //populate array
        List<Integer> arr = new ArrayList<Integer>();
        for (int i=0; i < num; i++) {
            arr.add(i+1);
        }
        for (int i=0; i < iterations; i++) {
            int index = i%2==0?0:num-1; 
            arr.add(num/2, arr.remove(index));
        }
        System.out.println(arr);
    }
}

Запустить онлайн

Хоппер Охотник
источник