Halıyı yuvarlayın


15

Bu soru Kevin Cruijssen'in sorusundan esinlenmiştir .

Şimdi halı döşendiğine göre, onu yuvarlamak istiyoruz. Göreviniz, bir dize alan ve bu dizeden yapılmış bir spiral (yan taraftan görüntülenen rulo halıyı temsil eden) döndüren bir program yazmaktır.

Halının yuvarlanması için bir adım prosedürü aşağıdaki gibidir. Ne demek istediğimi gösteren bir örnek var. Örneğin, daha iyi anlaşılması için kısmen haddelenmiş bir halı ile başladığına dikkat edin:

ac
rpet
  • "kafa" yı halının "kuyruğundan" ayırın: şu ana kadar haddelenmiş olan kafa, kuyruk haddelenecek olan şeydir.
Head: ac   Tail:
      rp          et
  • Kafayı saat yönünde 90 ° döndürün.
Rotated head: ra   Tail (unchanged):
              pc                       et
  • (burada yeni kafasının genişliği, eğer 2) daha az, ya da (buradan kuyruğunun uzunluğuna eşit 2)
    • sonra kuyruğun üstüne koy
    • başka, halı (adımın başında olduğu gibi) yuvarlandı
New carpet: ra
            pc
            et

Prosedürü gerektiği kadar tekrarlayın.


Halı sarmanın tüm adımlarını gösteren iki örnek:

carpet

 c
 arpet

  ac
  rpet

    ra
    pc
    et
0123456789

 0
 123456789

  10
  23456789

    21
    30
    456789

      432
      501
      6789

Bazı kesinlikler:

  • Tüm ara adımları göstermenize gerek yoktur, sadece rulo halı (örneğin, sonucu hesaplamak için yinelemesiz bir yol bulursanız, mükemmeldir). Ayrıca, herhangi bir önde gelen boşluk yazdırmanıza gerek yoktur, yukarıdaki örneklerde, bunları yalnızca bir şeyleri hizalamak için gösteririm.
  • Girdi bir String, karakter listesi / dizisidir
  • Çıktı stdout'a veya bir dosyaya yazdırılır.
  • Girdi güzel: uzunluk en az 1 karakterdir ve en fazla yeterince sabittir, böylece sorun yaratmaz, ancak programınızda bu sabiti kullanamazsınız; dizenin içeriği yalnızca hoş karakterler ([a-zA-Z0-9]), tercih ettiğiniz şekilde kodlanır.
  • Bu , bayt en kısa cevap kazanır. Kod golf dillerinin, kod yazmayan dillerle yanıt göndermenizi istemesine izin vermeyin. 'Herhangi bir' programlama dili için mümkün olduğunca kısa bir cevap bulmaya çalışın.
  • Varsayılan Loopholes yasaktır.
  • Mümkünse, lütfen kodunuz için test içeren bir bağlantı ekleyin.
  • Ayrıca, gerekli olduğunu düşünüyorsanız cevabınıza bir açıklama ekleyin.


2
Ayrıca bu: codegolf.stackexchange.com/questions/125966/… , ancak hiçbiri sonlandırma kontrolünü içermiyor.
Bromind

3
Önerilen test durumu: ProgrammingPuzzlesAndCodeGolf- 1'den büyük son kuyruk uzunluğu beni yukarı attı.
Sok

1
Sanırım burada "kafa" ve "kuyruk" kelimelerini değiştirdiniz: "yeni kafanın genişliği [...] kuyruğun uzunluğundan [...] daha büyük veya eşitse" ... ".
Erik the Outgolfer

1
Aşırı kısıtlayıcı girdi / çıktı kuralları nedeniyle indirilmemiştir; Birinin printiçinde kullanamayacağım için Python 2 cevabımı sildim lambda.
Chas Brown

Yanıtlar:


7

Kömür , 15 bayt

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

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı versiyonudur. Açıklama:

FS«

Halının üzerinde döngü.

F¬℅§KV⁰

