Ok tuşlarıyla metin içinde gezinme


11

Arka fon

Çoğu (yarım iyi) metin editörleri ok tuşlarını kullanarak metin içinde gezinmenizi sağlar. Yukarı ve aşağı çizgiler arasında gezinmenize izin verirken, sola ve sağa bir çizgi boyunca hareket ederken aynı zamanda etrafı sarar. Ayrıca, satır imlecinizin X konumundan daha kısaysa, imleç satırın sonunda görünür ancak yukarı veya aşağı hareket etmeye devam ederseniz aynı X konumuna geri döner. Belki de aşağıdaki görsel açıklama yardımcı olacaktır:

Hareket Örnekleri

Basit bir metin örneği şöyle görünebilir. İmleç, bu metindeki iki karakter arasına veya sonuna eklenir.

-----
---
------

let's put the cursor here:

X-----
---
------

move down (v):

-----
X---
------

move left (<):

-----X
---
------

v

-----
---X
------

v (notice how the X position of the cursor has been maintained)

-----
---
-----X-

^

-----
---X
------

>  (more line wrapping)

-----
---
X------

<

-----
---X
------

^ (the X-position from earlier is no longer maintained due to the left-right motion)

---X--
---
------

Meydan okuma

ASCII testinin birkaç satırı verildiğinde, başlangıç ​​konumundan bitiş konumuna en kısa yolu bulun. Başlangıç ​​konumu ile gösterilir ^ve bitiş konumu ile gösterilir $ve her birinden yalnızca bir tane olur. Bunlar metnin bir parçası sayılmaz ve bu satırın "uzunluğuna" katkıda bulunmaz.

Giriş, boş olmayan birkaç metin satırından oluşacaktır. Çıktı ^v<>, en kısa yollardan birini gösteren bir dizi karakter olacaktır . İsteğe bağlı olarak her birinin sonunda ek bir yeni satır olduğunu varsayabilirsiniz, ancak bu, gezilebilir metnin bir parçası olarak dahil edilmez.

Bir program veya adlandırılmış işlev yazabilirsiniz. Kazanan, bayt cinsinden ölçülen en kısa gönderim olacaktır.

Örnek G / Ç

^Squares
are
fun$ny

vv<v  (which is better than the naive vv>>>)

Squares
^are
funny$

<vv

Alp$habet^
Song

v<^

Mary had a little lamb,
His fleece was white as snow,
And$ everywhere that ^Mary went,
The lamb was sure to go.

^^>>>>v>>>

$^degenerate case

(no output)

"İmleç, bu metindeki iki karakter arasına veya sonuna eklenecek" - imleci ilk örnekte başlangıca yerleştirmeye devam ediyor
aditsu quit çünkü SE 4

Her çizginin iki ucu vardır. "Bir son" olarak düzenlendi.
PhiNotPi

Vim oklara izin verir. AIX kutumda gerçek bir vi yok (başlangıç ​​dosyama harita ifadeleri ekledim). "halfway decent" ... evet
Jerry Jeremiah

İlk örneğin çıktısı da olabilir v<vv, değil mi? Yoksa bu satırdaki son karakterden sonra mı biter?
mbomb007

@ mbomb007 Satırın son karakterinden sonra sona erer.
PhiNotPi

Yanıtlar:


7

CJam, 139 bayt

Pekala, bu işlemin hissettirdiği bir şeye gelmesi saatler sürdü. CJam kodunu agresif bir şekilde optimize etmek için geçen süre , kodun boyutuna göre O (n) ' den daha büyük bir şey gibi hissettiriyor ...

Şunları yapabilirsiniz çevrimiçi denemek , ancak herhangi bir giriş için hangi iyi yolu en az 6 operasyonları olduğu kadar, muhtemelen gerektiğini çevrimdışı denemek daha hızlı tercüman.

ezilmiş:

q_'$-_'^-:T;'^#\'^-'$#W{)2$5Y$5b+{:D[L"_T<W%_N#)_@>N+N#X-Ue>+-"_"W%-U"--2'<t2'>t'++'(')]=~0e>T,e<D3/1$T<N\+W%N#X?:X;}/2$-}g5b{" ^v<>"=}%]W=

