Akışlarımı çiz


60

Bir programcı olarak, muhtemelen eğik çizgiler ve geriye eğik çizgiler duymuşsunuzdur. Fakat aşağı akıntıları duydunuz mu? Bir demet eğik çizgi aldığınızda, uçlarını birleştirin ve aşağı doğru inmelerini sağlayın.

Bugünün meydan okuması için, sadece eğik çizgilerden oluşan bir dize alan ve aşağı doğru çizilen tüm eğik çizgileri bunları birleştiren bir çizgide çıkaran bir program veya işlev yazmalısınız. Bir örnek görürseniz, bu çok daha net olacaktır. Dize verildiğinde, \\\//\/\\çıktısını almalısınız:

\
 \
  \
  /
 /
 \
 /
 \
  \

İşte bazı açıklamalar:

  • Satır başına bir eğik çizgi olmalıdır.

  • İlk satırda 0 öncü boşluk olacaktır.

  • Her eğik çizgi çifti için:

    • Birbirlerinden farklılarsa, aynı sütunda çizilirler. Örneğin, \/verecek:

      \
      /
      
    • Aynı karakterdeyse, alt taraf işaret ettiği yönde , ters eğik çizgi için sağa ve öne eğik çizgi için sola hareket ediyor. Yani \\//verecek

      \
       \
       /
      /
      
  • Her satır, çıktının görsel görünümünü değiştirmediği sürece ekstra boşlukta olabilir. Bire kadar takip eden ve önde gelen yeni satır da kabul edilebilir. Ekstra boş alanlara izin verilmez !

Bunu daha basit tutmak için, dizginin asla çok fazla eğik çizgi içermeyeceğini varsayabilirsiniz. Başka bir deyişle, girişin öneki hiçbir ters eğik çizgiden daha fazla eğik çizgi içermez, bu nedenle bir giriş \\////veya //asla bir giriş yapılmaz. Bu aynı zamanda her girişin ters eğik çizgiyle başlayacağı anlamına gelir.

Girişiniz değişmez bir dize olarak alınmışsa, gerekirse ters eğik çizgiden kaçabilirsiniz. Ayrıca boş veya eğik çizgi dışındaki karakterleri içeren bir girişi hiçbir zaman işlemeniz gerekmez.

Herhangi bir makul formatta çıktı alabilirsiniz .

Her zamanki gibi, bu bir mücadelesidir, bu yüzden oldukça zor bir dil seçseniz bile mümkün olan en kısa çözümü yapmaya çalışın. Bayt çıkarmak için kullandığınız ilginç teknikleri açıklamak için bonus puan!

Örnekler

#Input
\\\\\\\\\\\

#Output
\
 \
  \
   \
    \
     \
      \
       \
        \
         \
          \

#Input
\\\//\\/\//\\///

#Output
\
 \
  \
  /
 /
 \
  \
  /
  \
  /
 /
 \
  \
  /
 /
/


#Input
\/\/\/

#Output
\
/
\
/
\
/

9
Ters eğik çizgiler sinir bozucu bir miktar kaçış lol ...
tamamen insan

Yanıtlar:


20

GNU Sed, 20

s|\\|&^L|g
s|/|^H/^L^H|g

Bunun ^Lve ^Hdeğişmez formfeed ve backspace karakterlerinin (0x12 ve 0x8) olduğunu unutmayın.

Bu cevap, imleci geri alma ve form besleme karakterlerini kullanarak hareket ettirerek çalışır. Eğik çizgiler / ters eğik çizgiler boşluklarla doldurulmamıştır - Bundan emin değil bu cevabı diskalifiye eder. Bu, TIO’da çalışmaz, ancak xtermvegnome-terminal .

Bu sed betiğini aşağıdaki gibi yeniden oluşturun:

base64 -d <<< c3xcXHwmDHxnCnN8L3wILwwIfGc= > downslash.sed

Aşağıdaki gibi çalıştırın:

$ echo '\\\//\/\\' | sed -f downslash.sed
\ 
 \ 
  \ 
  /
 /
 \ 
 /
 \ 
  \ 

$ 

Açıklama:

s|\\|&^L|g     # move cursor down after every "\"
s|/|^H/^L^H|g  # move cursor left before every "/", then after, down and left again

14

Kömür , 13 12 11 bayt

FS¿⁼ι/↓¶/↘ι

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

 S              Input string
F               Loop over each character
  ¿             If
    ι           Current character
   ⁼            Equals
     /          Literal /
      ↓¶        Move left
      ↓ /       Print a / downwards
         ↘ι     Else it's a \ so print that down and right

Bence ↓¶= "Sola git" açıklamasında doğru değil.
Jonathan Allan,

@JonathanAllan Bu doğru (newline aşağı basıldı = sola hareket et), muhtemelen " \n/aşağı yazdır " demek daha açık olsa da
ASCII sadece

Söylemedim, print \n/ downçünkü kelimenin tam anlamıyla çevirisinden ziyade kodun etkisini tanımlamanın daha yararlı olduğunu düşündüm.
Neil

