Se le da una cadena para hacer y, comenzando con la cadena vacía, hágalo usando el costo de anexión y clonación

17

Su tarea es crear la cadena objetivo dada. Comenzando con una cadena que está vacía, tendrá que agregarle caracteres, hasta que su cadena sea la misma que queremos. Puede agregar un carácter al final de su cadena con costo x, o puede clonar su cadena con costo y. Lo que queremos es la forma más barata de hacer esto.

Casos de prueba

targetString , appendcost, clonecost -> totalcost

"bb", 1, 2 -> 2
"bbbb", 2, 3 -> 7
"xzxpcxzxpy", 10, 11 -> 71
"abababab", 3, 5 -> 16
"abababab", 3, 11 -> 23

fuente
1
¿Cómo se definen los costos? ¿Son enteros positivos?
Arnauld
1
Creo que solo está buscando hacer un desafío de código de golf (código más corto), así que eliminé las etiquetas de desafío de código y rompecabezas de programación que indican alguna forma alternativa de puntuación.
xnor
77
Creo que ayudaría tener más casos de prueba, ya que parece probable que alguien pueda escribir un programa que tenga buenas heurísticas que funcionen para todos los casos de prueba pero que no sean óptimos en general. En particular, ninguno de los casos de prueba tiene múltiples clones o clones de subcadenas que no están al principio. Creo que también sería bueno tener un ejemplo en el que cambiar solo los costos cambie la producción.
xnor
66
Bonito primer desafío, por cierto!
Erik the Outgolfer
¿La clonación de una sola letra todavía se considera una operación de clonación?
digEmAll el

Respuestas:

2

Casco , 25 bytes

φ?ö▼z+:⁴∞²m⁰§:h§δf`€otṫḣ0

Pruébalo en línea!

Las entradas están en el orden agregar costo, costo de clonación, objetivo.

Explicación

φ?ö▼z+:⁴∞²m⁰§:h§δf`€otṫḣ0  Two explicit inputs and one implicit.
                           Example: 2, 3, s="abab"
φ                          Make a recursive function and call it on s:
 ?                      0   If s is empty, return 0.
  ö▼z+:⁴∞²m⁰§:h§δf`€otṫḣ    Otherwise do this.
                       ḣ    Prefixes: ["a","ab","aba","abab"]
                    otṫ     Suffixes except the first one: ["bab","ab","b"]
               §δf`€        Keep those prefixes that have the corresponding suffix as substring: ["ab","aba"]
            §:h             Prepend s minus last character: ["aba","ab","aba"]
          m⁰                Recurse on each: x=[6,4,6]
        ∞²                  Repeat the clone cost: [3,3,3,..
      :⁴                    Prepend append cost: [2,3,3,3,..
    z+                      Add component-wise to x: [8,7,9]
   ▼                        Minimum: 7
Zgarb
fuente
1

JavaScript (ES6), 123111 bytes

Toma entrada como (x)(y)(s).

x=>y=>m=g=([s,...r],o='',c=0)=>s?[...r,g(r,o+s,c+x)].map(_=>s+=r.shift(~o.search(s)&&g(r,o+s,c+y)))|m:m=m<c?m:c

Pruébalo en línea!

Comentado

x => y =>                    // x = 'append' cost; y = 'clone' cost
m =                          // m = minimum cost, initialized to a non-numeric value
                             //     this is what will eventually be returned
g = (                        // g = recursive function taking:
  [s,                        //   - the input string split into s = next character
      ...r],                 //     and r[] = array of remaining characters
  o = '',                    //   - o = output string
  c = 0                      //   - c = current cost
) =>                         //
  s ?                        // if s is defined:
    [ ...r,                  //   split a copy of r
      g(r, o + s, c + x)     //   do a recursive call with an 'append' operation
    ].map(_ =>               //   iterate as many times as there are remaining characters
                             //   in r[], + 1
      s +=                   //     append to s
        r.shift(             //     the next character picked from the beginning of r[]
          ~o.search(s) &&    //     if s is found in o,
          g(r, o + s, c + y) //     do a recursive call with a 'clone' operation
        )                    //     (note that both s and r are updated *after* the call)
    ) | m                    //   end of map(); return m
  :                          // else:
    m = m < c ? m : c        //   update m to min(m, c)
Arnauld
fuente
1

R , 192 185 bytes

f=function(s,a,c,k=0,x="",R=substring,N=nchar,p=R(s,1,1:N(s)))'if'(!N(s),k,{y={};for(i in c(R(s,1,1),p[mapply(grepl,p,x)]))y=min(y,f(R(s,N(i)+1),a,c,k+'if'(any(y),c,a),paste0(x,i)));y})

Pruébalo en línea!

Código desenrollado y explicación:

# s is the current remaining string (at the beginning is equal to the target string)
# a is the append cost
# c is the clone cost
# k is the current cost (at the beginning is zero)
# x is the partially constructed string (at the beginning is empty)
f=function(s,a,c,k=0,x=""){
  # store in p all the possible prefixes of s
  p = substring(s,1,1:nchar(s))
  # if s is empty return the current cost k
  if(!nchar(s))
    k
  else{
    y={}
    # prepend the first letter of s (=append operation) to  
    # the prefixes in p that are contained in x (=clone operations)
    for(i in c(substring(s,1,1),p[mapply(grepl,p,x)])){
      # perform first the append then the clone operations and recurse, 
      # storing the cost in y if lower than previous
      # (if y is NULL is an append operation otherwise is a clone, we use the right costs)
      y = min(y,f(substring(s,nchar(i)+1),a,c,k+'if'(any(y),c,a),paste0(x,i)))
    }
    # return the current cost
    y
  }
}
digEmAll
fuente