İmlecin üzerinde bir şey olup olmadığını kontrol edin.

⟲⁶

Değilse halıyı yuvarlayın.

→Pι

Sağa git ve geçerli karakteri çıkar.

Örnek: Giriş 0123456789için aşağıdaki eylemler gerçekleşir:

0

0 yazdırılır.

01

İmleç sağa hareket eder ve 1yazdırılır.

0
1

Üzerinde hiçbir şey olmadığından, 1tuval döndürülür.

0
12

İmleç sağa hareket eder ve 2basılır.

10
2

Üzerinde hiçbir şey olmadığından, 2tuval döndürülür.

10
23

İmleç sağa hareket eder ve 3basılır.

10
234

İmleç sağa hareket eder ve 4basılır.

21
30
4

Üzerinde hiçbir şey olmadığından, 4tuval döndürülür.

21
30
45

İmleç sağa hareket eder ve 5basılır.

21
30
456

İmleç sağa hareket eder ve 6basılır.

432
501
6

Üzerinde hiçbir şey olmadığından, 6tuval döndürülür.

432
501
67

İmleç sağa hareket eder ve 7basılır.

432
501
678

İmleç sağa hareket eder ve 8basılır.

432
501
6789

İmleç sağa hareket eder ve 9basılır.


Bu harika. Yani temelde Kömür yerleşik bir "rulo" operatörü var ?
Jonah

1
@Jonah Peki, benim için gittikçe yuvarlanmayacak, ama karakter karakter dizesini çıktı olarak giderken yuvarlayabilirim, evet.
Neil

3

Pyth, 37 bayt

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

Online Deneyin burada ya bir kerede tüm test durumları doğrulamak burada .

.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

Kabuk , 24 bayt

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

Çevrimiçi deneyin!

açıklama

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 bayt

FrownyFrog sayesinde -3 bayt

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

Çevrimiçi deneyin!

açıklama

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

Algoritma, J için biraz ayrıntılı olmasına rağmen basittir.

Genel Strateji: Girişi (muhtemelen boş) kalan bir parça ile kare bir tabloya azaltın.

Düşürdükçe 2 elementlik bir kutu listesi kullanacağız. "Şimdiye kadarki sonuç" ilk kutu olacak ve "işlenecek ürünler" 2. kutu olacak. İlk kutu girişin başına sıfırlanır (ancak tabloya dönüştürülür):

1 1 $ {.

ve "işlenecek kalan öğeler" girdinin kuyruğu olacaktır:

}. ;~

Şimdi elimizde:

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

burada 'c' aslında 1x1 tablodur.

Bunu bir J Do ... While döngüsü kullanarak azaltırız:

^:(...)^:_

Parantez içindeki parçanın "devam et" koşulu olduğu durumlarda:

<:&#&>/

"sağ kutunun uzunluğu sol kutunun uzunluğundan büyük veya ona eşitken (yani, kare matrisin yan uzunluğu)

"Devam et" ne demektir? Bu, ilk ^:sonucun solundaki fiilde tanımlanır , bu da bize mevcut sonucu nasıl alacağımızı ve bir sonraki yinelemeyi nasıl üreteceğimizi anlatır. Bu fiil:

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

Hadi yıkalım:

