Yön veren


15

Meydan okuma

Biraz benzeyen bir arkadaşınıza bir harita verdiniz:

      |
      /
     |
     /
    |
    \
     |
     \
      D

Üstte başlayan ve altta biten basit bir harita. Ne yazık ki, arkadaşın anlamıyor. Haritayı okuyabilmesi için deşifre edebilir misiniz?

Giriş

Giriş oluşan bir karakter dizesidir |, /, \, D, ^, Y, (boşluk) ve yenisatırlar.

  • | aynı sütunda kalmasını söyler.
  • \ sağa ve aşağıya doğru sütuna gitmeyi söyler 1.
  • / sola ve aşağı sütuna gitmeyi söyler 1.
  • D hedefi işaretler.
    • ^ (varsa) yoldaki bir bölünmeyi anlatır.
    • Y(varsa) yolların yeniden birleşmesini anlatır. Bir gibi davranın |.

Giriş, bir tür yol yapacak şekilde düzenlenecektir:

   |
   |
   \
    |
    ^
   / \
  /   |
 D    |

Her zaman iki yol arasında bir boşluk olacaktır ve tüm yollar ya yeniden katılır ya da girdinin son satırına ulaşır. Harita başına yalnızca bir bölünme olacaktır. Giriş haritasının uzunluğunda bir sınır yoktur. Asla ikiden fazla yol olmayacaktır.

Çıktı

Çıktı bir yönlendirme dizisi olmalıdır.

  • " L " hareket etmek Arkadaşınızı söylemelidir L eft ve ileriye 1 adım atmak.
  • " R " hareket etmek Arkadaşınızı söylemelidir R ight ve ileriye 1 adım atmak.
  • " F " arkadaşınıza 1 adım ilerlemesini söylemelidir.

Girdi örnek haritası için çıktı aşağıdaki gibi olacaktır:

F F L F R R R

Arkadaşınızın haritanın üstünden başlayıp haritanın aşağısına baktığını unutmayın. Yönlerini kendi bakış açısından verin. Bir "^" örneği için, programınızın hedefe (D) giden yolu seçebilmesi gerekir. İki yol yeniden birleşirse, programınız |izlenecek en düz yolu (en çok s olanı) seçmelidir . Yol boşluklarla ayrılması gerekir ve son bulmalı ile D .

Örnekler

Giriş

      |
      |
      \
       \
        ^
       / |
      |  |
      \  |
       \ \
        \ \
         \ /
          Y
          D

Çıktı

F F L L L F F F L L R F

En soldaki yol sadece 1 içerdiğinden |, 3 olan en sağdaki yolu kullanırız.


Giriş

\
 |
 /
|
\
 |
 /
D

Çıktı

L F R F L F R

Giriş

    /
   \
    /
   \
    ^
   \ \
    D \

Çıktı

R L R L R L

Diğer detaylar

  • Bu kod golf, yani 19 Ağustos Çarşamba günü en kısa koda sahip olan kişi kazanır.
  • Yapıcı geribildirim hoş geldiniz ve büyük beğeni topluyor.
  • Gizli Hazine Haritası'ndan kısmen ilham alındı
  • Başlığı daha yaratıcı bir şeye dönüştürmekten çekinmeyin.
  • Yaptığım hataları bulursanız, düzeltin.
  • Ve elbette eğlenin.

Teşekkür ederim!

Biraz geç, belki, ama UndefinedFunction JavaScript kazanan kodlama! Katılan herkese teşekkürler. Başka giriş kabul edilmeyecektir.


Hâlâ kapalı görünüyor. İlk örnek L Lolması gerektiğini düşünüyorum L L L. İle Yhala örnek bir 1sonunda var ve aynı zamanda başka hatalar var gibi görünüyor. Haritayı F F R R R F F F R R L Fkuralları doğru anlıyormuş gibi okuyorum .
Martin Ender

@ MartinBüttner, D ile bitirmeniz gerekiyor, sadece 2 L'ye ihtiyacınız olacak. 3 Ls D'
yi geçecekti

2
Bir yol son hatta ulaşmadan önce çıkmaz bir noktaya ulaşabilir mi? Yoksa tüm yollar girdinin son satırına mı ulaşacak?
jrich

