Magrathea 2.0 - Budowanie gór

50

Wraz z wielkim kryzysem gospodarki uniwersalnej spadł również popyt na planety na zamówienie. Magratheanie musieli dbać o bardziej stabilne przychody także od szerszej klasy klientów. Dlatego wymyślili własny łańcuch górski (lub krótkie spustoszenie gór) dla ludzi o mniejszym budżecie, których nie stać na kompletną planetę.

Góry są budowane zgodnie z planem klienta (aka ciągi cyfr i kropek) i dostarczane za pomocą ASCII-art (składające się z , /, \, ^i v).

Zadanie

Napisz kompletny program, który pobiera dane wejściowe (pojedynczy ciąg) ze STDIN lub jako argument i dane wyjściowe do STDOUT. Ta łamigłówka to gra w golfa kodowego, więc proszę pokazać trochę gry w golfa.

Wejście

Ciąg kropek i cyfr stanowiących podstawę łańcucha górskiego. Każdy łańcuch jest dokładnie tak długi, jak to konieczne, aby podeprzeć góry, a każdy szczyt jest oznaczony cyfrą zamiast kropki, wskazując wysokość szczytu.

Wynik

Ascii wersja łańcucha górskiego.

  • Każda cyfra na wejściu reprezentuje dokładnie jeden pik ( ^) na dokładnie wysokości wskazanej przez cyfrę (tj. 9 to najwyższa wysokość).
  • Na wyjściu nie mogą występować dodatkowe piki (tj. W miejscach, gdzie na wejściu jest kropka).
  • Góry mają kształt trójkąta, tzn. Stoki są tworzone za pomocą znaków /i \.
  • Przepustki, w których dwie góry zachodzą na siebie, są kształtowane za pomocą postaci v.
  • Żadnych zbędnych nowych linii ani pustych linii.
  • Linie dopełniające ze spacjami są opcjonalne.

Możesz założyć, że podane dane wejściowe są prawidłowe, tzn. Zawsze istnieje rozwiązanie zgodne z regułami (np. Dane wejściowe 13..nie spowodowałyby prawidłowej konfiguracji i mogą zostać zignorowane). Co więcej, po każdej stronie znajduje się dokładnie tyle kropek, że nie można przycinać gór.

Przykłady

Pierwszy wiersz pokazuje wejście, wszystkie pozostałe wiersze stanowią pożądany wynik. (W rzeczywistości góry wyglądają znacznie lepiej na mojej konsoli niż tutaj.)

1
^

11
^^

1.2.
  ^
^/ \

.2.3..
   ^
 ^/ \
/    \

.2..3..
    ^
 ^ / \
/ v   \

...4...3...3..
   ^
  / \  ^   ^ 
 /   \/ \ / \
/        v   \
Howard
źródło
1
Cóż za połączenie poezji i sztuki! Kocham to.
devnull
Czy drukowanie dodatkowych linii jest w porządku? Innymi słowy, dla wprowadzenia dozwolone 1jest \n\n\n\n\n\n\n\n^?
durron597
@ durron597 Dane wyjściowe nie powinny zawierać zbędnych znaków nowej linii, spójrz na przykłady.
Howard
Co z końcowymi znakami spacji? Czy to w porządku, jeśli wszystkie wiersze są tej samej długości co oryginalny ciąg, wypełnione spacjami?
Paul Prestidge
@Cron Tak, w porządku.
Howard

Odpowiedzi:

11

JavaScript: 272 268 233 232 201 192 189 188 178 180 znaków

Dzięki @Sam za zmniejszenie go z 268 do 233 znaków oraz za @manatwork za kolejny 1 znak. @VadimR za wskazanie błędu.

