Charge de téléphone portable

10

Défi relevé avec la permission de mon concours University Code Challenge


La dépendance que nous avons sur les téléphones portables nous fait les recharger tous les soirs jusqu'au niveau maximum de la batterie, donc nous ne courons pas le risque de manquer d'énergie au milieu du lendemain. Il y a même des gens qui, lorsqu'ils voient une prise gratuite pendant la journée, la font payer pour ce qui peut arriver.

Je suis l'un d'eux.

Au fil des années, j'ai affiné ma technique pour ne pas charger la batterie au maximum chaque nuit. Avec mes routines répétitives parfaitement connues, je sais clairement à quelles heures de la journée je pourrai effectuer ces recharges partielles (et combien d'unités le niveau augmentera) et ce qui abaisse le niveau de la batterie entre chaque charge. Avec ces données, chaque nuit, je calcule le niveau de batterie minimum avec lequel je dois quitter la maison le lendemain pour qu'il ne tombe jamais en dessous de mon seuil auto-imposé de deux unités.

Ce que je n'ai pas encore réussi à maîtriser, c'est ce même calcul quand je quitte la routine établie et j'ai plusieurs alternatives pour faire les choses. Cela arrive, par exemple, les jours où je suis en route vers une autre ville où je peux arriver de différentes manières.

Dans ma première approche du problème, je suppose que je veux me déplacer autour d'un "échiquier", du coin supérieur gauche au coin inférieur droit. Dans chaque "cellule", je peux soit charger le mobile d'un montant spécifique, soit je ne peux pas et son niveau de charge diminue.

Défi

Étant donné une matrice FxC d'entiers, produisez le niveau de batterie minimal dont j'ai besoin pour passer du coin supérieur gauche au coin inférieur droit sans que le niveau de charge ne tombe en dessous de 2 unités.

Dans la matrice, un nombre positif indique combien je peux charger mon téléphone portable avant de devoir reprendre mon chemin, tandis qu'un nombre négatif indique qu'il n'y a pas de prises et que la batterie du mobile baisse son niveau de charge de ce montant. Il est garanti que les quantités dans les cellules source et destination (coin supérieur gauche et coin inférieur droit) sont toujours égales à 0 et que le reste des valeurs (valeur absolue) ne dépasse pas 100.

Exemple
donné:

[📱-11-1-1-1-1-1-11-1-111-10]

Le chemin dont j'ai besoin de moins de batterie est:

[📱-11-1-1-1-1-1-11-1-111-10]

Et le niveau minimal de batterie dont j'ai besoin est de 4

Remarques

  • Le départ sera toujours le coin supérieur gauche
  • La fin sera toujours le coin inférieur droit
  • Vous ne pouvez pas vous rendre dans une cellule que vous avez déjà dépassée. Exemple: une fois en position (0,1), vous ne pouvez pas aller au point initial (0,0)
  • Votre niveau de batterie ne peut pas (pour une raison quelconque) descendre sous 2
  • Vous pouvez supposer qu'il y aura toujours un début et une fin
  • Vous pouvez prendre les tableaux unidimensionnels comme multidimensionnels si vous avez besoin de [1,2,3] == [[1,2,3]]
  • Il peut y avoir plusieurs chemins corrects (charge minimale nécessaire)
  • Votre objectif est de produire uniquement le niveau de batterie initial le plus bas nécessaire, pas l'itinéraire
  • Vous ne pouvez aller que verticalement et horizontalement (pas en diagonale)

Cas de test

[0, 0] => 2
[0, 1, 0] => 2
[0, -1, 0] => 3
[0, 15, -20, 5, 0] => 7
[[0, -3],[-5, 0]] => 5
[[0, -5, -9, 5], [-3, 5, 2, -2], [2, -4, -4, 0]] => 5
[[0, -1, 1, -1], [-1, -1, -1, -1], [-1, 1, -1, -1], [1, 1, -1, 0]] => 4
Luis felipe De jesus Munoz
la source
J'ai oublié le jour du défi. Post sandbox
Luis felipe De jesus Munoz
À tous ceux qui se souviennent: le défi "The Hungry Moose" n'a jamais réussi à sortir du bac à sable, donc ce n'est pas dupe.
Black Owl Kai
@BlackOwlKai Je pense que les deux défis sont différents
Luis felipe De jesus Munoz
1
Le chemin optimal nécessitera-t-il un jour de se déplacer vers la gauche ou vers le haut? Par exemple[[0,1,-1],[-9,-9,1],[-9,1,-1],[-9,-1,-9],[-9,1,0]]
Kamil Drakari
1
@dana non, il n'y en a que 2 0splacés l'un dans le coin supérieur gauche et l'autre en bas à droite
Luis felipe De jesus Munoz

Réponses:

3

JavaScript (ES7),  162156154  octets

m=>(M=g=(x,y,n,k)=>m.map((r,Y)=>[r[x+1]]+[m[y+1]]?r.map((v,X)=>r[1/v&&(x-X)**2+(y-Y)**2==1&&g(X,Y,u=v+n,k<u?k:u,r[X]=g),X]=v):M=M>k?M:k))(0,0,0)|M<0?2-M:2