Genişletilmiş ve yorum yapılan:

q               "Read the input";
_'$-            "Remove the end marker";
_'^-:T;         "Remove the start marker and save the text";
'^#             "With only the end marker removed, locate the start marker";
\'^-'$#         "With only the start marker removed, locate the end marker";
W               "Initialize the path number to -1";
{               "Do...";
  )               "Increment the path number";
  2$              "Initialize the cursor position to that of the start marker";
  5Y$5b+          "Convert the path number to base 5, then add a leading 5
                   (the leading 5 will act to initialize the column memory)";
  {:D             "For each digit in the path digit string:";
    [               "Begin cases:";
      L               "0: Do nothing";
      "_T<W%_N#)_@>N+N#X-Ue>+-"
"REFS: [   1   ][  2  ][ 3 ]45
                       1: [1] Calculate the distance to the end of the previous
                              line (0 if no such line)
                          [2] Calculate the length of the previous line (0 if
                              no such line)
                          [3] Calculate the distance to move backwards in the
                              previous line as the maximum of the length of the
                              previous line minus the column memory and 0
                          [4] Calculate the total distance to move as the sum 
                              of [1] and [3]
                          [5] Subtract [4] from the cursor position";
      _"W%-U"-        "2: Start with a base of the logic of case 1, but with a
                          few operations adjusted.";
      -2'<t2'>t       "   [1] Calculate the distance to the *start* of the
                              *next* line (0 if no such line)
                          [2] Calculate the length of the *next* line (0 if no
                              such line)
                          [3] Calculate the distance to move *forwards* in the
                              *next* line as the *minimum* of the length of the
                              *next line* and *the column memory*
                          [4] Calculate the total distance to move as the sum 
                              of [1] and [3]";
      '++             "   [5] *Add* [4] *to* the cursor position";
      '(              "3: Decrement the cursor position";
      ')              "4: Increment the cursor position";
    ]=~             "Execute the case corresponding to the path digit mod 5";
    0e>T,e<         "Clamp the cursor position to [0, text length]";
    D3/             "Check if the path digit is not 0, 1, or 2...";
    1$T<N\+W%N#     "Calculate the current column";
    X?:X;           "If the above check succeeded, update the column memory";
  }/              "End for each";
  2$-             "Subtract the end marker position from the cursor position";
}g              "... While the above subtraction is nonzero";
5b              "Convert the path number to base 5";
{" ^v<>"=}%     "Map each digit in the path string to its operation symbol";
]W=             "Clean up";

Genel olarak, bu oldukça basit bir çözümdür. Bir yol çalışana kadar 0 ile başlayarak her yinelemede artırılan bir yol numarasının base-5 temsilini rakamlarını "yürütür". Rakamlar 1- 4yukarı, aşağı, sol ve sağdaki işlemlerle eşleşir ve 0hiçbir şey yapmaz. Bir yol kullanan ilk yineleme 0dejenere durumu yakalar. A içeren diğer tüm yollar 0hiçbir zaman seçilmez, çünkü bunlar zaten eklenmiş op olmayan ekleri olan önceden test edilmiş yolların sürümleridir.

Durum mümkün olduğunca minimal bir şekilde modellenmiştir: başlangıç ​​ve bitiş işaretleyicileri kaldırılmış metin, metindeki imleç konumu ve "sütun belleği". Yeni satırlar çoğunlukla diğer karakterler gibi ele alınır, bu nedenle bir satır kavramı yoktur ve imleç konumu sadece bir indekstir. Bu, sol ve sağ ölüleri hareket ettirmeyi basitleştirir, bu sadece azalma ve artış olarak uygulanır (metnin boyutuna kenetlenerek). Yukarı ve aşağı hareket etmek biraz daha zordur, ancak yine de yönetilebilir.

Kodun yeniden kullanımı oldukça hayati bir optimizasyon taktiğiydi. Buna örnekler:

  • Yukarı doğru hareket etmek için kodun, çalışma zamanında aşağı doğru hareket etmek için kendi kodunu yazmaktan daha az kod üretecek şekilde yazılması. Bu, yukarı hareket etmek ve birkaç karakteri kaldırmak / değiştirmek için kod kopyalayarak yapılır.
  • "Sütun hafızasının" güncellenmesi, işlemin mantığına kodlanmak yerine yol basamağının 3'e bölünmesine bağlı olarak şartlı olarak yapılır. Bu aynı zamanda 5yol dizesinin başlangıcına bir kukla işlem ekleyerek sütun belleğinin başlatılmasına izin verir , bu da 0dairesel dizi indeksleme ve sadece 5 tanımlı işlem olması nedeniyle op-olmayan mantığı kullanır .