p=prompt(r=t='');s=' ';for(d=10;d--;r=s+q+s,t+=q.trim()?q+'\n':'')for(q='',i=0;i<p.length;)q+=' \\/v^'[p[i++]==d?4:(/\^|\\/.test(r[i-1])+2*/\^|\//.test(r[i+1]))*(r[i]==s)];alert(t)

Prawidłowo zidentyfikowana i nieco niepoznana wersja z komentarzami:

// The output initialization is just a golfing trick suggested by @manatwork.
input = prompt(state = output = '');
space = ' ';

// Repeat for each line, from the top (the highest peak, highest digit) to the floor (digit 1). Start at 10 to avoid a bug.
for (digit = 10; digit--;

      // Update the state of our automaton, at the end of the iteration.
      // Add a space after and before to simplify the future pattern recognization.
      state = space + line + space,

      // Add the line to the output if it is not an empty line, at the end of the iteration.
      output += line.trim() ? q + '\n' : '')
{ // This curly brace was added for readability, it is not in the golfed source.

  // Analyze each character in the current state to produce a new state, like a cellular automaton.
  for (line = '', i = 0; i < input.length;)
  { // This curly brace was added for readability, it is not in the golfed source.
    line +=

        // If the input is the current digit number, evaluate to 4 and put a peak in this character.
        // Otherwise evaluate this expression with those rules:
        // 1 means that the hill is higher only at right in the previous iteration, we do climb it to the right in this one.
        // 2 means that the hill is higher only at left in the previous iteration, we do climb it to the left in this one.
        // 3 means that the hill is higher at both sides in the previous iteration, we are in a v-shaped valley.
        // 0 means nothing to do here. If the middle is not a space, it will be multiplied by 0 and become 0.
        ' \\/v^'[input[i++] == digit ? 4 : (/\^|\\/.test(state[i - 1]) + 2 * /\^|\//.test(state[i + 1])) * (r[i] == space)];
    } // This curly brace was added for readability, it is not in the golfed source.
} // This curly brace was added for readability, it is not in the golfed source.

// Give the final output.
alert(output);

Jak można zauważyć z kodu, działa to jako automat komórkowy, w którym każda komórka sprawdza liczbę na wejściu, patrzy na siebie i swoich dwóch sąsiadów, aby zdecydować, jaka będzie następna iteracja. W każdej chwili komórka może być ^, /, \, vlub . Dane wejściowe podane w przypadkach testowych dają oczekiwany wynik.

Zauważ, że używanie tego alertpola jest do bani, ponieważ zwykle nie ma czcionki o stałej szerokości. Możesz skopiować i wkleić tekst z alertpola, aby gdzie indziej dla lepszego wzrostu wartości produkcji, czy może zastąpić ostatnią linię alertprzez console.log, ale ponieważ jest to kod-golf, alertjest krótszy.

Ponadto nie sprawdza niczego w danych wejściowych. Po prostu traktuje nierozpoznane znaki jako spacje w taki sam sposób, jak robi to .(w rzeczywistości .jest także nierozpoznaną postacią).

Victor Stafusa
źródło
Istnieje stara sztuczka golfowa polegająca na zmniejszeniu 1 znaku: inicjowanie zmiennych pustym ciągiem jako prompt()parametrem .
manatwork
@manatwork Dziękujemy. Gotowy.
Victor Stafusa
Przepraszam, może coś mi brakuje, ale uzyskuję spójne wyniki zarówno w FF, jak i Chromium. Uruchamiam przeglądarkę, uruchamiam kod JS z wersji 14 i otrzymuję komunikat o błędzie. Następnie uruchamiam kod z wersji 1 - działa OK. Ponownie uruchamiam kod 14 - i bez komunikatu o błędzie, działa OK. Więc nie można uruchomić kodu wersji 14?
user2846289,
1
@VadimR Dzięki, naprawiono. Był to efekt uboczny testowania go w zanieczyszczonym środowisku. Konieczne było prefiksowanie kodu, delete r; delete s; delete q; delete p; delete t; delete i; delete d;aby upewnić się, że nie został on zanieczyszczony.
Victor Stafusa,
q.trim()?q+'\n':''może być q.trim()&&q+'\n', oszczędzając dwa. Ponadto, i<p.lengthmoże po prostu być p[i].
Nicholas Pipitone
6

Rubin, 208 201 189

Bardzo fajne wyzwanie! Oto alternatywne rozwiązanie Ruby.

gets.size.times{|x|0.upto(h=$_[x].to_i-1){|d|r=$*[h-d]||=' '*~/$/
[x+d,x-d].map{|o|r[o]=r[o]>?!??v:o<x ??/:?\\if r[o]<?w}
d<1?r[x]=?^:r[x-d+1,w=2*d-1]=?w*w}}
puts$*.reverse.*($/).tr(?w,' ')

Jako bonus, oto Rubinowa implementacja bardzo sprytnego algorytmu „automatu komórkowego” Victora, składającego się z 162 znaków:

s=gets
9.downto(1){|h|$0=(-1..s.size).map{|x|$_=$0[x,3]
s[x]=="#{h}"??^:~/  [\^\/]/??/:~/[\^\\]  /??\\:~/[\^\\] [\^\/]/??v:' '}*''
$*<<$0[1..-2]if$0=~/\S/}
puts$*

Przykładowe dane wyjściowe:

....5.....6..6.....
          ^  ^
    ^    / \/ \
   / \  /      \
  /   \/        \
 /               \
/                 \
Paul Prestidge
źródło
1
Myślę, że możesz użyć $/do nowej linii.
Howard
4

C # - 588 znaków - nie tak dobre jak 321 Raya!

class P{static void Main(string[] a){char[,] w=new char[a[0].Length+1,10];int x=0;foreach(char c in a[0]){if(c!='.'){int h=int.Parse(c+"");if(w[x,h]=='\0')w[x,h]='^';int s=1;for(int l=h-1;l>0;l--){for(int m=x-s;m<=x+s;m++){if(w[m,l]!='\0'){if(w[m,l]=='^')w[m,l]='/';if(w[m,l]=='\\')w[m,l]='v';}else{if(m==x-s)w[m,l]='/';else if(m==x+s)w[m,l]='\\';else w[m,l]='\0';}bool t=false;for(int f=9;f>0;f--){if(t)w[m,f]='\0';if(w[m,f]!='\0')t=true;}}s++;}}x++;}for(int k=9;k>0;k--){string u="";for(int j=0;j<w.GetLength(0);j++){u+=w[j,k];}if(u.Replace("\0","")!="")System.Console.WriteLine(u);}}}

Przykładowe dane wyjściowe:

F:\>mountains ".2..3..4..."
       ^
    ^ / \
 ^ / v   \
/ v       \

Lub dłuższy, bardziej złożony ...

F:\>mountains ".2..3..6.....5...3......1..3..4....2."
       ^
      / \    ^
     /   \  / \               ^
    /     \/   \ ^         ^ / \
 ^ /            v \       / v   \  ^
/ v                \    ^/       \/ \

Genialna łamigłówka ... nie tak prosta, jak się wydaje ... uwielbiała!

użytkownik17567
źródło
2
„Complex one” jest źle sformułowany, nie ma piku dla „3”.
user2846289
Wszystkie 3są tam. Jeśli mówisz o pierwszym, jest to część stoku.
Hein Wessels
4

APL, 65 bajtów

⍉⌽↑⌽¨h↑¨'^/v\'[1+(~×a)×2+×2+/2-/0,0,⍨h←¯1+⊃⌈/a-↓|∘.-⍨⍳⍴a←11|⎕d⍳⍞]

ten symbol zwraca surowe (nieocenione) dane wejściowe jako tablicę znaków.

Rozwiązywanie interaktywnie w sesji APL:

      s←'...4...3...3..' ⍝ let's use s instead of ⍞
      ⎕d ⍝ the digits
0123456789
      ⎕d⍳s ⍝ the indices of s in ⎕d or 11-s if not found
11 11 11 5 11 11 11 4 11 11 11 4 11 11
      11|⎕d⍳s ⍝ modulo 11, so '.' is 0 instead of 11
0 0 0 5 0 0 0 4 0 0 0 4 0 0
      a←11|⎕d⍳s ⍝ remember it, we'll need it later
      ⍴a ⍝ length of a
14
      ⍳⍴a
1 2 3 4 5 6 7 8 9 10 11 12 13 14
      ⍝ ∘.-    subtraction table
      ⍝ ∘.-⍨A  same as: A ∘.- A
      ⍝ |      absolute value
      |∘.-⍨⍳⍴a
 0  1  2  3 4 5 6 7 8 9 10 11 12 13
 1  0  1  2 3 4 5 6 7 8  9 10 11 12
 2  1  0  1 2 3 4 5 6 7  8  9 10 11
 ...
13 12 11 10 9 8 7 6 5 4  3  2  1  0
      ⍝ ↓      split the above matrix into rows
      ⍝ a-     elements of "a" minus corresponding rows
      ⍝ ⊃⌈/    max them together
      ⊃⌈/a-↓|∘.-⍨⍳⍴a
2 3 4 5 4 3 3 4 3 2 3 4 3 2
      ⍝ This describes the desired landscape,
      ⍝ except that it's a little too high.
      ⍝ Add -1 to correct it:
      ¯1+⊃⌈/a-↓|∘.-⍨⍳⍴a
1 2 3 4 3 2 2 3 2 1 2 3 2 1
      ⍝ Perfect!  Call it "h":
      h←¯1+⊃⌈/a-↓|∘.-⍨⍳⍴a
      0,⍨h ⍝ append a 0 (same as h,0)
1 2 3 4 3 2 2 3 2 1 2 3 2 1 0
      0,0,⍨h ⍝ also prepend a 0
0 1 2 3 4 3 2 2 3 2 1 2 3 2 1 0
      2-/0,0,⍨h ⍝ differences of pairs of consecutive elements
¯1 ¯1 ¯1 ¯1 1 1 0 ¯1 1 1 ¯1 ¯1 1 1 1
      ⍝ this gives us slopes between elements
      2+/2-/0,0,⍨h ⍝ sum pairs: left slope + right slope
¯2 ¯2 ¯2 0 2 1 ¯1 0 2 0 ¯2 0 2 2
      ×2+/2-/0,0,⍨h ⍝ signum of that
¯1 ¯1 ¯1 0 1 1 ¯1 0 1 0 ¯1 0 1 1
      2+×2+/2-/0,0,⍨h ⍝ add 2 to make them suitable for indexing
1 1 1 2 3 3 1 2 3 2 1 2 3 3
      ⍝ Almost ready.  If at this point we replace
      ⍝ 1:/ 2:v 3:\, only the peaks will require fixing.
      ~×a ⍝ not signum of a
1 1 1 0 1 1 1 0 1 1 1 0 1 1
      (~×a)×2+×2+/2-/0,0,⍨h ⍝ replace peaks with 0-s
1 1 1 0 3 3 1 0 3 2 1 0 3 3
      ⍝ Now replace 0:^ 1:/ 2:v 3:\
      ⍝ We can do this by indexing a string with the vector above
      ⍝ (and adding 1 because of stupid 1-based indexing)
      '^/v\'[1+(~×a)×2+×2+/2-/0,0,⍨h]
///^\\/^\v/^\\
      ⍝ Looks like our mountain, only needs to be raised according to h
      r←'^/v\'[1+(~×a)×2+×2+/2-/0,0,⍨h] ⍝ name it for convenience
      h¨↑r ⍝ extend r[i] with spaces to make it h[i] long
 /  /   /    ^     \    \   /   ^    \   v  /   ^    \   \
      ↑⌽¨h¨↑r ⍝ reverse each and mix into a single matrix
/
 /
  /
   ^
  \
 \
 /
  ^
 \
v
 /
  ^
 \
\
      ⍉⌽↑⌽¨h¨↑r ⍝ reverse and transpose to the correct orientation
   ^
  / \  ^   ^
 /   \/ \ / \
/        v   \
ngn
źródło
3

Ruby, 390 znaków

Uff, ten był trudny.

Skończyło się na tym, że musiałem dołączyć nowy ciąg dla każdego znaku, używając zmiennej soznaczającej „pomiń następny znak”, która była potrzebna do przetworzenia ^i \.

To daje dokładnie dane wyjściowe próbki dla wszystkich przypadków testowych.

m=[gets.chomp]
a=m[0].scan(/\d/).max.to_i
m[0].gsub!(/./){|n|n==?. ? ' ':a-n.to_i}
s=nil
until a==0
o=''
m[-1].chars{|c|o+=case c
when ?0;?^
when ' ';t=s;s=nil;t ? '':' '
when /\d/;(c.to_i-1).to_s
when ?^;s=1;o.slice! -1;"/ \\"
when ?/;t=s;s=nil;t ? "#{o.slice! -1;' '}":o.slice!(-1)=='\\' ? 'v ':"/ "
when ?\\;s=1;' \\'
when ?v;' '
end}
m.push o
a-=1
end
puts (m[1..-1]*"\n").gsub /\d/,' '

Wykres znaczenia zmiennych:

m | The mountain array.
a | The highest height of a mountain. Used for counting when to stop.
s | Whether or not to skip the next character. 1 for yes, nil for no.
o | Temp string that will be appended to mountain.
t | Temp variable to hold the old value of s.

Jestem pewien, że mógłbym zagrać w golfa o wiele bardziej, ale muszę już iść. Poprawi się później!

Klamka
źródło
Walczę z danymi wejściowymi .2.2.i nie mogę zrozumieć, dlaczego to nie działa.
Howard
2

Java, 377 407

Edycja: @Victor zwrócił uwagę, że musi to być kompletny program, dlatego dodałem kilkadziesiąt znaków, aby był kompatybilny i działał. Wystarczy przekazać „zamówienie” jako pierwszy parametr podczas wykonywania programu, tak jak:java M ..3.4..6..4.3..

Myślę, że jest to podobne w duchu do innych odpowiedzi, w zasadzie po prostu przemierza „porządek górski” wielokrotnie dla każdej możliwej wysokości i buduje góry ze szczytów w dół. W ten sposób mam do czynienia tylko z czterema warunkami, jeśli nie buduję szczytu - albo zbocze w górę / /, zbocze w dół \, połączenie „v” lub puste ”. Mogę to odkryć, patrząc na trzy przestrzenie wyśrodkowane „powyżej” mojej obecnej pozycji w moim odgórnym zestawie.

Pamiętaj, że podobnie jak inne zgłoszenia traktuję wszystko inne niż liczbę jako równoważne „.” w danych wejściowych, dla zwięzłości.

Wersja golfowa:

class M{public static void main(String[]m){char[]n=m[0].toCharArray();int e=n.length,h=9,x=-1,p;char[][]o=new char[11][e];char l,r,u;boolean a,b,c;for(;h>=0;h--){for(p=0;p<e;p++){if(n[p]-49==h){o[h][p]=94;if(x==-1)x=h;}else{l=(p>0)?o[h+1][p-1]:0;r=(p<e-1)?o[h+1][p+1]:0;u=o[h+1][p];a=l>91&&l<99;b=r==94||r==47;c=u<33;o[h][p]=(char)((a&&b)?'v':(c&&b)?47:(c&&a)?92:32);}}if(x>=h)System.out.println(o[h]);}}}

Forma czytelna dla człowieka (i bez niektórych równoważnych transmisji do uzyskania formy golfa):

class Magrathea2 {
    public static void main(String[] mountain) {
        String out = "";
        char[][] output = new char[11][mountain[0].length()];
        int height = 9; int maxheight = -1;
        int position = 0;
        char left,right,up;
        char[] mount = mountain[0].toCharArray();
        for (; height >= 0; height--) {
            for (position=0; position < mount.length; position++) {
                if (mount[position]-49 == height) {
                    output[height][position] = '^';
                    if (maxheight==-1) {
                        maxheight=height;
                    }
                } else { // deal with non-numbers as '.'
                    left=(position>0)?output[height+1][position-1]:0;
                    right=(position<mount.length-1)?output[height+1][position+1]:0;
                    up=output[height+1][position];
                    if ((left=='^'||left=='\\')&&(right=='^'||right=='/')) {
                        output[height][position]='v';
                    } else if ((up==' '||up==0)&&(right=='/'||right=='^')) {
                        output[height][position]='/';
                    } else if ((up==' '||up==0)&&(left=='\\'||left=='^')) {
                        output[height][position]='\\';
                    } else {
                        output[height][position]=' ';
                    }
                }
            }
            if (maxheight >= height) {
                out+=new String(output[height]);
                if (height > 0) {
                    out+="\n";
                }
            }
        }
        System.out.println(out);
    }
}

Cieszyć się.

Przykładowe dane wyjściowe:

$ java M ..3..4...6...5....1
         ^
        / \  ^
     ^ /   \/ \
  ^ / v        \
 / v            \
/                \^
ProgrammerDan
źródło
Pytanie wspomina Napisz kompletny program , więc dodaj brakujący class X{public static void main(String[]z){.
Victor Stafusa
Tak jest. W następnej części tego zdania - „lub jako argument” zostałem źle skierowany i przeoczyłem całą część programu. Niedługo to zaktualizuję.
Programator
2

Perl 6, 264 224 216 206 200 194 124 bajtów

$_=get;my$a=10;((s:g/$a/^/;s:g/\s\.\s/ v /;s:g'\.\s'/ ';s:g/\s\./ \\/;$!=say TR/.1..9/ /;tr'^\\/v' ')if .match(--$a)|$!)xx 9

Dzięki @JoKing za pokazanie jako rozwiązanie ///. Gra jest nieco bardziej zaawansowana po naprawieniu błędu tr /// w Perlu 6.

Moje oryginalne rozwiązanie z subst:

my$t=get;for 9...1 {if $t.match($_)|$! {$t=$t.subst($_,'^',:g).subst(' . ',' v ',:g).subst('. ','/ ',:g).subst(' .',' \\',:g);$!=say $t.subst(/<[\.\d]>/,' ',:g);$t.=subst(/<[^\\/v]>/,' ',:g)};}

Nie golfowany:

my $t=slurp;
my $s;
for 9...1 {
    if $t.match($_)||$s {                    # match number or latched
        $t=$t.subst($_,'^',:g)               # peaks
        .subst(' . ',' v ',:g)               # troughs
        .subst('. ','/ ',:g)                 # up slope
        .subst(' .',' \\',:g);               # down slope
        $s=say $t.subst(/<[\.\d]>/,' ',:g);  # clean, display, latch
        $t=$t.subst(/<[^\\/v]>/,' ',:g)      # wipe for next line
    }
}

Wynik:

...4...3...33..4..4....2.3.22.33.5..22...333.222.3..
                                 ^                  
   ^           ^  ^             / \                 
  / \  ^   ^^ / \/ \     ^    ^^   \     ^^^     ^  
 /   \/ \ /  v      \  ^/ \^^/      ^^  /   \^^^/ \ 
/        v           \/               \/           \
donaldh
źródło
1
Nie sądzę, aby Perl ściśle potrzebował głównej funkcji, punkt wejścia może być pierwszą rzeczą poza funkcją.
Nissa,
Użyłem main do obsługi parametrów. Teraz używa standardowego wejścia. Dzięki.
donaldh
Rozwiązanie proceduralne. Jestem pewien, że ktoś może lepiej radzić sobie z wyrażeniami regularnymi i hyperopsami.
donaldh
1
131 bajtów przy użyciu s///i tr///. Myślę, że ten ostatni można użyć trzamiast, sale nie jestem w stanie wymyślić tłumaczenia odwrotnych ukośników. Być może pierwszy też
Jo King
Dobra robota @JoKing - wpadłem w bałagan w temacie, gdy próbowałem użyć s /// i TR ///. Widzę, że unikanie bloków jest odpowiedzią.
donaldh
1

Perl, 254 218 212

$s=<>;sub f{9-$i-$_[0]?$":pop}for$i(0..8){$h=1;$_=$s;s!(\.*)(\d?)!$D=($w=length$1)+$h-($2||1);join'',(map{($x=$_-int$D/2)<0?f--$h,'\\':$x?f++$h,'/':$D%2?f--$h,v:f$h,'/'}0..$w-1),$2?f$h=$2,'^':''!ge;print if/\S/}
$s=<>;
sub f{9-$i-$_[0]?$":pop}
for$i(0..8){
    $h=1;
    $_=$s;
    s!(\.*)(\d?)!
        $D=($w=length$1)+$h-($2||1);
        join'',(map{
            ($x=$_-int$D/2)<0
                ?f--$h,'\\'
                :$x
                    ?f++$h,'/'
                    :$D%2
                        ?f--$h,v
                        :f$h,'/'
        }0..$w-1),$2
            ?f$h=$2,'^'
            :''
    !ge;
    print if/\S/
}

Edycja: w rzeczywistości poprawka błędu działa na ..3..4...6...5....1przykładzie ProgrammerDan , ale w tym czasie niektóre bajty były wyłączone. I test online: https://ideone.com/P4XpMU

użytkownik 2846289
źródło
1

C # - 321 319

using System.Linq;class P{static void Main(string[]p){int h=p[0].Max()-48,i=h,j,n=p[0].Length;char[]A=new char[n+2],B=A;for(;i-->0;){for(j=0;j++<n;){var r=(A[j+1]==47|A[j+1]==94);B[j]=(char)(p[0][j-1]==i+49?94:i+1<h?A[j]==0?(A[j-1]>90&A[j-1]<95)?r?118:92:r?47:0:0:0);}A=(char[])B.Clone();System.Console.WriteLine(B);}}}

Nie golfił i skomentował:

using System.Linq;

class P
{
    static void Main(string[] p)
    {
        int h = p[0].Max() - 48,    // Getting the height. Codes for 0 to 9 are 48 to 57, so subtract 48 and hope no one will input anything but dots and numbers.
            i = h,
            j,                      // Declaring some iterators here, saves a few chars in loops.
            n = p[0].Length;
        char[] A = new char[n+2],   // Creating an array of char with 2 extra members so as not to check for "index out of bounds" exceptions
               B = A;               // B is referencing the same array as A at this point. A is previous row, B is the next one.
        for (;i-->0;)               // Looping from top to the bottom of the mountain
        {
            for (j = 0; j++ < n;)   // Looping from left to right.
            {
                var r = (A[j + 1] == 47 | A[j + 1] == 94);  // This bool is used twice, so it saves a few characters to make it a variable

                // Here's the logic
                B[j] = (char)(p[0][j - 1] == i + 49 ? 94    // If at this position in the string we have a number, output "^"
                                           : i + 1 < h ?    // And if not, check if we're on the top of the mountain
                                             A[j] == 0 ?    // If we're not at the top, check if the symbol above is a space (0, actually)
                                            (A[j - 1] > 90 & A[j - 1] < 95) ?   // If there's nothing above, we check to see what's to the left ( ^ or \ )
                                             r ?            // And then what's to the right ( ^ or / )
                                             118            // If there are appropriate symbols in both locations, print "v"
                                           : 92             // If there's only a symbol to the left, print "\"
                                           : r              // Otherwise check if there's a symbol to the right, but not to the left
                                           ? 47             // And if there is, print "/"
                                           : 0 : 0 : 0);    // Print nothing if there aren't any symbols above, to the left and to the right,
                                                            // or there's a "^" right above, or we're at the top of the mountain
            }
            A=(char[])B.Clone();    // Clone arrays to iterate over the next line
            System.Console.WriteLine(B);
        }
    }
}

Przykład:

C:\>program .2..3..4...
        ^
     ^ / \
  ^ / v   \
 / v       \

Myślę jednak, że generuje dodatkowe miejsce przed każdą linią.

Ray Poward
źródło
1

CJam, 128 117 112 106 104 bajtów

CJam jest nieco młodszy od tego wyzwania, więc ta odpowiedź nie konkuruje. To było jednak bardzo miłe wyzwanie! Z tego, co wiem o J i APL, wiem, że przesłanie ich byłoby imponująco krótkie.

WlW++"."Waer{_{~U(e>:U}%\W%}2*;W%]z{$W=}%_$W=S*\:L,2-,\f{\_)L=(~"^/ ^^/ \v ^ \\"S/2/@L>3<_$0=f-{=}/t}zN*

Oto przypadek testowy, który moim zdaniem zawiera wszystkie możliwe kombinacje stoków, szczytów i dolin:

...4...3...33..4..4....2.3.22.33.5..22...333.222.3..

co daje

                                 ^                  
   ^           ^  ^             / \                 
  / \  ^   ^^ / \/ \     ^    ^/   \     ^^^     ^  
 /   \/ \ /  v      \  ^/ \^^/      \^  /   \^^^/ \ 
/        v           \/               \/           \

Sprawdź to tutaj.

Wyjaśnię kod później.

Martin Ender
źródło
1

Pyton, 297 234 218

-63 bajty dzięki Jo King
-16 bajtów r=s.replacezamiast zamiast lambda

s=input()
r=s.replace
q=0
j=''.join
for i in range(9):
 if`9-i`in s or q:q=s=r(`9-i`,'^');s=r(' . ',' v ');s=r('. ','/ ');s=r(' .',' \\');print j([x,' '][x in'0123456789.']for x in s);s=j([x,' '][x in'/\^v']for x in s)

Pobiera dane wejściowe ze STDIN. Nie golfowy, uproszczony:

s=input() # Take input
r=lambda y,z: s.replace(y,z) # Function for quick s.replace(a, b)
j=lambda x: ''.join(x)
q=0 # Acts like boolean
for i in range(9): # Count to 9
 if `9-i`in s or q: # When digit has been found or found previously (no newlines at start)
  q=s=r(`9-i`,'^') # Digit to ^, set q to non-zero value for always executing from now on
  s=r(' . ',' v ') # ' . ' to ' v '
  s=r('. ','/ ') # '. ' to '/ '
  s=r(' .',' k') # ' .' to 'k'. K is a placeholder, since \\ takes two chars and `[...]`[2::5] fails
  print j([x,' '][x in'0123456789.']for x in s) # Print without '0123456789.'
  s=j([x,' '][x in'/\^v']for x in s) # Wipe (delete '/^\v`)
Duncan Whyte
źródło
234 bajty
Jo King
1
Tak, sam wypróbowałem tę s.replacemetodę, ale nie działa. Po prostu wykonujesz zamiany oryginalnego łańcucha, ponieważ łańcuchy są niezmienne
Jo King
0

PowerShell, 148 145 bajtów

To miłe wyzwanie!

param($s)9..1|?{($p+=$s-match$_)}|%{"$_,^; \. , v ;\. ,/ ; \., \;\^|\\|/|v, "-split';'|%{$x=$s-replace'\.|\d',' '
$s=$s-replace($_-split',')}
$x}

Skrypt testu mniej golfowego:

$f = {

param($s)
9..1|?{($p+=$s-match$_)}|%{      # loop digits form 9 downto 1, execute to the end as soon as a suitable digit met
    $s=$s-replace$_,'^'          # replace current digit with '^'
    $s=$s-replace' \. ',' v '    # replace ' . '  with ' v '
    $s=$s-replace'\. ','/ '      # replace '. ' with '/ '
    $s=$s-replace' \.',' \'      # replace ' .' with ' \'
       $s-replace'\.|\d',' '     # replace all dots and digits with ' ' and push to output. Don't store this replacement
    $s=$s-replace'\^|\\|/|v',' ' # prepeare to the next step: replace ^ \ / and v to space
}

    # Example:
    #     $s="...4...3...3.."
    # 4 : $s="...^...3...3.." output: "   ^          "
    # 4 : $s="... ...3...3.."
    # 3 : $s="../ \..^...^.." output: "  / \  ^   ^  "
    # 3 : $s="..   .. ... .."
    # 2 : $s="./   \/ \./ \." output: " /   \/ \ / \ "
    # 2 : $s=".        .   ."
    # 1 : $s="/        v   \" output: "/        v   \"
    # 1 : $s="              "

}

@(
    ,("1",
      "^")

    ,("11",
      "^^")

    ,("1.2.",
    "  ^ ",
    "^/ \")

    ,(".2.3..",
      "   ^  ",
      " ^/ \ ",
      "/    \")

    ,(".2..3..",
      "    ^  ",
      " ^ / \ ",
      "/ v   \")

    ,("...4...3...3..",
      "   ^          ",
      "  / \  ^   ^  ",
      " /   \/ \ / \ ",
      "/        v   \")

    ,("...4...3...33..4..4....2.3.22.3..5...22...333.222.3..",
      "                                 ^                   ",
      "   ^           ^  ^             / \                  ",
      "  / \  ^   ^^ / \/ \     ^    ^/   \      ^^^     ^  ",
      " /   \/ \ /  v      \  ^/ \^^/      \^^  /   \^^^/ \ ",
      "/        v           \/                \/           \")

    ,(".2..3..6.....5...3......1..3..4....2.",
      "       ^                             ",
      "      / \    ^                       ",
      "     /   \  / \               ^      ",
      "    ^     \/   \ ^         ^ / \     ",
      " ^ /            v \       / v   \  ^ ",
      "/ v                \    ^/       \/ \")
) | % {
    $s,$expected = $_
    $result = &$f $s
    "$result"-eq"$expected"
    $s
    $result
}

Wynik:

True
1
^
True
11
^^
True
1.2.
  ^
^/ \
True
.2.3..
   ^
 ^/ \
/    \
True
.2..3..
    ^
 ^ / \
/ v   \
True
...4...3...3..
   ^
  / \  ^   ^
 /   \/ \ / \
/        v   \
True
...4...3...33..4..4....2.3.22.3..5...22...333.222.3..
                                 ^
   ^           ^  ^             / \
  / \  ^   ^^ / \/ \     ^    ^/   \      ^^^     ^
 /   \/ \ /  v      \  ^/ \^^/      \^^  /   \^^^/ \
/        v           \/                \/           \
True
.2..3..6.....5...3......1..3..4....2.
       ^
      / \    ^
     /   \  / \               ^
    ^     \/   \ ^         ^ / \
 ^ /            v \       / v   \  ^
/ v                \    ^/       \/ \
mazzy
źródło
0

Pip -l , 100 bajtów

Y#aZGMXaFi,#aIh:+a@i{(yi--h):4j:0Wh-j&++(yi-++jh-j)(yi+jh-j):2}RV Z(J*y)R`.(?=.*[^0])`0R,6;^" /\v^^"

(Język jest nowszy niż pytanie, ale prawdopodobnie i tak nie przebije zgłoszenia APL. Chociaż mam nadzieję, że będzie znacznie krótszy.)

Pobiera dane wejściowe za pomocą argumentu wiersza polecenia. Wypróbuj online!

DLosc
źródło