Закатайте килим


15

Це питання натхнене питанням Кевіна Круїссена .

Тепер, коли килим викладений, ми хочемо його прокатати. Ваше завдання - написати програму, яка займає рядок і повертає спіраль, зроблену з цієї рядка (що представляє собою згорнутий килим, поглянути збоку).

Процедура одного кроку прокатки килима така. Є приклад, який ілюструє, що я маю на увазі. Зауважте, що приклад починається з частково згорнутого килима для кращого розуміння:

ac
rpet
  • відокремте «голову» від «хвоста» килима: голова - це те, що було згорнуто досі, хвіст - це те, що залишається прокатати.
Head: ac   Tail:
      rp          et
  • Поверніть голову на 90 °, за годинниковою стрілкою.
Rotated head: ra   Tail (unchanged):
              pc                       et
  • якщо ширина нової головки (тут 2) менша або дорівнює довжині хвоста (тут 2)
    • потім покладіть його на хвіст
    • інакше килим (як це було на початку кроку) був прокатував
New carpet: ra
            pc
            et

Повторіть процедуру стільки разів, скільки потрібно.


Два приклади, що показують усі етапи прокатки килима:

carpet

 c
 arpet

  ac
  rpet

    ra
    pc
    et
0123456789

 0
 123456789

  10
  23456789

    21
    30
    456789

      432
      501
      6789

Деякі заходи:

  • Вам не потрібно показувати всі проміжні кроки, лише прокатаний килим (наприклад, якщо ви знайдете неітераційний спосіб обчислення результату, це ідеально). Крім того, вам не потрібно друкувати будь-які провідні пробіли, у наведених вище прикладах я показую їх лише для вирівнювання матеріалів.
  • Введення - це рядок, список / масив знаків
  • Виведення друкується у stdout або у файл.
  • Введення приємно: довжина становить щонайменше 1 char, а щонайбільше - константа достатньо невелика, щоб не викликати проблем, але ви не можете використовувати цю константу у своїй програмі; вміст рядка - це лише приємні символи ([a-zA-Z0-9]), кодування за вашим уподобанням.
  • Це , тому найкоротша відповідь у байтах виграє. Не дозволяйте мовам з кодовим гольфом відштовхувати вас від публікації відповідей з не кодовими гольф-мовами. Спробуйте придумати якомога коротшу відповідь на "будь-яку" мову програмування.
  • Лазівки за замовчуванням заборонені.
  • Якщо можливо, додайте посилання з тестом для вашого коду.
  • Також додайте пояснення до своєї відповіді, якщо вважаєте, що це потрібно.


2
Також цей: codegolf.stackexchange.com/questions/125966/… , але жоден не включає перевірку припинення.
Bromind

3
Пропонований тестовий випадок: ProgrammingPuzzlesAndCodeGolf- кінцева довжина хвоста, більша за 1, спричинила мене.
Сок

1
Я думаю, ви тут поміняли слова "голова" та "хвіст": "якщо ширина нової голови [...] більша або дорівнює довжині хвоста [...]".
Ерік Аутгольфер

1
Захищений через занадто обмежувальні правила введення / виведення; Я видалив свою відповідь Python 2, оскільки не можна використовувати printвсередині lambda.
Час Браун

Відповіді:


7

Вугілля деревне , 15 байт

FS«F¬℅§KV⁰⟲⁶→Pι

Спробуйте в Інтернеті! Посилання на багатослівну версію коду. Пояснення:

FS«

Петля над килимом.

F¬℅§KV⁰

Перевірте, чи є щось над курсором.

⟲⁶

Якщо ні, то закатайте килим.

→Pι

Перемістіть праворуч і виведіть поточний символ.

Приклад: Для введення даних 0123456789виконуються наступні дії:

0

0 друкується.

01

Курсор рухається вправо і 1друкується.

0
1

Оскільки вище нічого немає 1, полотно обертається.