Genel olarak, bunun nasıl ortaya çıktığı için çok mutluyum. Bu kesinlikle bugüne kadar bir kod golf cevap koymak en çok iş (bir tweet uygun bir şey için !?). Ancak çalışma süresi oldukça berbat. CJam tam olarak başlamak için en hızlı dil değildir ve bu algoritma O (m * 5 n ) gibi bir karmaşıklığa sahiptir , burada m girişin boyutu ve n de çıktının boyutudur. İyi bir şey hızı sayılmaz!


Güzel :) Ben dolaylı olarak bu konuda çok zaman harcamak yapmak için biraz suçlu hissediyorum: p
aditsu çıkın çünkü SE EVIL

2

Python 2: 446

Q=input().split('\n');
def g(c):l=[l for l in Q if c in l][0];return Q.index(l),l.index(c)
a,b=g('^');c,d=g('$');Q=map(len,Q);Q[a]-=1;Q[c]-=1
if a==c:d-=b<d;b-=d<b
t=-1
while Q:
 l=[];T=t=t+1;x,y,z=a,b,b
 while T:l+=[T%5]*(T%5>0);T/=5
 for T in l:A=":x+=T+T-3;y=min(Q[x],z)";B="x<len(Q)-1";exec"if "+["","x"+A,B+A,"y:y=z=y-1\nelif x:x-=1;y=z=Q[x]","y<Q[x]:y=z=y+1\nelif "+B+":x+=1;y=z=0"][T]
 if(x,y)==(c,d):print''.join(' ^v<>'[x]for x in l);Q=0

Kolay çözüm. Önce geniş bir arama yapıyorum. ttüm farklı yollar üzerinde yinelenir. tTabana dönüştürüyorum 5, ancak yalnızca sıfır olmayan girişleri kullanıyorum. 1yukarı, 2aşağı, 3sol ve 4sağ.

Ben 3 değişkenlerde imlecin yeri tutmak x, yve z. xsatır, ysütun konumu ve z'gizli' sütun konumudur, yukarı veya aşağı giderseniz ve satır çok kısaysa. Birçok ifs karar verir, bir hareket sırasında değişken nasıl değişir.

Ön işleme gerçekten uzundur, ilk 4 satır sadece bu görevi yerine getirir.

Uzun test çantası çok uzun zaman alıyor. Algoritmanın O (N * 5 ^ N) karmaşıklığı vardır, burada N en kısa çözümün uzunluğudur.

Kullanım: Satırları tek bir dize (ayrılan satırlar \n) gibi girin"Alp$habet^\nSong"


1

CJam - 274

Henüz cevap yok? Tamam, işte bir tane :)

qN/_{0:V;{_'^={[UVV]:B;;}{'$={[UV]:E;}{V):V;}?}?}/U):U;}/"^$"f-:,:A;{:X0=[X0=(_A=X2=_@e<\]X?}:U;{:X0=A,(=X[X0=)_A=X2=_@e<\]?}:D;{:X1=[X~;(_]{X0=[X0=(_A=_]X?}?}:L;{:X1=X0=A=={X0=A,(=X[X0=)0_]?}[X~;)_]?}:R;[[BM]]{_{0=2<E=},_{0=1=o0}{;[{"U^DvL<R>"2/\f{[~@1/~@\+@@~\]}~}/]1}?}g;

Mary örneği veya bu boyutta bir şey hariç , http://cjam.aditsu.net/ ... adresinden deneyin , muhtemelen java tercümanını isteyeceksiniz .


1
O NE LAN? 274 !!!!!!
Doktor

@Optimizer hahaha, iyi, üzerinde yeterince zaman harcadım, devam edin ve isterseniz daha fazla golf yapın: p
aditsu çıkın çünkü SE EVIL
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.