((|:@|.@[ , #@[ {. ]) ; #@[ }. ])&>/
(  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

Yani, bu sadece OP'de tam anlamıyla J'ye tercüme edilen algoritmadır.

Son olarak (muhtemelen 0) artık eşya, halı rulonuzun kuyruğu ile ilgileniyoruz:

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

Bu, "sonucun son karaağaç hariç hepsini al" diyor:

}:@[ 

ve ,sonucun son öğelerine {:@[son öğeye eklenmiş kalan öğeler eklenir, ]


Ah, J ... harfler noobs içindir
RK.

,.ne yapabilir 1 1$]ve ne gibi $kullanılabilir {..
FrownyFrog

@FrownyFrog ty. Ben bunu aldım ilk öneriyle 70 bayt ama anlaşılan emin değildi $ can be used as {.- sen netleştirebilirsiniz?
Jonah

1
Açıklamanın son satırı {. kısaltmak için, bu benim anladığım kadarıyla bir $ olabilir.
FrownyFrog

Ayrıca sağ [: ile bir @
FrownyFrog

1

R , 146131 bayt

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="")}

Çevrimiçi deneyin!

Halı haddeleme prosedürünü uygular. Girişi karakter listesi olarak alır ve stdout'a yazdırır.

Bir do-whiledöngü kullanmanın yolunu bularak ve kullanmaya başlayarak 14 bayt kaydedildi 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

Jöle , 30 bayt

Aşırı uzun görünüyor ...

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

Çevrimiçi deneyin!

Nasıl?

Ḣ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 bayt

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

Çok uzun, ama Tuval'i kullanmak istedim .. Şimdi bitirdiğim için muhtemelen kötü bir seçimdi ve bu uzun olduğu ortaya çıktı.

Çevrimiçi deneyin . (Test paketi yok, çünkü yerleşik ile garip bir sorun var gibi görünüyor .)

Açıklama:

Kanvas ve kodumun neyi başarmasını istediğime dair genel bir açıklama vererek başlayayım. Daha ayrıntılı bilgi bu ilgili 05AB1E ipucumda bulunabilir , ancak bu meydan okuma için aşağıdakileri yapmak istedim:

Canvas yerleşik üç parametre alır:

  • bir[2,2,3,3,4,4,5,5,...]
  • b
  • c[2,0,6,4] ([,,,]) döndürülmüş nGiriş-string bağlı olarak kaç kere başka bir başlangıç yönü için (örneğin, giriş carpetolduğu[0,6,4,2]Bunun yerine ve giriş 0123456789ABCDEFGHIolduğu[6,4,2,0] yerine).

Kod gelince:

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)

Neden Ž8Oolduğunu anlamak için bu 05AB1E ucuma bakın ( Büyük tamsayılar nasıl sıkıştırılır? Bölümü )2064 .


0

Python 3 , 112 bayt

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

Bu durumda, çıktı işlevin değeridir.

Çevrimiçi deneyin!

İsterseniz, burada doğrudan haddelenmiş girişi yazdıran başka bir (daha uzun, 129 bayt ) çözüm:

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

Çevrimiçi deneyin!


1
yazdırmak gerekiyor
sadece ASCII sadece

@ Yalnızca ASCII: Sorunun yazarından alıntı yapmak: "Yazdırma yerine geri dönmek büyük bir gelişme veya hoş bir hile gösteriyorsa, bir yanıt gönderin (ve yazdırdığınızı açıkça belirttiğinizden emin olun)" . Bence sorun yok.
PieCot

0

MATLAB / Oktav , 154 bayt

En kısa değil, MATLAB / Octave'de golf yapmak her zaman eğlencelidir :)

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

Çevrimiçi deneyin!


1
ne yazık ki, op yazdırmak zorunda diyor
ASCII sadece

@ ASCII-sadece burada açıklandığı gibi ( it.mathworks.com/matlabcentral/answers/… ), Matlab dünyasındaki stdout komut penceresini ifade eder. Her komutun değerlendirilmesinin sonucunun otomatik olarak komut penceresine yazdırıldığı göz önüne alındığında, bu cevabın sorunun gereksinimleriyle tutarlı olarak değerlendirilebileceğini düşünüyorum.
PieCot


@ ASCII-sadece gerçekten ne demek istediğini anlamıyorum. Bu bir işlevdir, siz çağırırsınız, sonuç otomatik olarak komut penceresine yazdırılır (yani stdout). Bunun nesi var? R yanıtı bile böyle çalışıyor ...
PieCot

1
Şimdi sen dispo, sana kaldırmalısınız derdim dispo Ar bilmeyen insanlara bildirmek için yaptığı varsayılan olarak STDOUT yazma
ASCII sadece
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.