0
12

Курсор переміщується вправо і 2друкується символ.

10
2

Оскільки вище нічого немає 2, полотно обертається.

10
23

Курсор переміщується вправо і 3друкується символ.

10
234

Курсор переміщується вправо і 4друкується символ.

21
30
4

Оскільки вище нічого немає 4, полотно обертається.

21
30
45

Курсор переміщується вправо і 5друкується символ.

21
30
456

Курсор переміщується вправо і 6друкується символ.

432
501
6

Оскільки вище нічого немає 6, полотно обертається.

432
501
67

Курсор переміщується вправо і 7друкується символ.

432
501
678

Курсор переміщується вправо і 8друкується символ.

432
501
6789

Курсор переміщується вправо і 9друкується символ.


Це круто. Так в основному у вугіллі є вбудований оператор "рулону" ?
Йона

1
@Jonah Ну, це не буде для мене котитися, як це йде, але, вивівши строковий символ за символом, я можу прокручуватись, як іду, так.
Ніл

3

Pyth, 37 байт

.U+j;bZ.WgleHJlhH,+_MChZ<eZJ>eZJ,]hQt

Спробуйте це в Інтернеті тут або перевірити всі тестові випадки тут .

.U+j;bZ.WgleHJlhH,+_MChZ<eZJ>eZJ,]hQtQ   Implicit: Q=eval(input())
                                         Trailing Q inferred
                                 ]hQ     First character of Q, wrapped in an array
                                    tQ   All but the first character of Q
                                ,        2-element array of the two previous results
                                           This yields array with rolled carpet (as array of strings) followed by the tail
       .W                                While condition function is truthy, execute inner function, with initial value of the above:
         gleHJlhH                          Condition function, input H
             JlhH                            Number of layers in the current rolled carpet, store in J
          leH                                Lenth of the tail
         g   J                               Is the above greater than or equal to J?
                 ,+_MChZ<eZJ>eZJ           Inner function, input Z
                   _MChZ                     Rotate the current rolled carpet (transpose, then reverse each row)
                  +     <eZJ                 Append the first J characters of the tail as a new row
                 ,                           Pair the above with...
                            >eZJ             ... all but the first J characters of the tail - this is the new tail
.U+j;bZ                                  Join the carpet roll on newlines and append the tail, implicit print

3

Лушпиння , 24 байти

►S=ÖLmFȯ:T↔ø§z:oΘḣĠ+CṘ2N

Спробуйте в Інтернеті!

Пояснення

Implicit input, say s="carpets"