Essayez-le en ligne!

Commenté

m => (                          // m[] = input matrix
  M =                           // initialize M to a non-numeric value
  g = (x, y, n, k) =>           // g = recursive depth-first search function
    m.map((r, Y) =>             // for each row r[] at position Y in m[]:
      [r[x + 1]] +              //   if either r[x + 1]
      [m[y + 1]] ?              //   or m[y + 1] is defined:
        r.map((v, X) =>         //     for each value v at position X in r[]:
          r[                    //
            1 / v &&            //       if v is numeric
            (x - X) ** 2 +      //       and the squared Euclidean distance
            (y - Y) ** 2 == 1   //       between (x, y) and (X, Y) is 1:
            &&                  //
              g(                //         do a recursive call:
                X, Y,           //           with (X, Y)
                u = v + n,      //           with n = n + v
                k < u ? k : u,  //           with k = min(k, n + v)
                r[X] = g        //           set r[X] to a non-numeric value
              ),                //         end of recursive call
            X                   //       then restore r[X]
          ] = v                 //       to its initial value
        )                       //     end of inner map()
      :                         //   else (we've reached the bottom right corner):
        M = M > k ? M : k       //     update M to max(M, k)
    )                           // end of outer map()
)(0, 0, 0) |                    // initial call to g with x = y = n = 0 and k undefined
M < 0 ? 2 - M : 2               // return 2 - M if M is negative, or 2 otherwise
Arnauld
la source
3

Python 2 , 208 202 octets

lambda s:2-f(s)
def f(s,x=0,y=0):
 if x>-1<y<s[y:]>[]<s[y][x:]!="">s[y][x]:k=s[y][x];s[y][x]="";return k+min(0,max([len(s[y+1:]+s[y][x+1:])and f(eval(`s`),x+a/3-1,y+a%3-1)for a in 7,1,5,3]))
 return-9e9

Essayez-le en ligne!


Python 2 , 217 211 octets

i=input()
X,Y=len(i[0]),len(i)
s=[[0]*4+[i]];r=[]
for m,l,x,y,g in s:
 if X>x>-1<y<Y<"">g[y][x]:r+=[m]*(Y-y<2>X-x);l+=g[y][x];g[y][x]="";s+=[[min(m,l),l,x+a/3-1,y+a%3-1,eval(`g`)]for a in 7,1,5,3]
print 2-max(r)

Essayez-le en ligne!

ovs
la source
1

R , 224 220 217 213 210 octets

f=function(x,m=rbind(0,cbind(0,x,0),0),i=2,j=2,p=F,k=c(1:-1,0,0,-1:1),b=Inf,`^`=min){m[i,j]=0
for(h in 1:4)b=b^'if'(all(c(R<-i+k[h],C<-j+k[h+4])>dim(x)),max(2,2-cumsum(p)^0),if(v<-m[R,C])b^f(x,m,R,C,c(p,v)))
b}

Essayez-le en ligne!

digEmAll
la source
1

C # (Visual C # Interactive Compiler) , 242 octets

a=>{int m=1<<31,n=~m;void g(int w,int x,int y,int z){for(int i=4,t,c,d,e;i-->0;)try{t=a[c=i<1?w-1:i<2?w+1:w,d=i>2?x-1:i>1?x+1:x];n=t==0&z<n?z:n;a[c,d]=m;e=y+t<2?2-y-t:0;if(t!=m)g(c,d,y+t+e,z+e);a[c,d]=t;}catch{}}a[0,0]=m;g(0,0,2,2);return n;}

Essayez-le en ligne!

//a: input matrix
a=>{
  // m: marker for used cells
  // n: result, initialized to a huge value
  int m=1<<31,n=~m;
  // recursive function
  // w: 1st dim coordinate
  // x: 2nd dim coordinate
  // y: current charge level
  // z: initial charge for current path
  void g(int w,int x,int y,int z){
    // i: loop variable
    // t: temp holds overwritten value
    // c: adjacent 1st dim coordinate
    // d: adjacent 2nd dim coordinate
    // e: delta charge needed
    for(int i=4,t,c,d,e;i-->0;)
      // avoid index out of range errors
      // by using try/catch
      try{
        // determine neighbor
        // coordinates and save value
        t=a[c=i<1?w-1:i<2?w+1:w,
            d=i>2?x-1:i>1?x+1:x];
        // if we have found a 0, check if
        // initial charge is lower than the
        // lowest so far. save it if it is.
        n=t==0&z<n?z:n;
        // mark current cell used
        a[c,d]=m;
        // determine if we need to
        // increase the initial charge
        e=y+t<2?2-y-t:0;
        // make recursive call if current
        // cell was not previously in use
        if(t!=m)g(c,d,y+t+e,z+e);
        // restore current cell value
        a[c,d]=t;
      }catch{}
  }
  // mark starting cell used
  a[0,0]=m;
  // start the recursive function
  g(0,0,2,2);
  // return the result to the caller
  return n;
}
dana
la source