1
(Yanaktaki dil: Etkinin tanımlanması = MyCode - Do the spec). Etkisi sola hareket etse de şimdi anlıyorum ; "Sola git (aşağıya doğru yazdırma yönüne yeni bir satır yazdırarak))" demeye değer olabilir.
Jonathan Allan

Hepsinden en özlü ve öz açıklayıcı!
j4hangir 16:17


10

/// , 119 bayt

/// giriş komutu yoktur, bu nedenle giriş programa dahil edilmelidir. Bunun için giriş dizesi basitçe eklenir, kaçmaya gerek yoktur.

/=/\/\///M/
|%%=N/%|||=C/BA=\/\\/\/C\\=C\\/CbC=B\A\=CfC=AB=/A/%Mxy=B/|z%N|x|y% %N%x|y%%% |fzN%M%b|zN|M|%
=|/AB\\=%/|=AC

Nasıl çalışır

  • Aşağıda, \\/\//gösterim için programa bir girdi eklenecektir.
  • satır içi kodunda yeni satırları temsil etmek için kullanılır.

Kısaltmalar

Programın başında /=/\/\///M/␤|%%=N/%|||=C/BA=golf kısaltmaları yerine geçebilir.

  • =//, Mile ␤|%%, Narasında %|||ve Ciçin genişler BA.
  • Bundan sonra mevcut program

    /\/\\/\/BA\\//BA\\/BAbBA//B\A\//BAfBA//AB///A/%
    |%%xy//B/|z%%||||x|y% %%|||%x|y%%% |fz%|||%
    |%%%b|z%||||
    |%%|%
    //|/AB\\//%/|//ABA\\/\//
    

Giriş kodlama

Bir sonraki aşama, eklenen girdi dizesini daha kullanışlı bir formata dönüştürür. Tamamen /// 'nin iki komut karakterinden oluşması nedeniyle, temel programın yönetilmesinin engellenmesi biraz özen gösterir.

  • İlk önemli ikame, /\/\\/\/BA\\/dize /\ile değiştirir /BA\.
    • Temel program /\şu anda içermiyor , bu nedenle bu değiştirme onu etkilemiyor.
    • Bununla birlikte, bu, eklenen giriş dizgisini \s dizilerine, ardından da s dizisine böler /;ABA taban program sonunda mümkün aşağıdaki ikamelerin ile içinden yineleme kolaylaştırır.
    • Ondan önceki ABAönek dahil, örnek girdi dizgisi şimdi olur ABA\\/BA\//.
  • Bir sonraki değişiklik, tarafından /BA\\/BAbBA/değiştirilir . BA\BAbBA
    • /// ikameleri artık eşleşmeyene kadar tekrarlandığından \, bu, önekle birlikte şimdiki haline gelen girdi dizgisinin tüm s'lerini yineler.ABAbBAbBA/BAbBA//
  • Benzer bir şekilde, /B\A\//BAfBA/değişiklikleri BA/için BAfBAyineleme, /s.
    • \Bu sübstitüsyonda kaçış gerekli çünkü aksi takdirde öncekiyle karışacaktı.
    • Giriş şimdi dönüşmüştür ABAbBAbBAfBABAbBAfBAfBA.
  • Daha /AB//sonra, kodlamanın bazı gereksiz kısımlarını kaldırarak içine alır AbBAbBAfBAbBAfBAfBA.
    • Bu, aynı zamanda, bir kaldırır ABden /|/AB\\/daha sonra yukarıdan korumak için gerekli programında ikame /\manipülasyon.
    • Bu noktada \orjinal girdi dizgisindeki AbBher /biri ve her biri oldu AfB. ( bve fgeriye ve öne doğru durun.) ASonunda başıboş bir şey var .
  • Sonraki iki oyuncu değişikliği tüm As ve Bs'leri son aşamada çalıştırılacak program parçalarıyla değiştirdi. Değiştirme dizgelerinde, %s ve |s, sırasıyla /s ve \s olacak olanı kodlar . Bunun iki faydası vardır:
    • Aksine /ve \, %s ve |s kopyalanacak kaçan gerekmez.
    • Değiştirme dizeleri /\, daha önce yapılan manipülasyonlar tarafından değiştirilebilecek olan alt dizeyi içermekten kaçınır .
  • Bundan sonra, sübstitüsyon /|/\\/(eskiden /|/AB\\/) şimdi s'leri deşifre eder |, bundan sonra aşağıdakiler s /%/|//olur /%/\//ve şifrelerini çözer %.

Son aşamada program yapısı

Bu noktada, temel program bütün değişkenlerini çalıştırmıştır ve geriye kalan tek şey giriş dizesinin program kodlamasıdır.

  • Her giriş karakteri bir alt program haline geldi

    /
    \//xy*\z//\\\\x\y/ //\\\/x\y/// \fz/\\\/
    \///b\z/\\\\
    \//\/
    

    (arka satır), burada *herhangi birini temsil eder f, bir orijinal için /, ya da bbir orijinal için \.

  • Ayrıca, /␤\//xyprogramın sonunda /, önceki alt programın yerine konması için gerekli olmadıkça etkisi olmayacak olan eksik bir yerine koyma komutu vardır .

Paylaşılan alt dize