CṘ2N  Break s into chunks:
   N   Natural numbers: [1,2,3,4,..
 Ṙ2    Repeat each twice: [1,1,2,2,3,3,4,4,..
C      Break s into chunks of these lengths: ["c","a","rp","et","s"]
       The last chunk is shorter if we run out of characters.

§z:oΘḣĠ+  Attempt to merge suffix of chunks:
      Ġ    Cumulative reduce chunk list from right
       +   by concatenation: ["carpets","arpets","rpets","ets","s"]
   oΘḣ     Prefixes of chunk list (empty and nonempty): [[],["c"],..,["c","a","rp","et","s"]]
§z         Zip these by
  :        appending: [["carpets"],["c","arpets"],..,["c","a","rp","et","s"]]
           These are all versions of the chunk list where some suffix has been merged.

mFȯ:T↔ø  Roll each list:
m         Map
 F        reduce from left
      ø   starting from empty character matrix
  ȯ:T↔    by this function:
    T↔     Reverse and transpose (rotating by 90 degrees)
  ȯ:       then append next chunk as new row.
         Result: [["carpets"],["c","arpets"],..,["epr","tca","s"]]

►S=ÖL  Select the matrix rolled by the correct amount:
►       Find element that maximizes
 S=     being equal to
   ÖL   sort by length.
        This selects a matrix whose rows have non-decreasing lengths.
        Ties are broken by choosing the rightmost one.
       Result: ["ra","pc","ets"]

Implicitly print each row separated by newlines.

2

J , 69 байт

-3 байти завдяки FrownyFrog

[:(}:@[,{:@[,])&>/[:((|:@|.@[,#@[$]);#@[}.])&>/^:(<:&#&>/)^:_,.@{.;}.

Спробуйте в Інтернеті!

пояснення

[: (}:@[ , {:@[ , ])&>/ [: ((|:@|.@[ , #@[ {. ]) ; #@[ }. ])&>/^:(<:&#&>/)^:_ }. ;~ 1 1 $ {.

Алгоритм простий, незважаючи на те, що для Дж.

Загальна стратегія: Зменшіть вклад до квадратної таблиці за допомогою (можливо, порожнього) залишку.

Коли ми зменшимось, ми будемо використовувати список двох елементів. Наш "результат поки що" буде першим полем, а "елементи, що залишилися для обробки", будуть другими. Перше поле буде ініціалізовано на голову вводу (але перетворено в таблицю):

1 1 $ {.

і "елементи, що залишилися для обробки", будуть хвостиком введення:

}. ;~

Тепер ми маємо:

┌─┬─────┐
│c│arpet│
└─┴─────┘

де 'c' насправді є таблицею 1x1.

Ми зменшуємо це вниз, використовуючи J Do ... Поки цикл:

^:(...)^:_

Де в дужках є умова "продовжувати":

<:&#&>/

який говорить "продовжуйте, поки довжина правого поля більша або дорівнює довжині лівого поля (тобто довжина сторони квадратної матриці)

Що означає "продовжувати"? Це визначено у дієслові зліва від першого ^:, де йдеться про те, як приймати поточний результат та виробляти наступну ітерацію. Це дієслово:

((|:@|.@[ , #@[ {. ]) ; #@[ }. ])&>/

Давайте розбимо його:

((|:@|.@[ , #@[ {. ]) ; #@[ }. ])&>/
(  verb in parens               )&>/ NB. put the verb in parens
                                     NB. between the two items
                                     NB. of our list, and unbox
                                     NB. them into left / right
                                     NB. args ([ / ]) for the verb
 (|:@|.@[ , #@[ {. ]) ; #@[ }. ]     NB. breaking down verb in 
                                     NB. parens...
                      ; ....         NB. new "remaining items":
                            }. ]     NB. remove from remaining
                        #@[          NB. the size of a side of
                                     NB. the result matrix
                ....  ;              NB. new "result":
  |:@|.@[                            NB. rotate existing result
          ,                          NB. and put it on top of
            #@[ {. ]                 NB. the items we removed
                                     NB. from remaining items

Тобто це лише алгоритм, описаний в ОП, перекладений буквально на Дж.

Нарешті ми розбираємось із (можливо, 0) предметами, що залишились, хвостом нашого килимового рулону:

(}:@[ , {:@[ , ])&>/

Це говорить "взяти всіх, крім останнього в'яза результату":

}:@[ 

і додайте його до ,останніх елементів результату {:@[з рештою, доданими до цього останнього, ]


Ах, J ... букви - для нобіїв
РК.

,.може робити те, що 1 1$]робить, і $можна використовувати як {..
FrownyFrog

@FrownyFrog ty. Я отримав його в 70 байт з вашої першої пропозиції, але не був впевнений, чи зрозумів $ can be used as {.- ви можете уточнити?
Йона

1
Останній рядок пояснення ви використовуєте {. щоб усікати, це може бути доларом, наскільки я розумію.
FrownyFrog

Також ви можете замінити право [: а @
FrownyFrog

1

R , 146 132 байт

function(s){m=F[F]
while({m=rbind(t(m)[,F:0],s[1:F])
s=s[-1:-F]
length(s)>sum(F<-dim(m))})0
write(m[F:1,],1,F[1],,"")
cat(s,sep="")}

Спробуйте в Інтернеті!

Реалізує процедуру прокатки килимів. Приймає введення як список символів та відбитків для викреслювання.

Збережено 14 байт шляхом пошуку способу використання do-whileциклу та ініціалізації використання F.

function(s){
m=F[F]					# logical(0); create an empty array (this gets automatically promoted to character(0) later
while(					# do-while loop
      {m=rbind(t(m)[,F:0],s[1:F])	# rotate m counterclockwise and add the first F characters of s to the bottom
       s=s[-1:-F]			# remove those characters
       length(s)>sum(F<-dim(m))})0	# while the number of characters remaining is greater than the sum of m's dimensions
write(m[F:1,],1,F[1],,"")		# write the rolled portion write writes down the columns, we reverse each column
cat(s,sep="")				# and write the remaining characters
}

1

Желе , 30 байт

Здається, занадто довго ...

ḢW,ðZU;Ls@¥©ḢWɗ,®Ẏ¤ð/ẈṢƑ$¿ḢY;Ɗ

Спробуйте в Інтернеті!

Як?

ḢW,ðZU;Ls@¥©ḢWɗ,®Ẏ¤ð/ẈṢƑ$¿ḢY;Ɗ - Main Link: list of characters
Ḣ                              - pop and yield head
 W                             - wrap in a list
  ,                            - pair with (the remaining list after Ḣ)
                         ¿     - while...
                        $      - ...condition: last two links as a monad:
                     Ẉ         -   length of each
                       Ƒ       -   is invariant under:
                      Ṣ        -     sort
                    /          - ...do: reduce by:
   ð               ð           -   the enclosed dyadic chain -- i.e. f(head, tail):
    Z                          -     transpose
     U                         -     reverse each (giving a rotated head)
              ɗ                -     last three links as a dyad:
          ¥                    -       last two links as a dyad:
       L                       -         length (i.e. number of rows in current roll)
         @                     -         with swapped arguments:
        s                      -           split (the tail) into chunks of that length
           ©                   -       (copy to register for later)
            Ḣ                  -       pop and yield head (Note register "copy" is altered too)
             W                 -       wrap in a list
      ;                        -     concatenate (the rotated head with the first chunk of the tail)
                  ¤            -     nilad followed by link(s) as a nilad:
                ®              -       recall from register (other chunks of tail, or an empty list)
                 Ẏ             -       tighten (the chunks to a flat list)
               ,               -     pair (the concatenate result with the tightened chunks)
                             Ɗ - last three links as a monad:
                          Ḣ    -   pop and yield head
                           Y   -   join with newline characters
                            ;  -   concatenate (the remaining tail)
                               - when running as a full program implicitly prints

1

05AB1E , 41 байт

g©L¦€DD2šηO®>‹Ï©IŽ8OS®g4α._.ΛðÜI®O®g->.$«

Шлях занадто довгий, але я хотів використати полотно. Що було, мабуть, поганим вибором зараз, коли я закінчив це, і виявилося, що це було так довго ..

Спробуйте в Інтернеті . (Немає тестового набору, тому що, здається, є дивна проблема з вбудованим.)

Пояснення:

Дозвольте почати із загального пояснення полотна та того, що я хотів виконати. Більш детальну інформацію можна знайти в цьому відповідному наконечнику 05AB1E , але для цього завдання я хотів зробити наступне:

Побудований полотно має три параметри:

  • а[2,2,3,3,4,4,5,5,...]
  • б
  • c[2,0,6,4][,,,]нcarpet[0,6,4,2]0123456789ABCDEFGHI[6,4,2,0] замість цього).

Щодо коду:

g                # Get the length of the (implicit) input-string
 ©               # Store it in the register (without popping)
  L              # Create a list in the range [1,length]
   ¦             # Remove the first item to make the range [2,length]
    D           # Duplicate each to get the list [2,2,3,3,4,4,5,5,...]
      D2š        # Create a copy and prepend a 2: [2,2,2,3,3,4,4,5,5,...]
         η       # Get the prefixes: [[2],[2,2],[2,2,2],[2,2,2,3],...]
          O      # Sum each prefix: [2,4,6,9,12,16,20,...]
           ®     # Push the length from the register again
            >‹   # Check for each summed prefix if it's <= length
              Ï  # And only leave the truthy values
               © # And store this in the register (without popping)
                 # (This is our `a` for the Canvas builtin)
I                # Push the input-string
                 # (This is our `b` for the Canvas builtin)
Ž8O              # Push compressed integer 2064
   S             # Converted to a list of digits: [2,0,6,4]
    ®g           # Push the list from the register, and get its length
      4α         # Get the absolute difference with 4
        ._       # And rotate the [2,0,6,4] that many times towards the left
                 # (This is our `c` for the Canvas builtin)
               # Now use the Canvas builtin, without printing it yet
  ðÜ             # Remove any trailing spaces (since the Canvas implicitly makes a rectangle)
     ®O          # Push the sum of the list from the register
       ®g-       # Subtract the length of the list from the register
          >      # And add 1
    I      .$    # Remove that many leading characters from the input-string
             «   # And append it at the end of the roll created by the Canvas
                 # (after which the result is output implicitly)

Дивіться цей мінний наконечник 05AB1E (розділ Як стискати великі цілі числа? ), Щоб зрозуміти, чому Ž8Oце так 2064.


0

Python 3 , 112 байт

r=lambda t,h=[[]]:len(h)>len(t)and h[:-1]+[h[-1]+list(t)]or r(t[len(h):],list(zip(*h[::-1]))+[list(t)[:len(h)]])

У цьому випадку вихід - це значення функції.

Спробуйте в Інтернеті!

Якщо ви віддаєте перевагу, тут інше (довше, 129 байт ) рішення, яке друкує безпосередньо прокатуваний вхід:

r=lambda t,h=['']:len(h)>len(t)and set(map(print,h[:-1]+[h[-1]+t]))or r(t[len(h):],list(map(''.join,zip(*h[::-1])))+[t[:len(h)]])

Спробуйте в Інтернеті!


1
потрібно роздрукувати його
лише для ASCII

@ ASCII only: Цитуючи автора питання: "Якщо повернення замість друку показує велику поліпшення чи приємну хитрість, опублікуйте відповідь (і явно, що ви повертаєтесь, а не друкуєте)" . Тому я думаю, що це нормально.
PieCot

0

MATLAB / Octave , 154 байти

Не найкоротший, але грати в гольф у MATLAB / Octave - це завжди цікаво :)

function h=r(t,h);n=fliplr(h');s=size(n,2);q=numel(t);if s<=q h=r(t(max(s,1)+1:end),[n; t(1:max(s,1))]);elseif q>0 h(:,end+q)=' ';h(end,end-q+1:end)=t;end

Спробуйте в Інтернеті!


1
на жаль, оп каже, що вам потрібно надрукувати
лише для ASCII

@ ASCII лише як пояснено тут ( it.mathworks.com/matlabcentral/answers/… ), stdout у світі Matlab посилається на вікно команд. З огляду на те, що результат оцінки кожної команди автоматично друкується у вікні команд, я вважаю, що цю відповідь можна вважати відповідною вимогам запитання.
PieCot


@ ASCII-тільки я не розумію, що ти маєш на увазі, насправді. Це функція, ви її називаєте, результат автоматично надрукується у вікні команди (тобто stdout). Що з цим? Навіть відповідь на R працює так:
PieCot

1
Зараз ти dispце, я б сказав , що ви повинні видалити , dispщоб люди , які не знають R , що робить запис в STDOUT за замовчуванням
ASCII-тільки
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.