@BassetHound orada bir tane olmamalıdır Liçin ^ve iki Liki /? Ve neden örneğin Fsonuna iki tane daha eklediniz Y?
Martin Ender

@ETHproductions Evet.
The_Basset_Hound

Yanıtlar:


5

JavaScript (ES6), 261 248 252 248 212 bayt

Yalnızca bir bölümün desteklenmesi gerektiğinden:

s=>(s=s.replace(/ /g,o="",d=0).split(`
`)).map((v,j)=>{if(v=="^")for(v="/\\";(w=s[++j])&&(x=w[1]);d=x=="D"?1:w[0]=="D"?0:x>"{"?d+1:w[0]>"{"?d-1:d);o+=(p=v[d>0?1:0]||v[0])<"0"?"R ":p<"E"?"":p=="\\"?"L ":"F "})?o:o


Ancak, 240 bayt ve birden fazla bölme ile başa çıkabiliriz:

s=>(s=s.replace(/ /g,o="").split(`
`)).map((v,j)=>{if(!v[1])t=d=0
else if(!t){for(t=1;(w=s[++j])&&(x=w[1]);d=x=="D"?1:w[0]=="D"?0:x>"{"?d+1:w[0]>"{"?d-1:d);o+=d>0?"L ":"R "}o+=(p=v[d>0?1:0])<"0"?"R ":p<"E"||p=="^"?"":p=="\\"?"L ":"F "})?o:o


Her iki program da anonim işlevleri tanımlar.

Kullanmak için, işlevlere f=koddan önce ekleyerek bir ad verin .

Daha sonra,

alert(f(
`   |
   |
   \\
    |
    ^
   / \\
  /   |
 D    |`
))


açıklama

(eski ama yine de aynı kavram. Çoklu bölünmüş çözüm için)

s=>
    //Remove all spaces from the input
    (s=s.replace(/ /g,o="",
                 //Define function c, to convert symbols to directions
                 c=p=>p<"0"?"R ":p<"E"||p=="^"?"":p=="\\"?"L ":"F "
    //Split input into an array by newlines
    ).split(`
`))
    //for each string v in the input array, at index j:
    .map((v,j)=>{
        //if v is only one character long:
        if(!v[1]){
            t=1     //assign t to 1 (true) - we need to test if multiple paths
            d=0     //assign d to 0 - reset the counter for determining shortest path
        }
        //if v is two characters long, and we have not tested which path is shorter yet:
        else if(t){
            for(    t=0;    //assign t to 0 - we will have tested which path is longer

                    //for each string left in the input, while the input still has two characters:
                    (w=s[++j]) && w[1];
                    //assign d to determine which direction to go. This will be conveyed by if d>0
                    d=
                        w[1]=="D"?1:    //if the dest. is only on one side, choose that side.
                        w[0]=="D"?0:
                        w[1]=="|"?d+1:  //otherwise add/subtract from d (like a tug of war) to determine which side has more "|"
                        w[0]=="|"?d-1:
                        d
               );
            o+=d>0?"L ":"R "    //append to the output which direction was taken
        }

        o+=c(v[d>0?1:0])    //append to the output the characters from the correct path in any case, determined by d calculated above 
                            //(or defaulting to 0, if path is not split, in which case the only character is appended)

    }) ? o : o  //coerce the result, which will evaluate to an array of the input, to the output (o) and implicitly return


notlar

  • Girişteki tüm ters eğik çizgiler ( \) \\, javascript'in bunları tanıyabilmesi için olarak kaçar .

  • Her iki çıkış da bir arka boşluk içerir.


Lanet olsun, her şeyi düzelttiğimi düşündüm.
The_Basset_Hound

9

PHP 634 631 607 396 382 381 347 338 330 337 324 bayt

Benim ilk golf kadar nazik olun. Herhangi bir ipucu büyük takdir.