Alt programlardan geçen son yineleme başlamadan önce, her karakterin formun alt programından sonra sınırı geçen bir alt dizgi vardır \/␤/.

  • Bu alt diziler ortak bir genel durum olarak kullanılır. Programda kalan tüm değiştirmeler onları aynı ve paralel olarak değiştirecektir, öyle ki her giriş karakterinin alt programının sonunda bu paylaşılan alt dizinin kopyası (değiştirmeleri birleştiren son hariç /) bunun için satır yazdırmak için çalıştırılacak karakter.
  • Alt dizinin ilk sürümü /, ilk girdi karakterinin satırının başında yazdırılmasını sağlamak için hayali "önceki satır" olan doğru bir satır yazdırmayı temsil eder .
  • Genel olarak, yazdırma adımları sırasında, paylaşılan alt dize bir kaç boşluktan \\veya \/bir yeni satırdan ve bir izlemeden oluşur /.

Bir karakter alt programını çalıştırma

Aşağıdaki sübstitüsyonların \birçoğu, birbirleri ile eşleşmelerini ve birbirine karışmalarını önlemek için fazladan s içerir (diğer alt programlardaki diğer kopyalar dahil). Bu sağlanması da her iki nedeni budur xve yihtiyaç vardır.

  • Bir karakter alt programında ilk ikamesi, /␤\//xyf\z/ya /␤\//xyb\z/neden olur ␤/olmayı paylaşılan alt dizenin sonundaki xyfzveya xybzhemen sonrasında \/veya \\.
  • İkamesi /\\\\x\y/ /yerine \\xybir boşluk ve ikame /\\\/x\y//yerini \/xyhiçbir şey tarafından.
    • Bir önceki giriş karakteri , sırasıyla bir \veya olduğunda, geçerlidir /.
    • Paylaşılan alt dize şimdi bir \sonrakini yazdırmak için uygun sayıda boşluk , ardından fzveya tuşunu içerir bz.
  • İkame / \fz/\\\/␤\//yerine ​ fzgöre \/␤/ve /b\z/\\\\␤\//yerine bzgöre \\␤/.
    • Geçerli giriş karakteri sırasıyla /veya olduğunda geçerlidir \.
    • İlki, /doğru şekilde yerleştirmek için fazladan bir alan yer .
      • Bu alan eksikse (örneğin önek koşulunu ihlal eden giriş), aşağıdaki değişiklikler yanlış yorumlanır, çok fazla önemsiz baskı yapar ve genellikle ///sonsuz bir döngü olan a'yı vurur .
    • Her biri kendi karakterini yazdırmak için doğru komutu ekler ␤/ve paylaşılan alt dize sonunda orijinali eski durumuna getirir .
  • Karakter alt programı, çizgisini basmaya hazır olan paylaşılan alt dizenin kopyasına ulaştı.

Son karakter alt programı çalıştıktan sonra, programın kalıntıları nedir /␤\//xy. Bu eksik finalde eksik bir oyuncu değişikliği olduğu için /, program onu ​​atlar ve normal şekilde durur.


1
İş için doğru dil! Lol
DJMcMayhem

6

Jöle , 14 bayt

=”\ðḤ’+\_⁸⁶ẋżY

Sonucu basan tam bir program.

Çevrimiçi deneyin!

Nasıl?

=”\ðḤ’+\_⁸⁶ẋżY - Link: list of characters, s    e.g. "\\\//\\/"
 ”\            - literal '\'                         '\'
