¿Cuántos 14ers subí?

13

En terminología de montañismo, un "14er" es cualquier montaña con una elevación de 14 000 pies o más. Sin embargo, hay otra distinción. Para que un pico cuente como un 14er, también debe tener una "prominencia geográfica" de 300 o más pies. Esto significa que para pasar de un 14er a otro, primero debe descender al menos 300 pies antes de volver a subir. Toma este ejemplo. La línea 1 cuenta como 14 000 pies, y cada línea cuenta como 100 pies.

  /\__/\  
 /      \ 
/        \

Ahora, ambos picos tienen suficiente elevación para contar, pero no hay suficiente caída en la elevación entre ellos para contar como dos picos separados. Por lo tanto, uno de estos cuenta como un 14er, y el otro es solo un "pico parcial". Aquí hay un ejemplo donde los dos picos cuentan como dos 14er separados:

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

También puede haber un pico parcial en la disminución entre dos 14ers. Aquí hay una versión ligeramente modificada de la última cordillera:

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

Esta cordillera también cuenta como dos 14ers.

Debe escribir un programa o función que tome una representación ascii-art de una cordillera y devolver cuántos 14ers hay en la cordillera. Puede tomar la entrada en el formato que sea más conveniente para usted, ya sea una matriz 2D de caracteres, una cadena con nueva línea o una cadena con algún otro delimitador. Puede suponer que todas las entradas solo contendrán los caracteres /\_y que la longitud de cada línea será la misma (incluidos los espacios finales). También puede suponer que la cordillera comienza en la esquina inferior izquierda con a /o a _.

Si la última sección de una montaña no está en la línea de fondo, puede suponer que la montaña solo disminuye después de eso, p. Ej.

  /
 /
/

Cuenta como un solo 14er.

No tiene que manejar cadenas montañosas inválidas.

Aquí hay algunos ejemplos de E / S:

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

2

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

4

       /\                 
 _/\__/  \                
/         \               

1

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

1

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

3
James
fuente
Entonces, ¿la línea de salida cuenta como 14,000 pies?
R. Kap
@ R.Kap Sí, creo que es correcto, suponiendo que te refieres a la línea de fondo cuando dices línea de partida.
Alex A.
1
Creo que debería mencionar en alguna parte que un _cuenta como 100 pies más bajo que un corte en la misma línea. Al menos eso es lo que sugiere su último caso de prueba.
Martin Ender
3
La especificación parece delgada ... ¿podemos tener una turba plana / / / _ \ \ \ ? Además, supongo que el punto más alto en la entrada siempre debe contarse como un pico, pero esto no se especifica explícitamente; uno podría comenzar en un pico más bajo y terminar con un conteo diferente.
feersum
2
¿Será siempre continuo? ¿Tendrá como máximo un carácter no espacial para cada columna?
Leaky Nun

Respuestas:

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

Explicación

Dado que las especificaciones no se establecen claramente, esto hace un par de suposiciones:

  • El resultado final es la marca de 14,000 pies (por lo que todas las posiciones en la cuadrícula son lo suficientemente altas como para contar como un pico).
  • La cuadrícula comienza en (o ascendiendo) el primer pico (ya que tiene al menos 14,000 pies de altura ya según el supuesto anterior).
  • Un pico separado solo cuenta después de descender 300 pies y luego subir 300 pies .

Itera sobre el carácter cde cada columna (específicamente, itera hacia abajo cada columna hasta que encuentra un carácter). La altitud actual se almacena en a. Se sujeta a un mínimo de 0y un máximo de 3. La dirección necesaria para moverse para contar el siguiente pico se almacena en d( false= arriba, true= abajo). Si aalcanza 3y des false, el número de picos pse incrementa y dse establece en true(abajo). Una vez que aalcanza 0, dse establece de nuevo a false(arriba).

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>

usuario81655
fuente
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);}

Requiere una nueva línea final en la entrada, de lo contrario +4 bytes.

MIllIbyte
fuente
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

Donde \nrepresenta el carácter de nueva línea literal. Sin golf:

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;
}
Neil
fuente