Quantos 14ers eu subi?


13

Na terminologia do alpinismo, um "14er" é qualquer montanha com uma altitude de 14.000 pés ou mais. No entanto, há outra distinção. Para um pico contar como um 14er, ele também deve ter uma "proeminência geográfica" de 300 pés ou mais. Isso significa que, para passar de um 14er para outro, você deve primeiro descer pelo menos 300 pés antes de subir novamente. Veja este exemplo. A linha 1 conta como 14.000 pés e cada linha conta como 100 pés.

  /\__/\  
 /      \ 
/        \

Agora, ambos os picos têm elevação suficiente para contar, mas não há queda suficiente na elevação entre eles para contar como dois picos separados. Portanto, um deles conta como 14er, e o outro é apenas um "pico parcial". Aqui está um exemplo em que os dois picos contam como dois 14er separados:

   /\    /\   
  /  \  /  \  
 /    \/    \ 
/            \

Também pode haver um pico parcial no declínio entre dois 14ers. Aqui está uma versão ligeiramente modificada da última cordilheira:

   /\      /\   
  /  \/\  /  \  
 /      \/    \ 
/              \

Esta cordilheira também conta como dois 14ers.

Você deve escrever um programa ou função que faça uma representação artística de uma cadeia de montanhas e retornar quantos 14ers estão na cadeia. Você pode inserir dados no formato que for mais conveniente para você, seja um conjunto de caracteres 2D, uma sequência com nova linha ou uma sequência com outro delimitador. Você pode assumir que todas as entradas conterão apenas os caracteres /\_e que o comprimento de cada linha será o mesmo (incluindo espaços à direita). Você também pode assumir que a cordilheira começa no canto inferior esquerdo com a /ou a _.

Se a última seção de uma montanha não estiver na linha inferior, você pode assumir que a montanha só diminui depois disso, por exemplo

  /
 /
/

Conta como um único 14er.

Você não precisa lidar com cadeias de montanhas inválidas.

Aqui está uma amostra de E / S:

         /\___/\_             
        /        \    /\      
       /          \  /  \     
   _/\/            \/    \    
  /                       \   
 /                         \  
/                           \_

2

                  /\    /\
         /\      /  \  /  
  /\    /  \    /    \/   
 /  \  /    \  /          
/    \/      \/           

4

       /\                 
 _/\__/  \                
/         \               

1

      /\                  
     /  \   /\            
    /    \_/  \           
   /           \          
  /             \         
 /               \        
/                 \       

1

              /\          
    /\_/\    /  \_        
   /     \  /     \     /\
  /       \/       \   /  
 /                  \_/   
/                         

3

Então a linha de partida conta como 14.000 pés?
R. Kap

@ R.Kap Sim, acredito que esteja correto, supondo que você esteja falando da linha de fundo quando diz a linha de partida.
Alex A.

1
Eu acho que você deve mencionar em algum lugar que a _conta é de 30 metros mais baixa que uma barra na mesma linha. Pelo menos é o que seu último caso de teste sugere.
Martin Ender

3
A especificação parece fina ... podemos ter uma turfa plana / / / _ \ \ \ ? Além disso, suponho que o ponto mais alto da entrada sempre deve ser contado como um pico, mas isso não é especificado explicitamente; pode-se começar com um pico mais baixo e terminar com uma contagem diferente.
feersum

2
Será sempre contínuo? Terá no máximo um caractere não espacial para cada coluna?
Freira vazada

Respostas:


2

JavaScript (ES6), 133 bytes

s=>[...s].map((_,i)=>(c=s[i%h*w+i/h|0])=="/"?++a>2&&(p+=!d,d=a=3):c=="\\"&&--a<1&&(d=a=0),w=s.search`
`+1,h=-~s.length/w,a=3,d=p=1)|p

Explicação

Como as especificações não estão claramente definidas, isso faz algumas suposições:

  • A linha inferior é a marca de 14.000 pés (portanto, todas as posições na grade são altas o suficiente para contar como um pico).
  • A grade começa no (ou ascendente) primeiro pico (já que já tem pelo menos 14.000 pés de altura, conforme suposição anterior).
  • Um pico separado conta apenas depois de descer 300 pés e depois subir 300 pés .

Repete o caractere cde cada coluna (especificamente, itera cada coluna até encontrar um caractere). A altitude atual é armazenada em a. É fixado no mínimo 0e no máximo 3. A direção necessária para se mover para contar o próximo pico é armazenada em d( false= para cima, true= para baixo). Se aatingir 3e dfor false, o número de picos pé incrementado e ddefinido como true( para baixo). Uma vez aalcançado 0, dé retornado para false( para cima).