<?php
foreach(str_split(strtr(fgets(STDIN),[' '=>'']))as $i){if($i!=D){$z=$i=='^';$x=$i==Y;$s=!$z&&!$x?($i=='/'?R:($i=='|'?F:($i=='\\'?L:$s))):$s;$a.=$z?R:($x?F:(($c==1||!$c)?$s:''));$b.=$z?L:($x?F:(($c==2||!$c)?$s:''));$c=$z?1:($x?0:($c==1?2:($c==2?1:$c)));}else{echo(substr_count($a,F)<substr_count($b,F)&&$c==0||$c==2)?$b:$a;}}

Kısa Açıklama:
Girişin tek bir yolu varsa 0 olan bir sayım var. Yol bölündüğünde, sayı sol yol için 1 ve sağ yol için 2'dir. Her iki yolu da tanımladıktan sonra (veya sadece bir tane) Hangi yolun daha fazla "F" olduğunu kontrol ederim.

Ungolfed Sürümü:

<?php
$input = fgets(STDIN);
$inputArray = str_split($input);
foreach ($inputArray as $currentChar) {
    if ($currentChar != 'D') {
        if ($i == '^') {
            $firstPath .= 'R';
            $secondPath .= 'L';
            $count = 1;
        } elseif ($i == 'Y') {
            $secondPath .= 'F';
            $firstPath .= 'F';
            $count = 0;
        } else {
            if ($i == ' ') {
                continue;
            }
            if ($i == '/') {
                $direction = 'R';
            } else {
                if ($i == '|') {
                    $direction = 'F';
                } else {
                    if ($i == '\\') {
                        $direction = 'L';
                    } else {
                        $direction = '';
                    }
                }
            }
            if ($count == 1) {
                $firstPath .= $direction;
                $count = 2;
            } elseif ($count == 2) {
                $secondPath .= $direction;
                $count = 1;
            }
            if (!$count) {
                $firstPath .= $direction;
                $secondPath .= $direction;
            }
        }
    } else {
        echo (substr_count($firstPath, 'F') < substr_count($secondPath, 'F')) || $count == 2 ? $secondPath : $firstPath;
    }
};


Kayıt:
Kamehameha sayesinde 36 bayt kurtardı.
Mantığı biraz değiştirerek birçok bayt kaydetti.
Axiac sayesinde 42 bayt kurtardı.
Her if ifadesini üçlü operatörlerle değiştirdi.


3
Siteye Hoşgeldiniz!
isaacg

2
Bunun $a=$b='';yerine deneyebilirsiniz - $a='';$b='';3 bayt civarında tasarruf sağlar.
Kamehameha

1
Ayrıca gibi birleştirme $a=$a.'L ';de azaltılabilir $a.='L '. Bunu birkaç yerde yapmış gibi görünüyorsunuz. Bu yaklaşık 6 bayt tasarruf edecek :)
Kamehameha

1
Ben PHP çok iyi bilmiyorum, ama ben senin foreach ( foreach($e as$i)) sonra "gibi" sonra boşluk bırakabilirsiniz inanıyorum ; Bunu test ettim ve iyi çalışıyor gibi görünüyor.
ProgramFOX

1
@ProgramFox hakkında belirtildiği gibi Birkaç tane daha ipuçları, birkaç byte kaydetmek için asde foreach, arasındaki boşluklar echove değişken adı var bu yüzden hiç kaldırılabilir echo$b. Ayrıca, eşitlik testlerinin bir çift de kısa olabilir $c==0olabilir !$cve eğer durum buysa, sen ilklendirebilirsiniz $ciçin ''birlikte $ave $b!
Dom Hastings

3

PHP, 281 bayt

$b=0;$p=['|'=>'$a[$b].="F ";$f[$b]++;','/'=>'$a[$b].="R ";','\\'=>'$a[$b].="L ";','^'=>'$d.=$a[0];$n=2;$a=["R ","L "];$f=[];$b=1;','Y'=>'$d.=$a[$f[0]<$f[$n=1]]."F ";$a=[];','D'=>'$d.=$a[$b];exit(rtrim($d));'];foreach(str_split($argv[$n=1])as$c){if($x=$p[$c]){eval($x);$b=++$b%$n;}}

İki golf yinelemesinin sonucudur. Çözülmemiş versiyon:

$a=$f=[];       // these assignments are not required (they were suppresed in v2)
$n=1;           // this assignment can be squeezed into $argv[$n=1]
$b=0;           // if this assignment is suppressed $b becomes '' and breaks the logic
$code = [
    '|' => '$a[$b].="F ";$f[$b]++;',
    '/' => '$a[$b].="R ";',
    '\\'=> '$a[$b].="L ";',
    '^' => '$d.=$a[0];$n=2;$a=["R ","L "];$f=[];$b=1;',
    'Y' => '$d.=$a[$f[0]<$f[$n=1]]."F ";$a=[];',
    'D' => '$d.=$a[$b];echo(rtrim($d));',
];
foreach (str_split($argv[1]) as $char) {
    // ignore input characters not in the keys of $code
    if ($x = $code[$char]) {
        eval($x);
        $b = ++ $b % $n;   // cycles between 0 and 1 ($n == 2) or stays 0 ($n == 1)
    }
}

Oldukça golf oynamak ve aşağıdaki golf programı (312 bayt) bir gelişme olarak ortaya çıktı:

$b=0;foreach(str_split($argv[$n=1])as$c){if($c=='|'){$a[$b].='F ';$f[$b]++;}elseif($c=='/'){$a[$b].='R ';}elseif($c=='\\'){$a[$b].='L ';}elseif($c=='^'){$d.=$a[0];$n=2;$a=['R ','L '];$f=[];$b=1;}elseif($c==Y){$d.=$a[$f[0]<$f[$n=1]].'F ';$a=[];}elseif($c==D){$d.=$a[$b];exit(rtrim($d));}else continue;$b=++$b%$n;}

Orijinalin golf versiyonudur:

$map = $argv[1];

$dir = '';              // the already computed directions
$nb = 1;                // the number of branches
$branches = [ '' ];     // the branches (2 while between '^' and 'Y', 1 otherwise)
$nbF = [ 0, 0 ];        // the number of 'F's on the branches (used to select the branch)
$curr = 0;              // the current branch
foreach (str_split($map) as $char) {
    if ($char == '|') {             // go 'F'orward
        $branches[$curr] .= 'F ';       // put it to the current branch
        $nbF[$curr] ++;                 // count it for the current branch
    } elseif ($char == '/') {       // go 'R'ight
        $branches[$curr] .= 'R ';
    } elseif ($char == '\\') {      // go 'L'eft
        $branches[$curr] .= 'L ';
    } elseif ($char == '^') {       // fork; choose the path ('L' or 'R') that contains the most 'F'orward segments
        $dir .= $branches[0];           // flush the current path (it was stored as the first branch)
        $nb = 2;                        // start two branches
        $branches = [ 'R ', 'L ' ];     // put the correct directions on each branch
        $nbF = [ 0, 0 ];                // no 'F's on any branch yet
        $curr = 1;                      // need this to let it be 0 on the next loop
    } elseif ($char == 'Y') {       // join
        $dir .= $branches[$nbF[0] < $nbF[1]];   // flush; choose the branch having the most 'F's
        $dir .= 'F ';                           // treat it like a "|"
        $branches = [ '' ];                     // back to a single, empty branch
        $nb = 1;
    } elseif ($char == 'D') {       // finish
        $dir .= $branches[$curr];       // flush
        break;                          // and exit; could use 'return' but it's one byte longer; use exit() in the final program and save 5 bytes
    } else {
        continue;
    }
    $curr = ++ $curr % $nb;
}
echo rtrim($dir);

Örnek yürütme:

$ php -d error_reporting=0 directions.php '
      |
      |
      \
       \
        ^
       / |
      |  |
      \  |
       \ \
        \ \
         \ /
          Y
          D
'; echo
F F L L L F F F L L R F
$

Aynı zamanda çoklu çatalları doğru şekilde işler (herhangi bir zamanda en fazla iki şubeye sahip olmak için bir sonraki çataldan önce katılmanız gerekir). Bir yorumda birden fazla çatal sordum ama cevap ("gerekli değil") geldiğinde kod zaten yapıldı.

Test takımının tam kodu ve daha fazla yorum github'da bulunabilir .


Vay be iyi iş! Hala birkaç şey öğrenmem gerekiyor!
jrenk
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.