=              - equal? (call this e)                [1, 1, 1, 0, 0, 1, 1, 0]
   ð           - new dyadic chain f(e, s)
    Ḥ          - double                              [2, 2, 2, 0, 0, 2, 2, 0]
     ’         - decrement                           [1, 1, 1,-1,-1, 1, 1,-1]
      +\       - cumulative reduce with addition     [1, 2, 3, 2, 1, 2, 3, 2]
         ⁸     - chain's left argument, e            [1, 1, 1, 0, 0, 1, 1, 0]
        _      - subtract (# of leading spaces)      [0, 1, 2, 2, 1, 1, 2, 2]
          ⁶    - literal ' '                         ''
           ẋ   - repeat                              [""," ","  "," "," "," ","  ","  "]
            ż  - zip with s                          [["",'\'],[" ",'\'],["  ",'\'],["  ",'/'],[" ",'/'],[" ",'\'],["  ",'\'],["  ",'/']]
             Y - join with newlines                  ["",'\','\n'," ",'\','\n',"  ",'\','\n',"  ",'/','\n'," ",'/','\n'," ",'\','\n',"  ",'\','\n',"  ",'/']
               - implicit print - this smashes the lists (shown as "..." above) and the characters (shown as '...' above) together.



5

JavaScript (ES8), 66 59 63 bayt

Düzeltmek için Justin Mariner
+4 bayt sayesinde 7 bayt kaydedildi /\\/\\/( Neil tarafından fark edildi )

f=([a,...z],b=a<'0')=>a?a.padStart(b+=k=a>'/')+`
`+f(z,b-!k):''

Çevrimiçi deneyin!


5

MATL , 23 19 18 bayt

@Sanchises sayesinde 1 bayt kapalı

fGqoEq1yd~h*YsGZ?c

Giriş, tek tırnak içine alınmış bir dizedir.

Çevrimiçi deneyin! Veya test durumlarını doğrulayın: 1 , 2 , 3 .

açıklama

'\\\//\/\\'Bir örnek olarak girişi düşünün .

f      % Implicit input. Array of indices of nonzeros. Since all chars in the input
       % have nonzero code point, this gives [1 2 ... n] where n is input length
       % STACK: [1 2 3 4 5 6 7 8 9]
G      % Push input again
       % STACK: [1 2 3 4 5 6 7 8 9], '\\\//\/\\'
qo     % Subtract 1 from (the code-point) of each char and then compute modulo 2.
       % This transforms '\' into 1 and '/' into 0
       % STACK: [1 2 3 4 5 6 7 8 9], [1 1 1 0 0 1 0 1 1]
Eq     % Double, subtract 1. This transforms 0 into -1
       % STACK: [1 2 3 4 5 6 7 8 9], [1 1 1 -1 -1 1 -1 1 1]
1y     % Push 1 and duplicate from below
       % STACK: [1 2 3 4 5 6 7 8 9], [1 1 1 -1 -1 1 -1 1 1], 1, [1 1 1 -1 -1 1 -1 1 1]
d~     % Consecutive differences, logical negation: gives 1 if consecutive entries
       % are equal, 0 otherwise
       % STACK: [1 2 3 4 5 6 7 8 9], [1 1 1 -1 -1 1 -1 1 1], 1, [1 1 0 1 0 0 0 1]
h      % Horizontally concatenate
       % STACK: [1 2 3 4 5 6 7 8 9], [1 1 1 -1 -1 1 -1 1 1], [1 1 1 0 1 0 0 0 1]
*      % Element-wise multiplication
       % STACK: [1 2 3 4 5 6 7 8 9], [1 1 1 0 -1 0 0 0 1]
Ys     % Cumulative sum
       % STACK: [1 2 3 4 5 6 7 8 9], [1 2 3 3 2 2 2 2 3]
G      % Push input again
       % STACK: [1 2 3 4 5 6 7 8 9], [1 2 3 3 2 2 2 2 3], '\\\//\/\\'
Z?     % Build sparse matrix with those row indices, column indices, and values
       % STACK: [92  0  0;
                  0 92  0;
                  0  0 92;
                  0  0 47;
                  0 47  0;
                  0 92  0;
                  0 47  0;
                  0 92  0;
                  0  0 92]
c      % Convert to char. Char 0 is shown as space. Implicitly display
       % STACK: ['\  ';
                 ' \ ';
                 '  \';
                 '  /';
                 ' / ';
                 ' \ ';
                 ' / ';
                 ' \ ';
                 '  \']

Endekslerinizi almak için biraz farklı bir algoritmayla bir bayt: Çevrimiçi deneyin!
21'de Sanchises

@Sanchises Çok uygun düzenlemeleriniz için teşekkürler!
Luis Mendo

5

C # (.NET Core) , 74 88 82 78 77 76 + 18 bayt

Kevin Cruijssen sayesinde -1 bayt

s=>s.Select((x,i)=>$"{x}".PadLeft((x-s[0])/45-~s.Take(i).Sum(y=>y<92?-1:1)))

Her satır için bir tane olmak üzere bir dizi dizgi çıkarır. Bayt sayısı ayrıca şunları içerir:

using System.Linq;

Çevrimiçi deneyin!

77 baytlık cevap için açıklama:

s =>                              // Take input, a string
    s.Select((x, i) =>            // Replace every character with:
        $"{x}"                    //     The character as string
        .PadLeft(                 //     Pad with this many spaces:
            s.Take(i)             //         Take characters, in the input string, preceding current one
            .Sum(y =>             //         Sum them by:
                y < 92 ? -1 : 1   //             If it's a \ add 1, if / subtract 1
            )
            + (x - s[0]) / 45 + 1 //         If first slash is a / add one more space, if current slash is a \ add one more space (I got this through power of MATHS!)
                                  //         How I arrived at this function:
                                  //         + x / 48        If current slash is a \ add one more space
                                  //         - s[0] / 48 + 1 If the first slash is a / add one more space
        )
    )

3
İçin çalışmıyor /\\/\\/.
Neil

@Neil bunu belirttiğiniz için teşekkür ederiz! Sabit.
Grzegorz Puławski

1
Bunun bir süre oldu biliyorum ama değiştirerek byte kaydedebilirsiniz s.Take(i).Sum(y=>y<92?-1:1)+(x-s[0])/45+1için(x-s[0])/45-~s.Take(i).Sum(y=>y<92?-1:1)
Kevin Cruijssen

@KevinCruijssen!
Grzegorz Puławski

4

05AB1E , 14 bayt

ÇÈx<ηOs-W-ISú»

Çevrimiçi deneyin!

açıklama

Ç                # convert input string to a list of ascii codes
 È               # check each for evenness
  x              # push a doubled copy
   <             # decrement
    η            # compute prefixes
     O           # sum each prefix
      s          # swap the unaltered copy of evenness to the top
       -         # subtract from the prefix-sum list
        W-       # subtract the minimum value
          IS     # push input split to a list of chars
            ú    # pad each with the number of spaces computed
             »   # join on newline

1
İçin çalışmıyor /\\/\\/.
Neil

Ç¥.¥0<.SηOv¹Nèy<ú, ikili olarak hıçkırarak hıçkırarak
Magic Octopus Urn

3

R , 122 121 bayt

Giuseppe sayesinde -1 bayt

x=el(strsplit(scan(,""),""));n=seq(x);y=x>"/";for(i in n)cat(rep(" ",diffinv(y[n[-1]-1]+y[n[-1]]-1)[i]),x[i],"\n",sep="")

Çevrimiçi deneyin!

Ekstra boşluk ile:

x = el(strsplit(scan(,""),""))
n = seq(x)
y = x>"/"
for(i in n) {
  cat(rep(" ", diffinv(y[n[-1]-1]+y[n[-1]]-1)[i]), x[i], "\n", sep="")
}

Açıklama: Bu cevap, satır aralığı sayısının her satırın -1, artı sayının değiştiğini gözlemlemeye dayanmaktadır. / önceki ve geçerli satırların .

Eğer N eğik çizgilerimiz varsa, değişken yN uzunluklu bir vektördür, her pozisyon için 1 \, aksi halde 0. Bu nedenle, satır başına öncül alan sayısındaki değişikliği almak için hesaplıyoruz y[1:(N-1)] + y[2:N] - 1. İşlev diffinv, bu farkları, 0 ile başlayan bir diziye dönüştürür. Gerisi, her bir çizgiyi gerekli sayıda takip alanı olarak monte etmekten ibarettir, ardından ilgili eğik çizgi ve yeni bir satır izler.


1
ha. 119 bayt için oldukça farklı bir yaklaşım kullandım, bu da yaklaşımlarımızı birleştirip birleştiremeyeceğimi merak etmeme neden oldu. (güzel kullanım diffinv;) Ayrıca y=x>")"-1 bayt için ayarlayabilirsiniz
Giuseppe

@Giuseppe Ayrı bir cevap olarak, yeterince farklı bir yaklaşım olduğunu belirtmelisiniz. Sizinki strsplither zaman bir katil olan yapmak zorunda kalmamak için güzel bir yol . Ayrıca ünlülerden de yararlanabilirsiniz diffinv!
user2390246 14:17

1
Ayrıca, eğer library(methods)başlığa koyarsanız (ki bu R paketinin R tabanından dolayı ceza içermemesi gerektiği için), kullanabileceğinizi düşünüyorum el. Ayrıca, diffinvsadece olduğu kadar çıktı cumsum! :)
Giuseppe

Evet, sadece çok, o bağlam içinde oldukça işe yaramaz, fark edildi
user2390246

bir çözüm buldum ama evet, bu *Sişleri mahvetti.
Giuseppe

3

Brain-Flak , 175 bayt (174 karakter + 1 bayrak)

-cBayrak ile çalıştırın .

{(({})<(())>){({}[()]<([{}])>)}{}(({}<>{}<><({}<>)((()()()()()){})>)<{({}[()]<((((()()()()){}){}){})>)}>{})<>}<>{}{({}<>)(({})(())){({}[()]<([{}]())>)}{}{<>{}<>(<{}>)}{}<>}<>

Çevrimiçi deneyin!

açıklama

{ for each char in the input...
  (({})<(())>){({}[()]<([{}])>)}{} push 1/-1 for backslash/slash
  ((
   {}<>{}<> add the 1/-1 to a running total
   <
    ({}<>) move slash/backslash to other stack
    ((()()()()()){}) newline
   >
  )<{({}[()]<((((()()()()){}){}){})>)}>{}) spaces
  <>
}<>{} end for
reverse data order, removing one space before backslash
{({}<>)(({})(())){({}[()]<([{}]())>)}{}{<>{}<>(<{}>)}{}<>}<>

Beyin flakasını her zaman büyütürüm. : D
DJMcMayhem

3

Ruby , 80 76 bayt

Manatwork sayesinde -4 bayt

puts"\\";$*[i=0].chars.each_cons 2{|b,c|puts" "*(b==c ?b==?/?i-=1:i+=1:i)+c}

Çevrimiçi deneyin!

Açıklama:

puts "\\"           # Output the first backslash
$*[i=0].            # Get the first argument and set i to 0
chars.              # Go through every individual character,
each_cons 2 { |b,c| # In pairs to compare easily
                    #
    puts " " *      # Decide how many padding spaces to use based on the value
                    # of i. The expression inside the parenthesis will return
                    # i but before that, it will increment/decrement i based
                    # on what the previous character was.
                        #
    ( b==c ?            # if b == c
        b==?/ ?         #   if b == "/" (Going to the left)
            i-=1        #       return decremented i
            :           #   else        (Going to the right)
            i+=1        #       return incremented i
        :               # else
        i) +            #   return i
                    #
                c   # Finally, write the second of the characters that we're
}                   # iterating through.

1
Hangi Ruby versiyonu? Kod bloğu izlediğinde ben 2.3.3 parametresi etrafına parantez gerektiriyor: .each_cons(2){…}. Değişiklikte .each_char→ değiştirerek tasarruf edebilirsiniz .chars.
Manatwork

@ manatwork Yakut versiyonum 2.4.1. Karakter hakkındaki öneri için teşekkürler, bunu bilmiyordum.
Pazzaz

i+=Yuvalanmış üçlü ifadenin başlangıcına gidip ile bitirerek başka bir iki bayt kaydedebilirsiniz -1:1:0.
benj2240

3

Java 8, 121 118 110 109 102 bayt

a->{String r="";int s=0,p=0,i;for(char c:a){for(i=s+=p+(p=c-63)>>5;i-->0;r+=" ");r+=c+"\n";}return r;}

-7 bayt @Nevay 'ın bit-bilge büyüsü sayesinde. :)

Açıklama:

Burada dene.

a->{                    // Method with char-array parameter and String return-type
  String r="";          //  Return-String
  int s=0,              //  Amount of spaces
      p=0,              //  Previous characters (starting at 0)
      i;                //  Index-integer
  for(char c:a){        //  Loop over the input
    for(i=s+=p+(p=c-63)>>5;
                        //   If the current does not equals the previous character
                        //    Leave `s` the same
                        //   Else-if it's a '\':
                        //    Increase `s` by 1
                        //   Else (it's a '/'):
                        //    Decrease `s` by 1
                        //   And set the previous character to the current in the process
        i-->0;r+=" ");  //   Append `r` with `s` amount of spaces               
    r+=c+"\n";          //   Append the character + a new-line to the result
  }                     //  End of loop
  return r;             //  Return result-String
}                       // End of method

1
102 bayt:a->{String r="";int s=0,p=0,i;for(char c:a){for(i=s+=p+(p=c-63)>>5;i-->0;r+=" ");r+=c+"\n";}return r;}
Nevay

@ Nevay Teşekkürler. Bitsel işlemlerle kısaltılabileceğini biliyordum, ancak çözemedi. Ben etkilerini çalışıyor unuttuk başlıca nedeni >>/ >>>/ <<... Ben sadece bazı şeyleri kontrol vardı &/ |/ ~/ ^. ..>>
Kevin Cruijssen

3

C (GCC), 137 134 97 bayt

Çevrimiçi deneyin!

• 3 byte teşekkürler ATaco

• Digital Trauma & ThePirateBay sayesinde 37 byte

i,d;f(char*s){char c=s[i],n=s[++i];if(c){printf("%*c%c\n",d+1,c);(c-n)?d:(c==47)?--d:++d;f(s);}}

Çok fazla bir şey bir dize alan ve eğik çizgileri basan basit bir özyinelemeli işlev değildir, girişin önce ters eğik çizgiden kaçması gerektiğini unutmayın.

kullanım

f("\\\\\\//\\/\\\\",0,0);

Ungolfed

Bu eski cevap içindir, güncellenmiş olanın çevrimiçi denemesine bakın!

f(char *s, i, d) {
    char c=s[i], n=s[++i];
    if(!c) return;
    for(int j=0; j<d; j++) printf(" ");
    printf("%c\n",c);
    f(s, i, (c!=n)?d:(c=='/')?d-1:d+1);
}

Çıktı

görüntü tanımını buraya girin


Aynı etki için c=='\0'ile değiştirebilirsiniz !c.
ATaco 14:17

Müthiş teşekkürler sadece çözümü güncellendi!
Uykuda,

printf("%*s%c", n, "", c)Karakteri öndeki boşluklarla yazdırmak için kullanabilir misiniz ?
Dijital Travma

Sana değiştirerek birkaç byte kaydedebilirsiniz eminim (c!=n)ile c-nve üçlü ifadeleri yeniden düzenleme. İle aynı (c=='/'). Ayrıca, '/'değişmez sayı ile değiştirebilirsiniz 47. Toplam 7 bayt olduğunu düşünüyorum.



3

Retina , 47 bayt

^|\\
 $&
+m`^( *)( /|\\)(/| \\)
$1$2¶$1$3
m`^ 

Çevrimiçi deneyin! Link, test durumlarını içerir. Açıklama:

^|\\
 $&

Her satırın başına ve her birinden önce bir boşluk ekleyin \.

+m`^( *)( /|\\)(/| \\)
$1$2¶$1$3

Dizenin ilk iki karakterini düşünün. Birincisi bir /o zaman girintinin azaltılması gerekir; bu, yakalamaya önceki boşluğu dahil ederek (ilk aşama eklediği için her zaman var olan) sağlanır; ikinci bir ise \\o zaman arttırılması gerekir; bu, yakalamaya ilk aşamada eklenen alan dahil edilerek elde edilir. İkinci karaktere doğru girintiyi verdikten sonra, sahne ikinci ve üçüncü karakter vb. İçin tekrarlanır.

m`^ 

Fazladan girintiyi çıkarın.

(Kömür cevabım gibi) herhangi bir eğik çizgi kombinasyonuna izin veren 94 baytlık bir sürüm yazdım: Çevrimiçi deneyin! Açıklama:

.$
¶$.`$* $&

Son çizgiyi alarak ve kendi çizgisinde aynı konuma getirerek topu yuvarlayın.

/
 /

Tüm eğik çizgilere boşluk eklenmesi, böylece yakalanabilmelerini sağlar.

+`^(.*)( /|\\)¶( *)( \\|/)
$1¶$3$2¶$3$4

Girişin son kısmını tekrar tekrar alın ve aşağıdaki satırdaki eğik çizgiyle kendi çizgisine hizalayın.

+ms`^(?<!^[\\/].*) (?!.*^[\\/])

Kalan girintileri silin.

G`.

Şimdi boş girişi silin.


2

Lua , 96 bayt

c=0 for s in(...):gmatch(".")do c=c+(p==s and(s=="/"and-1or 1)or 0)p=s print((" "):rep(c)..s)end

Çevrimiçi deneyin!

Lua'da bulabildiğim en kısa olanı. Giriş komut satırından alınır.

Bu birkaç püf noktası kullanır:

  1. (...):gmatch(
    Bu komut satırından Lua programına tek bir dize girmenin en kısa şekli olmalıdır. ...Lua ifade işlev bildiriminde belirtilmeyen ve varargs için kullanılan bir işleve fazlalık parametreleri yakalar. Bir Lua programının ana gövdesi, komut satırı argümanları ile parametreleri olarak işlev olarak adlandırıldığından, komut satırı argümanları sona erecektir ....
    Etrafındaki parantezler, potansiyel olarak çok değerli ...ifadeyi tek değerli ifadeye dönüştürür. Şunu düşünün (biraz şaşırtıcı) örnek:
    function multipleReturnValues()
        return "abc", "def"
    end
    print(  multipleReturnValues()  ) --This prints: abc    def
    print( (multipleReturnValues()) ) --This prints: abc
  2. Lua ayrıştırıcısının, iki ifadenin belirteçleri açıkça ayrılabildiği ve Lua kodunun geçerli olduğu metnin yalnızca bir yorumu olduğu sürece, herhangi bir satır sonlandırıcısına ve hatta ifadeler arasındaki boşluklara gerek duymaz.
  3. Kötüye and/ ormantığını "x sonra başka deger2 deger1 eğer" için.
    Lua en andçok falsy ise operatör ilk argüman döndürür; Aksi takdirde ikinci argümanını döndürür. orO truthy ise operatör ilk argüman döndürür; Aksi takdirde, ikinci argüman.
  4. pbaşlatma gerektirmez.
    p==sgiriş ne olursa olsun, döngünün ilk çalışmasında her zaman yanlış olması gerekir. Döngüye pgirmeden önce herhangi bir değere ayarlanmamak (bırakarak nil) bunu gerçekleştirir ve baytları da kaydeder.

Bunu golf yapan var mı (Lua'da)?


İki bayt gmub kullanmak yerine gsub kullanarak kaydedebildim. c=0(...):gsub(".",function(s)c=c+(p==s and(s=="/"and-1or 1)or 0)p=s print((" "):rep(c)..s)end)
QuertyKeyboard

Önemli değil. Kolayca değiştirerek iki bayt kurtarabilirdim gmatch(".")için gmatch"."bir sonraki cevap yaptığı gibi.
QuertyKeyboard 14:17

@QuertyKeyboard Bu çok garip ... Aslında bu kodun ilk sürümünde tam olarak bu şekilde gsub kullandım, ancak daha sonra bir şekilde kısaldığı için gmatch'a geçtim. Neyi farklı yaptım bilemiyorum, maalesef dosyanın üzerine yazılmış.
Jonathan S.,


2

R , 119 bayt

function(s)for(i in 1:nchar(s))cat(rep(" ",cumsum(c(0,!diff(S<-(utf8ToInt(s)>48)*2-1))*S)[i]),substr(s,i,i),"
",sep="")

Çevrimiçi deneyin!

Bu kullanıcı2390246'nın cevabından biraz farklıdır . Her biri, dize üzerinde yinelenerek belirli sayıda boşluk karakteri ve ardından uygun/\ karakteri .

Bununla birlikte, karakterleri UTF-8 kodlama değerleriyle değiştirmeyi tercih ederek dizeyi bölmekten kaçındım, bu da doğrudan sayılar üzerinde aritmetik işlem yapmamı sağladı, bu da beni sadece birkaç bayt kurtardı.


Sadece biraz daha düşünmek, algoritmada bir hata olduğunu düşünüyorum: TIO
kullanıcı2390246

@ user2390246 Düzeltdim! Bazı yanlış yerleştirilmiş parantezlerim vardı, ancak şimdi diffinvkesinlikle burada çalışmaz.
Giuseppe


2

C # (.NET Core) , 60/65 bayt

Daha kısa C # sürümünü denedim

s=>{int i=0;return s.Select(x=>"".PadLeft(x<92?--i:i++)+x);}

belirtildiği gibi: "Bu, aynı zamanda her girişin ters eğik çizgiyle başlayacağı anlamına gelir." Veya "/" ile başlayan çözelti biraz daha uzun

s=>{int i=s[0]&1;return s.Select(x=>"".PadLeft(x<92?--i:i++)+x);}

Çevrimiçi deneyin!


Siteye Hoşgeldiniz! :)
DJMcMayhem

2

Lua , 88 84 bayt

Geliştirilmiş sürüm (QuertyKeyboard sayesinde -4 bayt)

s=""g=s.gsub g(...,".",function(c)s=g(g(g(s,"\\"," "),"/?$",c)," /","/")print(s)end)

Çevrimiçi deneyin!

Orijinal versiyon (88 bayt)

Lua'da bir başka deneme, bu sefer bir sayaç değişkeni yerine string manipülasyonu kullanarak tamamen farklı bir yaklaşımla.

s=""for c in(...):gmatch"."do s=s:gsub("\\"," "):gsub("/?$",c):gsub(" /","/")print(s)end

Ungolfed:

s = ""
for c in string.gmatch((...), ".") do --for each character in the input
  --s contains the output from the previous iteration
  s = s:gsub("\\", " ") --Replace backslash with space -> indent by 1
  s = s:gsub("/?$", c) --Remove any / at the end of the string and append c to the string
  s = s:gsub(" /", "/") --Remove a single space in front of any / -> un-indent by 1
  print(s)
end

Kodda ilginç bir şey var: (...):gmatch"."
Bu Lua ayrıştırıcısında bazı tuhaflıklar kullanıyor. Lua, formda bir kod parçasıyla karşılaştığında func "string", bunu buna dönüştürür func("string"). Bu, print "string"sabit bir dize yazdırmak için yazılabilmesi ve işlevden sonra yalnızca tek bir dize ile çalışabilmesidir. Başka bir şey bir sözdizimi hatası verecektir. Bununla birlikte, bu sözdizimsel şeker aynı zamanda bir ifadenin ortasındaki işlev çağrılarıyla da çalışır ve daha da şaşırtıcı olanı :sözdizimsel şeker çağrısı yöntemi ile birlikte çok iyi çalışır . Sonunda, Lua kodu şöyle yorumlar:

(...):gmatch"."
-> (...):gmatch(".")
-> string.gmatch((...), ".")

Birisi üç gsub çağrısından birini çıkarmanın bir yolunu düşünebilirse, lütfen bana söyle.


1
Diğer cevabınıza yazdığım gsub numaramın bunun için işe yaramadığını öğrendiğimde hayal kırıklığına uğradım. Aslında bir bayt ekleyerek sona erdi. Ancak bu kadar kolay pes etmem. İlk önce, kodu kısaltmak için bir değişken olarak gsub'u saklamaya çalıştım. Sürprizime göre, kodum tamamen aynı miktarda bayttı - 88. Ancak, gsub kaydedilirken gsub numaramın işe yarayabileceğini anladım! İşte benim 4 byte traş s=""g=s.gsub g(...,".",function(c)s=g(g(g(s,"\\"," "),"/?$",c)," /","/")print(s)end)
kodum

@QuertyKeyboard Yup, gsub'u döngüden önce bir değişkende saklamayı ve sonra üç kez gsub yazmak yerine onu kullanmayı denedim ve kesinlikle hiçbir fark yaratmadığını görünce şaşırdım. "Döngü yerine" gsub "ve" mağaza gsub "hilelerini birleştirmek gerçekten çok iyi bir şey değildi! Teşekkürler! :)
Jonathan S.


1

Perl, 40 + 2 bayt

/\//&&$.--,say($"x$.,$_),/\\/&&$.++for@F

-FBayrağa ihtiyacın var .


1

Perl, 34 38 + 1 bayt

iki davayı ele almak

s,(/)|.,$"x($1?$c&&--$c:$c++).$&.$/,ge

-pseçeneğiyle çalıştırılmak

s,(/)|.,$"x($1?--$c:$c++).$&.$/,ge

EDIT: ilk yorumu, aşağıdaki yorumu çalışmıyor /

s,(/)|.,$"x($1?$c--:++$c).$&.$/,ge

Ancak, eğer ilk karakter ise çıktı, sağdaki bir karakterden kaydırılır. \


1
İçin çalışmıyor /\\/\\/.
Neil

Güncellenen soru ile orijinal 34çözümünüz şimdi mükemmel bir şekilde geçerlidir
Ton Hospel

1

VBA (Excel), 181 bayt

Sub q()
a = Cells(1, 1)
For x = 1 To Len(a)
c = Mid(a, x, 1)
If c = "\" Then: Debug.Print b & c: b = b + " "
If c = "/" Then: b = Left(b, Len(b) - 1): Debug.Print b & c
Next
End Sub

1
Excel VBA'nın otomatik biçimlendirici doğasından yararlanarak ve [...]gösterim kullanarak algoritmanızı değiştirmeden bunu önemli ölçüde golf oynayabilirsiniz : Onu 128 Byte'a indirdim Sub q For x=1To[Len(A1)] c=Mid([A1],x,1) If c="\"Then Debug.?b;c:b=b+" " If c="/"Then b=Left(b,Len(b)-1):Debug.?b;c Next End Sub
Taylor Scott

Senaryoyu yazdığın için teşekkürler. Bundan bir şey öğrendim ve gelecekte geçerli olacak. :) Verileri doğrudan hücrelere almak için kullanabileceğimi bilmiyordum. Tekrar teşekkürler :)
Remoel



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.