Combien de 14ers ai-je grimpé?

13

Dans la terminologie de l'alpinisme, un "14er" est n'importe quelle montagne avec une élévation de 14 000 pieds ou plus. Cependant, il existe une autre distinction. Pour qu'un pic compte pour un 14er, il doit également avoir une «proéminence géographique» de 300 pieds ou plus. Cela signifie que pour passer d'un 14er à un autre, vous devez d'abord descendre au moins 300 pieds avant de remonter. Prenez cet exemple. La ligne 1 compte pour 14 000 pieds et chaque ligne compte pour 100 pieds.

  /\__/\  
 /      \ 
/        \

Maintenant, ces deux pics ont suffisamment d'élévation pour compter, mais il n'y a pas assez de baisse d'altitude entre eux pour compter comme deux pics distincts. Par conséquent, l'un d'entre eux compte comme un 14er, et l'autre n'est qu'un "pic partiel". Voici un exemple où les deux pics comptent comme deux 14er distincts:

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

Il peut également y avoir un pic partiel sur le déclin entre deux 14ers. Voici une version légèrement modifiée de la dernière chaîne de montagnes:

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

Cette chaîne de montagnes compte également comme deux 14ers.

Vous devez écrire un programme ou une fonction qui prend une représentation ascii-art d'une chaîne de montagnes, et retourner combien de 14ers sont dans la plage. Vous pouvez saisir des données dans le format qui vous convient le mieux, que ce soit un tableau 2D de caractères, une chaîne avec un retour à la ligne ou une chaîne avec un autre délimiteur. Vous pouvez supposer que toutes les entrées ne contiendront que les caractères /\_et que la longueur de chaque ligne sera la même (y compris les espaces de fin). Vous pouvez également supposer que la chaîne de montagnes commence dans le coin inférieur gauche par un /ou un _.

Si la dernière section d'une montagne n'est pas sur la ligne du bas, vous pouvez supposer que la montagne ne diminue que par la suite, par exemple

  /
 /
/

Compte comme un seul 14er.

Vous n'avez pas à gérer des chaînes de montagnes invalides.

Voici quelques exemples d'E / S:

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

2

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

4

       /\                 
 _/\__/  \                
/         \               

1

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

1

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

3
James
la source
Donc, la ligne de départ compte pour 14 000 pieds?
R. Kap
@ R.Kap Oui, je crois que c'est correct, en supposant que vous voulez dire la ligne du bas lorsque vous dites la ligne de départ.
Alex A.
1
Je pense que vous devriez mentionner quelque part qu'un a _compte comme 100 pieds plus bas qu'une barre oblique sur la même ligne. C'est du moins ce que suggère votre dernier test.
Martin Ender
3
La spécification semble mince ... pouvons-nous avoir une tourbe plate comme / / / _ \ \ \ ? En outre, je suppose que le point le plus élevé de l'entrée doit toujours être compté comme un pic, mais cela n'est pas explicitement spécifié; on pourrait commencer à un pic plus bas et finir avec un compte différent.
feersum
2
Sera-ce toujours continu? Aura-t-il au plus un caractère non-espace pour chaque colonne?
Leaky Nun

Réponses:

2

JavaScript (ES6), 133 octets

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

Explication

Étant donné que les spécifications ne sont pas clairement énoncées, cela fait deux hypothèses:

  • La ligne du bas est la marque de 14 000 pieds (donc toutes les positions sur la grille sont suffisamment hautes pour compter comme un pic).
  • La grille commence au (ou ascendant) le premier pic (car il atteint au moins 14 000 pieds de haut selon l'hypothèse précédente).
  • Un pic séparé ne compte qu'après avoir descendu 300 pieds puis monté 300 pieds .

Itère sur le caractère cde chaque colonne (en particulier, il parcourt chaque colonne jusqu'à ce qu'il trouve un caractère). L'altitude actuelle est enregistrée dans a. Il est fixé à un minimum 0et à un maximum de 3. La direction nécessaire pour se déplacer pour compter le prochain pic est stockée dans d( false= haut, true= bas). Si aatteint 3et dest false, le nombre de pics pest incrémenté et dest défini sur true(bas). Une fois aatteint 0, dest remis à false(haut).

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>

user81655
la source
2

C, 174 octets

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

Nécessite une nouvelle ligne de fin dans l'entrée, sinon +4 octets.

mIllIbyte
la source
1

JavaScript (ES6), 154 octets

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

\nreprésente le caractère de nouvelle ligne littéral. Non 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
la source