var solution =

s=>
  [...s].map((_,i)=>   // loop
    (c=s[i%h*w+i/h|0]) // c = current character (moves down columns)
    =="/"?             // if c is '/'
      ++a>2&&          // increment a, if a equals 3 and d is true:
        (p+=!d,d=a=3)  // increment p, set d to true, clamp a to 3
    :c=="\\"&&         // if c is '\':
      --a<1&&          // decrement a, if a equals 0:
        (d=a=0),       // set d to false, clamp a to 0
    
    // Initialisation (happens BEFORE the above code)
    w=s.search`\n`+1,  // w = grid width
    h=-~s.length/w,    // h = grid height
    a=3,               // a = current altitude (min = 0, max = 3)
    d=                 // d = required direction (false = up, true = down)
    p=1                // p = number of found peaks
  )|p                  // output the number of peaks

var testCases = [`
/\\
`,`
/\\          
  \\         
   \\    /\\  
    \\  /  \\ 
     \\/    \\
`,`
\\    /
 \\  / 
  \\/  
`,`
            /\\            
         /\\/  \\/\\         
      /\\/        \\/\\      
   /\\/              \\/\\   
/\\/                    \\/\\
`,`
  /\\__/\\
 /      \\
/        \\
`,`
   /\\    /\\   
  /  \\  /  \\  
 /    \\/    \\ 
/            \\
`,`
   /\\      /\\   
  /  \\/\\  /  \\  
 /      \\/    \\ 
/              \\
`,`
         /\\___/\\_             
        /        \\    /\\      
       /          \\  /  \\     
   _/\\/            \\/    \\    
  /                       \\   
 /                         \\  
/                           \\_
`,`
                  /\\    /\\
         /\\      /  \\  /  
  /\\    /  \\    /    \\/   
 /  \\  /    \\  /          
/    \\/      \\/           
`,`
       /\\                 
 _/\\__/  \\                
/         \\               
`,`
      /\\                  
     /  \\   /\\            
    /    \\_/  \\           
   /           \\          
  /             \\         
 /               \\        
/                 \\       
`,`
              /\\          
    /\\_/\\    /  \\_        
   /     \\  /     \\     /\\
  /       \\/       \\   /  
 /                  \\_/   
/                         
`];
result.textContent = testCases.map(c=>c+"\n"+solution(c.slice(1,-1))).join`\n\n`;
<textarea id="input" rows="6" cols="40"></textarea><br /><button onclick="result.textContent=solution(input.value)">Go</button><pre id="result"></pre>


2

C, 174 bytes

a[99],c,p,j,M,m;main(i){for(i=j=1;c=getchar(),~c;i++)c<11?a[i]=j++,i=0:c&4?a[i]=j:0;for(m=j;c=a[i++];c>a[i-2]?M-m>1&&c-m>1?M=c,m=j,p++:M<c?M=m=c:M:m>c?m=c:0);printf("%d",p);}

Requer uma nova linha à direita na entrada, caso contrário, +4 bytes.


1

JavaScript (ES6), 154 bytes

s=>s.split`\n`.map((s,i)=>s.replace(/\S/g,(c,j)=>{e[j]=i+(c!='\\');e[j+1]=i+(c>'/')}),e=[])&&e.map(n=>h-n+d?h-n-d*3?0:(c++,d=-d,h=n):h=n,h=e[0],c=d=1)|c>>1

Onde \nrepresenta o caractere literal de nova linha. Ungolfed:

function climb(string) {
    var heights = [];
    // Split the array into lines so that we know the offset of each char
    var array = string.split("\n");
    // Calculate the height (actually depth) before and after each char
    for (var i = 0; i < array.length; i++) {
        for (var j = 0; j < string.length; j++) {
            switch (array[i][j]) {
            case '\':
                heights[j] = i;
                heights[j+1] = i + 1;
                break;
            case '_':
                heights[j] = i + 1;
                heights[j+1] = i + 1;
                break;
            case '/':
                heights[j] = i + 1;
                heights[j+1] = i;
                break;
        }
    }
    var count = 1;
    // Start by looking for an upward direction
    var direction = 1;
    var height = heights[0];
    for (var k = 1; k < heights.length; k++) {
        if (heights[i] == height - direction * 3) { // peak or trough
            direction *= -1;
            count++; // we're counting changes of direction = peaks * 2
            height = heights[i];
        } else if (heights[i] == height + direction) {
            // Track the current peak or trough to the tip or base
            height = heights[i];
        }
    }
    return count >> 1;
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.